[checksum] add an individual checksum function call

* Part of #758
* Also define checksum types and fix a missing change in smart.c
This commit is contained in:
Pete Batard 2016-05-24 13:21:23 +01:00
parent a41bca3183
commit 04d6ac0cdd
5 changed files with 80 additions and 21 deletions

View File

@ -63,9 +63,9 @@
#define WAIT_TIME 5000
/* Globals */
char sum_str[NUM_CHECKSUMS][65];
uint32_t bufnum, sum_count[NUM_CHECKSUMS] = { 16, 20, 32 };
HANDLE data_ready[NUM_CHECKSUMS], thread_ready[NUM_CHECKSUMS];
char sum_str[CHECKSUM_MAX][65];
uint32_t bufnum, sum_count[CHECKSUM_MAX] = { 16, 20, 32 };
HANDLE data_ready[CHECKSUM_MAX], thread_ready[CHECKSUM_MAX];
DWORD read_size[2];
char ALIGNED(64) buffer[2][BUFFER_SIZE];
@ -709,9 +709,52 @@ static void null_final(SUM_CONTEXT *ctx) { }
typedef void sum_init_t(SUM_CONTEXT *ctx);
typedef void sum_write_t(SUM_CONTEXT *ctx, const unsigned char *buf, size_t len);
typedef void sum_final_t(SUM_CONTEXT *ctx);
sum_init_t *sum_init[NUM_CHECKSUMS] = { md5_init, sha1_init , sha256_init };
sum_write_t *sum_write[NUM_CHECKSUMS] = { md5_write, sha1_write , sha256_write };
sum_final_t *sum_final[NUM_CHECKSUMS] = { md5_final, sha1_final , sha256_final };
sum_init_t *sum_init[CHECKSUM_MAX] = { md5_init, sha1_init , sha256_init };
sum_write_t *sum_write[CHECKSUM_MAX] = { md5_write, sha1_write , sha256_write };
sum_final_t *sum_final[CHECKSUM_MAX] = { md5_final, sha1_final , sha256_final };
// Compute an individual checksum without threading or buffering, for a single file
BOOL Checksum(const unsigned type, const char* path, uint8_t* sum)
{
BOOL r = FALSE;
SUM_CONTEXT sum_ctx = { 0 };
HANDLE h = INVALID_HANDLE_VALUE;
DWORD read_size = 0;
uint64_t rb;
char buffer[4096];
if ((type >= CHECKSUM_MAX) || (path == NULL) || (sum == NULL))
goto out;
uprintf("\r\nComputing checksum for '%s'...", path);
h = CreateFileU(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (h == INVALID_HANDLE_VALUE) {
uprintf("Could not open file: %s", WindowsErrorString());
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED;
goto out;
}
sum_init[type](&sum_ctx);
for (rb = 0; ; rb += read_size) {
CHECK_FOR_USER_CANCEL;
if (!ReadFile(h, buffer, sizeof(buffer), &read_size, NULL)) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_READ_FAULT;
uprintf(" Read error: %s", WindowsErrorString());
goto out;
}
if (read_size == 0)
break;
sum_write[type](&sum_ctx, buffer, (size_t)read_size);
}
sum_final[type](&sum_ctx);
memcpy(sum, sum_ctx.buf, sum_count[type]);
r = TRUE;
out:
safe_closehandle(h);
return r;
}
/*
* Checksum dialog callback
@ -817,7 +860,7 @@ error:
DWORD WINAPI SumThread(void* param)
{
DWORD_PTR* thread_affinity = (DWORD_PTR*)param;
HANDLE sum_thread[NUM_CHECKSUMS] = { NULL, NULL, NULL };
HANDLE sum_thread[CHECKSUM_MAX] = { NULL, NULL, NULL };
HANDLE h = INVALID_HANDLE_VALUE;
uint64_t rb, LastRefresh = 0;
int i, _bufnum, r = -1;
@ -835,7 +878,7 @@ DWORD WINAPI SumThread(void* param)
// is usually in this first mask, for other tasks.
SetThreadAffinityMask(GetCurrentThread(), thread_affinity[0]);
for (i = 0; i < NUM_CHECKSUMS; i++) {
for (i = 0; i < CHECKSUM_MAX; i++) {
// NB: Can't use a single manual-reset event for data_ready as we
// wouldn't be able to ensure the event is reset before the thread
// gets into its next wait loop
@ -882,7 +925,7 @@ DWORD WINAPI SumThread(void* param)
// Toggle the read buffer
_bufnum = (bufnum + 1) % 2;
// Signal the waiting threads
for (i = 0; i < NUM_CHECKSUMS; i++) {
for (i = 0; i < CHECKSUM_MAX; i++) {
if (!SetEvent(data_ready[i])) {
uprintf("Could not signal checksum thread %d: %s", i, WindowsErrorString());
goto out;
@ -902,14 +945,14 @@ DWORD WINAPI SumThread(void* param)
}
// Wait for the thread to signal they are ready to process data
if (WaitForMultipleObjects(NUM_CHECKSUMS, thread_ready, TRUE, WAIT_TIME) != WAIT_OBJECT_0) {
if (WaitForMultipleObjects(CHECKSUM_MAX, thread_ready, TRUE, WAIT_TIME) != WAIT_OBJECT_0) {
uprintf("Checksum threads failed to signal: %s", WindowsErrorString());
goto out;
}
}
// Our last event with read_size=0 signaled the threads to exit - wait for that to happen
if (WaitForMultipleObjects(NUM_CHECKSUMS, sum_thread, TRUE, WAIT_TIME) != WAIT_OBJECT_0) {
if (WaitForMultipleObjects(CHECKSUM_MAX, sum_thread, TRUE, WAIT_TIME) != WAIT_OBJECT_0) {
uprintf("Checksum threads did not finalize: %s", WindowsErrorString());
goto out;
}
@ -920,7 +963,7 @@ DWORD WINAPI SumThread(void* param)
r = 0;
out:
for (i = 0; i < NUM_CHECKSUMS; i++) {
for (i = 0; i < CHECKSUM_MAX; i++) {
if (sum_thread[i] != NULL)
TerminateThread(sum_thread[i], 1);
CloseHandle(data_ready[i]);

View File

@ -2270,7 +2270,16 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break;
#ifdef RUFUS_TEST
case IDC_TEST:
{
int j;
char str[65];
uint8_t sum[32];
Checksum(CHECKSUM_SHA256, "C:\\rufus\\src\\.msvc\\rufus_files\\syslinux-6.03\\ldlinux.sys", sum);
for (j = 0; j < sizeof(sum); j++)
safe_sprintf(&str[2 * j], ARRAYSIZE(str) - 2 * j, "%02x", sum[j]);
uprintf(" Checksum: %s", str);
break;
}
#endif
case IDC_ADVANCED:
advanced_mode = !advanced_mode;
@ -2540,7 +2549,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
// Disable all controls except cancel
EnableControls(FALSE);
InitProgress(FALSE);
SetThreadAffinity(thread_affinity, NUM_CHECKSUMS + 1);
SetThreadAffinity(thread_affinity, CHECKSUM_MAX + 1);
format_thid = CreateThread(NULL, 0, SumThread, (LPVOID)thread_affinity, 0, NULL);
if (format_thid != NULL) {
PrintInfo(0, -1);

View File

@ -42,7 +42,7 @@
#define APPLICATION_NAME "Rufus"
#define COMPANY_NAME "Akeo Consulting"
#define STR_NO_LABEL "NO_LABEL"
// Yes, there is a character between these seemingly empty quotes!
// Yes, there exist characters between these seemingly empty quotes!
#define LEFT_TO_RIGHT_MARK ""
#define RIGHT_TO_LEFT_MARK ""
#define LEFT_TO_RIGHT_EMBEDDING ""
@ -68,7 +68,6 @@
#define MBR_UEFI_MARKER 0x49464555 // 'U', 'E', 'F', 'I', as a 32 bit little endian longword
#define STATUS_MSG_TIMEOUT 3500 // How long should cheat mode messages appear for on the status bar
#define WRITE_RETRIES 3
#define NUM_CHECKSUMS 3 // Number of checksum algorithms we support (MD5, SHA1, SHA256)
#define FS_DEFAULT FS_FAT32
#define SINGLE_CLUSTERSIZE_DEFAULT 0x00000100
#define BADBLOCK_PATTERNS {0xaa, 0x55, 0xff, 0x00}
@ -232,6 +231,13 @@ enum target_type {
#define GETTARGETTYPE(x) (((x)>0)?(((x) >> 16) & 0xFFFF):0)
#define GETPARTTYPE(x) (((x)>0)?((x) & 0xFFFF):0);
enum checksum_type {
CHECKSUM_MD5 = 0,
CHECKSUM_SHA1,
CHECKSUM_SHA256,
CHECKSUM_MAX
};
/* Special handling for old .c32 files we need to replace */
#define NB_OLD_C32 2
#define OLD_C32_NAMES { "menu.c32", "vesamenu.c32" }
@ -450,6 +456,7 @@ extern BOOL IsFontAvailable(const char* font_name);
extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries);
extern BOOL SetThreadAffinity(DWORD_PTR* thread_affinity, size_t num_threads);
extern BOOL Checksum(const unsigned type, const char* path, uint8_t* sum);
#define printbits(x) _printbits(sizeof(x), &x, 0)
#define printbitslz(x) _printbits(sizeof(x), &x, 1)
extern char* _printbits(size_t const size, void const * const ptr, int leading_zeroes);

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 2.10.938"
CAPTION "Rufus 2.10.939"
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -320,8 +320,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,10,938,0
PRODUCTVERSION 2,10,938,0
FILEVERSION 2,10,939,0
PRODUCTVERSION 2,10,939,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -338,13 +338,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "2.10.938"
VALUE "FileVersion", "2.10.939"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "2.10.938"
VALUE "ProductVersion", "2.10.939"
END
END
BLOCK "VarFileInfo"

View File

@ -181,7 +181,7 @@ static int SatAtaPassthrough(HANDLE hPhysical, ATA_PASSTHROUGH_CMD* Command, voi
int t_length = 0; /* 0 -> no data transferred */
uint8_t Direction;
if (BufLen % SelectedDrive.Geometry.BytesPerSector != 0) {
if (BufLen % SelectedDrive.SectorSize != 0) {
uprintf("SatAtaPassthrough: BufLen must be a multiple of <block size>\n");
return SPT_ERROR_BUFFER;
}