FFFTPのソースコードです。
Revision | 4fe3b8c6631b7c5862b657c7425af7696a6487b7 (tree) |
---|---|
Time | 2014-06-15 19:04:33 |
Author | s_kawamoto <s_kawamoto@user...> |
Commiter | s_kawamoto |
Add routines for creating files for software update.
@@ -305,98 +305,85 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi | ||
305 | 305 | MSG Msg; |
306 | 306 | int Ret; |
307 | 307 | BOOL Sts; |
308 | + // プロセス保護 | |
309 | + char* pCommand; | |
310 | + DWORD ProtectLevel; | |
311 | + char Option[FMAX_PATH+1]; | |
308 | 312 | // ソフトウェア自動更新 |
313 | + int ImmediateExit; | |
314 | + char PrivateKeyFile[FMAX_PATH+1]; | |
315 | + char Password[FMAX_PATH+1]; | |
316 | + char ServerPath[FMAX_PATH+1]; | |
317 | + char HashFile[FMAX_PATH+1]; | |
318 | + char ListFile[FMAX_PATH+1]; | |
319 | + char Description[FMAX_PATH+1]; | |
309 | 320 | char UpdateDir[FMAX_PATH+1]; |
310 | 321 | char Path[FMAX_PATH+1]; |
311 | 322 | char Command[FMAX_PATH+1]; |
312 | 323 | char* p; |
313 | 324 | |
314 | - // プロセス保護 | |
315 | 325 | #ifdef ENABLE_PROCESS_PROTECTION |
326 | + ProtectLevel = PROCESS_PROTECTION_NONE; | |
327 | + pCommand = lpszCmdLine; | |
328 | + while(pCommand = GetToken(pCommand, Option)) | |
316 | 329 | { |
317 | - DWORD ProtectLevel; | |
318 | - char* pCommand; | |
319 | - char Option[FMAX_PATH+1]; | |
320 | - ProtectLevel = PROCESS_PROTECTION_NONE; | |
321 | - pCommand = lpszCmdLine; | |
322 | - while(pCommand = GetToken(pCommand, Option)) | |
330 | + if(Option[0] == '-') | |
323 | 331 | { |
324 | - if(Option[0] == '-') | |
332 | + if(strcmp(&Option[1], "-protect") == 0) | |
325 | 333 | { |
326 | - if(strcmp(&Option[1], "-protect") == 0) | |
327 | - { | |
328 | - ProtectLevel = PROCESS_PROTECTION_DEFAULT; | |
329 | - break; | |
330 | - } | |
331 | - else if(strcmp(&Option[1], "-protect-high") == 0) | |
332 | - { | |
333 | - ProtectLevel = PROCESS_PROTECTION_HIGH; | |
334 | - break; | |
335 | - } | |
336 | - else if(strcmp(&Option[1], "-protect-medium") == 0) | |
337 | - { | |
338 | - ProtectLevel = PROCESS_PROTECTION_MEDIUM; | |
339 | - break; | |
340 | - } | |
341 | - else if(strcmp(&Option[1], "-protect-low") == 0) | |
342 | - { | |
343 | - ProtectLevel = PROCESS_PROTECTION_LOW; | |
344 | - break; | |
345 | - } | |
334 | + ProtectLevel = PROCESS_PROTECTION_DEFAULT; | |
335 | + break; | |
346 | 336 | } |
347 | - } | |
348 | - if(ProtectLevel != PROCESS_PROTECTION_NONE) | |
349 | - { | |
350 | - SetProcessProtectionLevel(ProtectLevel); | |
351 | - if(!InitializeLoadLibraryHook()) | |
337 | + else if(strcmp(&Option[1], "-protect-high") == 0) | |
352 | 338 | { |
353 | - MessageBox(NULL, MSGJPN321, "FFFTP", MB_OK | MB_ICONERROR); | |
354 | - return 0; | |
339 | + ProtectLevel = PROCESS_PROTECTION_HIGH; | |
340 | + break; | |
355 | 341 | } |
356 | -#ifndef _DEBUG | |
357 | - if(IsDebuggerPresent()) | |
342 | + else if(strcmp(&Option[1], "-protect-medium") == 0) | |
358 | 343 | { |
359 | - MessageBox(NULL, MSGJPN322, "FFFTP", MB_OK | MB_ICONERROR); | |
360 | - return 0; | |
344 | + ProtectLevel = PROCESS_PROTECTION_MEDIUM; | |
345 | + break; | |
361 | 346 | } |
362 | -#endif | |
363 | - if(!UnloadUntrustedModule()) | |
347 | + else if(strcmp(&Option[1], "-protect-low") == 0) | |
364 | 348 | { |
365 | - MessageBox(NULL, MSGJPN323, "FFFTP", MB_OK | MB_ICONERROR); | |
366 | - return 0; | |
349 | + ProtectLevel = PROCESS_PROTECTION_LOW; | |
350 | + break; | |
367 | 351 | } |
352 | + } | |
353 | + } | |
354 | + if(ProtectLevel != PROCESS_PROTECTION_NONE) | |
355 | + { | |
356 | + SetProcessProtectionLevel(ProtectLevel); | |
357 | + if(!InitializeLoadLibraryHook()) | |
358 | + { | |
359 | + MessageBox(NULL, MSGJPN321, "FFFTP", MB_OK | MB_ICONERROR); | |
360 | + return 0; | |
361 | + } | |
368 | 362 | #ifndef _DEBUG |
369 | - if(RestartProtectedProcess(" --restart")) | |
370 | - return 0; | |
363 | + if(IsDebuggerPresent()) | |
364 | + { | |
365 | + MessageBox(NULL, MSGJPN322, "FFFTP", MB_OK | MB_ICONERROR); | |
366 | + return 0; | |
367 | + } | |
371 | 368 | #endif |
372 | - if(!EnableLoadLibraryHook(TRUE)) | |
373 | - { | |
374 | - MessageBox(NULL, MSGJPN324, "FFFTP", MB_OK | MB_ICONERROR); | |
375 | - return 0; | |
376 | - } | |
369 | + if(!UnloadUntrustedModule()) | |
370 | + { | |
371 | + MessageBox(NULL, MSGJPN323, "FFFTP", MB_OK | MB_ICONERROR); | |
372 | + return 0; | |
377 | 373 | } |
378 | - else | |
379 | - InitializeLoadLibraryHook(); | |
380 | - } | |
374 | +#ifndef _DEBUG | |
375 | + if(RestartProtectedProcess(" --restart")) | |
376 | + return 0; | |
381 | 377 | #endif |
382 | - | |
383 | - // ソフトウェア自動更新 | |
384 | - if(GetTokenAfterOption(lpszCmdLine, UpdateDir, "-software-update", "-software-update")) | |
385 | - { | |
386 | - if(!RestartUpdateProcessAsAdministrator(lpszCmdLine, " --restart")) | |
378 | + if(!EnableLoadLibraryHook(TRUE)) | |
387 | 379 | { |
388 | - Sleep(1000); | |
389 | - if(ApplyUpdates(UpdateDir, "updatebackup")) | |
390 | - MessageBox(NULL, MSGJPN359, "FFFTP", MB_OK); | |
391 | - else | |
392 | - MessageBox(NULL, MSGJPN360, "FFFTP", MB_OK | MB_ICONERROR); | |
380 | + MessageBox(NULL, MSGJPN324, "FFFTP", MB_OK | MB_ICONERROR); | |
381 | + return 0; | |
393 | 382 | } |
394 | - return 0; | |
395 | - } | |
396 | - else if(GetTokenAfterOption(lpszCmdLine, UpdateDir, "-software-cleanup", "-software-cleanup")) | |
397 | - { | |
398 | - CleanupUpdates(UpdateDir); | |
399 | 383 | } |
384 | + else | |
385 | + InitializeLoadLibraryHook(); | |
386 | +#endif | |
400 | 387 | |
401 | 388 | // マルチコアCPUの特定環境下でファイル通信中にクラッシュするバグ対策 |
402 | 389 | #ifdef DISABLE_MULTI_CPUS |
@@ -429,10 +416,66 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi | ||
429 | 416 | // SFTP対応 |
430 | 417 | LoadPuTTY(); |
431 | 418 | |
419 | + // ソフトウェア自動更新 | |
420 | + ImmediateExit = NO; | |
421 | + pCommand = lpszCmdLine; | |
422 | + while(pCommand = GetToken(pCommand, Option)) | |
423 | + { | |
424 | + if(Option[0] == '-') | |
425 | + { | |
426 | + if(strcmp(&Option[1], "-build-software-update") == 0) | |
427 | + { | |
428 | + if(pCommand = GetToken(pCommand, PrivateKeyFile)) | |
429 | + { | |
430 | + if(pCommand = GetToken(pCommand, Password)) | |
431 | + { | |
432 | + if(pCommand = GetToken(pCommand, ServerPath)) | |
433 | + { | |
434 | + if(pCommand = GetToken(pCommand, HashFile)) | |
435 | + { | |
436 | + if(pCommand = GetToken(pCommand, ListFile)) | |
437 | + { | |
438 | + if(pCommand = GetToken(pCommand, Description)) | |
439 | + BuildUpdates(PrivateKeyFile, Password, ServerPath, HashFile, ListFile, RELEASE_VERSION_NUM, VER_STR, Description); | |
440 | + } | |
441 | + } | |
442 | + } | |
443 | + } | |
444 | + } | |
445 | + ImmediateExit = YES; | |
446 | + break; | |
447 | + } | |
448 | + else if(strcmp(&Option[1], "-software-update") == 0) | |
449 | + { | |
450 | + if(pCommand = GetToken(pCommand, UpdateDir)) | |
451 | + { | |
452 | + if(!RestartUpdateProcessAsAdministrator(lpszCmdLine, " --restart")) | |
453 | + { | |
454 | + Sleep(1000); | |
455 | + if(ApplyUpdates(UpdateDir, "updatebackup")) | |
456 | + MessageBox(NULL, MSGJPN359, "FFFTP", MB_OK); | |
457 | + else | |
458 | + MessageBox(NULL, MSGJPN360, "FFFTP", MB_OK | MB_ICONERROR); | |
459 | + } | |
460 | + } | |
461 | + ImmediateExit = YES; | |
462 | + break; | |
463 | + } | |
464 | + else if(strcmp(&Option[1], "-software-cleanup") == 0) | |
465 | + { | |
466 | + if(pCommand = GetToken(pCommand, UpdateDir)) | |
467 | + CleanupUpdates(UpdateDir); | |
468 | + break; | |
469 | + } | |
470 | + } | |
471 | + } | |
472 | + | |
432 | 473 | Ret = FALSE; |
433 | 474 | hWndFtp = NULL; |
434 | 475 | hInstFtp = hInstance; |
435 | - if(InitApp(lpszCmdLine, cmdShow) == FFFTP_SUCCESS) | |
476 | + // ソフトウェア自動更新 | |
477 | +// if(InitApp(lpszCmdLine, cmdShow) == FFFTP_SUCCESS) | |
478 | + if(ImmediateExit == NO && InitApp(lpszCmdLine, cmdShow) == FFFTP_SUCCESS) | |
436 | 479 | { |
437 | 480 | for(;;) |
438 | 481 | { |
@@ -2166,6 +2209,8 @@ static int AnalyzeComLine(char *Str, int *AutoConnect, int *CmdOption, char *unc | ||
2166 | 2209 | { |
2167 | 2210 | int Ret; |
2168 | 2211 | char Tmp[FMAX_PATH+1]; |
2212 | + // ソフトウェア自動更新 | |
2213 | + int i; | |
2169 | 2214 | |
2170 | 2215 | *AutoConnect = -1; |
2171 | 2216 | *CmdOption = 0; |
@@ -2292,6 +2337,17 @@ static int AnalyzeComLine(char *Str, int *AutoConnect, int *CmdOption, char *unc | ||
2292 | 2337 | else if((strcmp(&Tmp[1], "u8n") == 0) || (strcmp(&Tmp[1], "-utf8name") == 0)) |
2293 | 2338 | *CmdOption |= OPT_UTF8N_NAME; |
2294 | 2339 | // ソフトウェア自動更新 |
2340 | + else if(strcmp(&Tmp[1], "-build-software-update") == 0) | |
2341 | + { | |
2342 | + for(i = 0; i < 6; i++) | |
2343 | + { | |
2344 | + if((Str = GetToken(Str, Tmp)) == NULL) | |
2345 | + { | |
2346 | + Ret = -1; | |
2347 | + break; | |
2348 | + } | |
2349 | + } | |
2350 | + } | |
2295 | 2351 | else if(strcmp(&Tmp[1], "-software-update") == 0) |
2296 | 2352 | { |
2297 | 2353 | if((Str = GetToken(Str, Tmp)) == NULL) |
@@ -3650,7 +3706,8 @@ void UpdateSoftware(int Async, int NoError, int NoConfirm) | ||
3650 | 3706 | UPDATESOFTWAREDATA* pData; |
3651 | 3707 | DWORD Version; |
3652 | 3708 | char VersionString[32]; |
3653 | - char Tmp[FMAX_PATH+1]; | |
3709 | + char Description[1024]; | |
3710 | + char Tmp[2048]; | |
3654 | 3711 | if(Async == YES) |
3655 | 3712 | { |
3656 | 3713 | if(pData = malloc(sizeof(UPDATESOFTWAREDATA))) |
@@ -3667,18 +3724,18 @@ void UpdateSoftware(int Async, int NoError, int NoConfirm) | ||
3667 | 3724 | { |
3668 | 3725 | Version = RELEASE_VERSION_NUM; |
3669 | 3726 | LastAutoCheckForUpdates = time(NULL); |
3670 | - if(CheckForUpdates(FALSE, NULL, &Version, VersionString)) | |
3727 | + if(CheckForUpdates(FALSE, NULL, &Version, VersionString, Description)) | |
3671 | 3728 | { |
3672 | 3729 | if(Version > RELEASE_VERSION_NUM) |
3673 | 3730 | { |
3674 | - sprintf(Tmp, MSGJPN362, VER_STR, VersionString); | |
3731 | + sprintf(Tmp, MSGJPN362, VER_STR, VersionString, Description); | |
3675 | 3732 | if(NoConfirm == YES || MessageBox(GetMainHwnd(), Tmp, "FFFTP", MB_YESNO) == IDYES) |
3676 | 3733 | { |
3677 | 3734 | strcpy(Tmp, TmpPath); |
3678 | 3735 | SetYenTail(Tmp); |
3679 | 3736 | strcat(Tmp, "update"); |
3680 | 3737 | _mkdir(Tmp); |
3681 | - if(CheckForUpdates(TRUE, Tmp, &Version, VersionString)) | |
3738 | + if(CheckForUpdates(TRUE, Tmp, &Version, VersionString, Description)) | |
3682 | 3739 | { |
3683 | 3740 | MessageBox(GetMainHwnd(), MSGJPN365, "FFFTP", MB_OK); |
3684 | 3741 | ApplyUpdatesOnExit = YES; |
@@ -360,7 +360,7 @@ | ||
360 | 360 | #define MSGJPN359 _Tu8("Software update has been completed.", "Software update has been completed.") |
361 | 361 | #define MSGJPN360 _Tu8("Failed to update the software.\nPlease get the latest version from our web site and update it manually.", "Failed to update the software.\nPlease get the latest version from our web site and update it manually.") |
362 | 362 | #define MSGJPN361 _Tu8("Updates", "Updates") |
363 | -#define MSGJPN362 _Tu8("There is a new version.\n\nCurrent version: %s\nNew version: %s\n\nIt takes a few minutes to download the updates.\nDo you want to update now?\n", "There is a new version.\n\nCurrent version: %s\nNew version: %s\n\nIt takes a few minutes to download the updates.\nDo you want to update now?\n") | |
363 | +#define MSGJPN362 _Tu8("There is a new version.\n\nCurrent version: %s\nNew version: %s\n%s\n\nIt takes a few minutes to download the updates.\nDo you want to update now?\n", "There is a new version.\n\nCurrent version: %s\nNew version: %s\n%s\n\nIt takes a few minutes to download the updates.\nDo you want to update now?\n") | |
364 | 364 | #define MSGJPN363 _Tu8("Failed to update the software.\nCannot connect to the server or the data is corrupted.", "Failed to update the software.\nCannot connect to the server or the data is corrupted.") |
365 | 365 | #define MSGJPN364 _Tu8("Your version is already up-to-date.", "Your version is already up-to-date.") |
366 | 366 | #define MSGJPN365 _Tu8("Preparing for the software update has been completed.\nIt will be applied on exit.", "Preparing for the software update has been completed.\nIt will be applied on exit.") |
@@ -360,7 +360,7 @@ | ||
360 | 360 | #define MSGJPN359 _Tu8("ソフトウェアの更新が完了しました.", "\xE3\x82\xBD\xE3\x83\x95\xE3\x83\x88\xE3\x82\xA6\xE3\x82\xA7\xE3\x82\xA2\xE3\x81\xAE\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\x8C\xE5\xAE\x8C\xE4\xBA\x86\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F.") |
361 | 361 | #define MSGJPN360 _Tu8("ソフトウェアの更新に失敗しました.\nWebサイトから最新版を入手して手動で更新してください.", "\xE3\x82\xBD\xE3\x83\x95\xE3\x83\x88\xE3\x82\xA6\xE3\x82\xA7\xE3\x82\xA2\xE3\x81\xAE\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F.\nWeb\xE3\x82\xB5\xE3\x82\xA4\xE3\x83\x88\xE3\x81\x8B\xE3\x82\x89\xE6\x9C\x80\xE6\x96\xB0\xE7\x89\x88\xE3\x82\x92\xE5\x85\xA5\xE6\x89\x8B\xE3\x81\x97\xE3\x81\xA6\xE6\x89\x8B\xE5\x8B\x95\xE3\x81\xA7\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x8F\xE3\x81\xA0\xE3\x81\x95\xE3\x81\x84.") |
362 | 362 | #define MSGJPN361 _Tu8("更新", "\xE6\x9B\xB4\xE6\x96\xB0") |
363 | -#define MSGJPN362 _Tu8("新しいバージョンがあります.\n\n現在のバージョン: %s\n新しいバージョン: %s\n\n更新のダウンロードには数分間かかります.\n今すぐ更新しますか.", "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3\x83\xB3\xE3\x81\x8C\xE3\x81\x82\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x99.\n\n\xE7\x8F\xBE\xE5\x9C\xA8\xE3\x81\xAE\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3\x83\xB3: %s\n\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3\x83\xB3: %s\n\n\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\xAE\xE3\x83\x80\xE3\x82\xA6\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xAB\xE3\x81\xAF\xE6\x95\xB0\xE5\x88\x86\xE9\x96\x93\xE3\x81\x8B\xE3\x81\x8B\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x99.\n\xE4\xBB\x8A\xE3\x81\x99\xE3\x81\x90\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x99\xE3\x81\x8B.") | |
363 | +#define MSGJPN362 _Tu8("新しいバージョンがあります.\n\n現在のバージョン: %s\n新しいバージョン: %s\n%s\n\n更新のダウンロードには数分間かかります.\n今すぐ更新しますか.", "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3\x83\xB3\xE3\x81\x8C\xE3\x81\x82\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x99.\n\n\xE7\x8F\xBE\xE5\x9C\xA8\xE3\x81\xAE\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3\x83\xB3: %s\n\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3\x83\xB3: %s\n%s\n\n\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\xAE\xE3\x83\x80\xE3\x82\xA6\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xAB\xE3\x81\xAF\xE6\x95\xB0\xE5\x88\x86\xE9\x96\x93\xE3\x81\x8B\xE3\x81\x8B\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x99.\n\xE4\xBB\x8A\xE3\x81\x99\xE3\x81\x90\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x99\xE3\x81\x8B.") | |
364 | 364 | #define MSGJPN363 _Tu8("ソフトウェアの更新に失敗しました.\nサーバーに接続できないかデータが破損しています.", "\xE3\x82\xBD\xE3\x83\x95\xE3\x83\x88\xE3\x82\xA6\xE3\x82\xA7\xE3\x82\xA2\xE3\x81\xAE\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F.\n\xE3\x82\xB5\xE3\x83\xBC\xE3\x83\x90\xE3\x83\xBC\xE3\x81\xAB\xE6\x8E\xA5\xE7\xB6\x9A\xE3\x81\xA7\xE3\x81\x8D\xE3\x81\xAA\xE3\x81\x84\xE3\x81\x8B\xE3\x83\x87\xE3\x83\xBC\xE3\x82\xBF\xE3\x81\x8C\xE7\xA0\xB4\xE6\x90\x8D\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x84\xE3\x81\xBE\xE3\x81\x99.") |
365 | 365 | #define MSGJPN364 _Tu8("お使いのバージョンはすでに最新です.", "\xE3\x81\x8A\xE4\xBD\xBF\xE3\x81\x84\xE3\x81\xAE\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3\x83\xB3\xE3\x81\xAF\xE3\x81\x99\xE3\x81\xA7\xE3\x81\xAB\xE6\x9C\x80\xE6\x96\xB0\xE3\x81\xA7\xE3\x81\x99.") |
366 | 366 | #define MSGJPN365 _Tu8("ソフトウェアの更新の準備が完了しました.\nFFFTPの終了時に更新が適用されます.", "\xE3\x82\xBD\xE3\x83\x95\xE3\x83\x88\xE3\x82\xA6\xE3\x82\xA7\xE3\x82\xA2\xE3\x81\xAE\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\xAE\xE6\xBA\x96\xE5\x82\x99\xE3\x81\x8C\xE5\xAE\x8C\xE4\xBA\x86\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F.\nFFFTP\xE3\x81\xAE\xE7\xB5\x82\xE4\xBA\x86\xE6\x99\x82\xE3\x81\xAB\xE6\x9B\xB4\xE6\x96\xB0\xE3\x81\x8C\xE9\x81\xA9\xE7\x94\xA8\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x99.") |
@@ -52,6 +52,7 @@ typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long) | ||
52 | 52 | typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*); |
53 | 53 | typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long); |
54 | 54 | typedef void (__cdecl* _X509_CRL_free)(X509_CRL*); |
55 | +typedef EVP_PKEY* (__cdecl* _PEM_read_bio_PrivateKey)(BIO*, EVP_PKEY**, pem_password_cb*, void*); | |
55 | 56 | typedef EVP_PKEY* (__cdecl* _PEM_read_bio_PUBKEY)(BIO*, EVP_PKEY**, pem_password_cb*, void*); |
56 | 57 | typedef X509* (__cdecl* _PEM_read_bio_X509)(BIO*, X509**, pem_password_cb*, void*); |
57 | 58 | typedef X509_CRL* (__cdecl* _PEM_read_bio_X509_CRL)(BIO*, X509_CRL**, pem_password_cb*, void*); |
@@ -61,6 +62,7 @@ typedef void (__cdecl* _EVP_PKEY_free)(EVP_PKEY*); | ||
61 | 62 | typedef RSA* (__cdecl* _EVP_PKEY_get1_RSA)(EVP_PKEY*); |
62 | 63 | typedef void (__cdecl* _RSA_free)(RSA*); |
63 | 64 | typedef int (__cdecl* _RSA_size)(const RSA*); |
65 | +typedef int (__cdecl* _RSA_private_encrypt)(int, const unsigned char*, unsigned char*, RSA*, int); | |
64 | 66 | typedef int (__cdecl* _RSA_public_decrypt)(int, const unsigned char*, unsigned char*, RSA*, int); |
65 | 67 | typedef unsigned char* (__cdecl* _SHA1)(const unsigned char*, size_t, unsigned char*); |
66 | 68 | typedef unsigned char* (__cdecl* _SHA224)(const unsigned char*, size_t, unsigned char*); |
@@ -102,6 +104,7 @@ _X509_print_ex p_X509_print_ex; | ||
102 | 104 | _X509_get_subject_name p_X509_get_subject_name; |
103 | 105 | _X509_NAME_print_ex p_X509_NAME_print_ex; |
104 | 106 | _X509_CRL_free p_X509_CRL_free; |
107 | +_PEM_read_bio_PrivateKey p_PEM_read_bio_PrivateKey; | |
105 | 108 | _PEM_read_bio_PUBKEY p_PEM_read_bio_PUBKEY; |
106 | 109 | _PEM_read_bio_X509 p_PEM_read_bio_X509; |
107 | 110 | _PEM_read_bio_X509_CRL p_PEM_read_bio_X509_CRL; |
@@ -111,6 +114,7 @@ _EVP_PKEY_free p_EVP_PKEY_free; | ||
111 | 114 | _EVP_PKEY_get1_RSA p_EVP_PKEY_get1_RSA; |
112 | 115 | _RSA_free p_RSA_free; |
113 | 116 | _RSA_size p_RSA_size; |
117 | +_RSA_private_encrypt p_RSA_private_encrypt; | |
114 | 118 | _RSA_public_decrypt p_RSA_public_decrypt; |
115 | 119 | _SHA1 p_SHA1; |
116 | 120 | _SHA224 p_SHA224; |
@@ -207,6 +211,7 @@ BOOL LoadOpenSSL() | ||
207 | 211 | || !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name")) |
208 | 212 | || !(p_X509_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex")) |
209 | 213 | || !(p_X509_CRL_free = (_X509_CRL_free)GetProcAddress(g_hOpenSSLCommon, "X509_CRL_free")) |
214 | + || !(p_PEM_read_bio_PrivateKey = (_PEM_read_bio_PrivateKey)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_PrivateKey")) | |
210 | 215 | || !(p_PEM_read_bio_PUBKEY = (_PEM_read_bio_PUBKEY)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_PUBKEY")) |
211 | 216 | || !(p_PEM_read_bio_X509 = (_PEM_read_bio_X509)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_X509")) |
212 | 217 | || !(p_PEM_read_bio_X509_CRL = (_PEM_read_bio_X509_CRL)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_X509_CRL")) |
@@ -216,6 +221,7 @@ BOOL LoadOpenSSL() | ||
216 | 221 | || !(p_EVP_PKEY_get1_RSA = (_EVP_PKEY_get1_RSA)GetProcAddress(g_hOpenSSLCommon, "EVP_PKEY_get1_RSA")) |
217 | 222 | || !(p_RSA_free = (_RSA_free)GetProcAddress(g_hOpenSSLCommon, "RSA_free")) |
218 | 223 | || !(p_RSA_size = (_RSA_size)GetProcAddress(g_hOpenSSLCommon, "RSA_size")) |
224 | + || !(p_RSA_private_encrypt = (_RSA_private_encrypt)GetProcAddress(g_hOpenSSLCommon, "RSA_private_encrypt")) | |
219 | 225 | || !(p_RSA_public_decrypt = (_RSA_public_decrypt)GetProcAddress(g_hOpenSSLCommon, "RSA_public_decrypt")) |
220 | 226 | || !(p_SHA1 = (_SHA1)GetProcAddress(g_hOpenSSLCommon, "SHA1")) |
221 | 227 | || !(p_SHA224 = (_SHA224)GetProcAddress(g_hOpenSSLCommon, "SHA224")) |
@@ -536,9 +542,47 @@ BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName) | ||
536 | 542 | return bResult; |
537 | 543 | } |
538 | 544 | |
545 | +#pragma warning(push) | |
546 | +#pragma warning(disable:4090) | |
547 | + | |
548 | +// RSA暗号化 | |
549 | +BOOL EncryptSignature(const char* PrivateKey, const char* Password, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength) | |
550 | +{ | |
551 | + BOOL bResult; | |
552 | + BIO* pBIO; | |
553 | + EVP_PKEY* pPKEY; | |
554 | + RSA* pRSA; | |
555 | + int i; | |
556 | + if(!g_bOpenSSLLoaded) | |
557 | + return FALSE; | |
558 | + bResult = FALSE; | |
559 | + if(pBIO = p_BIO_new_mem_buf((void*)PrivateKey, sizeof(char) * strlen(PrivateKey))) | |
560 | + { | |
561 | + if(pPKEY = p_PEM_read_bio_PrivateKey(pBIO, NULL, NULL, (void*)Password)) | |
562 | + { | |
563 | + if(pRSA = p_EVP_PKEY_get1_RSA(pPKEY)) | |
564 | + { | |
565 | + if(p_RSA_size(pRSA) <= (int)OutLength) | |
566 | + { | |
567 | + i = p_RSA_private_encrypt((int)InLength, (const unsigned char*)pIn, (unsigned char*)pOut, pRSA, RSA_PKCS1_PADDING); | |
568 | + if(i >= 0) | |
569 | + { | |
570 | + *pOutLength = (DWORD)i; | |
571 | + bResult = TRUE; | |
572 | + } | |
573 | + } | |
574 | + p_RSA_free(pRSA); | |
575 | + } | |
576 | + p_EVP_PKEY_free(pPKEY); | |
577 | + } | |
578 | + p_BIO_free(pBIO); | |
579 | + } | |
580 | + return bResult; | |
581 | +} | |
582 | + | |
539 | 583 | // RSA復号化 |
540 | 584 | // 主に自動更新ファイルのハッシュの改竄確認 |
541 | -BOOL DecryptSignature(const char* PublicKey, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength) | |
585 | +BOOL DecryptSignature(const char* PublicKey, const char* Password, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength) | |
542 | 586 | { |
543 | 587 | BOOL bResult; |
544 | 588 | BIO* pBIO; |
@@ -550,7 +594,7 @@ BOOL DecryptSignature(const char* PublicKey, const void* pIn, DWORD InLength, vo | ||
550 | 594 | bResult = FALSE; |
551 | 595 | if(pBIO = p_BIO_new_mem_buf((void*)PublicKey, sizeof(char) * strlen(PublicKey))) |
552 | 596 | { |
553 | - if(pPKEY = p_PEM_read_bio_PUBKEY(pBIO, NULL, NULL, NULL)) | |
597 | + if(pPKEY = p_PEM_read_bio_PUBKEY(pBIO, NULL, NULL, Password)) | |
554 | 598 | { |
555 | 599 | if(pRSA = p_EVP_PKEY_get1_RSA(pPKEY)) |
556 | 600 | { |
@@ -572,6 +616,8 @@ BOOL DecryptSignature(const char* PublicKey, const void* pIn, DWORD InLength, vo | ||
572 | 616 | return bResult; |
573 | 617 | } |
574 | 618 | |
619 | +#pragma warning(pop) | |
620 | + | |
575 | 621 | // ハッシュ計算 |
576 | 622 | // 他にも同等の関数はあるが主にマルウェア対策のための冗長化 |
577 | 623 | BOOL GetHashSHA1(const void* pData, DWORD Size, void* pHash) |
@@ -20,7 +20,8 @@ void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback); | ||
20 | 20 | void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback); |
21 | 21 | BOOL SetSSLRootCertificate(const void* pData, DWORD Length); |
22 | 22 | BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName); |
23 | -BOOL DecryptSignature(const char* PublicKey, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength); | |
23 | +BOOL EncryptSignature(const char* PrivateKey, const char* Password, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength); | |
24 | +BOOL DecryptSignature(const char* PublicKey, const char* Password, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength); | |
24 | 25 | BOOL GetHashSHA1(const void* pData, DWORD Size, void* pHash); |
25 | 26 | BOOL GetHashSHA224(const void* pData, DWORD Size, void* pHash); |
26 | 27 | BOOL GetHashSHA256(const void* pData, DWORD Size, void* pHash); |
@@ -37,6 +37,7 @@ typedef struct | ||
37 | 37 | { |
38 | 38 | DWORD Version; |
39 | 39 | CHAR VersionString[32]; |
40 | + CHAR Description[1024]; | |
40 | 41 | DWORD FileCount; |
41 | 42 | UPDATE_LIST_FILE File[1]; |
42 | 43 | } UPDATE_LIST; |
@@ -102,7 +103,12 @@ BOOL SaveMemoryToFileWithTimestamp(LPCTSTR FileName, void* pData, DWORD Size, FI | ||
102 | 103 | { |
103 | 104 | if(WriteFile(hFile, pData, Size, &Size, NULL)) |
104 | 105 | { |
105 | - if(SetFileTime(hFile, NULL, NULL, pTimestamp)) | |
106 | + if(pTimestamp) | |
107 | + { | |
108 | + if(SetFileTime(hFile, NULL, NULL, pTimestamp)) | |
109 | + bResult = TRUE; | |
110 | + } | |
111 | + else | |
106 | 112 | bResult = TRUE; |
107 | 113 | } |
108 | 114 | CloseHandle(hFile); |
@@ -110,6 +116,38 @@ BOOL SaveMemoryToFileWithTimestamp(LPCTSTR FileName, void* pData, DWORD Size, FI | ||
110 | 116 | return bResult; |
111 | 117 | } |
112 | 118 | |
119 | +BOOL LoadMemoryFromFileWithTimestamp(LPCTSTR FileName, void* pData, DWORD Size, DWORD* pReadSize, FILETIME* pTimestamp) | |
120 | +{ | |
121 | + BOOL bResult; | |
122 | + HANDLE hFile; | |
123 | + LARGE_INTEGER li; | |
124 | + bResult = FALSE; | |
125 | + if((hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) | |
126 | + { | |
127 | + if(GetFileSizeEx(hFile, &li)) | |
128 | + { | |
129 | + if(li.QuadPart <= (LONGLONG)Size) | |
130 | + { | |
131 | + if(ReadFile(hFile, pData, Size, pReadSize, NULL)) | |
132 | + { | |
133 | + if(*pReadSize == li.LowPart) | |
134 | + { | |
135 | + if(pTimestamp) | |
136 | + { | |
137 | + if(GetFileTime(hFile, NULL, NULL, pTimestamp)) | |
138 | + bResult = TRUE; | |
139 | + } | |
140 | + else | |
141 | + bResult = TRUE; | |
142 | + } | |
143 | + } | |
144 | + } | |
145 | + CloseHandle(hFile); | |
146 | + } | |
147 | + } | |
148 | + return bResult; | |
149 | +} | |
150 | + | |
113 | 151 | BOOL CopyAllFilesInDirectory(LPCTSTR From, LPCTSTR To) |
114 | 152 | { |
115 | 153 | BOOL bResult; |
@@ -158,46 +196,189 @@ BOOL DeleteDirectoryAndContents(LPCTSTR Path) | ||
158 | 196 | return bResult; |
159 | 197 | } |
160 | 198 | |
199 | +DWORD ListUpdateFile(UPDATE_LIST* pList, DWORD MaxCount, LPCTSTR ServerPath, LPCTSTR ReferenceDir, LPCTSTR Path) | |
200 | +{ | |
201 | + DWORD Result; | |
202 | + TCHAR Temp1[MAX_PATH]; | |
203 | + TCHAR Temp2[MAX_PATH]; | |
204 | + TCHAR Temp3[MAX_PATH]; | |
205 | + HANDLE hFind; | |
206 | + WIN32_FIND_DATA Find; | |
207 | + void* pBuf; | |
208 | + DWORD Length; | |
209 | + FILETIME Time; | |
210 | + BYTE Hash[64]; | |
211 | + Result = 0; | |
212 | + if(!Path) | |
213 | + Path = _T(""); | |
214 | + if(_tcslen(ReferenceDir) + _tcslen(Path) + _tcslen(_T("\\*")) < MAX_PATH) | |
215 | + { | |
216 | + _tcscpy(Temp1, ReferenceDir); | |
217 | + _tcscat(Temp1, Path); | |
218 | + _tcscat(Temp1, _T("\\*")); | |
219 | + if((hFind = FindFirstFile(Temp1, &Find)) != INVALID_HANDLE_VALUE) | |
220 | + { | |
221 | + do | |
222 | + { | |
223 | + if(_tcscmp(Find.cFileName, _T(".")) != 0 && _tcscmp(Find.cFileName, _T("..")) != 0) | |
224 | + { | |
225 | + if(_tcslen(ServerPath) + _tcslen(_T("/")) + _tcslen(Find.cFileName) < 128 && _tcslen(Path) + _tcslen(_T("\\")) + _tcslen(Find.cFileName) < 128) | |
226 | + { | |
227 | + _tcscpy(Temp1, ServerPath); | |
228 | + _tcscat(Temp1, _T("/")); | |
229 | + _tcscat(Temp1, Find.cFileName); | |
230 | + _tcscpy(Temp2, Path); | |
231 | + _tcscat(Temp2, _T("\\")); | |
232 | + _tcscat(Temp2, Find.cFileName); | |
233 | + if(_tcslen(ReferenceDir) + _tcslen(Temp2) < MAX_PATH) | |
234 | + { | |
235 | + _tcscpy(Temp3, ReferenceDir); | |
236 | + _tcscat(Temp3, Temp2); | |
237 | + if((Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) | |
238 | + { | |
239 | + if(!(Find.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) | |
240 | + { | |
241 | + if(pList) | |
242 | + { | |
243 | + memset(&pList->File[pList->FileCount], 0, sizeof(UPDATE_LIST_FILE)); | |
244 | + pList->File[pList->FileCount].Flags = UPDATE_LIST_FILE_FLAG_DIRECTORY; | |
245 | + _tcscpy(pList->File[pList->FileCount].DstPath, Temp2); | |
246 | + pList->FileCount++; | |
247 | + } | |
248 | + Result++; | |
249 | + if(Result >= MaxCount) | |
250 | + break; | |
251 | + Result += ListUpdateFile(pList, MaxCount, Temp1, ReferenceDir, Temp2); | |
252 | + } | |
253 | + } | |
254 | + else | |
255 | + { | |
256 | + if(pList) | |
257 | + { | |
258 | + if(pBuf = malloc(16777216)) | |
259 | + { | |
260 | + if(LoadMemoryFromFileWithTimestamp(Temp3, pBuf, 16777216, &Length, &Time)) | |
261 | + { | |
262 | + if(GetHashSHA512(pBuf, Length, &Hash)) | |
263 | + { | |
264 | + memset(&pList->File[pList->FileCount], 0, sizeof(UPDATE_LIST_FILE)); | |
265 | + _tcscpy(pList->File[pList->FileCount].SrcPath, Temp1); | |
266 | + memcpy(&pList->File[pList->FileCount].SrcHash, &Hash, 64); | |
267 | + _tcscpy(pList->File[pList->FileCount].DstPath, Temp2); | |
268 | + pList->File[pList->FileCount].Timestamp = Time; | |
269 | + pList->FileCount++; | |
270 | + } | |
271 | + } | |
272 | + free(pBuf); | |
273 | + } | |
274 | + } | |
275 | + Result++; | |
276 | + if(Result >= MaxCount) | |
277 | + break; | |
278 | + } | |
279 | + } | |
280 | + } | |
281 | + } | |
282 | + } | |
283 | + while(FindNextFile(hFind, &Find)); | |
284 | + FindClose(hFind); | |
285 | + } | |
286 | + } | |
287 | + return Result; | |
288 | +} | |
289 | + | |
290 | +// FFFTPの更新情報を作成 | |
291 | +BOOL BuildUpdates(LPCTSTR PrivateKeyFile, LPCTSTR Password, LPCTSTR ServerPath, LPCTSTR HashFile, LPCTSTR ListFile, DWORD Version, LPCTSTR VersionString, LPCTSTR Description) | |
292 | +{ | |
293 | + BOOL bResult; | |
294 | + char PrivateKey[4096]; | |
295 | + DWORD Length; | |
296 | + TCHAR Name[MAX_PATH]; | |
297 | + TCHAR* p; | |
298 | + UPDATE_LIST* pList; | |
299 | + UPDATE_HASH Hash; | |
300 | + BYTE Buf[1024]; | |
301 | + bResult = FALSE; | |
302 | + memset(PrivateKey, 0, sizeof(PrivateKey)); | |
303 | + if(LoadMemoryFromFileWithTimestamp(PrivateKeyFile, &PrivateKey, sizeof(PrivateKey) - sizeof(char), &Length, NULL)) | |
304 | + { | |
305 | + if(GetModuleFileName(NULL, Name, MAX_PATH) > 0) | |
306 | + { | |
307 | + if(p = _tcsrchr(Name, _T('\\'))) | |
308 | + *p = _T('\0'); | |
309 | + if(pList = (UPDATE_LIST*)malloc(1048576)) | |
310 | + { | |
311 | + memset(pList, 0, 1048576); | |
312 | + pList->Version = Version; | |
313 | + _tcscpy(pList->VersionString, VersionString); | |
314 | + _tcscpy(pList->Description, Description); | |
315 | + ListUpdateFile(pList, (1048576 - sizeof(UPDATE_LIST)) / sizeof(UPDATE_LIST_FILE) + 1, ServerPath, Name, NULL); | |
316 | + Length = (pList->FileCount - 1) * sizeof(UPDATE_LIST_FILE) + sizeof(UPDATE_LIST); | |
317 | + if(SaveMemoryToFileWithTimestamp(ListFile, pList, Length, NULL)) | |
318 | + { | |
319 | + memcpy(&Hash.Signature, UPDATE_SIGNATURE, 64); | |
320 | + if(GetHashSHA512(pList, Length, &Hash.ListHash)) | |
321 | + { | |
322 | + if(EncryptSignature(PrivateKey, Password, &Hash, sizeof(UPDATE_HASH), &Buf, sizeof(Buf), &Length)) | |
323 | + { | |
324 | + if(SaveMemoryToFileWithTimestamp(HashFile, &Buf, Length, NULL)) | |
325 | + bResult = TRUE; | |
326 | + } | |
327 | + } | |
328 | + } | |
329 | + free(pList); | |
330 | + } | |
331 | + } | |
332 | + } | |
333 | + return bResult; | |
334 | +} | |
335 | + | |
161 | 336 | // FFFTPの更新情報を確認 |
162 | -BOOL CheckForUpdates(BOOL bDownload, LPCTSTR DownloadDir, DWORD* pVersion, LPTSTR pVersionString) | |
337 | +BOOL CheckForUpdates(BOOL bDownload, LPCTSTR DownloadDir, DWORD* pVersion, LPTSTR pVersionString, LPTSTR pDescription) | |
163 | 338 | { |
164 | 339 | BOOL bResult; |
165 | 340 | DWORD Length; |
166 | - BYTE Buf1[65536]; | |
341 | + BYTE Buf1[1024]; | |
167 | 342 | BYTE Buf2[1024]; |
343 | + void* pBuf; | |
168 | 344 | UPDATE_HASH UpdateHash; |
169 | 345 | BYTE Hash[64]; |
170 | 346 | UPDATE_LIST* pUpdateList; |
171 | 347 | bResult = FALSE; |
172 | 348 | if(ReadFileViaHTTP(&Buf1, sizeof(Buf1), &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_HASH_PATH)) |
173 | 349 | { |
174 | - if(DecryptSignature(UPDATE_RSA_PUBLIC_KEY, &Buf1, Length, &Buf2, sizeof(Buf2), &Length)) | |
350 | + if(DecryptSignature(UPDATE_RSA_PUBLIC_KEY, NULL, &Buf1, Length, &Buf2, sizeof(Buf2), &Length)) | |
175 | 351 | { |
176 | 352 | if(Length == sizeof(UPDATE_HASH)) |
177 | 353 | { |
178 | 354 | memcpy(&UpdateHash, &Buf2, sizeof(UPDATE_HASH)); |
179 | 355 | if(memcmp(&UpdateHash.Signature, UPDATE_SIGNATURE, 64) == 0) |
180 | 356 | { |
181 | - if(ReadFileViaHTTP(&Buf1, sizeof(Buf1), &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_LIST_PATH)) | |
357 | + if(pBuf = malloc(1048576)) | |
182 | 358 | { |
183 | - if(GetHashSHA512(&Buf1, Length, &Hash)) | |
359 | + if(ReadFileViaHTTP(pBuf, 1048576, &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_LIST_PATH)) | |
184 | 360 | { |
185 | - if(memcmp(&Hash, &UpdateHash.ListHash, 64) == 0) | |
361 | + if(GetHashSHA512(pBuf, Length, &Hash)) | |
186 | 362 | { |
187 | - if(Length >= sizeof(UPDATE_LIST)) | |
363 | + if(memcmp(&Hash, &UpdateHash.ListHash, 64) == 0) | |
188 | 364 | { |
189 | - bResult = TRUE; | |
190 | - pUpdateList = (UPDATE_LIST*)&Buf1; | |
191 | - if(pUpdateList->Version > *pVersion) | |
365 | + if(Length >= sizeof(UPDATE_LIST)) | |
192 | 366 | { |
193 | - *pVersion = pUpdateList->Version; | |
194 | - _tcscpy(pVersionString, pUpdateList->VersionString); | |
367 | + bResult = TRUE; | |
368 | + pUpdateList = (UPDATE_LIST*)pBuf; | |
369 | + if(pUpdateList->Version > *pVersion) | |
370 | + { | |
371 | + *pVersion = pUpdateList->Version; | |
372 | + _tcscpy(pVersionString, pUpdateList->VersionString); | |
373 | + _tcscpy(pDescription, pUpdateList->Description); | |
374 | + } | |
375 | + if(bDownload) | |
376 | + bResult = PrepareUpdates(pBuf, Length, DownloadDir); | |
195 | 377 | } |
196 | - if(bDownload) | |
197 | - bResult = PrepareUpdates(&Buf1, Length, DownloadDir); | |
198 | 378 | } |
199 | 379 | } |
200 | 380 | } |
381 | + free(pBuf); | |
201 | 382 | } |
202 | 383 | } |
203 | 384 | } |
@@ -226,42 +407,42 @@ BOOL PrepareUpdates(void* pList, DWORD ListLength, LPCTSTR DownloadDir) | ||
226 | 407 | bResult = TRUE; |
227 | 408 | DeleteDirectoryAndContents(DownloadDir); |
228 | 409 | CreateDirectory(DownloadDir, NULL); |
229 | - pBuf = malloc(16777216); | |
230 | - for(i = 0; i < pUpdateList->FileCount; i++) | |
410 | + if(pBuf = malloc(16777216)) | |
231 | 411 | { |
232 | - b = FALSE; | |
233 | - if(pUpdateList->File[i].Flags & UPDATE_LIST_FILE_FLAG_DIRECTORY) | |
412 | + for(i = 0; i < pUpdateList->FileCount; i++) | |
234 | 413 | { |
235 | - _tcscpy(Path, DownloadDir); | |
236 | - _tcscat(Path, _T("\\")); | |
237 | - _tcscat(Path, pUpdateList->File[i].DstPath); | |
238 | - if(CreateDirectory(Path, NULL)) | |
239 | - b = TRUE; | |
240 | - } | |
241 | - if(strlen(pUpdateList->File[i].SrcPath) > 0) | |
242 | - { | |
243 | - if(ReadFileViaHTTP(pBuf, 16777216, &Length, HTTP_USER_AGENT, UPDATE_SERVER, pUpdateList->File[i].SrcPath)) | |
414 | + b = FALSE; | |
415 | + if(pUpdateList->File[i].Flags & UPDATE_LIST_FILE_FLAG_DIRECTORY) | |
244 | 416 | { |
245 | - if(GetHashSHA512(pBuf, Length, &Hash)) | |
417 | + _tcscpy(Path, DownloadDir); | |
418 | + _tcscat(Path, pUpdateList->File[i].DstPath); | |
419 | + if(CreateDirectory(Path, NULL)) | |
420 | + b = TRUE; | |
421 | + } | |
422 | + if(strlen(pUpdateList->File[i].SrcPath) > 0) | |
423 | + { | |
424 | + if(ReadFileViaHTTP(pBuf, 16777216, &Length, HTTP_USER_AGENT, UPDATE_SERVER, pUpdateList->File[i].SrcPath)) | |
246 | 425 | { |
247 | - if(memcmp(&Hash, &pUpdateList->File[i].SrcHash, 64) == 0) | |
426 | + if(GetHashSHA512(pBuf, Length, &Hash)) | |
248 | 427 | { |
249 | - _tcscpy(Path, DownloadDir); | |
250 | - _tcscat(Path, _T("\\")); | |
251 | - _tcscat(Path, pUpdateList->File[i].DstPath); | |
252 | - if(SaveMemoryToFileWithTimestamp(Path, pBuf, Length, &pUpdateList->File[i].Timestamp)) | |
253 | - b = TRUE; | |
428 | + if(memcmp(&Hash, &pUpdateList->File[i].SrcHash, 64) == 0) | |
429 | + { | |
430 | + _tcscpy(Path, DownloadDir); | |
431 | + _tcscat(Path, pUpdateList->File[i].DstPath); | |
432 | + if(SaveMemoryToFileWithTimestamp(Path, pBuf, Length, &pUpdateList->File[i].Timestamp)) | |
433 | + b = TRUE; | |
434 | + } | |
254 | 435 | } |
255 | 436 | } |
256 | 437 | } |
438 | + if(!b) | |
439 | + { | |
440 | + bResult = FALSE; | |
441 | + break; | |
442 | + } | |
257 | 443 | } |
258 | - if(!b) | |
259 | - { | |
260 | - bResult = FALSE; | |
261 | - break; | |
262 | - } | |
444 | + free(pBuf); | |
263 | 445 | } |
264 | - free(pBuf); | |
265 | 446 | } |
266 | 447 | } |
267 | 448 | return bResult; |
@@ -33,7 +33,8 @@ | ||
33 | 33 | "-----END PUBLIC KEY-----\n" |
34 | 34 | #define UPDATE_SIGNATURE "\x4C\x2A\x8E\x57\xAB\x75\x0C\xB5\xDA\x5F\xFE\xB9\x57\x9A\x1B\xA2\x7A\x61\x32\xF8\xFA\x4B\x61\xE2\xBA\x20\x9C\x37\xD5\x0A\xDC\x94\x10\x4D\x02\x30\x9B\xCD\x01\x9B\xB8\x73\x1E\xDB\xFD\xD7\x45\xCA\xE0\x8E\xF9\xB0\x1F\xB4\x0D\xD8\xFB\xE8\x41\x48\xE7\xF5\xE8\x64" |
35 | 35 | |
36 | -BOOL CheckForUpdates(BOOL bDownload, LPCTSTR DownloadDir, DWORD* pVersion, LPTSTR pVersionString); | |
36 | +BOOL BuildUpdates(LPCTSTR PrivateKeyFile, LPCTSTR Password, LPCTSTR ServerPath, LPCTSTR HashFile, LPCTSTR ListFile, DWORD Version, LPCTSTR VersionString, LPCTSTR Description); | |
37 | +BOOL CheckForUpdates(BOOL bDownload, LPCTSTR DownloadDir, DWORD* pVersion, LPTSTR pVersionString, LPTSTR pDescription); | |
37 | 38 | BOOL PrepareUpdates(void* pList, DWORD ListLength, LPCTSTR DownloadDir); |
38 | 39 | BOOL ApplyUpdates(LPCTSTR DestinationDir, LPCTSTR BackupDirName); |
39 | 40 | BOOL CleanupUpdates(LPCTSTR DownloadDir); |