mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-19 09:25:12 -04:00
[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:
parent
a41bca3183
commit
04d6ac0cdd
5 changed files with 80 additions and 21 deletions
|
@ -63,9 +63,9 @@
|
||||||
#define WAIT_TIME 5000
|
#define WAIT_TIME 5000
|
||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
char sum_str[NUM_CHECKSUMS][65];
|
char sum_str[CHECKSUM_MAX][65];
|
||||||
uint32_t bufnum, sum_count[NUM_CHECKSUMS] = { 16, 20, 32 };
|
uint32_t bufnum, sum_count[CHECKSUM_MAX] = { 16, 20, 32 };
|
||||||
HANDLE data_ready[NUM_CHECKSUMS], thread_ready[NUM_CHECKSUMS];
|
HANDLE data_ready[CHECKSUM_MAX], thread_ready[CHECKSUM_MAX];
|
||||||
DWORD read_size[2];
|
DWORD read_size[2];
|
||||||
char ALIGNED(64) buffer[2][BUFFER_SIZE];
|
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_init_t(SUM_CONTEXT *ctx);
|
||||||
typedef void sum_write_t(SUM_CONTEXT *ctx, const unsigned char *buf, size_t len);
|
typedef void sum_write_t(SUM_CONTEXT *ctx, const unsigned char *buf, size_t len);
|
||||||
typedef void sum_final_t(SUM_CONTEXT *ctx);
|
typedef void sum_final_t(SUM_CONTEXT *ctx);
|
||||||
sum_init_t *sum_init[NUM_CHECKSUMS] = { md5_init, sha1_init , sha256_init };
|
sum_init_t *sum_init[CHECKSUM_MAX] = { md5_init, sha1_init , sha256_init };
|
||||||
sum_write_t *sum_write[NUM_CHECKSUMS] = { md5_write, sha1_write , sha256_write };
|
sum_write_t *sum_write[CHECKSUM_MAX] = { md5_write, sha1_write , sha256_write };
|
||||||
sum_final_t *sum_final[NUM_CHECKSUMS] = { md5_final, sha1_final , sha256_final };
|
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
|
* Checksum dialog callback
|
||||||
|
@ -817,7 +860,7 @@ error:
|
||||||
DWORD WINAPI SumThread(void* param)
|
DWORD WINAPI SumThread(void* param)
|
||||||
{
|
{
|
||||||
DWORD_PTR* thread_affinity = (DWORD_PTR*)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;
|
HANDLE h = INVALID_HANDLE_VALUE;
|
||||||
uint64_t rb, LastRefresh = 0;
|
uint64_t rb, LastRefresh = 0;
|
||||||
int i, _bufnum, r = -1;
|
int i, _bufnum, r = -1;
|
||||||
|
@ -835,7 +878,7 @@ DWORD WINAPI SumThread(void* param)
|
||||||
// is usually in this first mask, for other tasks.
|
// is usually in this first mask, for other tasks.
|
||||||
SetThreadAffinityMask(GetCurrentThread(), thread_affinity[0]);
|
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
|
// 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
|
// wouldn't be able to ensure the event is reset before the thread
|
||||||
// gets into its next wait loop
|
// gets into its next wait loop
|
||||||
|
@ -882,7 +925,7 @@ DWORD WINAPI SumThread(void* param)
|
||||||
// Toggle the read buffer
|
// Toggle the read buffer
|
||||||
_bufnum = (bufnum + 1) % 2;
|
_bufnum = (bufnum + 1) % 2;
|
||||||
// Signal the waiting threads
|
// Signal the waiting threads
|
||||||
for (i = 0; i < NUM_CHECKSUMS; i++) {
|
for (i = 0; i < CHECKSUM_MAX; i++) {
|
||||||
if (!SetEvent(data_ready[i])) {
|
if (!SetEvent(data_ready[i])) {
|
||||||
uprintf("Could not signal checksum thread %d: %s", i, WindowsErrorString());
|
uprintf("Could not signal checksum thread %d: %s", i, WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -902,14 +945,14 @@ DWORD WINAPI SumThread(void* param)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the thread to signal they are ready to process data
|
// 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());
|
uprintf("Checksum threads failed to signal: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our last event with read_size=0 signaled the threads to exit - wait for that to happen
|
// 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());
|
uprintf("Checksum threads did not finalize: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -920,7 +963,7 @@ DWORD WINAPI SumThread(void* param)
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
for (i = 0; i < NUM_CHECKSUMS; i++) {
|
for (i = 0; i < CHECKSUM_MAX; i++) {
|
||||||
if (sum_thread[i] != NULL)
|
if (sum_thread[i] != NULL)
|
||||||
TerminateThread(sum_thread[i], 1);
|
TerminateThread(sum_thread[i], 1);
|
||||||
CloseHandle(data_ready[i]);
|
CloseHandle(data_ready[i]);
|
||||||
|
|
11
src/rufus.c
11
src/rufus.c
|
@ -2270,7 +2270,16 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
#ifdef RUFUS_TEST
|
#ifdef RUFUS_TEST
|
||||||
case IDC_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;
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
case IDC_ADVANCED:
|
case IDC_ADVANCED:
|
||||||
advanced_mode = !advanced_mode;
|
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
|
// Disable all controls except cancel
|
||||||
EnableControls(FALSE);
|
EnableControls(FALSE);
|
||||||
InitProgress(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);
|
format_thid = CreateThread(NULL, 0, SumThread, (LPVOID)thread_affinity, 0, NULL);
|
||||||
if (format_thid != NULL) {
|
if (format_thid != NULL) {
|
||||||
PrintInfo(0, -1);
|
PrintInfo(0, -1);
|
||||||
|
|
11
src/rufus.h
11
src/rufus.h
|
@ -42,7 +42,7 @@
|
||||||
#define APPLICATION_NAME "Rufus"
|
#define APPLICATION_NAME "Rufus"
|
||||||
#define COMPANY_NAME "Akeo Consulting"
|
#define COMPANY_NAME "Akeo Consulting"
|
||||||
#define STR_NO_LABEL "NO_LABEL"
|
#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 LEFT_TO_RIGHT_MARK ""
|
||||||
#define RIGHT_TO_LEFT_MARK ""
|
#define RIGHT_TO_LEFT_MARK ""
|
||||||
#define LEFT_TO_RIGHT_EMBEDDING ""
|
#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 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 STATUS_MSG_TIMEOUT 3500 // How long should cheat mode messages appear for on the status bar
|
||||||
#define WRITE_RETRIES 3
|
#define WRITE_RETRIES 3
|
||||||
#define NUM_CHECKSUMS 3 // Number of checksum algorithms we support (MD5, SHA1, SHA256)
|
|
||||||
#define FS_DEFAULT FS_FAT32
|
#define FS_DEFAULT FS_FAT32
|
||||||
#define SINGLE_CLUSTERSIZE_DEFAULT 0x00000100
|
#define SINGLE_CLUSTERSIZE_DEFAULT 0x00000100
|
||||||
#define BADBLOCK_PATTERNS {0xaa, 0x55, 0xff, 0x00}
|
#define BADBLOCK_PATTERNS {0xaa, 0x55, 0xff, 0x00}
|
||||||
|
@ -232,6 +231,13 @@ enum target_type {
|
||||||
#define GETTARGETTYPE(x) (((x)>0)?(((x) >> 16) & 0xFFFF):0)
|
#define GETTARGETTYPE(x) (((x)>0)?(((x) >> 16) & 0xFFFF):0)
|
||||||
#define GETPARTTYPE(x) (((x)>0)?((x) & 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 */
|
/* Special handling for old .c32 files we need to replace */
|
||||||
#define NB_OLD_C32 2
|
#define NB_OLD_C32 2
|
||||||
#define OLD_C32_NAMES { "menu.c32", "vesamenu.c32" }
|
#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,
|
extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||||
LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries);
|
LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries);
|
||||||
extern BOOL SetThreadAffinity(DWORD_PTR* thread_affinity, size_t num_threads);
|
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 printbits(x) _printbits(sizeof(x), &x, 0)
|
||||||
#define printbitslz(x) _printbits(sizeof(x), &x, 1)
|
#define printbitslz(x) _printbits(sizeof(x), &x, 1)
|
||||||
extern char* _printbits(size_t const size, void const * const ptr, int leading_zeroes);
|
extern char* _printbits(size_t const size, void const * const ptr, int leading_zeroes);
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 2.10.938"
|
CAPTION "Rufus 2.10.939"
|
||||||
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
||||||
|
@ -320,8 +320,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,10,938,0
|
FILEVERSION 2,10,939,0
|
||||||
PRODUCTVERSION 2,10,938,0
|
PRODUCTVERSION 2,10,939,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -338,13 +338,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "2.10.938"
|
VALUE "FileVersion", "2.10.939"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "2.10.938"
|
VALUE "ProductVersion", "2.10.939"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -181,7 +181,7 @@ static int SatAtaPassthrough(HANDLE hPhysical, ATA_PASSTHROUGH_CMD* Command, voi
|
||||||
int t_length = 0; /* 0 -> no data transferred */
|
int t_length = 0; /* 0 -> no data transferred */
|
||||||
uint8_t Direction;
|
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");
|
uprintf("SatAtaPassthrough: BufLen must be a multiple of <block size>\n");
|
||||||
return SPT_ERROR_BUFFER;
|
return SPT_ERROR_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue