OSDN Git Service

bdab8a2075997e059ff52d93c6a7ab9add8e5ca8
[ffftp/ffftp.git] / registory.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 #include <windows.h>\r
37 #include <stdio.h>\r
38 #include <stdlib.h>\r
39 #include <time.h>\r
40 #include <string.h>\r
41 #include <windowsx.h>\r
42 #include <process.h>\r
43 \r
44 \r
45 #include "common.h"\r
46 #include "resource.h"\r
47 #include "sample.h"\r
48 #include "sha.h"\r
49 #include "aes.h"\r
50 \r
51 \r
52 /*===== プロトタイプ =====*/\r
53 \r
54 static void SaveStr(HKEY hKey, char *Key, char *Str, char *DefaultStr);\r
55 static void SaveIntNum(HKEY hKey, char *Key, int Num, int DefaultNum);\r
56 static void MakeFontData(LOGFONT Font, HFONT hFont, char *Buf);\r
57 static int RestoreFontData(char *Str, LOGFONT *Font);\r
58 \r
59 static void EncodePassword(char *Str, char *Buf);\r
60 static void EncodePasswordOriginal(char *Str, char *Buf);\r
61 static void EncodePassword2(char *Str, char *Buf, const char *Key);\r
62 static void EncodePassword3(char *Str, char *Buf, const char *Key);\r
63 \r
64 static void DecodePassword(char *Str, char *Buf);\r
65 static void DecodePasswordOriginal(char *Str, char *Buf);\r
66 static void DecodePassword2(char *Str, char *Buf, const char *Key);\r
67 static void DecodePassword3(char *Str, char *Buf, const char *Key);\r
68 static int CreateAesKey(unsigned char *AesKey, const char* Key);\r
69 \r
70 static void SetRegType(int Type);\r
71 static int OpenReg(char *Name, void **Handle);\r
72 static int CreateReg(char *Name, void **Handle);\r
73 static int CloseReg(void *Handle);\r
74 static int OpenSubKey(void *Parent, char *Name, void **Handle);\r
75 static int CreateSubKey(void *Parent, char *Name, void **Handle);\r
76 static int CloseSubKey(void *Handle);\r
77 static int DeleteSubKey(void *Handle, char *Name);\r
78 static int DeleteValue(void *Handle, char *Name);\r
79 static int ReadIntValueFromReg(void *Handle, char *Name, int *Value);\r
80 static int WriteIntValueToReg(void *Handle, char *Name, int Value);\r
81 static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size);\r
82 static int WriteStringToReg(void *Handle, char *Name, char *Str);\r
83 static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Size);\r
84 static int WriteMultiStringToReg(void *Handle, char *Name, char *Str);\r
85 static int ReadBinaryFromReg(void *Handle, char *Name, void *Bin, DWORD Size);\r
86 static int WriteBinaryToReg(void *Handle, char *Name, void *Bin, int Len);\r
87 \r
88 int CheckPasswordValidity( char* Password, int length, const char* HashStr );\r
89 void CreatePasswordHash( char* Password, int length, char* HashStr );\r
90 void SetHashSalt( DWORD salt );\r
91 \r
92 DWORD GetRandamDWRODValue(void);\r
93 \r
94 /* 2010.01.30 genta 追加 */\r
95 static char SecretKey[FMAX_PATH+1];\r
96 static int SecretKeyLength;\r
97 static int IsMasterPasswordError = PASSWORD_OK;\r
98 \r
99 static int IsRndSourceInit = 0;\r
100 static ulong RndSource[9];\r
101 \r
102 /*===== 外部参照 =====*/\r
103 \r
104 /* 設定値 */\r
105 extern int WinPosX;\r
106 extern int WinPosY;\r
107 extern int WinWidth;\r
108 extern int WinHeight;\r
109 extern int LocalWidth;\r
110 extern int TaskHeight;\r
111 extern int LocalTabWidth[4];\r
112 extern int RemoteTabWidth[6];\r
113 extern char UserMailAdrs[USER_MAIL_LEN+1];\r
114 extern char ViewerName[VIEWERS][FMAX_PATH+1];\r
115 extern HFONT ListFont;\r
116 extern LOGFONT ListLogFont;\r
117 extern int LocalFileSort;\r
118 extern int LocalDirSort;\r
119 extern int RemoteFileSort;\r
120 extern int RemoteDirSort;\r
121 extern int TransMode;\r
122 extern int ConnectOnStart;\r
123 extern int DebugConsole;\r
124 extern int SaveWinPos;\r
125 extern char AsciiExt[ASCII_EXT_LEN+1];\r
126 extern int RecvMode;\r
127 extern int SendMode;\r
128 extern int MoveMode;\r
129 extern int ListType;\r
130 extern int CacheEntry;\r
131 extern int CacheSave;\r
132 extern char DefaultLocalPath[FMAX_PATH+1];\r
133 extern int SaveTimeStamp;\r
134 extern int FindMode;\r
135 extern int DotFile;\r
136 extern int DclickOpen;\r
137 extern SOUNDFILE Sound[SOUND_TYPES];\r
138 extern int FnameCnv;\r
139 extern int ConnectAndSet;\r
140 extern int TimeOut;\r
141 extern int RmEOF;\r
142 extern int RegType;\r
143 extern char FwallHost[HOST_ADRS_LEN+1];\r
144 extern char FwallUser[USER_NAME_LEN+1];\r
145 extern char FwallPass[PASSWORD_LEN+1];\r
146 extern int FwallPort;\r
147 extern int FwallType;\r
148 extern int FwallDefault;\r
149 extern int FwallSecurity;\r
150 extern int FwallResolv;\r
151 extern int FwallLower;\r
152 extern int FwallDelimiter;\r
153 extern int PasvDefault;\r
154 extern char MirrorNoTrn[MIRROR_LEN+1];\r
155 extern char MirrorNoDel[MIRROR_LEN+1];\r
156 extern int MirrorFnameCnv;\r
157 //extern int MirrorFolderCnv;\r
158 extern int RasClose;\r
159 extern int RasCloseNotify;\r
160 extern int FileHist;\r
161 extern char DefAttrList[DEFATTRLIST_LEN+1];\r
162 extern SIZE HostDlgSize;\r
163 extern SIZE BmarkDlgSize;\r
164 extern SIZE MirrorDlgSize;\r
165 extern int Sizing;\r
166 extern int SortSave;\r
167 extern char TmpPath[FMAX_PATH+1];\r
168 extern int QuickAnonymous;\r
169 extern int PassToHist;\r
170 extern int VaxSemicolon;\r
171 extern int SendQuit;\r
172 extern int NoRasControl;\r
173 extern int SuppressSave;\r
174 \r
175 extern int UpExistMode;\r
176 extern int ExistMode;\r
177 extern int DispIgnoreHide;\r
178 extern int DispDrives;\r
179 extern int MirUpDelNotify;\r
180 extern int MirDownDelNotify;\r
181 \r
182 extern int FolderAttr;\r
183 extern int FolderAttrNum;\r
184 \r
185 /*----- マスタパスワードの設定 ----------------------------------------------\r
186 *\r
187 *       Parameter\r
188 *               const char* Password : マスターパスワード\r
189 *\r
190 *       Return Value\r
191 *               なし\r
192 *----------------------------------------------------------------------------*/\r
193 void SetMasterPassword( const char* Password )\r
194 {\r
195         ZeroMemory( SecretKey, MAX_PASSWORD_LEN + 12 );\r
196         if( Password != NULL ){\r
197                 strncpy( SecretKey, Password, MAX_PASSWORD_LEN );\r
198         }\r
199         else {\r
200                 strcpy( SecretKey, DEFAULT_PASSWORD );\r
201         }\r
202         SecretKeyLength = strlen( SecretKey );\r
203         \r
204         /* 未検証なので,初期状態はOKにする (強制再設定→保存にを可能にする)*/\r
205         IsMasterPasswordError = PASSWORD_OK;\r
206 }\r
207 \r
208 /*----- マスタパスワードの状態取得 ----------------------------------------------\r
209 *\r
210 *       Parameter\r
211 *               なし\r
212 *\r
213 *       Return Value\r
214 *               PASSWORD_OK : OK\r
215 *               PASSWORD_UNMATCH : パスワード不一致\r
216 *               BAD_PASSWORD_HASH : パスワード確認失敗\r
217 *----------------------------------------------------------------------------*/\r
218 int GetMasterPasswordStatus(void)\r
219 {\r
220         return IsMasterPasswordError;\r
221 }\r
222 \r
223 /*----- レジストリ/INIファイルのマスターパスワードの検証を行う ------------\r
224 *\r
225 *       Parameter\r
226 *               なし\r
227 *\r
228 *       Return Value\r
229 *               \r
230 *----------------------------------------------------------------------------*/\r
231 \r
232 int ValidateMasterPassword(void)\r
233 {\r
234         void *hKey3;\r
235         int i;\r
236 \r
237         SetRegType(REGTYPE_INI);\r
238         if((i = OpenReg("FFFTP", &hKey3)) != FFFTP_SUCCESS)\r
239         {\r
240                 if(AskForceIni() == NO)\r
241                 {\r
242                         SetRegType(REGTYPE_REG);\r
243                         i = OpenReg("FFFTP", &hKey3);\r
244                 }\r
245         }\r
246         if(i == FFFTP_SUCCESS){\r
247                 char checkbuf[48];\r
248                 int salt = 0;\r
249 \r
250                 if( ReadIntValueFromReg(hKey3, "CredentialSalt", &salt)){\r
251                         SetHashSalt( salt );\r
252                 }\r
253                 if( ReadStringFromReg(hKey3, "CredentialCheck", checkbuf, sizeof( checkbuf )) == FFFTP_SUCCESS ){\r
254                         switch( CheckPasswordValidity( SecretKey, SecretKeyLength, checkbuf ) ){\r
255                         case 0: /* not match */\r
256                                 IsMasterPasswordError = PASSWORD_UNMATCH;\r
257                                 break;\r
258                         case 1: /* match */\r
259                                 IsMasterPasswordError = PASSWORD_OK;\r
260                                 break;\r
261                         case 2: /* invalid hash */\r
262                         default:\r
263                                 IsMasterPasswordError = BAD_PASSWORD_HASH;\r
264                                 break;\r
265                         }\r
266                 }\r
267                 CloseReg(hKey3);\r
268                 return YES;\r
269         }\r
270         return NO;\r
271 }\r
272 \r
273 /*----- レジストリ/INIファイルに設定値を保存 ---------------------------------\r
274 *\r
275 *       Parameter\r
276 *               なし\r
277 *\r
278 *       Return Value\r
279 *               なし\r
280 *----------------------------------------------------------------------------*/\r
281 \r
282 void SaveRegistory(void)\r
283 {\r
284         void *hKey3;\r
285         void *hKey4;\r
286         void *hKey5;\r
287         char Str[FMAX_PATH+1];\r
288         int i;\r
289         int n;\r
290         HOSTDATA DefaultHost;\r
291         HOSTDATA Host;\r
292         HISTORYDATA Hist;\r
293         HISTORYDATA DefaultHist;\r
294         \r
295         if( GetMasterPasswordStatus() == PASSWORD_UNMATCH ){\r
296                 /* 2010.01.30 genta: マスターパスワードが不一致の場合は不用意に上書きしない */\r
297                 return;\r
298         }\r
299 \r
300         SetRegType(RegType);\r
301         if(CreateReg("FFFTP", &hKey3) == FFFTP_SUCCESS)\r
302         {\r
303                 char buf[48];\r
304                 int salt = GetTickCount();\r
305         \r
306                 WriteIntValueToReg(hKey3, "Version", VER_NUM);\r
307                 WriteIntValueToReg(hKey3, "CredentialSalt", salt);\r
308                 \r
309                 SetHashSalt( salt );\r
310                 /* save password hash */\r
311                 CreatePasswordHash( SecretKey, SecretKeyLength, buf );\r
312                 WriteStringToReg(hKey3, "CredentialCheck", buf);\r
313 \r
314                 if(CreateSubKey(hKey3, "Options", &hKey4) == FFFTP_SUCCESS)\r
315                 {\r
316                         WriteIntValueToReg(hKey4, "NoSave", SuppressSave);\r
317 \r
318                         if(SuppressSave != YES)\r
319                         {\r
320                                 WriteIntValueToReg(hKey4, "WinPosX", WinPosX);\r
321                                 WriteIntValueToReg(hKey4, "WinPosY", WinPosY);\r
322                                 WriteIntValueToReg(hKey4, "WinWidth", WinWidth);\r
323                                 WriteIntValueToReg(hKey4, "WinHeight", WinHeight);\r
324                                 WriteIntValueToReg(hKey4, "LocalWidth", LocalWidth);\r
325                                 WriteIntValueToReg(hKey4, "TaskHeight", TaskHeight);\r
326                                 WriteBinaryToReg(hKey4, "LocalColm", LocalTabWidth, sizeof(LocalTabWidth));\r
327                                 WriteBinaryToReg(hKey4, "RemoteColm", RemoteTabWidth, sizeof(RemoteTabWidth));\r
328                                 WriteIntValueToReg(hKey4, "SwCmd", Sizing);\r
329 \r
330                                 WriteStringToReg(hKey4, "UserMail", UserMailAdrs);\r
331                                 WriteStringToReg(hKey4, "Viewer", ViewerName[0]);\r
332                                 WriteStringToReg(hKey4, "Viewer2", ViewerName[1]);\r
333                                 WriteStringToReg(hKey4, "Viewer3", ViewerName[2]);\r
334 \r
335                                 WriteIntValueToReg(hKey4, "TrType", TransMode);\r
336                                 WriteIntValueToReg(hKey4, "Recv", RecvMode);\r
337                                 WriteIntValueToReg(hKey4, "Send", SendMode);\r
338                                 WriteIntValueToReg(hKey4, "Move", MoveMode);\r
339                                 WriteStringToReg(hKey4, "Path", DefaultLocalPath);\r
340                                 WriteIntValueToReg(hKey4, "Time", SaveTimeStamp);\r
341                                 WriteIntValueToReg(hKey4, "EOF", RmEOF);\r
342                                 WriteIntValueToReg(hKey4, "Scolon", VaxSemicolon);\r
343 \r
344                                 WriteIntValueToReg(hKey4, "RecvEx", ExistMode);\r
345                                 WriteIntValueToReg(hKey4, "SendEx", UpExistMode);\r
346 \r
347                                 WriteIntValueToReg(hKey4, "LFsort", LocalFileSort);\r
348                                 WriteIntValueToReg(hKey4, "LDsort", LocalDirSort);\r
349                                 WriteIntValueToReg(hKey4, "RFsort", RemoteFileSort);\r
350                                 WriteIntValueToReg(hKey4, "RDsort", RemoteDirSort);\r
351                                 WriteIntValueToReg(hKey4, "SortSave", SortSave);\r
352 \r
353                                 WriteIntValueToReg(hKey4, "ListType", ListType);\r
354                                 WriteIntValueToReg(hKey4, "Cache", CacheEntry);\r
355                                 WriteIntValueToReg(hKey4, "CacheSave", CacheSave);\r
356                                 WriteIntValueToReg(hKey4, "DotFile", DotFile);\r
357                                 WriteIntValueToReg(hKey4, "Dclick", DclickOpen);\r
358 \r
359                                 WriteIntValueToReg(hKey4, "ConS", ConnectOnStart);\r
360                                 WriteIntValueToReg(hKey4, "OldDlg", ConnectAndSet);\r
361                                 WriteIntValueToReg(hKey4, "RasClose", RasClose);\r
362                                 WriteIntValueToReg(hKey4, "RasNotify", RasCloseNotify);\r
363                                 WriteIntValueToReg(hKey4, "Qanony", QuickAnonymous);\r
364                                 WriteIntValueToReg(hKey4, "PassHist", PassToHist);\r
365                                 WriteIntValueToReg(hKey4, "SendQuit", SendQuit);\r
366                                 WriteIntValueToReg(hKey4, "NoRas", NoRasControl);\r
367 \r
368                                 WriteIntValueToReg(hKey4, "Debug", DebugConsole);\r
369                                 WriteIntValueToReg(hKey4, "WinPos", SaveWinPos);\r
370                                 WriteIntValueToReg(hKey4, "RegExp", FindMode);\r
371                                 WriteIntValueToReg(hKey4, "Reg", RegType);\r
372 \r
373                                 WriteMultiStringToReg(hKey4, "AsciiFile", AsciiExt);\r
374                                 WriteIntValueToReg(hKey4, "LowUp", FnameCnv);\r
375                                 WriteIntValueToReg(hKey4, "Tout", TimeOut);\r
376 \r
377                                 WriteMultiStringToReg(hKey4, "NoTrn", MirrorNoTrn);\r
378                                 WriteMultiStringToReg(hKey4, "NoDel", MirrorNoDel);\r
379                                 WriteIntValueToReg(hKey4, "MirFile", MirrorFnameCnv);\r
380                                 WriteIntValueToReg(hKey4, "MirUNot", MirUpDelNotify);\r
381                                 WriteIntValueToReg(hKey4, "MirDNot", MirDownDelNotify);\r
382 \r
383                                 MakeFontData(ListLogFont, ListFont, Str);\r
384                                 WriteStringToReg(hKey4, "ListFont", Str);\r
385                                 WriteIntValueToReg(hKey4, "ListHide", DispIgnoreHide);\r
386                                 WriteIntValueToReg(hKey4, "ListDrv", DispDrives);\r
387 \r
388                                 WriteStringToReg(hKey4, "FwallHost", FwallHost);\r
389                                 WriteStringToReg(hKey4, "FwallUser", FwallUser);\r
390                                 EncodePassword(FwallPass, Str);\r
391                                 WriteStringToReg(hKey4, "FwallPass", Str);\r
392                                 WriteIntValueToReg(hKey4, "FwallPort", FwallPort);\r
393                                 WriteIntValueToReg(hKey4, "FwallType", FwallType);\r
394                                 WriteIntValueToReg(hKey4, "FwallDef", FwallDefault);\r
395                                 WriteIntValueToReg(hKey4, "FwallSec", FwallSecurity);\r
396                                 WriteIntValueToReg(hKey4, "PasvDef", PasvDefault);\r
397                                 WriteIntValueToReg(hKey4, "FwallRes", FwallResolv);\r
398                                 WriteIntValueToReg(hKey4, "FwallLow", FwallLower);\r
399                                 WriteIntValueToReg(hKey4, "FwallDel", FwallDelimiter);\r
400 \r
401                                 WriteIntValueToReg(hKey4, "SndConSw", Sound[SND_CONNECT].On);\r
402                                 WriteIntValueToReg(hKey4, "SndTrnSw", Sound[SND_TRANS].On);\r
403                                 WriteIntValueToReg(hKey4, "SndErrSw", Sound[SND_ERROR].On);\r
404                                 WriteStringToReg(hKey4, "SndCon", Sound[SND_CONNECT].Fname);\r
405                                 WriteStringToReg(hKey4, "SndTrn", Sound[SND_TRANS].Fname);\r
406                                 WriteStringToReg(hKey4, "SndErr", Sound[SND_ERROR].Fname);\r
407 \r
408                                 WriteMultiStringToReg(hKey4, "DefAttr", DefAttrList);\r
409 \r
410                                 GetTempPath(FMAX_PATH, Str);\r
411                                 SaveStr(hKey4, "Tmp", TmpPath, Str);\r
412 \r
413                                 WriteBinaryToReg(hKey4, "Hdlg", &HostDlgSize, sizeof(SIZE));\r
414                                 WriteBinaryToReg(hKey4, "Bdlg", &BmarkDlgSize, sizeof(SIZE));\r
415                                 WriteBinaryToReg(hKey4, "Mdlg", &MirrorDlgSize, sizeof(SIZE));\r
416 \r
417                                 WriteIntValueToReg(hKey4, "FAttrSw", FolderAttr);\r
418                                 WriteIntValueToReg(hKey4, "FAttr", FolderAttrNum);\r
419 \r
420                                 WriteIntValueToReg(hKey4, "HistNum", FileHist);\r
421 \r
422                                 /* Ver1.54a以前の形式のヒストリデータは削除 */\r
423                                 DeleteValue(hKey4, "Hist");\r
424 \r
425                                 /* ヒストリの設定を保存 */\r
426                                 CopyDefaultHistory(&DefaultHist);\r
427                                 n = 0;\r
428                                 for(i = AskHistoryNum(); i > 0; i--)\r
429                                 {\r
430                                         if(GetHistoryByNum(i-1, &Hist) == FFFTP_SUCCESS)\r
431                                         {\r
432                                                 sprintf(Str, "History%d", n);\r
433                                                 if(CreateSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
434                                                 {\r
435                                                         SaveStr(hKey5, "HostAdrs", Hist.HostAdrs, DefaultHist.HostAdrs);\r
436                                                         SaveStr(hKey5, "UserName", Hist.UserName, DefaultHist.UserName);\r
437                                                         SaveStr(hKey5, "Account", Hist.Account, DefaultHist.Account);\r
438                                                         SaveStr(hKey5, "LocalDir", Hist.LocalInitDir, NULL);\r
439                                                         SaveStr(hKey5, "RemoteDir", Hist.RemoteInitDir, DefaultHist.RemoteInitDir);\r
440                                                         SaveStr(hKey5, "Chmod", Hist.ChmodCmd, DefaultHist.ChmodCmd);\r
441                                                         SaveStr(hKey5, "Nlst", Hist.LsName, DefaultHist.LsName);\r
442                                                         SaveStr(hKey5, "Init", Hist.InitCmd, DefaultHist.InitCmd);\r
443                                                         EncodePassword(Hist.PassWord, Str);\r
444                                                         SaveStr(hKey5, "Password", Str, DefaultHist.PassWord);\r
445                                                         SaveIntNum(hKey5, "Port", Hist.Port, DefaultHist.Port);\r
446                                                         SaveIntNum(hKey5, "Kanji", Hist.KanjiCode, DefaultHist.KanjiCode);\r
447                                                         SaveIntNum(hKey5, "KanaCnv", Hist.KanaCnv, DefaultHist.KanaCnv);\r
448                                                         SaveIntNum(hKey5, "NameKanji", Hist.NameKanjiCode, DefaultHist.NameKanjiCode);\r
449                                                         SaveIntNum(hKey5, "NameKana", Hist.NameKanaCnv, DefaultHist.NameKanaCnv);\r
450                                                         SaveIntNum(hKey5, "Pasv", Hist.Pasv, DefaultHist.Pasv);\r
451                                                         SaveIntNum(hKey5, "Fwall", Hist.FireWall, DefaultHist.FireWall);\r
452                                                         SaveIntNum(hKey5, "List", Hist.ListCmdOnly, DefaultHist.ListCmdOnly);\r
453                                                         SaveIntNum(hKey5, "NLST-R", Hist.UseNLST_R, DefaultHist.UseNLST_R);\r
454                                                         SaveIntNum(hKey5, "Tzone", Hist.TimeZone, DefaultHist.TimeZone);\r
455                                                         SaveIntNum(hKey5, "Type", Hist.HostType, DefaultHist.HostType);\r
456                                                         SaveIntNum(hKey5, "Sync", Hist.SyncMove, DefaultHist.SyncMove);\r
457                                                         SaveIntNum(hKey5, "Fpath", Hist.NoFullPath, DefaultHist.NoFullPath);\r
458                                                         WriteBinaryToReg(hKey5, "Sort", &Hist.Sort, sizeof(Hist.Sort));\r
459                                                         SaveIntNum(hKey5, "Secu", Hist.Security, DefaultHist.Security);\r
460                                                         WriteIntValueToReg(hKey5, "TrType", Hist.Type);\r
461                                                         SaveIntNum(hKey5, "Dial", Hist.Dialup, DefaultHist.Dialup);\r
462                                                         SaveIntNum(hKey5, "UseIt", Hist.DialupAlways, DefaultHist.DialupAlways);\r
463                                                         SaveIntNum(hKey5, "Notify", Hist.DialupNotify, DefaultHist.DialupNotify);\r
464                                                         SaveStr(hKey5, "DialTo", Hist.DialEntry, DefaultHist.DialEntry);\r
465                                                         // 暗号化通信対応\r
466                                                         SaveIntNum(hKey5, "FTPES", Hist.UseFTPES, DefaultHist.UseFTPES);\r
467                                                         SaveIntNum(hKey5, "FTPIS", Hist.UseFTPIS, DefaultHist.UseFTPIS);\r
468                                                         SaveIntNum(hKey5, "SFTP", Hist.UseSFTP, DefaultHist.UseSFTP);\r
469                                                         // 同時接続対応\r
470                                                         SaveIntNum(hKey5, "ThreadCount", Hist.MaxThreadCount, DefaultHist.MaxThreadCount);\r
471                                                         // MLSD対応\r
472                                                         SaveIntNum(hKey5, "MLSD", Hist.UseMLSD, DefaultHist.UseMLSD);\r
473                                                         // IPv6対応\r
474                                                         SaveIntNum(hKey5, "IPv6", Hist.UseIPv6, DefaultHist.UseIPv6);\r
475 \r
476                                                         CloseSubKey(hKey5);\r
477                                                         n++;\r
478                                                 }\r
479                                         }\r
480                                 }\r
481                                 WriteIntValueToReg(hKey4, "SavedHist", n);\r
482 \r
483                                 /* 余分なヒストリがあったら削除 */\r
484                                 for(; n < 999; n++)\r
485                                 {\r
486                                         sprintf(Str, "History%d", n);\r
487                                         if(DeleteSubKey(hKey4, Str) != FFFTP_SUCCESS)\r
488                                                 break;\r
489                                 }\r
490 \r
491                                 /* ホストの設定を保存 */\r
492                                 CopyDefaultHost(&DefaultHost);\r
493                                 i = 0;\r
494                                 while(CopyHostFromList(i, &Host) == FFFTP_SUCCESS)\r
495                                 {\r
496                                         sprintf(Str, "Host%d", i);\r
497                                         if(CreateSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
498                                         {\r
499 //                                              SaveIntNum(hKey5, "Set", Host.Level, DefaultHost.Level);\r
500                                                 WriteIntValueToReg(hKey5, "Set", Host.Level);\r
501                                                 SaveStr(hKey5, "HostName", Host.HostName, DefaultHost.HostName);\r
502                                                 if((Host.Level & SET_LEVEL_GROUP) == 0)\r
503                                                 {\r
504                                                         SaveStr(hKey5, "HostAdrs", Host.HostAdrs, DefaultHost.HostAdrs);\r
505                                                         SaveStr(hKey5, "UserName", Host.UserName, DefaultHost.UserName);\r
506                                                         SaveStr(hKey5, "Account", Host.Account, DefaultHost.Account);\r
507                                                         SaveStr(hKey5, "LocalDir", Host.LocalInitDir, NULL);\r
508                                                         SaveStr(hKey5, "RemoteDir", Host.RemoteInitDir, DefaultHost.RemoteInitDir);\r
509                                                         SaveStr(hKey5, "Chmod", Host.ChmodCmd, DefaultHost.ChmodCmd);\r
510                                                         SaveStr(hKey5, "Nlst", Host.LsName, DefaultHost.LsName);\r
511                                                         SaveStr(hKey5, "Init", Host.InitCmd, DefaultHost.InitCmd);\r
512 \r
513                                                         if(Host.Anonymous == NO)\r
514                                                                 EncodePassword(Host.PassWord, Str);\r
515                                                         else\r
516                                                                 strcpy(Str, DefaultHost.PassWord);\r
517                                                         SaveStr(hKey5, "Password", Str, DefaultHost.PassWord);\r
518 \r
519                                                         SaveIntNum(hKey5, "Port", Host.Port, DefaultHost.Port);\r
520                                                         SaveIntNum(hKey5, "Anonymous", Host.Anonymous, DefaultHost.Anonymous);\r
521                                                         SaveIntNum(hKey5, "Kanji", Host.KanjiCode, DefaultHost.KanjiCode);\r
522                                                         SaveIntNum(hKey5, "KanaCnv", Host.KanaCnv, DefaultHost.KanaCnv);\r
523                                                         SaveIntNum(hKey5, "NameKanji", Host.NameKanjiCode, DefaultHost.NameKanjiCode);\r
524                                                         SaveIntNum(hKey5, "NameKana", Host.NameKanaCnv, DefaultHost.NameKanaCnv);\r
525                                                         SaveIntNum(hKey5, "Pasv", Host.Pasv, DefaultHost.Pasv);\r
526                                                         SaveIntNum(hKey5, "Fwall", Host.FireWall, DefaultHost.FireWall);\r
527                                                         SaveIntNum(hKey5, "List", Host.ListCmdOnly, DefaultHost.ListCmdOnly);\r
528                                                         SaveIntNum(hKey5, "NLST-R", Host.UseNLST_R, DefaultHost.UseNLST_R);\r
529                                                         SaveIntNum(hKey5, "Last", Host.LastDir, DefaultHost.LastDir);\r
530                                                         SaveIntNum(hKey5, "Tzone", Host.TimeZone, DefaultHost.TimeZone);\r
531                                                         SaveIntNum(hKey5, "Type", Host.HostType, DefaultHost.HostType);\r
532                                                         SaveIntNum(hKey5, "Sync", Host.SyncMove, DefaultHost.SyncMove);\r
533                                                         SaveIntNum(hKey5, "Fpath", Host.NoFullPath, DefaultHost.NoFullPath);\r
534                                                         WriteBinaryToReg(hKey5, "Sort", &Host.Sort, sizeof(Host.Sort));\r
535                                                         SaveIntNum(hKey5, "Secu", Host.Security, DefaultHost.Security);\r
536 \r
537                                                         WriteMultiStringToReg(hKey5, "Bmarks", Host.BookMark);\r
538 \r
539                                                         SaveIntNum(hKey5, "Dial", Host.Dialup, DefaultHost.Dialup);\r
540                                                         SaveIntNum(hKey5, "UseIt", Host.DialupAlways, DefaultHost.DialupAlways);\r
541                                                         SaveIntNum(hKey5, "Notify", Host.DialupNotify, DefaultHost.DialupNotify);\r
542                                                         SaveStr(hKey5, "DialTo", Host.DialEntry, DefaultHost.DialEntry);\r
543                                                         // 暗号化通信対応\r
544                                                         SaveIntNum(hKey5, "FTPES", Host.UseFTPES, DefaultHost.UseFTPES);\r
545                                                         SaveIntNum(hKey5, "FTPIS", Host.UseFTPIS, DefaultHost.UseFTPIS);\r
546                                                         SaveIntNum(hKey5, "SFTP", Host.UseSFTP, DefaultHost.UseSFTP);\r
547                                                         // 同時接続対応\r
548                                                         SaveIntNum(hKey5, "ThreadCount", Host.MaxThreadCount, DefaultHost.MaxThreadCount);\r
549                                                         // MLSD対応\r
550                                                         SaveIntNum(hKey5, "MLSD", Host.UseMLSD, DefaultHost.UseMLSD);\r
551                                                         // IPv6対応\r
552                                                         SaveIntNum(hKey5, "IPv6", Host.UseIPv6, DefaultHost.UseIPv6);\r
553                                                 }\r
554                                                 CloseSubKey(hKey5);\r
555                                         }\r
556                                         i++;\r
557                                 }\r
558                                 WriteIntValueToReg(hKey4, "SetNum", i);\r
559 \r
560                                 /* 余分なホストの設定があったら削除 */\r
561                                 for(; i < 998; i++)\r
562                                 {\r
563                                         sprintf(Str, "Host%d", i);\r
564                                         if(DeleteSubKey(hKey4, Str) != FFFTP_SUCCESS)\r
565                                                 break;\r
566                                 }\r
567 \r
568                                 if((i = AskCurrentHost()) == HOSTNUM_NOENTRY)\r
569                                         i = 0;\r
570                                 WriteIntValueToReg(hKey4, "CurSet", i);\r
571                         }\r
572                         CloseSubKey(hKey4);\r
573                 }\r
574                 CloseReg(hKey3);\r
575         }\r
576         return;\r
577 }\r
578 \r
579 /*----- レジストリ/INIファイルから設定値を呼び出す ---------------------------\r
580 *\r
581 *       この関数を複数回呼び出すと,ホスト設定が追加される.\r
582 *\r
583 *       Parameter\r
584 *               なし\r
585 *\r
586 *       Return Value\r
587 *               YES: 読み出し成功\r
588 *               NO:  読み出し失敗(設定無し)\r
589 *----------------------------------------------------------------------------*/\r
590 \r
591 int LoadRegistory(void)\r
592 {\r
593         void *hKey3;\r
594         void *hKey4;\r
595         void *hKey5;\r
596         int i;\r
597         int Sets;\r
598         char Str[256];  /* ASCII_EXT_LENより大きい事 */\r
599         char *Pos;\r
600         char *Pos2;\r
601         HOSTDATA Host;\r
602         HISTORYDATA Hist;\r
603         int Sts;\r
604         int Version;\r
605 \r
606         Sts = NO;\r
607 \r
608         SetRegType(REGTYPE_INI);\r
609         if((i = OpenReg("FFFTP", &hKey3)) != FFFTP_SUCCESS)\r
610         {\r
611                 if(AskForceIni() == NO)\r
612                 {\r
613                         SetRegType(REGTYPE_REG);\r
614                         i = OpenReg("FFFTP", &hKey3);\r
615                 }\r
616         }\r
617 \r
618         if(i == FFFTP_SUCCESS)\r
619         {\r
620 //              char checkbuf[48];\r
621                 int salt = 0;\r
622                 Sts = YES;\r
623 \r
624                 ReadIntValueFromReg(hKey3, "Version", &Version);\r
625 \r
626                 if(OpenSubKey(hKey3, "Options", &hKey4) == FFFTP_SUCCESS)\r
627                 {\r
628                         ReadIntValueFromReg(hKey4, "WinPosX", &WinPosX);\r
629                         ReadIntValueFromReg(hKey4, "WinPosY", &WinPosY);\r
630                         ReadIntValueFromReg(hKey4, "WinWidth", &WinWidth);\r
631                         ReadIntValueFromReg(hKey4, "WinHeight", &WinHeight);\r
632                         ReadIntValueFromReg(hKey4, "LocalWidth", &LocalWidth);\r
633                         /* ↓旧バージョンのバグ対策 */\r
634                         LocalWidth = max1(0, LocalWidth);\r
635                         ReadIntValueFromReg(hKey4, "TaskHeight", &TaskHeight);\r
636                         /* ↓旧バージョンのバグ対策 */\r
637                         TaskHeight = max1(0, TaskHeight);\r
638                         ReadBinaryFromReg(hKey4, "LocalColm", &LocalTabWidth, sizeof(LocalTabWidth));\r
639                         ReadBinaryFromReg(hKey4, "RemoteColm", &RemoteTabWidth, sizeof(RemoteTabWidth));\r
640                         ReadIntValueFromReg(hKey4, "SwCmd", &Sizing);\r
641 \r
642                         ReadStringFromReg(hKey4, "UserMail", UserMailAdrs, USER_MAIL_LEN+1);\r
643                         ReadStringFromReg(hKey4, "Viewer", ViewerName[0], FMAX_PATH+1);\r
644                         ReadStringFromReg(hKey4, "Viewer2", ViewerName[1], FMAX_PATH+1);\r
645                         ReadStringFromReg(hKey4, "Viewer3", ViewerName[2], FMAX_PATH+1);\r
646 \r
647                         ReadIntValueFromReg(hKey4, "TrType", &TransMode);\r
648                         ReadIntValueFromReg(hKey4, "Recv", &RecvMode);\r
649                         ReadIntValueFromReg(hKey4, "Send", &SendMode);\r
650                         ReadIntValueFromReg(hKey4, "Move", &MoveMode);\r
651                         ReadStringFromReg(hKey4, "Path", DefaultLocalPath, FMAX_PATH+1);\r
652                         ReadIntValueFromReg(hKey4, "Time", &SaveTimeStamp);\r
653                         ReadIntValueFromReg(hKey4, "EOF", &RmEOF);\r
654                         ReadIntValueFromReg(hKey4, "Scolon", &VaxSemicolon);\r
655 \r
656                         ReadIntValueFromReg(hKey4, "RecvEx", &ExistMode);\r
657                         ReadIntValueFromReg(hKey4, "SendEx", &UpExistMode);\r
658 \r
659                         ReadIntValueFromReg(hKey4, "LFsort", &LocalFileSort);\r
660                         ReadIntValueFromReg(hKey4, "LDsort", &LocalDirSort);\r
661                         ReadIntValueFromReg(hKey4, "RFsort", &RemoteFileSort);\r
662                         ReadIntValueFromReg(hKey4, "RDsort", &RemoteDirSort);\r
663                         ReadIntValueFromReg(hKey4, "SortSave", &SortSave);\r
664 \r
665                         ReadIntValueFromReg(hKey4, "ListType", &ListType);\r
666                         ReadIntValueFromReg(hKey4, "Cache", &CacheEntry);\r
667                         ReadIntValueFromReg(hKey4, "CacheSave", &CacheSave);\r
668                         ReadIntValueFromReg(hKey4, "DotFile", &DotFile);\r
669                         ReadIntValueFromReg(hKey4, "Dclick", &DclickOpen);\r
670 \r
671                         ReadIntValueFromReg(hKey4, "ConS", &ConnectOnStart);\r
672                         ReadIntValueFromReg(hKey4, "OldDlg", &ConnectAndSet);\r
673                         ReadIntValueFromReg(hKey4, "RasClose", &RasClose);\r
674                         ReadIntValueFromReg(hKey4, "RasNotify", &RasCloseNotify);\r
675                         ReadIntValueFromReg(hKey4, "Qanony", &QuickAnonymous);\r
676                         ReadIntValueFromReg(hKey4, "PassHist", &PassToHist);\r
677                         ReadIntValueFromReg(hKey4, "SendQuit", &SendQuit);\r
678                         ReadIntValueFromReg(hKey4, "NoRas", &NoRasControl);\r
679 \r
680                         ReadIntValueFromReg(hKey4, "Debug", &DebugConsole);\r
681                         ReadIntValueFromReg(hKey4, "WinPos", &SaveWinPos);\r
682                         ReadIntValueFromReg(hKey4, "RegExp", &FindMode);\r
683                         ReadIntValueFromReg(hKey4, "Reg", &RegType);\r
684 \r
685                         if(ReadMultiStringFromReg(hKey4, "AsciiFile", AsciiExt, ASCII_EXT_LEN+1) == FFFTP_FAIL)\r
686                         {\r
687                                 /* 旧ASCIIモードの拡張子の設定を新しいものに変換 */\r
688                                 ReadStringFromReg(hKey4, "Ascii", Str, ASCII_EXT_LEN+1);\r
689                                 memset(AsciiExt, NUL, ASCII_EXT_LEN+1);\r
690                                 Pos = Str;\r
691                                 while(*Pos != NUL)\r
692                                 {\r
693                                         if((Pos2 = strchr(Pos, ';')) == NULL)\r
694                                                 Pos2 = strchr(Pos, NUL);\r
695                                         if((Pos2 - Pos) > 0)\r
696                                         {\r
697                                                 if((StrMultiLen(AsciiExt) + (Pos2 - Pos) + 2) >= ASCII_EXT_LEN)\r
698                                                         break;\r
699                                                 strcpy(AsciiExt + StrMultiLen(AsciiExt), "*.");\r
700                                                 strncpy(AsciiExt + StrMultiLen(AsciiExt) - 1, Pos, (Pos2 - Pos));\r
701                                         }\r
702                                         Pos = Pos2;\r
703                                         if(*Pos == ';')\r
704                                                 Pos++;\r
705                                 }\r
706                         }\r
707 \r
708                         ReadIntValueFromReg(hKey4, "LowUp", &FnameCnv);\r
709                         ReadIntValueFromReg(hKey4, "Tout", &TimeOut);\r
710 \r
711                         ReadMultiStringFromReg(hKey4, "NoTrn", MirrorNoTrn, MIRROR_LEN+1);\r
712                         ReadMultiStringFromReg(hKey4, "NoDel", MirrorNoDel, MIRROR_LEN+1);\r
713                         ReadIntValueFromReg(hKey4, "MirFile", &MirrorFnameCnv);\r
714                         ReadIntValueFromReg(hKey4, "MirUNot", &MirUpDelNotify);\r
715                         ReadIntValueFromReg(hKey4, "MirDNot", &MirDownDelNotify);\r
716 \r
717                         if(ReadStringFromReg(hKey4, "ListFont", Str, 256) == FFFTP_SUCCESS)\r
718                         {\r
719                                 if(RestoreFontData(Str, &ListLogFont) == FFFTP_SUCCESS)\r
720                                         ListFont = CreateFontIndirect(&ListLogFont);\r
721                         }\r
722                         ReadIntValueFromReg(hKey4, "ListHide", &DispIgnoreHide);\r
723                         ReadIntValueFromReg(hKey4, "ListDrv", &DispDrives);\r
724 \r
725                         ReadStringFromReg(hKey4, "FwallHost", FwallHost, HOST_ADRS_LEN+1);\r
726                         ReadStringFromReg(hKey4, "FwallUser", FwallUser, USER_NAME_LEN+1);\r
727                         ReadStringFromReg(hKey4, "FwallPass", Str, 255);\r
728                         DecodePassword(Str, FwallPass);\r
729                         ReadIntValueFromReg(hKey4, "FwallPort", &FwallPort);\r
730                         ReadIntValueFromReg(hKey4, "FwallType", &FwallType);\r
731                         ReadIntValueFromReg(hKey4, "FwallDef", &FwallDefault);\r
732                         ReadIntValueFromReg(hKey4, "FwallSec", &FwallSecurity);\r
733                         ReadIntValueFromReg(hKey4, "PasvDef", &PasvDefault);\r
734                         ReadIntValueFromReg(hKey4, "FwallRes", &FwallResolv);\r
735                         ReadIntValueFromReg(hKey4, "FwallLow", &FwallLower);\r
736                         ReadIntValueFromReg(hKey4, "FwallDel", &FwallDelimiter);\r
737 \r
738                         ReadIntValueFromReg(hKey4, "SndConSw", &Sound[SND_CONNECT].On);\r
739                         ReadIntValueFromReg(hKey4, "SndTrnSw", &Sound[SND_TRANS].On);\r
740                         ReadIntValueFromReg(hKey4, "SndErrSw", &Sound[SND_ERROR].On);\r
741                         ReadStringFromReg(hKey4, "SndCon", Sound[SND_CONNECT].Fname, FMAX_PATH+1);\r
742                         ReadStringFromReg(hKey4, "SndTrn", Sound[SND_TRANS].Fname, FMAX_PATH+1);\r
743                         ReadStringFromReg(hKey4, "SndErr", Sound[SND_ERROR].Fname, FMAX_PATH+1);\r
744 \r
745                         ReadMultiStringFromReg(hKey4, "DefAttr", DefAttrList, DEFATTRLIST_LEN+1);\r
746 \r
747                         ReadStringFromReg(hKey4, "Tmp", TmpPath, FMAX_PATH+1);\r
748 \r
749                         ReadBinaryFromReg(hKey4, "Hdlg", &HostDlgSize, sizeof(SIZE));\r
750                         ReadBinaryFromReg(hKey4, "Bdlg", &BmarkDlgSize, sizeof(SIZE));\r
751                         ReadBinaryFromReg(hKey4, "Mdlg", &MirrorDlgSize, sizeof(SIZE));\r
752 \r
753                         ReadIntValueFromReg(hKey4, "FAttrSw", &FolderAttr);\r
754                         ReadIntValueFromReg(hKey4, "FAttr", &FolderAttrNum);\r
755 \r
756                         ReadIntValueFromReg(hKey4, "NoSave", &SuppressSave);\r
757 \r
758                         ReadIntValueFromReg(hKey4, "HistNum", &FileHist);\r
759 //                      ReadMultiStringFromReg(hKey4, "Hist", Hist, (FMAX_PATH+1)*HISTORY_MAX+1);\r
760 \r
761                         /* ヒストリの設定を読み込む */\r
762                         Sets = 0;\r
763                         ReadIntValueFromReg(hKey4, "SavedHist", &Sets);\r
764 \r
765                         for(i = 0; i < Sets; i++)\r
766                         {\r
767                                 sprintf(Str, "History%d", i);\r
768                                 if(OpenSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
769                                 {\r
770                                         CopyDefaultHistory(&Hist);\r
771 \r
772                                         ReadStringFromReg(hKey5, "HostAdrs", Hist.HostAdrs, HOST_ADRS_LEN+1);\r
773                                         ReadStringFromReg(hKey5, "UserName", Hist.UserName, USER_NAME_LEN+1);\r
774                                         ReadStringFromReg(hKey5, "Account", Hist.Account, ACCOUNT_LEN+1);\r
775                                         ReadStringFromReg(hKey5, "LocalDir", Hist.LocalInitDir, INIT_DIR_LEN+1);\r
776                                         ReadStringFromReg(hKey5, "RemoteDir", Hist.RemoteInitDir, INIT_DIR_LEN+1);\r
777                                         ReadStringFromReg(hKey5, "Chmod", Hist.ChmodCmd, CHMOD_CMD_LEN+1);\r
778                                         ReadStringFromReg(hKey5, "Nlst", Hist.LsName, NLST_NAME_LEN+1);\r
779                                         ReadStringFromReg(hKey5, "Init", Hist.InitCmd, INITCMD_LEN+1);\r
780                                         ReadIntValueFromReg(hKey5, "Port", &Hist.Port);\r
781                                         ReadIntValueFromReg(hKey5, "Kanji", &Hist.KanjiCode);\r
782                                         ReadIntValueFromReg(hKey5, "KanaCnv", &Hist.KanaCnv);\r
783                                         ReadIntValueFromReg(hKey5, "NameKanji", &Hist.NameKanjiCode);\r
784                                         ReadIntValueFromReg(hKey5, "NameKana", &Hist.NameKanaCnv);\r
785                                         ReadIntValueFromReg(hKey5, "Pasv", &Hist.Pasv);\r
786                                         ReadIntValueFromReg(hKey5, "Fwall", &Hist.FireWall);\r
787                                         ReadIntValueFromReg(hKey5, "List", &Hist.ListCmdOnly);\r
788                                         ReadIntValueFromReg(hKey5, "NLST-R", &Hist.UseNLST_R);\r
789                                         ReadIntValueFromReg(hKey5, "Tzone", &Hist.TimeZone);\r
790                                         ReadIntValueFromReg(hKey5, "Type", &Hist.HostType);\r
791                                         ReadIntValueFromReg(hKey5, "Sync", &Hist.SyncMove);\r
792                                         ReadIntValueFromReg(hKey5, "Fpath", &Hist.NoFullPath);\r
793                                         ReadBinaryFromReg(hKey5, "Sort", &Hist.Sort, sizeof(Hist.Sort));\r
794                                         ReadIntValueFromReg(hKey5, "Secu", &Hist.Security);\r
795                                         ReadIntValueFromReg(hKey5, "TrType", &Hist.Type);\r
796                                         strcpy(Str, "");\r
797                                         ReadStringFromReg(hKey5, "Password", Str, 255);\r
798                                         DecodePassword(Str, Hist.PassWord);\r
799                                         ReadIntValueFromReg(hKey5, "Dial", &Hist.Dialup);\r
800                                         ReadIntValueFromReg(hKey5, "UseIt", &Hist.DialupAlways);\r
801                                         ReadIntValueFromReg(hKey5, "Notify", &Hist.DialupNotify);\r
802                                         ReadStringFromReg(hKey5, "DialTo", Hist.DialEntry, RAS_NAME_LEN+1);\r
803                                         // 暗号化通信対応\r
804                                         ReadIntValueFromReg(hKey5, "FTPES", &Hist.UseFTPES);\r
805                                         ReadIntValueFromReg(hKey5, "FTPIS", &Hist.UseFTPIS);\r
806                                         ReadIntValueFromReg(hKey5, "SFTP", &Hist.UseSFTP);\r
807                                         // 同時接続対応\r
808                                         ReadIntValueFromReg(hKey5, "ThreadCount", &Hist.MaxThreadCount);\r
809                                         // MLSD対応\r
810                                         ReadIntValueFromReg(hKey5, "MLSD", &Hist.UseMLSD);\r
811                                         // IPv6対応\r
812                                         ReadIntValueFromReg(hKey5, "IPv6", &Hist.UseIPv6);\r
813 \r
814                                         CloseSubKey(hKey5);\r
815                                         AddHistoryToHistory(&Hist);\r
816                                 }\r
817                         }\r
818 \r
819                         /* ホストの設定を読み込む */\r
820                         Sets = 0;\r
821                         ReadIntValueFromReg(hKey4, "SetNum", &Sets);\r
822 \r
823                         for(i = 0; i < Sets; i++)\r
824                         {\r
825                                 sprintf(Str, "Host%d", i);\r
826                                 if(OpenSubKey(hKey4, Str, &hKey5) == FFFTP_SUCCESS)\r
827                                 {\r
828                                         CopyDefaultHost(&Host);\r
829                                         /* 下位互換性のため */\r
830                                         // SourceForge.JPによるフォーク\r
831 //                                      if(Version < VER_NUM)\r
832                                         if(Version < 1921)\r
833                                         {\r
834                                                 Host.Pasv = NO;\r
835                                                 Host.ListCmdOnly = NO;\r
836                                         }\r
837                                         // 1.97b以前はデフォルトでShift_JIS\r
838                                         if(Version < 1980)\r
839                                                 Host.NameKanjiCode = KANJI_SJIS;\r
840                                         ReadIntValueFromReg(hKey5, "Set", &Host.Level);\r
841 \r
842                                         ReadStringFromReg(hKey5, "HostName", Host.HostName, HOST_NAME_LEN+1);\r
843                                         ReadStringFromReg(hKey5, "HostAdrs", Host.HostAdrs, HOST_ADRS_LEN+1);\r
844                                         ReadStringFromReg(hKey5, "UserName", Host.UserName, USER_NAME_LEN+1);\r
845                                         ReadStringFromReg(hKey5, "Account", Host.Account, ACCOUNT_LEN+1);\r
846                                         ReadStringFromReg(hKey5, "LocalDir", Host.LocalInitDir, INIT_DIR_LEN+1);\r
847                                         ReadStringFromReg(hKey5, "RemoteDir", Host.RemoteInitDir, INIT_DIR_LEN+1);\r
848                                         ReadStringFromReg(hKey5, "Chmod", Host.ChmodCmd, CHMOD_CMD_LEN+1);\r
849                                         ReadStringFromReg(hKey5, "Nlst", Host.LsName, NLST_NAME_LEN+1);\r
850                                         ReadStringFromReg(hKey5, "Init", Host.InitCmd, INITCMD_LEN+1);\r
851                                         ReadIntValueFromReg(hKey5, "Port", &Host.Port);\r
852                                         ReadIntValueFromReg(hKey5, "Anonymous", &Host.Anonymous);\r
853                                         ReadIntValueFromReg(hKey5, "Kanji", &Host.KanjiCode);\r
854                                         ReadIntValueFromReg(hKey5, "KanaCnv", &Host.KanaCnv);\r
855                                         ReadIntValueFromReg(hKey5, "NameKanji", &Host.NameKanjiCode);\r
856                                         ReadIntValueFromReg(hKey5, "NameKana", &Host.NameKanaCnv);\r
857                                         ReadIntValueFromReg(hKey5, "Pasv", &Host.Pasv);\r
858                                         ReadIntValueFromReg(hKey5, "Fwall", &Host.FireWall);\r
859                                         ReadIntValueFromReg(hKey5, "List", &Host.ListCmdOnly);\r
860                                         ReadIntValueFromReg(hKey5, "NLST-R", &Host.UseNLST_R);\r
861                                         ReadIntValueFromReg(hKey5, "Last", &Host.LastDir);\r
862                                         ReadIntValueFromReg(hKey5, "Tzone", &Host.TimeZone);\r
863                                         ReadIntValueFromReg(hKey5, "Type", &Host.HostType);\r
864                                         ReadIntValueFromReg(hKey5, "Sync", &Host.SyncMove);\r
865                                         ReadIntValueFromReg(hKey5, "Fpath", &Host.NoFullPath);\r
866                                         ReadBinaryFromReg(hKey5, "Sort", &Host.Sort, sizeof(Host.Sort));\r
867                                         ReadIntValueFromReg(hKey5, "Secu", &Host.Security);\r
868                                         if(Host.Anonymous != YES)\r
869                                         {\r
870                                                 strcpy(Str, "");\r
871                                                 ReadStringFromReg(hKey5, "Password", Str, 255);\r
872                                                 DecodePassword(Str, Host.PassWord);\r
873                                         }\r
874                                         else\r
875                                                 strcpy(Host.PassWord, UserMailAdrs);\r
876 \r
877                                         ReadMultiStringFromReg(hKey5, "Bmarks", Host.BookMark, BOOKMARK_SIZE);\r
878 \r
879                                         ReadIntValueFromReg(hKey5, "Dial", &Host.Dialup);\r
880                                         ReadIntValueFromReg(hKey5, "UseIt", &Host.DialupAlways);\r
881                                         ReadIntValueFromReg(hKey5, "Notify", &Host.DialupNotify);\r
882                                         ReadStringFromReg(hKey5, "DialTo", Host.DialEntry, RAS_NAME_LEN+1);\r
883                                         // 暗号化通信対応\r
884                                         ReadIntValueFromReg(hKey5, "FTPES", &Host.UseFTPES);\r
885                                         ReadIntValueFromReg(hKey5, "FTPIS", &Host.UseFTPIS);\r
886                                         ReadIntValueFromReg(hKey5, "SFTP", &Host.UseSFTP);\r
887                                         // 同時接続対応\r
888                                         ReadIntValueFromReg(hKey5, "ThreadCount", &Host.MaxThreadCount);\r
889                                         // MLSD対応\r
890                                         ReadIntValueFromReg(hKey5, "MLSD", &Host.UseMLSD);\r
891                                         // IPv6対応\r
892                                         ReadIntValueFromReg(hKey5, "IPv6", &Host.UseIPv6);\r
893 \r
894                                         CloseSubKey(hKey5);\r
895 \r
896                                         AddHostToList(&Host, -1, Host.Level);\r
897                                 }\r
898                         }\r
899 \r
900                         ReadIntValueFromReg(hKey4, "CurSet", &Sets);\r
901                         SetCurrentHost(Sets);\r
902 \r
903                         CloseSubKey(hKey4);\r
904                 }\r
905                 CloseReg(hKey3);\r
906         }\r
907         else\r
908         {\r
909                 /*===== 最初の起動時(設定が無い) =====*/\r
910 \r
911 #if 0\r
912                 strcpy(UserMailAdrs, "");\r
913                 strcpy(Str, "");\r
914                 if(InputDialogBox(mailadrs_dlg, HWND_DESKTOP, NULL, Str, USER_MAIL_LEN+1, &i, IDH_HELP_TOPIC_0000001) == YES)\r
915                         strcpy(UserMailAdrs, Str);\r
916 \r
917                 for(i = 0; i < SAMPLE_HOSTS; i++)\r
918                 {\r
919                         CopyDefaultHost(&Host);\r
920                         Host.Level = Sample[i].Level;\r
921                         strcpy(Host.PassWord, UserMailAdrs);\r
922                         strcpy(Host.HostName, Sample[i].HostName);\r
923                         strcpy(Host.HostAdrs, Sample[i].HostAdrs);\r
924                         strcpy(Host.UserName, "anonymous");\r
925                         AddHostToList(&Host, -1, Host.Level);\r
926                 }\r
927 #endif\r
928         }\r
929         return(Sts);\r
930 }\r
931 \r
932 \r
933 /*----- 隠しドライブ情報を取得 ------------------------------------------------\r
934 *\r
935 *       Parameter\r
936 *               なし\r
937 *\r
938 *       Return Value\r
939 *               DWORD \r
940 *                       YES/NO=設定無し\r
941 *----------------------------------------------------------------------------*/\r
942 \r
943 DWORD LoadHideDriveListRegistory(void)\r
944 {\r
945         HKEY hKey1;\r
946         HKEY hKey2;\r
947         HKEY hKey3;\r
948         HKEY hKey4;\r
949         HKEY hKey5;\r
950         HKEY hKey6;\r
951         DWORD Size;\r
952         DWORD Type;\r
953         DWORD Ret;\r
954 \r
955         Ret = 0;\r
956         if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hKey1) == ERROR_SUCCESS)\r
957         {\r
958                 if(RegOpenKeyEx(hKey1, "Microsoft", 0, KEY_READ, &hKey2) == ERROR_SUCCESS)\r
959                 {\r
960                         if(RegOpenKeyEx(hKey2, "Windows", 0, KEY_READ, &hKey3) == ERROR_SUCCESS)\r
961                         {\r
962                                 if(RegOpenKeyEx(hKey3, "CurrentVersion", 0, KEY_READ, &hKey4) == ERROR_SUCCESS)\r
963                                 {\r
964                                         if(RegOpenKeyEx(hKey4, "Policies", 0, KEY_READ, &hKey5) == ERROR_SUCCESS)\r
965                                         {\r
966                                                 if(RegOpenKeyEx(hKey5, "Explorer", 0, KEY_READ, &hKey6) == ERROR_SUCCESS)\r
967                                                 {\r
968                                                         Size = sizeof(DWORD);\r
969                                                         RegQueryValueEx(hKey6, "NoDrives", NULL, &Type, (BYTE *)&Ret, &Size);\r
970                                                         RegCloseKey(hKey6);\r
971                                                 }\r
972                                                 RegCloseKey(hKey5);\r
973                                         }\r
974                                         RegCloseKey(hKey4);\r
975                                 }\r
976                                 RegCloseKey(hKey3);\r
977                         }\r
978                         RegCloseKey(hKey2);\r
979                 }\r
980                 RegCloseKey(hKey1);\r
981         }\r
982         return(Ret);\r
983 }\r
984 \r
985 \r
986 /*----- レジストリの設定値をクリア --------------------------------------------\r
987 *\r
988 *       Parameter\r
989 *               なし\r
990 *\r
991 *       Return Value\r
992 *               なし\r
993 *----------------------------------------------------------------------------*/\r
994 \r
995 void ClearRegistory(void)\r
996 {\r
997         HKEY hKey2;\r
998         HKEY hKey3;\r
999         HKEY hKey4;\r
1000         DWORD Dispos;\r
1001         char Str[20];\r
1002         int i;\r
1003 \r
1004         if(RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Sota", 0, "", REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey2, &Dispos) == ERROR_SUCCESS)\r
1005         {\r
1006                 if(RegCreateKeyEx(hKey2, "FFFTP", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey3, &Dispos) == ERROR_SUCCESS)\r
1007                 {\r
1008                         if(RegCreateKeyEx(hKey3, "Options", 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey4, &Dispos) == ERROR_SUCCESS)\r
1009                         {\r
1010                                 for(i = 0; ; i++)\r
1011                                 {\r
1012                                         sprintf(Str, "Host%d", i);\r
1013                                         if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
1014                                                 break;\r
1015                                 }\r
1016                                 for(i = 0; ; i++)\r
1017                                 {\r
1018                                         sprintf(Str, "History%d", i);\r
1019                                         if(RegDeleteKey(hKey4, Str) != ERROR_SUCCESS)\r
1020                                                 break;\r
1021                                 }\r
1022                                 RegCloseKey(hKey4);\r
1023                         }\r
1024                         RegDeleteKey(hKey3, "Options");\r
1025                         RegCloseKey(hKey3);\r
1026                 }\r
1027                 RegDeleteKey(hKey2, "FFFTP");\r
1028                 RegCloseKey(hKey2);\r
1029         }\r
1030         return;\r
1031 }\r
1032 \r
1033 \r
1034 /*----- 設定をファイルに保存 --------------------------------------------------\r
1035 *\r
1036 *       Parameter\r
1037 *               なし\r
1038 *\r
1039 *       Return Value\r
1040 *               なし\r
1041 *----------------------------------------------------------------------------*/\r
1042 \r
1043 void SaveSettingsToFile(void)\r
1044 {\r
1045         char Tmp[FMAX_PATH*2];\r
1046         char Fname[FMAX_PATH+1];\r
1047 \r
1048         if(RegType == REGTYPE_REG)\r
1049         {\r
1050                 strcpy(Fname, "FFFTP.reg");\r
1051                 if(SelectFile(GetMainHwnd(), Fname, MSGJPN286, MSGJPN287, "reg", OFN_EXTENSIONDIFFERENT | OFN_OVERWRITEPROMPT, 1) == TRUE)\r
1052                 {\r
1053                         sprintf(Tmp, "/e \x22%s\x22 HKEY_CURRENT_USER\\Software\\sota\\FFFTP", Fname);\r
1054                         if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32)\r
1055                         {\r
1056                                 MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK);\r
1057                         }\r
1058                 }\r
1059         }\r
1060         else\r
1061         {\r
1062                 strcpy(Fname, "FFFTP-Backup.ini");\r
1063                 if(SelectFile(GetMainHwnd(), Fname, MSGJPN286, MSGJPN288, "ini", OFN_EXTENSIONDIFFERENT | OFN_OVERWRITEPROMPT, 1) == TRUE)\r
1064                 {\r
1065                         CopyFile(AskIniFilePath(), Fname, FALSE);\r
1066                 }\r
1067         }\r
1068         return;\r
1069 }\r
1070 \r
1071 \r
1072 /*----- 設定をファイルから復元 ------------------------------------------------\r
1073 *\r
1074 *       Parameter\r
1075 *               なし\r
1076 *\r
1077 *       Return Value\r
1078 *               int     ロードしたかどうか (YES/NO)\r
1079 *----------------------------------------------------------------------------*/\r
1080 \r
1081 int LoadSettingsFromFile(void)\r
1082 {\r
1083         int Ret;\r
1084         char Tmp[FMAX_PATH*2];\r
1085         char Fname[FMAX_PATH+1];\r
1086 \r
1087         Ret = NO;\r
1088         strcpy(Fname, "");\r
1089         if(SelectFile(GetMainHwnd(), Fname, MSGJPN291, MSGJPN290, "", OFN_FILEMUSTEXIST, 0) == TRUE)\r
1090         {\r
1091                 if((strlen(Fname) >= 5) && (_stricmp(&Fname[strlen(Fname)-4], ".reg") == 0))\r
1092                 {\r
1093                         sprintf(Tmp, "\x22%s\x22", Fname);\r
1094                         if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32)\r
1095                         {\r
1096                                 MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK);\r
1097                         }\r
1098                         else\r
1099                         {\r
1100                                 Ret = YES;\r
1101                                 /* レジストリエディタが終了するのを待つ */\r
1102 //                              WaitForSingleObject(Info.hProcess, INFINITE);\r
1103                         }\r
1104                 }\r
1105                 else if((strlen(Fname) >= 5) && (_stricmp(&Fname[strlen(Fname)-4], ".ini") == 0))\r
1106                 {\r
1107                         CopyFile(Fname, AskIniFilePath(), FALSE);\r
1108                         Ret = YES;\r
1109                 }\r
1110                 else\r
1111                         MessageBox(NULL, MSGJPN293, "FFFTP", MB_OK);\r
1112         }\r
1113         return(Ret);\r
1114 }\r
1115 \r
1116 \r
1117 \r
1118 \r
1119 /*----- レジストリ/INIファイルに文字列をセーブ --------------------------------\r
1120 *\r
1121 *       Parameter\r
1122 *               HKEY hKey : レジストリキー\r
1123 *               char *Key : キー名\r
1124 *               char *Str : セーブする文字列\r
1125 *               char *DefaultStr : デフォルトの文字列\r
1126 *\r
1127 *       Return Value\r
1128 *               なし\r
1129 *\r
1130 *       Note\r
1131 *               文字列がデフォルトの文字列と同じならセーブしない\r
1132 *----------------------------------------------------------------------------*/\r
1133 \r
1134 static void SaveStr(HKEY hKey, char *Key, char *Str, char *DefaultStr)\r
1135 {\r
1136         if((DefaultStr != NULL) && (strcmp(Str, DefaultStr) == 0))\r
1137                 DeleteValue(hKey, Key);\r
1138         else\r
1139                 WriteStringToReg(hKey, Key, Str);\r
1140 \r
1141         return;\r
1142 }\r
1143 \r
1144 \r
1145 /*----- レジストリ/INIファイルに数値(INT)をセーブ -----------------------------\r
1146 *\r
1147 *       Parameter\r
1148 *               HKEY hKey : レジストリキー\r
1149 *               char *Key : キー名\r
1150 *               int Num : セーブする値\r
1151 *               int DefaultNum : デフォルトの値\r
1152 *\r
1153 *       Return Value\r
1154 *               なし\r
1155 *\r
1156 *       Note\r
1157 *               数値がデフォルトの値と同じならセーブしない\r
1158 *----------------------------------------------------------------------------*/\r
1159 \r
1160 static void SaveIntNum(HKEY hKey, char *Key, int Num, int DefaultNum)\r
1161 {\r
1162         if(Num == DefaultNum)\r
1163                 DeleteValue(hKey, Key);\r
1164         else\r
1165                 WriteIntValueToReg(hKey, Key, Num);\r
1166 \r
1167         return;\r
1168 }\r
1169 \r
1170 \r
1171 /*----- LOGFONTデータを文字列に変換する ---------------------------------------\r
1172 *\r
1173 *       Parameter\r
1174 *               LOGFONT Font : フォントデータ\r
1175 *               HFONT hFont : フォントのハンドル\r
1176 *                       NULL = デフォルトのフォント\r
1177 *               char *Buf : バッファ\r
1178 *\r
1179 *       Return Value\r
1180 *               なし\r
1181 *----------------------------------------------------------------------------*/\r
1182 \r
1183 static void MakeFontData(LOGFONT Font, HFONT hFont, char *Buf)\r
1184 {\r
1185         *Buf = NUL;\r
1186         if(hFont != NULL)\r
1187                 sprintf(Buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %s",\r
1188                         Font.lfHeight, Font.lfWidth, Font.lfEscapement, Font.lfOrientation,\r
1189                         Font.lfWeight, Font.lfItalic, Font.lfUnderline, Font.lfStrikeOut,\r
1190                         Font.lfCharSet, Font.lfOutPrecision, Font.lfClipPrecision,\r
1191                         Font.lfQuality, Font.lfPitchAndFamily, Font.lfFaceName);\r
1192         return;\r
1193 }\r
1194 \r
1195 \r
1196 /*----- 文字列をLOGFONTデータに変換する ---------------------------------------\r
1197 *\r
1198 *       Parameter\r
1199 *               char *Str : 文字列\r
1200 *               LOGFONT *Font : フォントデータ\r
1201 *\r
1202 *       Return Value\r
1203 *               int ステータス\r
1204 *                       FFFTP_SUCCESS/FFFTP_FAIL=変換できない\r
1205 *----------------------------------------------------------------------------*/\r
1206 \r
1207 static int RestoreFontData(char *Str, LOGFONT *Font)\r
1208 {\r
1209         int i;\r
1210         int Sts;\r
1211 \r
1212         Sts = FFFTP_FAIL;\r
1213         if(sscanf(Str, "%d %d %d %d %d %d %d %d %d %d %d %d %d",\r
1214                         &(Font->lfHeight), &(Font->lfWidth), &(Font->lfEscapement), &(Font->lfOrientation),\r
1215                         &(Font->lfWeight), &(Font->lfItalic), &(Font->lfUnderline), &(Font->lfStrikeOut),\r
1216                         &(Font->lfCharSet), &(Font->lfOutPrecision), &(Font->lfClipPrecision),\r
1217                         &(Font->lfQuality), &(Font->lfPitchAndFamily)) == 13)\r
1218         {\r
1219                 for(i = 13; i > 0; i--)\r
1220                 {\r
1221                         if((Str = strchr(Str, ' ')) == NULL)\r
1222                                 break;\r
1223                         Str++;\r
1224                 }\r
1225                 if(i == 0)\r
1226                 {\r
1227                         strcpy(Font->lfFaceName, Str);\r
1228                         Sts = FFFTP_SUCCESS;\r
1229                 }\r
1230         }\r
1231 \r
1232         if(Sts == FFFTP_FAIL)\r
1233                 memset(Font, NUL, sizeof(LOGFONT));\r
1234 \r
1235         return(Sts);\r
1236 }\r
1237 \r
1238 /*----- パスワードを暗号化する ------------------------------------------------\r
1239 *\r
1240 *       Parameter\r
1241 *               char *Str : パスワード\r
1242 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1243 *\r
1244 *       Return Value\r
1245 *               なし\r
1246 *----------------------------------------------------------------------------*/\r
1247 static void EncodePassword(char *Str, char *Buf)\r
1248 {\r
1249         EncodePassword3( Str, Buf, SecretKey );\r
1250 }\r
1251 \r
1252 /*----- パスワードを暗号化する(オリジナルアルゴリズム)  ------------------\r
1253 *\r
1254 *       Parameter\r
1255 *               char *Str : パスワード\r
1256 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1257 *\r
1258 *       Return Value\r
1259 *               なし\r
1260 *----------------------------------------------------------------------------*/\r
1261 \r
1262 static void EncodePasswordOriginal(char *Str, char *Buf)\r
1263 {\r
1264         unsigned char *Get;\r
1265         unsigned char *Put;\r
1266         int Rnd;\r
1267         int Ch;\r
1268 \r
1269         srand((unsigned)time(NULL));\r
1270 \r
1271         Get = (unsigned char *)Str;\r
1272         Put = (unsigned char *)Buf;\r
1273         \r
1274         if( *Get == NUL ){\r
1275                 *Put = NUL;\r
1276                 return;\r
1277         }\r
1278 \r
1279         /* 識別子を先頭に置く */\r
1280         Put[0] = '0';\r
1281         Put[1] = 'A';\r
1282         Put += 2;\r
1283 \r
1284         while(*Get != NUL)\r
1285         {\r
1286                 Rnd = rand() % 3;\r
1287                 Ch = ((int)*Get++) << Rnd;\r
1288                 Ch = (unsigned char)Ch | (unsigned char)(Ch >> 8);\r
1289                 *Put++ = 0x40 | ((Rnd & 0x3) << 4) | (Ch & 0xF);\r
1290                 *Put++ = 0x40 | ((Ch >> 4) & 0xF);\r
1291                 if((*(Put-2) & 0x1) != 0)\r
1292                         *Put++ = (rand() % 62) + 0x40;\r
1293         }\r
1294         *Put = NUL;\r
1295         return;\r
1296 }\r
1297 \r
1298 /*----- パスワードを暗号化する(オリジナルアルゴリズム^Key)  ----------------\r
1299 *\r
1300 *       Parameter\r
1301 *               char *Str : パスワード\r
1302 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1303 *               const char *Key : 暗号化キー\r
1304 *\r
1305 *       Return Value\r
1306 *               なし\r
1307 *----------------------------------------------------------------------------*/\r
1308 \r
1309 static void EncodePassword2(char *Str, char *Buf, const char* Key)\r
1310 {\r
1311         unsigned char *Get;\r
1312         unsigned char *Put;\r
1313         int Rnd;\r
1314         int Ch;\r
1315 \r
1316         /* 2010.01.31 genta Key */\r
1317         unsigned char *KeyHead = (unsigned char *)Key;\r
1318         unsigned char *KeyEnd = KeyHead + strlen(KeyHead);\r
1319         unsigned char *KeyCurrent = KeyHead;\r
1320 \r
1321         srand((unsigned)time(NULL));\r
1322 \r
1323         Get = (unsigned char *)Str;\r
1324         Put = (unsigned char *)Buf;\r
1325         \r
1326         if( *Get == NUL ){\r
1327                 *Put = NUL;\r
1328                 return;\r
1329         }\r
1330 \r
1331         /* 識別子を先頭に置く */\r
1332         Put[0] = '0';\r
1333         Put[1] = 'B';\r
1334         Put += 2;\r
1335 \r
1336         while(*Get != NUL)\r
1337         {\r
1338                 Rnd = rand() % 3;\r
1339                 Ch = ((int)(*Get++ ^ *KeyCurrent)) << Rnd;\r
1340                 Ch = (unsigned char)Ch | (unsigned char)(Ch >> 8);\r
1341                 *Put++ = 0x40 | ((Rnd & 0x3) << 4) | (Ch & 0xF);\r
1342                 *Put++ = 0x40 | ((Ch >> 4) & 0xF);\r
1343                 if((*(Put-2) & 0x1) != 0)\r
1344                         *Put++ = (rand() % 62) + 0x40;\r
1345 \r
1346                 /* 2010.01.31 genta Key */\r
1347                 if( ++KeyCurrent == KeyEnd ){\r
1348                         KeyCurrent = KeyHead;\r
1349                 }\r
1350         }\r
1351         *Put = NUL;\r
1352         return;\r
1353 }\r
1354 \r
1355 /*----- パスワードを暗号化する(AES) ------------------------------------------\r
1356 *\r
1357 *       Parameter\r
1358 *               char *Str : パスワード\r
1359 *               char *Buf : 暗号化したパスワードを格納するバッファ\r
1360 *               const char *Key : 暗号化キー\r
1361 *\r
1362 *       Return Value\r
1363 *               なし\r
1364 *----------------------------------------------------------------------------*/\r
1365 \r
1366 static void EncodePassword3(char *Str, char *Buf, const char *Key)\r
1367 {\r
1368         unsigned char *Put;\r
1369         unsigned char *AesEncBuf;\r
1370         unsigned char *StrPadBuf;\r
1371         size_t StrLen;\r
1372         size_t StrPadLen;\r
1373         size_t StrPadIndex;\r
1374         size_t IvIndex;\r
1375         size_t EncBufIndex;\r
1376         DWORD RandValue;\r
1377         int RandByteCount;\r
1378         unsigned char AesKey[32];\r
1379         unsigned char AesCbcIv[AES_BLOCK_SIZE];\r
1380         aes_encrypt_ctx Ctx;\r
1381 \r
1382         Buf[0] = NUL;\r
1383 \r
1384         Put = (unsigned char *)Buf;\r
1385         StrLen = strlen(Str);\r
1386         StrPadLen = ((StrLen + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;\r
1387 \r
1388         /* 最低長を32文字とする */\r
1389 //      StrPadLen = min1(StrPadLen, AES_BLOCK_SIZE * 2);\r
1390         StrPadLen = max1(StrPadLen, AES_BLOCK_SIZE * 2);\r
1391 \r
1392         if((StrPadBuf = malloc(StrPadLen)) != NULL)\r
1393         {\r
1394                 if((AesEncBuf = malloc(StrPadLen)) != NULL)\r
1395                 {\r
1396                         BOOL PutState;\r
1397 \r
1398                         PutState = FALSE;\r
1399                         strncpy(StrPadBuf, Str, StrPadLen);\r
1400                         \r
1401                         /* PAD部分を乱数で埋める StrPad[StrLen](が有効な場合) は NUL */\r
1402                         for(StrPadIndex = StrLen + 1; StrPadIndex < StrPadLen;)\r
1403                         {\r
1404                                 RandValue = GetRandamDWRODValue();\r
1405                                 for(RandByteCount = 0; RandByteCount < 4; RandByteCount++)\r
1406                                 {\r
1407                                         if(StrPadIndex < StrPadLen)\r
1408                                         {\r
1409                                                 StrPadBuf[StrPadIndex++] = (unsigned char)(RandValue & 0xff);\r
1410                                                 RandValue >>= 8;\r
1411                                         }\r
1412                                 }\r
1413                         }\r
1414                         \r
1415                         // IVの初期化\r
1416                         for(IvIndex = 0; IvIndex < AES_BLOCK_SIZE;)\r
1417                         {\r
1418                                 RandValue = GetRandamDWRODValue();\r
1419                                 for(RandByteCount = 0; RandByteCount < 4; RandByteCount++)\r
1420                                 {\r
1421                                         if(IvIndex < AES_BLOCK_SIZE)\r
1422                                         {\r
1423                                                 AesCbcIv[IvIndex++] = (unsigned char)(RandValue & 0xff);\r
1424                                                 RandValue >>= 8;\r
1425                                         }\r
1426                                 }\r
1427                         }\r
1428                         Put[0] = '0';\r
1429                         Put[1] = 'C';\r
1430                         Put += 2;\r
1431                         for(IvIndex = 0; IvIndex < AES_BLOCK_SIZE; IvIndex++)\r
1432                         {\r
1433                                 sprintf(Put, "%02x", AesCbcIv[IvIndex]);\r
1434                                 Put += 2;\r
1435                         }\r
1436                         *Put++ = ':';\r
1437 \r
1438                         if(CreateAesKey(AesKey, Key) == FFFTP_SUCCESS)\r
1439                         {\r
1440                                 aes_encrypt_key(AesKey, 32, &Ctx);\r
1441 \r
1442                                 if(aes_cbc_encrypt(StrPadBuf, AesEncBuf, StrPadLen, AesCbcIv, &Ctx) == EXIT_SUCCESS)\r
1443                                 {\r
1444                                         for(EncBufIndex = 0; EncBufIndex < StrPadLen; EncBufIndex++)\r
1445                                         {\r
1446                                                 sprintf(Put, "%02x", AesEncBuf[EncBufIndex]);\r
1447                                                 Put += 2;\r
1448                                         }\r
1449                                         *Put = NUL;\r
1450                                         PutState = TRUE;\r
1451                                 }\r
1452                         }\r
1453                         if(FALSE == PutState)\r
1454                         {\r
1455                                 Buf[0] = NUL;\r
1456                         }\r
1457                         free(StrPadBuf);\r
1458                 }\r
1459                 free(AesEncBuf);\r
1460         }\r
1461         return;\r
1462 }\r
1463 \r
1464 \r
1465 /*----- パスワードの暗号化を解く ----------------------------------------------\r
1466 *\r
1467 *       Parameter\r
1468 *               char *Str : 暗号化したパスワード\r
1469 *               char *Buf : パスワードを格納するバッファ\r
1470 *\r
1471 *       Return Value\r
1472 *               なし\r
1473 *----------------------------------------------------------------------------*/\r
1474 \r
1475 static void DecodePassword(char *Str, char *Buf)\r
1476 {\r
1477         unsigned char *Get;\r
1478         unsigned char *Put;\r
1479 \r
1480         Get = (unsigned char *)Str;\r
1481         Put = (unsigned char *)Buf;\r
1482         \r
1483         if( *Get == NUL ){\r
1484                 *Put = NUL;\r
1485         }\r
1486         else if( 0x40 <= *Get && *Get < 0x80 ){\r
1487                 /* Original algorithm */\r
1488                 DecodePasswordOriginal( Str, Buf );\r
1489         }\r
1490         else if( strncmp( Get, "0A", 2 ) == 0 ){\r
1491                 DecodePasswordOriginal( Str + 2, Buf );\r
1492         }\r
1493         else if( strncmp( Get, "0B", 2 ) == 0 ){\r
1494                 DecodePassword2( Str + 2, Buf, SecretKey );\r
1495         }\r
1496         else if( strncmp( Get, "0C", 2 ) == 0 ){\r
1497                 DecodePassword3( Str + 2, Buf, SecretKey );\r
1498         }\r
1499         else {\r
1500                 //      unknown encoding\r
1501                 *Put = NUL;\r
1502                 return;\r
1503         }\r
1504 }\r
1505 \r
1506 /*----- パスワードの暗号化を解く(オリジナルアルゴリズム) -------------------\r
1507 *\r
1508 *       Parameter\r
1509 *               char *Str : 暗号化したパスワード\r
1510 *               char *Buf : パスワードを格納するバッファ\r
1511 *\r
1512 *       Return Value\r
1513 *               なし\r
1514 *----------------------------------------------------------------------------*/\r
1515 static void DecodePasswordOriginal(char *Str, char *Buf)\r
1516 {\r
1517         unsigned char *Get;\r
1518         unsigned char *Put;\r
1519         int Rnd;\r
1520         int Ch;\r
1521 \r
1522         Get = (unsigned char *)Str;\r
1523         Put = (unsigned char *)Buf;\r
1524 \r
1525         while(*Get != NUL)\r
1526         {\r
1527                 Rnd = ((unsigned int)*Get >> 4) & 0x3;\r
1528                 Ch = (*Get & 0xF) | ((*(Get+1) & 0xF) << 4);\r
1529                 Ch <<= 8;\r
1530                 if((*Get & 0x1) != 0)\r
1531                         Get++;\r
1532                 Get += 2;\r
1533                 Ch >>= Rnd;\r
1534                 Ch = (Ch & 0xFF) | ((Ch >> 8) & 0xFF);\r
1535                 *Put++ = Ch;\r
1536         }\r
1537         *Put = NUL;\r
1538         return;\r
1539 }\r
1540 \r
1541 /*----- パスワードの暗号化を解く(オリジナルアルゴリズム^Key) -------------------\r
1542 *\r
1543 *       Parameter\r
1544 *               char *Str : 暗号化したパスワード\r
1545 *               char *Buf : パスワードを格納するバッファ\r
1546 *               const char *Key : 暗号化キー\r
1547 *\r
1548 *       Return Value\r
1549 *               なし\r
1550 *----------------------------------------------------------------------------*/\r
1551 static void DecodePassword2(char *Str, char *Buf, const char* Key)\r
1552 {\r
1553         int Rnd;\r
1554         int Ch;\r
1555         unsigned char *Get = (unsigned char *)Str;\r
1556         unsigned char *Put = (unsigned char *)Buf;\r
1557 \r
1558         /* 2010.01.31 genta Key */\r
1559         unsigned char *KeyHead = (unsigned char *)Key;\r
1560         unsigned char *KeyEnd = KeyHead + strlen(KeyHead);\r
1561         unsigned char *KeyCurrent = KeyHead;\r
1562 \r
1563         while(*Get != NUL)\r
1564         {\r
1565                 Rnd = ((unsigned int)*Get >> 4) & 0x3;\r
1566                 Ch = (*Get & 0xF) | ((*(Get+1) & 0xF) << 4);\r
1567                 Ch <<= 8;\r
1568                 if((*Get & 0x1) != 0)\r
1569                         Get++;\r
1570                 Get += 2;\r
1571                 Ch >>= Rnd;\r
1572                 Ch = (Ch & 0xFF) | ((Ch >> 8) & 0xFF);\r
1573                 *Put++ = Ch ^ *KeyCurrent;\r
1574                 \r
1575                 /* 2010.01.31 genta Key */\r
1576                 if( ++KeyCurrent == KeyEnd ){\r
1577                         KeyCurrent = KeyHead;\r
1578                 }\r
1579         }\r
1580         *Put = NUL;\r
1581         return;\r
1582 }\r
1583 \r
1584 /*----- パスワードの暗号化を解く(AES) ---------------------------------------\r
1585 *\r
1586 *       Parameter\r
1587 *               char *Str : 暗号化したパスワード\r
1588 *               char *Buf : パスワードを格納するバッファ\r
1589 *               const char *Key : 暗号化キー\r
1590 *\r
1591 *       Return Value\r
1592 *               なし\r
1593 *----------------------------------------------------------------------------*/\r
1594 \r
1595 static void DecodePassword3(char *Str, char *Buf, const char *Key)\r
1596 {\r
1597         char *Get;\r
1598         unsigned char *EncBuf;\r
1599         size_t StrLen;\r
1600         size_t IvIndex;\r
1601         size_t EncBufIndex;\r
1602         size_t EncBufLen;\r
1603         unsigned char AesKey[32];\r
1604         unsigned char AesCbcIv[AES_BLOCK_SIZE];\r
1605         aes_decrypt_ctx Ctx;\r
1606 \r
1607         Buf[0] = NUL;\r
1608 \r
1609         Get = Str;\r
1610         StrLen = strlen(Str);\r
1611 \r
1612         if(AES_BLOCK_SIZE * 2 + 1 < StrLen)\r
1613         {\r
1614 \r
1615                 EncBufLen = (StrLen - 1 ) / 2 - AES_BLOCK_SIZE;\r
1616                 if((EncBuf = malloc(EncBufLen)) != NULL)\r
1617                 {\r
1618                         for(IvIndex = 0; IvIndex < AES_BLOCK_SIZE; IvIndex++)\r
1619                         {\r
1620                                 AesCbcIv[IvIndex]  = hex2bin(*Get++) << 4;\r
1621                                 AesCbcIv[IvIndex] |= hex2bin(*Get++);\r
1622                         }\r
1623 \r
1624                         if(*Get++ == ':')\r
1625                         {\r
1626                                 if(CreateAesKey(AesKey, Key) == FFFTP_SUCCESS)\r
1627                                 {\r
1628                                         aes_decrypt_key(AesKey, 32, &Ctx);\r
1629 \r
1630                                         for(EncBufIndex = 0; EncBufIndex < EncBufLen; EncBufIndex++)\r
1631                                         {\r
1632                                                 EncBuf[EncBufIndex]  = hex2bin(*Get++) << 4;\r
1633                                                 EncBuf[EncBufIndex] |= hex2bin(*Get++);\r
1634                                         }\r
1635                                         if(aes_cbc_decrypt(EncBuf, Buf, EncBufLen, AesCbcIv, &Ctx) == EXIT_SUCCESS)\r
1636                                         {\r
1637                                                 Buf[EncBufLen] = NUL;\r
1638                                         }\r
1639                                 }\r
1640                         }\r
1641                         free(EncBuf);\r
1642                 }\r
1643         }\r
1644         return;\r
1645 }\r
1646 \r
1647 /*----- AES用固定長キーを作成 ----------------------------------------------\r
1648 *\r
1649 *       Parameter\r
1650 *               unsigned char *AesKey : AES暗号鍵\r
1651 *               const char *Key : 暗号化キー\r
1652 *\r
1653 *       Return Value\r
1654 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
1655 *       Note\r
1656 *               SHA-1をもちいて32Byte鍵を生成する\r
1657 *----------------------------------------------------------------------------*/\r
1658 \r
1659 static int CreateAesKey(unsigned char *AesKey, const char* Key)\r
1660 {\r
1661         char* HashKey;\r
1662         uint32 HashKeyLen;\r
1663         uint32 results[10];\r
1664         int ByteOffset;\r
1665         int KeyIndex;\r
1666         int ResIndex;\r
1667 \r
1668         HashKeyLen = strlen(Key) + 16;\r
1669         if((HashKey = malloc(HashKeyLen + 1)) == NULL){\r
1670                 return (FFFTP_FAIL);\r
1671         }\r
1672 \r
1673         strcpy(HashKey, Key);\r
1674         strcat(HashKey, ">g^r=@N7=//z<[`:");\r
1675     sha_memory((uchar *)HashKey, HashKeyLen, results);\r
1676 \r
1677         strcpy(HashKey, Key);\r
1678         strcat(HashKey, "VG77dO1#EyC]$|C@");\r
1679     sha_memory((uchar *)HashKey, HashKeyLen, results + 5);\r
1680 \r
1681         KeyIndex = 0;\r
1682         ResIndex = 0;\r
1683         while(ResIndex < 8){\r
1684                 for(ByteOffset = 0; ByteOffset < 4; ByteOffset++){\r
1685                         AesKey[KeyIndex++] = (results[ResIndex] >> ByteOffset * 8) & 0xff;\r
1686                 }\r
1687                 ResIndex++;\r
1688         }\r
1689         free(HashKey);\r
1690 \r
1691         return (FFFTP_SUCCESS);\r
1692 }\r
1693 \r
1694 \r
1695 /*===== レジストリとINIファイルのアクセス処理 ============*/\r
1696 \r
1697 \r
1698 /*===== INIファイル用のレジストリデータ =====*/\r
1699 \r
1700 typedef struct regdatatbl {\r
1701         char KeyName[80+1];                     /* キー名 */\r
1702         char ValTbl[REG_SECT_MAX];      /* 値のテーブル */\r
1703         int ValLen;                                     /* 値データのバイト数 */\r
1704         int Mode;                                       /* キーのモード */\r
1705         struct regdatatbl *Next;\r
1706 } REGDATATBL;\r
1707 \r
1708 /*===== プロトタイプ =====*/\r
1709 \r
1710 static BOOL WriteOutRegToFile(REGDATATBL *Pos);\r
1711 static int ReadInReg(char *Name, REGDATATBL **Handle);\r
1712 static int StrCatOut(char *Src, int Len, char *Dst);\r
1713 static int StrReadIn(char *Src, int Max, char *Dst);\r
1714 static char *ScanValue(void *Handle, char *Name);\r
1715 \r
1716 \r
1717 /*===== ローカルなワーク =====*/\r
1718 \r
1719 static int TmpRegType;\r
1720 \r
1721 \r
1722 \r
1723 /*----- レジストリのタイプを設定する ------------------------------------------\r
1724 *\r
1725 *       Parameter\r
1726 *               int Type : タイプ (REGTYPE_xxx)\r
1727 *\r
1728 *       Return Value\r
1729 *               int ステータス\r
1730 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1731 *----------------------------------------------------------------------------*/\r
1732 \r
1733 static void SetRegType(int Type)\r
1734 {\r
1735         TmpRegType = Type;\r
1736         return;\r
1737 }\r
1738 \r
1739 \r
1740 /*----- レジストリ/INIファイルをオープンする(読み込み)-----------------------\r
1741 *\r
1742 *       Parameter\r
1743 *               char *Name : レジストリ名\r
1744 *               void **Handle : ハンドルを返すワーク\r
1745 *\r
1746 *       Return Value\r
1747 *               int ステータス\r
1748 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1749 *----------------------------------------------------------------------------*/\r
1750 \r
1751 static int OpenReg(char *Name, void **Handle)\r
1752 {\r
1753         int Sts;\r
1754         char Tmp[FMAX_PATH+1];\r
1755 \r
1756         Sts = FFFTP_FAIL;\r
1757         if(TmpRegType == REGTYPE_REG)\r
1758         {\r
1759                 strcpy(Tmp, "Software\\Sota\\");\r
1760                 strcat(Tmp, Name);\r
1761                 if(RegOpenKeyEx(HKEY_CURRENT_USER, Tmp, 0, KEY_READ, (HKEY *)Handle) == ERROR_SUCCESS)\r
1762                         Sts = FFFTP_SUCCESS;\r
1763         }\r
1764         else\r
1765         {\r
1766                 if((Sts = ReadInReg(Name, (REGDATATBL **)Handle)) == FFFTP_SUCCESS)\r
1767                         ((REGDATATBL *)(*Handle))->Mode = 0;\r
1768         }\r
1769         return(Sts);\r
1770 }\r
1771 \r
1772 \r
1773 /*----- レジストリ/INIファイルを作成する(書き込み)---------------------------\r
1774 *\r
1775 *       Parameter\r
1776 *               char *Name : レジストリ名\r
1777 *               void **Handle : ハンドルを返すワーク\r
1778 *\r
1779 *       Return Value\r
1780 *               int ステータス\r
1781 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1782 *----------------------------------------------------------------------------*/\r
1783 \r
1784 static int CreateReg(char *Name, void **Handle)\r
1785 {\r
1786         int Sts;\r
1787         char Tmp[FMAX_PATH+1];\r
1788         DWORD Dispos;\r
1789 \r
1790         Sts = FFFTP_FAIL;\r
1791         if(TmpRegType == REGTYPE_REG)\r
1792         {\r
1793                 strcpy(Tmp, "Software\\Sota\\");\r
1794                 strcat(Tmp, Name);\r
1795                 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
1796                         Sts = FFFTP_SUCCESS;\r
1797         }\r
1798         else\r
1799         {\r
1800                 if((*Handle = malloc(sizeof(REGDATATBL))) != NULL)\r
1801                 {\r
1802                         strcpy(((REGDATATBL *)(*Handle))->KeyName, Name);\r
1803                         ((REGDATATBL *)(*Handle))->ValLen = 0;\r
1804                         ((REGDATATBL *)(*Handle))->Next = NULL;\r
1805                         ((REGDATATBL *)(*Handle))->Mode = 1;\r
1806                         Sts = FFFTP_SUCCESS;\r
1807                 }\r
1808         }\r
1809         return(Sts);\r
1810 }\r
1811 \r
1812 \r
1813 /*----- レジストリ/INIファイルをクローズする ----------------------------------\r
1814 *\r
1815 *       Parameter\r
1816 *               void *Handle : ハンドル\r
1817 *\r
1818 *       Return Value\r
1819 *               int ステータス\r
1820 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1821 *----------------------------------------------------------------------------*/\r
1822 \r
1823 static int CloseReg(void *Handle)\r
1824 {\r
1825         REGDATATBL *Pos;\r
1826         REGDATATBL *Next;\r
1827         FILE *Strm;\r
1828 \r
1829         if(TmpRegType == REGTYPE_REG)\r
1830         {\r
1831                 RegCloseKey(Handle);\r
1832 \r
1833                 /* INIファイルを削除 */\r
1834                 if((Strm = fopen(AskIniFilePath(), "rt")) != NULL)\r
1835                 {\r
1836                         fclose(Strm);\r
1837                         MoveFileToTrashCan(AskIniFilePath());\r
1838                 }\r
1839         }\r
1840         else\r
1841         {\r
1842                 if(((REGDATATBL *)Handle)->Mode == 1)\r
1843                 {\r
1844                         if(WriteOutRegToFile(Handle) == TRUE)\r
1845                         {\r
1846 //                              /* レジストリをクリア */\r
1847 //                              ClearRegistory();\r
1848                         }\r
1849                 }\r
1850                 /* テーブルを削除 */\r
1851                 Pos = Handle;\r
1852                 while(Pos != NULL)\r
1853                 {\r
1854                         Next = Pos->Next;\r
1855                         free(Pos);\r
1856                         Pos = Next;\r
1857                 }\r
1858         }\r
1859         return(FFFTP_SUCCESS);\r
1860 }\r
1861 \r
1862 \r
1863 /*----- レジストリ情報をINIファイルに書き込む ---------------------------------\r
1864 *\r
1865 *       Parameter\r
1866 *               REGDATATBL *Pos : レジストリデータ\r
1867 *\r
1868 *       Return Value\r
1869 *               なし\r
1870 *----------------------------------------------------------------------------*/\r
1871 \r
1872 static BOOL WriteOutRegToFile(REGDATATBL *Pos)\r
1873 {\r
1874         FILE *Strm;\r
1875         char *Disp;\r
1876         BOOL Ret;\r
1877 \r
1878         Ret = FALSE;\r
1879         if((Strm = fopen(AskIniFilePath(), "wt")) != NULL)\r
1880         {\r
1881                 fprintf(Strm, MSGJPN239);\r
1882                 while(Pos != NULL)\r
1883                 {\r
1884                         fprintf(Strm, "\n[%s]\n", Pos->KeyName);\r
1885 \r
1886                         Disp = Pos->ValTbl;\r
1887                         while(Disp < (Pos->ValTbl + Pos->ValLen))\r
1888                         {\r
1889                                 fprintf(Strm, "%s\n", Disp);\r
1890                                 Disp = Disp + strlen(Disp) + 1;\r
1891                         }\r
1892                         Pos = Pos->Next;\r
1893                 }\r
1894                 fclose(Strm);\r
1895                 Ret = TRUE;\r
1896         }\r
1897         else\r
1898                 MessageBox(NULL, MSGJPN240, "FFFTP", MB_OK);\r
1899 \r
1900         return(Ret);\r
1901 }\r
1902 \r
1903 \r
1904 /*----- INIファイルからレジストリ情報を読み込む -------------------------------\r
1905 *\r
1906 *       Parameter\r
1907 *               char *Name : 名前\r
1908 *               void *Handle : ハンドル\r
1909 *\r
1910 *       Return Value\r
1911 *               int ステータス\r
1912 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1913 *----------------------------------------------------------------------------*/\r
1914 \r
1915 static int ReadInReg(char *Name, REGDATATBL **Handle)\r
1916 {\r
1917         FILE *Strm;\r
1918         char *Buf;\r
1919         char *Tmp;\r
1920         char *Data;\r
1921         REGDATATBL *New;\r
1922         REGDATATBL *Pos;\r
1923         int Sts;\r
1924 \r
1925         Sts = FFFTP_FAIL;\r
1926         *Handle = NULL;\r
1927 \r
1928         if((Strm = fopen(AskIniFilePath(), "rt")) != NULL)\r
1929         {\r
1930                 if((Buf = malloc(REG_SECT_MAX)) != NULL)\r
1931                 {\r
1932                         while(fgets(Buf, REG_SECT_MAX, Strm) != NULL)\r
1933                         {\r
1934                                 if(*Buf != '#')\r
1935                                 {\r
1936                                         if((Tmp = strchr(Buf, '\n')) != NULL)\r
1937                                                 *Tmp = NUL;\r
1938 \r
1939                                         if(*Buf == '[')\r
1940                                         {\r
1941                                                 if((New = malloc(sizeof(REGDATATBL))) != NULL)\r
1942                                                 {\r
1943                                                         if((Tmp = strchr(Buf, ']')) != NULL)\r
1944                                                                 *Tmp = NUL;\r
1945                                                         strcpy(New->KeyName, Buf+1);\r
1946                                                         New->ValLen = 0;\r
1947                                                         New->Next = NULL;\r
1948                                                         Data = New->ValTbl;\r
1949                                                 }\r
1950                                                 if(*Handle == NULL)\r
1951                                                         *Handle = New;\r
1952                                                 else\r
1953                                                 {\r
1954                                                         Pos = *Handle;\r
1955                                                         while(Pos->Next != NULL)\r
1956                                                                 Pos = Pos->Next;\r
1957                                                         Pos->Next = New;\r
1958                                                 }\r
1959                                         }\r
1960                                         else if(strlen(Buf) > 0)\r
1961                                         {\r
1962                                                 strcpy(Data, Buf);\r
1963                                                 Data += strlen(Buf) + 1;\r
1964                                                 New->ValLen += strlen(Buf) + 1;\r
1965                                         }\r
1966                                 }\r
1967                         }\r
1968                         Sts = FFFTP_SUCCESS;\r
1969                         free(Buf);\r
1970                 }\r
1971                 fclose(Strm);\r
1972         }\r
1973         return(Sts);\r
1974 }\r
1975 \r
1976 \r
1977 /*----- サブキーをオープンする ------------------------------------------------\r
1978 *\r
1979 *       Parameter\r
1980 *               void *Parent : 親のハンドル\r
1981 *               char *Name : 名前\r
1982 *               void **Handle : ハンドルを返すワーク\r
1983 *\r
1984 *       Return Value\r
1985 *               int ステータス\r
1986 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1987 *----------------------------------------------------------------------------*/\r
1988 \r
1989 static int OpenSubKey(void *Parent, char *Name, void **Handle)\r
1990 {\r
1991         int Sts;\r
1992         char Key[80];\r
1993         REGDATATBL *Pos;\r
1994 \r
1995         Sts = FFFTP_FAIL;\r
1996         if(TmpRegType == REGTYPE_REG)\r
1997         {\r
1998                 if(RegOpenKeyEx(Parent, Name, 0, KEY_READ, (HKEY *)Handle) == ERROR_SUCCESS)\r
1999                         Sts = FFFTP_SUCCESS;\r
2000         }\r
2001         else\r
2002         {\r
2003                 strcpy(Key, ((REGDATATBL *)Parent)->KeyName);\r
2004                 strcat(Key, "\\");\r
2005                 strcat(Key, Name);\r
2006                 Pos = Parent;\r
2007                 while(Pos != NULL)\r
2008                 {\r
2009                         if(strcmp(Pos->KeyName, Key) == 0)\r
2010                         {\r
2011                                 *Handle = Pos;\r
2012                                 Sts = FFFTP_SUCCESS;\r
2013                                 break;\r
2014                         }\r
2015                         Pos = Pos->Next;\r
2016                 }\r
2017         }\r
2018         return(Sts);\r
2019 }\r
2020 \r
2021 \r
2022 /*----- サブキーを作成する ----------------------------------------------------\r
2023 *\r
2024 *       Parameter\r
2025 *               void *Parent : 親のハンドル\r
2026 *               char *Name : 名前\r
2027 *               void **Handle : ハンドルを返すワーク\r
2028 *\r
2029 *       Return Value\r
2030 *               int ステータス\r
2031 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2032 *----------------------------------------------------------------------------*/\r
2033 \r
2034 static int CreateSubKey(void *Parent, char *Name, void **Handle)\r
2035 {\r
2036         int Sts;\r
2037         DWORD Dispos;\r
2038         REGDATATBL *Pos;\r
2039 \r
2040         Sts = FFFTP_FAIL;\r
2041         if(TmpRegType == REGTYPE_REG)\r
2042         {\r
2043                 if(RegCreateKeyEx(Parent, Name, 0, "", REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, (HKEY *)Handle, &Dispos) == ERROR_SUCCESS)\r
2044                         Sts = FFFTP_SUCCESS;\r
2045         }\r
2046         else\r
2047         {\r
2048                 if((*Handle = malloc(sizeof(REGDATATBL))) != NULL)\r
2049                 {\r
2050                         strcpy(((REGDATATBL *)(*Handle))->KeyName, ((REGDATATBL *)Parent)->KeyName);\r
2051                         strcat(((REGDATATBL *)(*Handle))->KeyName, "\\");\r
2052                         strcat(((REGDATATBL *)(*Handle))->KeyName, Name);\r
2053 \r
2054                         ((REGDATATBL *)(*Handle))->ValLen = 0;\r
2055                         ((REGDATATBL *)(*Handle))->Next = NULL;\r
2056 \r
2057                         Pos = (REGDATATBL *)Parent;\r
2058                         while(Pos->Next != NULL)\r
2059                                 Pos = Pos->Next;\r
2060                         Pos->Next = *Handle;\r
2061                         Sts = FFFTP_SUCCESS;\r
2062                 }\r
2063         }\r
2064         return(Sts);\r
2065 }\r
2066 \r
2067 \r
2068 /*----- サブキーをクローズする ------------------------------------------------\r
2069 *\r
2070 *       Parameter\r
2071 *               void *Handle : ハンドル\r
2072 *\r
2073 *       Return Value\r
2074 *               int ステータス\r
2075 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2076 *----------------------------------------------------------------------------*/\r
2077 \r
2078 static int CloseSubKey(void *Handle)\r
2079 {\r
2080         if(TmpRegType == REGTYPE_REG)\r
2081                 RegCloseKey(Handle);\r
2082         else\r
2083         {\r
2084                 /* Nothing */\r
2085         }\r
2086         return(FFFTP_SUCCESS);\r
2087 }\r
2088 \r
2089 \r
2090 /*----- サブキーを削除する ----------------------------------------------------\r
2091 *\r
2092 *       Parameter\r
2093 *               void *Handle : ハンドル\r
2094 *               char *Name : 名前\r
2095 *\r
2096 *       Return Value\r
2097 *               int ステータス\r
2098 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2099 *----------------------------------------------------------------------------*/\r
2100 \r
2101 static int DeleteSubKey(void *Handle, char *Name)\r
2102 {\r
2103         int Sts;\r
2104 \r
2105         Sts = FFFTP_FAIL;\r
2106         if(TmpRegType == REGTYPE_REG)\r
2107         {\r
2108                 if(RegDeleteKey(Handle, Name) == ERROR_SUCCESS)\r
2109                         Sts = FFFTP_SUCCESS;\r
2110         }\r
2111         else\r
2112         {\r
2113                 Sts = FFFTP_FAIL;\r
2114         }\r
2115         return(Sts);\r
2116 }\r
2117 \r
2118 \r
2119 /*----- 値を削除する ----------------------------------------------------------\r
2120 *\r
2121 *       Parameter\r
2122 *               void *Handle : ハンドル\r
2123 *               char *Name : 名前\r
2124 *\r
2125 *       Return Value\r
2126 *               int ステータス\r
2127 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2128 *----------------------------------------------------------------------------*/\r
2129 \r
2130 static int DeleteValue(void *Handle, char *Name)\r
2131 {\r
2132         int Sts;\r
2133 \r
2134         Sts = FFFTP_FAIL;\r
2135         if(TmpRegType == REGTYPE_REG)\r
2136         {\r
2137                 if(RegDeleteValue(Handle, Name) == ERROR_SUCCESS)\r
2138                         Sts = FFFTP_SUCCESS;\r
2139         }\r
2140         else\r
2141         {\r
2142                 Sts = FFFTP_FAIL;\r
2143         }\r
2144         return(Sts);\r
2145 }\r
2146 \r
2147 \r
2148 /*----- INT値を読み込む -------------------------------------------------------\r
2149 *\r
2150 *       Parameter\r
2151 *               void *Handle : ハンドル\r
2152 *               char *Name : 名前\r
2153 *               int *Value : INT値を返すワーク\r
2154 *\r
2155 *       Return Value\r
2156 *               int ステータス\r
2157 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2158 *----------------------------------------------------------------------------*/\r
2159 \r
2160 static int ReadIntValueFromReg(void *Handle, char *Name, int *Value)\r
2161 {\r
2162         int Sts;\r
2163         DWORD Size;\r
2164         char *Pos;\r
2165 \r
2166         Sts = FFFTP_FAIL;\r
2167         if(TmpRegType == REGTYPE_REG)\r
2168         {\r
2169                 Size = sizeof(int);\r
2170                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Value, &Size) == ERROR_SUCCESS)\r
2171                         Sts = FFFTP_SUCCESS;\r
2172         }\r
2173         else\r
2174         {\r
2175                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2176                 {\r
2177                         *Value = atoi(Pos);\r
2178                         Sts = FFFTP_SUCCESS;\r
2179                 }\r
2180         }\r
2181         return(Sts);\r
2182 }\r
2183 \r
2184 \r
2185 /*----- INT値を書き込む -------------------------------------------------------\r
2186 *\r
2187 *       Parameter\r
2188 *               void *Handle : ハンドル\r
2189 *               char *Name : 名前\r
2190 *               int Value : INT値\r
2191 *\r
2192 *       Return Value\r
2193 *               int ステータス\r
2194 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2195 *----------------------------------------------------------------------------*/\r
2196 \r
2197 static int WriteIntValueToReg(void *Handle, char *Name, int Value)\r
2198 {\r
2199         REGDATATBL *Pos;\r
2200         char *Data;\r
2201         char Tmp[20];\r
2202 \r
2203         if(TmpRegType == REGTYPE_REG)\r
2204                 RegSetValueEx(Handle, Name, 0, REG_DWORD, (CONST BYTE *)&Value, sizeof(int));\r
2205         else\r
2206         {\r
2207                 Pos = (REGDATATBL *)Handle;\r
2208                 Data = Pos->ValTbl + Pos->ValLen;\r
2209                 strcpy(Data, Name);\r
2210                 strcat(Data, "=");\r
2211                 sprintf(Tmp, "%d", Value);\r
2212                 strcat(Data, Tmp);\r
2213                 Pos->ValLen += strlen(Data) + 1;\r
2214         }\r
2215         return(FFFTP_SUCCESS);\r
2216 }\r
2217 \r
2218 \r
2219 /*----- 文字列を読み込む ------------------------------------------------------\r
2220 *\r
2221 *       Parameter\r
2222 *               void *Handle : ハンドル\r
2223 *               char *Name : 名前\r
2224 *               char *Str : 文字列を返すワーク\r
2225 *               DWORD Size : 最大サイズ\r
2226 *\r
2227 *       Return Value\r
2228 *               int ステータス\r
2229 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2230 *----------------------------------------------------------------------------*/\r
2231 \r
2232 static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size)\r
2233 {\r
2234         int Sts;\r
2235         char *Pos;\r
2236 \r
2237         Sts = FFFTP_FAIL;\r
2238         if(TmpRegType == REGTYPE_REG)\r
2239         {\r
2240                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Str, &Size) == ERROR_SUCCESS)\r
2241                 {\r
2242                         if(*(Str + Size - 1) != NUL)\r
2243                                 *(Str + Size) = NUL;\r
2244                         Sts = FFFTP_SUCCESS;\r
2245                 }\r
2246         }\r
2247         else\r
2248         {\r
2249                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2250                 {\r
2251                         Size = min1(Size-1, strlen(Pos));\r
2252                         Size = StrReadIn(Pos, Size, Str);\r
2253                         *(Str + Size) = NUL;\r
2254                         Sts = FFFTP_SUCCESS;\r
2255                 }\r
2256         }\r
2257         return(Sts);\r
2258 }\r
2259 \r
2260 \r
2261 /*----- 文字列を書き込む ------------------------------------------------------\r
2262 *\r
2263 *       Parameter\r
2264 *               void *Handle : ハンドル\r
2265 *               char *Name : 名前\r
2266 *               char *Str :文字列\r
2267 *\r
2268 *       Return Value\r
2269 *               int ステータス\r
2270 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2271 *----------------------------------------------------------------------------*/\r
2272 \r
2273 static int WriteStringToReg(void *Handle, char *Name, char *Str)\r
2274 {\r
2275         REGDATATBL *Pos;\r
2276         char *Data;\r
2277 \r
2278         if(TmpRegType == REGTYPE_REG)\r
2279                 RegSetValueEx(Handle, Name, 0, REG_SZ, (CONST BYTE *)Str, strlen(Str)+1);\r
2280         else\r
2281         {\r
2282                 Pos = (REGDATATBL *)Handle;\r
2283                 Data = Pos->ValTbl + Pos->ValLen;\r
2284                 strcpy(Data, Name);\r
2285                 strcat(Data, "=");\r
2286                 Pos->ValLen += strlen(Data);\r
2287                 Data = Pos->ValTbl + Pos->ValLen;\r
2288                 Pos->ValLen += StrCatOut(Str, strlen(Str), Data) + 1;\r
2289         }\r
2290         return(FFFTP_SUCCESS);\r
2291 }\r
2292 \r
2293 \r
2294 /*----- マルチ文字列を読み込む ------------------------------------------------\r
2295 *\r
2296 *       Parameter\r
2297 *               void *Handle : ハンドル\r
2298 *               char *Name : 名前\r
2299 *               char *Str : 文字列を返すワーク\r
2300 *               DWORD Size : 最大サイズ\r
2301 *\r
2302 *       Return Value\r
2303 *               int ステータス\r
2304 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2305 *----------------------------------------------------------------------------*/\r
2306 \r
2307 static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Size)\r
2308 {\r
2309         int Sts;\r
2310         char *Pos;\r
2311 \r
2312         Sts = FFFTP_FAIL;\r
2313         if(TmpRegType == REGTYPE_REG)\r
2314         {\r
2315                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Str, &Size) == ERROR_SUCCESS)\r
2316                 {\r
2317                         if(*(Str + Size - 1) != NUL)\r
2318                                 *(Str + Size) = NUL;\r
2319                         Sts = FFFTP_SUCCESS;\r
2320                 }\r
2321         }\r
2322         else\r
2323         {\r
2324                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2325                 {\r
2326                         Size = min1(Size-1, strlen(Pos));\r
2327                         Size = StrReadIn(Pos, Size, Str);\r
2328                         *(Str + Size) = NUL;\r
2329                         Sts = FFFTP_SUCCESS;\r
2330                 }\r
2331         }\r
2332         return(Sts);\r
2333 }\r
2334 \r
2335 \r
2336 /*----- マルチ文字列を書き込む ------------------------------------------------\r
2337 *\r
2338 *       Parameter\r
2339 *               void *Handle : ハンドル\r
2340 *               char *Name : 名前\r
2341 *               char *Str : 文字列\r
2342 *\r
2343 *       Return Value\r
2344 *               int ステータス\r
2345 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2346 *----------------------------------------------------------------------------*/\r
2347 \r
2348 static int WriteMultiStringToReg(void *Handle, char *Name, char *Str)\r
2349 {\r
2350         REGDATATBL *Pos;\r
2351         char *Data;\r
2352 \r
2353         if(TmpRegType == REGTYPE_REG)\r
2354                 RegSetValueEx(Handle, Name, 0, REG_MULTI_SZ, (CONST BYTE *)Str, StrMultiLen(Str)+1);\r
2355         else\r
2356         {\r
2357                 Pos = (REGDATATBL *)Handle;\r
2358                 Data = Pos->ValTbl + Pos->ValLen;\r
2359                 strcpy(Data, Name);\r
2360                 strcat(Data, "=");\r
2361                 Pos->ValLen += strlen(Data);\r
2362                 Data = Pos->ValTbl + Pos->ValLen;\r
2363                 Pos->ValLen += StrCatOut(Str, StrMultiLen(Str), Data) + 1;\r
2364         }\r
2365         return(FFFTP_SUCCESS);\r
2366 }\r
2367 \r
2368 \r
2369 /*----- バイナリを読み込む-----------------------------------------------------\r
2370 *\r
2371 *       Parameter\r
2372 *               void *Handle : ハンドル\r
2373 *               char *Name : 名前\r
2374 *               void *Bin : バイナリを返すワーク\r
2375 *               DWORD Size : 最大サイズ\r
2376 *\r
2377 *       Return Value\r
2378 *               int ステータス\r
2379 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2380 *----------------------------------------------------------------------------*/\r
2381 \r
2382 static int ReadBinaryFromReg(void *Handle, char *Name, void *Bin, DWORD Size)\r
2383 {\r
2384         int Sts;\r
2385         char *Pos;\r
2386 \r
2387         Sts = FFFTP_FAIL;\r
2388         if(TmpRegType == REGTYPE_REG)\r
2389         {\r
2390                 if(RegQueryValueEx(Handle, Name, NULL, NULL, (BYTE *)Bin, &Size) == ERROR_SUCCESS)\r
2391                         Sts = FFFTP_SUCCESS;\r
2392         }\r
2393         else\r
2394         {\r
2395                 if((Pos = ScanValue(Handle, Name)) != NULL)\r
2396                 {\r
2397                         Size = min1(Size, strlen(Pos));\r
2398                         Size = StrReadIn(Pos, Size, Bin);\r
2399                         Sts = FFFTP_SUCCESS;\r
2400                 }\r
2401         }\r
2402         return(Sts);\r
2403 }\r
2404 \r
2405 \r
2406 /*----- バイナリを書き込む ----------------------------------------------------\r
2407 *\r
2408 *       Parameter\r
2409 *               void *Handle : ハンドル\r
2410 *               char *Name : 名前\r
2411 *               void *Bin : バイナリ\r
2412 *               int Len : 長さ\r
2413 *\r
2414 *       Return Value\r
2415 *               int ステータス\r
2416 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2417 *----------------------------------------------------------------------------*/\r
2418 \r
2419 static int WriteBinaryToReg(void *Handle, char *Name, void *Bin, int Len)\r
2420 {\r
2421         REGDATATBL *Pos;\r
2422         char *Data;\r
2423 \r
2424         if(TmpRegType == REGTYPE_REG)\r
2425                 RegSetValueEx(Handle, Name, 0, REG_BINARY, (CONST BYTE *)Bin, Len);\r
2426         else\r
2427         {\r
2428                 Pos = (REGDATATBL *)Handle;\r
2429                 Data = Pos->ValTbl + Pos->ValLen;\r
2430                 strcpy(Data, Name);\r
2431                 strcat(Data, "=");\r
2432                 Pos->ValLen += strlen(Data);\r
2433                 Data = Pos->ValTbl + Pos->ValLen;\r
2434                 Pos->ValLen += StrCatOut(Bin, Len, Data) + 1;\r
2435         }\r
2436         return(FFFTP_SUCCESS);\r
2437 }\r
2438 \r
2439 \r
2440 /*----- 文字列をバッファに追加書き込みする ------------------------------------\r
2441 *\r
2442 *       Parameter\r
2443 *               char *Src : 文字列\r
2444 *               int len : 文字列の長さ\r
2445 *               char *Dst : 書き込みするバッファ\r
2446 *\r
2447 *       Return Value\r
2448 *               int 追加したバイト数\r
2449 *----------------------------------------------------------------------------*/\r
2450 \r
2451 static int StrCatOut(char *Src, int Len, char *Dst)\r
2452 {\r
2453         int Count;\r
2454 \r
2455         Dst += strlen(Dst);\r
2456         Count = 0;\r
2457         for(; Len > 0; Len--)\r
2458         {\r
2459                 if(*Src == '\\')\r
2460                 {\r
2461                         *Dst++ = '\\';\r
2462                         *Dst++ = '\\';\r
2463                         Count += 2;\r
2464                 }\r
2465                 else if((*Src >= 0x20) && (*Src <= 0x7E))\r
2466                 {\r
2467                         *Dst++ = *Src;\r
2468                         Count++;\r
2469                 }\r
2470                 else\r
2471                 {\r
2472                         sprintf(Dst, "\\%02X", *(unsigned char *)Src);\r
2473                         Dst += 3;\r
2474                         Count += 3;\r
2475                 }\r
2476                 Src++;\r
2477         }\r
2478         *Dst = NUL;\r
2479         return(Count);\r
2480 }\r
2481 \r
2482 \r
2483 /*----- 文字列をバッファに読み込む --------------------------------------------\r
2484 *\r
2485 *       Parameter\r
2486 *               char *Src : 文字列\r
2487 *               int Max : 最大サイズ\r
2488 *               char *Dst : 書き込みするバッファ\r
2489 *\r
2490 *       Return Value\r
2491 *               int 読み込んだバイト数\r
2492 *----------------------------------------------------------------------------*/\r
2493 \r
2494 static int StrReadIn(char *Src, int Max, char *Dst)\r
2495 {\r
2496         int Count;\r
2497         int Tmp;\r
2498 \r
2499         Count = 0;\r
2500         while(*Src != NUL)\r
2501         {\r
2502                 if(Count >= Max)\r
2503                         break;\r
2504 \r
2505                 if(*Src == '\\')\r
2506                 {\r
2507                         Src++;\r
2508                         if(*Src == '\\')\r
2509                                 *Dst = '\\';\r
2510                         else\r
2511                         {\r
2512                                 sscanf(Src, "%02x", &Tmp);\r
2513                                 *Dst = Tmp;\r
2514                                 Src++;\r
2515                         }\r
2516                 }\r
2517                 else\r
2518                         *Dst = *Src;\r
2519 \r
2520                 Count++;\r
2521                 Dst++;\r
2522                 Src++;\r
2523         }\r
2524         return(Count);\r
2525 }\r
2526 \r
2527 \r
2528 /*----- 値を検索する ----------------------------------------------------------\r
2529 *\r
2530 *       Parameter\r
2531 *               char *Handle : ハンドル\r
2532 *               char *Name : 名前\r
2533 *\r
2534 *       Return Value\r
2535 *               char *値データの先頭\r
2536 *                       NULL=指定の名前の値が見つからない\r
2537 *----------------------------------------------------------------------------*/\r
2538 \r
2539 static char *ScanValue(void *Handle, char *Name)\r
2540 {\r
2541         REGDATATBL *Cur;\r
2542         char *Pos;\r
2543         char *Ret;\r
2544 \r
2545         Ret = NULL;\r
2546         Cur = Handle;\r
2547         Pos = Cur->ValTbl;\r
2548         while(Pos < (Cur->ValTbl + Cur->ValLen))\r
2549         {\r
2550                 if((strncmp(Name, Pos, strlen(Name)) == 0) &&\r
2551                    (*(Pos + strlen(Name)) == '='))\r
2552                 {\r
2553                         Ret = Pos + strlen(Name) + 1;\r
2554                         break;\r
2555                 }\r
2556                 Pos += strlen(Pos) + 1;\r
2557         }\r
2558         return(Ret);\r
2559 }\r
2560 \r
2561 \r
2562 /*----------- パスワードの妥当性を確認する ------------------------------------\r
2563 *\r
2564 *       Parameter\r
2565 *               char *Password: パスワード文字列\r
2566 *               char *HashStr: SHA-1ハッシュ文字列\r
2567 *\r
2568 *       Return Value\r
2569 *               int 0 不一致\r
2570 *                       1: 一致\r
2571 *                       2: 異常\r
2572 *----------------------------------------------------------------------------*/\r
2573 int CheckPasswordValidity( char* Password, int length, const char* HashStr )\r
2574 {\r
2575         ulong hash1[5];\r
2576         ulong hash2[5];\r
2577         \r
2578         int i, j;\r
2579         \r
2580         const char* p = HashStr;\r
2581         \r
2582         /* 空文字列は一致したことにする */\r
2583         if( HashStr[0] == NUL ) return 1;\r
2584 \r
2585         /* Hashをチェックするする*/\r
2586         if( strlen(HashStr) != 40 )     return 2;\r
2587 \r
2588         /* Hashをデコードする*/\r
2589         for( i = 0; i < 5; i++ ){\r
2590                 ulong decode = 0;\r
2591                 for( j = 0; j < 8; j++ ){\r
2592                         if( *p < 0x40 || 0x40 + 15 < *p ){\r
2593                                 return 2;\r
2594                         }\r
2595                         decode = (decode << 4 ) + (*p - 0x40);\r
2596                         ++p;\r
2597                 }\r
2598                 hash1[i] = decode;\r
2599         }\r
2600         \r
2601         /* Password をハッシュする */\r
2602         sha_memory( Password, length, hash2 );\r
2603         \r
2604         if( memcmp( (char*)hash1, (char*)hash2, sizeof( hash1 )) == 0 ){\r
2605                 return 1;\r
2606         }\r
2607         return 0;\r
2608 }\r
2609 \r
2610 /*----------- パスワードの妥当性チェックのための文字列を作成する ------------\r
2611 *\r
2612 *       Parameter\r
2613 *               char *Password: パスワード文字列\r
2614 *               char *Str: SHA-1ハッシュ文字列格納場所 (41bytes以上)\r
2615 *\r
2616 *       Return Value\r
2617 *               None\r
2618 *----------------------------------------------------------------------------*/\r
2619 void CreatePasswordHash( char* Password, int length, char* HashStr )\r
2620 {\r
2621         ulong hash[5];\r
2622         int i, j;\r
2623         unsigned char *p = (unsigned char *)HashStr;\r
2624 \r
2625         sha_memory( Password, length, hash );\r
2626 \r
2627         for( i = 0; i < 5; i++ ){\r
2628                 ulong rest = hash[i];\r
2629                 for( j = 0; j < 8; j++ ){\r
2630                         *p++ = (unsigned char)((rest & 0xf0000000) >> 28) + '@';\r
2631                         rest <<= 4;\r
2632                 }\r
2633         }\r
2634         *p = NUL;\r
2635 }\r
2636 \r
2637 void SetHashSalt( DWORD salt )\r
2638 {\r
2639         unsigned char* pos = &SecretKey[strlen(SecretKey) + 1];\r
2640         *pos++ = ( salt >> 24 ) & 0xff;\r
2641         *pos++ = ( salt >> 16 ) & 0xff;\r
2642         *pos++ = ( salt >>  8 ) & 0xff;\r
2643         *pos++ = ( salt       ) & 0xff;\r
2644         \r
2645         SecretKeyLength = strlen( SecretKey ) + 5;\r
2646 }\r
2647 \r
2648 /*----------- 乱数生成をする -------------------------------------------------\r
2649 *\r
2650 *       Parameter\r
2651 *\r
2652 *       Return Value\r
2653 *               ランダムな値:コンパイラVS2005/動作環境WinXP以上では rand_s から取得する\r
2654 *----------------------------------------------------------------------------*/\r
2655 DWORD GetRandamDWRODValue(void)\r
2656 {\r
2657         DWORD rndValue;\r
2658         int errorCode;\r
2659 #ifdef _CRT_RAND_S\r
2660         errno_t errnoRand_s;\r
2661         errnoRand_s = rand_s(&rndValue);\r
2662         errorCode = (0 != errnoRand_s ? 1 : 0);\r
2663 #else\r
2664         errorCode = 1;\r
2665 #endif\r
2666         if(0 != errorCode){\r
2667 #ifdef USE_RANDAM_C_RAND\r
2668                 rndValue = rand() | (rand() << 16);\r
2669 #else\r
2670                 /* rand() のかわりに、SHA-1とパフォーマンスカウンタを用いる */\r
2671                 ulong shaValue[5];\r
2672                 LARGE_INTEGER Counter;\r
2673                 \r
2674                 if(0 == IsRndSourceInit){\r
2675                         /* 初回取得時 */\r
2676                         HANDLE CurProcHandle;\r
2677                         HANDLE CurThreadHandle;\r
2678                         \r
2679                         if(DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),\r
2680                                 &CurProcHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))\r
2681                         {\r
2682                                 CloseHandle(CurProcHandle);\r
2683                         }\r
2684                         if(DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(),\r
2685                                 &CurThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))\r
2686                         {\r
2687                                 CloseHandle(CurThreadHandle);\r
2688                         }\r
2689                         \r
2690                         /* _WIN64 では64bitだが、その場合はrand_sが大抵利用可能なのでここでは32bitのみ用いる */\r
2691                         RndSource[0] = (ulong)CurProcHandle;\r
2692                         RndSource[1] = (ulong)CurThreadHandle;\r
2693                         RndSource[2] = (ulong)GetTickCount();\r
2694                         RndSource[3] = (ulong)timeGetTime();\r
2695                         RndSource[4] = 0; /* カウントアップ */\r
2696                         RndSource[5] = RndSource[3] + 1;\r
2697                         IsRndSourceInit = 1;\r
2698                 }\r
2699                 RndSource[4]++;\r
2700                 RndSource[5] += 0x00010010;\r
2701                 if(QueryPerformanceCounter(&Counter)){\r
2702                         RndSource[6] = Counter.LowPart;\r
2703                         RndSource[7] = Counter.HighPart;\r
2704                         RndSource[8] = (ulong)rand();\r
2705                 }else{\r
2706                         RndSource[6] = (ulong)timeGetTime();\r
2707                         RndSource[7] = (ulong)rand();\r
2708                         RndSource[8] = (ulong)rand();\r
2709                 }\r
2710                 \r
2711                 sha_memory((char *)RndSource, sizeof(RndSource), shaValue);\r
2712                 rndValue = shaValue[0] ^ shaValue[1] ^ shaValue[2] ^ shaValue[3] ^ shaValue[4];\r
2713 #endif\r
2714         }\r
2715         return rndValue;\r
2716 }\r