diff --git a/file.c b/file.c index 807ab05..ff380b6 100644 --- a/file.c +++ b/file.c @@ -96,25 +96,34 @@ int getFileSize(char *pInputFileName) } int getFileSha1(char *pInputFileName, uint8_t *pSha1Out, uint64_t *value, uint64_t max, void (* SetProgress)(uint64_t value, uint64_t max), int (* cancelHandler)()) { + + // Set up SHA1 context SHA1_CTX ctx; sha1_init(&ctx); + // Open the file to read, else return the error SceUID fd = sceIoOpen(pInputFileName, SCE_O_RDONLY, 0); if (fd < 0) return fd; + // Open up the buffer for copying data into void *buf = malloc(TRANSFER_SIZE); int read; + + // Actually take the SHA1 sum while ((read = sceIoRead(fd, buf, TRANSFER_SIZE)) > 0) { sha1_update(&ctx, buf, read); + + // Defined in io_process.c, check to make sure pointer isn't null before incrementing if(value) - (*value)++; + (*value)++; // Note: Max value is filesize/TRANSFER_SIZE if(SetProgress) SetProgress(value ? *value : 0, max); + // Check to see if cancelHandler exists, if so call it and free memory if cancelled if(cancelHandler && cancelHandler()) { free(buf); sceIoClose(fd); @@ -128,10 +137,13 @@ int getFileSha1(char *pInputFileName, uint8_t *pSha1Out, uint64_t *value, uint64 sceKernelDelayThread(500000); } + // Final iteration of SHA1 sum, dump final value into pSha1Out buffer sha1_final(&ctx, pSha1Out); + // Free up file buffer free(buf); + // Close file proper sceIoClose(fd); return 1; } diff --git a/io_process.c b/io_process.c index 45e0a9d..9018731 100644 --- a/io_process.c +++ b/io_process.c @@ -336,18 +336,20 @@ int hash_thread(SceSize args_size, HashArguments *args) { // SHA1 process uint64_t value = 0; + // Spin off a thread to update the progress dialog thid = createStartUpdateThread(max); uint8_t sha1out[20]; int res = getFileSha1(args->file_path, sha1out, &value, max, SetProgress, cancelHandler); if (res <= 0) { + // SHA1 Didn't complete successfully, or was cancelled closeWaitDialog(); dialog_step = DIALOG_STEP_CANCELLED; errorDialog(res); goto EXIT; } - // Set progress to 100% + // Since we hit here, we're done. Set progress to 100% sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 100); sceKernelDelayThread(COUNTUP_WAIT); @@ -356,9 +358,12 @@ int hash_thread(SceSize args_size, HashArguments *args) { char sha1msg[41]; int i; + + // Construct SHA1 sum string for (i = 0; i < 20; i++) { sprintf(sha1msg + (2*i), "%02x ", sha1out[i]); } + sha1msg[40] = '\0'; initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_OK, sha1msg); @@ -373,10 +378,13 @@ int hash_thread(SceSize args_size, HashArguments *args) { sceMsgDialogClose(); EXIT: + + // Ensure the update thread ends gracefully if(thid>=0) sceKernelWaitThreadEnd(thid, NULL, NULL); powerUnlock(); + // Kill current thread return sceKernelExitDeleteThread(0); } diff --git a/main.c b/main.c index ebefa75..99a97f0 100644 --- a/main.c +++ b/main.c @@ -801,6 +801,7 @@ void contextMenuCtrl() { case MENU_ENTRY_SHA1: { + // Ensure user wants to actually take the hash initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_YESNO, language_container[HASH_FILE_QUESTION]); dialog_step = DIALOG_STEP_HASH_QUESTION; break; @@ -1000,10 +1001,11 @@ int dialogSteps() { case DIALOG_STEP_HASH_QUESTION: if (msg_result == MESSAGE_DIALOG_RESULT_YES) { - + // Throw up the progress bar, enter hashing state initMessageDialog(MESSAGE_DIALOG_PROGRESS_BAR, language_container[HASHING]); dialog_step = DIALOG_STEP_HASH_CONFIRMED; } else if (msg_result == MESSAGE_DIALOG_RESULT_NO) { + // Quit dialog_step = DIALOG_STEP_NONE; } @@ -1011,12 +1013,16 @@ int dialogSteps() { case DIALOG_STEP_HASH_CONFIRMED: if (msg_result == MESSAGE_DIALOG_RESULT_RUNNING) { + // User has confirmed desire to hash, get requested file entry FileListEntry *file_entry = fileListGetNthEntry(&file_list, base_pos + rel_pos); + + // Place the full file path in cur_file snprintf(cur_file, MAX_PATH_LENGTH, "%s%s", file_list.path, file_entry->name); HashArguments args; args.file_path = cur_file; + // Create a thread to run out actual sum SceUID thid = sceKernelCreateThread("hash_thread", (SceKernelThreadEntry)hash_thread, 0x40, 0x10000, 0, 0, NULL); if (thid >= 0) sceKernelStartThread(thid, sizeof(HashArguments), &args); @@ -1027,6 +1033,7 @@ int dialogSteps() { break; case DIALOG_STEP_HASH_DISPLAY: + // Reset dialog state when user selects yes/no if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) { dialog_step = DIALOG_STEP_NONE; } diff --git a/resources/english_us.txt b/resources/english_us.txt index 1cf1029..ac836cb 100644 --- a/resources/english_us.txt +++ b/resources/english_us.txt @@ -14,10 +14,10 @@ PASTE = "Paste" DELETE = "Delete" RENAME = "Rename" NEW_FOLDER = "New folder" +FOLDER = "Folder" SHA1 = "SHA1 checksum" HASHING = "Hashing..." HASH_FILE_QUESTION = "SHA1 hashing may take a long time. Continue?" -FOLDER = "Folder" COPIED_FILE = "Copied %d file." COPIED_FOLDER = "Copied %d folder." COPIED_FILES_FOLDERS = "Copied %d files/folders."