Add SHA1 Context Menu Option

This commit is contained in:
xperia64 2016-09-06 23:52:33 +00:00
parent a627edca9e
commit 5c4c231dfe
9 changed files with 174 additions and 2 deletions

42
file.c
View File

@ -20,6 +20,7 @@
#include "archive.h"
#include "file.h"
#include "utils.h"
#include "sha1.h"
static char *mount_points[] = {
"app0:",
@ -94,6 +95,47 @@ int getFileSize(char *pInputFileName)
return fileSize;
}
int getFileSha1(char *pInputFileName, uint8_t *pSha1Out, uint64_t *value, uint64_t max, void (* SetProgress)(uint64_t value, uint64_t max), int (* cancelHandler)()) {
SHA1_CTX ctx;
sha1_init(&ctx);
SceUID fd = sceIoOpen(pInputFileName, SCE_O_RDONLY, 0);
if (fd < 0)
return fd;
void *buf = malloc(TRANSFER_SIZE);
int read;
while ((read = sceIoRead(fd, buf, TRANSFER_SIZE)) > 0)
{
sha1_update(&ctx, buf, read);
if(value)
(*value)++;
if(SetProgress)
SetProgress(value ? *value : 0, max);
if(cancelHandler && cancelHandler()) {
free(buf);
sceIoClose(fd);
return 0;
}
// This is CPU intensive so the progress bar won't refresh unless we sleep
// DIALOG_WAIT seemed too long for this application
// so I set it to 1/2 of a second every 8192 TRANSFER_SIZE blocks
if((*value)%8192 == 0)
sceKernelDelayThread(500000);
}
sha1_final(&ctx, pSha1Out);
free(buf);
sceIoClose(fd);
return 1;
}
int getPathInfo(char *path, uint64_t *size, uint32_t *folders, uint32_t *files) {
SceUID dfd = sceIoDopen(path);
if (dfd >= 0) {

1
file.h
View File

@ -79,6 +79,7 @@ int ReadFile(char *file, void *buf, int size);
int WriteFile(char *file, void *buf, int size);
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)());
int getPathInfo(char *path, uint64_t *size, uint32_t *folders, uint32_t *files);
int removePath(char *path, uint64_t *value, uint64_t max, void (* SetProgress)(uint64_t value, uint64_t max), int (* cancelHandler)());
int copyFile(char *src_path, char *dst_path, uint64_t *value, uint64_t max, void (* SetProgress)(uint64_t value, uint64_t max), int (* cancelHandler)());

View File

@ -319,4 +319,64 @@ EXIT:
powerUnlock();
return sceKernelExitDeleteThread(0);
}
}
int hash_thread(SceSize args_size, HashArguments *args) {
SceUID thid = -1;
// Lock power timers
powerLock();
// Set progress to 0%
sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 0);
sceKernelDelayThread(DIALOG_WAIT); // Needed to see the percentage
uint64_t max = (uint64_t) (getFileSize(args->file_path)/(TRANSFER_SIZE));
// SHA1 process
uint64_t value = 0;
thid = createStartUpdateThread(max);
uint8_t sha1out[20];
int res = getFileSha1(args->file_path, sha1out, &value, max, SetProgress, cancelHandler);
if (res <= 0) {
closeWaitDialog();
dialog_step = DIALOG_STEP_CANCELLED;
errorDialog(res);
goto EXIT;
}
// Set progress to 100%
sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 100);
sceKernelDelayThread(COUNTUP_WAIT);
// Close
closeWaitDialog();
char sha1msg[41];
int i;
for (i = 0; i < 20; i++) {
sprintf(sha1msg + (2*i), "%02x ", sha1out[i]);
}
sha1msg[40] = '\0';
initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_OK, sha1msg);
dialog_step = DIALOG_STEP_HASH_DISPLAY;
// Wait for response
while (dialog_step == DIALOG_STEP_HASH_DISPLAY) {
sceKernelDelayThread(1000);
}
closeWaitDialog();
sceMsgDialogClose();
EXIT:
if(thid>=0)
sceKernelWaitThreadEnd(thid, NULL, NULL);
powerUnlock();
return sceKernelExitDeleteThread(0);
}

View File

@ -45,6 +45,10 @@ typedef struct {
int copy_mode;
} CopyArguments;
typedef struct {
char *file_path;
} HashArguments;
void closeWaitDialog();
int cancelHandler();
void SetProgress(uint64_t value, uint64_t max);
@ -52,5 +56,6 @@ SceUID createStartUpdateThread(uint64_t max);
int delete_thread(SceSize args_size, DeleteArguments *args);
int copy_thread(SceSize args_size, CopyArguments *args);
int hash_thread(SceSize args_size, HashArguments *args);
#endif
#endif

View File

@ -98,6 +98,9 @@ void loadLanguage(int id) {
LANGUAGE_ENTRY(SYS_INFO),
LANGUAGE_ENTRY(INSTALL_ALL),
LANGUAGE_ENTRY(UPDATE_QUESTION),
LANGUAGE_ENTRY(SHA1),
LANGUAGE_ENTRY(HASHING),
LANGUAGE_ENTRY(HASH_FILE_QUESTION),
};
// Load default config file

