mirror of
https://github.com/joel16/VitaShell.git
synced 2024-11-23 19:59:42 +00:00
commit
0e7ad6cef4
54
file.c
54
file.c
@ -20,6 +20,7 @@
|
||||
#include "archive.h"
|
||||
#include "file.h"
|
||||
#include "utils.h"
|
||||
#include "sha1.h"
|
||||
|
||||
static char *mount_points[] = {
|
||||
"app0:",
|
||||
@ -94,6 +95,59 @@ 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)()) {
|
||||
|
||||
// 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)++; // 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);
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
int getPathInfo(char *path, uint64_t *size, uint32_t *folders, uint32_t *files) {
|
||||
SceUID dfd = sceIoDopen(path);
|
||||
if (dfd >= 0) {
|
||||
|
1
file.h
1
file.h
@ -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)());
|
||||
|
70
io_process.c
70
io_process.c
@ -319,4 +319,72 @@ 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Since we hit here, we're done. Set progress to 100%
|
||||
sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 100);
|
||||
sceKernelDelayThread(COUNTUP_WAIT);
|
||||
|
||||
// Close
|
||||
closeWaitDialog();
|
||||
|
||||
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);
|
||||
dialog_step = DIALOG_STEP_HASH_DISPLAY;
|
||||
|
||||
// Wait for response
|
||||
while (dialog_step == DIALOG_STEP_HASH_DISPLAY) {
|
||||
sceKernelDelayThread(1000);
|
||||
}
|
||||
|
||||
closeWaitDialog();
|
||||
sceMsgDialogClose();
|
||||
|
||||
EXIT:
|
||||
|
||||
// Ensure the update thread ends gracefully
|
||||
if(thid>=0)
|
||||
sceKernelWaitThreadEnd(thid, NULL, NULL);
|
||||
|
||||
powerUnlock();
|
||||
|
||||
// Kill current thread
|
||||
return sceKernelExitDeleteThread(0);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -56,6 +56,9 @@ enum LanguageContainer {
|
||||
SYS_INFO,
|
||||
INSTALL_ALL,
|
||||
UPDATE_QUESTION,
|
||||
SHA1,
|
||||
HASHING,
|
||||
HASH_FILE_QUESTION,
|
||||
LANGUAGE_CONTRAINER_SIZE,
|
||||
};
|
||||
|
||||
|
57
main.c
57
main.c
@ -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,14 @@ void contextMenuCtrl() {
|
||||
dialog_step = DIALOG_STEP_NEW_FOLDER;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
case MENU_ENTRY_INSTALL_ALL:
|
||||
{
|
||||
@ -982,7 +998,48 @@ int dialogSteps() {
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
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);
|
||||
|
||||
dialog_step = DIALOG_STEP_HASHING;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DIALOG_STEP_INSTALL_QUESTION:
|
||||
if (msg_result == MESSAGE_DIALOG_RESULT_YES) {
|
||||
initMessageDialog(MESSAGE_DIALOG_PROGRESS_BAR, language_container[INSTALLING]);
|
||||
|
5
main.h
5
main.h
@ -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;
|
||||
|
@ -15,6 +15,9 @@ 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?"
|
||||
COPIED_FILE = "Copied %d file."
|
||||
COPIED_FOLDER = "Copied %d folder."
|
||||
COPIED_FILES_FOLDERS = "Copied %d files/folders."
|
||||
|
Loading…
Reference in New Issue
Block a user