| 1 | // SoftEther UT-VPN SourceCode | 
|---|
| 2 | //  | 
|---|
| 3 | // Copyright (C) 2004-2010 SoftEther Corporation. | 
|---|
| 4 | // Copyright (C) 2004-2010 University of Tsukuba, Japan. | 
|---|
| 5 | // Copyright (C) 2003-2010 Daiyuu Nobori. | 
|---|
| 6 | // All Rights Reserved. | 
|---|
| 7 | //  | 
|---|
| 8 | // http://utvpn.tsukuba.ac.jp/ | 
|---|
| 9 | //  | 
|---|
| 10 | // This program is free software; you can redistribute it and/or | 
|---|
| 11 | // modify it under the terms of the GNU General Public License | 
|---|
| 12 | // version 2 as published by the Free Software Foundation. | 
|---|
| 13 | //  | 
|---|
| 14 | // This program is distributed in the hope that it will be useful, | 
|---|
| 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
|---|
| 17 | // GNU General Public License for more details. | 
|---|
| 18 | //  | 
|---|
| 19 | // You should have received a copy of the GNU General Public License version 2 | 
|---|
| 20 | // along with this program; if not, write to the Free Software | 
|---|
| 21 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 
|---|
| 22 | //  | 
|---|
| 23 | // このファイルは GPL バージョン 2 ライセンスで公開されています。 | 
|---|
| 24 | // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布 | 
|---|
| 25 | // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示 | 
|---|
| 26 | // を除去することはできません。改変した著作物を配布する場合は、改変実施者の | 
|---|
| 27 | // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。 | 
|---|
| 28 | //  | 
|---|
| 29 | // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の | 
|---|
| 30 | // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ ) | 
|---|
| 31 | // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって | 
|---|
| 32 | // ホストされています。 | 
|---|
| 33 | // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、 | 
|---|
| 34 | // および、試験または研究のために利用が行われることを想定して配布 | 
|---|
| 35 | // しています。 | 
|---|
| 36 | // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に | 
|---|
| 37 | // あります。 | 
|---|
| 38 | // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード | 
|---|
| 39 | // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して | 
|---|
| 40 | // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して | 
|---|
| 41 | // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース | 
|---|
| 42 | // に組み込みさせていただきます。 | 
|---|
| 43 | //  | 
|---|
| 44 | // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する | 
|---|
| 45 | // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。 | 
|---|
| 46 | //  | 
|---|
| 47 | // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社 | 
|---|
| 48 | // (SoftEther Corporation) およびその他の著作権保持者が保有しています。 | 
|---|
| 49 | // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの | 
|---|
| 50 | // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意 | 
|---|
| 51 | // ください。 | 
|---|
| 52 | //  | 
|---|
| 53 | // お願い: どのような通信ソフトウェアにも通常は必ず未発見の | 
|---|
| 54 | // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、 | 
|---|
| 55 | // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの | 
|---|
| 56 | // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社 | 
|---|
| 57 | // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、 | 
|---|
| 58 | // 公益保護にご協力いただきますようお願い申し上げます。 | 
|---|
| 59 | //  | 
|---|
| 60 | // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を | 
|---|
| 61 | // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客 | 
|---|
| 62 | // を保護するための努力を行います。 | 
|---|
| 63 | //  | 
|---|
| 64 | // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/ | 
|---|
| 65 | // 日本国内の脆弱性情報届出受付公的機関: | 
|---|
| 66 | //         独立行政法人 情報処理推進機構 | 
|---|
| 67 | //         http://www.ipa.go.jp/security/vuln/report/ | 
|---|
| 68 | //  | 
|---|
| 69 | // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。 | 
|---|
| 70 | // 連絡先: http://www.softether.co.jp/jp/contact/ | 
|---|
| 71 |  | 
|---|
| 72 | // ----------------------------------------------- | 
|---|
| 73 | // [ChangeLog] | 
|---|
| 74 | // 2010.05.20 | 
|---|
| 75 | //  新規リリース by SoftEther | 
|---|
| 76 | // ----------------------------------------------- | 
|---|
| 77 |  | 
|---|
| 78 | // Cfg.c | 
|---|
| 79 | // 設定情報操作モジュール | 
|---|
| 80 |  | 
|---|
| 81 | #define CFG_C | 
|---|
| 82 |  | 
|---|
| 83 | #include <stdio.h> | 
|---|
| 84 | #include <stdlib.h> | 
|---|
| 85 | #include <string.h> | 
|---|
| 86 | #include <wchar.h> | 
|---|
| 87 | #include <stdarg.h> | 
|---|
| 88 | #include <time.h> | 
|---|
| 89 | #include <errno.h> | 
|---|
| 90 | #include <Mayaqua/Mayaqua.h> | 
|---|
| 91 |  | 
|---|
| 92 | // 設定ファイルのバックアップの作成 | 
|---|
| 93 | void BackupCfg(FOLDER *f, char *original) | 
|---|
| 94 | { | 
|---|
| 95 |     wchar_t *original_w = CopyStrToUni(original); | 
|---|
| 96 |  | 
|---|
| 97 |     BackupCfgW(f, original_w); | 
|---|
| 98 |  | 
|---|
| 99 |     Free(original_w); | 
|---|
| 100 | } | 
|---|
| 101 | void BackupCfgW(FOLDER *f, wchar_t *original) | 
|---|
| 102 | { | 
|---|
| 103 |     wchar_t dirname[MAX_PATH]; | 
|---|
| 104 |     wchar_t filename[MAX_PATH]; | 
|---|
| 105 |     wchar_t fullpath[MAX_PATH]; | 
|---|
| 106 |     SYSTEMTIME st; | 
|---|
| 107 |     // 引数チェック | 
|---|
| 108 |     if (f == NULL || filename == NULL) | 
|---|
| 109 |     { | 
|---|
| 110 |         return; | 
|---|
| 111 |     } | 
|---|
| 112 |  | 
|---|
| 113 |     // ディレクトリ名を決定 | 
|---|
| 114 |     UniFormat(dirname, sizeof(dirname), L"@backup.%s", original[0] == L'@' ? original + 1 : original); | 
|---|
| 115 |  | 
|---|
| 116 |     // ファイル名を決定 | 
|---|
| 117 |     LocalTime(&st); | 
|---|
| 118 |     UniFormat(filename, sizeof(filename), L"%04u%02u%02u%02u_%s", | 
|---|
| 119 |         st.wYear, st.wMonth, st.wDay, st.wHour, original[0] == L'@' ? original + 1 : original); | 
|---|
| 120 |  | 
|---|
| 121 |     // このファイル名が存在するかどうかチェックする | 
|---|
| 122 |     if (IsFileExistsW(filename)) | 
|---|
| 123 |     { | 
|---|
| 124 |         return; | 
|---|
| 125 |     } | 
|---|
| 126 |  | 
|---|
| 127 |     // ディレクトリ作成 | 
|---|
| 128 |     MakeDirW(dirname); | 
|---|
| 129 |  | 
|---|
| 130 |     // ファイル保存 | 
|---|
| 131 |     UniFormat(fullpath, sizeof(fullpath), L"%s/%s", dirname, filename); | 
|---|
| 132 |     CfgSaveW(f, fullpath); | 
|---|
| 133 | } | 
|---|
| 134 |  | 
|---|
| 135 | // 設定ファイル R/W を閉じる | 
|---|
| 136 | void FreeCfgRw(CFG_RW *rw) | 
|---|
| 137 | { | 
|---|
| 138 |     // 引数チェック | 
|---|
| 139 |     if (rw == NULL) | 
|---|
| 140 |     { | 
|---|
| 141 |         return; | 
|---|
| 142 |     } | 
|---|
| 143 |  | 
|---|
| 144 |     if (rw->Io != NULL) | 
|---|
| 145 |     { | 
|---|
| 146 |         FileClose(rw->Io); | 
|---|
| 147 |     } | 
|---|
| 148 |  | 
|---|
| 149 |     DeleteLock(rw->lock); | 
|---|
| 150 |     Free(rw->FileNameW); | 
|---|
| 151 |     Free(rw->FileName); | 
|---|
| 152 |     Free(rw); | 
|---|
| 153 | } | 
|---|
| 154 |  | 
|---|
| 155 | // 設定ファイルの書き込み | 
|---|
| 156 | UINT SaveCfgRw(CFG_RW *rw, FOLDER *f) | 
|---|
| 157 | { | 
|---|
| 158 |     UINT ret = 0; | 
|---|
| 159 |     // 引数チェック | 
|---|
| 160 |     if (rw == NULL || f == NULL) | 
|---|
| 161 |     { | 
|---|
| 162 |         return 0; | 
|---|
| 163 |     } | 
|---|
| 164 |  | 
|---|
| 165 |     Lock(rw->lock); | 
|---|
| 166 |     { | 
|---|
| 167 |         if (rw->Io != NULL) | 
|---|
| 168 |         { | 
|---|
| 169 |             FileClose(rw->Io); | 
|---|
| 170 |             rw->Io = NULL; | 
|---|
| 171 |         } | 
|---|
| 172 |  | 
|---|
| 173 |         if (CfgSaveExW2(rw, f, rw->FileNameW, &ret)) | 
|---|
| 174 |         { | 
|---|
| 175 |             if (rw->DontBackup == false) | 
|---|
| 176 |             { | 
|---|
| 177 |                 BackupCfgW(f, rw->FileNameW); | 
|---|
| 178 |             } | 
|---|
| 179 |         } | 
|---|
| 180 |         else | 
|---|
| 181 |         { | 
|---|
| 182 |             ret = 0; | 
|---|
| 183 |         } | 
|---|
| 184 |  | 
|---|
| 185 |         rw->Io = FileOpenW(rw->FileNameW, false); | 
|---|
| 186 |     } | 
|---|
| 187 |     Unlock(rw->lock); | 
|---|
| 188 |  | 
|---|
| 189 |     return ret; | 
|---|
| 190 | } | 
|---|
| 191 |  | 
|---|
| 192 | // 設定ファイル R/W の作成 | 
|---|
| 193 | CFG_RW *NewCfgRw(FOLDER **root, char *cfg_name) | 
|---|
| 194 | { | 
|---|
| 195 |     return NewCfgRwEx(root, cfg_name, false); | 
|---|
| 196 | } | 
|---|
| 197 | CFG_RW *NewCfgRwW(FOLDER **root, wchar_t *cfg_name) | 
|---|
| 198 | { | 
|---|
| 199 |     return NewCfgRwExW(root, cfg_name, false); | 
|---|
| 200 | } | 
|---|
| 201 | CFG_RW *NewCfgRwEx(FOLDER **root, char *cfg_name, bool dont_backup) | 
|---|
| 202 | { | 
|---|
| 203 |     wchar_t *cfg_name_w = CopyStrToUni(cfg_name); | 
|---|
| 204 |     CFG_RW *ret = NewCfgRwExW(root, cfg_name_w, dont_backup); | 
|---|
| 205 |  | 
|---|
| 206 |     Free(cfg_name_w); | 
|---|
| 207 |  | 
|---|
| 208 |     return ret; | 
|---|
| 209 | } | 
|---|
| 210 | CFG_RW *NewCfgRwExW(FOLDER **root, wchar_t *cfg_name, bool dont_backup) | 
|---|
| 211 | { | 
|---|
| 212 |     CFG_RW *rw; | 
|---|
| 213 |     FOLDER *f; | 
|---|
| 214 |     // 引数チェック | 
|---|
| 215 |     if (cfg_name == NULL || root == NULL) | 
|---|
| 216 |     { | 
|---|
| 217 |         return NULL; | 
|---|
| 218 |     } | 
|---|
| 219 |  | 
|---|
| 220 |     f = CfgReadW(cfg_name); | 
|---|
| 221 |     if (f == NULL) | 
|---|
| 222 |     { | 
|---|
| 223 |         rw = ZeroMalloc(sizeof(CFG_RW)); | 
|---|
| 224 |         rw->lock = NewLock(); | 
|---|
| 225 |         rw->FileNameW = CopyUniStr(cfg_name); | 
|---|
| 226 |         rw->FileName = CopyUniToStr(cfg_name); | 
|---|
| 227 |         rw->Io = FileCreateW(cfg_name); | 
|---|
| 228 |         *root = NULL; | 
|---|
| 229 |         rw->DontBackup = dont_backup; | 
|---|
| 230 |  | 
|---|
| 231 |         return rw; | 
|---|
| 232 |     } | 
|---|
| 233 |  | 
|---|
| 234 |     rw = ZeroMalloc(sizeof(CFG_RW)); | 
|---|
| 235 |     rw->FileNameW = CopyUniStr(cfg_name); | 
|---|
| 236 |     rw->FileName = CopyUniToStr(cfg_name); | 
|---|
| 237 |     rw->Io = FileOpenW(cfg_name, false); | 
|---|
| 238 |     rw->lock = NewLock(); | 
|---|
| 239 |  | 
|---|
| 240 |     *root = f; | 
|---|
| 241 |  | 
|---|
| 242 |     rw->DontBackup = dont_backup; | 
|---|
| 243 |  | 
|---|
| 244 |     return rw; | 
|---|
| 245 | } | 
|---|
| 246 |  | 
|---|
| 247 | // ファイルをコピーする | 
|---|
| 248 | bool FileCopy(char *src, char *dst) | 
|---|
| 249 | { | 
|---|
| 250 |     BUF *b; | 
|---|
| 251 |     bool ret = false; | 
|---|
| 252 |     // 引数チェック | 
|---|
| 253 |     if (src == NULL || dst == NULL) | 
|---|
| 254 |     { | 
|---|
| 255 |         return false; | 
|---|
| 256 |     } | 
|---|
| 257 |  | 
|---|
| 258 |     b = ReadDump(src); | 
|---|
| 259 |     if (b == NULL) | 
|---|
| 260 |     { | 
|---|
| 261 |         return false; | 
|---|
| 262 |     } | 
|---|
| 263 |  | 
|---|
| 264 |     SeekBuf(b, 0, 0); | 
|---|
| 265 |  | 
|---|
| 266 |     ret = DumpBuf(b, dst); | 
|---|
| 267 |  | 
|---|
| 268 |     FreeBuf(b); | 
|---|
| 269 |  | 
|---|
| 270 |     return ret; | 
|---|
| 271 | } | 
|---|
| 272 | bool FileCopyW(wchar_t *src, wchar_t *dst) | 
|---|
| 273 | { | 
|---|
| 274 |     BUF *b; | 
|---|
| 275 |     bool ret = false; | 
|---|
| 276 |     // 引数チェック | 
|---|
| 277 |     if (src == NULL || dst == NULL) | 
|---|
| 278 |     { | 
|---|
| 279 |         return false; | 
|---|
| 280 |     } | 
|---|
| 281 |  | 
|---|
| 282 |     b = ReadDumpW(src); | 
|---|
| 283 |     if (b == NULL) | 
|---|
| 284 |     { | 
|---|
| 285 |         return false; | 
|---|
| 286 |     } | 
|---|
| 287 |  | 
|---|
| 288 |     SeekBuf(b, 0, 0); | 
|---|
| 289 |  | 
|---|
| 290 |     ret = DumpBufW(b, dst); | 
|---|
| 291 |  | 
|---|
| 292 |     FreeBuf(b); | 
|---|
| 293 |  | 
|---|
| 294 |     return ret; | 
|---|
| 295 | } | 
|---|
| 296 |  | 
|---|
| 297 | // ファイルへ設定を保存する | 
|---|
| 298 | void CfgSave(FOLDER *f, char *name) | 
|---|
| 299 | { | 
|---|
| 300 |     CfgSaveEx(NULL, f, name); | 
|---|
| 301 | } | 
|---|
| 302 | void CfgSaveW(FOLDER *f, wchar_t *name) | 
|---|
| 303 | { | 
|---|
| 304 |     CfgSaveExW(NULL, f, name); | 
|---|
| 305 | } | 
|---|
| 306 | bool CfgSaveEx(CFG_RW *rw, FOLDER *f, char *name) | 
|---|
| 307 | { | 
|---|
| 308 |     wchar_t *name_w = CopyStrToUni(name); | 
|---|
| 309 |     bool ret = CfgSaveExW(rw, f, name_w); | 
|---|
| 310 |  | 
|---|
| 311 |     Free(name_w); | 
|---|
| 312 |  | 
|---|
| 313 |     return ret; | 
|---|
| 314 | } | 
|---|
| 315 | bool CfgSaveExW(CFG_RW *rw, FOLDER *f, wchar_t *name) | 
|---|
| 316 | { | 
|---|
| 317 |     return CfgSaveExW2(rw, f, name, NULL); | 
|---|
| 318 | } | 
|---|
| 319 | bool CfgSaveExW2(CFG_RW *rw, FOLDER *f, wchar_t *name, UINT *written_size) | 
|---|
| 320 | { | 
|---|
| 321 |     wchar_t tmp[MAX_SIZE]; | 
|---|
| 322 |     bool text = true; | 
|---|
| 323 |     UCHAR hash[SHA1_SIZE]; | 
|---|
| 324 |     BUF *b; | 
|---|
| 325 |     IO *o; | 
|---|
| 326 |     bool ret = true; | 
|---|
| 327 |     UINT dummy_int = 0; | 
|---|
| 328 |     // 引数チェック | 
|---|
| 329 |     if (name == NULL || f == NULL) | 
|---|
| 330 |     { | 
|---|
| 331 |         return false; | 
|---|
| 332 |     } | 
|---|
| 333 |     if (written_size == NULL) | 
|---|
| 334 |     { | 
|---|
| 335 |         written_size = &dummy_int; | 
|---|
| 336 |     } | 
|---|
| 337 |  | 
|---|
| 338 |     // 同じディレクトリにある SAVE_BINARY_FILE_NAME_SWITCH ファイルがあるかどうか確認 | 
|---|
| 339 |     if (IsFileExistsW(SAVE_BINARY_FILE_NAME_SWITCH)) | 
|---|
| 340 |     { | 
|---|
| 341 |         text = false; | 
|---|
| 342 |     } | 
|---|
| 343 |  | 
|---|
| 344 |     // バッファに変換 | 
|---|
| 345 |     b = CfgFolderToBuf(f, text); | 
|---|
| 346 |     if (b == NULL) | 
|---|
| 347 |     { | 
|---|
| 348 |         return false; | 
|---|
| 349 |     } | 
|---|
| 350 |     // 内容をハッシュする | 
|---|
| 351 |     Hash(hash, b->Buf, b->Size, true); | 
|---|
| 352 |  | 
|---|
| 353 |     // 最後に書き込んだ内容と書き込む内容を比較する | 
|---|
| 354 |     if (rw != NULL) | 
|---|
| 355 |     { | 
|---|
| 356 |         if (Cmp(hash, rw->LashHash, SHA1_SIZE) == 0) | 
|---|
| 357 |         { | 
|---|
| 358 |             // 内容が変更されていない | 
|---|
| 359 |             ret = false; | 
|---|
| 360 |         } | 
|---|
| 361 |         else | 
|---|
| 362 |         { | 
|---|
| 363 |             Copy(rw->LashHash, hash, SHA1_SIZE); | 
|---|
| 364 |         } | 
|---|
| 365 |     } | 
|---|
| 366 |  | 
|---|
| 367 |     if (ret || OS_IS_UNIX(GetOsInfo()->OsType)) | 
|---|
| 368 |     { | 
|---|
| 369 |         // 一時的なファイル名の生成 | 
|---|
| 370 |         UniFormat(tmp, sizeof(tmp), L"%s.log", name); | 
|---|
| 371 |         // 現在存在するファイルを一時ファイルにコピー | 
|---|
| 372 |         FileCopyW(name, tmp); | 
|---|
| 373 |  | 
|---|
| 374 |         // 新しいファイルを保存 | 
|---|
| 375 |         o = FileCreateW(name); | 
|---|
| 376 |         if (o != NULL) | 
|---|
| 377 |         { | 
|---|
| 378 |             if (FileWrite(o, b->Buf, b->Size) == false) | 
|---|
| 379 |             { | 
|---|
| 380 |                 // ファイル保存失敗 | 
|---|
| 381 |                 FileClose(o); | 
|---|
| 382 |                 FileDeleteW(name); | 
|---|
| 383 |                 FileRenameW(tmp, name); | 
|---|
| 384 |  | 
|---|
| 385 |                 if (rw != NULL) | 
|---|
| 386 |                 { | 
|---|
| 387 |                     Zero(rw->LashHash, sizeof(rw->LashHash)); | 
|---|
| 388 |                 } | 
|---|
| 389 |             } | 
|---|
| 390 |             else | 
|---|
| 391 |             { | 
|---|
| 392 |                 // ファイル保存成功 | 
|---|
| 393 |                 FileClose(o); | 
|---|
| 394 |                 // 一時ファイルの削除 | 
|---|
| 395 |                 FileDeleteW(tmp); | 
|---|
| 396 |             } | 
|---|
| 397 |         } | 
|---|
| 398 |         else | 
|---|
| 399 |         { | 
|---|
| 400 |             // ファイル保存失敗 | 
|---|
| 401 |             FileRenameW(tmp, name); | 
|---|
| 402 |  | 
|---|
| 403 |             if (rw != NULL) | 
|---|
| 404 |             { | 
|---|
| 405 |                 Zero(rw->LashHash, sizeof(rw->LashHash)); | 
|---|
| 406 |             } | 
|---|
| 407 |         } | 
|---|
| 408 |     } | 
|---|
| 409 |  | 
|---|
| 410 |     *written_size = b->Size; | 
|---|
| 411 |  | 
|---|
| 412 |     // メモリ解放 | 
|---|
| 413 |     FreeBuf(b); | 
|---|
| 414 |  | 
|---|
| 415 |     return ret; | 
|---|
| 416 | } | 
|---|
| 417 |  | 
|---|
| 418 | // ファイルから設定を読み込む | 
|---|
| 419 | FOLDER *CfgRead(char *name) | 
|---|
| 420 | { | 
|---|
| 421 |     wchar_t *name_w = CopyStrToUni(name); | 
|---|
| 422 |     FOLDER *ret = CfgReadW(name_w); | 
|---|
| 423 |  | 
|---|
| 424 |     Free(name_w); | 
|---|
| 425 |  | 
|---|
| 426 |     return ret; | 
|---|
| 427 | } | 
|---|
| 428 | FOLDER *CfgReadW(wchar_t *name) | 
|---|
| 429 | { | 
|---|
| 430 |     wchar_t tmp[MAX_SIZE]; | 
|---|
| 431 |     wchar_t newfile[MAX_SIZE]; | 
|---|
| 432 |     BUF *b; | 
|---|
| 433 |     IO *o; | 
|---|
| 434 |     UINT size; | 
|---|
| 435 |     void *buf; | 
|---|
| 436 |     FOLDER *f; | 
|---|
| 437 |     bool delete_new = false; | 
|---|
| 438 |     bool binary_file = false; | 
|---|
| 439 |     bool invalid_file = false; | 
|---|
| 440 |     UCHAR header[8]; | 
|---|
| 441 |     // 引数チェック | 
|---|
| 442 |     if (name == NULL) | 
|---|
| 443 |     { | 
|---|
| 444 |         return NULL; | 
|---|
| 445 |     } | 
|---|
| 446 |  | 
|---|
| 447 |     // 新しいファイル名の生成 | 
|---|
| 448 |     UniFormat(newfile, sizeof(newfile), L"%s.new", name); | 
|---|
| 449 |     // 一時的なファイル名の生成 | 
|---|
| 450 |     UniFormat(tmp, sizeof(tmp), L"%s.log", name); | 
|---|
| 451 |  | 
|---|
| 452 |     // 新しいファイルが存在していれば読み込む | 
|---|
| 453 |     o = FileOpenW(newfile, false); | 
|---|
| 454 |     if (o == NULL) | 
|---|
| 455 |     { | 
|---|
| 456 |         // 一時的なファイルを読む | 
|---|
| 457 |         o = FileOpenW(tmp, false); | 
|---|
| 458 |     } | 
|---|
| 459 |     else | 
|---|
| 460 |     { | 
|---|
| 461 |         delete_new = true; | 
|---|
| 462 |     } | 
|---|
| 463 |     if (o == NULL) | 
|---|
| 464 |     { | 
|---|
| 465 |         // 一時的なファイルが無い場合は本来のファイルを読む | 
|---|
| 466 |         o = FileOpenW(name, false); | 
|---|
| 467 |     } | 
|---|
| 468 |     else | 
|---|
| 469 |     { | 
|---|
| 470 |         // 一時的なファイルのサイズが 0 の場合も本来のファイルを読み込む | 
|---|
| 471 |         if (FileSize(o) == 0) | 
|---|
| 472 |         { | 
|---|
| 473 |             invalid_file = true; | 
|---|
| 474 |         } | 
|---|
| 475 |  | 
|---|
| 476 |         if (invalid_file) | 
|---|
| 477 |         { | 
|---|
| 478 |             FileClose(o); | 
|---|
| 479 |             o = FileOpenW(name, false); | 
|---|
| 480 |         } | 
|---|
| 481 |     } | 
|---|
| 482 |     if (o == NULL) | 
|---|
| 483 |     { | 
|---|
| 484 |         // 読み込みに失敗した | 
|---|
| 485 |         return NULL; | 
|---|
| 486 |     } | 
|---|
| 487 |  | 
|---|
| 488 |     // バッファに読み込む | 
|---|
| 489 |     size = FileSize(o); | 
|---|
| 490 |     buf = Malloc(size); | 
|---|
| 491 |     FileRead(o, buf, size); | 
|---|
| 492 |     b = NewBuf(); | 
|---|
| 493 |     WriteBuf(b, buf, size); | 
|---|
| 494 |     SeekBuf(b, 0, 0); | 
|---|
| 495 |  | 
|---|
| 496 |     // ファイルを閉じる | 
|---|
| 497 |     FileClose(o); | 
|---|
| 498 |  | 
|---|
| 499 |     if (delete_new) | 
|---|
| 500 |     { | 
|---|
| 501 |         // 新しいファイルを削除する | 
|---|
| 502 |         FileDeleteW(newfile); | 
|---|
| 503 |     } | 
|---|
| 504 |  | 
|---|
| 505 |     // バッファの先頭 8 文字が "SEVPN_DB" の場合はバイナリファイル | 
|---|
| 506 |     ReadBuf(b, header, sizeof(header)); | 
|---|
| 507 |     if (Cmp(header, TAG_BINARY, 8) == 0) | 
|---|
| 508 |     { | 
|---|
| 509 |         UCHAR hash1[SHA1_SIZE], hash2[SHA1_SIZE]; | 
|---|
| 510 |         binary_file = true; | 
|---|
| 511 |  | 
|---|
| 512 |         // ハッシュチェック | 
|---|
| 513 |         ReadBuf(b, hash1, sizeof(hash1)); | 
|---|
| 514 |  | 
|---|
| 515 |         Hash(hash2, ((UCHAR *)b->Buf) + 8 + SHA1_SIZE, b->Size - 8 - SHA1_SIZE, true); | 
|---|
| 516 |  | 
|---|
| 517 |         if (Cmp(hash1, hash2, SHA1_SIZE) != 0) | 
|---|
| 518 |         { | 
|---|
| 519 |             // 破損ファイル | 
|---|
| 520 |             invalid_file = true; | 
|---|
| 521 |             FreeBuf(b); | 
|---|
| 522 |             return NULL; | 
|---|
| 523 |         } | 
|---|
| 524 |     } | 
|---|
| 525 |  | 
|---|
| 526 |     SeekBuf(b, 0, 0); | 
|---|
| 527 |  | 
|---|
| 528 |     if (binary_file) | 
|---|
| 529 |     { | 
|---|
| 530 |         SeekBuf(b, 8 + SHA1_SIZE, 0); | 
|---|
| 531 |     } | 
|---|
| 532 |  | 
|---|
| 533 |     // バッファからフォルダに変換 | 
|---|
| 534 |     if (binary_file == false) | 
|---|
| 535 |     { | 
|---|
| 536 |         // テキストモード | 
|---|
| 537 |         f = CfgBufTextToFolder(b); | 
|---|
| 538 |     } | 
|---|
| 539 |     else | 
|---|
| 540 |     { | 
|---|
| 541 |         // バイナリモード | 
|---|
| 542 |         f = CfgBufBinToFolder(b); | 
|---|
| 543 |     } | 
|---|
| 544 |  | 
|---|
| 545 |     // メモリ解放 | 
|---|
| 546 |     Free(buf); | 
|---|
| 547 |     FreeBuf(b); | 
|---|
| 548 |  | 
|---|
| 549 |     FileDeleteW(newfile); | 
|---|
| 550 |  | 
|---|
| 551 |     return f; | 
|---|
| 552 | } | 
|---|
| 553 |  | 
|---|
| 554 | // Cfg のテスト | 
|---|
| 555 | void CfgTest2(FOLDER *f, UINT n) | 
|---|
| 556 | { | 
|---|
| 557 | } | 
|---|
| 558 |  | 
|---|
| 559 | void CfgTest() | 
|---|
| 560 | { | 
|---|
| 561 | #if 0 | 
|---|
| 562 |     FOLDER *root; | 
|---|
| 563 |     BUF *b; | 
|---|
| 564 |     Debug("\nCFG Test Begin\n"); | 
|---|
| 565 |  | 
|---|
| 566 |     root = CfgCreateFolder(NULL, TAG_ROOT); | 
|---|
| 567 |     CfgTest2(root, 5); | 
|---|
| 568 |  | 
|---|
| 569 |     b = CfgFolderToBufText(root); | 
|---|
| 570 |     //Print("%s\n", b->Buf); | 
|---|
| 571 |     SeekBuf(b, 0, 0); | 
|---|
| 572 |  | 
|---|
| 573 |     CfgDeleteFolder(root); | 
|---|
| 574 |  | 
|---|
| 575 |     DumpBuf(b, "test1.config"); | 
|---|
| 576 |  | 
|---|
| 577 |     root = CfgBufTextToFolder(b); | 
|---|
| 578 |  | 
|---|
| 579 |     FreeBuf(b); | 
|---|
| 580 |  | 
|---|
| 581 |     b = CfgFolderToBufText(root); | 
|---|
| 582 | //  Print("%s\n", b->Buf); | 
|---|
| 583 |     DumpBuf(b, "test2.config"); | 
|---|
| 584 |     FreeBuf(b); | 
|---|
| 585 |  | 
|---|
| 586 |     CfgSave(root, "test.txt"); | 
|---|
| 587 |  | 
|---|
| 588 |     CfgDeleteFolder(root); | 
|---|
| 589 |  | 
|---|
| 590 |     Debug("\nCFG Test End\n"); | 
|---|
| 591 | #endif | 
|---|
| 592 | } | 
|---|
| 593 |  | 
|---|
| 594 | // 1 行読み込む | 
|---|
| 595 | char *CfgReadNextLine(BUF *b) | 
|---|
| 596 | { | 
|---|
| 597 |     char *tmp; | 
|---|
| 598 |     char *buf; | 
|---|
| 599 |     UINT len; | 
|---|
| 600 |     // 引数チェック | 
|---|
| 601 |     if (b == NULL) | 
|---|
| 602 |     { | 
|---|
| 603 |         return NULL; | 
|---|
| 604 |     } | 
|---|
| 605 |  | 
|---|
| 606 |     // 次の改行までの文字数を調査 | 
|---|
| 607 |     tmp = (char *)b->Buf + b->Current; | 
|---|
| 608 |     if ((b->Size - b->Current) == 0) | 
|---|
| 609 |     { | 
|---|
| 610 |         // 最後まで読んだ | 
|---|
| 611 |         return NULL; | 
|---|
| 612 |     } | 
|---|
| 613 |     len = 0; | 
|---|
| 614 |     while (true) | 
|---|
| 615 |     { | 
|---|
| 616 |         if (tmp[len] == 13 || tmp[len] == 10) | 
|---|
| 617 |         { | 
|---|
| 618 |             if (tmp[len] == 13) | 
|---|
| 619 |             { | 
|---|
| 620 |                 if (len < (b->Size - b->Current)) | 
|---|
| 621 |                 { | 
|---|
| 622 |                     len++; | 
|---|
| 623 |                 } | 
|---|
| 624 |             } | 
|---|
| 625 |             break; | 
|---|
| 626 |         } | 
|---|
| 627 |         len++; | 
|---|
| 628 |         if (len >= (b->Size - b->Current)) | 
|---|
| 629 |         { | 
|---|
| 630 |             break; | 
|---|
| 631 |         } | 
|---|
| 632 |     } | 
|---|
| 633 |  | 
|---|
| 634 |     // len だけ読み込む | 
|---|
| 635 |     buf = ZeroMalloc(len + 1); | 
|---|
| 636 |     ReadBuf(b, buf, len); | 
|---|
| 637 |     SeekBuf(b, 1, 1); | 
|---|
| 638 |  | 
|---|
| 639 |     if (StrLen(buf) >= 1) | 
|---|
| 640 |     { | 
|---|
| 641 |         if (buf[StrLen(buf) - 1] == 13) | 
|---|
| 642 |         { | 
|---|
| 643 |             buf[StrLen(buf) - 1] = 0; | 
|---|
| 644 |         } | 
|---|
| 645 |     } | 
|---|
| 646 |  | 
|---|
| 647 |     return buf; | 
|---|
| 648 | } | 
|---|
| 649 |  | 
|---|
| 650 | // テキストストリームを読み込む | 
|---|
| 651 | bool CfgReadNextTextBUF(BUF *b, FOLDER *current) | 
|---|
| 652 | { | 
|---|
| 653 |     char *buf; | 
|---|
| 654 |     TOKEN_LIST *token; | 
|---|
| 655 |     char *name; | 
|---|
| 656 |     char *string; | 
|---|
| 657 |     char *data; | 
|---|
| 658 |     bool ret; | 
|---|
| 659 |     FOLDER *f; | 
|---|
| 660 |  | 
|---|
| 661 |     // 引数チェック | 
|---|
| 662 |     if (b == NULL || current == NULL) | 
|---|
| 663 |     { | 
|---|
| 664 |         return false; | 
|---|
| 665 |     } | 
|---|
| 666 |  | 
|---|
| 667 |     ret = true; | 
|---|
| 668 |  | 
|---|
| 669 |     // 1 行読み込む | 
|---|
| 670 |     buf = CfgReadNextLine(b); | 
|---|
| 671 |     if (buf == NULL) | 
|---|
| 672 |     { | 
|---|
| 673 |         return false; | 
|---|
| 674 |     } | 
|---|
| 675 |  | 
|---|
| 676 |     // この行を解析 | 
|---|
| 677 |     token = ParseToken(buf, "\t "); | 
|---|
| 678 |     if (token == NULL) | 
|---|
| 679 |     { | 
|---|
| 680 |         Free(buf); | 
|---|
| 681 |         return false; | 
|---|
| 682 |     } | 
|---|
| 683 |  | 
|---|
| 684 |     if (token->NumTokens >= 1) | 
|---|
| 685 |     { | 
|---|
| 686 |         if (!StrCmpi(token->Token[0], TAG_DECLARE)) | 
|---|
| 687 |         { | 
|---|
| 688 |             if (token->NumTokens >= 2) | 
|---|
| 689 |             { | 
|---|
| 690 |                 // declare | 
|---|
| 691 |                 name = CfgUnescape(token->Token[1]); | 
|---|
| 692 |  | 
|---|
| 693 |                 // フォルダの作成 | 
|---|
| 694 |                 f = CfgCreateFolder(current, name); | 
|---|
| 695 |  | 
|---|
| 696 |                 // 次のフォルダを読み込む | 
|---|
| 697 |                 while (true) | 
|---|
| 698 |                 { | 
|---|
| 699 |                     if (CfgReadNextTextBUF(b, f) == false) | 
|---|
| 700 |                     { | 
|---|
| 701 |                         break; | 
|---|
| 702 |                     } | 
|---|
| 703 |                 } | 
|---|
| 704 |  | 
|---|
| 705 |                 Free(name); | 
|---|
| 706 |             } | 
|---|
| 707 |         } | 
|---|
| 708 |         if (!StrCmpi(token->Token[0], "}")) | 
|---|
| 709 |         { | 
|---|
| 710 |             // end | 
|---|
| 711 |             ret = false; | 
|---|
| 712 |         } | 
|---|
| 713 |         if (token->NumTokens >= 3) | 
|---|
| 714 |         { | 
|---|
| 715 |             name = CfgUnescape(token->Token[1]); | 
|---|
| 716 |             data = token->Token[2]; | 
|---|
| 717 |  | 
|---|
| 718 |             if (!StrCmpi(token->Token[0], TAG_STRING)) | 
|---|
| 719 |             { | 
|---|
| 720 |                 // string | 
|---|
| 721 |                 wchar_t *uni; | 
|---|
| 722 |                 UINT uni_size; | 
|---|
| 723 |                 string = CfgUnescape(data); | 
|---|
| 724 |                 uni_size = CalcUtf8ToUni(string, StrLen(string)); | 
|---|
| 725 |                 if (uni_size != 0) | 
|---|
| 726 |                 { | 
|---|
| 727 |                     uni = Malloc(uni_size); | 
|---|
| 728 |                     Utf8ToUni(uni, uni_size, string, StrLen(string)); | 
|---|
| 729 |                     CfgAddUniStr(current, name, uni); | 
|---|
| 730 |                     Free(uni); | 
|---|
| 731 |                 } | 
|---|
| 732 |                 Free(string); | 
|---|
| 733 |             } | 
|---|
| 734 |             if (!StrCmpi(token->Token[0], TAG_INT)) | 
|---|
| 735 |             { | 
|---|
| 736 |                 // uint | 
|---|
| 737 |                 CfgAddInt(current, name, ToInt(data)); | 
|---|
| 738 |             } | 
|---|
| 739 |             if (!StrCmpi(token->Token[0], TAG_INT64)) | 
|---|
| 740 |             { | 
|---|
| 741 |                 // uint64 | 
|---|
| 742 |                 CfgAddInt64(current, name, ToInt64(data)); | 
|---|
| 743 |             } | 
|---|
| 744 |             if (!StrCmpi(token->Token[0], TAG_BOOL)) | 
|---|
| 745 |             { | 
|---|
| 746 |                 // bool | 
|---|
| 747 |                 bool b = false; | 
|---|
| 748 |                 if (!StrCmpi(data, TAG_TRUE)) | 
|---|
| 749 |                 { | 
|---|
| 750 |                     b = true; | 
|---|
| 751 |                 } | 
|---|
| 752 |                 else if (ToInt(data) != 0) | 
|---|
| 753 |                 { | 
|---|
| 754 |                     b = true; | 
|---|
| 755 |                 } | 
|---|
| 756 |                 CfgAddBool(current, name, b); | 
|---|
| 757 |             } | 
|---|
| 758 |             if (!StrCmpi(token->Token[0], TAG_BYTE)) | 
|---|
| 759 |             { | 
|---|
| 760 |                 // byte | 
|---|
| 761 |                 char *unescaped_b64 = CfgUnescape(data); | 
|---|
| 762 |                 void *tmp = Malloc(StrLen(unescaped_b64) * 4 + 64); | 
|---|
| 763 |                 int size = B64_Decode(tmp, unescaped_b64, StrLen(unescaped_b64)); | 
|---|
| 764 |                 CfgAddByte(current, name, tmp, size); | 
|---|
| 765 |                 Free(tmp); | 
|---|
| 766 |                 Free(unescaped_b64); | 
|---|
| 767 |             } | 
|---|
| 768 |  | 
|---|
| 769 |             Free(name); | 
|---|
| 770 |         } | 
|---|
| 771 |     } | 
|---|
| 772 |  | 
|---|
| 773 |     // トークンの解放 | 
|---|
| 774 |     FreeToken(token); | 
|---|
| 775 |  | 
|---|
| 776 |     Free(buf); | 
|---|
| 777 |  | 
|---|
| 778 |     return ret; | 
|---|
| 779 | } | 
|---|
| 780 |  | 
|---|
| 781 | // ストリームテキストをフォルダに変換 | 
|---|
| 782 | FOLDER *CfgBufTextToFolder(BUF *b) | 
|---|
| 783 | { | 
|---|
| 784 |     FOLDER *f, *c; | 
|---|
| 785 |     // 引数チェック | 
|---|
| 786 |     if (b == NULL) | 
|---|
| 787 |     { | 
|---|
| 788 |         return NULL; | 
|---|
| 789 |     } | 
|---|
| 790 |  | 
|---|
| 791 |     // root フォルダから再帰的に読み込む | 
|---|
| 792 |     c = CfgCreateFolder(NULL, "tmp"); | 
|---|
| 793 |  | 
|---|
| 794 |     while (true) | 
|---|
| 795 |     { | 
|---|
| 796 |         // テキストストリームを読み込む | 
|---|
| 797 |         if (CfgReadNextTextBUF(b, c) == false) | 
|---|
| 798 |         { | 
|---|
| 799 |             break; | 
|---|
| 800 |         } | 
|---|
| 801 |     } | 
|---|
| 802 |  | 
|---|
| 803 |     // root フォルダの取得 | 
|---|
| 804 |     f = CfgGetFolder(c, TAG_ROOT); | 
|---|
| 805 |     if (f == NULL) | 
|---|
| 806 |     { | 
|---|
| 807 |         // root フォルダが見つからない | 
|---|
| 808 |         CfgDeleteFolder(c); | 
|---|
| 809 |         return NULL; | 
|---|
| 810 |     } | 
|---|
| 811 |  | 
|---|
| 812 |     // tmp フォルダから root への参照を削除 | 
|---|
| 813 |     Delete(c->Folders, f); | 
|---|
| 814 |     f->Parent = NULL; | 
|---|
| 815 |  | 
|---|
| 816 |     // tmp フォルダを削除 | 
|---|
| 817 |     CfgDeleteFolder(c); | 
|---|
| 818 |  | 
|---|
| 819 |     // root フォルダを返す | 
|---|
| 820 |     return f; | 
|---|
| 821 | } | 
|---|
| 822 |  | 
|---|
| 823 | // 次のフォルダを読み込む | 
|---|
| 824 | void CfgReadNextFolderBin(BUF *b, FOLDER *parent) | 
|---|
| 825 | { | 
|---|
| 826 |     char name[MAX_SIZE]; | 
|---|
| 827 |     FOLDER *f; | 
|---|
| 828 |     UINT n, i; | 
|---|
| 829 |     UINT size; | 
|---|
| 830 |     UCHAR *buf; | 
|---|
| 831 |     wchar_t *string; | 
|---|
| 832 |     // 引数チェック | 
|---|
| 833 |     if (b == NULL || parent == NULL) | 
|---|
| 834 |     { | 
|---|
| 835 |         return; | 
|---|
| 836 |     } | 
|---|
| 837 |  | 
|---|
| 838 |     // フォルダ名 | 
|---|
| 839 |     ReadBufStr(b, name, sizeof(name)); | 
|---|
| 840 |     f = CfgCreateFolder(parent, name); | 
|---|
| 841 |  | 
|---|
| 842 |     // サブフォルダ数 | 
|---|
| 843 |     n = ReadBufInt(b); | 
|---|
| 844 |     for (i = 0;i < n;i++) | 
|---|
| 845 |     { | 
|---|
| 846 |         // サブフォルダ | 
|---|
| 847 |         CfgReadNextFolderBin(b, f); | 
|---|
| 848 |     } | 
|---|
| 849 |  | 
|---|
| 850 |     // アイテム数 | 
|---|
| 851 |     n = ReadBufInt(b); | 
|---|
| 852 |     for (i = 0;i < n;i++) | 
|---|
| 853 |     { | 
|---|
| 854 |         UINT type; | 
|---|
| 855 |  | 
|---|
| 856 |         // 名前 | 
|---|
| 857 |         ReadBufStr(b, name, sizeof(name)); | 
|---|
| 858 |         // 種類 | 
|---|
| 859 |         type = ReadBufInt(b); | 
|---|
| 860 |  | 
|---|
| 861 |         switch (type) | 
|---|
| 862 |         { | 
|---|
| 863 |         case ITEM_TYPE_INT: | 
|---|
| 864 |             // int | 
|---|
| 865 |             CfgAddInt(f, name, ReadBufInt(b)); | 
|---|
| 866 |             break; | 
|---|
| 867 |  | 
|---|
| 868 |         case ITEM_TYPE_INT64: | 
|---|
| 869 |             // int64 | 
|---|
| 870 |             CfgAddInt64(f, name, ReadBufInt64(b)); | 
|---|
| 871 |             break; | 
|---|
| 872 |  | 
|---|
| 873 |         case ITEM_TYPE_BYTE: | 
|---|
| 874 |             // data | 
|---|
| 875 |             size = ReadBufInt(b); | 
|---|
| 876 |             buf = ZeroMalloc(size); | 
|---|
| 877 |             ReadBuf(b, buf, size); | 
|---|
| 878 |             CfgAddByte(f, name, buf, size); | 
|---|
| 879 |             Free(buf); | 
|---|
| 880 |             break; | 
|---|
| 881 |  | 
|---|
| 882 |         case ITEM_TYPE_STRING: | 
|---|
| 883 |             // string | 
|---|
| 884 |             size = ReadBufInt(b); | 
|---|
| 885 |             buf = ZeroMalloc(size + 1); | 
|---|
| 886 |             ReadBuf(b, buf, size); | 
|---|
| 887 |             string = ZeroMalloc(CalcUtf8ToUni(buf, StrLen(buf)) + 4); | 
|---|
| 888 |             Utf8ToUni(string, 0, buf, StrLen(buf)); | 
|---|
| 889 |             CfgAddUniStr(f, name, string); | 
|---|
| 890 |             Free(string); | 
|---|
| 891 |             Free(buf); | 
|---|
| 892 |             break; | 
|---|
| 893 |  | 
|---|
| 894 |         case ITEM_TYPE_BOOL: | 
|---|
| 895 |             // bool | 
|---|
| 896 |             CfgAddBool(f, name, ReadBufInt(b) == 0 ? false : true); | 
|---|
| 897 |             break; | 
|---|
| 898 |         } | 
|---|
| 899 |     } | 
|---|
| 900 | } | 
|---|
| 901 |  | 
|---|
| 902 | // バイナリをフォルダに変換 | 
|---|
| 903 | FOLDER *CfgBufBinToFolder(BUF *b) | 
|---|
| 904 | { | 
|---|
| 905 |     FOLDER *f, *c; | 
|---|
| 906 |     // 引数チェック | 
|---|
| 907 |     if (b == NULL) | 
|---|
| 908 |     { | 
|---|
| 909 |         return NULL; | 
|---|
| 910 |     } | 
|---|
| 911 |  | 
|---|
| 912 |     // 一時フォルダを作成 | 
|---|
| 913 |     c = CfgCreateFolder(NULL, "tmp"); | 
|---|
| 914 |  | 
|---|
| 915 |     // バイナリを読み込む | 
|---|
| 916 |     CfgReadNextFolderBin(b, c); | 
|---|
| 917 |  | 
|---|
| 918 |     // root の取得 | 
|---|
| 919 |     f = CfgGetFolder(c, TAG_ROOT); | 
|---|
| 920 |     if (f == NULL) | 
|---|
| 921 |     { | 
|---|
| 922 |         // 見つからない | 
|---|
| 923 |         CfgDeleteFolder(c); | 
|---|
| 924 |         return NULL; | 
|---|
| 925 |     } | 
|---|
| 926 |  | 
|---|
| 927 |     Delete(c->Folders, f); | 
|---|
| 928 |     f->Parent = NULL; | 
|---|
| 929 |  | 
|---|
| 930 |     CfgDeleteFolder(c); | 
|---|
| 931 |  | 
|---|
| 932 |     return f; | 
|---|
| 933 | } | 
|---|
| 934 |  | 
|---|
| 935 | // フォルダをバイナリに変換 | 
|---|
| 936 | BUF *CfgFolderToBufBin(FOLDER *f) | 
|---|
| 937 | { | 
|---|
| 938 |     BUF *b; | 
|---|
| 939 |     UCHAR hash[SHA1_SIZE]; | 
|---|
| 940 |     // 引数チェック | 
|---|
| 941 |     if (f == NULL) | 
|---|
| 942 |     { | 
|---|
| 943 |         return NULL; | 
|---|
| 944 |     } | 
|---|
| 945 |  | 
|---|
| 946 |     b = NewBuf(); | 
|---|
| 947 |  | 
|---|
| 948 |     // ヘッダ | 
|---|
| 949 |     WriteBuf(b, TAG_BINARY, 8); | 
|---|
| 950 |  | 
|---|
| 951 |     // ハッシュ領域 | 
|---|
| 952 |     Zero(hash, sizeof(hash)); | 
|---|
| 953 |     WriteBuf(b, hash, sizeof(hash)); | 
|---|
| 954 |  | 
|---|
| 955 |     // ルートフォルダを出力 (再帰) | 
|---|
| 956 |     CfgOutputFolderBin(b, f); | 
|---|
| 957 |  | 
|---|
| 958 |     // ハッシュ | 
|---|
| 959 |     Hash(((UCHAR *)b->Buf) + 8, ((UCHAR *)b->Buf) + 8 + SHA1_SIZE, b->Size - 8 - SHA1_SIZE, true); | 
|---|
| 960 |  | 
|---|
| 961 |     return b; | 
|---|
| 962 | } | 
|---|
| 963 |  | 
|---|
| 964 | // フォルダをストリームテキストに変換 | 
|---|
| 965 | BUF *CfgFolderToBufText(FOLDER *f) | 
|---|
| 966 | { | 
|---|
| 967 |     return CfgFolderToBufTextEx(f, false); | 
|---|
| 968 | } | 
|---|
| 969 | BUF *CfgFolderToBufTextEx(FOLDER *f, bool no_banner) | 
|---|
| 970 | { | 
|---|
| 971 |     BUF *b; | 
|---|
| 972 |     // 引数チェック | 
|---|
| 973 |     if (f == NULL) | 
|---|
| 974 |     { | 
|---|
| 975 |         return NULL; | 
|---|
| 976 |     } | 
|---|
| 977 |  | 
|---|
| 978 |     // ストリーム作成 | 
|---|
| 979 |     b = NewBuf(); | 
|---|
| 980 |  | 
|---|
| 981 |     // 著作権情報 | 
|---|
| 982 |     if (no_banner == false) | 
|---|
| 983 |     { | 
|---|
| 984 |         WriteBuf(b, TAG_CPYRIGHT, StrLen(TAG_CPYRIGHT)); | 
|---|
| 985 |     } | 
|---|
| 986 |  | 
|---|
| 987 |     // ルートフォルダを出力 (再帰) | 
|---|
| 988 |     CfgOutputFolderText(b, f, 0); | 
|---|
| 989 |  | 
|---|
| 990 |     return b; | 
|---|
| 991 | } | 
|---|
| 992 |  | 
|---|
| 993 | // フォルダ内容を出力 (フォルダを列挙) | 
|---|
| 994 | bool CfgEnumFolderProc(FOLDER *f, void *param) | 
|---|
| 995 | { | 
|---|
| 996 |     CFG_ENUM_PARAM *p; | 
|---|
| 997 |     // 引数チェック | 
|---|
| 998 |     if (f == NULL || param == NULL) | 
|---|
| 999 |     { | 
|---|
| 1000 |         return false; | 
|---|
| 1001 |     } | 
|---|
| 1002 |  | 
|---|
| 1003 |     p = (CFG_ENUM_PARAM *)param; | 
|---|
| 1004 |     // フォルダ内容を出力 (再帰) | 
|---|
| 1005 |     CfgOutputFolderText(p->b, f, p->depth); | 
|---|
| 1006 |  | 
|---|
| 1007 |     return true; | 
|---|
| 1008 | } | 
|---|
| 1009 |  | 
|---|
| 1010 | // アイテム内容を出力 (列挙) | 
|---|
| 1011 | bool CfgEnumItemProc(ITEM *t, void *param) | 
|---|
| 1012 | { | 
|---|
| 1013 |     CFG_ENUM_PARAM *p; | 
|---|
| 1014 |     // 引数チェック | 
|---|
| 1015 |     if (t == NULL || param == NULL) | 
|---|
| 1016 |     { | 
|---|
| 1017 |         return false; | 
|---|
| 1018 |     } | 
|---|
| 1019 |  | 
|---|
| 1020 |     p = (CFG_ENUM_PARAM *)param; | 
|---|
| 1021 |     CfgAddItemText(p->b, t, p->depth); | 
|---|
| 1022 |  | 
|---|
| 1023 |     return true; | 
|---|
| 1024 | } | 
|---|
| 1025 |  | 
|---|
| 1026 | // フォルダ内容を出力 (再帰、バイナリ) | 
|---|
| 1027 | void CfgOutputFolderBin(BUF *b, FOLDER *f) | 
|---|
| 1028 | { | 
|---|
| 1029 |     UINT i; | 
|---|
| 1030 |     // 引数チェック | 
|---|
| 1031 |     if (b == NULL || f == NULL) | 
|---|
| 1032 |     { | 
|---|
| 1033 |         return; | 
|---|
| 1034 |     } | 
|---|
| 1035 |  | 
|---|
| 1036 |     // フォルダ名 | 
|---|
| 1037 |     WriteBufStr(b, f->Name); | 
|---|
| 1038 |  | 
|---|
| 1039 |     // サブフォルダ個数 | 
|---|
| 1040 |     WriteBufInt(b, LIST_NUM(f->Folders)); | 
|---|
| 1041 |  | 
|---|
| 1042 |     // サブフォルダ | 
|---|
| 1043 |     for (i = 0;i < LIST_NUM(f->Folders);i++) | 
|---|
| 1044 |     { | 
|---|
| 1045 |         FOLDER *sub = LIST_DATA(f->Folders, i); | 
|---|
| 1046 |         CfgOutputFolderBin(b, sub); | 
|---|
| 1047 |  | 
|---|
| 1048 |         if ((i % 100) == 99) | 
|---|
| 1049 |         { | 
|---|
| 1050 |             YieldCpu(); | 
|---|
| 1051 |         } | 
|---|
| 1052 |     } | 
|---|
| 1053 |  | 
|---|
| 1054 |     // アイテム個数 | 
|---|
| 1055 |     WriteBufInt(b, LIST_NUM(f->Items)); | 
|---|
| 1056 |  | 
|---|
| 1057 |     // アイテム | 
|---|
| 1058 |     for (i = 0;i < LIST_NUM(f->Items);i++) | 
|---|
| 1059 |     { | 
|---|
| 1060 |         char *utf8; | 
|---|
| 1061 |         UINT utf8_size; | 
|---|
| 1062 |         ITEM *t = LIST_DATA(f->Items, i); | 
|---|
| 1063 |  | 
|---|
| 1064 |         // アイテム名 | 
|---|
| 1065 |         WriteBufStr(b, t->Name); | 
|---|
| 1066 |  | 
|---|
| 1067 |         // 型 | 
|---|
| 1068 |         WriteBufInt(b, t->Type); | 
|---|
| 1069 |  | 
|---|
| 1070 |         switch (t->Type) | 
|---|
| 1071 |         { | 
|---|
| 1072 |         case ITEM_TYPE_INT: | 
|---|
| 1073 |             // 整数 | 
|---|
| 1074 |             WriteBufInt(b, *((UINT *)t->Buf)); | 
|---|
| 1075 |             break; | 
|---|
| 1076 |  | 
|---|
| 1077 |         case ITEM_TYPE_INT64: | 
|---|
| 1078 |             // 64bit 整数 | 
|---|
| 1079 |             WriteBufInt64(b, *((UINT64 *)t->Buf)); | 
|---|
| 1080 |             break; | 
|---|
| 1081 |  | 
|---|
| 1082 |         case ITEM_TYPE_BYTE: | 
|---|
| 1083 |             // データサイズ | 
|---|
| 1084 |             WriteBufInt(b, t->size); | 
|---|
| 1085 |             // データ | 
|---|
| 1086 |             WriteBuf(b, t->Buf, t->size); | 
|---|
| 1087 |             break; | 
|---|
| 1088 |  | 
|---|
| 1089 |         case ITEM_TYPE_STRING: | 
|---|
| 1090 |             // 文字列 | 
|---|
| 1091 |             utf8_size = CalcUniToUtf8((wchar_t *)t->Buf) + 1; | 
|---|
| 1092 |             utf8 = ZeroMalloc(utf8_size); | 
|---|
| 1093 |             UniToUtf8(utf8, utf8_size, (wchar_t *)t->Buf); | 
|---|
| 1094 |             WriteBufInt(b, StrLen(utf8)); | 
|---|
| 1095 |             WriteBuf(b, utf8, StrLen(utf8)); | 
|---|
| 1096 |             Free(utf8); | 
|---|
| 1097 |             break; | 
|---|
| 1098 |  | 
|---|
| 1099 |         case ITEM_TYPE_BOOL: | 
|---|
| 1100 |             // ブール型 | 
|---|
| 1101 |             if (*((bool *)t->Buf) == false) | 
|---|
| 1102 |             { | 
|---|
| 1103 |                 WriteBufInt(b, 0); | 
|---|
| 1104 |             } | 
|---|
| 1105 |             else | 
|---|
| 1106 |             { | 
|---|
| 1107 |                 WriteBufInt(b, 1); | 
|---|
| 1108 |             } | 
|---|
| 1109 |             break; | 
|---|
| 1110 |         } | 
|---|
| 1111 |     } | 
|---|
| 1112 | } | 
|---|
| 1113 |  | 
|---|
| 1114 | // フォルダ内容を出力 (再帰、テキスト) | 
|---|
| 1115 | void CfgOutputFolderText(BUF *b, FOLDER *f, UINT depth) | 
|---|
| 1116 | { | 
|---|
| 1117 |     CFG_ENUM_PARAM p; | 
|---|
| 1118 |     // 引数チェック | 
|---|
| 1119 |     if (b == NULL || f == NULL) | 
|---|
| 1120 |     { | 
|---|
| 1121 |         return; | 
|---|
| 1122 |     } | 
|---|
| 1123 |  | 
|---|
| 1124 |     // フォルダの開始を出力 | 
|---|
| 1125 |     CfgAddDeclare(b, f->Name, depth); | 
|---|
| 1126 |     depth++; | 
|---|
| 1127 |  | 
|---|
| 1128 |     Zero(&p, sizeof(CFG_ENUM_PARAM)); | 
|---|
| 1129 |     p.depth = depth; | 
|---|
| 1130 |     p.b = b; | 
|---|
| 1131 |     p.f = f; | 
|---|
| 1132 |  | 
|---|
| 1133 |     // アイテム一覧を列挙 | 
|---|
| 1134 |     CfgEnumItem(f, CfgEnumItemProc, &p); | 
|---|
| 1135 |  | 
|---|
| 1136 |     if (LIST_NUM(f->Folders) != 0 && LIST_NUM(f->Items) != 0) | 
|---|
| 1137 |     { | 
|---|
| 1138 |         WriteBuf(b, "\r\n", 2); | 
|---|
| 1139 |     } | 
|---|
| 1140 |  | 
|---|
| 1141 |     // フォルダ一覧を列挙 | 
|---|
| 1142 |     CfgEnumFolder(f, CfgEnumFolderProc, &p); | 
|---|
| 1143 |     // フォルダの終了を出力 | 
|---|
| 1144 |     depth--; | 
|---|
| 1145 |     CfgAddEnd(b, depth); | 
|---|
| 1146 |  | 
|---|
| 1147 |     //WriteBuf(b, "\r\n", 2); | 
|---|
| 1148 | } | 
|---|
| 1149 |  | 
|---|
| 1150 | // アイテム内容を出力 | 
|---|
| 1151 | void CfgAddItemText(BUF *b, ITEM *t, UINT depth) | 
|---|
| 1152 | { | 
|---|
| 1153 |     char *data; | 
|---|
| 1154 |     char *sub = NULL; | 
|---|
| 1155 |     UINT len; | 
|---|
| 1156 |     UINT size; | 
|---|
| 1157 |     char *utf8; | 
|---|
| 1158 |     UINT utf8_size; | 
|---|
| 1159 |     wchar_t *string; | 
|---|
| 1160 |     // 引数チェック | 
|---|
| 1161 |     if (b == NULL || t == NULL) | 
|---|
| 1162 |     { | 
|---|
| 1163 |         return; | 
|---|
| 1164 |     } | 
|---|
| 1165 |  | 
|---|
| 1166 |     // データ種類別に処理をする | 
|---|
| 1167 |     data = NULL; | 
|---|
| 1168 |     switch (t->Type) | 
|---|
| 1169 |     { | 
|---|
| 1170 |     case ITEM_TYPE_INT: | 
|---|
| 1171 |         data = Malloc(32); | 
|---|
| 1172 |         ToStr(data, *((UINT *)t->Buf)); | 
|---|
| 1173 |         break; | 
|---|
| 1174 |  | 
|---|
| 1175 |     case ITEM_TYPE_INT64: | 
|---|
| 1176 |         data = Malloc(64); | 
|---|
| 1177 |         ToStr64(data, *((UINT64 *)t->Buf)); | 
|---|
| 1178 |         break; | 
|---|
| 1179 |  | 
|---|
| 1180 |     case ITEM_TYPE_BYTE: | 
|---|
| 1181 |         data = ZeroMalloc(t->size * 4 + 32); | 
|---|
| 1182 |         len = B64_Encode(data, t->Buf, t->size); | 
|---|
| 1183 |         data[len] = 0; | 
|---|
| 1184 |         break; | 
|---|
| 1185 |  | 
|---|
| 1186 |     case ITEM_TYPE_STRING: | 
|---|
| 1187 |         string = t->Buf; | 
|---|
| 1188 |         utf8_size = CalcUniToUtf8(string); | 
|---|
| 1189 |         utf8_size++; | 
|---|
| 1190 |         utf8 = ZeroMalloc(utf8_size); | 
|---|
| 1191 |         utf8[0] = 0; | 
|---|
| 1192 |         UniToUtf8(utf8, utf8_size, string); | 
|---|
| 1193 |         size = utf8_size; | 
|---|
| 1194 |         data = utf8; | 
|---|
| 1195 |         break; | 
|---|
| 1196 |  | 
|---|
| 1197 |     case ITEM_TYPE_BOOL: | 
|---|
| 1198 |         size = 32; | 
|---|
| 1199 |         data = Malloc(size); | 
|---|
| 1200 |         if (*((bool *)t->Buf) == false) | 
|---|
| 1201 |         { | 
|---|
| 1202 |             StrCpy(data, size, TAG_FALSE); | 
|---|
| 1203 |         } | 
|---|
| 1204 |         else | 
|---|
| 1205 |         { | 
|---|
| 1206 |             StrCpy(data, size, TAG_TRUE); | 
|---|
| 1207 |         } | 
|---|
| 1208 |         break; | 
|---|
| 1209 |     } | 
|---|
| 1210 |     if (data == NULL) | 
|---|
| 1211 |     { | 
|---|
| 1212 |         return; | 
|---|
| 1213 |     } | 
|---|
| 1214 |  | 
|---|
| 1215 |     // データ行を出力 | 
|---|
| 1216 |     CfgAddData(b, t->Type, t->Name, data, sub, depth); | 
|---|
| 1217 |  | 
|---|
| 1218 |     // メモリ解放 | 
|---|
| 1219 |     Free(data); | 
|---|
| 1220 |     if (sub != NULL) | 
|---|
| 1221 |     { | 
|---|
| 1222 |         Free(sub); | 
|---|
| 1223 |     } | 
|---|
| 1224 | } | 
|---|
| 1225 |  | 
|---|
| 1226 | // データ行を出力 | 
|---|
| 1227 | void CfgAddData(BUF *b, UINT type, char *name, char *data, char *sub, UINT depth) | 
|---|
| 1228 | { | 
|---|
| 1229 |     char *tmp; | 
|---|
| 1230 |     char *name2; | 
|---|
| 1231 |     char *data2; | 
|---|
| 1232 |     char *sub2 = NULL; | 
|---|
| 1233 |     UINT tmp_size; | 
|---|
| 1234 |     // 引数チェック | 
|---|
| 1235 |     if (b == NULL || type == 0 || name == NULL || data == NULL) | 
|---|
| 1236 |     { | 
|---|
| 1237 |         return; | 
|---|
| 1238 |     } | 
|---|
| 1239 |  | 
|---|
| 1240 |     name2 = CfgEscape(name); | 
|---|
| 1241 |     data2 = CfgEscape(data); | 
|---|
| 1242 |     if (sub != NULL) | 
|---|
| 1243 |     { | 
|---|
| 1244 |         sub2 = CfgEscape(sub); | 
|---|
| 1245 |     } | 
|---|
| 1246 |  | 
|---|
| 1247 |     tmp_size = StrLen(name2) + StrLen(data2) + 2 + 64 + 1; | 
|---|
| 1248 |     tmp = Malloc(tmp_size); | 
|---|
| 1249 |  | 
|---|
| 1250 |     if (sub2 != NULL) | 
|---|
| 1251 |     { | 
|---|
| 1252 |         StrCpy(tmp, tmp_size, CfgTypeToStr(type)); | 
|---|
| 1253 |         StrCat(tmp, tmp_size, " "); | 
|---|
| 1254 |         StrCat(tmp, tmp_size, name2); | 
|---|
| 1255 |         StrCat(tmp, tmp_size, " "); | 
|---|
| 1256 |         StrCat(tmp, tmp_size, data2); | 
|---|
| 1257 |         StrCat(tmp, tmp_size, " "); | 
|---|
| 1258 |         StrCat(tmp, tmp_size, sub2); | 
|---|
| 1259 |     } | 
|---|
| 1260 |     else | 
|---|
| 1261 |     { | 
|---|
| 1262 |         StrCpy(tmp, tmp_size, CfgTypeToStr(type)); | 
|---|
| 1263 |         StrCat(tmp, tmp_size, " "); | 
|---|
| 1264 |         StrCat(tmp, tmp_size, name2); | 
|---|
| 1265 |         StrCat(tmp, tmp_size, " "); | 
|---|
| 1266 |         StrCat(tmp, tmp_size, data2); | 
|---|
| 1267 |     } | 
|---|
| 1268 |  | 
|---|
| 1269 |     Free(name2); | 
|---|
| 1270 |     Free(data2); | 
|---|
| 1271 |     if (sub2 != NULL) | 
|---|
| 1272 |     { | 
|---|
| 1273 |         Free(sub2); | 
|---|
| 1274 |     } | 
|---|
| 1275 |     CfgAddLine(b, tmp, depth); | 
|---|
| 1276 |     Free(tmp); | 
|---|
| 1277 | } | 
|---|
| 1278 |  | 
|---|
| 1279 | // データ種類文字列を整数値に変換 | 
|---|
| 1280 | UINT CfgStrToType(char *str) | 
|---|
| 1281 | { | 
|---|
| 1282 |     if (!StrCmpi(str, TAG_INT)) return ITEM_TYPE_INT; | 
|---|
| 1283 |     if (!StrCmpi(str, TAG_INT64)) return ITEM_TYPE_INT64; | 
|---|
| 1284 |     if (!StrCmpi(str, TAG_BYTE)) return ITEM_TYPE_BYTE; | 
|---|
| 1285 |     if (!StrCmpi(str, TAG_STRING)) return ITEM_TYPE_STRING; | 
|---|
| 1286 |     if (!StrCmpi(str, TAG_BOOL)) return ITEM_TYPE_BOOL; | 
|---|
| 1287 |     return 0; | 
|---|
| 1288 | } | 
|---|
| 1289 |  | 
|---|
| 1290 | // データの種類を文字列に変換 | 
|---|
| 1291 | char *CfgTypeToStr(UINT type) | 
|---|
| 1292 | { | 
|---|
| 1293 |     switch (type) | 
|---|
| 1294 |     { | 
|---|
| 1295 |     case ITEM_TYPE_INT: | 
|---|
| 1296 |         return TAG_INT; | 
|---|
| 1297 |     case ITEM_TYPE_INT64: | 
|---|
| 1298 |         return TAG_INT64; | 
|---|
| 1299 |     case ITEM_TYPE_BYTE: | 
|---|
| 1300 |         return TAG_BYTE; | 
|---|
| 1301 |     case ITEM_TYPE_STRING: | 
|---|
| 1302 |         return TAG_STRING; | 
|---|
| 1303 |     case ITEM_TYPE_BOOL: | 
|---|
| 1304 |         return TAG_BOOL; | 
|---|
| 1305 |     } | 
|---|
| 1306 |     return NULL; | 
|---|
| 1307 | } | 
|---|
| 1308 |  | 
|---|
| 1309 | // End 行を出力 | 
|---|
| 1310 | void CfgAddEnd(BUF *b, UINT depth) | 
|---|
| 1311 | { | 
|---|
| 1312 |     // 引数チェック | 
|---|
| 1313 |     if (b == NULL) | 
|---|
| 1314 |     { | 
|---|
| 1315 |         return; | 
|---|
| 1316 |     } | 
|---|
| 1317 |  | 
|---|
| 1318 |     CfgAddLine(b, "}", depth); | 
|---|
| 1319 | //  CfgAddLine(b, TAG_END, depth); | 
|---|
| 1320 | } | 
|---|
| 1321 |  | 
|---|
| 1322 | // Declare 行を出力 | 
|---|
| 1323 | void CfgAddDeclare(BUF *b, char *name, UINT depth) | 
|---|
| 1324 | { | 
|---|
| 1325 |     char *tmp; | 
|---|
| 1326 |     char *name2; | 
|---|
| 1327 |     UINT tmp_size; | 
|---|
| 1328 |     // 引数チェック | 
|---|
| 1329 |     if (b == NULL || name == NULL) | 
|---|
| 1330 |     { | 
|---|
| 1331 |         return; | 
|---|
| 1332 |     } | 
|---|
| 1333 |  | 
|---|
| 1334 |     name2 = CfgEscape(name); | 
|---|
| 1335 |  | 
|---|
| 1336 |     tmp_size = StrLen(name2) + 2 + StrLen(TAG_DECLARE); | 
|---|
| 1337 |     tmp = Malloc(tmp_size); | 
|---|
| 1338 |  | 
|---|
| 1339 |     Format(tmp, 0, "%s %s", TAG_DECLARE, name2); | 
|---|
| 1340 |     CfgAddLine(b, tmp, depth); | 
|---|
| 1341 |     CfgAddLine(b, "{", depth); | 
|---|
| 1342 |     Free(tmp); | 
|---|
| 1343 |     Free(name2); | 
|---|
| 1344 | } | 
|---|
| 1345 |  | 
|---|
| 1346 | // 1 行を出力 | 
|---|
| 1347 | void CfgAddLine(BUF *b, char *str, UINT depth) | 
|---|
| 1348 | { | 
|---|
| 1349 |     UINT i; | 
|---|
| 1350 |     // 引数チェック | 
|---|
| 1351 |     if (b == NULL) | 
|---|
| 1352 |     { | 
|---|
| 1353 |         return; | 
|---|
| 1354 |     } | 
|---|
| 1355 |  | 
|---|
| 1356 |     for (i = 0;i < depth;i++) | 
|---|
| 1357 |     { | 
|---|
| 1358 |         WriteBuf(b, "\t", 1); | 
|---|
| 1359 |     } | 
|---|
| 1360 |     WriteBuf(b, str, StrLen(str)); | 
|---|
| 1361 |     WriteBuf(b, "\r\n", 2); | 
|---|
| 1362 | } | 
|---|
| 1363 |  | 
|---|
| 1364 | // フォルダをストリームに変換 | 
|---|
| 1365 | BUF *CfgFolderToBuf(FOLDER *f, bool textmode) | 
|---|
| 1366 | { | 
|---|
| 1367 |     return CfgFolderToBufEx(f, textmode, false); | 
|---|
| 1368 | } | 
|---|
| 1369 | BUF *CfgFolderToBufEx(FOLDER *f, bool textmode, bool no_banner) | 
|---|
| 1370 | { | 
|---|
| 1371 |     // 引数チェック | 
|---|
| 1372 |     if (f == NULL) | 
|---|
| 1373 |     { | 
|---|
| 1374 |         return NULL; | 
|---|
| 1375 |     } | 
|---|
| 1376 |  | 
|---|
| 1377 |     if (textmode) | 
|---|
| 1378 |     { | 
|---|
| 1379 |         return CfgFolderToBufTextEx(f, no_banner); | 
|---|
| 1380 |     } | 
|---|
| 1381 |     else | 
|---|
| 1382 |     { | 
|---|
| 1383 |         return CfgFolderToBufBin(f);; | 
|---|
| 1384 |     } | 
|---|
| 1385 | } | 
|---|
| 1386 |  | 
|---|
| 1387 | // 文字列のエスケープ復元 | 
|---|
| 1388 | char *CfgUnescape(char *str) | 
|---|
| 1389 | { | 
|---|
| 1390 |     char *tmp; | 
|---|
| 1391 |     char *ret; | 
|---|
| 1392 |     char tmp2[16]; | 
|---|
| 1393 |     UINT len, wp, i; | 
|---|
| 1394 |     UINT code; | 
|---|
| 1395 |     // 引数チェック | 
|---|
| 1396 |     if (str == NULL) | 
|---|
| 1397 |     { | 
|---|
| 1398 |         return NULL; | 
|---|
| 1399 |     } | 
|---|
| 1400 |  | 
|---|
| 1401 |     len = StrLen(str); | 
|---|
| 1402 |     tmp = ZeroMalloc(len + 1); | 
|---|
| 1403 |     wp = 0; | 
|---|
| 1404 |     if (len == 1 && str[0] == '$') | 
|---|
| 1405 |     { | 
|---|
| 1406 |         // 空文字 | 
|---|
| 1407 |         tmp[0] = 0; | 
|---|
| 1408 |     } | 
|---|
| 1409 |     else | 
|---|
| 1410 |     { | 
|---|
| 1411 |         for (i = 0;i < len;i++) | 
|---|
| 1412 |         { | 
|---|
| 1413 |             if (str[i] != '$') | 
|---|
| 1414 |             { | 
|---|
| 1415 |                 tmp[wp++] = str[i]; | 
|---|
| 1416 |             } | 
|---|
| 1417 |             else | 
|---|
| 1418 |             { | 
|---|
| 1419 |                 tmp2[0] = '0'; | 
|---|
| 1420 |                 tmp2[1] = 'x'; | 
|---|
| 1421 |                 tmp2[2] = str[i + 1]; | 
|---|
| 1422 |                 tmp2[3] = str[i + 2]; | 
|---|
| 1423 |                 i += 2; | 
|---|
| 1424 |                 tmp2[4] = 0; | 
|---|
| 1425 |                 code = ToInt(tmp2); | 
|---|
| 1426 |                 tmp[wp++] = (char)code; | 
|---|
| 1427 |             } | 
|---|
| 1428 |         } | 
|---|
| 1429 |     } | 
|---|
| 1430 |     ret = Malloc(StrLen(tmp) + 1); | 
|---|
| 1431 |     StrCpy(ret, StrLen(tmp) + 1, tmp); | 
|---|
| 1432 |     Free(tmp); | 
|---|
| 1433 |     return ret; | 
|---|
| 1434 | } | 
|---|
| 1435 |  | 
|---|
| 1436 | // 文字列のエスケープ | 
|---|
| 1437 | char *CfgEscape(char *str) | 
|---|
| 1438 | { | 
|---|
| 1439 |     char *tmp; | 
|---|
| 1440 |     char *ret; | 
|---|
| 1441 |     char tmp2[16]; | 
|---|
| 1442 |     UINT len; | 
|---|
| 1443 |     UINT wp, i; | 
|---|
| 1444 |     // 引数チェック | 
|---|
| 1445 |     if (str == NULL) | 
|---|
| 1446 |     { | 
|---|
| 1447 |         return NULL; | 
|---|
| 1448 |     } | 
|---|
| 1449 |  | 
|---|
| 1450 |     len = StrLen(str); | 
|---|
| 1451 |     tmp = ZeroMalloc(len * 3 + 2); | 
|---|
| 1452 |     if (len == 0) | 
|---|
| 1453 |     { | 
|---|
| 1454 |         // 空文字 | 
|---|
| 1455 |         StrCpy(tmp, (len * 3 + 2), "$"); | 
|---|
| 1456 |     } | 
|---|
| 1457 |     else | 
|---|
| 1458 |     { | 
|---|
| 1459 |         // 空文字以外 | 
|---|
| 1460 |         wp = 0; | 
|---|
| 1461 |         for (i = 0;i < len;i++) | 
|---|
| 1462 |         { | 
|---|
| 1463 |             if (CfgCheckCharForName(str[i])) | 
|---|
| 1464 |             { | 
|---|
| 1465 |                 tmp[wp++] = str[i]; | 
|---|
| 1466 |             } | 
|---|
| 1467 |             else | 
|---|
| 1468 |             { | 
|---|
| 1469 |                 tmp[wp++] = '$'; | 
|---|
| 1470 |                 Format(tmp2, sizeof(tmp2), "%02X", (UINT)str[i]); | 
|---|
| 1471 |                 tmp[wp++] = tmp2[0]; | 
|---|
| 1472 |                 tmp[wp++] = tmp2[1]; | 
|---|
| 1473 |             } | 
|---|
| 1474 |         } | 
|---|
| 1475 |     } | 
|---|
| 1476 |     ret = Malloc(StrLen(tmp) + 1); | 
|---|
| 1477 |     StrCpy(ret, 0, tmp); | 
|---|
| 1478 |     Free(tmp); | 
|---|
| 1479 |     return ret; | 
|---|
| 1480 | } | 
|---|
| 1481 |  | 
|---|
| 1482 | // 名前に使用することができる文字かどうかチェック | 
|---|
| 1483 | bool CfgCheckCharForName(char c) | 
|---|
| 1484 | { | 
|---|
| 1485 |     if (c >= 0 && c <= 31) | 
|---|
| 1486 |     { | 
|---|
| 1487 |         return false; | 
|---|
| 1488 |     } | 
|---|
| 1489 |     if (c == ' ' || c == '\t') | 
|---|
| 1490 |     { | 
|---|
| 1491 |         return false; | 
|---|
| 1492 |     } | 
|---|
| 1493 |     if (c == '$') | 
|---|
| 1494 |     { | 
|---|
| 1495 |         return false; | 
|---|
| 1496 |     } | 
|---|
| 1497 |     return true; | 
|---|
| 1498 | } | 
|---|
| 1499 |  | 
|---|
| 1500 | // string 型の値の取得 | 
|---|
| 1501 | bool CfgGetStr(FOLDER *f, char *name, char *str, UINT size) | 
|---|
| 1502 | { | 
|---|
| 1503 |     wchar_t *tmp; | 
|---|
| 1504 |     UINT tmp_size; | 
|---|
| 1505 |     // 引数チェック | 
|---|
| 1506 |     if (f == NULL || name == NULL || str == NULL) | 
|---|
| 1507 |     { | 
|---|
| 1508 |         return false; | 
|---|
| 1509 |     } | 
|---|
| 1510 |  | 
|---|
| 1511 |     str[0] = 0; | 
|---|
| 1512 |  | 
|---|
| 1513 |     // unicode 文字列を一時的に取得する | 
|---|
| 1514 |     tmp_size = size * 4 + 10; // 一応これくらいとっておく | 
|---|
| 1515 |     tmp = Malloc(tmp_size); | 
|---|
| 1516 |     if (CfgGetUniStr(f, name, tmp, tmp_size) == false) | 
|---|
| 1517 |     { | 
|---|
| 1518 |         // 失敗 | 
|---|
| 1519 |         Free(tmp); | 
|---|
| 1520 |         return false; | 
|---|
| 1521 |     } | 
|---|
| 1522 |  | 
|---|
| 1523 |     // ANSI 文字列にコピー | 
|---|
| 1524 |     UniToStr(str, size, tmp); | 
|---|
| 1525 |     Free(tmp); | 
|---|
| 1526 |  | 
|---|
| 1527 |     return true; | 
|---|
| 1528 | } | 
|---|
| 1529 |  | 
|---|
| 1530 | // unicode_string 型の値の取得 | 
|---|
| 1531 | bool CfgGetUniStr(FOLDER *f, char *name, wchar_t *str, UINT size) | 
|---|
| 1532 | { | 
|---|
| 1533 |     ITEM *t; | 
|---|
| 1534 |     // 引数チェック | 
|---|
| 1535 |     if (f == NULL || name == NULL || str == NULL) | 
|---|
| 1536 |     { | 
|---|
| 1537 |         return false; | 
|---|
| 1538 |     } | 
|---|
| 1539 |  | 
|---|
| 1540 |     str[0] = 0; | 
|---|
| 1541 |  | 
|---|
| 1542 |     t = CfgFindItem(f, name); | 
|---|
| 1543 |     if (t == NULL) | 
|---|
| 1544 |     { | 
|---|
| 1545 |         return false; | 
|---|
| 1546 |     } | 
|---|
| 1547 |     if (t->Type != ITEM_TYPE_STRING) | 
|---|
| 1548 |     { | 
|---|
| 1549 |         return false; | 
|---|
| 1550 |     } | 
|---|
| 1551 |     UniStrCpy(str, size, t->Buf); | 
|---|
| 1552 |     return true; | 
|---|
| 1553 | } | 
|---|
| 1554 |  | 
|---|
| 1555 | // フォルダの存在を確認 | 
|---|
| 1556 | bool CfgIsFolder(FOLDER *f, char *name) | 
|---|
| 1557 | { | 
|---|
| 1558 |     // 引数チェック | 
|---|
| 1559 |     if (f == NULL || name == NULL) | 
|---|
| 1560 |     { | 
|---|
| 1561 |         return false; | 
|---|
| 1562 |     } | 
|---|
| 1563 |  | 
|---|
| 1564 |     return (CfgGetFolder(f, name) == NULL) ? false : true; | 
|---|
| 1565 | } | 
|---|
| 1566 |  | 
|---|
| 1567 | // アイテムの存在を確認 | 
|---|
| 1568 | bool CfgIsItem(FOLDER *f, char *name) | 
|---|
| 1569 | { | 
|---|
| 1570 |     ITEM *t; | 
|---|
| 1571 |     // 引数チェック | 
|---|
| 1572 |     if (f == NULL || name == NULL) | 
|---|
| 1573 |     { | 
|---|
| 1574 |         return false; | 
|---|
| 1575 |     } | 
|---|
| 1576 |  | 
|---|
| 1577 |     t = CfgFindItem(f, name); | 
|---|
| 1578 |     if (t == NULL) | 
|---|
| 1579 |     { | 
|---|
| 1580 |         return false; | 
|---|
| 1581 |     } | 
|---|
| 1582 |  | 
|---|
| 1583 |     return true; | 
|---|
| 1584 | } | 
|---|
| 1585 |  | 
|---|
| 1586 | // byte[] 型を BUF で取得 | 
|---|
| 1587 | BUF *CfgGetBuf(FOLDER *f, char *name) | 
|---|
| 1588 | { | 
|---|
| 1589 |     ITEM *t; | 
|---|
| 1590 |     BUF *b; | 
|---|
| 1591 |     // 引数チェック | 
|---|
| 1592 |     if (f == NULL || name == NULL) | 
|---|
| 1593 |     { | 
|---|
| 1594 |         return NULL; | 
|---|
| 1595 |     } | 
|---|
| 1596 |  | 
|---|
| 1597 |     t = CfgFindItem(f, name); | 
|---|
| 1598 |     if (t == NULL) | 
|---|
| 1599 |     { | 
|---|
| 1600 |         return NULL; | 
|---|
| 1601 |     } | 
|---|
| 1602 |  | 
|---|
| 1603 |     b = NewBuf(); | 
|---|
| 1604 |     WriteBuf(b, t->Buf, t->size); | 
|---|
| 1605 |     SeekBuf(b, 0, 0); | 
|---|
| 1606 |  | 
|---|
| 1607 |     return b; | 
|---|
| 1608 | } | 
|---|
| 1609 |  | 
|---|
| 1610 | // byte[] 型の値の取得 | 
|---|
| 1611 | UINT CfgGetByte(FOLDER *f, char *name, void *buf, UINT size) | 
|---|
| 1612 | { | 
|---|
| 1613 |     ITEM *t; | 
|---|
| 1614 |     // 引数チェック | 
|---|
| 1615 |     if (f == NULL || name == NULL || buf == NULL) | 
|---|
| 1616 |     { | 
|---|
| 1617 |         return 0; | 
|---|
| 1618 |     } | 
|---|
| 1619 |  | 
|---|
| 1620 |     t = CfgFindItem(f, name); | 
|---|
| 1621 |     if (t == NULL) | 
|---|
| 1622 |     { | 
|---|
| 1623 |         return 0; | 
|---|
| 1624 |     } | 
|---|
| 1625 |     if (t->Type != ITEM_TYPE_BYTE) | 
|---|
| 1626 |     { | 
|---|
| 1627 |         return 0; | 
|---|
| 1628 |     } | 
|---|
| 1629 |     if (t->size <= size) | 
|---|
| 1630 |     { | 
|---|
| 1631 |         Copy(buf, t->Buf, t->size); | 
|---|
| 1632 |         return t->size; | 
|---|
| 1633 |     } | 
|---|
| 1634 |     else | 
|---|
| 1635 |     { | 
|---|
| 1636 |         Copy(buf, t->Buf, size); | 
|---|
| 1637 |         return t->size; | 
|---|
| 1638 |     } | 
|---|
| 1639 | } | 
|---|
| 1640 |  | 
|---|
| 1641 | // int64 型の値の取得 | 
|---|
| 1642 | UINT64 CfgGetInt64(FOLDER *f, char *name) | 
|---|
| 1643 | { | 
|---|
| 1644 |     ITEM *t; | 
|---|
| 1645 |     UINT64 *ret; | 
|---|
| 1646 |     // 引数チェック | 
|---|
| 1647 |     if (f == NULL || name == NULL) | 
|---|
| 1648 |     { | 
|---|
| 1649 |         return 0; | 
|---|
| 1650 |     } | 
|---|
| 1651 |  | 
|---|
| 1652 |     t = CfgFindItem(f, name); | 
|---|
| 1653 |     if (t == NULL) | 
|---|
| 1654 |     { | 
|---|
| 1655 |         return 0; | 
|---|
| 1656 |     } | 
|---|
| 1657 |     if (t->Type != ITEM_TYPE_INT64) | 
|---|
| 1658 |     { | 
|---|
| 1659 |         return 0; | 
|---|
| 1660 |     } | 
|---|
| 1661 |     if (t->size != sizeof(UINT64)) | 
|---|
| 1662 |     { | 
|---|
| 1663 |         return 0; | 
|---|
| 1664 |     } | 
|---|
| 1665 |  | 
|---|
| 1666 |     ret = (UINT64 *)t->Buf; | 
|---|
| 1667 |     return *ret; | 
|---|
| 1668 | } | 
|---|
| 1669 |  | 
|---|
| 1670 | // bool 型の値の取得 | 
|---|
| 1671 | bool CfgGetBool(FOLDER *f, char *name) | 
|---|
| 1672 | { | 
|---|
| 1673 |     ITEM *t; | 
|---|
| 1674 |     bool *ret; | 
|---|
| 1675 |     // 引数チェック | 
|---|
| 1676 |     if (f == NULL || name == NULL) | 
|---|
| 1677 |     { | 
|---|
| 1678 |         return 0; | 
|---|
| 1679 |     } | 
|---|
| 1680 |  | 
|---|
| 1681 |     t = CfgFindItem(f, name); | 
|---|
| 1682 |     if (t == NULL) | 
|---|
| 1683 |     { | 
|---|
| 1684 |         return 0; | 
|---|
| 1685 |     } | 
|---|
| 1686 |     if (t->Type != ITEM_TYPE_BOOL) | 
|---|
| 1687 |     { | 
|---|
| 1688 |         return 0; | 
|---|
| 1689 |     } | 
|---|
| 1690 |     if (t->size != sizeof(bool)) | 
|---|
| 1691 |     { | 
|---|
| 1692 |         return 0; | 
|---|
| 1693 |     } | 
|---|
| 1694 |  | 
|---|
| 1695 |     ret = (bool *)t->Buf; | 
|---|
| 1696 |     if (*ret == false) | 
|---|
| 1697 |     { | 
|---|
| 1698 |         return false; | 
|---|
| 1699 |     } | 
|---|
| 1700 |     else | 
|---|
| 1701 |     { | 
|---|
| 1702 |         return true; | 
|---|
| 1703 |     } | 
|---|
| 1704 | } | 
|---|
| 1705 |  | 
|---|
| 1706 | // int 型の値の取得 | 
|---|
| 1707 | UINT CfgGetInt(FOLDER *f, char *name) | 
|---|
| 1708 | { | 
|---|
| 1709 |     ITEM *t; | 
|---|
| 1710 |     UINT *ret; | 
|---|
| 1711 |     // 引数チェック | 
|---|
| 1712 |     if (f == NULL || name == NULL) | 
|---|
| 1713 |     { | 
|---|
| 1714 |         return 0; | 
|---|
| 1715 |     } | 
|---|
| 1716 |  | 
|---|
| 1717 |     t = CfgFindItem(f, name); | 
|---|
| 1718 |     if (t == NULL) | 
|---|
| 1719 |     { | 
|---|
| 1720 |         return 0; | 
|---|
| 1721 |     } | 
|---|
| 1722 |     if (t->Type != ITEM_TYPE_INT) | 
|---|
| 1723 |     { | 
|---|
| 1724 |         return 0; | 
|---|
| 1725 |     } | 
|---|
| 1726 |     if (t->size != sizeof(UINT)) | 
|---|
| 1727 |     { | 
|---|
| 1728 |         return 0; | 
|---|
| 1729 |     } | 
|---|
| 1730 |  | 
|---|
| 1731 |     ret = (UINT *)t->Buf; | 
|---|
| 1732 |     return *ret; | 
|---|
| 1733 | } | 
|---|
| 1734 |  | 
|---|
| 1735 | // アイテムの検索 | 
|---|
| 1736 | ITEM *CfgFindItem(FOLDER *parent, char *name) | 
|---|
| 1737 | { | 
|---|
| 1738 |     ITEM *t, tt; | 
|---|
| 1739 |     // 引数チェック | 
|---|
| 1740 |     if (parent == NULL || name == NULL) | 
|---|
| 1741 |     { | 
|---|
| 1742 |         return NULL; | 
|---|
| 1743 |     } | 
|---|
| 1744 |  | 
|---|
| 1745 |     tt.Name = ZeroMalloc(StrLen(name) + 1); | 
|---|
| 1746 |     StrCpy(tt.Name, 0, name); | 
|---|
| 1747 |     t = Search(parent->Items, &tt); | 
|---|
| 1748 |     Free(tt.Name); | 
|---|
| 1749 |  | 
|---|
| 1750 |     return t; | 
|---|
| 1751 | } | 
|---|
| 1752 |  | 
|---|
| 1753 | // フォルダの取得 | 
|---|
| 1754 | FOLDER *CfgGetFolder(FOLDER *parent, char *name) | 
|---|
| 1755 | { | 
|---|
| 1756 |     return CfgFindFolder(parent, name); | 
|---|
| 1757 | } | 
|---|
| 1758 |  | 
|---|
| 1759 | // フォルダの検索 | 
|---|
| 1760 | FOLDER *CfgFindFolder(FOLDER *parent, char *name) | 
|---|
| 1761 | { | 
|---|
| 1762 |     FOLDER *f, ff; | 
|---|
| 1763 |     // 引数チェック | 
|---|
| 1764 |     if (parent == NULL || name == NULL) | 
|---|
| 1765 |     { | 
|---|
| 1766 |         return NULL; | 
|---|
| 1767 |     } | 
|---|
| 1768 |  | 
|---|
| 1769 |     ff.Name = ZeroMalloc(StrLen(name) + 1); | 
|---|
| 1770 |     StrCpy(ff.Name, 0, name); | 
|---|
| 1771 |     f = Search(parent->Folders, &ff); | 
|---|
| 1772 |     Free(ff.Name); | 
|---|
| 1773 |  | 
|---|
| 1774 |     return f; | 
|---|
| 1775 | } | 
|---|
| 1776 |  | 
|---|
| 1777 | // string 型の追加 | 
|---|
| 1778 | ITEM *CfgAddStr(FOLDER *f, char *name, char *str) | 
|---|
| 1779 | { | 
|---|
| 1780 |     wchar_t *tmp; | 
|---|
| 1781 |     UINT tmp_size; | 
|---|
| 1782 |     ITEM *t; | 
|---|
| 1783 |     // 引数チェック | 
|---|
| 1784 |     if (f == NULL || name == NULL || str == NULL) | 
|---|
| 1785 |     { | 
|---|
| 1786 |         return NULL; | 
|---|
| 1787 |     } | 
|---|
| 1788 |  | 
|---|
| 1789 |     // Unicode 文字列に変換 | 
|---|
| 1790 |     tmp_size = CalcStrToUni(str); | 
|---|
| 1791 |     if (tmp_size == 0) | 
|---|
| 1792 |     { | 
|---|
| 1793 |         return NULL; | 
|---|
| 1794 |     } | 
|---|
| 1795 |     tmp = Malloc(tmp_size); | 
|---|
| 1796 |     StrToUni(tmp, tmp_size, str); | 
|---|
| 1797 |     t = CfgAddUniStr(f, name, tmp); | 
|---|
| 1798 |     Free(tmp); | 
|---|
| 1799 |  | 
|---|
| 1800 |     return t; | 
|---|
| 1801 | } | 
|---|
| 1802 |  | 
|---|
| 1803 | // unicode_string 型の追加 | 
|---|
| 1804 | ITEM *CfgAddUniStr(FOLDER *f, char *name, wchar_t *str) | 
|---|
| 1805 | { | 
|---|
| 1806 |     // 引数チェック | 
|---|
| 1807 |     if (f == NULL || name == NULL || str == NULL) | 
|---|
| 1808 |     { | 
|---|
| 1809 |         return NULL; | 
|---|
| 1810 |     } | 
|---|
| 1811 |  | 
|---|
| 1812 |     return CfgCreateItem(f, name, ITEM_TYPE_STRING, str, UniStrSize(str)); | 
|---|
| 1813 | } | 
|---|
| 1814 |  | 
|---|
| 1815 | // バイナリの追加 | 
|---|
| 1816 | ITEM *CfgAddBuf(FOLDER *f, char *name, BUF *b) | 
|---|
| 1817 | { | 
|---|
| 1818 |     // 引数チェック | 
|---|
| 1819 |     if (f == NULL || name == NULL || b == NULL) | 
|---|
| 1820 |     { | 
|---|
| 1821 |         return NULL; | 
|---|
| 1822 |     } | 
|---|
| 1823 |     return CfgAddByte(f, name, b->Buf, b->Size); | 
|---|
| 1824 | } | 
|---|
| 1825 |  | 
|---|
| 1826 | // バイト型の追加 | 
|---|
| 1827 | ITEM *CfgAddByte(FOLDER *f, char *name, void *buf, UINT size) | 
|---|
| 1828 | { | 
|---|
| 1829 |     // 引数チェック | 
|---|
| 1830 |     if (f == NULL || name == NULL || buf == NULL) | 
|---|
| 1831 |     { | 
|---|
| 1832 |         return NULL; | 
|---|
| 1833 |     } | 
|---|
| 1834 |     return CfgCreateItem(f, name, ITEM_TYPE_BYTE, buf, size); | 
|---|
| 1835 | } | 
|---|
| 1836 |  | 
|---|
| 1837 | // 64bit 整数型の追加 | 
|---|
| 1838 | ITEM *CfgAddInt64(FOLDER *f, char *name, UINT64 i) | 
|---|
| 1839 | { | 
|---|
| 1840 |     // 引数チェック | 
|---|
| 1841 |     if (f == NULL || name == NULL) | 
|---|
| 1842 |     { | 
|---|
| 1843 |         return NULL; | 
|---|
| 1844 |     } | 
|---|
| 1845 |     return CfgCreateItem(f, name, ITEM_TYPE_INT64, &i, sizeof(UINT64)); | 
|---|
| 1846 | } | 
|---|
| 1847 |  | 
|---|
| 1848 | // IP アドレス型の取得 | 
|---|
| 1849 | bool CfgGetIp(FOLDER *f, char *name, struct IP *ip) | 
|---|
| 1850 | { | 
|---|
| 1851 |     char tmp[MAX_SIZE]; | 
|---|
| 1852 |     // 引数チェック | 
|---|
| 1853 |     if (f == NULL || name == NULL || ip == NULL) | 
|---|
| 1854 |     { | 
|---|
| 1855 |         return false; | 
|---|
| 1856 |     } | 
|---|
| 1857 |  | 
|---|
| 1858 |     Zero(ip, sizeof(IP)); | 
|---|
| 1859 |  | 
|---|
| 1860 |     if (CfgGetStr(f, name, tmp, sizeof(tmp)) == false) | 
|---|
| 1861 |     { | 
|---|
| 1862 |         return false; | 
|---|
| 1863 |     } | 
|---|
| 1864 |  | 
|---|
| 1865 |     if (StrToIP(ip, tmp) == false) | 
|---|
| 1866 |     { | 
|---|
| 1867 |         return false; | 
|---|
| 1868 |     } | 
|---|
| 1869 |  | 
|---|
| 1870 |     return true; | 
|---|
| 1871 | } | 
|---|
| 1872 | UINT CfgGetIp32(FOLDER *f, char *name) | 
|---|
| 1873 | { | 
|---|
| 1874 |     IP p; | 
|---|
| 1875 |     // 引数チェック | 
|---|
| 1876 |     if (f == NULL || name == NULL) | 
|---|
| 1877 |     { | 
|---|
| 1878 |         return 0; | 
|---|
| 1879 |     } | 
|---|
| 1880 |  | 
|---|
| 1881 |     if (CfgGetIp(f, name, &p) == false) | 
|---|
| 1882 |     { | 
|---|
| 1883 |         return 0; | 
|---|
| 1884 |     } | 
|---|
| 1885 |  | 
|---|
| 1886 |     return IPToUINT(&p); | 
|---|
| 1887 | } | 
|---|
| 1888 | bool CfgGetIp6Addr(FOLDER *f, char *name, IPV6_ADDR *addr) | 
|---|
| 1889 | { | 
|---|
| 1890 |     IP ip; | 
|---|
| 1891 |     // 引数チェック | 
|---|
| 1892 |     Zero(addr, sizeof(IPV6_ADDR)); | 
|---|
| 1893 |     if (f == NULL || name == NULL || addr == NULL) | 
|---|
| 1894 |     { | 
|---|
| 1895 |         return false; | 
|---|
| 1896 |     } | 
|---|
| 1897 |  | 
|---|
| 1898 |     if (CfgGetIp(f, name, &ip) == false) | 
|---|
| 1899 |     { | 
|---|
| 1900 |         return false; | 
|---|
| 1901 |     } | 
|---|
| 1902 |  | 
|---|
| 1903 |     if (IsIP6(&ip) == false) | 
|---|
| 1904 |     { | 
|---|
| 1905 |         return false; | 
|---|
| 1906 |     } | 
|---|
| 1907 |  | 
|---|
| 1908 |     if (IPToIPv6Addr(addr, &ip) == false) | 
|---|
| 1909 |     { | 
|---|
| 1910 |         return false; | 
|---|
| 1911 |     } | 
|---|
| 1912 |  | 
|---|
| 1913 |     return true; | 
|---|
| 1914 | } | 
|---|
| 1915 |  | 
|---|
| 1916 | // IP アドレス型の追加 | 
|---|
| 1917 | ITEM *CfgAddIp(FOLDER *f, char *name, struct IP *ip) | 
|---|
| 1918 | { | 
|---|
| 1919 |     char tmp[MAX_SIZE]; | 
|---|
| 1920 |     // 引数チェック | 
|---|
| 1921 |     if (f == NULL || name == NULL || ip == NULL) | 
|---|
| 1922 |     { | 
|---|
| 1923 |         return NULL; | 
|---|
| 1924 |     } | 
|---|
| 1925 |  | 
|---|
| 1926 |     IPToStr(tmp, sizeof(tmp), ip); | 
|---|
| 1927 |  | 
|---|
| 1928 |     return CfgAddStr(f, name, tmp); | 
|---|
| 1929 | } | 
|---|
| 1930 | ITEM *CfgAddIp32(FOLDER *f, char *name, UINT ip) | 
|---|
| 1931 | { | 
|---|
| 1932 |     IP p; | 
|---|
| 1933 |     // 引数チェック | 
|---|
| 1934 |     if (f == NULL || name == NULL) | 
|---|
| 1935 |     { | 
|---|
| 1936 |         return NULL; | 
|---|
| 1937 |     } | 
|---|
| 1938 |  | 
|---|
| 1939 |     UINTToIP(&p, ip); | 
|---|
| 1940 |  | 
|---|
| 1941 |     return CfgAddIp(f, name, &p); | 
|---|
| 1942 | } | 
|---|
| 1943 | ITEM *CfgAddIp6Addr(FOLDER *f, char *name, IPV6_ADDR *addr) | 
|---|
| 1944 | { | 
|---|
| 1945 |     IP ip; | 
|---|
| 1946 |     // 引数チェック | 
|---|
| 1947 |     if (f == NULL || name == NULL || addr == NULL) | 
|---|
| 1948 |     { | 
|---|
| 1949 |         return NULL; | 
|---|
| 1950 |     } | 
|---|
| 1951 |  | 
|---|
| 1952 |     IPv6AddrToIP(&ip, addr); | 
|---|
| 1953 |  | 
|---|
| 1954 |     return CfgAddIp(f, name, &ip); | 
|---|
| 1955 | } | 
|---|
| 1956 |  | 
|---|
| 1957 | // 整数型の追加 | 
|---|
| 1958 | ITEM *CfgAddInt(FOLDER *f, char *name, UINT i) | 
|---|
| 1959 | { | 
|---|
| 1960 |     // 引数チェック | 
|---|
| 1961 |     if (f == NULL || name == NULL) | 
|---|
| 1962 |     { | 
|---|
| 1963 |         return NULL; | 
|---|
| 1964 |     } | 
|---|
| 1965 |     return CfgCreateItem(f, name, ITEM_TYPE_INT, &i, sizeof(UINT)); | 
|---|
| 1966 | } | 
|---|
| 1967 |  | 
|---|
| 1968 | // bool 型の追加 | 
|---|
| 1969 | ITEM *CfgAddBool(FOLDER *f, char *name, bool b) | 
|---|
| 1970 | { | 
|---|
| 1971 |     bool v; | 
|---|
| 1972 |     // 引数チェック | 
|---|
| 1973 |     if (f == NULL || name == NULL) | 
|---|
| 1974 |     { | 
|---|
| 1975 |         return NULL; | 
|---|
| 1976 |     } | 
|---|
| 1977 |  | 
|---|
| 1978 |     v = b ? 1 : 0; | 
|---|
| 1979 |     return CfgCreateItem(f, name, ITEM_TYPE_BOOL, &b, sizeof(bool)); | 
|---|
| 1980 | } | 
|---|
| 1981 |  | 
|---|
| 1982 | // アイテム名の比較関数 | 
|---|
| 1983 | int CmpItemName(void *p1, void *p2) | 
|---|
| 1984 | { | 
|---|
| 1985 |     ITEM *f1, *f2; | 
|---|
| 1986 |     if (p1 == NULL || p2 == NULL) | 
|---|
| 1987 |     { | 
|---|
| 1988 |         return 0; | 
|---|
| 1989 |     } | 
|---|
| 1990 |     f1 = *(ITEM **)p1; | 
|---|
| 1991 |     f2 = *(ITEM **)p2; | 
|---|
| 1992 |     if (f1 == NULL || f2 == NULL) | 
|---|
| 1993 |     { | 
|---|
| 1994 |         return 0; | 
|---|
| 1995 |     } | 
|---|
| 1996 |     return StrCmpi(f1->Name, f2->Name); | 
|---|
| 1997 | } | 
|---|
| 1998 |  | 
|---|
| 1999 | // フォルダ名の比較関数 | 
|---|
| 2000 | int CmpFolderName(void *p1, void *p2) | 
|---|
| 2001 | { | 
|---|
| 2002 |     FOLDER *f1, *f2; | 
|---|
| 2003 |     if (p1 == NULL || p2 == NULL) | 
|---|
| 2004 |     { | 
|---|
| 2005 |         return 0; | 
|---|
| 2006 |     } | 
|---|
| 2007 |     f1 = *(FOLDER **)p1; | 
|---|
| 2008 |     f2 = *(FOLDER **)p2; | 
|---|
| 2009 |     if (f1 == NULL || f2 == NULL) | 
|---|
| 2010 |     { | 
|---|
| 2011 |         return 0; | 
|---|
| 2012 |     } | 
|---|
| 2013 |     return StrCmpi(f1->Name, f2->Name); | 
|---|
| 2014 | } | 
|---|
| 2015 |  | 
|---|
| 2016 | // アイテムの列挙 | 
|---|
| 2017 | void CfgEnumItem(FOLDER *f, ENUM_ITEM proc, void *param) | 
|---|
| 2018 | { | 
|---|
| 2019 |     UINT i; | 
|---|
| 2020 |     // 引数チェック | 
|---|
| 2021 |     if (f == NULL || proc == NULL) | 
|---|
| 2022 |     { | 
|---|
| 2023 |         return; | 
|---|
| 2024 |     } | 
|---|
| 2025 |      | 
|---|
| 2026 |     for (i = 0;i < LIST_NUM(f->Items);i++) | 
|---|
| 2027 |     { | 
|---|
| 2028 |         ITEM *tt = LIST_DATA(f->Items, i); | 
|---|
| 2029 |         if (proc(tt, param) == false) | 
|---|
| 2030 |         { | 
|---|
| 2031 |             break; | 
|---|
| 2032 |         } | 
|---|
| 2033 |     } | 
|---|
| 2034 | } | 
|---|
| 2035 |  | 
|---|
| 2036 | // フォルダを列挙してトークンリストに格納 | 
|---|
| 2037 | TOKEN_LIST *CfgEnumFolderToTokenList(FOLDER *f) | 
|---|
| 2038 | { | 
|---|
| 2039 |     TOKEN_LIST *t, *ret; | 
|---|
| 2040 |     UINT i; | 
|---|
| 2041 |     // 引数チェック | 
|---|
| 2042 |     if (f == NULL) | 
|---|
| 2043 |     { | 
|---|
| 2044 |         return NULL; | 
|---|
| 2045 |     } | 
|---|
| 2046 |  | 
|---|
| 2047 |     t = ZeroMalloc(sizeof(TOKEN_LIST)); | 
|---|
| 2048 |     t->NumTokens = LIST_NUM(f->Folders); | 
|---|
| 2049 |     t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); | 
|---|
| 2050 |  | 
|---|
| 2051 |     for (i = 0;i < t->NumTokens;i++) | 
|---|
| 2052 |     { | 
|---|
| 2053 |         FOLDER *ff = LIST_DATA(f->Folders, i); | 
|---|
| 2054 |         t->Token[i] = CopyStr(ff->Name); | 
|---|
| 2055 |     } | 
|---|
| 2056 |  | 
|---|
| 2057 |     ret = UniqueToken(t); | 
|---|
| 2058 |     FreeToken(t); | 
|---|
| 2059 |  | 
|---|
| 2060 |     return ret; | 
|---|
| 2061 | } | 
|---|
| 2062 |  | 
|---|
| 2063 | // アイテムを列挙してトークンリストに格納 | 
|---|
| 2064 | TOKEN_LIST *CfgEnumItemToTokenList(FOLDER *f) | 
|---|
| 2065 | { | 
|---|
| 2066 |     TOKEN_LIST *t, *ret; | 
|---|
| 2067 |     UINT i; | 
|---|
| 2068 |     // 引数チェック | 
|---|
| 2069 |     if (f == NULL) | 
|---|
| 2070 |     { | 
|---|
| 2071 |         return NULL; | 
|---|
| 2072 |     } | 
|---|
| 2073 |  | 
|---|
| 2074 |     t = ZeroMalloc(sizeof(TOKEN_LIST)); | 
|---|
| 2075 |     t->NumTokens = LIST_NUM(f->Items); | 
|---|
| 2076 |     t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); | 
|---|
| 2077 |  | 
|---|
| 2078 |     for (i = 0;i < t->NumTokens;i++) | 
|---|
| 2079 |     { | 
|---|
| 2080 |         FOLDER *ff = LIST_DATA(f->Items, i); | 
|---|
| 2081 |         t->Token[i] = CopyStr(ff->Name); | 
|---|
| 2082 |     } | 
|---|
| 2083 |  | 
|---|
| 2084 |     ret = UniqueToken(t); | 
|---|
| 2085 |     FreeToken(t); | 
|---|
| 2086 |  | 
|---|
| 2087 |     return ret; | 
|---|
| 2088 | } | 
|---|
| 2089 |  | 
|---|
| 2090 | // フォルダの列挙 | 
|---|
| 2091 | void CfgEnumFolder(FOLDER *f, ENUM_FOLDER proc, void *param) | 
|---|
| 2092 | { | 
|---|
| 2093 |     UINT i; | 
|---|
| 2094 |     // 引数チェック | 
|---|
| 2095 |     if (f == NULL || proc == NULL) | 
|---|
| 2096 |     { | 
|---|
| 2097 |         return; | 
|---|
| 2098 |     } | 
|---|
| 2099 |      | 
|---|
| 2100 |     for (i = 0;i < LIST_NUM(f->Folders);i++) | 
|---|
| 2101 |     { | 
|---|
| 2102 |         FOLDER *ff = LIST_DATA(f->Folders, i); | 
|---|
| 2103 |         if (proc(ff, param) == false) | 
|---|
| 2104 |         { | 
|---|
| 2105 |             break; | 
|---|
| 2106 |         } | 
|---|
| 2107 |  | 
|---|
| 2108 |         if ((i % 100) == 99) | 
|---|
| 2109 |         { | 
|---|
| 2110 |             YieldCpu(); | 
|---|
| 2111 |         } | 
|---|
| 2112 |     } | 
|---|
| 2113 | } | 
|---|
| 2114 |  | 
|---|
| 2115 | // アイテムの作成 | 
|---|
| 2116 | ITEM *CfgCreateItem(FOLDER *parent, char *name, UINT type, void *buf, UINT size) | 
|---|
| 2117 | { | 
|---|
| 2118 |     UINT name_size; | 
|---|
| 2119 |     ITEM *t; | 
|---|
| 2120 | #ifdef  CHECK_CFG_NAME_EXISTS | 
|---|
| 2121 |     ITEM tt; | 
|---|
| 2122 | #endif  // CHECK_CFG_NAME_EXISTS | 
|---|
| 2123 |     // 引数チェック | 
|---|
| 2124 |     if (parent == NULL || name == NULL || type == 0 || buf == NULL) | 
|---|
| 2125 |     { | 
|---|
| 2126 |         return NULL; | 
|---|
| 2127 |     } | 
|---|
| 2128 |  | 
|---|
| 2129 |     name_size = StrLen(name) + 1; | 
|---|
| 2130 |  | 
|---|
| 2131 | #ifdef  CHECK_CFG_NAME_EXISTS | 
|---|
| 2132 |  | 
|---|
| 2133 |     // すでに同名のアイテムが無いかどうか確認 | 
|---|
| 2134 |     tt.Name = ZeroMalloc(name_size); | 
|---|
| 2135 |     StrCpy(tt.Name, 0, name); | 
|---|
| 2136 |     t = Search(parent->Items, &tt); | 
|---|
| 2137 |     Free(tt.Name); | 
|---|
| 2138 |     if (t != NULL) | 
|---|
| 2139 |     { | 
|---|
| 2140 |         // 重複している | 
|---|
| 2141 |         return NULL; | 
|---|
| 2142 |     } | 
|---|
| 2143 |  | 
|---|
| 2144 | #endif  // CHECK_CFG_NAME_EXISTS | 
|---|
| 2145 |  | 
|---|
| 2146 |     t = ZeroMalloc(sizeof(ITEM)); | 
|---|
| 2147 |     t->Buf = Malloc(size); | 
|---|
| 2148 |     Copy(t->Buf, buf, size); | 
|---|
| 2149 |     t->Name = ZeroMalloc(name_size); | 
|---|
| 2150 |     StrCpy(t->Name, 0, name); | 
|---|
| 2151 |     t->Type = type; | 
|---|
| 2152 |     t->size = size; | 
|---|
| 2153 |     t->Parent = parent; | 
|---|
| 2154 |      | 
|---|
| 2155 |     // 親のリストに追加 | 
|---|
| 2156 |     Insert(parent->Items, t); | 
|---|
| 2157 |  | 
|---|
| 2158 |     return t; | 
|---|
| 2159 | } | 
|---|
| 2160 |  | 
|---|
| 2161 | // アイテムの削除 | 
|---|
| 2162 | void CfgDeleteItem(ITEM *t) | 
|---|
| 2163 | { | 
|---|
| 2164 |     // 引数チェック | 
|---|
| 2165 |     if (t == NULL) | 
|---|
| 2166 |     { | 
|---|
| 2167 |         return; | 
|---|
| 2168 |     } | 
|---|
| 2169 |  | 
|---|
| 2170 |     // 親のリストから削除 | 
|---|
| 2171 |     Delete(t->Parent->Items, t); | 
|---|
| 2172 |  | 
|---|
| 2173 |     // メモリ解放 | 
|---|
| 2174 |     Free(t->Buf); | 
|---|
| 2175 |     Free(t->Name); | 
|---|
| 2176 |     Free(t); | 
|---|
| 2177 | } | 
|---|
| 2178 |  | 
|---|
| 2179 |  | 
|---|
| 2180 | // フォルダの削除 | 
|---|
| 2181 | void CfgDeleteFolder(FOLDER *f) | 
|---|
| 2182 | { | 
|---|
| 2183 |     FOLDER **ff; | 
|---|
| 2184 |     ITEM **tt; | 
|---|
| 2185 |     UINT num, i; | 
|---|
| 2186 |     // 引数チェック | 
|---|
| 2187 |     if (f == NULL) | 
|---|
| 2188 |     { | 
|---|
| 2189 |         return; | 
|---|
| 2190 |     } | 
|---|
| 2191 |  | 
|---|
| 2192 |     // サブフォルダをすべて削除 | 
|---|
| 2193 |     num = LIST_NUM(f->Folders); | 
|---|
| 2194 |     ff = Malloc(sizeof(FOLDER *) * num); | 
|---|
| 2195 |     Copy(ff, f->Folders->p, sizeof(FOLDER *) * num); | 
|---|
| 2196 |     for (i = 0;i < num;i++) | 
|---|
| 2197 |     { | 
|---|
| 2198 |         CfgDeleteFolder(ff[i]); | 
|---|
| 2199 |     } | 
|---|
| 2200 |     Free(ff); | 
|---|
| 2201 |  | 
|---|
| 2202 |     // アイテムをすべて削除 | 
|---|
| 2203 |     num = LIST_NUM(f->Items); | 
|---|
| 2204 |     tt = Malloc(sizeof(ITEM *) * num); | 
|---|
| 2205 |     Copy(tt, f->Items->p, sizeof(ITEM *) * num); | 
|---|
| 2206 |     for (i = 0;i < num;i++) | 
|---|
| 2207 |     { | 
|---|
| 2208 |         CfgDeleteItem(tt[i]); | 
|---|
| 2209 |     } | 
|---|
| 2210 |     Free(tt); | 
|---|
| 2211 |  | 
|---|
| 2212 |     // メモリ解放 | 
|---|
| 2213 |     Free(f->Name); | 
|---|
| 2214 |     // 親のリストから削除 | 
|---|
| 2215 |     if (f->Parent != NULL) | 
|---|
| 2216 |     { | 
|---|
| 2217 |         Delete(f->Parent->Folders, f); | 
|---|
| 2218 |     } | 
|---|
| 2219 |     // リストの解放 | 
|---|
| 2220 |     ReleaseList(f->Folders); | 
|---|
| 2221 |     ReleaseList(f->Items); | 
|---|
| 2222 |  | 
|---|
| 2223 |     // 本体のメモリの解放 | 
|---|
| 2224 |     Free(f); | 
|---|
| 2225 | } | 
|---|
| 2226 |  | 
|---|
| 2227 | // ルートの作成 | 
|---|
| 2228 | FOLDER *CfgCreateRoot() | 
|---|
| 2229 | { | 
|---|
| 2230 |     return CfgCreateFolder(NULL, TAG_ROOT); | 
|---|
| 2231 | } | 
|---|
| 2232 |  | 
|---|
| 2233 | // フォルダの作成 | 
|---|
| 2234 | FOLDER *CfgCreateFolder(FOLDER *parent, char *name) | 
|---|
| 2235 | { | 
|---|
| 2236 |     UINT size; | 
|---|
| 2237 |     FOLDER *f; | 
|---|
| 2238 |     // 引数チェック | 
|---|
| 2239 |     if (name == NULL) | 
|---|
| 2240 |     { | 
|---|
| 2241 |         return NULL; | 
|---|
| 2242 |     } | 
|---|
| 2243 |  | 
|---|
| 2244 |     size = StrLen(name) + 1; | 
|---|
| 2245 |  | 
|---|
| 2246 | #ifdef  CHECK_CFG_NAME_EXISTS | 
|---|
| 2247 |  | 
|---|
| 2248 |     // 親のリストの名前を検査 | 
|---|
| 2249 |     if (parent != NULL) | 
|---|
| 2250 |     { | 
|---|
| 2251 |         FOLDER ff; | 
|---|
| 2252 |         ff.Name = ZeroMalloc(size); | 
|---|
| 2253 |         StrCpy(ff.Name, 0, name); | 
|---|
| 2254 |         f = Search(parent->Folders, &ff); | 
|---|
| 2255 |         Free(ff.Name); | 
|---|
| 2256 |         if (f != NULL) | 
|---|
| 2257 |         { | 
|---|
| 2258 |             // 既に同じ名前のフォルダが存在する | 
|---|
| 2259 |             return NULL; | 
|---|
| 2260 |         } | 
|---|
| 2261 |     } | 
|---|
| 2262 |  | 
|---|
| 2263 | #endif  // CHECK_CFG_NAME_EXISTS | 
|---|
| 2264 |  | 
|---|
| 2265 |     f = ZeroMalloc(sizeof(FOLDER)); | 
|---|
| 2266 |     f->Items = NewListFast(CmpItemName); | 
|---|
| 2267 |     f->Folders = NewListFast(CmpFolderName); | 
|---|
| 2268 |     f->Name = ZeroMalloc(size); | 
|---|
| 2269 |     StrCpy(f->Name, 0, name); | 
|---|
| 2270 |     f->Parent = parent; | 
|---|
| 2271 |  | 
|---|
| 2272 |     // 親のリストに追加 | 
|---|
| 2273 |     if (f->Parent != NULL) | 
|---|
| 2274 |     { | 
|---|
| 2275 |         Insert(f->Parent->Folders, f); | 
|---|
| 2276 |     } | 
|---|
| 2277 |     return f; | 
|---|
| 2278 | } | 
|---|
| 2279 |  | 
|---|
| 2280 |  | 
|---|