View File

@ -56,6 +56,9 @@ enum LanguageContainer {
SYS_INFO,
INSTALL_ALL,
UPDATE_QUESTION,
SHA1,
HASHING,
HASH_FILE_QUESTION,
LANGUAGE_CONTRAINER_SIZE,
};

50
main.c
View File

@ -450,6 +450,7 @@ enum MenuEntrys {
MENU_ENTRY_RENAME,
MENU_ENTRY_EMPTY_4,
MENU_ENTRY_NEW_FOLDER,
MENU_ENTRY_SHA1,
};
enum MenuVisibilities {
@ -475,6 +476,7 @@ MenuEntry menu_entries[] = {
{ RENAME, VISIBILITY_INVISIBLE },
{ -1, VISIBILITY_UNUSED },
{ NEW_FOLDER, VISIBILITY_INVISIBLE },
{ SHA1, VISIBILITY_INVISIBLE }
};
#define N_MENU_ENTRIES (sizeof(menu_entries) / sizeof(MenuEntry))
@ -497,6 +499,7 @@ void initContextMenu() {
menu_entries[MENU_ENTRY_COPY].visibility = VISIBILITY_INVISIBLE;
menu_entries[MENU_ENTRY_DELETE].visibility = VISIBILITY_INVISIBLE;
menu_entries[MENU_ENTRY_RENAME].visibility = VISIBILITY_INVISIBLE;
menu_entries[MENU_ENTRY_SHA1].visibility = VISIBILITY_INVISIBLE;
}
// Invisible 'Paste' if nothing is copied yet
@ -510,6 +513,11 @@ void initContextMenu() {
menu_entries[MENU_ENTRY_DELETE].visibility = VISIBILITY_INVISIBLE;
menu_entries[MENU_ENTRY_RENAME].visibility = VISIBILITY_INVISIBLE;
menu_entries[MENU_ENTRY_NEW_FOLDER].visibility = VISIBILITY_INVISIBLE;
menu_entries[MENU_ENTRY_SHA1].visibility = VISIBILITY_INVISIBLE;
}
if(file_entry->is_folder) {
menu_entries[MENU_ENTRY_SHA1].visibility = VISIBILITY_INVISIBLE;
}
if(file_entry->type != FILE_TYPE_VPK) {
@ -790,6 +798,13 @@ void contextMenuCtrl() {
dialog_step = DIALOG_STEP_NEW_FOLDER;
break;
}
case MENU_ENTRY_SHA1:
{
initMessageDialog(SCE_MSG_DIALOG_BUTTON_TYPE_YESNO, language_container[HASH_FILE_QUESTION]);
dialog_step = DIALOG_STEP_HASH_QUESTION;
break;
}
case MENU_ENTRY_INSTALL_ALL:
{
@ -982,7 +997,42 @@ int dialogSteps() {
}
break;
case DIALOG_STEP_HASH_QUESTION:
if (msg_result == MESSAGE_DIALOG_RESULT_YES) {
initMessageDialog(MESSAGE_DIALOG_PROGRESS_BAR, language_container[HASHING]);
dialog_step = DIALOG_STEP_HASH_CONFIRMED;
} else if (msg_result == MESSAGE_DIALOG_RESULT_NO) {
dialog_step = DIALOG_STEP_NONE;
}
break;
case DIALOG_STEP_HASH_CONFIRMED:
if (msg_result == MESSAGE_DIALOG_RESULT_RUNNING) {
FileListEntry *file_entry = fileListGetNthEntry(&file_list, base_pos + rel_pos);
snprintf(cur_file, MAX_PATH_LENGTH, "%s%s", file_list.path, file_entry->name);
HashArguments args;
args.file_path = cur_file;
SceUID thid = sceKernelCreateThread("hash_thread", (SceKernelThreadEntry)hash_thread, 0x40, 0x10000, 0, 0, NULL);
if (thid >= 0)
sceKernelStartThread(thid, sizeof(HashArguments), &args);
dialog_step = DIALOG_STEP_HASHING;
}
break;
case DIALOG_STEP_HASH_DISPLAY:
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
dialog_step = DIALOG_STEP_NONE;
}
break;
case DIALOG_STEP_INSTALL_QUESTION:
if (msg_result == MESSAGE_DIALOG_RESULT_YES) {
initMessageDialog(MESSAGE_DIALOG_PROGRESS_BAR, language_container[INSTALLING]);

5
main.h
View File

@ -179,6 +179,11 @@ enum DialogSteps {
DIALOG_STEP_DOWNLOADED,
DIALOG_STEP_EXTRACTING,
DIALOG_STEP_EXTRACTED,
DIALOG_STEP_HASH_QUESTION,
DIALOG_STEP_HASH_CONFIRMED,
DIALOG_STEP_HASHING,
DIALOG_STEP_HASH_DISPLAY,
};
extern vita2d_pgf *font;

View File

@ -14,6 +14,9 @@ PASTE = "Paste"
DELETE = "Delete"
RENAME = "Rename"
NEW_FOLDER = "New 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."