mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00: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
|
||||
|
||||
/* 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]);
|
||||
|
|
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;
|
||||
#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);
|
||||
|
|
11
src/rufus.h
11
src/rufus.h
|
@ -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);
|
||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue