@@ -44,7 +44,7 @@ __forceinline VOID WINAPI HashCalcSetSavePrefix( PHASHCALCCONTEXT phcctx, PTSTR
44
44
Path processing
45
45
\*============================================================================*/
46
46
47
- VOID WINAPI HashCalcPrepare ( PHASHCALCCONTEXT phcctx )
47
+ BOOL WINAPI HashCalcPrepare ( PHASHCALCCONTEXT phcctx )
48
48
{
49
49
PTSTR pszPrev = NULL ;
50
50
PTSTR pszCurrent , pszCurrentEnd ;
@@ -128,7 +128,7 @@ VOID WINAPI HashCalcPrepare( PHASHCALCCONTEXT phcctx )
128
128
129
129
if (pItem )
130
130
{
131
- pItem -> bValid = FALSE ;
131
+ pItem -> results . dwFlags = 0 ;
132
132
pItem -> cchPath = cchCurrent ;
133
133
memcpy (pItem -> szPath , pszCurrent , cbCurrent );
134
134
@@ -143,10 +143,11 @@ VOID WINAPI HashCalcPrepare( PHASHCALCCONTEXT phcctx )
143
143
if (phcctx -> status == PAUSED )
144
144
WaitForSingleObject (phcctx -> hUnpauseEvent , INFINITE );
145
145
if (phcctx -> status == CANCEL_REQUESTED )
146
- return ;
146
+ return (FALSE) ;
147
147
148
148
pszPrev = pszCurrent ;
149
149
}
150
+ return (TRUE);
150
151
}
151
152
152
153
VOID WINAPI HashCalcWalkDirectory ( PHASHCALCCONTEXT phcctx , PTSTR pszPath , UINT cchPath )
@@ -192,7 +193,7 @@ VOID WINAPI HashCalcWalkDirectory( PHASHCALCCONTEXT phcctx, PTSTR pszPath, UINT
192
193
193
194
if (pItem )
194
195
{
195
- pItem -> bValid = FALSE ;
196
+ pItem -> results . dwFlags = 0 ;
196
197
pItem -> cchPath = cchNew ;
197
198
memcpy (pItem -> szPath , pszPath , cbPathBuffer );
198
199
@@ -300,8 +301,6 @@ VOID WINAPI HashCalcInitSave( PHASHCALCCONTEXT phcctx )
300
301
phcctx -> ofn .nFilterIndex &&
301
302
phcctx -> ofn .nFilterIndex <= NUM_HASHES )
302
303
{
303
- BOOL bSuccess = FALSE;
304
-
305
304
// Save the filter in the user's preferences
306
305
if (phcctx -> opt .dwFilterIndex != phcctx -> ofn .nFilterIndex )
307
306
{
@@ -330,7 +329,7 @@ VOID WINAPI HashCalcInitSave( PHASHCALCCONTEXT phcctx )
330
329
// Open the file for output
331
330
phcctx -> hFileOut = CreateFile (
332
331
pszFile ,
333
- FILE_APPEND_DATA ,
332
+ FILE_APPEND_DATA | DELETE ,
334
333
FILE_SHARE_READ ,
335
334
NULL ,
336
335
CREATE_ALWAYS ,
@@ -385,19 +384,32 @@ VOID WINAPI HashCalcSetSaveFormat( PHASHCALCCONTEXT phcctx )
385
384
386
385
BOOL WINAPI HashCalcWriteResult ( PHASHCALCCONTEXT phcctx , PHASHCALCITEM pItem )
387
386
{
388
- PCTSTR pszHash ;
389
- WCHAR szWbuffer [MAX_PATH_BUFFER ];
390
- CHAR szAbuffer [MAX_PATH_BUFFER ];
387
+ PCTSTR pszHash ; // will be pointed to the hash name
388
+ WCHAR szWbuffer [MAX_PATH_BUFFER ]; // wide-char buffer
389
+ CHAR szAbuffer [MAX_PATH_BUFFER ]; // narrow-char buffer
391
390
#ifdef UNICODE
392
391
# define szTbuffer szWbuffer
393
392
#else
394
393
# define szTbuffer szAbuffer
395
394
#endif
396
- PVOID pvLine ; // Will be pointed to the buffer to write out
397
- size_t cchLine , cbLine ; // Length of line, in TCHARs or BYTEs, EXCLUDING the terminator
398
-
399
- if (!pItem -> bValid )
400
- return (FALSE);
395
+ PTSTR szTbufferAppend = szTbuffer ; // current end of the buffer used to build output
396
+ size_t cchLine = MAX_PATH_BUFFER ; // starts off as count of remaining TCHARS in the buffer
397
+ PVOID pvLine ; // will be pointed to the buffer to write out
398
+ size_t cbLine ; // will be line length in bytes, EXCLUDING nul terminator
399
+ BOOL bRetval = TRUE;
400
+
401
+ // If the checksum to save isn't present in the results
402
+ if (! ((1 << (phcctx -> ofn .nFilterIndex - 1 )) & pItem -> results .dwFlags ))
403
+ {
404
+ // Start with a commented-out error message - "; UNREADABLE:"
405
+ WCHAR szUnreadable [MAX_STRINGRES ];
406
+ LoadString (g_hModThisDll , IDS_HV_STATUS_UNREADABLE , szUnreadable , MAX_STRINGRES );
407
+ StringCchPrintfEx (szTbufferAppend , cchLine , & szTbufferAppend , & cchLine , 0 , TEXT ("; %s:\r\n" ), szUnreadable );
408
+
409
+ // We'll still output a hash, but it will be all 0's, that way Verify will indicate an mismatch
410
+ HashCalcClearInvalid (& pItem -> results , TEXT ('0' ));
411
+ bRetval = FALSE;
412
+ }
401
413
402
414
// Translate the filter index to a hash
403
415
switch (phcctx -> ofn .nFilterIndex )
@@ -409,19 +421,18 @@ BOOL WINAPI HashCalcWriteResult( PHASHCALCCONTEXT phcctx, PHASHCALCITEM pItem )
409
421
}
410
422
411
423
// Format the line
412
- #define HashCalcFormat (a , b ) StringCchPrintfEx(szTbuffer, MAX_PATH_BUFFER, NULL , &cchLine, 0, phcctx->szFormat, a, b)
424
+ #define HashCalcFormat (a , b ) StringCchPrintfEx(szTbufferAppend, cchLine, &szTbufferAppend , &cchLine, 0, phcctx->szFormat, a, b)
413
425
(phcctx -> ofn .nFilterIndex == 1 ) ?
414
426
HashCalcFormat (pItem -> szPath + phcctx -> cchAdjusted , pszHash ) : // SFV
415
427
HashCalcFormat (pszHash , pItem -> szPath + phcctx -> cchAdjusted ); // everything else
416
428
#undef HashCalcFormat
417
- // cchLine is temporarily the count of characters left in the buffer instead of the line length
418
429
419
430
#ifdef _TIMED
420
- StringCchPrintfEx (szTbuffer + ( MAX_PATH_BUFFER - cchLine ) , cchLine , NULL , & cchLine , 0 ,
431
+ StringCchPrintfEx (szTbufferAppend , cchLine , NULL , & cchLine , 0 ,
421
432
_T ("; Elapsed: %d ms\r\n" ), pItem -> dwElapsed );
422
433
#endif
423
434
424
- cchLine = MAX_PATH_BUFFER - cchLine ; // now it's back to being the line length
435
+ cchLine = MAX_PATH_BUFFER - cchLine ; // from now on cchLine is the line length in bytes, EXCLUDING nul terminator
425
436
if (cchLine > 0 )
426
437
{
427
438
// Convert to the correct encoding
@@ -479,7 +490,45 @@ BOOL WINAPI HashCalcWriteResult( PHASHCALCCONTEXT phcctx, PHASHCALCITEM pItem )
479
490
}
480
491
else return (FALSE);
481
492
482
- return (TRUE);
493
+ return (bRetval );
494
+ }
495
+
496
+ VOID WINAPI HashCalcClearInvalid ( PWHRESULTEX pwhres , WCHAR cInvalid )
497
+ {
498
+ #ifdef UNICODE
499
+ # define _tmemset wmemset
500
+ #else
501
+ # define _tmemset memset
502
+ #endif
503
+
504
+ #define HASH_CLEAR_INVALID_op (alg ) \
505
+ if (! (pwhres->dwFlags & WHEX_CHECK##alg)) \
506
+ { \
507
+ _tmemset(pwhres->szHex##alg, cInvalid, countof(pwhres->szHex##alg) - 1); \
508
+ pwhres->szHex##alg[countof(pwhres->szHex##alg) - 1] = L'\0'; \
509
+ }
510
+ FOR_EACH_HASH (HASH_CLEAR_INVALID_op )
511
+ }
512
+
513
+ // This can only succeed on Windows Vista and later;
514
+ // returns FALSE on failure
515
+ BOOL WINAPI HashCalcDeleteFileByHandle (HANDLE hFile )
516
+ {
517
+ if (hFile == INVALID_HANDLE_VALUE )
518
+ return (FALSE);
519
+
520
+ HMODULE hKernel32 = GetModuleHandle (TEXT ("kernel32.dll" ));
521
+ if (hKernel32 == NULL )
522
+ return (FALSE);
523
+
524
+ typedef BOOL (WINAPI * PFN_SFIBH )(_In_ HANDLE , _In_ FILE_INFO_BY_HANDLE_CLASS , _In_ LPVOID , _In_ DWORD );
525
+ PFN_SFIBH pfnSetFileInformationByHandle = (PFN_SFIBH )GetProcAddress (hKernel32 , "SetFileInformationByHandle" );
526
+ if (pfnSetFileInformationByHandle == NULL )
527
+ return (FALSE);
528
+
529
+ FILE_DISPOSITION_INFO fdi ;
530
+ fdi .DeleteFile = TRUE;
531
+ return (pfnSetFileInformationByHandle (hFile , FileDispositionInfo , & fdi , sizeof (fdi )));
483
532
}
484
533
485
534
VOID WINAPI HashCalcSetSavePrefix ( PHASHCALCCONTEXT phcctx , PTSTR pszSave )
0 commit comments