OSDN Git Service

Change the algorithm to encrypt all settings.
[ffftp/ffftp.git] / registry.c
1 /*=============================================================================\r
2 *                                                               レジストリ関係\r
3 *\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 // VC 8.0(2005)以上でのみ rand_s を利用可能\r
31 #if 1400 <= _MSC_VER\r
32 //#define _CRT_RAND_S\r
33 #endif\r
34 \r
35 #define STRICT\r
36 // IPv6対応\r
37 #include <winsock2.h>\r
38 #include <windows.h>\r
39 #include <stdio.h>\r
40 #include <stdlib.h>\r
41 #include <time.h>\r
42 #include <string.h>\r
43 #include <windowsx.h>\r
44 #include <process.h>\r
45 \r
46 \r
47 #include "common.h"\r
48 #include "resource.h"\r
49 #include "sample.h"\r
50 #include "sha.h"\r
51 #include "aes.h"\r
52 \r
53 \r
54 /*===== プロトタイプ =====*/\r
55 \r
56 static void SaveStr(HKEY hKey, char *Key, char *Str, char *DefaultStr);\r
57 static void SaveIntNum(HKEY hKey, char *Key, int Num, int DefaultNum);\r
58 static void MakeFontData(LOGFONT Font, HFONT hFont, char *Buf);\r
59 static int RestoreFontData(char *Str, LOGFONT *Font);\r
60 \r
61 static void EncodePassword(char *Str, char *Buf);\r
62 static void EncodePasswordOriginal(char *Str, char *Buf);\r
63 static void EncodePassword2(char *Str, char *Buf, const char *Key);\r
64 static void EncodePassword3(char *Str, char *Buf, const char *Key);\r
65 \r
66 static void DecodePassword(char *Str, char *Buf);\r
67 static void DecodePasswordOriginal(char *Str, char *Buf);\r
68 static void DecodePassword2(char *Str, char *Buf, const char *Key);\r
69 static void DecodePassword3(char *Str, char *Buf, const char *Key);\r
70 static int CreateAesKey(unsigned char *AesKey, const char* Key);\r
71 \r
72 static void SetRegType(int Type);\r
73 static int OpenReg(char *Name, void **Handle);\r
74 static int CreateReg(char *Name, void **Handle);\r
75 static int CloseReg(void *Handle);\r
76 static int OpenSubKey(void *Parent, char *Name, void **Handle);\r
77 static int CreateSubKey(void *Parent, char *Name, void **Handle);\r
78 static int CloseSubKey(void *Handle);\r
79 static int DeleteSubKey(void *Handle, char *Name);\r
80 static int DeleteValue(void *Handle, char *Name);\r
81 static int ReadIntValueFromReg(void *Handle, char *Name, int *Value);\r
82 static int WriteIntValueToReg(void *Handle, char *Name, int Value);\r
83 static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size);\r
84 static int WriteStringToReg(void *Handle, char *Name, char *Str);\r
85 static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Size);\r
86 static int WriteMultiStringToReg(void *Handle, char *Name, char *Str);\r
87 static int ReadBinaryFromReg(void *Handle, char *Name, void *Bin, DWORD Size);\r
88 static int WriteBinaryToReg(void *Handle, char *Name, void *Bin, int Len);\r
89 // 暗号化通信対応\r
90 static int StrCatOut(char *Src, int Len, char *Dst);\r
91 static int StrReadIn(char *Src, int Max, char *Dst);\r
92 \r
93 int CheckPasswordValidity( char* Password, int length, const char* HashStr );\r
94 void CreatePasswordHash( char* Password, int length, char* HashStr );\r
95 void SetHashSalt( DWORD salt );\r
96 \r
97 DWORD GetRandamDWRODValue(void);\r
98 \r
99 // 全設定暗号化対応\r
100 void MaskSettingsData(const char* Salt, int SaltLength, void* Data, DWORD Size, int EscapeZero);\r
101 void UnmaskSettingsData(const char* Salt, int SaltLength, void* Data, DWORD Size, int EscapeZero);\r
102 void CalculateSettingsDataChecksum(void* Data, DWORD Size);\r
103 \r
104 /* 2010.01.30 genta 追加 */\r
105 static char SecretKey[FMAX_PATH+1];\r
106 static int SecretKeyLength;\r
107 static int IsMasterPasswordError = PASSWORD_OK;\r
108 \r
109 static int IsRndSourceInit = 0;\r
110 static ulong RndSource[9];\r
111 \r
112 // UTF-8対応\r
113 static int IniKanjiCode = KANJI_NOCNV;\r
114 \r
115 // 全設定暗号化対応\r
116 static int EncryptSettings = NO;\r
117 static BYTE EncryptSettingsChecksum[20];\r
118 static int EncryptSettingsError = NO;\r
119 \r
120 /*===== 外部参照 =====*/\r
121 \r
122 /* 設定値 */\r
123 extern int WinPosX;\r
124 extern int WinPosY;\r
125 extern int WinWidth;\r
126 extern int WinHeight;\r
127 extern int LocalWidth;\r
128 extern int TaskHeight;\r
129 extern int LocalTabWidth[4];\r
130 extern int RemoteTabWidth[6];\r
131 extern char UserMailAdrs[USER_MAIL_LEN+1];\r
132 extern char ViewerName[VIEWERS][FMAX_PATH+1];\r
133 extern HFONT ListFont;\r
134 extern LOGFONT ListLogFont;\r
135 extern int LocalFileSort;\r
136 extern int LocalDirSort;\r
137 extern int RemoteFileSort;\r
138 extern int RemoteDirSort;\r
139 extern int TransMode;\r
140 extern int ConnectOnStart;\r
141 extern int DebugConsole;\r
142 extern int SaveWinPos;\r
143 extern char AsciiExt[ASCII_EXT_LEN+1];\r
144 extern int RecvMode;\r
145 extern int SendMode;\r
146 extern int MoveMode;\r
147 extern int ListType;\r
148 extern int CacheEntry;\r
149 extern int CacheSave;\r
150 extern char DefaultLocalPath[FMAX_PATH+1];\r
151 extern int SaveTimeStamp;\r
152 extern int FindMode;\r
153 extern int DotFile;\r
154 extern int DclickOpen;\r
155 extern SOUNDFILE Sound[SOUND_TYPES];\r
156 extern int FnameCnv;\r
157 extern int ConnectAndSet;\r
158 extern int TimeOut;\r
159 extern int RmEOF;\r
160 extern int RegType;\r
161 extern char FwallHost[HOST_ADRS_LEN+1];\r
162 extern char FwallUser[USER_NAME_LEN+1];\r
163 extern char FwallPass[PASSWORD_LEN+1];\r
164 extern int FwallPort;\r
165 extern int FwallType;\r
166 extern int FwallDefault;\r
167 extern int FwallSecurity;\r
168 extern int FwallResolve;\r
169 extern int FwallLower;\r
170 extern int FwallDelimiter;\r
171 extern int PasvDefault;\r
172 extern char MirrorNoTrn[MIRROR_LEN+1];\r
173 extern char MirrorNoDel[MIRROR_LEN+1];\r
174 extern int MirrorFnameCnv;\r
175 //extern int MirrorFolderCnv;\r
176 extern int RasClose;\r
177 extern int RasCloseNotify;\r
178 extern int FileHist;\r
179 extern char DefAttrList[DEFATTRLIST_LEN+1];\r
180 extern SIZE HostDlgSize;\r
181 extern SIZE BmarkDlgSize;\r
182 extern SIZE MirrorDlgSize;\r
183 extern int Sizing;\r
184 extern int SortSave;\r
185 extern char TmpPath[FMAX_PATH+1];\r
186 extern int QuickAnonymous;\r
187 extern int PassToHist;\r
188 extern int VaxSemicolon;\r
189 extern int SendQuit;\r
190 extern int NoRasControl;\r
191 extern int SuppressSave;\r
192 \r
193 extern int UpExistMode;\r
194 extern int ExistMode;\r
195 extern int DispIgnoreHide;\r
196 extern int DispDrives;\r
197 extern int MirUpDelNotify;\r
198 extern int MirDownDelNotify;\r
199 \r
200 extern int FolderAttr;\r
201 extern int FolderAttrNum;\r
202 \r
203 // 暗号化通信対応\r
204 extern BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];\r
205 extern BYTE SSLRootCAFileHash[20];\r
206 // ファイルアイコン表示対応\r
207 extern int DispFileIcon;\r
208 // タイムスタンプのバグ修正\r
209 extern int DispTimeSeconds;\r
210 // ファイルの属性を数字で表示\r
211 extern int DispPermissionsNumber;\r
212 // ディレクトリ自動作成\r
213 extern int MakeAllDir;\r
214 // UTF-8対応\r
215 extern int LocalKanjiCode;\r
216 // UPnP対応\r
217 extern int UPnPEnabled;\r
218 // 全設定暗号化対応\r
219 extern int EncryptAllSettings;\r
220 // ローカル側自動更新\r
221 extern int AutoRefreshFileList;\r
222 // 古い処理内容を消去\r
223 extern int RemoveOldLog;\r
224 // バージョン確認\r
225 extern int ReadOnlySettings;\r
226 \r
227 /*----- マスタパスワードの設定 ----------------------------------------------\r
228 *\r
229 *       Parameter\r
230 *               const char* Password : マスターパスワード\r
231 *\r
232 *       Return Value\r
233 *               なし\r
234 *----------------------------------------------------------------------------*/\r
235 void SetMasterPassword( const char* Password )\r
236 {\r
237         ZeroMemory( SecretKey, MAX_PASSWORD_LEN + 12 );\r
238         if( Password != NULL ){\r
239                 strncpy( SecretKey, Password, MAX_PASSWORD_LEN );\r
240         }\r
241         else {\r
242                 strcpy( SecretKey, DEFAULT_PASSWORD );\r
243         }\r
244         SecretKeyLength = strlen( SecretKey );\r
245         \r
246         /* 未検証なので,初期状態はOKにする (強制再設定→保存にを可能にする)*/\r
247         IsMasterPasswordError = PASSWORD_OK;\r
248 }\r
249 \r
250 // セキュリティ強化\r
251 void GetMasterPassword(char* Password)\r
252 {\r
253         strcpy(Password, SecretKey);\r
254 }\r
255 \r
256 /*----- マスタパスワードの状態取得 ----------------------------------------------\r
257 *\r
258 *       Parameter\r
259 *               なし\r
260 *\r
261 *       Return Value\r
262 *               PASSWORD_OK : OK\r
263 *               PASSWORD_UNMATCH : パスワード不一致\r
264 *               BAD_PASSWORD_HASH : パスワード確認失敗\r
265 *----------------------------------------------------------------------------*/\r
266 int GetMasterPasswordStatus(void)\r
267 {\r
268         return IsMasterPasswordError;\r
269 }\r
270 \r
271 /*----- レジストリ/INIファイルのマスターパスワードの検証を行う ------------\r
272 *\r
273 *       Parameter\r
274 *               なし\r
275 *\r
276 *       Return Value\r
277 *               \r
278 *----------------------------------------------------------------------------*/\r
279 \r
280 int ValidateMasterPassword(void)\r
281 {\r
282         void *hKey3;\r
283         int i;\r
284 \r
285         SetRegType(REGTYPE_INI);\r
286         if((i = OpenReg("FFFTP", &hKey3)) != FFFTP_SUCCESS)\r
287         {\r
288                 if(AskForceIni() == NO)\r
289                 {\r
290                         SetRegType(REGTYPE_REG);\r
291                         i = OpenReg("FFFTP", &hKey3);\r
292                 }\r
293         }\r
294         if(i == FFFTP_SUCCESS){\r
295                 char checkbuf[48];\r
296                 int salt = 0;\r
297 \r
298                 if( ReadIntValueFromReg(hKey3, "CredentialSalt", &salt)){\r
299                         SetHashSalt( salt );\r
300                 }\r
301                 if( ReadStringFromReg(hKey3, "CredentialCheck", checkbuf, sizeof( checkbuf )) == FFFTP_SUCCESS ){\r
302                         switch( CheckPasswordValidity( SecretKey, SecretKeyLength, checkbuf ) ){\r
303                         case 0: /* not match */\r
304                                 IsMasterPasswordError = PASSWORD_UNMATCH;\r
305                                 break;\r
306                         case 1: /* match */\r
307                                 IsMasterPasswordError = PASSWORD_OK;\r
308                                 break;\r
309                         case 2: /* invalid hash */\r
310                         default:\r
311                                 IsMasterPasswordError = BAD_PASSWORD_HASH;\r
312                                 break;\r
313                         }\r
314                 }\r
315                 CloseReg(hKey3);\r
316                 return YES;\r
317         }\r
318         return NO;\r
319 }\r
320 \r
321 /*----- レジストリ/INIファイルに設定値を保存 ---------------------------------\r
322 *\r
323 *       Parameter\r
324 *               なし\r
325 *\r
326 *       Return Value\r
327 *               なし\r
328 *----------------------------------------------------------------------------*/\r
329 \r
330 void SaveRegistry(void)\r
331 {\r
332         void *hKey3;\r
333         void *hKey4;\r
334         void *hKey5;\r
335         // 暗号化通信対応\r
336 //      char Str[FMAX_PATH+1];\r
337         char Str[PRIVATE_KEY_LEN*4+1];\r
338         char Buf[FMAX_PATH+1];\r
339         int i;\r
340         int n;\r
341         HOSTDATA DefaultHost;\r
342         HOSTDATA Host;\r
343         HISTORYDATA Hist;\r
344         HISTORYDATA DefaultHist;\r
345         \r
346         if( GetMasterPasswordStatus() == PASSWORD_UNMATCH ){\r
347                 /* 2010.01.30 genta: マスターパスワードが不一致の場合は不用意に上書きしない */\r
348                 return;\r
349         }\r
350 \r
351         // 全設定暗号化対応\r
352         if(EncryptSettingsError == YES)\r
353                 return;\r
354 \r
355         // バージョン確認\r
356         if(ReadOnlySettings == YES)\r
357                 return;\r
358 \r
359         SetRegType(RegType);\r
360         if(CreateReg("FFFTP", &hKey3) == FFFTP_SUCCESS)\r
361         {\r
362                 char buf[48];\r
363                 int salt = GetTickCount();\r
364         \r
365                 WriteIntValueToReg(hKey3, "Version", VER_NUM);\r
366                 WriteIntValueToReg(hKey3, "CredentialSalt", salt);\r
367                 \r
368                 SetHashSalt( salt );\r
369                 /* save password hash */\r
370                 CreatePasswordHash( SecretKey, SecretKeyLength, buf );\r
371                 WriteStringToReg(hKey3, "CredentialCheck", buf);\r
372 \r
373                 // 全設定暗号化対応\r
374                 WriteIntValueToReg(hKey3, "EncryptAll", EncryptAllSettings);\r
375                 sprintf(Buf, "%d", EncryptAllSettings);\r
376                 EncodePassword(Buf, Str);\r
377                 WriteStringToReg(hKey3, "EncryptAllDetector", Str);\r
378                 EncryptSettings = EncryptAllSettings;\r
379                 memset(&EncryptSettingsChecksum, 0, 20);\r
380 \r
381                 // 全設定暗号化対応\r
382 //              if(CreateSubKey(hKey3, "Options", &hKey4) == FFFTP_SUCCESS)\r
383                 if(EncryptAllSettings == YES)\r
384                         strcpy(Str, "EncryptedOptions");\r
385                 else\r
386                         strcpy(Str, "Options");\r
387                 if(CreateSubKey(hKey3, Str, &hKey4) == FFFTP_SUCCESS)\r
388                 {\r
389                         WriteIntValueToReg(hKey4, "NoSave", SuppressSave);\r
390 \r
391                         if(SuppressSave != YES)\r
392                         {\r
393                                 WriteIntValueToReg(hKey4, "WinPosX", WinPosX);\r
394                                 WriteIntValueToReg(hKey4, "WinPosY", WinPosY);\r
395                                 WriteIntValueToReg(hKey4, "WinWidth", WinWidth);\r
396                                 WriteIntValueToReg(hKey4, "WinHeight", WinHeight);\r
397                                 WriteIntValueToReg(hKey4, "LocalWidth", LocalWidth);\r
398                                 WriteIntValueToReg(hKey4, "TaskHeight", TaskHeight);\r
399                                 WriteBinaryToReg(hKey4, "LocalColm", LocalTabWidth, sizeof(LocalTabWidth));\r
400                                 WriteBinaryToReg(hKey4, "RemoteColm", RemoteTabWidth, sizeof(RemoteTabWidth));\r
401                                 WriteIntValueToReg(hKey4, "SwCmd", Sizing);\r
402 \r
403                                 WriteStringToReg(hKey4, "UserMail", UserMailAdrs);\r
404                                 WriteStringToReg(hKey4, "Viewer", ViewerName[0]);\r
405                                 WriteStringToReg(hKey4, "Viewer2", ViewerName[1]);\r
406                                 WriteStringToReg(hKey4, "Viewer3", ViewerName[2]);\r
407 \r
408                                 WriteIntValueToReg(hKey4, "TrType", TransMode);\r
409                                 WriteIntValueToReg(hKey4, "Recv", RecvMode);\r
410                                 WriteIntValueToReg(hKey4, "Send", SendMode);\r
411                                 WriteIntValueToReg(hKey4, "Move", MoveMode);\r
412                                 WriteStringToReg(hKey4, "Path", DefaultLocalPath);\r
413                                 WriteIntValueToReg(hKey4, "Time", SaveTimeStamp);\r
414                                 WriteIntValueToReg(hKey4, "EOF", RmEOF);\r
415                                 WriteIntValueToReg(hKey4, "Scolon", VaxSemicolon);\r
416 \r
417                                 WriteIntValueToReg(hKey4, "RecvEx", ExistMode);\r
418                                 WriteIntValueToReg(hKey4, "SendEx", UpExistMode);\r
419 \r
420                                 WriteIntValueToReg(hKey4, "LFsort", LocalFileSort);\r
421                                 WriteIntValueToReg(hKey4, "LDsort", LocalDirSort);\r
422                                 WriteIntValueToReg(hKey4, "RFsort", RemoteFileSort);\r
423                                 WriteIntValueToReg(hKey4, "RDsort", RemoteDirSort);\r
424                                 WriteIntValueToReg(hKey4, "SortSave", SortSave);\r
425 \r
426                                 WriteIntValueToReg(hKey4, "ListType", ListType);\r
427                                 WriteIntValueToReg(hKey4, "Cache", CacheEntry);\r
428                                 WriteIntValueToReg(hKey4, "CacheSave", CacheSave);\r
429                                 WriteIntValueToReg(hKey4, "DotFile", DotFile);\r
430                                 WriteIntValueToReg(hKey4, "Dclick", DclickOpen);\r
431 \r
432                                 WriteIntValueToReg(hKey4, "ConS", ConnectOnStart);\r
433                                 WriteIntValueToReg(hKey4, "OldDlg", ConnectAndSet);\r
434                                 WriteIntValueToReg(hKey4, "RasClose", RasClose);\r
435                                 WriteIntValueToReg(hKey4, "RasNotify", RasCloseNotify);\r
436                                 WriteIntValueToReg(hKey4, "Qanony", QuickAnonymous);\r
437                                 WriteIntValueToReg(hKey4, "PassHist", PassToHist);\r
438                                 WriteIntValueToReg(hKey4, "SendQuit", SendQuit);\r
439                                 WriteIntValueToReg(hKey4, "NoRas", NoRasControl);\r
440 \r
441                                 WriteIntValueToReg(hKey4, "Debug", DebugConsole);\r
442                                 WriteIntValueToReg(hKey4, "WinPos", SaveWinPos);\r
443                                 WriteIntValueToReg(hKey4, "RegExp", FindMode);\r
444                                 WriteIntValueToReg(hKey4, "Reg", RegType);\r
445 \r
446                                 WriteMultiStringToReg(hKey4, "AsciiFile", AsciiExt);\r
447                                 WriteIntValueToReg(hKey4, "LowUp", FnameCnv);\r
448                                 WriteIntValueToReg(hKey4, "Tout", TimeOut);\r
449 \r
450                                 WriteMultiStringToReg(hKey4, "NoTrn", MirrorNoTrn);\r
451                                 WriteMultiStringToReg(hKey4, "NoDel", MirrorNoDel);\r
452                                 WriteIntValueToReg(hKey4, "MirFile", MirrorFnameCnv);\r
453                                 WriteIntValueToReg(hKey4, "MirUNot", MirUpDelNotify);\r
454                                 WriteIntValueToReg(hKey4, "MirDNot", MirDownDelNotify);\r
455 \r
456                                 MakeFontData(ListLogFont, ListFont, Str);\r
457                                 WriteStringToReg(hKey4, "ListFont", Str);\r
458                                 WriteIntValueToReg(hKey4, "ListHide", DispIgnoreHide);\r
459                                 WriteIntValueToReg(hKey4, "ListDrv", DispDrives);\r
460 \r
461                                 WriteStringToReg(hKey4, "FwallHost", FwallHost);\r
462                                 WriteStringToReg(hKey4, "FwallUser", FwallUser);\r
463                                 EncodePassword(FwallPass, Str);\r
464                                 WriteStringToReg(hKey4, "FwallPass", Str);\r
465                                 WriteIntValueToReg(hKey4, "FwallPort", FwallPort);\r
466                                 WriteIntValueToReg(hKey4, "FwallType", FwallType);\r
467                                 WriteIntValueToReg(hKey4, "FwallDef", FwallDefault);\r
468                                 WriteIntValueToReg(hKey4, "FwallSec", FwallSecurity);\r
469                                 WriteIntValueToReg(hKey4, "PasvDef", PasvDefault);\r
470                                 WriteIntValueToReg(hKey4, "FwallRes", FwallResolve);\r
471                                 WriteIntValueToReg(hKey4, "FwallLow", FwallLower);\r
472                                 WriteIntValueToReg(hKey4, "FwallDel", FwallDelimiter);\r
473 \r
474                                 WriteIntValueToReg(hKey4, "SndConSw", Sound[SND_CONNECT].On);\r
475                                 WriteIntValueToReg(hKey4, "SndTrnSw", Sound[SND_TRANS].On);\r
476                                 WriteIntValueToReg(hKey4, "SndErrSw", Sound[SND_ERROR].On);\r
477                                 WriteStringToReg(hKey4, "SndCon", Sound[SND_CONNECT].Fname);\r
478                                 WriteStringToReg(hKey4, "SndTrn", Sound[SND_TRANS].Fname);\r
479                                 WriteStringToReg(hKey4, "SndErr", Sound[SND_ERROR].Fname);\r
480 \r
481                                 WriteMultiStringToReg(hKey4, "DefAttr", DefAttrList);\r
482 \r
483                                 // 環境依存の不具合対策\r
484 //                              GetTempPath(FMAX_PATH, Str);\r
485                                 GetAppTempPath(Str);\r
486                                 SetYenTail(Str);\r
487                                 SaveStr(hKey4, "Tmp", TmpPath, Str);\r
488 \r
489                                 WriteBinaryToReg(hKey4, "Hdlg", &HostDlgSize, sizeof(SIZE));\r
490                                 WriteBinaryToReg(hKey4, "Bdlg", &BmarkDlgSize, sizeof(SIZE));\r
491                                 WriteBinaryToReg(hKey4, "Mdlg", &MirrorDlgSize, sizeof(SIZE));\r
492 \r
493                                 WriteIntValueToReg(hKey4, "FAttrSw", FolderAttr);\r
494                                 WriteIntValueToReg(hKey4, "FAttr", FolderAttrNum);\r
495 \r
496                                 WriteIntValueToReg(hKey4, "HistNum", FileHist);\r
497 \r
498                                 /* Ver1.54a以前の形式のヒストリデータは削除 */\r
499                                 DeleteValue(hKey4, "Hist");\r
500 \r
501                                 /* ヒストリの設定を保存 */\r
502                                 CopyDefaultHistory(&DefaultHist);\r
503                                 n = 0;\r
504                                 for(i = AskHistoryNum(); i > 0; i--)\r
505                                 {\r
506                                         if(GetHistoryByNum(i-1, &Hist) == FFFTP_SUCCESS)\r
507                                         {\r
508                                                 sprintf(Str, "History%d", n);\r
509                                                 if(CreateSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
510                                                 {\r
511                                                         SaveStr(hKey5, "HostAdrs", Hist.HostAdrs, DefaultHist.HostAdrs);\r
512                                                         SaveStr(hKey5, "UserName", Hist.UserName, DefaultHist.UserName);\r
513                                                         SaveStr(hKey5, "Account", Hist.Account, DefaultHist.Account);\r
514                                                         SaveStr(hKey5, "LocalDir", Hist.LocalInitDir, NULL);\r
515                                                         SaveStr(hKey5, "RemoteDir", Hist.RemoteInitDir, DefaultHist.RemoteInitDir);\r
516                                                         SaveStr(hKey5, "Chmod", Hist.ChmodCmd, DefaultHist.ChmodCmd);\r
517                                                         SaveStr(hKey5, "Nlst", Hist.LsName, DefaultHist.LsName);\r
518                                                         SaveStr(hKey5, "Init", Hist.InitCmd, DefaultHist.InitCmd);\r
519                                                         EncodePassword(Hist.PassWord, Str);\r
520                                                         SaveStr(hKey5, "Password", Str, DefaultHist.PassWord);\r
521                                                         SaveIntNum(hKey5, "Port", Hist.Port, DefaultHist.Port);\r
522                                                         SaveIntNum(hKey5, "Kanji", Hist.KanjiCode, DefaultHist.KanjiCode);\r
523                                                         SaveIntNum(hKey5, "KanaCnv", Hist.KanaCnv, DefaultHist.KanaCnv);\r
524                                                         SaveIntNum(hKey5, "NameKanji", Hist.NameKanjiCode, DefaultHist.NameKanjiCode);\r
525                                                         SaveIntNum(hKey5, "NameKana", Hist.NameKanaCnv, DefaultHist.NameKanaCnv);\r
526                                                         SaveIntNum(hKey5, "Pasv", Hist.Pasv, DefaultHist.Pasv);\r
527                                                         SaveIntNum(hKey5, "Fwall", Hist.FireWall, DefaultHist.FireWall);\r
528                                                         SaveIntNum(hKey5, "List", Hist.ListCmdOnly, DefaultHist.ListCmdOnly);\r
529                                                         SaveIntNum(hKey5, "NLST-R", Hist.UseNLST_R, DefaultHist.UseNLST_R);\r
530                                                         SaveIntNum(hKey5, "Tzone", Hist.TimeZone, DefaultHist.TimeZone);\r
531                                                         SaveIntNum(hKey5, "Type", Hist.HostType, DefaultHist.HostType);\r
532                                                         SaveIntNum(hKey5, "Sync", Hist.SyncMove, DefaultHist.SyncMove);\r
533                                                         SaveIntNum(hKey5, "Fpath", Hist.NoFullPath, DefaultHist.NoFullPath);\r
534                                                         WriteBinaryToReg(hKey5, "Sort", &Hist.Sort, sizeof(Hist.Sort));\r
535                                                         SaveIntNum(hKey5, "Secu", Hist.Security, DefaultHist.Security);\r
536                                                         WriteIntValueToReg(hKey5, "TrType", Hist.Type);\r
537                                                         SaveIntNum(hKey5, "Dial", Hist.Dialup, DefaultHist.Dialup);\r
538                                                         SaveIntNum(hKey5, "UseIt", Hist.DialupAlways, DefaultHist.DialupAlways);\r
539                                                         SaveIntNum(hKey5, "Notify", Hist.DialupNotify, DefaultHist.DialupNotify);\r
540                                                         SaveStr(hKey5, "DialTo", Hist.DialEntry, DefaultHist.DialEntry);\r
541                                                         // 暗号化通信対応\r
542                                                         SaveIntNum(hKey5, "NoEncryption", Hist.UseNoEncryption, DefaultHist.UseNoEncryption);\r
543                                                         SaveIntNum(hKey5, "FTPES", Hist.UseFTPES, DefaultHist.UseFTPES);\r
544                                                         SaveIntNum(hKey5, "FTPIS", Hist.UseFTPIS, DefaultHist.UseFTPIS);\r
545                                                         SaveIntNum(hKey5, "SFTP", Hist.UseSFTP, DefaultHist.UseSFTP);\r
546                                                         EncodePassword(Hist.PrivateKey, Str);\r
547                                                         SaveStr(hKey5, "PKey", Str, DefaultHist.PrivateKey);\r
548                                                         // 同時接続対応\r
549                                                         SaveIntNum(hKey5, "ThreadCount", Hist.MaxThreadCount, DefaultHist.MaxThreadCount);\r
550                                                         SaveIntNum(hKey5, "ReuseCmdSkt", Hist.ReuseCmdSkt, DefaultHist.ReuseCmdSkt);\r
551                                                         // MLSD対応\r
552                                                         SaveIntNum(hKey5, "MLSD", Hist.UseMLSD, DefaultHist.UseMLSD);\r
553                                                         // IPv6対応\r
554                                                         SaveIntNum(hKey5, "NetType", Hist.NetType, DefaultHist.NetType);\r
555                                                         // 自動切断対策\r
556                                                         SaveIntNum(hKey5, "Noop", Hist.NoopInterval, DefaultHist.NoopInterval);\r
557                                                         // 再転送対応\r
558                                                         SaveIntNum(hKey5, "ErrMode", Hist.TransferErrorMode, DefaultHist.TransferErrorMode);\r
559                                                         SaveIntNum(hKey5, "ErrNotify", Hist.TransferErrorNotify, DefaultHist.TransferErrorNotify);\r
560                                                         // セッションあたりの転送量制限対策\r
561                                                         SaveIntNum(hKey5, "ErrReconnect", Hist.TransferErrorReconnect, DefaultHist.TransferErrorReconnect);\r
562 \r
563                                                         CloseSubKey(hKey5);\r
564                                                         n++;\r
565                                                 }\r
566                                         }\r
567                                 }\r
568                                 WriteIntValueToReg(hKey4, "SavedHist", n);\r
569 \r
570                                 /* 余分なヒストリがあったら削除 */\r
571                                 for(; n < 999; n++)\r
572                                 {\r
573                                         sprintf(Str, "History%d", n);\r
574                                         if(DeleteSubKey(hKey4, Str) != FFFTP_SUCCESS)\r
575                                                 break;\r
576                                 }\r
577 \r
578                                 /* ホストの設定を保存 */\r
579                                 CopyDefaultHost(&DefaultHost);\r
580                                 i = 0;\r
581                                 while(CopyHostFromList(i, &Host) == FFFTP_SUCCESS)\r
582                                 {\r
583                                         sprintf(Str, "Host%d", i);\r
584                                         if(CreateSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
585                                         {\r
586 //                                              SaveIntNum(hKey5, "Set", Host.Level, DefaultHost.Level);\r
587                                                 WriteIntValueToReg(hKey5, "Set", Host.Level);\r
588                                                 SaveStr(hKey5, "HostName", Host.HostName, DefaultHost.HostName);\r
589                                                 if((Host.Level & SET_LEVEL_GROUP) == 0)\r
590                                                 {\r
591                                                         SaveStr(hKey5, "HostAdrs", Host.HostAdrs, DefaultHost.HostAdrs);\r
592                                                         SaveStr(hKey5, "UserName", Host.UserName, DefaultHost.UserName);\r
593                                                         SaveStr(hKey5, "Account", Host.Account, DefaultHost.Account);\r
594                                                         SaveStr(hKey5, "LocalDir", Host.LocalInitDir, NULL);\r
595                                                         SaveStr(hKey5, "RemoteDir", Host.RemoteInitDir, DefaultHost.RemoteInitDir);\r
596                                                         SaveStr(hKey5, "Chmod", Host.ChmodCmd, DefaultHost.ChmodCmd);\r
597                                                         SaveStr(hKey5, "Nlst", Host.LsName, DefaultHost.LsName);\r
598                                                         SaveStr(hKey5, "Init", Host.InitCmd, DefaultHost.InitCmd);\r
599 \r
600                                                         if(Host.Anonymous == NO)\r
601                                                                 EncodePassword(Host.PassWord, Str);\r
602                                                         else\r
603                                                                 strcpy(Str, DefaultHost.PassWord);\r
604                                                         SaveStr(hKey5, "Password", Str, DefaultHost.PassWord);\r
605 \r
606                                                         SaveIntNum(hKey5, "Port", Host.Port, DefaultHost.Port);\r
607                                                         SaveIntNum(hKey5, "Anonymous", Host.Anonymous, DefaultHost.Anonymous);\r
608                                                         SaveIntNum(hKey5, "Kanji", Host.KanjiCode, DefaultHost.KanjiCode);\r
609                                                         SaveIntNum(hKey5, "KanaCnv", Host.KanaCnv, DefaultHost.KanaCnv);\r
610                                                         SaveIntNum(hKey5, "NameKanji", Host.NameKanjiCode, DefaultHost.NameKanjiCode);\r
611                                                         SaveIntNum(hKey5, "NameKana", Host.NameKanaCnv, DefaultHost.NameKanaCnv);\r
612                                                         SaveIntNum(hKey5, "Pasv", Host.Pasv, DefaultHost.Pasv);\r
613                                                         SaveIntNum(hKey5, "Fwall", Host.FireWall, DefaultHost.FireWall);\r
614                                                         SaveIntNum(hKey5, "List", Host.ListCmdOnly, DefaultHost.ListCmdOnly);\r
615                                                         SaveIntNum(hKey5, "NLST-R", Host.UseNLST_R, DefaultHost.UseNLST_R);\r
616                                                         SaveIntNum(hKey5, "Last", Host.LastDir, DefaultHost.LastDir);\r
617                                                         SaveIntNum(hKey5, "Tzone", Host.TimeZone, DefaultHost.TimeZone);\r
618                                                         SaveIntNum(hKey5, "Type", Host.HostType, DefaultHost.HostType);\r
619                                                         SaveIntNum(hKey5, "Sync", Host.SyncMove, DefaultHost.SyncMove);\r
620                                                         SaveIntNum(hKey5, "Fpath", Host.NoFullPath, DefaultHost.NoFullPath);\r
621                                                         WriteBinaryToReg(hKey5, "Sort", &Host.Sort, sizeof(Host.Sort));\r
622                                                         SaveIntNum(hKey5, "Secu", Host.Security, DefaultHost.Security);\r
623 \r
624                                                         WriteMultiStringToReg(hKey5, "Bmarks", Host.BookMark);\r
625 \r
626                                                         SaveIntNum(hKey5, "Dial", Host.Dialup, DefaultHost.Dialup);\r
627                                                         SaveIntNum(hKey5, "UseIt", Host.DialupAlways, DefaultHost.DialupAlways);\r
628                                                         SaveIntNum(hKey5, "Notify", Host.DialupNotify, DefaultHost.DialupNotify);\r
629                                                         SaveStr(hKey5, "DialTo", Host.DialEntry, DefaultHost.DialEntry);\r
630                                                         // 暗号化通信対応\r
631                                                         SaveIntNum(hKey5, "NoEncryption", Host.UseNoEncryption, DefaultHost.UseNoEncryption);\r
632                                                         SaveIntNum(hKey5, "FTPES", Host.UseFTPES, DefaultHost.UseFTPES);\r
633                                                         SaveIntNum(hKey5, "FTPIS", Host.UseFTPIS, DefaultHost.UseFTPIS);\r
634                                                         SaveIntNum(hKey5, "SFTP", Host.UseSFTP, DefaultHost.UseSFTP);\r
635                                                         EncodePassword(Host.PrivateKey, Str);\r
636                                                         SaveStr(hKey5, "PKey", Str, DefaultHost.PrivateKey);\r
637                                                         // 同時接続対応\r
638                                                         SaveIntNum(hKey5, "ThreadCount", Host.MaxThreadCount, DefaultHost.MaxThreadCount);\r
639                                                         SaveIntNum(hKey5, "ReuseCmdSkt", Host.ReuseCmdSkt, DefaultHost.ReuseCmdSkt);\r
640                                                         // MLSD対応\r
641                                                         SaveIntNum(hKey5, "MLSD", Host.UseMLSD, DefaultHost.UseMLSD);\r
642                                                         // IPv6対応\r
643                                                         SaveIntNum(hKey5, "NetType", Host.NetType, DefaultHost.NetType);\r
644                                                         // 自動切断対策\r
645                                                         SaveIntNum(hKey5, "Noop", Host.NoopInterval, DefaultHost.NoopInterval);\r
646                                                         // 再転送対応\r
647                                                         SaveIntNum(hKey5, "ErrMode", Host.TransferErrorMode, DefaultHost.TransferErrorMode);\r
648                                                         SaveIntNum(hKey5, "ErrNotify", Host.TransferErrorNotify, DefaultHost.TransferErrorNotify);\r
649                                                         // セッションあたりの転送量制限対策\r
650                                                         SaveIntNum(hKey5, "ErrReconnect", Host.TransferErrorReconnect, DefaultHost.TransferErrorReconnect);\r
651                                                 }\r
652                                                 CloseSubKey(hKey5);\r
653                                         }\r
654                                         i++;\r
655                                 }\r
656                                 WriteIntValueToReg(hKey4, "SetNum", i);\r
657 \r
658                                 /* 余分なホストの設定があったら削除 */\r
659                                 for(; i < 998; i++)\r
660                                 {\r
661                                         sprintf(Str, "Host%d", i);\r
662                                         if(DeleteSubKey(hKey4, Str) != FFFTP_SUCCESS)\r
663                                                 break;\r
664                                 }\r
665 \r
666                                 if((i = AskCurrentHost()) == HOSTNUM_NOENTRY)\r
667                                         i = 0;\r
668                                 WriteIntValueToReg(hKey4, "CurSet", i);\r
669 \r
670                                 // 暗号化通信対応\r
671                                 WriteBinaryToReg(hKey4, "CertCacheHash", &CertificateCacheHash, sizeof(CertificateCacheHash));\r
672                                 strcpy(Buf, "");\r
673                                 StrCatOut((char*)&SSLRootCAFileHash, sizeof(SSLRootCAFileHash), Buf);\r
674                                 EncodePassword(Buf, Str);\r
675                                 WriteStringToReg(hKey4, "RootCertHash", Str);\r
676                                 // ファイルアイコン表示対応\r
677                                 WriteIntValueToReg(hKey4, "ListIcon", DispFileIcon);\r
678                                 // タイムスタンプのバグ修正\r
679                                 WriteIntValueToReg(hKey4, "ListSecond", DispTimeSeconds);\r
680                                 // ファイルの属性を数字で表示\r
681                                 WriteIntValueToReg(hKey4, "ListPermitNum", DispPermissionsNumber);\r
682                                 // ディレクトリ自動作成\r
683                                 WriteIntValueToReg(hKey4, "MakeDir", MakeAllDir);\r
684                                 // UTF-8対応\r
685                                 WriteIntValueToReg(hKey4, "Kanji", LocalKanjiCode);\r
686                                 // UPnP対応\r
687                                 WriteIntValueToReg(hKey4, "UPnP", UPnPEnabled);\r
688                                 // ローカル側自動更新\r
689                                 WriteIntValueToReg(hKey4, "ListRefresh", AutoRefreshFileList);\r
690                                 // 古い処理内容を消去\r
691                                 WriteIntValueToReg(hKey4, "OldLog", RemoveOldLog);\r
692                         }\r
693                         CloseSubKey(hKey4);\r
694                 }\r
695                 // 全設定暗号化対応\r
696                 EncryptSettings = NO;\r
697                 WriteBinaryToReg(hKey3, "EncryptAllChecksum", &EncryptSettingsChecksum, 20);\r
698                 if(EncryptAllSettings == YES)\r
699                 {\r
700                         if(RegType == REGTYPE_REG)\r
701                         {\r
702                                 if(RegCreateKeyEx(hKey3, "Options", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, (HKEY*)&hKey4, NULL) == ERROR_SUCCESS)\r
703                                 {\r
704                                         for(i = 0; ; i++)\r
705                                         {\r
706                                                 sprintf(Str, "Host%d", i);\r
707                                                 if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
708                                                         break;\r
709                                         }\r
710                                         for(i = 0; ; i++)\r
711                                         {\r
712                                                 sprintf(Str, "History%d", i);\r
713                                                 if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
714                                                         break;\r
715                                         }\r
716                                         RegCloseKey(hKey4);\r
717                                 }\r
718                                 RegDeleteKey(hKey3, "Options");\r
719                         }\r
720                 }\r
721                 CloseReg(hKey3);\r
722         }\r
723         return;\r
724 }\r
725 \r
726 /*----- レジストリ/INIファイルから設定値を呼び出す ---------------------------\r
727 *\r
728 *       この関数を複数回呼び出すと,ホスト設定が追加される.\r
729 *\r
730 *       Parameter\r
731 *               なし\r
732 *\r
733 *       Return Value\r
734 *               YES: 読み出し成功\r
735 *               NO:  読み出し失敗(設定無し)\r
736 *----------------------------------------------------------------------------*/\r
737 \r
738 int LoadRegistry(void)\r
739 {\r
740         void *hKey3;\r
741         void *hKey4;\r
742         void *hKey5;\r
743         int i;\r
744         int Sets;\r
745         // 暗号化通信対応\r
746 //      char Str[256];  /* ASCII_EXT_LENより大きい事 */\r
747         char Str[PRIVATE_KEY_LEN*4+1];\r
748         char Buf[FMAX_PATH+1];\r
749         // 全設定暗号化対応\r
750         char Buf2[FMAX_PATH+1];\r
751         char *Pos;\r
752         char *Pos2;\r
753         HOSTDATA Host;\r
754         HISTORYDATA Hist;\r
755         int Sts;\r
756         int Version;\r
757         // 全設定暗号化対応\r
758         BYTE Checksum[20];\r
759 \r
760         Sts = NO;\r
761 \r
762         SetRegType(REGTYPE_INI);\r
763         if((i = OpenReg("FFFTP", &hKey3)) != FFFTP_SUCCESS)\r
764         {\r
765                 if(AskForceIni() == NO)\r
766                 {\r
767                         SetRegType(REGTYPE_REG);\r
768                         i = OpenReg("FFFTP", &hKey3);\r
769                 }\r
770         }\r
771 \r
772         if(i == FFFTP_SUCCESS)\r
773         {\r
774 //              char checkbuf[48];\r
775                 int salt = 0;\r
776                 Sts = YES;\r
777 \r
778                 ReadIntValueFromReg(hKey3, "Version", &Version);\r
779                 // UTF-8対応\r
780                 if(Version < 1980)\r
781                         IniKanjiCode = KANJI_SJIS;\r
782 \r
783                 // 全設定暗号化対応\r
784                 if(Version >= 1990)\r
785                 {\r
786                         ReadIntValueFromReg(hKey3, "EncryptAll", &EncryptAllSettings);\r
787                         sprintf(Buf, "%d", EncryptAllSettings);\r
788                         ReadStringFromReg(hKey3, "EncryptAllDetector", Str, 255);\r
789                         DecodePassword(Str, Buf2);\r
790                         EncryptSettings = EncryptAllSettings;\r
791                         memset(&EncryptSettingsChecksum, 0, 20);\r
792                         if(strcmp(Buf, Buf2) != 0)\r
793                         {\r
794                                 switch(MessageBox(GetMainHwnd(), MSGJPN343, "FFFTP", MB_ABORTRETRYIGNORE | MB_DEFBUTTON2))\r
795                                 {\r
796                                 case IDABORT:\r
797                                         CloseReg(hKey3);\r
798                                         ClearRegistry();\r
799                                         ClearIni();\r
800                                         RestartAndTerminate();\r
801                                         break;\r
802                                 case IDRETRY:\r
803                                         EncryptSettingsError = YES;\r
804                                         break;\r
805                                 case IDIGNORE:\r
806                                         break;\r
807                                 }\r
808                         }\r
809                 }\r
810 \r
811                 // 全設定暗号化対応\r
812 //              if(OpenSubKey(hKey3, "Options", &hKey4) == FFFTP_SUCCESS)\r
813                 if(EncryptAllSettings == YES)\r
814                         strcpy(Str, "EncryptedOptions");\r
815                 else\r
816                         strcpy(Str, "Options");\r
817                 if(OpenSubKey(hKey3, Str, &hKey4) == FFFTP_SUCCESS)\r
818                 {\r
819                         ReadIntValueFromReg(hKey4, "WinPosX", &WinPosX);\r
820                         ReadIntValueFromReg(hKey4, "WinPosY", &WinPosY);\r
821                         ReadIntValueFromReg(hKey4, "WinWidth", &WinWidth);\r
822                         ReadIntValueFromReg(hKey4, "WinHeight", &WinHeight);\r
823                         ReadIntValueFromReg(hKey4, "LocalWidth", &LocalWidth);\r
824                         /* ↓旧バージョンのバグ対策 */\r
825                         LocalWidth = max1(0, LocalWidth);\r
826                         ReadIntValueFromReg(hKey4, "TaskHeight", &TaskHeight);\r
827                         /* ↓旧バージョンのバグ対策 */\r
828                         TaskHeight = max1(0, TaskHeight);\r
829                         ReadBinaryFromReg(hKey4, "LocalColm", &LocalTabWidth, sizeof(LocalTabWidth));\r
830                         ReadBinaryFromReg(hKey4, "RemoteColm", &RemoteTabWidth, sizeof(RemoteTabWidth));\r
831                         ReadIntValueFromReg(hKey4, "SwCmd", &Sizing);\r
832 \r
833                         ReadStringFromReg(hKey4, "UserMail", UserMailAdrs, USER_MAIL_LEN+1);\r
834                         ReadStringFromReg(hKey4, "Viewer", ViewerName[0], FMAX_PATH+1);\r
835                         ReadStringFromReg(hKey4, "Viewer2", ViewerName[1], FMAX_PATH+1);\r
836                         ReadStringFromReg(hKey4, "Viewer3", ViewerName[2], FMAX_PATH+1);\r
837 \r
838                         ReadIntValueFromReg(hKey4, "TrType", &TransMode);\r
839                         ReadIntValueFromReg(hKey4, "Recv", &RecvMode);\r
840                         ReadIntValueFromReg(hKey4, "Send", &SendMode);\r
841                         ReadIntValueFromReg(hKey4, "Move", &MoveMode);\r
842                         ReadStringFromReg(hKey4, "Path", DefaultLocalPath, FMAX_PATH+1);\r
843                         ReadIntValueFromReg(hKey4, "Time", &SaveTimeStamp);\r
844                         ReadIntValueFromReg(hKey4, "EOF", &RmEOF);\r
845                         ReadIntValueFromReg(hKey4, "Scolon", &VaxSemicolon);\r
846 \r
847                         ReadIntValueFromReg(hKey4, "RecvEx", &ExistMode);\r
848                         ReadIntValueFromReg(hKey4, "SendEx", &UpExistMode);\r
849 \r
850                         ReadIntValueFromReg(hKey4, "LFsort", &LocalFileSort);\r
851                         ReadIntValueFromReg(hKey4, "LDsort", &LocalDirSort);\r
852                         ReadIntValueFromReg(hKey4, "RFsort", &RemoteFileSort);\r
853                         ReadIntValueFromReg(hKey4, "RDsort", &RemoteDirSort);\r
854                         ReadIntValueFromReg(hKey4, "SortSave", &SortSave);\r
855 \r
856                         ReadIntValueFromReg(hKey4, "ListType", &ListType);\r
857                         ReadIntValueFromReg(hKey4, "Cache", &CacheEntry);\r
858                         ReadIntValueFromReg(hKey4, "CacheSave", &CacheSave);\r
859                         ReadIntValueFromReg(hKey4, "DotFile", &DotFile);\r
860                         ReadIntValueFromReg(hKey4, "Dclick", &DclickOpen);\r
861 \r
862                         ReadIntValueFromReg(hKey4, "ConS", &ConnectOnStart);\r
863                         ReadIntValueFromReg(hKey4, "OldDlg", &ConnectAndSet);\r
864                         ReadIntValueFromReg(hKey4, "RasClose", &RasClose);\r
865                         ReadIntValueFromReg(hKey4, "RasNotify", &RasCloseNotify);\r
866                         ReadIntValueFromReg(hKey4, "Qanony", &QuickAnonymous);\r
867                         ReadIntValueFromReg(hKey4, "PassHist", &PassToHist);\r
868                         ReadIntValueFromReg(hKey4, "SendQuit", &SendQuit);\r
869                         ReadIntValueFromReg(hKey4, "NoRas", &NoRasControl);\r
870 \r
871                         ReadIntValueFromReg(hKey4, "Debug", &DebugConsole);\r
872                         ReadIntValueFromReg(hKey4, "WinPos", &SaveWinPos);\r
873                         ReadIntValueFromReg(hKey4, "RegExp", &FindMode);\r
874                         ReadIntValueFromReg(hKey4, "Reg", &RegType);\r
875 \r
876                         if(ReadMultiStringFromReg(hKey4, "AsciiFile", AsciiExt, ASCII_EXT_LEN+1) == FFFTP_FAIL)\r
877                         {\r
878                                 /* 旧ASCIIモードの拡張子の設定を新しいものに変換 */\r
879                                 // アスキーモード判別の改良\r
880 //                              ReadStringFromReg(hKey4, "Ascii", Str, ASCII_EXT_LEN+1);\r
881 //                              memset(AsciiExt, NUL, ASCII_EXT_LEN+1);\r
882                                 Str[0] = NUL;\r
883                                 if(ReadStringFromReg(hKey4, "Ascii", Str, ASCII_EXT_LEN+1) == FFFTP_SUCCESS)\r
884                                         memset(AsciiExt, NUL, ASCII_EXT_LEN+1);\r
885                                 Pos = Str;\r
886                                 while(*Pos != NUL)\r
887                                 {\r
888                                         if((Pos2 = strchr(Pos, ';')) == NULL)\r
889                                                 Pos2 = strchr(Pos, NUL);\r
890                                         if((Pos2 - Pos) > 0)\r
891                                         {\r
892                                                 if((StrMultiLen(AsciiExt) + (Pos2 - Pos) + 2) >= ASCII_EXT_LEN)\r
893                                                         break;\r
894                                                 strcpy(AsciiExt + StrMultiLen(AsciiExt), "*.");\r
895                                                 strncpy(AsciiExt + StrMultiLen(AsciiExt) - 1, Pos, (Pos2 - Pos));\r
896                                         }\r
897                                         Pos = Pos2;\r
898                                         if(*Pos == ';')\r
899                                                 Pos++;\r
900                                 }\r
901                         }\r
902                         // アスキーモード判別の改良\r
903                         if(Version < 1986)\r
904                         {\r
905                                 Pos = "*.js\0*.vbs\0*.css\0*.rss\0*.rdf\0*.xml\0*.xhtml\0*.xht\0*.shtml\0*.shtm\0*.sh\0*.py\0*.rb\0*.properties\0*.sql\0*.asp\0*.aspx\0*.php\0*.htaccess\0";\r
906                                 while(*Pos != NUL)\r
907                                 {\r
908                                         Pos2 = AsciiExt;\r
909                                         while(*Pos2 != NUL)\r
910                                         {\r
911                                                 if(_stricmp(Pos2, Pos) == 0)\r
912                                                         break;\r
913                                                 Pos2 = strchr(Pos2, NUL) + 1;\r
914                                         }\r
915                                         if(*Pos2 == NUL)\r
916                                         {\r
917                                                 if((StrMultiLen(AsciiExt) + strlen(Pos) + 2) < ASCII_EXT_LEN)\r
918                                                         strncpy(AsciiExt + StrMultiLen(AsciiExt), Pos, strlen(Pos) + 2);\r
919                                         }\r
920                                         Pos = strchr(Pos, NUL) + 1;\r
921                                 }\r
922                         }\r
923 \r
924                         ReadIntValueFromReg(hKey4, "LowUp", &FnameCnv);\r
925                         ReadIntValueFromReg(hKey4, "Tout", &TimeOut);\r
926 \r
927                         ReadMultiStringFromReg(hKey4, "NoTrn", MirrorNoTrn, MIRROR_LEN+1);\r
928                         ReadMultiStringFromReg(hKey4, "NoDel", MirrorNoDel, MIRROR_LEN+1);\r
929                         ReadIntValueFromReg(hKey4, "MirFile", &MirrorFnameCnv);\r
930                         ReadIntValueFromReg(hKey4, "MirUNot", &MirUpDelNotify);\r
931                         ReadIntValueFromReg(hKey4, "MirDNot", &MirDownDelNotify);\r
932 \r
933                         if(ReadStringFromReg(hKey4, "ListFont", Str, 256) == FFFTP_SUCCESS)\r
934                         {\r
935                                 if(RestoreFontData(Str, &ListLogFont) == FFFTP_SUCCESS)\r
936                                         ListFont = CreateFontIndirect(&ListLogFont);\r
937                         }\r
938                         ReadIntValueFromReg(hKey4, "ListHide", &DispIgnoreHide);\r
939                         ReadIntValueFromReg(hKey4, "ListDrv", &DispDrives);\r
940 \r
941                         ReadStringFromReg(hKey4, "FwallHost", FwallHost, HOST_ADRS_LEN+1);\r
942                         ReadStringFromReg(hKey4, "FwallUser", FwallUser, USER_NAME_LEN+1);\r
943                         ReadStringFromReg(hKey4, "FwallPass", Str, 255);\r
944                         DecodePassword(Str, FwallPass);\r
945                         ReadIntValueFromReg(hKey4, "FwallPort", &FwallPort);\r
946                         ReadIntValueFromReg(hKey4, "FwallType", &FwallType);\r
947                         ReadIntValueFromReg(hKey4, "FwallDef", &FwallDefault);\r
948                         ReadIntValueFromReg(hKey4, "FwallSec", &FwallSecurity);\r
949                         ReadIntValueFromReg(hKey4, "PasvDef", &PasvDefault);\r
950                         ReadIntValueFromReg(hKey4, "FwallRes", &FwallResolve);\r
951                         ReadIntValueFromReg(hKey4, "FwallLow", &FwallLower);\r
952                         ReadIntValueFromReg(hKey4, "FwallDel", &FwallDelimiter);\r
953 \r
954                         ReadIntValueFromReg(hKey4, "SndConSw", &Sound[SND_CONNECT].On);\r
955                         ReadIntValueFromReg(hKey4, "SndTrnSw", &Sound[SND_TRANS].On);\r
956                         ReadIntValueFromReg(hKey4, "SndErrSw", &Sound[SND_ERROR].On);\r
957                         ReadStringFromReg(hKey4, "SndCon", Sound[SND_CONNECT].Fname, FMAX_PATH+1);\r
958                         ReadStringFromReg(hKey4, "SndTrn", Sound[SND_TRANS].Fname, FMAX_PATH+1);\r
959                         ReadStringFromReg(hKey4, "SndErr", Sound[SND_ERROR].Fname, FMAX_PATH+1);\r
960 \r
961                         ReadMultiStringFromReg(hKey4, "DefAttr", DefAttrList, DEFATTRLIST_LEN+1);\r
962 \r
963                         ReadStringFromReg(hKey4, "Tmp", TmpPath, FMAX_PATH+1);\r
964 \r
965                         ReadBinaryFromReg(hKey4, "Hdlg", &HostDlgSize, sizeof(SIZE));\r
966                         ReadBinaryFromReg(hKey4, "Bdlg", &BmarkDlgSize, sizeof(SIZE));\r
967                         ReadBinaryFromReg(hKey4, "Mdlg", &MirrorDlgSize, sizeof(SIZE));\r
968 \r
969                         ReadIntValueFromReg(hKey4, "FAttrSw", &FolderAttr);\r
970                         ReadIntValueFromReg(hKey4, "FAttr", &FolderAttrNum);\r
971 \r
972                         ReadIntValueFromReg(hKey4, "NoSave", &SuppressSave);\r
973 \r
974                         ReadIntValueFromReg(hKey4, "HistNum", &FileHist);\r
975 //                      ReadMultiStringFromReg(hKey4, "Hist", Hist, (FMAX_PATH+1)*HISTORY_MAX+1);\r
976 \r
977                         /* ヒストリの設定を読み込む */\r
978                         Sets = 0;\r
979                         ReadIntValueFromReg(hKey4, "SavedHist", &Sets);\r
980 \r
981                         for(i = 0; i < Sets; i++)\r
982                         {\r
983                                 sprintf(Str, "History%d", i);\r
984                                 if(OpenSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
985                                 {\r
986                                         CopyDefaultHistory(&Hist);\r
987 \r
988                                         ReadStringFromReg(hKey5, "HostAdrs", Hist.HostAdrs, HOST_ADRS_LEN+1);\r
989                                         ReadStringFromReg(hKey5, "UserName", Hist.UserName, USER_NAME_LEN+1);\r
990                                         ReadStringFromReg(hKey5, "Account", Hist.Account, ACCOUNT_LEN+1);\r
991                                         ReadStringFromReg(hKey5, "LocalDir", Hist.LocalInitDir, INIT_DIR_LEN+1);\r
992                                         ReadStringFromReg(hKey5, "RemoteDir", Hist.RemoteInitDir, INIT_DIR_LEN+1);\r
993                                         ReadStringFromReg(hKey5, "Chmod", Hist.ChmodCmd, CHMOD_CMD_LEN+1);\r
994                                         ReadStringFromReg(hKey5, "Nlst", Hist.LsName, NLST_NAME_LEN+1);\r
995                                         ReadStringFromReg(hKey5, "Init", Hist.InitCmd, INITCMD_LEN+1);\r
996                                         ReadIntValueFromReg(hKey5, "Port", &Hist.Port);\r
997                                         ReadIntValueFromReg(hKey5, "Kanji", &Hist.KanjiCode);\r
998                                         ReadIntValueFromReg(hKey5, "KanaCnv", &Hist.KanaCnv);\r
999                                         ReadIntValueFromReg(hKey5, "NameKanji", &Hist.NameKanjiCode);\r
1000                                         ReadIntValueFromReg(hKey5, "NameKana", &Hist.NameKanaCnv);\r
1001                                         ReadIntValueFromReg(hKey5, "Pasv", &Hist.Pasv);\r
1002                                         ReadIntValueFromReg(hKey5, "Fwall", &Hist.FireWall);\r
1003                                         ReadIntValueFromReg(hKey5, "List", &Hist.ListCmdOnly);\r
1004                                         ReadIntValueFromReg(hKey5, "NLST-R", &Hist.UseNLST_R);\r
1005                                         ReadIntValueFromReg(hKey5, "Tzone", &Hist.TimeZone);\r
1006                                         ReadIntValueFromReg(hKey5, "Type", &Hist.HostType);\r
1007                                         ReadIntValueFromReg(hKey5, "Sync", &Hist.SyncMove);\r
1008                                         ReadIntValueFromReg(hKey5, "Fpath", &Hist.NoFullPath);\r
1009                                         ReadBinaryFromReg(hKey5, "Sort", &Hist.Sort, sizeof(Hist.Sort));\r
1010                                         ReadIntValueFromReg(hKey5, "Secu", &Hist.Security);\r
1011                                         ReadIntValueFromReg(hKey5, "TrType", &Hist.Type);\r
1012                                         strcpy(Str, "");\r
1013                                         ReadStringFromReg(hKey5, "Password", Str, 255);\r
1014                                         DecodePassword(Str, Hist.PassWord);\r
1015                                         ReadIntValueFromReg(hKey5, "Dial", &Hist.Dialup);\r
1016                                         ReadIntValueFromReg(hKey5, "UseIt", &Hist.DialupAlways);\r
1017                                         ReadIntValueFromReg(hKey5, "Notify", &Hist.DialupNotify);\r
1018                                         ReadStringFromReg(hKey5, "DialTo", Hist.DialEntry, RAS_NAME_LEN+1);\r
1019                                         // 暗号化通信対応\r
1020                                         ReadIntValueFromReg(hKey5, "NoEncryption", &Hist.UseNoEncryption);\r
1021                                         ReadIntValueFromReg(hKey5, "FTPES", &Hist.UseFTPES);\r
1022                                         ReadIntValueFromReg(hKey5, "FTPIS", &Hist.UseFTPIS);\r
1023                                         ReadIntValueFromReg(hKey5, "SFTP", &Hist.UseSFTP);\r
1024                                         strcpy(Str, "");\r
1025                                         ReadStringFromReg(hKey5, "PKey", Str, PRIVATE_KEY_LEN*4+1);\r
1026                                         DecodePassword(Str, Hist.PrivateKey);\r
1027                                         // 同時接続対応\r
1028                                         ReadIntValueFromReg(hKey5, "ThreadCount", &Hist.MaxThreadCount);\r
1029                                         ReadIntValueFromReg(hKey5, "ReuseCmdSkt", &Hist.ReuseCmdSkt);\r
1030                                         // MLSD対応\r
1031                                         ReadIntValueFromReg(hKey5, "MLSD", &Hist.UseMLSD);\r
1032                                         // IPv6対応\r
1033                                         ReadIntValueFromReg(hKey5, "NetType", &Hist.NetType);\r
1034                                         // 自動切断対策\r
1035                                         ReadIntValueFromReg(hKey5, "Noop", &Hist.NoopInterval);\r
1036                                         // 再転送対応\r
1037                                         ReadIntValueFromReg(hKey5, "ErrMode", &Hist.TransferErrorMode);\r
1038                                         ReadIntValueFromReg(hKey5, "ErrNotify", &Hist.TransferErrorNotify);\r
1039 \r
1040                                         CloseSubKey(hKey5);\r
1041                                         AddHistoryToHistory(&Hist);\r
1042                                 }\r
1043                         }\r
1044 \r
1045                         /* ホストの設定を読み込む */\r
1046                         Sets = 0;\r
1047                         ReadIntValueFromReg(hKey4, "SetNum", &Sets);\r
1048 \r
1049                         for(i = 0; i < Sets; i++)\r
1050                         {\r
1051                                 sprintf(Str, "Host%d", i);\r
1052                                 if(OpenSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
1053                                 {\r
1054                                         CopyDefaultHost(&Host);\r
1055                                         /* 下位互換性のため */\r
1056                                         // SourceForge.JPによるフォーク\r
1057 //                                      if(Version < VER_NUM)\r
1058                                         if(Version < 1921)\r
1059                                         {\r
1060                                                 Host.Pasv = NO;\r
1061                                                 Host.ListCmdOnly = NO;\r
1062                                         }\r
1063                                         // 1.97b以前はデフォルトでShift_JIS\r
1064                                         if(Version < 1980)\r
1065                                                 Host.NameKanjiCode = KANJI_SJIS;\r
1066                                         ReadIntValueFromReg(hKey5, "Set", &Host.Level);\r
1067 \r
1068                                         ReadStringFromReg(hKey5, "HostName", Host.HostName, HOST_NAME_LEN+1);\r
1069                                         ReadStringFromReg(hKey5, "HostAdrs", Host.HostAdrs, HOST_ADRS_LEN+1);\r
1070                                         ReadStringFromReg(hKey5, "UserName", Host.UserName, USER_NAME_LEN+1);\r
1071                                         ReadStringFromReg(hKey5, "Account", Host.Account, ACCOUNT_LEN+1);\r
1072                                         ReadStringFromReg(hKey5, "LocalDir", Host.LocalInitDir, INIT_DIR_LEN+1);\r
1073                                         ReadStringFromReg(hKey5, "RemoteDir", Host.RemoteInitDir, INIT_DIR_LEN+1);\r
1074                                         ReadStringFromReg(hKey5, "Chmod", Host.ChmodCmd, CHMOD_CMD_LEN+1);\r
1075                                         ReadStringFromReg(hKey5, "Nlst", Host.LsName, NLST_NAME_LEN+1);\r
1076                                         ReadStringFromReg(hKey5, "Init", Host.InitCmd, INITCMD_LEN+1);\r
1077                                         ReadIntValueFromReg(hKey5, "Port", &Host.Port);\r
1078                                         ReadIntValueFromReg(hKey5, "Anonymous", &Host.Anonymous);\r
1079                                         ReadIntValueFromReg(hKey5, "Kanji", &Host.KanjiCode);\r
1080                                         // 1.98b以前のUTF-8はBOMあり\r
1081                                         if(Version < 1983)\r
1082                                         {\r
1083                                                 if(Host.KanjiCode == KANJI_UTF8N)\r
1084                                                         Host.KanjiCode = KANJI_UTF8BOM;\r
1085                                         }\r
1086                                         ReadIntValueFromReg(hKey5, "KanaCnv", &Host.KanaCnv);\r
1087                                         ReadIntValueFromReg(hKey5, "NameKanji", &Host.NameKanjiCode);\r
1088                                         ReadIntValueFromReg(hKey5, "NameKana", &Host.NameKanaCnv);\r
1089                                         ReadIntValueFromReg(hKey5, "Pasv", &Host.Pasv);\r
1090                                         ReadIntValueFromReg(hKey5, "Fwall", &Host.FireWall);\r
1091                                         ReadIntValueFromReg(hKey5, "List", &Host.ListCmdOnly);\r
1092                                         ReadIntValueFromReg(hKey5, "NLST-R", &Host.UseNLST_R);\r
1093                                         ReadIntValueFromReg(hKey5, "Last", &Host.LastDir);\r
1094                                         ReadIntValueFromReg(hKey5, "Tzone", &Host.TimeZone);\r
1095                                         ReadIntValueFromReg(hKey5, "Type", &Host.HostType);\r
1096                                         ReadIntValueFromReg(hKey5, "Sync", &Host.SyncMove);\r
1097                                         ReadIntValueFromReg(hKey5, "Fpath", &Host.NoFullPath);\r
1098                                         ReadBinaryFromReg(hKey5, "Sort", &Host.Sort, sizeof(Host.Sort));\r
1099                                         ReadIntValueFromReg(hKey5, "Secu", &Host.Security);\r
1100                                         if(Host.Anonymous != YES)\r
1101                                         {\r
1102                                                 strcpy(Str, "");\r
1103                                                 ReadStringFromReg(hKey5, "Password", Str, 255);\r
1104                                                 DecodePassword(Str, Host.PassWord);\r
1105                                         }\r
1106                                         else\r
1107                                                 strcpy(Host.PassWord, UserMailAdrs);\r
1108 \r
1109                                         ReadMultiStringFromReg(hKey5, "Bmarks", Host.BookMark, BOOKMARK_SIZE);\r
1110 \r
1111                                         ReadIntValueFromReg(hKey5, "Dial", &Host.Dialup);\r
1112                                         ReadIntValueFromReg(hKey5, "UseIt", &Host.DialupAlways);\r
1113                                         ReadIntValueFromReg(hKey5, "Notify", &Host.DialupNotify);\r
1114                                         ReadStringFromReg(hKey5, "DialTo", Host.DialEntry, RAS_NAME_LEN+1);\r
1115                                         // 暗号化通信対応\r
1116                                         ReadIntValueFromReg(hKey5, "NoEncryption", &Host.UseNoEncryption);\r
1117                                         ReadIntValueFromReg(hKey5, "FTPES", &Host.UseFTPES);\r
1118                                         ReadIntValueFromReg(hKey5, "FTPIS", &Host.UseFTPIS);\r
1119                                         ReadIntValueFromReg(hKey5, "SFTP", &Host.UseSFTP);\r
1120                                         strcpy(Str, "");\r
1121                                         ReadStringFromReg(hKey5, "PKey", Str, PRIVATE_KEY_LEN*4+1);\r
1122                                         DecodePassword(Str, Host.PrivateKey);\r
1123                                         // 同時接続対応\r
1124                                         ReadIntValueFromReg(hKey5, "ThreadCount", &Host.MaxThreadCount);\r
1125                                         ReadIntValueFromReg(hKey5, "ReuseCmdSkt", &Host.ReuseCmdSkt);\r
1126                                         // 1.98d以前で同時接続数が1より大きい場合はソケットの再利用なし\r
1127                                         if(Version < 1985)\r
1128                                         {\r
1129                                                 if(Host.MaxThreadCount > 1)\r
1130                                                         Host.ReuseCmdSkt = NO;\r
1131                                         }\r
1132                                         // MLSD対応\r
1133                                         ReadIntValueFromReg(hKey5, "MLSD", &Host.UseMLSD);\r
1134                                         // IPv6対応\r
1135                                         ReadIntValueFromReg(hKey5, "NetType", &Host.NetType);\r
1136                                         // 自動切断対策\r
1137                                         ReadIntValueFromReg(hKey5, "Noop", &Host.NoopInterval);\r
1138                                         // 再転送対応\r
1139                                         ReadIntValueFromReg(hKey5, "ErrMode", &Host.TransferErrorMode);\r
1140                                         ReadIntValueFromReg(hKey5, "ErrNotify", &Host.TransferErrorNotify);\r
1141                                         // セッションあたりの転送量制限対策\r
1142                                         ReadIntValueFromReg(hKey5, "ErrReconnect", &Host.TransferErrorReconnect);\r
1143 \r
1144                                         CloseSubKey(hKey5);\r
1145 \r
1146                                         AddHostToList(&Host, -1, Host.Level);\r
1147                                 }\r
1148                         }\r
1149 \r
1150                         ReadIntValueFromReg(hKey4, "CurSet", &Sets);\r
1151                         SetCurrentHost(Sets);\r
1152 \r
1153                         // 暗号化通信対応\r
1154                         ReadBinaryFromReg(hKey4, "CertCacheHash", &CertificateCacheHash, sizeof(CertificateCacheHash));\r
1155                         ReadStringFromReg(hKey4, "RootCertHash", Str, PRIVATE_KEY_LEN*4+1);\r
1156                         DecodePassword(Str, Buf);\r
1157                         StrReadIn(Buf, sizeof(SSLRootCAFileHash), (char*)&SSLRootCAFileHash);\r
1158                         // ファイルアイコン表示対応\r
1159                         ReadIntValueFromReg(hKey4, "ListIcon", &DispFileIcon);\r
1160                         // タイムスタンプのバグ修正\r
1161                         ReadIntValueFromReg(hKey4, "ListSecond", &DispTimeSeconds);\r
1162                         // ファイルの属性を数字で表示\r
1163                         ReadIntValueFromReg(hKey4, "ListPermitNum", &DispPermissionsNumber);\r
1164                         // ディレクトリ自動作成\r
1165                         ReadIntValueFromReg(hKey4, "MakeDir", &MakeAllDir);\r
1166                         // UTF-8対応\r
1167                         ReadIntValueFromReg(hKey4, "Kanji", &LocalKanjiCode);\r
1168                         // UPnP対応\r
1169                         ReadIntValueFromReg(hKey4, "UPnP", &UPnPEnabled);\r
1170                         // ローカル側自動更新\r
1171                         ReadIntValueFromReg(hKey4, "ListRefresh", &AutoRefreshFileList);\r
1172                         // 古い処理内容を消去\r
1173                         ReadIntValueFromReg(hKey4, "OldLog", &RemoveOldLog);\r
1174 \r
1175                         CloseSubKey(hKey4);\r
1176                 }\r
1177                 // 全設定暗号化対応\r
1178                 EncryptSettings = NO;\r
1179                 if(Version >= 1990)\r
1180                 {\r
1181                         memset(&Checksum, 0, 20);\r
1182                         ReadBinaryFromReg(hKey3, "EncryptAllChecksum", &Checksum, 20);\r
1183                         if(memcmp(&Checksum, &EncryptSettingsChecksum, 20) != 0)\r
1184                         {\r
1185                                 switch(MessageBox(GetMainHwnd(), MSGJPN343, "FFFTP", MB_ABORTRETRYIGNORE | MB_DEFBUTTON2))\r
1186                                 {\r
1187                                 case IDABORT:\r
1188                                         CloseReg(hKey3);\r
1189                                         ClearRegistry();\r
1190                                         ClearIni();\r
1191                                         RestartAndTerminate();\r
1192                                         break;\r
1193                                 case IDRETRY:\r
1194                                         EncryptSettingsError = YES;\r
1195                                         break;\r
1196                                 case IDIGNORE:\r
1197                                         break;\r
1198                                 }\r
1199                         }\r
1200                 }\r
1201                 CloseReg(hKey3);\r
1202         }\r
1203         else\r
1204         {\r
1205                 /*===== 最初の起動時(設定が無い) =====*/\r
1206 \r
1207 #if 0\r
1208                 strcpy(UserMailAdrs, "");\r
1209                 strcpy(Str, "");\r
1210                 if(InputDialogBox(mailadrs_dlg, HWND_DESKTOP, NULL, Str, USER_MAIL_LEN+1, &i, IDH_HELP_TOPIC_0000001) == YES)\r
1211                         strcpy(UserMailAdrs, Str);\r
1212 \r
1213                 for(i = 0; i < SAMPLE_HOSTS; i++)\r
1214                 {\r
1215                         CopyDefaultHost(&Host);\r
1216                         Host.Level = Sample[i].Level;\r
1217                         strcpy(Host.PassWord, UserMailAdrs);\r
1218                         strcpy(Host.HostName, Sample[i].HostName);\r
1219                         strcpy(Host.HostAdrs, Sample[i].HostAdrs);\r
1220                         strcpy(Host.UserName, "anonymous");\r
1221                         AddHostToList(&Host, -1, Host.Level);\r
1222                 }\r
1223 #endif\r
1224         }\r
1225         return(Sts);\r
1226 }\r
1227 \r
1228 \r
1229 /*----- 隠しドライブ情報を取得 ------------------------------------------------\r
1230 *\r
1231 *       Parameter\r
1232 *               なし\r
1233 *\r
1234 *       Return Value\r
1235 *               DWORD \r
1236 *                       YES/NO=設定無し\r
1237 *----------------------------------------------------------------------------*/\r
1238 \r
1239 DWORD LoadHideDriveListRegistry(void)\r
1240 {\r
1241         HKEY hKey1;\r
1242         HKEY hKey2;\r
1243         HKEY hKey3;\r
1244         HKEY hKey4;\r
1245         HKEY hKey5;\r
1246         HKEY hKey6;\r
1247         DWORD Size;\r
1248         DWORD Type;\r
1249         DWORD Ret;\r
1250 \r
1251         Ret = 0;\r
1252         if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hKey1) == ERROR_SUCCESS)\r
1253         {\r
1254                 if(RegOpenKeyEx(hKey1, "Microsoft", 0, KEY_READ, &hKey2) == ERROR_SUCCESS)\r
1255                 {\r
1256                         if(RegOpenKeyEx(hKey2, "Windows", 0, KEY_READ, &hKey3) == ERROR_SUCCESS)\r
1257                         {\r
1258                                 if(RegOpenKeyEx(hKey3, "CurrentVersion", 0, KEY_READ, &hKey4) == ERROR_SUCCESS)\r
1259                                 {\r
1260                                         if(RegOpenKeyEx(hKey4, "Policies", 0, KEY_READ, &hKey5) == ERROR_SUCCESS)\r
1261                                         {\r
1262                                                 if(RegOpenKeyEx(hKey5, "Explorer", 0, KEY_READ, &hKey6) == ERROR_SUCCESS)\r
1263                                                 {\r
1264                                                         Size = sizeof(DWORD);\r
1265                                                         RegQueryValueEx(hKey6, "NoDrives", NULL, &Type, (BYTE *)&Ret, &Size);\r
1266                                                         RegCloseKey(hKey6);\r
1267                                                 }\r
1268                                                 RegCloseKey(hKey5);\r
1269                                         }\r
1270                                         RegCloseKey(hKey4);\r
1271                                 }\r
1272                                 RegCloseKey(hKey3);\r
1273                         }\r
1274                         RegCloseKey(hKey2);\r
1275                 }\r
1276                 RegCloseKey(hKey1);\r
1277         }\r
1278         return(Ret);\r
1279 }\r
1280 \r
1281 \r
1282 /*----- レジストリの設定値をクリア --------------------------------------------\r
1283 *\r
1284 *       Parameter\r
1285 *               なし\r
1286 *\r
1287 *       Return Value\r
1288 *               なし\r
1289 *----------------------------------------------------------------------------*/\r
1290 \r
1291 void ClearRegistry(void)\r
1292 {\r
1293         HKEY hKey2;\r
1294         HKEY hKey3;\r
1295         HKEY hKey4;\r
1296         DWORD Dispos;\r
1297         char Str[20];\r
1298         int i;\r
1299 \r
1300         if(RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Sota", 0, "", REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey2, &Dispos) == ERROR_SUCCESS)\r
1301         {\r
1302                 if(RegCreateKeyEx(hKey2, "FFFTP", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey3, &Dispos) == ERROR_SUCCESS)\r
1303                 {\r
1304                         if(RegCreateKeyEx(hKey3, "Options", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey4, &Dispos) == ERROR_SUCCESS)\r
1305                         {\r
1306                                 for(i = 0; ; i++)\r
1307                                 {\r
1308                                         sprintf(Str, "Host%d", i);\r
1309                                         if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
1310                                                 break;\r
1311                                 }\r
1312                                 for(i = 0; ; i++)\r
1313                                 {\r
1314                                         sprintf(Str, "History%d", i);\r
1315                                         if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
1316                                                 break;\r
1317                                 }\r
1318                                 RegCloseKey(hKey4);\r
1319                         }\r
1320                         RegDeleteKey(hKey3, "Options");\r
1321                         // 全設定暗号化対応\r
1322                         if(RegCreateKeyEx(hKey3, "EncryptedOptions", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey4, &Dispos) == ERROR_SUCCESS)\r
1323                         {\r
1324                                 for(i = 0; ; i++)\r
1325                                 {\r
1326                                         sprintf(Str, "Host%d", i);\r
1327                                         if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
1328                                                 break;\r
1329                                 }\r
1330                                 for(i = 0; ; i++)\r
1331                                 {\r
1332                                         sprintf(Str, "History%d", i);\r
1333                                         if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
1334                                                 break;\r
1335                                 }\r
1336                                 RegCloseKey(hKey4);\r
1337                         }\r
1338                         RegDeleteKey(hKey3, "EncryptedOptions");\r
1339                         RegCloseKey(hKey3);\r
1340                 }\r
1341                 RegDeleteKey(hKey2, "FFFTP");\r
1342                 RegCloseKey(hKey2);\r
1343         }\r
1344         return;\r
1345 }\r
1346 \r
1347 \r
1348 // ポータブル版判定\r
1349 void ClearIni(void)\r
1350 {\r
1351 //      FILE *Strm;\r
1352 //      if((Strm = fopen(AskIniFilePath(), "rt")) != NULL)\r
1353 //      {\r
1354 //              fclose(Strm);\r
1355 //              MoveFileToTrashCan(AskIniFilePath());\r
1356 //      }\r
1357         DeleteFile(AskIniFilePath());\r
1358         return;\r
1359 }\r
1360 \r
1361 \r
1362 /*----- 設定をファイルに保存 --------------------------------------------------\r
1363 *\r
1364 *       Parameter\r
1365 *               なし\r
1366 *\r
1367 *       Return Value\r
1368 *               なし\r
1369 *----------------------------------------------------------------------------*/\r
1370 \r
1371 void SaveSettingsToFile(void)\r
1372 {\r
1373         char Tmp[FMAX_PATH*2];\r
1374         char Fname[FMAX_PATH+1];\r
1375         // 任意のコードが実行されるバグ修正\r
1376         char CurDir[FMAX_PATH+1];\r
1377         char SysDir[FMAX_PATH+1];\r
1378 \r
1379         if(RegType == REGTYPE_REG)\r
1380         {\r
1381                 strcpy(Fname, "FFFTP.reg");\r
1382                 if(SelectFile(GetMainHwnd(), Fname, MSGJPN286, MSGJPN287, "reg", OFN_EXTENSIONDIFFERENT | OFN_OVERWRITEPROMPT, 1) == TRUE)\r
1383                 {\r
1384                         sprintf(Tmp, "/e \x22%s\x22 HKEY_CURRENT_USER\\Software\\sota\\FFFTP", Fname);\r
1385                         // 任意のコードが実行されるバグ修正\r
1386 //                      if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32)\r
1387 //                      {\r
1388 //                              MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK);\r
1389 //                      }\r
1390                         if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0)\r
1391                         {\r
1392                                 if(GetSystemDirectory(SysDir, FMAX_PATH) > 0)\r
1393                                 {\r
1394                                         if(SetCurrentDirectory(SysDir))\r
1395                                         {\r
1396                                                 if(ShellExecute(NULL, "open", "regedit", Tmp, NULL, SW_SHOW) <= (HINSTANCE)32)\r
1397                                                 {\r
1398                                                         MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK);\r
1399                                                 }\r
1400                                                 SetCurrentDirectory(CurDir);\r
1401                                         }\r
1402                                 }\r
1403                         }\r
1404                 }\r
1405         }\r
1406         else\r
1407         {\r
1408                 strcpy(Fname, "FFFTP-Backup.ini");\r
1409                 if(SelectFile(GetMainHwnd(), Fname, MSGJPN286, MSGJPN288, "ini", OFN_EXTENSIONDIFFERENT | OFN_OVERWRITEPROMPT, 1) == TRUE)\r
1410                 {\r
1411                         CopyFile(AskIniFilePath(), Fname, FALSE);\r
1412                 }\r
1413         }\r
1414         return;\r
1415 }\r
1416 \r
1417 \r
1418 /*----- 設定をファイルから復元 ------------------------------------------------\r
1419 *\r
1420 *       Parameter\r
1421 *               なし\r
1422 *\r
1423 *       Return Value\r
1424 *               int     ロードしたかどうか (YES/NO)\r
1425 *----------------------------------------------------------------------------*/\r
1426 \r
1427 int LoadSettingsFromFile(void)\r
1428 {\r
1429         int Ret;\r
1430         char Tmp[FMAX_PATH*2];\r
1431         char Fname[FMAX_PATH+1];\r
1432         // 任意のコードが実行されるバグ修正\r
1433         char CurDir[FMAX_PATH+1];\r
1434         char SysDir[FMAX_PATH+1];\r
1435 \r
1436         Ret = NO;\r
1437         strcpy(Fname, "");\r
1438         if(SelectFile(GetMainHwnd(), Fname, MSGJPN291, MSGJPN290, "", OFN_FILEMUSTEXIST, 0) == TRUE)\r
1439         {\r
1440                 if((strlen(Fname) >= 5) && (_stricmp(&Fname[strlen(Fname)-4], ".reg") == 0))\r
1441                 {\r
1442                         sprintf(Tmp, "\x22%s\x22", Fname);\r
1443                         // 任意のコードが実行されるバグ修正\r
1444 //                      if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32)\r
1445 //                      {\r
1446 //                              MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK);\r
1447 //                      }\r
1448 //                      else\r
1449 //                      {\r
1450 //                              Ret = YES;\r
1451 //                              /* レジストリエディタが終了するのを待つ */\r
1452 //                              WaitForSingleObject(Info.hProcess, INFINITE);\r
1453 //                      }\r
1454                         if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0)\r
1455                         {\r
1456                                 if(GetSystemDirectory(SysDir, FMAX_PATH) > 0)\r
1457                                 {\r
1458                                         if(SetCurrentDirectory(SysDir))\r
1459                                         {\r
1460                                                 if(ShellExecute(NULL, "open", "regedit", Tmp, NULL, SW_SHOW) <= (HINSTANCE)32)\r
1461                                                 {\r
1462                                                         MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK);\r
1463                                                 }\r
1464                                                 else\r
1465                                                 {\r
1466                                                         Ret = YES;\r
1467                                                         /* レジストリエディタが終了するのを待つ */\r
1468 //                                                      WaitForSingleObject(Info.hProcess, INFINITE);\r
1469                                                 }\r
1470                                                 SetCurrentDirectory(CurDir);\r
1471                                         }\r
1472                                 }\r
1473                         }\r
1474                 }\r
1475                 else if((strlen(Fname) >= 5) && (_stricmp(&Fname[strlen(Fname)-4], ".ini") == 0))\r
1476                 {\r
1477                         CopyFile(Fname, AskIniFilePath(), FALSE);\r
1478                         Ret = YES;\r
1479                 }\r
1480                 else\r
1481                         MessageBox(NULL, MSGJPN293, "FFFTP", MB_OK);\r
1482         }\r
1483         return(Ret);\r
1484 }\r
1485 \r
1486 \r
1487 \r
1488 \r
1489 /*----- レジストリ/INIファイルに文字列をセーブ --------------------------------\r
1490 *\r
1491 *       Parameter\r
1492 *               HKEY hKey : レジストリキー\r
1493 *               char *Key : キー名\r
1494 *               char *Str : セーブする文字列\r
1495 *               char *DefaultStr : デフォルトの文字列\r
1496 *\r
1497 *       Return Value\r
1498 *               なし\r
1499 *\r
1500 *       Note\r
1501 *               文字列がデフォルトの文字列と同じならセーブしない\r
1502 *----------------------------------------------------------------------------*/\r
1503 \r
1504 static void SaveStr(HKEY hKey, char *Key, char *Str, char *DefaultStr)\r
1505 {\r
1506         if((DefaultStr != NULL) && (strcmp(Str, DefaultStr) == 0))\r
1507                 DeleteValue(hKey, Key);\r
1508         else\r
1509                 WriteStringToReg(hKey, Key, Str);\r
1510 \r
1511         return;\r
1512 }\r
1513 \r
1514 \r
1515 /*----- レジストリ/INIファイルに数値(INT)をセーブ -----------------------------\r
1516 *\r
1517 *       Parameter\r
1518 *               HKEY hKey : レジストリキー\r
1519 *               char *Key : キー名\r
1520 *               int Num : セーブする値\r
1521 *               int DefaultNum : デフォルトの値\r
1522 *\r
1523 *       Return Value\r
1524 *               なし\r
1525 *\r
1526 *       Note\r
1527 *               数値がデフォルトの値と同じならセーブしない\r
1528 *----------------------------------------------------------------------------*/\r
1529 \r
1530 static void SaveIntNum(HKEY hKey, char *Key, int Num, int DefaultNum)\r
1531 {\r
1532         if(Num == DefaultNum)\r
1533                 DeleteValue(hKey, Key);\r
1534         else\r
1535                 WriteIntValueToReg(hKey, Key, Num);\r
1536 \r
1537         return;\r
1538 }\r
1539 \r
1540 \r
1541 /*----- LOGFONTデータを文字列に変換する ---------------------------------------\r
1542 *\r
1543 *       Parameter\r
1544 *               LOGFONT Font : フォントデータ\r
1545 *               HFONT hFont : フォントのハンドル\r
1546 *                       NULL = デフォルトのフォント\r
1547 *               char *Buf : バッファ\r
1548 *\r
1549 *       Return Value\r
1550 *               なし\r
1551 *----------------------------------------------------------------------------*/\r
1552 \r
1553 static void MakeFontData(LOGFONT Font, HFONT hFont, char *Buf)\r
1554 {\r
1555         *Buf = NUL;\r
1556         if(hFont != NULL)\r
1557                 sprintf(Buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %s",\r
1558                         Font.lfHeight, Font.lfWidth, Font.lfEscapement, Font.lfOrientation,\r
1559                         Font.lfWeight, Font.lfItalic, Font.lfUnderline, Font.lfStrikeOut,\r
1560                         Font.lfCharSet, Font.lfOutPrecision, Font.lfClipPrecision,\r
1561                         Font.lfQuality, Font.lfPitchAndFamily, Font.lfFaceName);\r
1562         return;\r
1563 }\r
1564 \r
1565 \r
1566 /*----- 文字列をLOGFONTデータに変換する ---------------------------------------\r
1567 *\r
1568 *       Parameter\r
1569 *               char *Str : 文字列\r
1570 *               LOGFONT *Font : フォントデータ\r
1571 *\r
1572 *       Return Value\r
1573 *               int ステータス\r
1574 *                       FFFTP_SUCCESS/FFFTP_FAIL=変換できない\r
1575 *----------------------------------------------------------------------------*/\r
1576 \r
1577 static int RestoreFontData(char *Str, LOGFONT *Font)\r
1578 {\r
1579         int i;\r
1580         int Sts;\r
1581 \r
1582         Sts = FFFTP_FAIL;\r
1583         if(sscanf(Str, "%d %d %d %d %d %d %d %d %d %d %d %d %d",\r
1584                         &(Font->lfHeight), &(Font->lfWidth), &(Font->lfEscapement), &(Font->lfOrientation),\r
1585                         &(Font->lfWeight), &(Font->lfItalic), &(Font->lfUnderline), &(Font->lfStrikeOut),\r
1586                         &(Font->lfCharSet), &(Font->lfOutPrecision), &(Font->lfClipPrecision),\r
1587                         &(Font->lfQuality), &(Font->lfPitchAndFamily)) == 13)\r
1588         {\r
1589                 for(i = 13; i > 0; i--)\r
1590                 {\r
1591                         if((Str = strchr(Str, ' ')) == NULL)\r
1592                                 break;\r
1593                         Str++;\r
1594                 }\r
1595                 if(i == 0)\r
1596                 {\r
1597                         strcpy(Font->lfFaceName, Str);\r
1598                         Sts = FFFTP_SUCCESS;\r
1599                 }\r
1600         }\r
1601 \r
1602         if(Sts == FFFTP_FAIL)\r
1603                 memset(Font, NUL, sizeof(LOGFONT));\r
1604 \r
1605         return(Sts);\r
1606 }\r
1607 \r
1608 /*----- パスワードを暗号化する ------------------------------------------------\r
1609 *\r
1610 *       Parameter\r
1611 *               char *Str : パスワード\r
1612 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1613 *\r
1614 *       Return Value\r
1615 *               なし\r
1616 *----------------------------------------------------------------------------*/\r
1617 static void EncodePassword(char *Str, char *Buf)\r
1618 {\r
1619         EncodePassword3( Str, Buf, SecretKey );\r
1620 }\r
1621 \r
1622 /*----- パスワードを暗号化する(オリジナルアルゴリズム)  ------------------\r
1623 *\r
1624 *       Parameter\r
1625 *               char *Str : パスワード\r
1626 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1627 *\r
1628 *       Return Value\r
1629 *               なし\r
1630 *----------------------------------------------------------------------------*/\r
1631 \r
1632 static void EncodePasswordOriginal(char *Str, char *Buf)\r
1633 {\r
1634         unsigned char *Get;\r
1635         unsigned char *Put;\r
1636         int Rnd;\r
1637         int Ch;\r
1638 \r
1639         srand((unsigned)time(NULL));\r
1640 \r
1641         Get = (unsigned char *)Str;\r
1642         Put = (unsigned char *)Buf;\r
1643         \r
1644         if( *Get == NUL ){\r
1645                 *Put = NUL;\r
1646                 return;\r
1647         }\r
1648 \r
1649         /* 識別子を先頭に置く */\r
1650         Put[0] = '0';\r
1651         Put[1] = 'A';\r
1652         Put += 2;\r
1653 \r
1654         while(*Get != NUL)\r
1655         {\r
1656                 Rnd = rand() % 3;\r
1657                 Ch = ((int)*Get++) << Rnd;\r
1658                 Ch = (unsigned char)Ch | (unsigned char)(Ch >> 8);\r
1659                 *Put++ = 0x40 | ((Rnd & 0x3) << 4) | (Ch & 0xF);\r
1660                 *Put++ = 0x40 | ((Ch >> 4) & 0xF);\r
1661                 if((*(Put-2) & 0x1) != 0)\r
1662                         *Put++ = (rand() % 62) + 0x40;\r
1663         }\r
1664         *Put = NUL;\r
1665         return;\r
1666 }\r
1667 \r
1668 /*----- パスワードを暗号化する(オリジナルアルゴリズム^Key)  ----------------\r
1669 *\r
1670 *       Parameter\r
1671 *               char *Str : パスワード\r
1672 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1673 *               const char *Key : 暗号化キー\r
1674 *\r
1675 *       Return Value\r
1676 *               なし\r
1677 *----------------------------------------------------------------------------*/\r
1678 \r
1679 static void EncodePassword2(char *Str, char *Buf, const char* Key)\r
1680 {\r
1681         unsigned char *Get;\r
1682         unsigned char *Put;\r
1683         int Rnd;\r
1684         int Ch;\r
1685 \r
1686         /* 2010.01.31 genta Key */\r
1687         unsigned char *KeyHead = (unsigned char *)Key;\r
1688         unsigned char *KeyEnd = KeyHead + strlen(KeyHead);\r
1689         unsigned char *KeyCurrent = KeyHead;\r
1690 \r
1691         srand((unsigned)time(NULL));\r
1692 \r
1693         Get = (unsigned char *)Str;\r
1694         Put = (unsigned char *)Buf;\r
1695         \r
1696         if( *Get == NUL ){\r
1697                 *Put = NUL;\r
1698                 return;\r
1699         }\r
1700 \r
1701         /* 識別子を先頭に置く */\r
1702         Put[0] = '0';\r
1703         Put[1] = 'B';\r
1704         Put += 2;\r
1705 \r
1706         while(*Get != NUL)\r
1707         {\r
1708                 Rnd = rand() % 3;\r
1709                 Ch = ((int)(*Get++ ^ *KeyCurrent)) << Rnd;\r
1710                 Ch = (unsigned char)Ch | (unsigned char)(Ch >> 8);\r
1711                 *Put++ = 0x40 | ((Rnd & 0x3) << 4) | (Ch & 0xF);\r
1712                 *Put++ = 0x40 | ((Ch >> 4) & 0xF);\r
1713                 if((*(Put-2) & 0x1) != 0)\r
1714                         *Put++ = (rand() % 62) + 0x40;\r
1715 \r
1716                 /* 2010.01.31 genta Key */\r
1717                 if( ++KeyCurrent == KeyEnd ){\r
1718                         KeyCurrent = KeyHead;\r
1719                 }\r
1720         }\r
1721         *Put = NUL;\r
1722         return;\r
1723 }\r
1724 \r
1725 /*----- パスワードを暗号化する(AES) ------------------------------------------\r
1726 *\r
1727 *       Parameter\r
1728 *               char *Str : パスワード\r
1729 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1730 *               const char *Key : 暗号化キー\r
1731 *\r
1732 *       Return Value\r
1733 *               なし\r
1734 *----------------------------------------------------------------------------*/\r
1735 \r
1736 static void EncodePassword3(char *Str, char *Buf, const char *Key)\r
1737 {\r
1738         unsigned char *Put;\r
1739         unsigned char *AesEncBuf;\r
1740         unsigned char *StrPadBuf;\r
1741         size_t StrLen;\r
1742         size_t StrPadLen;\r
1743         size_t StrPadIndex;\r
1744         size_t IvIndex;\r
1745         size_t EncBufIndex;\r
1746         DWORD RandValue;\r
1747         int RandByteCount;\r
1748         unsigned char AesKey[32];\r
1749         unsigned char AesCbcIv[AES_BLOCK_SIZE];\r
1750         aes_encrypt_ctx Ctx;\r
1751 \r
1752         Buf[0] = NUL;\r
1753 \r
1754         Put = (unsigned char *)Buf;\r
1755         StrLen = strlen(Str);\r
1756         StrPadLen = ((StrLen + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;\r
1757 \r
1758         /* 最低長を32文字とする */\r
1759 //      StrPadLen = min1(StrPadLen, AES_BLOCK_SIZE * 2);\r
1760         StrPadLen = max1(StrPadLen, AES_BLOCK_SIZE * 2);\r
1761 \r
1762         if((StrPadBuf = malloc(StrPadLen)) != NULL)\r
1763         {\r
1764                 if((AesEncBuf = malloc(StrPadLen)) != NULL)\r
1765                 {\r
1766                         BOOL PutState;\r
1767 \r
1768                         PutState = FALSE;\r
1769                         strncpy(StrPadBuf, Str, StrPadLen);\r
1770                         \r
1771                         /* PAD部分を乱数で埋める StrPad[StrLen](が有効な場合) は NUL */\r
1772                         for(StrPadIndex = StrLen + 1; StrPadIndex < StrPadLen;)\r
1773                         {\r
1774                                 RandValue = GetRandamDWRODValue();\r
1775                                 for(RandByteCount = 0; RandByteCount < 4; RandByteCount++)\r
1776                                 {\r
1777                                         if(StrPadIndex < StrPadLen)\r
1778                                         {\r
1779                                                 StrPadBuf[StrPadIndex++] = (unsigned char)(RandValue & 0xff);\r
1780                                                 RandValue >>= 8;\r
1781                                         }\r
1782                                 }\r
1783                         }\r
1784                         \r
1785                         // IVの初期化\r
1786                         for(IvIndex = 0; IvIndex < AES_BLOCK_SIZE;)\r
1787                         {\r
1788                                 RandValue = GetRandamDWRODValue();\r
1789                                 for(RandByteCount = 0; RandByteCount < 4; RandByteCount++)\r
1790                                 {\r
1791                                         if(IvIndex < AES_BLOCK_SIZE)\r
1792                                         {\r
1793                                                 AesCbcIv[IvIndex++] = (unsigned char)(RandValue & 0xff);\r
1794                                                 RandValue >>= 8;\r
1795                                         }\r
1796                                 }\r
1797                         }\r
1798                         Put[0] = '0';\r
1799                         Put[1] = 'C';\r
1800                         Put += 2;\r
1801                         for(IvIndex = 0; IvIndex < AES_BLOCK_SIZE; IvIndex++)\r
1802                         {\r
1803                                 sprintf(Put, "%02x", AesCbcIv[IvIndex]);\r
1804                                 Put += 2;\r
1805                         }\r
1806                         *Put++ = ':';\r
1807 \r
1808                         if(CreateAesKey(AesKey, Key) == FFFTP_SUCCESS)\r
1809                         {\r
1810                                 aes_encrypt_key(AesKey, 32, &Ctx);\r
1811 \r
1812                                 if(aes_cbc_encrypt(StrPadBuf, AesEncBuf, StrPadLen, AesCbcIv, &Ctx) == EXIT_SUCCESS)\r
1813                                 {\r
1814                                         for(EncBufIndex = 0; EncBufIndex < StrPadLen; EncBufIndex++)\r
1815                                         {\r
1816                                                 sprintf(Put, "%02x", AesEncBuf[EncBufIndex]);\r
1817                                                 Put += 2;\r
1818                                         }\r
1819                                         *Put = NUL;\r
1820                                         PutState = TRUE;\r
1821                                 }\r
1822                         }\r
1823                         if(FALSE == PutState)\r
1824                         {\r
1825                                 Buf[0] = NUL;\r
1826                         }\r
1827                         free(StrPadBuf);\r
1828                 }\r
1829                 free(AesEncBuf);\r
1830         }\r
1831         return;\r
1832 }\r
1833 \r
1834 \r
1835 /*----- パスワードの暗号化を解く ----------------------------------------------\r
1836 *\r
1837 *       Parameter\r
1838 *               char *Str : 暗号化したパスワード\r
1839 *               char *Buf : パスワードを格納するバッファ\r
1840 *\r
1841 *       Return Value\r
1842 *               なし\r
1843 *----------------------------------------------------------------------------*/\r
1844 \r
1845 static void DecodePassword(char *Str, char *Buf)\r
1846 {\r
1847         unsigned char *Get;\r
1848         unsigned char *Put;\r
1849 \r
1850         Get = (unsigned char *)Str;\r
1851         Put = (unsigned char *)Buf;\r
1852         \r
1853         if( *Get == NUL ){\r
1854                 *Put = NUL;\r
1855         }\r
1856         else if( 0x40 <= *Get && *Get < 0x80 ){\r
1857                 /* Original algorithm */\r
1858                 DecodePasswordOriginal( Str, Buf );\r
1859         }\r
1860         else if( strncmp( Get, "0A", 2 ) == 0 ){\r
1861                 DecodePasswordOriginal( Str + 2, Buf );\r
1862         }\r
1863         else if( strncmp( Get, "0B", 2 ) == 0 ){\r
1864                 DecodePassword2( Str + 2, Buf, SecretKey );\r
1865         }\r
1866         else if( strncmp( Get, "0C", 2 ) == 0 ){\r
1867                 DecodePassword3( Str + 2, Buf, SecretKey );\r
1868         }\r
1869         else {\r
1870                 //      unknown encoding\r
1871                 *Put = NUL;\r
1872                 return;\r
1873         }\r
1874 }\r
1875 \r
1876 /*----- パスワードの暗号化を解く(オリジナルアルゴリズム) -------------------\r
1877 *\r
1878 *       Parameter\r
1879 *               char *Str : 暗号化したパスワード\r
1880 *               char *Buf : パスワードを格納するバッファ\r
1881 *\r
1882 *       Return Value\r
1883 *               なし\r
1884 *----------------------------------------------------------------------------*/\r
1885 static void DecodePasswordOriginal(char *Str, char *Buf)\r
1886 {\r
1887         unsigned char *Get;\r
1888         unsigned char *Put;\r
1889         int Rnd;\r
1890         int Ch;\r
1891 \r
1892         Get = (unsigned char *)Str;\r
1893         Put = (unsigned char *)Buf;\r
1894 \r
1895         while(*Get != NUL)\r
1896         {\r
1897                 Rnd = ((unsigned int)*Get >> 4) & 0x3;\r
1898                 Ch = (*Get & 0xF) | ((*(Get+1) & 0xF) << 4);\r
1899                 Ch <<= 8;\r
1900                 if((*Get & 0x1) != 0)\r
1901                         Get++;\r
1902                 Get += 2;\r
1903                 Ch >>= Rnd;\r
1904                 Ch = (Ch & 0xFF) | ((Ch >> 8) & 0xFF);\r
1905                 *Put++ = Ch;\r
1906         }\r
1907         *Put = NUL;\r
1908         return;\r
1909 }\r
1910 \r
1911 /*----- パスワードの暗号化を解く(オリジナルアルゴリズム^Key) -------------------\r
1912 *\r
1913 *       Parameter\r
1914 *               char *Str : 暗号化したパスワード\r
1915 *               char *Buf : パスワードを格納するバッファ\r
1916 *               const char *Key : 暗号化キー\r
1917 *\r
1918 *       Return Value\r
1919 *               なし\r
1920 *----------------------------------------------------------------------------*/\r
1921 static void DecodePassword2(char *Str, char *Buf, const char* Key)\r
1922 {\r
1923         int Rnd;\r
1924         int Ch;\r
1925         unsigned char *Get = (unsigned char *)Str;\r
1926         unsigned char *Put = (unsigned char *)Buf;\r
1927 \r
1928         /* 2010.01.31 genta Key */\r
1929         unsigned char *KeyHead = (unsigned char *)Key;\r
1930         unsigned char *KeyEnd = KeyHead + strlen(KeyHead);\r
1931         unsigned char *KeyCurrent = KeyHead;\r
1932 \r
1933         while(*Get != NUL)\r
1934         {\r
1935                 Rnd = ((unsigned int)*Get >> 4) & 0x3;\r
1936                 Ch = (*Get & 0xF) | ((*(Get+1) & 0xF) << 4);\r
1937                 Ch <<= 8;\r
1938                 if((*Get & 0x1) != 0)\r
1939                         Get++;\r
1940                 Get += 2;\r
1941                 Ch >>= Rnd;\r
1942                 Ch = (Ch & 0xFF) | ((Ch >> 8) & 0xFF);\r
1943                 *Put++ = Ch ^ *KeyCurrent;\r
1944                 \r
1945                 /* 2010.01.31 genta Key */\r
1946                 if( ++KeyCurrent == KeyEnd ){\r
1947                         KeyCurrent = KeyHead;\r
1948                 }\r
1949         }\r
1950         *Put = NUL;\r
1951         return;\r
1952 }\r
1953 \r
1954 /*----- パスワードの暗号化を解く(AES) ---------------------------------------\r
1955 *\r
1956 *       Parameter\r
1957 *               char *Str : 暗号化したパスワード\r
1958 *               char *Buf : パスワードを格納するバッファ\r
1959 *               const char *Key : 暗号化キー\r
1960 *\r
1961 *       Return Value\r
1962 *               なし\r
1963 *----------------------------------------------------------------------------*/\r
1964 \r
1965 static void DecodePassword3(char *Str, char *Buf, const char *Key)\r
1966 {\r
1967         char *Get;\r
1968         unsigned char *EncBuf;\r
1969         size_t StrLen;\r
1970         size_t IvIndex;\r
1971         size_t EncBufIndex;\r
1972         size_t EncBufLen;\r
1973         unsigned char AesKey[32];\r
1974         unsigned char AesCbcIv[AES_BLOCK_SIZE];\r
1975         aes_decrypt_ctx Ctx;\r
1976 \r
1977         Buf[0] = NUL;\r
1978 \r
1979         Get = Str;\r
1980         StrLen = strlen(Str);\r
1981 \r
1982         if(AES_BLOCK_SIZE * 2 + 1 < StrLen)\r
1983         {\r
1984 \r
1985                 EncBufLen = (StrLen - 1 ) / 2 - AES_BLOCK_SIZE;\r
1986                 if((EncBuf = malloc(EncBufLen)) != NULL)\r
1987                 {\r
1988                         for(IvIndex = 0; IvIndex < AES_BLOCK_SIZE; IvIndex++)\r
1989                         {\r
1990                                 AesCbcIv[IvIndex]  = hex2bin(*Get++) << 4;\r
1991                                 AesCbcIv[IvIndex] |= hex2bin(*Get++);\r
1992                         }\r
1993 \r
1994                         if(*Get++ == ':')\r
1995                         {\r
1996                                 if(CreateAesKey(AesKey, Key) == FFFTP_SUCCESS)\r
1997                                 {\r
1998                                         aes_decrypt_key(AesKey, 32, &Ctx);\r
1999 \r
2000                                         for(EncBufIndex = 0; EncBufIndex < EncBufLen; EncBufIndex++)\r
2001                                         {\r
2002                                                 EncBuf[EncBufIndex]  = hex2bin(*Get++) << 4;\r
2003                                                 EncBuf[EncBufIndex] |= hex2bin(*Get++);\r
2004                                         }\r
2005                                         if(aes_cbc_decrypt(EncBuf, Buf, EncBufLen, AesCbcIv, &Ctx) == EXIT_SUCCESS)\r
2006                                         {\r
2007                                                 Buf[EncBufLen] = NUL;\r
2008                                         }\r
2009                                 }\r
2010                         }\r
2011                         free(EncBuf);\r
2012                 }\r
2013         }\r
2014         return;\r
2015 }\r
2016 \r
2017 /*----- AES用固定長キーを作成 ----------------------------------------------\r
2018 *\r
2019 *       Parameter\r
2020 *               unsigned char *AesKey : AES暗号鍵\r
2021 *               const char *Key : 暗号化キー\r
2022 *\r
2023 *       Return Value\r
2024 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
2025 *       Note\r
2026 *               SHA-1をもちいて32Byte鍵を生成する\r
2027 *----------------------------------------------------------------------------*/\r
2028 \r
2029 static int CreateAesKey(unsigned char *AesKey, const char* Key)\r
2030 {\r
2031         char* HashKey;\r
2032         uint32 HashKeyLen;\r
2033         uint32 results[10];\r
2034         int ByteOffset;\r
2035         int KeyIndex;\r
2036         int ResIndex;\r
2037 \r
2038         HashKeyLen = strlen(Key) + 16;\r
2039         if((HashKey = malloc(HashKeyLen + 1)) == NULL){\r
2040                 return (FFFTP_FAIL);\r
2041         }\r
2042 \r
2043         strcpy(HashKey, Key);\r
2044         strcat(HashKey, ">g^r=@N7=//z<[`:");\r
2045     sha_memory((uchar *)HashKey, HashKeyLen, results);\r
2046 \r
2047         strcpy(HashKey, Key);\r
2048         strcat(HashKey, "VG77dO1#EyC]$|C@");\r
2049     sha_memory((uchar *)HashKey, HashKeyLen, results + 5);\r
2050 \r
2051         KeyIndex = 0;\r
2052         ResIndex = 0;\r
2053         while(ResIndex < 8){\r
2054                 for(ByteOffset = 0; ByteOffset < 4; ByteOffset++){\r
2055                         AesKey[KeyIndex++] = (results[ResIndex] >> ByteOffset * 8) & 0xff;\r
2056                 }\r
2057                 ResIndex++;\r
2058         }\r
2059         free(HashKey);\r
2060 \r
2061         return (FFFTP_SUCCESS);\r
2062 }\r
2063 \r
2064 \r
2065 /*===== レジストリとINIファイルのアクセス処理 ============*/\r
2066 \r
2067 \r
2068 /*===== INIファイル用のレジストリデータ =====*/\r
2069 \r
2070 typedef struct regdatatbl {\r
2071         char KeyName[80+1];                     /* キー名 */\r
2072         char ValTbl[REG_SECT_MAX];      /* 値のテーブル */\r
2073         int ValLen;                                     /* 値データのバイト数 */\r
2074         int Mode;                                       /* キーのモード */\r
2075         struct regdatatbl *Next;\r
2076 } REGDATATBL;\r
2077 \r
2078 /*===== プロトタイプ =====*/\r
2079 \r
2080 static BOOL WriteOutRegToFile(REGDATATBL *Pos);\r
2081 static int ReadInReg(char *Name, REGDATATBL **Handle);\r
2082 // 暗号化通信対応\r
2083 //static int StrCatOut(char *Src, int Len, char *Dst);\r
2084 //static int StrReadIn(char *Src, int Max, char *Dst);\r
2085 static char *ScanValue(void *Handle, char *Name);\r
2086 \r
2087 \r
2088 /*===== ローカルなワーク =====*/\r
2089 \r
2090 static int TmpRegType;\r
2091 \r
2092 \r
2093 \r
2094 /*----- レジストリのタイプを設定する ------------------------------------------\r
2095 *\r
2096 *       Parameter\r
2097 *               int Type : タイプ (REGTYPE_xxx)\r
2098 *\r
2099 *       Return Value\r
2100 *               int ステータス\r
2101 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2102 *----------------------------------------------------------------------------*/\r
2103 \r
2104 static void SetRegType(int Type)\r
2105 {\r
2106         TmpRegType = Type;\r
2107         return;\r
2108 }\r
2109 \r
2110 \r
2111 /*----- レジストリ/INIファイルをオープンする(読み込み)-----------------------\r
2112 *\r
2113 *       Parameter\r
2114 *               char *Name : レジストリ名\r
2115 *               void **Handle : ハンドルを返すワーク\r
2116 *\r
2117 *       Return Value\r
2118 *               int ステータス\r
2119 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2120 *----------------------------------------------------------------------------*/\r
2121 \r
2122 static int OpenReg(char *Name, void **Handle)\r
2123 {\r
2124         int Sts;\r
2125         char Tmp[FMAX_PATH+1];\r
2126 \r
2127         Sts = FFFTP_FAIL;\r
2128         if(TmpRegType == REGTYPE_REG)\r
2129         {\r
2130                 strcpy(Tmp, "Software\\Sota\\");\r
2131                 strcat(Tmp, Name);\r
2132                 if(RegOpenKeyEx(HKEY_CURRENT_USER, Tmp, 0, KEY_READ, (HKEY *)Handle) == ERROR_SUCCESS)\r
2133                         Sts = FFFTP_SUCCESS;\r
2134         }\r
2135         else\r
2136         {\r
2137                 if((Sts = ReadInReg(Name, (REGDATATBL **)Handle)) == FFFTP_SUCCESS)\r
2138                         ((REGDATATBL *)(*Handle))->Mode = 0;\r
2139         }\r
2140         return(Sts);\r
2141 }\r
2142 \r
2143 \r
2144 /*----- レジストリ/INIファイルを作成する(書き込み)---------------------------\r
2145 *\r
2146 *       Parameter\r
2147 *               char *Name : レジストリ名\r
2148 *               void **Handle : ハンドルを返すワーク\r
2149 *\r
2150 *       Return Value\r
2151 *               int ステータス\r
2152 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2153 *----------------------------------------------------------------------------*/\r
2154 \r
2155 static int CreateReg(char *Name, void **Handle)\r
2156 {\r
2157         int Sts;\r
2158         char Tmp[FMAX_PATH+1];\r
2159         DWORD Dispos;\r
2160 \r
2161         Sts = FFFTP_FAIL;\r
2162         if(TmpRegType == REGTYPE_REG)\r
2163         {\r
2164                 strcpy(Tmp, "Software\\Sota\\");\r
2165                 strcat(Tmp, Name);\r
2166                 if(RegCreateKeyEx(HKEY_CURRENT_USER, Tmp, 0, "", REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY | KEY_SET_VALUE, NULL, (HKEY *)Handle, &Dispos) == ERROR_SUCCESS)\r
2167                         Sts = FFFTP_SUCCESS;\r
2168         }\r
2169         else\r
2170         {\r
2171                 if((*Handle = malloc(sizeof(REGDATATBL))) != NULL)\r
2172                 {\r
2173                         strcpy(((REGDATATBL *)(*Handle))->KeyName, Name);\r
2174                         ((REGDATATBL *)(*Handle))->ValLen = 0;\r
2175                         ((REGDATATBL *)(*Handle))->Next = NULL;\r
2176                         ((REGDATATBL *)(*Handle))->Mode = 1;\r
2177                         Sts = FFFTP_SUCCESS;\r
2178                 }\r
2179         }\r
2180         return(Sts);\r
2181 }\r
2182 \r
2183 \r
2184 /*----- レジストリ/INIファイルをクローズする ----------------------------------\r
2185 *\r
2186 *       Parameter\r
2187 *               void *Handle : ハンドル\r
2188 *\r
2189 *       Return Value\r
2190 *               int ステータス\r
2191 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2192 *----------------------------------------------------------------------------*/\r
2193 \r
2194 static int CloseReg(void *Handle)\r
2195 {\r
2196         REGDATATBL *Pos;\r
2197         REGDATATBL *Next;\r
2198         // ポータブル版判定\r
2199 //      FILE *Strm;\r
2200 \r
2201         if(TmpRegType == REGTYPE_REG)\r
2202         {\r
2203                 RegCloseKey(Handle);\r
2204 \r
2205                 /* INIファイルを削除 */\r
2206                 // ポータブル版判定\r
2207 //              if((Strm = fopen(AskIniFilePath(), "rt")) != NULL)\r
2208 //              {\r
2209 //                      fclose(Strm);\r
2210 //                      MoveFileToTrashCan(AskIniFilePath());\r
2211 //              }\r
2212         }\r
2213         else\r
2214         {\r
2215                 if(((REGDATATBL *)Handle)->Mode == 1)\r
2216                 {\r
2217                         if(WriteOutRegToFile(Handle) == TRUE)\r
2218                         {\r
2219 //                              /* レジストリをクリア */\r
2220 //                              ClearRegistry();\r
2221                         }\r
2222                 }\r
2223                 /* テーブルを削除 */\r
2224                 Pos = Handle;\r
2225                 while(Pos != NULL)\r
2226                 {\r
2227                         Next = Pos->Next;\r
2228                         free(Pos);\r
2229                         Pos = Next;\r
2230                 }\r
2231         }\r
2232         return(FFFTP_SUCCESS);\r
2233 }\r
2234 \r
2235 \r
2236 /*----- レジストリ情報をINIファイルに書き込む ---------------------------------\r
2237 *\r
2238 *       Parameter\r
2239 *               REGDATATBL *Pos : レジストリデータ\r
2240 *\r
2241 *       Return Value\r
2242 *               なし\r
2243 *----------------------------------------------------------------------------*/\r
2244 \r
2245 static BOOL WriteOutRegToFile(REGDATATBL *Pos)\r
2246 {\r
2247         FILE *Strm;\r
2248         char *Disp;\r
2249         BOOL Ret;\r
2250 \r
2251         Ret = FALSE;\r
2252         if((Strm = fopen(AskIniFilePath(), "wt")) != NULL)\r
2253         {\r
2254                 fprintf(Strm, MSGJPN239);\r
2255                 while(Pos != NULL)\r
2256                 {\r
2257                         fprintf(Strm, "\n[%s]\n", Pos->KeyName);\r
2258 \r
2259                         Disp = Pos->ValTbl;\r
2260                         while(Disp < (Pos->ValTbl + Pos->ValLen))\r
2261                         {\r
2262                                 fprintf(Strm, "%s\n", Disp);\r
2263                                 Disp = Disp + strlen(Disp) + 1;\r
2264                         }\r
2265                         Pos = Pos->Next;\r
2266                 }\r
2267                 fclose(Strm);\r
2268                 Ret = TRUE;\r
2269         }\r
2270         else\r
2271                 MessageBox(NULL, MSGJPN240, "FFFTP", MB_OK);\r
2272 \r
2273         return(Ret);\r
2274 }\r
2275 \r
2276 \r
2277 /*----- INIファイルからレジストリ情報を読み込む -------------------------------\r
2278 *\r
2279 *       Parameter\r
2280 *               char *Name : 名前\r
2281 *               void *Handle : ハンドル\r
2282 *\r
2283 *       Return Value\r
2284 *               int ステータス\r
2285 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2286 *----------------------------------------------------------------------------*/\r
2287 \r
2288 static int ReadInReg(char *Name, REGDATATBL **Handle)\r
2289 {\r
2290         FILE *Strm;\r
2291         char *Buf;\r
2292         char *Tmp;\r
2293         char *Data;\r
2294         REGDATATBL *New;\r
2295         REGDATATBL *Pos;\r
2296         int Sts;\r
2297 \r
2298         Sts = FFFTP_FAIL;\r
2299         *Handle = NULL;\r
2300         // バグ修正\r
2301         New = NULL;\r
2302 \r
2303         if((Strm = fopen(AskIniFilePath(), "rt")) != NULL)\r
2304         {\r
2305                 if((Buf = malloc(REG_SECT_MAX)) != NULL)\r
2306                 {\r
2307                         while(fgets(Buf, REG_SECT_MAX, Strm) != NULL)\r
2308                         {\r
2309                                 if(*Buf != '#')\r
2310                                 {\r
2311                                         if((Tmp = strchr(Buf, '\n')) != NULL)\r
2312                                                 *Tmp = NUL;\r
2313 \r
2314                                         if(*Buf == '[')\r
2315                                         {\r
2316                                                 if((New = malloc(sizeof(REGDATATBL))) != NULL)\r
2317                                                 {\r
2318                                                         if((Tmp = strchr(Buf, ']')) != NULL)\r
2319                                                                 *Tmp = NUL;\r
2320                                                         // バグ修正\r
2321 //                                                      strcpy(New->KeyName, Buf+1);\r
2322                                                         strncpy(New->KeyName, Buf+1, 80);\r
2323                                                         New->KeyName[80] = NUL;\r
2324                                                         New->ValLen = 0;\r
2325                                                         New->Next = NULL;\r
2326                                                         Data = New->ValTbl;\r
2327                                                 }\r
2328                                                 if(*Handle == NULL)\r
2329                                                         *Handle = New;\r
2330                                                 else\r
2331                                                 {\r
2332                                                         Pos = *Handle;\r
2333                                                         while(Pos->Next != NULL)\r
2334                                                                 Pos = Pos->Next;\r
2335                                                         Pos->Next = New;\r
2336                                                 }\r
2337                                         }\r
2338                                         else if(strlen(Buf) > 0)\r
2339                                         {\r
2340                                                 // バグ修正\r
2341 //                                              strcpy(Data, Buf);\r
2342 //                                              Data += strlen(Buf) + 1;\r
2343 //                                              New->ValLen += strlen(Buf) + 1;\r
2344                                                 if(Data != NULL && New != NULL)\r
2345                                                 {\r
2346                                                         if(New->ValLen + strlen(Buf) + 1 <= REG_SECT_MAX)\r
2347                                                         {\r
2348                                                                 strcpy(Data, Buf);\r
2349                                                                 Data += strlen(Buf) + 1;\r
2350                                                                 New->ValLen += strlen(Buf) + 1;\r
2351                                                         }\r
2352                                                 }\r
2353                                         }\r
2354                                 }\r
2355                         }\r
2356                         Sts = FFFTP_SUCCESS;\r
2357                         free(Buf);\r
2358                 }\r
2359                 fclose(Strm);\r
2360         }\r
2361         return(Sts);\r
2362 }\r
2363 \r
2364 \r
2365 /*----- サブキーをオープンする ------------------------------------------------\r
2366 *\r
2367 *       Parameter\r
2368 *               void *Parent : 親のハンドル\r
2369 *               char *Name : 名前\r
2370 *               void **Handle : ハンドルを返すワーク\r
2371 *\r
2372 *       Return Value\r
2373 *               int ステータス\r
2374 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2375 *----------------------------------------------------------------------------*/\r
2376 \r
2377 static int OpenSubKey(void *Parent, char *Name, void **Handle)\r
2378 {\r
2379         int Sts;\r
2380         char Key[80];\r
2381         REGDATATBL *Pos;\r
2382 \r
2383         Sts = FFFTP_FAIL;\r
2384         if(TmpRegType == REGTYPE_REG)\r
2385         {\r
2386                 if(RegOpenKeyEx(Parent, Name, 0, KEY_READ, (HKEY *)Handle) == ERROR_SUCCESS)\r
2387                         Sts = FFFTP_SUCCESS;\r
2388         }\r
2389         else\r
2390         {\r
2391                 strcpy(Key, ((REGDATATBL *)Parent)->KeyName);\r
2392                 strcat(Key, "\\");\r
2393                 strcat(Key, Name);\r
2394                 Pos = Parent;\r
2395                 while(Pos != NULL)\r
2396                 {\r
2397                         if(strcmp(Pos->KeyName, Key) == 0)\r
2398                         {\r
2399                                 *Handle = Pos;\r
2400                                 Sts = FFFTP_SUCCESS;\r
2401                                 break;\r
2402                         }\r
2403                         Pos = Pos->Next;\r
2404                 }\r
2405         }\r
2406         return(Sts);\r
2407 }\r
2408 \r
2409 \r
2410 /*----- サブキーを作成する ----------------------------------------------------\r
2411 *\r
2412 *       Parameter\r
2413 *               void *Parent : 親のハンドル\r
2414 *               char *Name : 名前\r
2415 *               void **Handle : ハンドルを返すワーク\r
2416 *\r
2417 *       Return Value\r
2418 *               int ステータス\r
2419 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2420 *----------------------------------------------------------------------------*/\r
2421 \r
2422 static int CreateSubKey(void *Parent, char *Name, void **Handle)\r
2423 {\r
2424         int Sts;\r
2425         DWORD Dispos;\r
2426         REGDATATBL *Pos;\r
2427 \r
2428         Sts = FFFTP_FAIL;\r
2429         if(TmpRegType == REGTYPE_REG)\r
2430         {\r
2431                 if(RegCreateKeyEx(Parent, Name, 0, "", REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, (HKEY *)Handle, &Dispos) == ERROR_SUCCESS)\r
2432                         Sts = FFFTP_SUCCESS;\r
2433         }\r
2434         else\r
2435         {\r
2436                 if((*Handle = malloc(sizeof(REGDATATBL))) != NULL)\r
2437                 {\r
2438                         strcpy(((REGDATATBL *)(*Handle))->KeyName, ((REGDATATBL *)Parent)->KeyName);\r
2439                         strcat(((REGDATATBL *)(*Handle))->KeyName, "\\");\r
2440                         strcat(((REGDATATBL *)(*Handle))->KeyName, Name);\r
2441 \r
2442                         ((REGDATATBL *)(*Handle))->ValLen = 0;\r
2443                         ((REGDATATBL *)(*Handle))->Next = NULL;\r
2444 \r
2445                         Pos = (REGDATATBL *)Parent;\r
2446                         while(Pos->Next != NULL)\r
2447                                 Pos = Pos->Next;\r
2448                         Pos->Next = *Handle;\r
2449                         Sts = FFFTP_SUCCESS;\r
2450                 }\r
2451         }\r
2452         return(Sts);\r
2453 }\r
2454 \r
2455 \r
2456 /*----- サブキーをクローズする ------------------------------------------------\r
2457 *\r
2458 *       Parameter\r
2459 *               void *Handle : ハンドル\r
2460 *\r
2461 *       Return Value\r
2462 *               int ステータス\r
2463 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2464 *----------------------------------------------------------------------------*/\r
2465 \r
2466 static int CloseSubKey(void *Handle)\r
2467 {\r
2468         if(TmpRegType == REGTYPE_REG)\r
2469                 RegCloseKey(Handle);\r
2470         else\r
2471         {\r
2472                 /* Nothing */\r
2473         }\r
2474         return(FFFTP_SUCCESS);\r
2475 }\r
2476 \r
2477 \r
2478 /*----- サブキーを削除する ----------------------------------------------------\r
2479 *\r
2480 *       Parameter\r
2481 *               void *Handle : ハンドル\r
2482 *               char *Name : 名前\r
2483 *\r
2484 *       Return Value\r
2485 *               int ステータス\r
2486 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2487 *----------------------------------------------------------------------------*/\r
2488 \r
2489 static int DeleteSubKey(void *Handle, char *Name)\r
2490 {\r
2491         int Sts;\r
2492 \r
2493         Sts = FFFTP_FAIL;\r
2494         if(TmpRegType == REGTYPE_REG)\r
2495         {\r
2496                 if(RegDeleteKey(Handle, Name) == ERROR_SUCCESS)\r
2497                         Sts = FFFTP_SUCCESS;\r
2498         }\r
2499         else\r
2500         {\r
2501                 Sts = FFFTP_FAIL;\r
2502         }\r
2503         return(Sts);\r
2504 }\r
2505 \r
2506 \r
2507 /*----- 値を削除する ----------------------------------------------------------\r
2508 *\r
2509 *       Parameter\r
2510 *               void *Handle : ハンドル\r
2511 *               char *Name : 名前\r
2512 *\r
2513 *       Return Value\r
2514 *               int ステータス\r
2515 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2516 *----------------------------------------------------------------------------*/\r
2517 \r
2518 static int DeleteValue(void *Handle, char *Name)\r
2519 {\r
2520         int Sts;\r
2521 \r
2522         Sts = FFFTP_FAIL;\r
2523         if(TmpRegType == REGTYPE_REG)\r
2524         {\r
2525                 if(RegDeleteValue(Handle, Name) == ERROR_SUCCESS)\r
2526                         Sts = FFFTP_SUCCESS;\r
2527         }\r
2528         else\r
2529         {\r
2530                 Sts = FFFTP_FAIL;\r
2531         }\r
2532         return(Sts);\r
2533 }\r
2534 \r
2535 \r
2536 /*----- INT値を読み込む -------------------------------------------------------\r
2537 *\r
2538 *       Parameter\r
2539 *               void *Handle : ハンドル\r
2540 *               char *Name : 名前\r
2541 *               int *Value : INT値を返すワーク\r
2542 *\r
2543 *       Return Value\r
2544 *               int ステータス\r
2545 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2546 *----------------------------------------------------------------------------*/\r
2547 \r
2548 static int ReadIntValueFromReg(void *Handle, char *Name, int *Value)\r
2549 {\r
2550         int Sts;\r
2551         DWORD Size;\r
2552         char *Pos;\r
2553 \r
2554         Sts = FFFTP_FAIL;\r
2555         if(TmpRegType == REGTYPE_REG)\r
2556         {\r
2557                 Size = sizeof(int);\r
2558                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Value, &Size) == ERROR_SUCCESS)\r
2559                         Sts = FFFTP_SUCCESS;\r
2560         }\r
2561         else\r
2562         {\r
2563                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2564                 {\r
2565                         *Value = atoi(Pos);\r
2566                         Sts = FFFTP_SUCCESS;\r
2567                 }\r
2568         }\r
2569         // 全設定暗号化対応\r
2570         if(Sts == FFFTP_SUCCESS)\r
2571         {\r
2572                 if(EncryptSettings == YES)\r
2573                 {\r
2574                         UnmaskSettingsData(Name, strlen(Name), Value, sizeof(int), NO);\r
2575                         CalculateSettingsDataChecksum(Value, sizeof(int));\r
2576                 }\r
2577         }\r
2578         return(Sts);\r
2579 }\r
2580 \r
2581 \r
2582 /*----- INT値を書き込む -------------------------------------------------------\r
2583 *\r
2584 *       Parameter\r
2585 *               void *Handle : ハンドル\r
2586 *               char *Name : 名前\r
2587 *               int Value : INT値\r
2588 *\r
2589 *       Return Value\r
2590 *               int ステータス\r
2591 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2592 *----------------------------------------------------------------------------*/\r
2593 \r
2594 static int WriteIntValueToReg(void *Handle, char *Name, int Value)\r
2595 {\r
2596         REGDATATBL *Pos;\r
2597         char *Data;\r
2598         char Tmp[20];\r
2599 \r
2600         // 全設定暗号化対応\r
2601         if(EncryptSettings == YES)\r
2602                 MaskSettingsData(Name, strlen(Name), &Value, sizeof(int), NO);\r
2603         if(TmpRegType == REGTYPE_REG)\r
2604                 RegSetValueEx(Handle, Name, 0, REG_DWORD, (CONST BYTE *)&Value, sizeof(int));\r
2605         else\r
2606         {\r
2607                 Pos = (REGDATATBL *)Handle;\r
2608                 Data = Pos->ValTbl + Pos->ValLen;\r
2609                 strcpy(Data, Name);\r
2610                 strcat(Data, "=");\r
2611                 sprintf(Tmp, "%d", Value);\r
2612                 strcat(Data, Tmp);\r
2613                 Pos->ValLen += strlen(Data) + 1;\r
2614         }\r
2615         // 全設定暗号化対応\r
2616         if(EncryptSettings == YES)\r
2617         {\r
2618                 UnmaskSettingsData(Name, strlen(Name), &Value, sizeof(int), NO);\r
2619                 CalculateSettingsDataChecksum(&Value, sizeof(int));\r
2620         }\r
2621         return(FFFTP_SUCCESS);\r
2622 }\r
2623 \r
2624 \r
2625 /*----- 文字列を読み込む ------------------------------------------------------\r
2626 *\r
2627 *       Parameter\r
2628 *               void *Handle : ハンドル\r
2629 *               char *Name : 名前\r
2630 *               char *Str : 文字列を返すワーク\r
2631 *               DWORD Size : 最大サイズ\r
2632 *\r
2633 *       Return Value\r
2634 *               int ステータス\r
2635 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2636 *----------------------------------------------------------------------------*/\r
2637 \r
2638 static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size)\r
2639 {\r
2640         int Sts;\r
2641         char *Pos;\r
2642         // UTF-8対応\r
2643         DWORD TempSize;\r
2644         char* pa0;\r
2645         wchar_t* pw0;\r
2646 \r
2647         Sts = FFFTP_FAIL;\r
2648         if(TmpRegType == REGTYPE_REG)\r
2649         {\r
2650                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Str, &Size) == ERROR_SUCCESS)\r
2651                 {\r
2652                         if(*(Str + Size - 1) != NUL)\r
2653                                 *(Str + Size) = NUL;\r
2654                         Sts = FFFTP_SUCCESS;\r
2655                 }\r
2656         }\r
2657         else\r
2658         {\r
2659                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2660                 {\r
2661                         // UTF-8対応\r
2662 //                      Size = min1(Size-1, strlen(Pos));\r
2663 //                      Size = StrReadIn(Pos, Size, Str);\r
2664 //                      *(Str + Size) = NUL;\r
2665 //                      Sts = FFFTP_SUCCESS;\r
2666                         switch(IniKanjiCode)\r
2667                         {\r
2668                         case KANJI_NOCNV:\r
2669                                 TempSize = min1(Size-1, strlen(Pos));\r
2670                                 TempSize = StrReadIn(Pos, TempSize, Str);\r
2671                                 *(Str + TempSize) = NUL;\r
2672                                 Sts = FFFTP_SUCCESS;\r
2673                                 break;\r
2674                         case KANJI_SJIS:\r
2675                                 if(pa0 = AllocateStringA(Size * 4))\r
2676                                 {\r
2677                                         if(pw0 = AllocateStringW(Size * 4 * 4))\r
2678                                         {\r
2679                                                 TempSize = min1((Size * 4) - 1, strlen(Pos));\r
2680                                                 TempSize = StrReadIn(Pos, TempSize, pa0);\r
2681                                                 *(pa0 + TempSize) = NUL;\r
2682                                                 AtoW(pw0, Size * 4 * 4, pa0, -1);\r
2683                                                 WtoM(Str, Size, pw0, -1);\r
2684                                                 TerminateStringM(Str, Size);\r
2685                                                 Sts = FFFTP_SUCCESS;\r
2686                                                 FreeDuplicatedString(pw0);\r
2687                                         }\r
2688                                         FreeDuplicatedString(pa0);\r
2689                                 }\r
2690                                 break;\r
2691                         }\r
2692                 }\r
2693         }\r
2694         // 全設定暗号化対応\r
2695         if(Sts == FFFTP_SUCCESS)\r
2696         {\r
2697                 if(EncryptSettings == YES)\r
2698                 {\r
2699                         UnmaskSettingsData(Name, strlen(Name), Str, strlen(Str) + 1, YES);\r
2700                         CalculateSettingsDataChecksum(Str, strlen(Str) + 1);\r
2701                 }\r
2702         }\r
2703         return(Sts);\r
2704 }\r
2705 \r
2706 \r
2707 /*----- 文字列を書き込む ------------------------------------------------------\r
2708 *\r
2709 *       Parameter\r
2710 *               void *Handle : ハンドル\r
2711 *               char *Name : 名前\r
2712 *               char *Str :文字列\r
2713 *\r
2714 *       Return Value\r
2715 *               int ステータス\r
2716 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2717 *----------------------------------------------------------------------------*/\r
2718 \r
2719 static int WriteStringToReg(void *Handle, char *Name, char *Str)\r
2720 {\r
2721         REGDATATBL *Pos;\r
2722         char *Data;\r
2723 \r
2724         // 全設定暗号化対応\r
2725         if(EncryptSettings == YES)\r
2726                 MaskSettingsData(Name, strlen(Name), Str, strlen(Str) + 1, YES);\r
2727         if(TmpRegType == REGTYPE_REG)\r
2728         // 全設定暗号化対応\r
2729 //              RegSetValueEx(Handle, Name, 0, REG_SZ, (CONST BYTE *)Str, strlen(Str)+1);\r
2730                 RegSetValueEx(Handle, Name, 0, EncryptSettings == YES ? REG_BINARY : REG_SZ, (CONST BYTE *)Str, strlen(Str)+1);\r
2731         else\r
2732         {\r
2733                 Pos = (REGDATATBL *)Handle;\r
2734                 Data = Pos->ValTbl + Pos->ValLen;\r
2735                 strcpy(Data, Name);\r
2736                 strcat(Data, "=");\r
2737                 Pos->ValLen += strlen(Data);\r
2738                 Data = Pos->ValTbl + Pos->ValLen;\r
2739                 Pos->ValLen += StrCatOut(Str, strlen(Str), Data) + 1;\r
2740         }\r
2741         // 全設定暗号化対応\r
2742         if(EncryptSettings == YES)\r
2743         {\r
2744                 UnmaskSettingsData(Name, strlen(Name), Str, strlen(Str) + 1, YES);\r
2745                 CalculateSettingsDataChecksum(Str, strlen(Str) + 1);\r
2746         }\r
2747         return(FFFTP_SUCCESS);\r
2748 }\r
2749 \r
2750 \r
2751 /*----- マルチ文字列を読み込む ------------------------------------------------\r
2752 *\r
2753 *       Parameter\r
2754 *               void *Handle : ハンドル\r
2755 *               char *Name : 名前\r
2756 *               char *Str : 文字列を返すワーク\r
2757 *               DWORD Size : 最大サイズ\r
2758 *\r
2759 *       Return Value\r
2760 *               int ステータス\r
2761 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2762 *----------------------------------------------------------------------------*/\r
2763 \r
2764 static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Size)\r
2765 {\r
2766         int Sts;\r
2767         char *Pos;\r
2768         // UTF-8対応\r
2769         DWORD TempSize;\r
2770         char* pa0;\r
2771         wchar_t* pw0;\r
2772 \r
2773         Sts = FFFTP_FAIL;\r
2774         if(TmpRegType == REGTYPE_REG)\r
2775         {\r
2776                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Str, &Size) == ERROR_SUCCESS)\r
2777                 {\r
2778                         if(*(Str + Size - 1) != NUL)\r
2779                                 *(Str + Size) = NUL;\r
2780                         Sts = FFFTP_SUCCESS;\r
2781                 }\r
2782         }\r
2783         else\r
2784         {\r
2785                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2786                 {\r
2787                         // UTF-8対応\r
2788 //                      Size = min1(Size-1, strlen(Pos));\r
2789 //                      Size = StrReadIn(Pos, Size, Str);\r
2790 //                      *(Str + Size) = NUL;\r
2791 //                      Sts = FFFTP_SUCCESS;\r
2792                         switch(IniKanjiCode)\r
2793                         {\r
2794                         case KANJI_NOCNV:\r
2795                                 TempSize = min1(Size - 2, strlen(Pos));\r
2796                                 TempSize = StrReadIn(Pos, TempSize, Str);\r
2797                                 *(Str + TempSize) = NUL;\r
2798                                 *(Str + TempSize + 1) = NUL;\r
2799                                 Sts = FFFTP_SUCCESS;\r
2800                                 break;\r
2801                         case KANJI_SJIS:\r
2802                                 if(pa0 = AllocateStringA(Size * 4))\r
2803                                 {\r
2804                                         if(pw0 = AllocateStringW(Size * 4 * 4))\r
2805                                         {\r
2806                                                 TempSize = min1((Size * 4) - 2, strlen(Pos));\r
2807                                                 TempSize = StrReadIn(Pos, TempSize, pa0);\r
2808                                                 *(pa0 + TempSize) = NUL;\r
2809                                                 *(pa0 + TempSize + 1) = NUL;\r
2810                                                 AtoWMultiString(pw0, Size * 4 * 4, pa0);\r
2811                                                 WtoMMultiString(Str, Size, pw0);\r
2812                                                 TerminateStringM(Str, Size);\r
2813                                                 TerminateStringM(Str, Size - 1);\r
2814                                                 Sts = FFFTP_SUCCESS;\r
2815                                                 FreeDuplicatedString(pw0);\r
2816                                         }\r
2817                                         FreeDuplicatedString(pa0);\r
2818                                 }\r
2819                                 break;\r
2820                         }\r
2821                 }\r
2822         }\r
2823         // 全設定暗号化対応\r
2824         if(Sts == FFFTP_SUCCESS)\r
2825         {\r
2826                 if(EncryptSettings == YES)\r
2827                 {\r
2828                         UnmaskSettingsData(Name, strlen(Name), Str, StrMultiLen(Str) + 1, YES);\r
2829                         CalculateSettingsDataChecksum(Str, StrMultiLen(Str) + 1);\r
2830                 }\r
2831         }\r
2832         return(Sts);\r
2833 }\r
2834 \r
2835 \r
2836 /*----- マルチ文字列を書き込む ------------------------------------------------\r
2837 *\r
2838 *       Parameter\r
2839 *               void *Handle : ハンドル\r
2840 *               char *Name : 名前\r
2841 *               char *Str : 文字列\r
2842 *\r
2843 *       Return Value\r
2844 *               int ステータス\r
2845 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2846 *----------------------------------------------------------------------------*/\r
2847 \r
2848 static int WriteMultiStringToReg(void *Handle, char *Name, char *Str)\r
2849 {\r
2850         REGDATATBL *Pos;\r
2851         char *Data;\r
2852 \r
2853         // 全設定暗号化対応\r
2854         if(EncryptSettings == YES)\r
2855                 MaskSettingsData(Name, strlen(Name), Str, StrMultiLen(Str) + 1, YES);\r
2856         if(TmpRegType == REGTYPE_REG)\r
2857         // 全設定暗号化対応\r
2858 //              RegSetValueEx(Handle, Name, 0, REG_MULTI_SZ, (CONST BYTE *)Str, StrMultiLen(Str)+1);\r
2859                 RegSetValueEx(Handle, Name, 0, EncryptSettings == YES ? REG_BINARY : REG_MULTI_SZ, (CONST BYTE *)Str, StrMultiLen(Str)+1);\r
2860         else\r
2861         {\r
2862                 Pos = (REGDATATBL *)Handle;\r
2863                 Data = Pos->ValTbl + Pos->ValLen;\r
2864                 strcpy(Data, Name);\r
2865                 strcat(Data, "=");\r
2866                 Pos->ValLen += strlen(Data);\r
2867                 Data = Pos->ValTbl + Pos->ValLen;\r
2868                 Pos->ValLen += StrCatOut(Str, StrMultiLen(Str), Data) + 1;\r
2869         }\r
2870         // 全設定暗号化対応\r
2871         if(EncryptSettings == YES)\r
2872         {\r
2873                 UnmaskSettingsData(Name, strlen(Name), Str, StrMultiLen(Str) + 1, YES);\r
2874                 CalculateSettingsDataChecksum(Str, StrMultiLen(Str) + 1);\r
2875         }\r
2876         return(FFFTP_SUCCESS);\r
2877 }\r
2878 \r
2879 \r
2880 /*----- バイナリを読み込む-----------------------------------------------------\r
2881 *\r
2882 *       Parameter\r
2883 *               void *Handle : ハンドル\r
2884 *               char *Name : 名前\r
2885 *               void *Bin : バイナリを返すワーク\r
2886 *               DWORD Size : 最大サイズ\r
2887 *\r
2888 *       Return Value\r
2889 *               int ステータス\r
2890 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2891 *----------------------------------------------------------------------------*/\r
2892 \r
2893 static int ReadBinaryFromReg(void *Handle, char *Name, void *Bin, DWORD Size)\r
2894 {\r
2895         int Sts;\r
2896         char *Pos;\r
2897 \r
2898         Sts = FFFTP_FAIL;\r
2899         if(TmpRegType == REGTYPE_REG)\r
2900         {\r
2901                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Bin, &Size) == ERROR_SUCCESS)\r
2902                         Sts = FFFTP_SUCCESS;\r
2903         }\r
2904         else\r
2905         {\r
2906                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2907                 {\r
2908                         Size = min1(Size, strlen(Pos));\r
2909                         Size = StrReadIn(Pos, Size, Bin);\r
2910                         Sts = FFFTP_SUCCESS;\r
2911                 }\r
2912         }\r
2913         // 全設定暗号化対応\r
2914         if(Sts == FFFTP_SUCCESS)\r
2915         {\r
2916                 if(EncryptSettings == YES)\r
2917                 {\r
2918                         UnmaskSettingsData(Name, strlen(Name), Bin, Size, NO);\r
2919                         CalculateSettingsDataChecksum(Bin, Size);\r
2920                 }\r
2921         }\r
2922         return(Sts);\r
2923 }\r
2924 \r
2925 \r
2926 /*----- バイナリを書き込む ----------------------------------------------------\r
2927 *\r
2928 *       Parameter\r
2929 *               void *Handle : ハンドル\r
2930 *               char *Name : 名前\r
2931 *               void *Bin : バイナリ\r
2932 *               int Len : 長さ\r
2933 *\r
2934 *       Return Value\r
2935 *               int ステータス\r
2936 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2937 *----------------------------------------------------------------------------*/\r
2938 \r
2939 static int WriteBinaryToReg(void *Handle, char *Name, void *Bin, int Len)\r
2940 {\r
2941         REGDATATBL *Pos;\r
2942         char *Data;\r
2943 \r
2944         // 全設定暗号化対応\r
2945         if(EncryptSettings == YES)\r
2946                 MaskSettingsData(Name, strlen(Name), Bin, Len, NO);\r
2947         if(TmpRegType == REGTYPE_REG)\r
2948                 RegSetValueEx(Handle, Name, 0, REG_BINARY, (CONST BYTE *)Bin, Len);\r
2949         else\r
2950         {\r
2951                 Pos = (REGDATATBL *)Handle;\r
2952                 Data = Pos->ValTbl + Pos->ValLen;\r
2953                 strcpy(Data, Name);\r
2954                 strcat(Data, "=");\r
2955                 Pos->ValLen += strlen(Data);\r
2956                 Data = Pos->ValTbl + Pos->ValLen;\r
2957                 Pos->ValLen += StrCatOut(Bin, Len, Data) + 1;\r
2958         }\r
2959         // 全設定暗号化対応\r
2960         if(EncryptSettings == YES)\r
2961         {\r
2962                 UnmaskSettingsData(Name, strlen(Name), Bin, Len, NO);\r
2963                 CalculateSettingsDataChecksum(Bin, Len);\r
2964         }\r
2965         return(FFFTP_SUCCESS);\r
2966 }\r
2967 \r
2968 \r
2969 /*----- 文字列をバッファに追加書き込みする ------------------------------------\r
2970 *\r
2971 *       Parameter\r
2972 *               char *Src : 文字列\r
2973 *               int len : 文字列の長さ\r
2974 *               char *Dst : 書き込みするバッファ\r
2975 *\r
2976 *       Return Value\r
2977 *               int 追加したバイト数\r
2978 *----------------------------------------------------------------------------*/\r
2979 \r
2980 static int StrCatOut(char *Src, int Len, char *Dst)\r
2981 {\r
2982         int Count;\r
2983 \r
2984         Dst += strlen(Dst);\r
2985         Count = 0;\r
2986         for(; Len > 0; Len--)\r
2987         {\r
2988                 if(*Src == '\\')\r
2989                 {\r
2990                         *Dst++ = '\\';\r
2991                         *Dst++ = '\\';\r
2992                         Count += 2;\r
2993                 }\r
2994                 else if((*Src >= 0x20) && (*Src <= 0x7E))\r
2995                 {\r
2996                         *Dst++ = *Src;\r
2997                         Count++;\r
2998                 }\r
2999                 else\r
3000                 {\r
3001                         sprintf(Dst, "\\%02X", *(unsigned char *)Src);\r
3002                         Dst += 3;\r
3003                         Count += 3;\r
3004                 }\r
3005                 Src++;\r
3006         }\r
3007         *Dst = NUL;\r
3008         return(Count);\r
3009 }\r
3010 \r
3011 \r
3012 /*----- 文字列をバッファに読み込む --------------------------------------------\r
3013 *\r
3014 *       Parameter\r
3015 *               char *Src : 文字列\r
3016 *               int Max : 最大サイズ\r
3017 *               char *Dst : 書き込みするバッファ\r
3018 *\r
3019 *       Return Value\r
3020 *               int 読み込んだバイト数\r
3021 *----------------------------------------------------------------------------*/\r
3022 \r
3023 static int StrReadIn(char *Src, int Max, char *Dst)\r
3024 {\r
3025         int Count;\r
3026         int Tmp;\r
3027 \r
3028         Count = 0;\r
3029         while(*Src != NUL)\r
3030         {\r
3031                 if(Count >= Max)\r
3032                         break;\r
3033 \r
3034                 if(*Src == '\\')\r
3035                 {\r
3036                         Src++;\r
3037                         if(*Src == '\\')\r
3038                                 *Dst = '\\';\r
3039                         else\r
3040                         {\r
3041                                 sscanf(Src, "%02x", &Tmp);\r
3042                                 *Dst = Tmp;\r
3043                                 Src++;\r
3044                         }\r
3045                 }\r
3046                 else\r
3047                         *Dst = *Src;\r
3048 \r
3049                 Count++;\r
3050                 Dst++;\r
3051                 Src++;\r
3052         }\r
3053         return(Count);\r
3054 }\r
3055 \r
3056 \r
3057 /*----- 値を検索する ----------------------------------------------------------\r
3058 *\r
3059 *       Parameter\r
3060 *               char *Handle : ハンドル\r
3061 *               char *Name : 名前\r
3062 *\r
3063 *       Return Value\r
3064 *               char *値データの先頭\r
3065 *                       NULL=指定の名前の値が見つからない\r
3066 *----------------------------------------------------------------------------*/\r
3067 \r
3068 static char *ScanValue(void *Handle, char *Name)\r
3069 {\r
3070         REGDATATBL *Cur;\r
3071         char *Pos;\r
3072         char *Ret;\r
3073 \r
3074         Ret = NULL;\r
3075         Cur = Handle;\r
3076         Pos = Cur->ValTbl;\r
3077         while(Pos < (Cur->ValTbl + Cur->ValLen))\r
3078         {\r
3079                 if((strncmp(Name, Pos, strlen(Name)) == 0) &&\r
3080                    (*(Pos + strlen(Name)) == '='))\r
3081                 {\r
3082                         Ret = Pos + strlen(Name) + 1;\r
3083                         break;\r
3084                 }\r
3085                 Pos += strlen(Pos) + 1;\r
3086         }\r
3087         return(Ret);\r
3088 }\r
3089 \r
3090 \r
3091 /*----------- パスワードの妥当性を確認する ------------------------------------\r
3092 *\r
3093 *       Parameter\r
3094 *               char *Password: パスワード文字列\r
3095 *               char *HashStr: SHA-1ハッシュ文字列\r
3096 *\r
3097 *       Return Value\r
3098 *               int 0 不一致\r
3099 *                       1: 一致\r
3100 *                       2: 異常\r
3101 *----------------------------------------------------------------------------*/\r
3102 int CheckPasswordValidity( char* Password, int length, const char* HashStr )\r
3103 {\r
3104         ulong hash1[5];\r
3105         ulong hash2[5];\r
3106         \r
3107         int i, j;\r
3108         \r
3109         const char* p = HashStr;\r
3110         \r
3111         /* 空文字列は一致したことにする */\r
3112         if( HashStr[0] == NUL ) return 1;\r
3113 \r
3114         /* Hashをチェックするする*/\r
3115         if( strlen(HashStr) != 40 )     return 2;\r
3116 \r
3117         /* Hashをデコードする*/\r
3118         for( i = 0; i < 5; i++ ){\r
3119                 ulong decode = 0;\r
3120                 for( j = 0; j < 8; j++ ){\r
3121                         if( *p < 0x40 || 0x40 + 15 < *p ){\r
3122                                 return 2;\r
3123                         }\r
3124                         decode = (decode << 4 ) + (*p - 0x40);\r
3125                         ++p;\r
3126                 }\r
3127                 hash1[i] = decode;\r
3128         }\r
3129         \r
3130         /* Password をハッシュする */\r
3131         sha_memory( Password, length, hash2 );\r
3132         \r
3133         if( memcmp( (char*)hash1, (char*)hash2, sizeof( hash1 )) == 0 ){\r
3134                 return 1;\r
3135         }\r
3136         return 0;\r
3137 }\r
3138 \r
3139 /*----------- パスワードの妥当性チェックのための文字列を作成する ------------\r
3140 *\r
3141 *       Parameter\r
3142 *               char *Password: パスワード文字列\r
3143 *               char *Str: SHA-1ハッシュ文字列格納場所 (41bytes以上)\r
3144 *\r
3145 *       Return Value\r
3146 *               None\r
3147 *----------------------------------------------------------------------------*/\r
3148 void CreatePasswordHash( char* Password, int length, char* HashStr )\r
3149 {\r
3150         ulong hash[5];\r
3151         int i, j;\r
3152         unsigned char *p = (unsigned char *)HashStr;\r
3153 \r
3154         sha_memory( Password, length, hash );\r
3155 \r
3156         for( i = 0; i < 5; i++ ){\r
3157                 ulong rest = hash[i];\r
3158                 for( j = 0; j < 8; j++ ){\r
3159                         *p++ = (unsigned char)((rest & 0xf0000000) >> 28) + '@';\r
3160                         rest <<= 4;\r
3161                 }\r
3162         }\r
3163         *p = NUL;\r
3164 }\r
3165 \r
3166 void SetHashSalt( DWORD salt )\r
3167 {\r
3168         unsigned char* pos = &SecretKey[strlen(SecretKey) + 1];\r
3169         *pos++ = ( salt >> 24 ) & 0xff;\r
3170         *pos++ = ( salt >> 16 ) & 0xff;\r
3171         *pos++ = ( salt >>  8 ) & 0xff;\r
3172         *pos++ = ( salt       ) & 0xff;\r
3173         \r
3174         SecretKeyLength = strlen( SecretKey ) + 5;\r
3175 }\r
3176 \r
3177 /*----------- 乱数生成をする -------------------------------------------------\r
3178 *\r
3179 *       Parameter\r
3180 *\r
3181 *       Return Value\r
3182 *               ランダムな値:コンパイラVS2005/動作環境WinXP以上では rand_s から取得する\r
3183 *----------------------------------------------------------------------------*/\r
3184 DWORD GetRandamDWRODValue(void)\r
3185 {\r
3186         DWORD rndValue;\r
3187         int errorCode;\r
3188 #ifdef _CRT_RAND_S\r
3189         errno_t errnoRand_s;\r
3190         errnoRand_s = rand_s(&rndValue);\r
3191         errorCode = (0 != errnoRand_s ? 1 : 0);\r
3192 #else\r
3193         errorCode = 1;\r
3194 #endif\r
3195         if(0 != errorCode){\r
3196 #ifdef USE_RANDAM_C_RAND\r
3197                 rndValue = rand() | (rand() << 16);\r
3198 #else\r
3199                 /* rand() のかわりに、SHA-1とパフォーマンスカウンタを用いる */\r
3200                 ulong shaValue[5];\r
3201                 LARGE_INTEGER Counter;\r
3202                 \r
3203                 if(0 == IsRndSourceInit){\r
3204                         /* 初回取得時 */\r
3205                         HANDLE CurProcHandle;\r
3206                         HANDLE CurThreadHandle;\r
3207                         \r
3208                         if(DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),\r
3209                                 &CurProcHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))\r
3210                         {\r
3211                                 CloseHandle(CurProcHandle);\r
3212                         }\r
3213                         if(DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(),\r
3214                                 &CurThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))\r
3215                         {\r
3216                                 CloseHandle(CurThreadHandle);\r
3217                         }\r
3218                         \r
3219                         /* _WIN64 では64bitだが、その場合はrand_sが大抵利用可能なのでここでは32bitのみ用いる */\r
3220                         RndSource[0] = (ulong)CurProcHandle;\r
3221                         RndSource[1] = (ulong)CurThreadHandle;\r
3222                         RndSource[2] = (ulong)GetTickCount();\r
3223                         RndSource[3] = (ulong)timeGetTime();\r
3224                         RndSource[4] = 0; /* カウントアップ */\r
3225                         RndSource[5] = RndSource[3] + 1;\r
3226                         IsRndSourceInit = 1;\r
3227                 }\r
3228                 RndSource[4]++;\r
3229                 RndSource[5] += 0x00010010;\r
3230                 if(QueryPerformanceCounter(&Counter)){\r
3231                         RndSource[6] = Counter.LowPart;\r
3232                         RndSource[7] = Counter.HighPart;\r
3233                         RndSource[8] = (ulong)rand();\r
3234                 }else{\r
3235                         RndSource[6] = (ulong)timeGetTime();\r
3236                         RndSource[7] = (ulong)rand();\r
3237                         RndSource[8] = (ulong)rand();\r
3238                 }\r
3239                 \r
3240                 sha_memory((char *)RndSource, sizeof(RndSource), shaValue);\r
3241                 rndValue = shaValue[0] ^ shaValue[1] ^ shaValue[2] ^ shaValue[3] ^ shaValue[4];\r
3242 #endif\r
3243         }\r
3244         return rndValue;\r
3245 }\r
3246 \r
3247 // 全設定暗号化対応\r
3248 // 内部状態推定対策としてハッシュの160ビットのうち80ビットのみを鍵として使用\r
3249 void MaskSettingsData(const char* Salt, int SaltLength, void* Data, DWORD Size, int EscapeZero)\r
3250 {\r
3251         char Key[FMAX_PATH*2+1];\r
3252         BYTE* p;\r
3253         DWORD i;\r
3254         DWORD j;\r
3255         ulong Hash[5];\r
3256         BYTE Mask[10];\r
3257         memcpy(&Key[0], SecretKey, SecretKeyLength);\r
3258         memcpy(&Key[SecretKeyLength], Salt, SaltLength);\r
3259         p = (BYTE*)Data;\r
3260         for(i = 0; i < Size; i++)\r
3261         {\r
3262                 if(i % 10 == 0)\r
3263                 {\r
3264                         memcpy(&Key[SecretKeyLength + SaltLength], &i, 4);\r
3265                         sha_memory(Key, SecretKeyLength + SaltLength + 4, Hash);\r
3266                         // sha.cはビッグエンディアンのため\r
3267                         for(j = 0; j < 5; j++)\r
3268                                 Hash[j] = _byteswap_ulong(Hash[j]);\r
3269                         memcpy(&Mask, &Hash, 10);\r
3270                 }\r
3271                 if(EscapeZero == NO || (p[i] != 0 && p[i] != Mask[i % 10]))\r
3272                         p[i] ^= Mask[i % 10];\r
3273         }\r
3274 }\r
3275 \r
3276 void UnmaskSettingsData(const char* Salt, int SaltLength, void* Data, DWORD Size, int EscapeZero)\r
3277 {\r
3278         MaskSettingsData(Salt, SaltLength, Data, Size, EscapeZero);\r
3279 }\r
3280 \r
3281 void CalculateSettingsDataChecksum(void* Data, DWORD Size)\r
3282 {\r
3283         ulong Hash[5];\r
3284         DWORD i;\r
3285         BYTE Mask[20];\r
3286         sha_memory((char*)Data, Size, Hash);\r
3287         // sha.cはビッグエンディアンのため\r
3288         for(i = 0; i < 5; i++)\r
3289                 Hash[i] = _byteswap_ulong(Hash[i]);\r
3290         memcpy(&Mask, &Hash, 20);\r
3291         for(i = 0; i < 20; i++)\r
3292                 EncryptSettingsChecksum[i] ^= Mask[i];\r
3293 }\r
3294 \r
3295 // ポータブル版判定\r
3296 int IsRegAvailable()\r
3297 {\r
3298         int Sts;\r
3299         void* h;\r
3300         Sts = NO;\r
3301         SetRegType(REGTYPE_REG);\r
3302         if(OpenReg("FFFTP", &h) == FFFTP_SUCCESS)\r
3303         {\r
3304                 CloseReg(h);\r
3305                 Sts = YES;\r
3306         }\r
3307         return Sts;\r
3308 }\r
3309 \r
3310 int IsIniAvailable()\r
3311 {\r
3312         int Sts;\r
3313         void* h;\r
3314         Sts = NO;\r
3315         SetRegType(REGTYPE_INI);\r
3316         if(OpenReg("FFFTP", &h) == FFFTP_SUCCESS)\r
3317         {\r
3318                 CloseReg(h);\r
3319                 Sts = YES;\r
3320         }\r
3321         return Sts;\r
3322 }\r
3323 \r
3324 // バージョン確認\r
3325 int ReadSettingsVersion()\r
3326 {\r
3327         void *hKey3;\r
3328         int i;\r
3329         int Version;\r
3330 \r
3331         SetRegType(REGTYPE_INI);\r
3332         if((i = OpenReg("FFFTP", &hKey3)) != FFFTP_SUCCESS)\r
3333         {\r
3334                 if(AskForceIni() == NO)\r
3335                 {\r
3336                         SetRegType(REGTYPE_REG);\r
3337                         i = OpenReg("FFFTP", &hKey3);\r
3338                 }\r
3339         }\r
3340         Version = INT_MAX;\r
3341         if(i == FFFTP_SUCCESS)\r
3342         {\r
3343                 ReadIntValueFromReg(hKey3, "Version", &Version);\r
3344                 CloseReg(hKey3);\r
3345         }\r
3346         return Version;\r
3347 }\r
3348 \r