約 4,173,188 件
https://w.atwiki.jp/genesis-ticket/pages/703.html
【名前】 歴代クリアファイル 【読み方】 れきだいくりあふぁいる 【詳細】 葵・トーリが初等部の講師を行う際におみやげと称して持ち込んだファイル。 エロゲの初回限定版を買いまくりで余ったものらしい。
https://w.atwiki.jp/yamamura2/pages/12919.html
【TOP】【←prev】【PlayStation 2】【next→】 Velvet File Plus タイトル Velvet File Plus ヴェルベットファイルプラス 機種 プレイステーション2 型番 SLPS-25037 ジャンル シミュレーション 発売元 ダズ 発売日 2001-3-29 価格 3800円(税別) タイトル Velvet File Plus 機種 プレイステーション2 型番 SLPS-25097 ジャンル シミュレーション 発売元 ダズ 発売日 2002-3-7 価格 2000円(税別) ヴェルベットファイル 関連 Console Game PS2 Velvet File Velvet File Plus 駿河屋で購入 プレイステーション2
https://w.atwiki.jp/lspdfrinfo/pages/87.html
metaファイルとは? metaファイルとは、アセットの管理等に使われるデータが保持されるもの。 管理者もmetaについて詳しくはないので解説はしないが、GTA5にもmetaファイルで制御されているデータが多く、そこを弄ることでゲーム内に変更を与えることができる。 LSPDFRをプレイするにあたり、データを弄ることは少なくない。そのため管理者が知っている限りでのmetaデータの解説を行う。 一般的に、弄るmetaファイルは vehicles.meta carvariations.meta carcols.meta の3つがメインだと管理人は思っている。 vehicles.metaは、乗り物のモデルの指定や音、名前、乗り物の特徴といった乗り物の大部分のデータが書かれている。 carvariations.metaは、乗り物のライトやサイレン、ナンバープレートなどの設定が書かれている。 carcols.metaは、carvariations.metaで使用されるサイレンやライトの仕様が書かれたもの。 まとめると、carcols.metaでライトやサイレンといった設定を定め、vehicles.metaで乗り物自体の設定を定め、carvariations.metaで乗り物がゲーム内でどのような動きをするのかを設定する、といったもの。 テキスト編集の際の注意点など metaデータはopenIVのEditから書き換えもできるが、Notepad++やVisual Studio Codeの使用をお勧めする。 (ダウンロードサイトに飛びます) また、metaデータは上記の通りゲームのオブジェクトや車のデータの核が書かれているため、1文字でも間違えると起動しなくなる可能性がある。 metaデータにミスがあるとゲームのロード中に突然デスクトップに戻され、LSPDFR関係なくゲームが起動しなくなる。 そのため書き換える作業をする際は絶対にバックアップを取っておこう。
https://w.atwiki.jp/mekagazira/pages/16.html
https://w.atwiki.jp/udk_tips/pages/23.html
概要 UDKのコンテンツには命名規則があります。これによりファイル名でソートしやすくなります。 テクスチャー 「T_Name」 マテリアル「M_Name」 スタティックオブジェクト「S_Name_」 スケルトンメッシュ「SK_Name」 サウンド「A_Name」 パーティクルシステム「P_Name」 アニメーションセット「K_Name」 ~~
https://w.atwiki.jp/mugenexploit/pages/33.html
ファイル名書式文字列攻撃 ファイル名にフォーマット指定子を使用することができるバグ。 %nによる任意コード実行の可能性を秘めている。 概要 "mugenw.log"にファイル名を出力する際にバグが発生するが、現状有効な活用事例がない。 活用できない主な理由として、winmugenはC99準拠であるため"$"が使えない事が挙げられる。 "$"が使えないことによって目的の位置までアドレスを進めるには膨大な量の指定子を用意する必要があり、更にこのバグでは引数アドレスの初期位置がファイル名の先頭付近であるため、ファイル名の文字数を増やせば増やすほど目的のアドレスへのオフセットが増加してしまうという悪循環が発生し、結果的に任意コードを実行しようと思うとファイルの文字数が255文字を超過してしまう。 検証記録 通常ファイル名に特殊文字やNullなどは含むことができないが、mugenの処理中にファイル名は一度Unicodeで出力してからUTF8に変換している。その残骸が一部残ることを利用して0x00XX00YYという形でのみNullを含んだバイト列を利用することが可能になる。 検証では0x004C0040へ任意の数値を書き込むことに成功した。
https://w.atwiki.jp/ooooasys/pages/12.html
勝手な推測 ファイルはヘッダ部とデータ部に分かれるだろう 昔のワープロなのでそんなに機能はないだろう。 文字ごとにプロパティを設定する訳じゃない。あってせいぜい行単位 2倍角とか3倍角とかあるかも 半角漢字とかもあるよね。扱いはどうしようか。 文字罫線だったような気がする 同じデータが2種類箇所にある可能性はあるよね あとここでは特に記載が無い限りbig endianとする。 未確定 C \Program Files\OASYS2002\Viewer\OASPROP\FMLBPQP.DLL がファイルを右クリックてプロパティをみたときに呼ばれる。これに文書のフォーマットの情報がすべて載っている。ということはこれを解析すればヘッダ情報が分かるだろう。OASYS1,2,3すべて同じファイルが呼ばれる。ここまでは分かった。 ヘッダは2ffまで 300からデータ ヘッダは000-0ff, 100-1ffで同様な組がある 2f24(/$)が行の前のスペースを表す---前インデント その次データがある 2f22(/")が改行を表す 改行の後を21(!)でpadding 正しくは1区1点の全角スペースを入れている 2f25(/%)が行の後のスペースを表す---後インデント 行の後に00(nul)でpadding(5個だがこれはレイアウトの桁数によりそう)= ここが違う。行の後に0001が来たら次の行の文字の修飾を表すことを示し、7Dまでを修飾として扱う。どのように扱われるかは解析中。 最後の改行の後にも完全に空白な行がデータとしてある。データとしては行単位で処理しており、最後の空白行でデータが最後という処理をしていそう 空白行の後に06ffまで0でpadding = 多分 0x300分ヘッダがあり、以降0x400ずつセグメントがある。 勘違いしていることに気がついた。完全に行指向のエディタとして考えなければならない 単位は2バイトごとの文字半角英数の後に全角文字を入力すると自動的にA0でpaddingされる = これはスペース20の7ビット目を立てたもの 英数一部の記号のみ半角単位で打てる。半角でできる記号は何か、全角の記号は何かを要調査 なんかラインプリンタにどのようにデータを流し込むかを考えていけばできそうな気がしてきた。 2バイトごとに読み込み0x0080との ANDをとる。もし trueなら ASCII falseならOASYS区点 なんか違ったな。1行分のデータ(桁数x2) byteを読む。次の5byte を読む。0x0000000000なら次の行が始まる。 0x0001000000なら装飾情報が入っているので続いた後1行分のデータ(桁数x2)を読み込む。その次に 0x7d0000の装飾情報終了文字があり、次の行が始まる。 データ・修飾方法の長さには前インデント、後インデントを含む 半角文字と全角文字で書式データの処理方法が異なるかもしれない。 全角文字の場合 1byte目の先頭bitが立っていたら修飾情報あり、無かったら修飾情報無し。(先頭bitを0にして修飾情報を加えても表示には反映されなかった) 修飾情報 0x8000 = 細下線 0x8338 = 点線下線 0x8339 = 太線下線 0x833A = 二重線下線 0x833B = 波線下線 0x8336 = 網掛け状下線 0x833F = 細下線付き黒丸傍点 0x8335 = 細下線付き句点型傍点 0x033F = 黒丸傍点 0x0335 = 句点型傍点 OASYS形式では細下線と傍点は同時につけられるが、それ以外の下線と傍点では下線が優先される。 網掛けとか取消線をつけると一気にヘッダが増える0x。これから考えると、文字を重ねる場合には、データフォーマットの 変更が行われると思われる。 ファイル形式 0x1ffまでがWindowsとかUNIX用に加えられた部分 0x200からがOASYSのフォーマットそのまま のような気がする。 確定っぽい 文字コード 文字コードについてはOASYS区点コードを参照 ヘッダー部 アドレス(サイズ) タイプ 内容 値の範囲 (範囲外の時の値) 備考 0x0204 (0x02) uword-be 文書の総ページ数 0 = uword = 0xffff 0x0206 ubyte 版数 0 = ubyte 100 (0) 0x0207 ubyte 書き込み保護 0 =ubyte =1 (0) 0 なし, 1 あり 0x0208 ubyte 1ページの行数 1 = ubyte = 254 (30) 0x020b (0x32) ubyte 題名 OASYS区点コードの文字列 0x023d ubyte 文字間隔 1 = ubyte =7 (1) 1 "3.81mm" 2 "5.08mm" (分岐あり) 3 "3.18mm" 4 "4.45mm" 5 "その他" 6 "定型" 7 "字間", インチ表示とか混ざっていてなんか処理をしている。sub_10002096 要再解析 0x023e ubyte 行間隔 ubyte ==4 だったら ubyte = 2 2 6.35mm 3 4.23mm 5 その他 6 8.89mm 7 定型 else 8.47mm , 定型は.OASにはなし 0x0248 ubyte 用紙の向き 1 = ubyte =2 0x025fを参照 0x025c ubyte 用紙サイズ 1 = ubyte = 10 1 A4 2 B4 3 A5 4 B5 5 その他 6 はがき 7 A3 8 B3 9 レター 10 リーガル 11 レジャー(.OASにはなし) 0x025d(0x02) uword-be 用紙サイズその他の時の縦(mm) 0x025f ubyte 用紙の向き 1 =ubyte =2 [0x025f]==[0x0248]の場合は横長, [0x025f]!=[0x0248]の場合は縦長 0x0260 (0x02) uword-be 上部余白 1 = uword-be = 0x3e7 (10) 上部余白か右側余白かは多分書く方向による。要再解析 0x0262 (0x02) uword-be 左側余白 1 = uword-be = 0x3e7 (10) 左側余白か下側余白かは多分書く方向による。要再解析 0x0275 ubyte 行内文字数 OASYSの書式設定では10-200 0x0283(0x02) uword-be 用紙サイズその他の時の横(mm) 0x02c0 ubyte 縦書き/横書き 0 = ubyte = 1 [0x0248]==1の場合--横書きのみ, [0x0248]==2の場合--0 印刷時のみ縦書き 1 縦書き 0x20d8 (0x05) ubyte[5] 更新日付(yymmddhhMM) sub_10004725関数で2000年問題の日付の処理をしている。要解析。2進化10進のデータの場合と16進のデータの場合がある。 0x20dd (0x05) ubyte[5] 作成日付(yymmddhhMM) sub_10004725関数で2000年問題の日付の処理をしている。要解析。2進化10進のデータの場合と16進のデータの場合がある。 0x0008 32byte 文書名 (EUCで記述) 最初の32byte分か? しかも半角文字が全角に変換される。 0x0208 1byte 行数 0x0274 1byte 行内文字数 0x0275 1byte 行内文字数 0x274と同じ。なぜか同じデータが2個 ????日時 = 作成か? 0x02d3 1byte 年(2桁) 0x02d4 1byte 月(1-12) 0x02d5 1byte 日(1-31) 0x02d6 1byte 時(1-24) 0x02d7 1byte 分(0-59) 更新日時 0x02d8 1byte 年(2桁) 0x02d9 1byte 月(1-12) 0x02da 1byte 日(1-31) 0x02db 1byte 時(1-24) 0x02dc 1byte 分(0-59) データの実装 解析 拡張子が .OAS = hObject+400h =2 .OA2 = hObject+400h = 3 .FMT = hObject+400h = 4 .OA3 = hObject+400h = 5 最初の8バイトを読み込む {Buffer[0],Buffer[1],Buffer[2],Buffer[3],var_64,var_63,var_62,var_61} Buffer[0] == 0xf0; Buffer[1] == 0xf2; がマジック //ここもうちょっと整理 switch (var_62) { case 0xf0 if (var_61 == 0xf0) { if (Buffer[3] == 0xd6 var_64 == 0xc1) { switch (var_63) { case 0xc6 var_62 = 0xf1; var_61 = 0xf1; [esi + 401 h] = 2; lDistanceToMove = 0x200 break; case 0xc5 var_62 = 0xf0; var_61 = 0xf5; [esi + 401 h] = 2; lDistanceToMove = 0x200 break; case 0xb8 var_62 = 0xf1; var_61 = 0xf2; [esi + 401 h] = 2; lDistanceToMove = 0x200; break; case 0xb7 var_62 = 0xf1; var_61 = 0xf3; [esi + 401 h] = 2; lDistanceToMove = 0x200; break; case 0xb3 var_62 = 0xf0; var_61 = 0xf0; [esi + 401 h] = 2; lDistanceToMove = 0x200; break; case 0xa5 var_62 = 0xf3; var_61 = 0xf1; [esi + 401 h] = 1; lDistanceToMove = 0x200; break; case 0xa3 var_62 = 0xf1; var_61 = 0xf5; [esi + 401 h] = 1; lDistanceToMove = 0x200; break; default var_62 = 0xf3; var_61 = 0xf1; [esi + 401 h] = 1; lDistanceToMove = 0x200; break; } break; } else { goto_error(); } } else { // to loc_1000510f if (var_61 = 0xf6 var_61 = 0xf9) { [esi + 401 h] = 2; lDistanceToMove = 0x200; break; } } // ここにbreakなし case 0xf1 if (var_61 = 0xf0 var_61 = 0xf3) { [esi + 401 h] = 2; lDistanceToMove = 0x200; break; } // ここにbreakなし case 0xf2 if (var_61 = 0xf1 var_61 = 0xf4) { [esi + 401 h] = 2; lDistanceToMove = 0x200; break; } // ここにbreakなし default [esi + 401 h] = 1; lDistanceToMove = 0x200; break; } 200h byte に飛ぶ hObjectに 400h byte読み込む var_Cを0クリア var_CにhObject 7D (27Dh) から4バイトコピーする hObject 88h から hObject 7D へ4バイトコピーする var_cから 88hへ4byteコピーする = i.e 27Dh と 288hの値を4byte分 swapする esp += 30h (スタックを30hbyte解放) hObjectをpushして call sub_1000483F sub_1000483Fの処理 ここで word の処理は signed, byteの処理はunsigned if(hObject[0] 1 || hObject[0] 16) { hObject[0] = 1;} if (hObject[1] 0x7D) { hObject[1] = 0;} if (hObject[2] 0x7C ) { hObject[2] = 4;} if (hObject[3] 1 || hObject[3] 0x7d) { hObject[3] = 0x2b; } if (hObject[6] 0x63 ) {hObject[6] = 0;} if (hObject[7] != 1) {hObject[7] = 0;} if (hObject[8] 1 || hObject[8] 0xfe) {hObject[8] = 0x1e;} if (hObject[9] 1 || hObject[9] 4) { hObject[9] = 1;} else if (hObject[9] == 0) {hObject[9] = 1;} 1の時のメモリ書き換えよりレジスタ比較の方が早くて最適化された? hObject[0x0a]からhObject[0x3c]はなし if( hObject[0x3d] 1 || hObject[0x3d] 7) { hObject[0x3d] = 1;} if( hObject[0x3e] 1 || hObject[0x3e] 7) { hObject[0x3e] = 1;} if( hObject[0x3e] == 4 ) { hObject[0x3e] = 2 }; hObject[0x3f]からhObject[0x40]はなし if( hObject[0x41] 1 || hObject[0x41] 4) { hObject[0x41] = 2 }; if( hObject[0x42]hObject[0x43] 0xfc19(-999) || hObject[0x42]hObject[0x43] 0x270f(9999) ) { hObject[0x42] = 0; hObject[0x43] = 1;} hObject[0x44] は複雑なので後で解析 if(hObject[0x45] 1 || hObject[0x45] 3) { hObject[0x45] = 3;} hObject[0x46], hObject[0x47]はなし if(hObject[0x48] != 2 ) {hObject[0x48] = 1;} if(hObject[0x49] 0x80){ hObject[0x49] = 0;} if(hObject[0x4A] 1 || hObject[0x4A] 4 ) { hObject[0x4A] = 1;} if(hObject[0x4B] 1 || hObject[0x4B} 3 ) { hObject[0x4B] = 1;} if(hObject[0x4d] != 2) {hObject[0x4d] = 1;} if(hObject[0x4f] != 2) {hObject[0x4f] = 1;} if(hObject[0x50] 1 || xObject[0x50] 3) {hObject[0x50] = 1;} if(hObject[0x52] != 1) {hObject[0x52] = 2;} if(hObject[0x53] != 2) {hObject[0x53] = 1;} if(hObject[0x55] 0x80) {hObject[0x55] = 0;} if(hObject[0x59] 2) {hObject[0x59] = 0;} if(hObject[0x5a] 1 || hObject[0x5a] 5) { hObject[0x5a] = 1;} if(hObject[0x5b] != 2) { hObject[0x5b] = 1;} if(hObject[0x5c] 1 || hObject[0x5c] 0x0a) { hObject[0x5c] = 1;} if( hObject[0x5d]hObject[0x5e] 0 || hObject[0x5d]hObject[0x5e] 0x270f (9999) ) { hObject[0x5d] = 2; hObject[0x5e] = 0x61;} なぜ609? if( hObject[0x5f] != 2) { hObject[0x5f] = 1;} if(hObject[0x60]hObject[0x61] 0 || hObject[0x60]hObject[0x61] 0x3e7 ) { hObject[0x60] = 0; hObject[0x61] = 0x0d;} if(hObject[0x62]hObject[0x63] 0 || hObject[0x62]hObject[0x63] 0x3e7 ) { hObject[0x62] = 0; hObject[0x63] = 0x0d;} (0x3e7 = 999) if(hObject[0x64]hObject[0x65] 0 || hObject[0x64]hObject[0x65] 0x3e7 ) { hObject[0x64] = 0; hObject[0x65] = 0x7f;} if(hObject[0x66]hObject[0x67] 0 || hObject[0x66]hObject[0x67] 0x3e7 ) { hObject[0x66] = 0; hObject[0x67] = 0x1b;} if(hObject[0x68]hObject[0x69] 0 || hObject[0x68]hObject[0x69] 0x3e7 ) { hObject[0x68] = 0; hObject[0x69] = 0x1b;} if(hObject[0x6a]hObject[0x6b] 0 || hObject[0x6a]hObject[0x6b] 0x3e7 ) { hObject[0x6a] = 0; hObject[0x6b] = 0x96;} (0x96 = 150) if(hObject[0x6c]hObject[0x6d] 0 || hObject[0x6c]hObject[0x6d] 0x3e7 ) { hObject[0x6c] = 0; hObject[0x6d] = 0x96;} (0x96 = 150) if(hObject[0x6e]hObject[0x6f] 0 || hObject[0x6e]hObject[0x6f] 0x3e7 ) { hObject[0x6e] = 0; hObject[0x6f] = 0x5A;} (0x5a = 90) if(hObject[0x70]hObject[0x71] 0 || hObject[0x70]hObject[0x71] 0x3e7 ) { hObject[0x70] = 0; hObject[0x71] = 5;} if(hObject[0x77] 2) {hObject[0x77] = 0;} if(hObject[0x78]hObject[0x79] 0 || hObject[0x78]hObject[0x79] 0x3e7 ) { hObject[0x78] = 0; hObject[0x79] = 0;} if(hObject[0x7a] 2) {hObject[0x7a] = 0;} hObject[0x7c]は複雑なので後で解析 if(hObject[0x7d] != 1) {hOjbect[0x7d] = 0;} if(hObject[0x7e] 7 ) {hObject[0x7e} = 0;} if(hObject[0x7f] != 1 ) {hObject[0x7f] = 0;} if(hObject[0x80] != 1 ) {hObject[0x80] = 0;} if(hObject[0x81] 3) {hObject[0x81] = 0;} if(hObject[0x82]hObject[0x83] 0 || hObject[0x82]hObject[0x83] 0x3e7 ) { hObject[0x82] = 0; hObject[0x83] = 0;} if(hObject[0x8c] 2) {hObject[0x8c] = 0;} if(hObject[0x8d] != 1) {hObject[0x8d] = 0;} if(hObject[0x8F]hObject[0x90] 0 || hObject[0x8F]hObject[0x90] 0x270f) {hObject[0x8f] = hObject[0x90] = 0;} (0x270f = 9999) if(hObject[0x91] != 1) {hObject[0x91] = 0;} if(hObject[0x92] != 2) {hObject[0x92] = 1;} if(hObject[0x93] 1 || hObject[0x93] 0xff) {hObject[0x93] = 1;} このケースよくわからない。なぜ hObject[0x93] 0xffの比較が必要か? if(hObject[0x94]hObject[0x95] 1 || hObject[0x94]hObject[0x95] 0x3e7 ) { hObject[0x94] = 0; hObject[0x95] = 1;} if(hObject[0x96] 1 || hObject[0x96] 0xff) {hObject[0x96] = 1;} このケースよくわからない if(hObject[0x97]hObject[0x98] 1 || hObject[0x97]hObject[0x98] 0x3e7 ) { hObject[0x97] = 0; hObject[0x98] = 1;} if(hObject[0x9b]! != 1) {hObject[0x9b] = 0;} if(hObject[0x9c]hObject[0x9d] 0 || hObject[0x9c]hObject[0x9d] 0x63 ) { hObject[0x9c] = hObject[0x9d] = 0;} if(hObject[0x9f] != 1) {hObject[0x9f] = 0;} if(hObject[0xa3] 2) {hObject[0xa3] = 0;} if(hObject[0xa4] != 1) {hObject[0xa4] =0;} if(hObject[0xa6] != 1) {hObject[0xa6] = 0;} if(hObject[0xa7] != 1) {hObject[0xa7] = 0;} if(hObject[0xa8] != 1) {hObject[0xa8] = 0;} if(hObject[0xa9] != 1) {hObject[0xa9] = 0;} if(hObject[0xaa] 1 || hObject[0xaa] 0x63) {hObject[0xaa] = 1;} if(hObject[0xab] 1 || hObject[0xab] 0x63) {hObject[0xab] = 1;} if(hObject[0xac] != 1) {hObject[0xac] = 0;} if(hObject[0xb1] 2) {hObject[0xb1] = 0;} if(hObject[0xb4] != 1) {hObject[0xb4] = 0;} if(hObject[0xb5] 3) {hObject[0xb5] = 0;} if(hObject[0xb6] 4) {hObject[0xb6] = 0;} if(hObject[0xb7] 3) {hObject[0xb7] = 0;} if(hObject[0xb8] != 1) {hObject[0xb8] = 0;} if(hObject[0xb9] 0x2d || hObject[0xb9] != 0xff) hObject[0xb9] = 0;} if(hObject[0xba] != 1) {hObject[0xba] = 0;} if(hObject[0xbb] 9) {hObject[0xbb] = 0 } if(hObject[0xbc] 9) {hObject[0xbc] = 0 } if(hObject[0xbd] != 1) {hObject[0xbd] = 0;} if(hObject[0xbe] 9) {hObject[0xbe] = 0 } if(hObject[0xbf] != 1) {hObject[0xbf] = 0;} if(hObject[0xc0] != 1) {hObject[0xc0] = 0;} if(hObject[0xc1]hObject[0xc2] 0 || hObject[0xc1]hObject[0xc2] 0x270f) {hObject[0xc1]=hObject[0xc2]=0} if(hObject[0xc3] 0x63) {hObject[0xc3]=0;} if(hObject[0xc4] != 1) {hObject[0xc4] = 0;} if(hObject[0xc5] != 1) {hObject[0xc5] = 0;} if(hObject[0xc6] != 1) {hObject[0xc6] = 0;} if(hObject[0xc7] 0xff ) {hObject[0xc7] = 0;} if(hObject[0xc8] 0xff ) {hObject[0xc8] = 0;} if(hObject[0xc9] 3) {hObject[0xc9] = 0;} if(hObject[0xca] != 1) {hObject[0xca] = 0;} if(hObject[0xcb] 7) {hObject[0xcb] = 0;} if(hObject[0xcc] 0xff) {hObject[0xcc] = 0;} return; とりあえず印刷形式タブまでは解析できた。不明な点がいくつかあるが。重複あるが下記にメモ 5e7c = 7090 = 7a3c = MSVCRT.dll_??2@YAPAXI@Z_name F100010bb = ローカルの関数 引数なし? L10009e98 のカウントを1増やすL10009e98 = 値を1増やしたり減らしたりしているので参照のカウンタL10007608 = L10007608 10007608 times 008h db 0 10007610 db 0,0,0,0,0,0,0,0, 0c0h,000h,000h,000h,000h,000h,000h,046h関数の戻り値は AL(8bit) AX(16bit) EAX (32bit)に入る 拡張子が .OAS = hObject+400h =2 .OA2 = hObject+400h = 3 .FMT = hObject+400h = 4 .OA3 = hObject+400h = 5 .OASの場合 ( i.e. [esi+400h] == 2)8byte読み込む最初の2byte = 0xf0f2Buffer[0] == 0xf0Buffer[1] == 0xf2Buffer[2] == Unspecified;switch (var_62) {case 0xf0 if( var_61 == 0xf0) {if(Buffer[3] == 0xd6 var_64 == 0xc1) {//ここは 10005094の処理を解析switch(var_63) {case 0xc6 var_62 = 0xf1;var_61 = 0xf1;[esi+401h] = 2;lDistanceToMove = 0x200 break;case 0xc5 var_62 = 0xf0;var_61 = 0xf5;[esi+401h] = 2;lDistanceToMove = 0x200 break;case 0xb8 var_62 = 0xf1;var_61 = 0xf2;[esi+401h] = 2;lDistanceToMove = 0x200;break;case 0xb7 var_62 = 0xf1;var_61 = 0xf3;[esi+401h] = 2;lDistanceToMove = 0x200;break;case 0xb3 var_62 = 0xf0;var_61 = 0xf0;[esi+401h] = 2;lDistanceToMove = 0x200;break;case 0xa5 var_62 = 0xf3;var_61 = 0xf1;[esi+401h] = 1;lDistanceToMove = 0x200;break;case 0xa3 var_62 = 0xf1;var_61 = 0xf5;[esi+401h] = 1;lDistanceToMove = 0x200;break;default var_62 = 0xf3;var_61 = 0xf1;[esi+401h] = 1;lDistanceToMove = 0x200;break;}break;} else {goto_error;}} else { // to loc_1000510fif( var_61 = 0xf6 var_61 = 0xf9 ) {[esi+401h] = 2;lDistanceToMove = 0x200 break;}}// ここにbreakなしcase 0xf1 if( var_61 = 0xf0 var_61 = 0xf3) {[esi+401h] = 2;lDistanceToMove = 0x200 break;}// ここにbreakなしcase 0xf2 if (var_61 = 0xf1 var_61 = 0xf4) {[esi+401h] = 2;lDistanceToMove = 0x200 break;}//ここにbreakなしdefault [esi+401h] = 1;lDistanceToMove = 0x200 break;}ここからfseekをする処理}3Dhの処理if [3dh] = 2 then arg_c=1if [3dh] = 3 then [8eh と 5ah の処理 arg_c= 7 分岐処理が沢山if [3dh] = 4 then arg_c = 3if [3dh] = 5 then arg_c = 4if [3dh] = 6 then arg_c = 5if [3dh] = 7 then arg_c = 6else arg_c = 0行間隔if [3eh] == 2 then arg_c = 1if [3eh] == 3 then arg_c = 0if [3eh] == 5 then arg_c = 5if [3eh] == 6 then arg_c = 3if [3eh] == 7 then arg_c = 4else arg_c = 2if[0x5c] == 5 その他if[0x5c] 0x8000 不明if[0x5c] = 0ch 不明[0x5f] 2 or 1[0x48] 2 or 1if [0x5f] ==2 [0x48] == 2 横長if [0x5f] ==2 [0x48] == 1 縦長if [0x5f] ==1 [0x48] == 2 縦長if [0x5f] ==1 [0x48] == 1 横長0x028e なんかのフラグif [0x8e] == 0x20 if [0x5a] ==0 || [0x5a] == 1 標準9ポイント if [0x5a] == 2 標準10.5ポイント if [0x5a] == 3 縮小 if [0x5a] == 4 (if [0xc3] == 9 標準9ポイント else その他の処理) if [0x5a] == 5 標準9ポイントendifif [0x8e] != 0x20 if [0x8e] == 0 || [0x8e] == 1 標準10.5ポイント if [0x8e] == 2 大文字 if [0x8e] == 3 縮小 if [0x8e] == 4 その他の処理 if [0x8e] == 5 標準9ポイント else その他の処理その他の処理の内容 [0xc3] ポイント数が入る [0xb9] 書体が入る 28通り、後で解析 [0x8e], [0xa5], [0xcb] ---- 20通り 縮小英文字の種類、後で解析 [0xca] 縮小文字の向き 1 横向き それ以外 縦向き(2文字単位) [0x77] 添え字の文字種 2 カタカナ それ以外 ひらがな [0x92] 添え字/欧文文字 1 欧文文字 それ以外 添え字数字===============================================禁則/揃え[0xa9] 字詰め範囲 1 行単位 それ以外 文書全体[0xa8] 制御記号の扱い 0 空白置き換え それ以外 詰める[0x7c] 罫線位置ずれ 下位2ビットでマスク 0 半角詰め/制御記号 1 制御記号のみ 2 なし[0xc9] 文字揃え 0 標準 1 下端[左端] 2 中央 3 上端[右端] それ以外 標準[0x4a] 禁則処理 0 なし 1 Aランク 2 Bランク 3 Cランク それ以外 なし = ここでarg_cに何かを入れている[0xc6] ぶら下げ禁則文字(ぶら下げがあるとき) 0 送り出し それ以外 ぶら下げ[0x7a] 英文禁則 0 なし 1 ワードラップ それ以外 ハイフネーション[0x9f] 登録縮小文字 0 禁則、英文禁則指定無効 1 禁則、英文禁則指定有効[0x7f] 禁則、英文均等 0 なし それ以外 あり[0xa4] 行末行頭空白数 0 半角空白1個対象 それ以外 半角空白2個対象===================================================印刷形式[0x41] 頁番号印刷 1 なし 2 頁 3 -頁- 4 頁/総ページ数 それ以外 頁[0x8f][0x90] word-be 総ページ数 0 文書のページ数に従う それ以外 itoaの結果[0x42][0x43] signed word-be 番号初期値[0x6e][0x6f] word-be 番号位置(左右) mm 印刷開始位置からの長さ[0x70][0x71] word-be 番号位置(上下) mm 用紙下端からの長さ[0x4b] 印刷形式 0 標準 1 袋とじ 2 中央空け それ以外 標準[0x4d] ページ番号付け 0 一箇所 1 2箇所(左右) 2 2箇所(上下)[0x6a][0x6b] word-be 右ページ開始位置(中央空けの場合) mm [0x48]==2と併せてみる[0x66][0x67] word-be 右ページ開始位置(袋とじの場合) 桁数 [0x48]==2と併せてみる[0x6c][0x6d] word-be ページ番号までの長さ(中央あけの場合) mm [0x48]==2と併せて見る[0x68][0x69] word-be ページ番号までの長さ(袋とじの場合)桁数 [0x48]==2と併せて見る[0xc7] 多段組印刷 0 なし 1 あり 1から9 が段数 1という値をとることはプログラム的には無い?[0xc8] 段組印刷位置 桁======================================================印刷情報[0x44]
https://w.atwiki.jp/okkk/pages/12.html
最近は着うたフルなんかも出ていますが、着信音として使用する場合にはやはり短めが良いですよね? ということで好きな部分をカットして行きます。 使用するソフト ◎ SoundEngine (Free) ○ Audacity (Free) ○ その他の音楽ファイル編集ソフト ※ ◎ オススメ ○ 使用可 上記の内1つだけDLすれば大丈夫です。 ココではSoundEngineを使ったやり方のみ説明致します。 インストールで躓く人はあんまりいないとは思いますが、念のためにインストールガイドです。
https://w.atwiki.jp/fsharpmaster/pages/35.html
スキャナが出力したPDFを、出力デバイスに合わせて変換しよう この記事はF# Advent Calender 2012の11日目(10個目)の記事です。ひとつ前の記事はyukitos22さんのTypeProvider関連の丁寧な記事で、これを書き終わったら手を動かして試してみたいところです。 さて、主催者様の「実用的な」というお題を僕はそのまま字面通りとってしまい、「仕事以外に、F#で実用的なプログラムを書いたっけ・・・」などと回想した結果ひねり出したのがこのネタです。 いささか「実用」というよりは「オレ用」という感じもしなくはないのですが・・・ 僕が富士通の名作ドキュメントスキャナS1500を購入したのは、ひとえにオライリーの「プログラミング F#」や技評の「実践F#関数型プログラミング入門」を持ち歩くのが辛かったからである、と言っていいほど僕の中でF#とS1500のつながりは実は深く、S1500でスキャンしたデータをSONY Readerで持ち歩くための変換プログラムがF#で書かれたこともまた必然と言っていいと思います。 そんなわけで、このプログラムは1年前に書いたもので、今回の記事のためにチョコチョコ直しましたが色々とアレなところがある点についてはご容赦ください。 ちなみにPDFの操作は独自実装といいたいところですが、残念ながらiTextSharpを使用しています。開発環境はVS2008です。まだVS2012買ってないんですすみません。 実行にはiTextSharpが必要なため、ここからダウンロードしてください。最新の5.3.3で動作確認しています。 機能と使い方 指定したPDFファイル(S-1500が出力したもの)から、JPEGファイルを取り出して特定のディレクトリに保存する(上のテキストボックスに元PDFのパスを入れて「PDF解体」)。出力先は「c \temp」下になります。 保存したページを画面に表示し、トリミング範囲を指定する。トリミング範囲は、左のページの左上、右下をクリックしてオレンジ色の枠を動かす。ドラッグでなく2か所クリック。右のページも同じトリミングで枠が出る。ページを送って、他のページで文字が枠からはみ出ないことを確認する。 画面サイズ(右と下のテキストボックスで指定)を指定するその際、画面いっぱいになるよう画像を縮小するか、比を変えずに天地左右に空白を入れるかも指定できる。 最後にガンマ補正のパラメータを左下のスライダーで指定し、「PDF作成」ボタンで少々待てば出力先に新しいPDFが作成される。 特筆すべき部分 全ソースがここで公開されている!(UIはC#で、コアはF#で、unsafeなところはまたC#で) だからもう自分の好きなようにいじり放題。機能追加も変更も思いのまま。ただしF#erに限る。 既存の補正ソフトがどれも「帯に短し・・・」と感じられる方は是非! ソースの見どころ? このプログラムはいろんなサンプルになっていると思います。 F#からiTextSharpを呼んでJpegを取り出す iTextSharpをF#から呼んで利用するサンプルは、今のところ日本語では見当たらないようなので、ごく部分的ではありますが紹介します。 C#からdelegateをF#側に渡し、コールバックして画面の更新を行う C#からF#の関数を呼び出すこと自体には何ら難しいことはありませんが、作業の進捗を画面に表示するため、C#からクロージャを一緒に渡してそれをF#から呼びだす方法を解説します。 この際、画面の更新はUIスレッドにしかできない、というルールを回避するための方法を例示します。 複数ページの処理をマルチコアで分散して処理 PDFファイルからイメージを取り出す処理や、複数のイメージにガンマ補正をかけたりする処理は、並行に動かしても何ら差支えがありません。こういう処理をマルチコアに分散して、全体的な処理速度を上げる方法を例示してみます。 F#からC#の関数を読んでunsafeな処理(ガンマ補正)を行う F#は僕の知る限りunsafeな処理を自分ではできません。そのため、C#で作成したライブラリに処理を託します。 F#からiTextSharpを呼んでJpegを取り出す こんな流れで進んでいきます。 ファイル名をPdfReaderに与えて、PdfReaderオブジェクトを作成 let ExtractOperation (msgcb msgCallback) (endcb endCallback) (sourcePdf string) outputPath = createDirectory outputPath let pdf = new PdfReader(sourcePdf) List.iter (OnePageFrom msgcb outputPath pdf) [1..pdf.NumberOfPages] pdfオブジェクトにページ番号を与えて、ページごとのPdfDictionaryオブジェクトを取得 let OnePageFrom (msgcb msgCallback) outputPath (pdf PdfReader) (page int) = let pg = pdf.GetPageN(page) getImages outputPath pg pdf page PdfDictionaryからリソースとxobjを取得 let getImages outputPath (dict PdfDictionary) (doc PdfReader) page = let res = PdfReader.GetPdfObject(dict.Get(PdfName.RESOURCES)) ? PdfDictionary let xobj = PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT)) ? PdfDictionary getPdfObjects xobj doc | Seq.iter (saveImage outputPath page) xobjからキーを列挙し、そのキーごとにxobjからPdfObjectを取り出し、そのサブタイプがPdfName.IMAGEであるものだけを列挙する。 let getImage (doc PdfReader) (theObj PdfObject) = let tg = PdfReader.GetPdfObject(theObj) ? PdfDictionary let subtype = PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE)) ? PdfName if PdfName.IMAGE.Equals(subtype) then let xrefIdx = (theObj ? PRIndirectReference).Number let pdfObj = doc.GetPdfObject(xrefIdx) let str = pdfObj ? PdfStream let filter = tg.Get(PdfName.FILTER).ToString() match filter with | "/FlateDecode" - None | _ - Some(PdfReader.GetStreamBytesRaw(str ? PRStream)) else None let getPdfObjects (xobj PdfDictionary) (doc PdfReader) = seq { match xobj with | null - () | xobj - for key in xobj.Keys do let theObj = xobj.Get(key) if theObj.IsIndirect() then yield getImage doc theObj } 取り出すことができれば、それをbyteのストリームに見立てファイルに保存するだけです。 let parms = new System.Drawing.Imaging.EncoderParameters(1) parms.Param.[0] - new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, byte 12) let saveImage outputPath pageNumber (img byte[] option) = match img with | None - () | Some image - use memStream = new System.IO.MemoryStream(image) memStream.Position - 0L use img = System.Drawing.Image.FromStream(memStream) let path = System.IO.Path.Combine(outputPath, System.String.Format(tempFileFormat, pageNumber, 1)) match jpegEncoder with | None - () | Some enc - img.Save(path, enc, parms) 逆にF#からiTextSharpを呼んでPDFを作成し、Jpegごとにページを作って貼り込む まず、最初に用紙サイズとマージンを指定してDocumentを作成し、それとファイル名を引数にPdfWriterオブジェクトを作成してそれを開きます。 let CreatePdf outputPath aspectRatio numOfPage = let margin = 0.0f let document = new Document(new iTextSharp.text.Rectangle(0.0f, 0.0f, PageSize.A4.Width, PageSize.A4.Width * aspectRatio), margin, margin, margin, margin) PdfWriter.GetInstance(document, new System.IO.FileStream(outputPath, System.IO.FileMode.Create)) | ignore document.Open () List.iter (addOnePage document aspectRatio) [1..numOfPage] document.Close(); 次に、JpegファイルごとにImageオブジェクトを作成し、位置と大きさを設定してdocumentにAddしたのち、NewPageします。これで1ページできます。これを最後のページまで繰り返すだけです。 let addOnePage (document Document) aspectRatio pageNum = let path = System.IO.Path.Combine(effectedTempPath, System.String.Format(tempFileFormat, pageNum, 1)) let jpeg = iTextSharp.text.Image.GetInstance(path) jpeg.SetAbsolutePosition(0.0f, 0.0f) jpeg.ScaleToFit(PageSize.A4.Width, PageSize.A4.Width * aspectRatio) document.Add jpeg | ignore document.NewPage() | ignore 意外に簡単ですね。 確か海外のどっかのサイトに乗っていたC#のサンプルをF#に移植しただけではなかったかと思います。 ちょっとignoreが目立つのは、僕が手を抜いていると考えてもらっていいです。あくまで「オレ用」ですんで。 C#からdelegateをF#側に渡し、コールバックして画面の更新を行う と、ここまで書いて気が付いたのですが、この件については以前にここで書いていました。 これより細かくここで書くのはちょっと無理な気がするので、こちらを参照してください。これと同じことをこのプログラムはやっています。 具体的には、進行度をメッセージするメッセージコールバックのdelegateと、終了をメッセージするdelegateをF#の関数に渡して、それをF#の中から随時Invokeしています。 C#側のコード PDFConvertLib.ExtractImagesFromPDF( delegate(string msg){ var deleg = new MessageDelegate(ExtractImageMsg); var ret = this.BeginInvoke(deleg, new object[] {msg}); }, delegate() { var deleg = new EndDelegate(ExtractImageEndOperation); var ret = this.BeginInvoke(deleg, new object[]{}); }, filePath.Text, PDFConvertLib.outputTempPath ); F#側のコード let OnePageFrom (msgcb msgCallback) outputPath (pdf PdfReader) (page int) = let pg = pdf.GetPageN(page) getImages outputPath pg pdf page sprintf "%A %d" pdf page | msgcb.Invoke // ← ココで呼びだし! let ExtractOperation (msgcb msgCallback) (endcb endCallback) (sourcePdf string) outputPath = async { createDirectory outputPath let pdf = new PdfReader(sourcePdf) [1..numberOfThreads] | List.map (ThreadRoundRobbin (OnePageFrom msgcb outputPath pdf) pdf.NumberOfPages numberOfThreads) | Async.Parallel | Async.RunSynchronously | ignore endcb.Invoke () // ← ココで呼びだし! } let ExtractImagesFromPDF (msgcb msgCallback) (endcb endCallback) (sourcePdf string) outputPath = ExtractOperation msgcb endcb sourcePdf outputPath | Async.Start | ignore 呼び出されるコードは、asyncで囲ってAsync.Startしないと別スレッドにならないため、いくら中でコールバックしても実際の画面更新はすべてすっかり終わってからになってしまいます。 複数ページの処理をマルチコアで分散して処理 C#の方も色々機能強化されて非同期処理がだいぶ得意になっていますが、それでも記述の自由さではF#に一日の長があります。 上にも書いてあるように、PDFからイメージを取り出して保存したり、取り出した画像にエフェクトをかけたりする作業はページ単位で独立しているため、並列動作が可能です。 このプログラムは当初シリアルに処理していますが、最後になってマルチコアを有効利用するように書き換えました。それが以下の部分です。 順次処理 let ExtractOperation (msgcb msgCallback) (endcb endCallback) (sourcePdf string) outputPath = async { createDirectory outputPath let pdf = new PdfReader(sourcePdf) List.iter (OnePageFrom msgcb outputPath pdf) [1..pdf.NumberOfPages] endcb.Invoke () } 並列化 let ThreadRoundRobbin theMethod max cntThread n = async { List.iter theMethod [n..cntThread..max] } let ExtractOperation (msgcb msgCallback) (endcb endCallback) (sourcePdf string) outputPath = async { createDirectory outputPath let pdf = new PdfReader(sourcePdf) [1..numberOfThreads] | List.map (ThreadRoundRobbin (OnePageFrom msgcb outputPath pdf) pdf.NumberOfPages numberOfThreads) | Async.Parallel | Async.RunSynchronously | ignore endcb.Invoke () } ThreadRoundRobbinは、ページごとに処理を指定数のスレッドに振り分ける関数です。スレッド数が4なら、最初にスレッドにはページ1,5,9,13...が、二つ目には2,6,10.14...が、三つめには3,7,11,15...が、四つ目には4,8,12,16...が割り振られ、それがAsync.Parallelで並列に動作し、Async.RunSynchronouslyですべての処理の終了を待ってendcb.Invoke(終了通知処理)を呼び出すようになっています。 今回はこんな方法をとったのですが、何も考えずに全ページをasyncしてもページ数が少なければそれなりに動きます。ただ、あまりページが多いとエラーになるようです。 F#からC#の関数を読んでunsafeな処理(ガンマ補正)を行う C#でFastBitmapなるクラスを作り、最初にガンマ値を与えて補正テーブルを作成してから、ビットマップごとにピクセル単位でをかけています。去年どこかで見たソースそのままだったような・・・ そんなわけなのでここでは掲載しませんが、興味がある方はソースを覗いてみてください。 と思ったら、.Netの機能でガンマ補正ってかけられるんですね・・・トホホ。しかも1.1からあるみたいだし。去年何を調べたんだ。 ImageAttributes.SetGamma 終わりに という具合でざっくり説明してきましたが「全部C#でかける」とか言わないでこのF#の濃密なソースを楽しんでもらえれば幸いです。 ソースはとバイナリはこのページ最下部の添付ファイルからダウンロード(S1500PDfConverter.zip)できますが、後日Githubにもあげようと思っています。そしたらみなさんで好きなように機能拡張してください。僕も使いますので。 サポート すみません。2013年2月24日以前のソースでは「C \temp\pdfeffected」ディレクトリをプログラム内部で作っていなかったため、このディレクトリがないとPDF作成時に落ちてしまいます。最新版をダウンロードしなおすか、このディレクトリをあらかじめ作成しておいてください。m(_ _)m (文責:片山 功士 2012/12/11) 今日: - 人 昨日: - 人 トータル: - 人
https://w.atwiki.jp/kimikage/pages/41.html
結合バッチを作ってみました。 万が一使用する人がいたとしたら、自己責任で使用してください。 当バッチを使って起きた問題に対して、僕は一切責任を負いません。 join.bat @ECHO OFF ECHO ■■■■■■■■■■■■■ ECHO ■【ファイル結合バッチ】■ ECHO ■■■■■■■■■■■■■ REM ****************************************************** REM *【説明】 * REM * 分割されたファイルを結合します。 * REM * 拡張子が、".001、.002、…"、または、".aa、.ab、…" * REM * であるファイルをCOPYコマンドを使用して結合します。 * REM ****************************************************** REM ********************************************************************************* REM *【使用方法】 * REM * ①結合したいファイルを当バッチファイルと同じフォルダに配置します。 * REM * ②結合したいファイルを選択し、当バッチファイルにドラッグアンドドロップします。* REM * ③メッセージにしたがって、ファイルを結合します。 * REM ********************************************************************************* REM ---バッチファイルのフォルダに移動------------------------- CD /D %~dp0 REM ---一時ファイル名と結合先ファイル名の宣言----------------- SET tmpfilelist=join.tmp.list.txt SET tmpfilesort=join.tmp.sort.txt SET outfname=%~n1 SET FCNT=0 REM ---ファイルの存在チェック--------------------------------- IF EXIST "%tmpfilelist%" ( CALL ERROR "0" %tmpfilelist% GOTO END ) IF EXIST "%tmpfilesort%" ( CALL ERROR "0" %tmpfilesort% GOTO END ) IF EXIST "%outfname%" ( CALL ERROR "1" %outfname% GOTO END ) REM ---マージ用にファイル名をソートしてファイルに書き出し----- ECHO; ECHO ■【結合元ファイル一覧】 TYPE nul "%tmpfilelist%" FOR %%i IN (%*) DO ( IF "%%~dpi" NEQ "%~dp0" ( CALL ERROR "2" %%i GOTO END ) IF NOT EXIST "%%~nxi\" ( ECHO %%~nxi "%tmpfilelist%" ECHO ■ %%~nxi SET /A FCNT+=1 ) ) REM ---結合ファイル数のチェック------------------------------- IF %FCNT% LSS 2 ( CALL ERROR "3" GOTO END ) REM ---結合の確認メッセージ----------------------------------- ECHO; ECHO ■【結合先ファイル】 ECHO ■ %outfname% ECHO ■に【結合元ファイル一覧】のファイルを結合します。 SET /P input=■結合してもよろしいですか?(はい:Y、いいえ:N): IF /I "%input%" NEQ "y" ( ECHO ■処理を中断します。 CALL DELTMP GOTO END ) REM ---結合処理----------------------------------------------- ECHO; ECHO ■結合処理を開始しました。 SORT "%tmpfilelist%" "%tmpfilesort%" SET CNT=0 FOR /F "delims=" %%i IN (%tmpfilesort%) DO ( CALL JOIN "%%i" ) CALL DELTMP ECHO ■結合処理が完了しました。 GOTO END REM ---エラー処理--------------------------------------------- ERROR ECHO; ECHO ■!!!エラー!!! IF %1 EQU "0" ( REM 一時ファイルの存在チェックエラー ECHO ■【一時ファイル】 ECHO ■ %2 ECHO ■を削除してください。 ) ELSE IF %1 EQU "1" ( REM 結合先ファイルの存在チェックエラー ECHO ■【結合先ファイル】 ECHO ■ %2 ECHO ■が既に存在します。 ) ELSE IF %1 EQU "2" ( REM 結合元ファイルの配置エラー ECHO ■【結合元ファイル】 ECHO ■ %2 ECHO ■をバッチファイルと同じフォルダに配置してください。 CALL DELTMP ) ELSE IF %1 EQU "3" ( REM ファイル数が2つより少ない ECHO ■ 結合したいファイルを2つ以上選択し、 ECHO ■ 当バッチファイルにドラッグ&ドロップしてください。 CALL DELTMP ) ECHO ■処理を中断します。 GOTO EOF REM ---一時ファイルの削除処理--------------------------------- DELTMP IF EXIST "%tmpfilelist%" ( DEL "%tmpfilelist%" ) IF EXIST "%tmpfilesort%" ( DEL "%tmpfilesort%" ) GOTO EOF REM ---結合処理----------------------------------------------- JOIN SET /A CNT+=1 ECHO ■%CNT%つめのファイルを結合中 IF %CNT% EQU 1 ( COPY /B "%~nx1" "%outfname%" ) ELSE ( COPY /B "%outfname%" + "%~nx1" ) GOTO EOF REM ---終了処理----------------------------------------------- END ECHO; ECHO ■処理が完了しました。 PAUSE