mirror of
https://github.com/joel16/VitaShell.git
synced 2024-11-23 19:59:42 +00:00
210 lines
4.9 KiB
C
210 lines
4.9 KiB
C
/*
|
|
VitaShell
|
|
Copyright (C) 2015-2017, TheFloW
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "main.h"
|
|
#include "init.h"
|
|
#include "io_process.h"
|
|
#include "refresh.h"
|
|
#include "package_installer.h"
|
|
#include "sfo.h"
|
|
#include "file.h"
|
|
#include "message_dialog.h"
|
|
#include "language.h"
|
|
#include "utils.h"
|
|
|
|
int isCustomHomebrew() {
|
|
uint32_t work[512/4];
|
|
|
|
if (ReadFile("ux0:temp/game/sce_sys/package/work.bin", work, sizeof(work)) != sizeof(work))
|
|
return 0;
|
|
|
|
int i;
|
|
for (i = 0; i < sizeof(work) / sizeof(uint32_t); i++)
|
|
if (work[i] != 0)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int refreshApp(const char *name) {
|
|
char app_path[MAX_PATH_LENGTH], param_path[MAX_PATH_LENGTH], license_path[MAX_PATH_LENGTH];
|
|
int res;
|
|
|
|
// Path
|
|
snprintf(app_path, MAX_PATH_LENGTH, "ux0:app/%s", name);
|
|
snprintf(param_path, MAX_PATH_LENGTH, "ux0:app/%s/sce_sys/param.sfo", name);
|
|
|
|
// Read param.sfo
|
|
void *sfo_buffer = NULL;
|
|
int sfo_size = allocateReadFile(param_path, &sfo_buffer);
|
|
if (sfo_size < 0) {
|
|
if (sfo_buffer)
|
|
free(sfo_buffer);
|
|
return sfo_size;
|
|
}
|
|
|
|
// Get titleid
|
|
char titleid[12];
|
|
getSfoString(sfo_buffer, "TITLE_ID", titleid, sizeof(titleid));
|
|
|
|
// Free sfo buffer
|
|
free(sfo_buffer);
|
|
|
|
// Check if app exists
|
|
if (checkAppExist(titleid)) {
|
|
char rif_name[48];
|
|
|
|
uint64_t aid;
|
|
sceRegMgrGetKeyBin("/CONFIG/NP", "account_id", &aid, sizeof(uint64_t));
|
|
|
|
// Check if bounded rif file exits
|
|
_sceNpDrmGetRifName(rif_name, 0, aid);
|
|
snprintf(license_path, MAX_PATH_LENGTH, "ux0:license/app/%s/%s", titleid, rif_name);
|
|
if (checkFileExist(license_path))
|
|
return 0;
|
|
|
|
// Check if fixed rif file exits
|
|
_sceNpDrmGetFixedRifName(rif_name, 0, 0);
|
|
snprintf(license_path, MAX_PATH_LENGTH, "ux0:license/app/%s/%s", titleid, rif_name);
|
|
if (checkFileExist(license_path))
|
|
return 0;
|
|
}
|
|
|
|
// Clean
|
|
removePath("ux0:temp/game", NULL);
|
|
sceIoMkdir("ux0:temp", 0006);
|
|
|
|
// Rename app
|
|
res = sceIoRename(app_path, "ux0:temp/game");
|
|
if (res < 0)
|
|
return res;
|
|
|
|
// Remove work.bin for custom homebrews
|
|
if (isCustomHomebrew())
|
|
sceIoRemove("ux0:temp/game/sce_sys/package/work.bin");
|
|
|
|
// Promote app
|
|
res = promoteApp("ux0:temp/game");
|
|
|
|
// Rename back if it failed
|
|
if (res < 0) {
|
|
sceIoRename("ux0:temp/game", app_path);
|
|
return res;
|
|
}
|
|
|
|
// Return success
|
|
return 1;
|
|
}
|
|
|
|
int refresh_thread(SceSize args, void *argp) {
|
|
SceUID thid = -1;
|
|
SceUID dfd = -1;
|
|
int folders = 0;
|
|
int count = 0;
|
|
int items = 0;
|
|
|
|
// 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
|
|
|
|
// Get number of folders
|
|
dfd = sceIoDopen("ux0:app");
|
|
if (dfd >= 0) {
|
|
int res = 0;
|
|
|
|
do {
|
|
SceIoDirent dir;
|
|
memset(&dir, 0, sizeof(SceIoDirent));
|
|
|
|
res = sceIoDread(dfd, &dir);
|
|
if (res > 0) {
|
|
if (SCE_S_ISDIR(dir.d_stat.st_mode)) {
|
|
if (strcmp(dir.d_name, vitashell_titleid) == 0)
|
|
continue;
|
|
|
|
// Count
|
|
folders++;
|
|
|
|
if (cancelHandler()) {
|
|
closeWaitDialog();
|
|
setDialogStep(DIALOG_STEP_CANCELLED);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
}
|
|
} while (res > 0);
|
|
|
|
sceIoDclose(dfd);
|
|
}
|
|
|
|
// Update thread
|
|
thid = createStartUpdateThread(folders, 0);
|
|
|
|
dfd = sceIoDopen("ux0:app");
|
|
if (dfd >= 0) {
|
|
int res = 0;
|
|
|
|
do {
|
|
SceIoDirent dir;
|
|
memset(&dir, 0, sizeof(SceIoDirent));
|
|
|
|
res = sceIoDread(dfd, &dir);
|
|
if (res > 0) {
|
|
if (SCE_S_ISDIR(dir.d_stat.st_mode)) {
|
|
if (strcmp(dir.d_name, vitashell_titleid) == 0)
|
|
continue;
|
|
|
|
// Refresh app
|
|
if (refreshApp(dir.d_name) == 1)
|
|
items++;
|
|
|
|
SetProgress(++count, folders);
|
|
|
|
if (cancelHandler()) {
|
|
closeWaitDialog();
|
|
setDialogStep(DIALOG_STEP_CANCELLED);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
}
|
|
} while (res > 0);
|
|
|
|
sceIoDclose(dfd);
|
|
}
|
|
|
|
// Set progress to 100%
|
|
sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 100);
|
|
sceKernelDelayThread(COUNTUP_WAIT);
|
|
|
|
// Close
|
|
closeWaitDialog();
|
|
|
|
infoDialog(language_container[REFRESHED], items);
|
|
|
|
EXIT:
|
|
if (thid >= 0)
|
|
sceKernelWaitThreadEnd(thid, NULL, NULL);
|
|
|
|
// Unlock power timers
|
|
powerUnlock();
|
|
|
|
return sceKernelExitDeleteThread(0);
|
|
} |