示例#1
0
int extractArchivePath(char *src, char *dst, FileProcessParam *param) {
	if (!uf)
		return -1;

	SceIoStat stat;
	memset(&stat, 0, sizeof(SceIoStat));
	if (archiveFileGetstat(src, &stat) < 0) {
		FileList list;
		memset(&list, 0, sizeof(FileList));
		fileListGetArchiveEntries(&list, src, SORT_NONE);

		int ret = sceIoMkdir(dst, 0777);
		if (ret < 0 && ret != SCE_ERROR_ERRNO_EEXIST) {
			fileListEmpty(&list);
			return ret;
		}

		if (param) {
			if (param->value)
				(*param->value) += DIRECTORY_SIZE;

			if (param->SetProgress)
				param->SetProgress(param->value ? *param->value : 0, param->max);
			
			if (param->cancelHandler && param->cancelHandler()) {
				fileListEmpty(&list);
				return 0;
			}
		}

		FileListEntry *entry = list.head->next; // Ignore ..

		int i;
		for (i = 0; i < list.length - 1; i++) {
			char *src_path = malloc(strlen(src) + strlen(entry->name) + 2);
			snprintf(src_path, MAX_PATH_LENGTH, "%s%s", src, entry->name);

			char *dst_path = malloc(strlen(dst) + strlen(entry->name) + 2);
			snprintf(dst_path, MAX_PATH_LENGTH, "%s%s", dst, entry->name);

			int ret = extractArchivePath(src_path, dst_path, param);

			free(dst_path);
			free(src_path);

			if (ret <= 0) {
				fileListEmpty(&list);
				return ret;
			}

			entry = entry->next;
		}

		fileListEmpty(&list);
	} else {
		SceUID fdsrc = archiveFileOpen(src, SCE_O_RDONLY, 0);
		if (fdsrc < 0)
			return fdsrc;

		SceUID fddst = sceIoOpen(dst, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
		if (fddst < 0) {
			archiveFileClose(fdsrc);
			return fddst;
		}

		void *buf = malloc(TRANSFER_SIZE);

		uint64_t seek = 0;

		while (1) {
			int read = archiveFileRead(fdsrc, buf, TRANSFER_SIZE);
			if (read < 0) {
				free(buf);

				sceIoClose(fddst);
				archiveFileClose(fdsrc);

				return read;
			}

			if (read == 0)
				break;

			int written = sceIoWrite(fddst, buf, read);
			if (written == SCE_ERROR_ERRNO_ENODEV) {
				fddst = sceIoOpen(dst, SCE_O_WRONLY | SCE_O_CREAT, 0777);
				if (fddst >= 0) {
					sceIoLseek(fddst, seek, SCE_SEEK_SET);
					written = sceIoWrite(fddst, buf, read);
				}
			}

			if (written < 0) {
				free(buf);

				sceIoClose(fddst);
				archiveFileClose(fdsrc);

				return written;
			}

			seek += written;

			if (param) {
				if (param->value)
					(*param->value) += read;

				if (param->SetProgress)
					param->SetProgress(param->value ? *param->value : 0, param->max);

				if (param->cancelHandler && param->cancelHandler()) {
					free(buf);

					sceIoClose(fddst);
					archiveFileClose(fdsrc);

					return 0;
				}
			}
		}

		free(buf);

		sceIoClose(fddst);
		archiveFileClose(fdsrc);
	}

	return 1;
}
示例#2
0
int copy_thread(SceSize args_size, CopyArguments *args) {
	SceUID thid = -1;

	// Set progress to 0%
	sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 0);
	sceKernelDelayThread(DIALOG_WAIT); // Needed to see the percentage

	char src_path[MAX_PATH_LENGTH], dst_path[MAX_PATH_LENGTH];
	FileListEntry *copy_entry = NULL;

	if (args->copy_mode == COPY_MODE_MOVE) { // Move
		// Update thread
		thid = createStartUpdateThread(args->copy_list->length);

		copy_entry = args->copy_list->head;

		int i;
		for (i = 0; i < args->copy_list->length; i++) {
			snprintf(src_path, MAX_PATH_LENGTH, "%s%s", args->copy_list->path, copy_entry->name);
			snprintf(dst_path, MAX_PATH_LENGTH, "%s%s", args->file_list->path, copy_entry->name);

			int res = sceIoRename(src_path, dst_path);
			// TODO: if (res == SCE_ERROR_ERRNO_EEXIST) if folder
			if (res < 0) {
				closeWaitDialog();
				errorDialog(res);
				goto EXIT;
			}

			SetProgress(i + 1, args->copy_list->length);

			copy_entry = copy_entry->next;
		}

		// Set progress to 100%
		sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 100);
		sceKernelDelayThread(COUNTUP_WAIT);

		// Close
		sceMsgDialogClose();

		dialog_step = DIALOG_STEP_MOVED;
	} else { // Copy
		if (args->copy_mode == COPY_MODE_EXTRACT)
			archiveOpen(args->archive_path);

		// Get src paths info
		uint32_t size = 0, folders = 0, files = 0;

		copy_entry = args->copy_list->head;

		int i;
		for (i = 0; i < args->copy_list->length; i++) {
			disableAutoSuspend();

			snprintf(src_path, MAX_PATH_LENGTH, "%s%s", args->copy_list->path, copy_entry->name);

			if (args->copy_mode == COPY_MODE_EXTRACT) {
				addEndSlash(src_path);
				getArchivePathInfo(src_path, &size, &folders, &files);
			} else {
				removeEndSlash(src_path);
				getPathInfo(src_path, &size, &folders, &files);
			}

			copy_entry = copy_entry->next;
		}

		// Update thread
		thid = createStartUpdateThread(size + folders);

		// Copy process
		uint32_t value = 0;

		copy_entry = args->copy_list->head;

		for (i = 0; i < args->copy_list->length; i++) {
			snprintf(src_path, MAX_PATH_LENGTH, "%s%s", args->copy_list->path, copy_entry->name);
			snprintf(dst_path, MAX_PATH_LENGTH, "%s%s", args->file_list->path, copy_entry->name);

			if (args->copy_mode == COPY_MODE_EXTRACT) {
				addEndSlash(src_path);
				addEndSlash(dst_path);

				int res = extractArchivePath(src_path, dst_path, &value, size + folders, SetProgress);
				if (res < 0) {
					closeWaitDialog();
					errorDialog(res);
					goto EXIT;
				}
			} else {
				removeEndSlash(src_path);
				removeEndSlash(dst_path);

				int res = copyPath(src_path, dst_path, &value, size + folders, SetProgress);
				if (res < 0) {
					closeWaitDialog();
					errorDialog(res);
					goto EXIT;
				}
			}

			copy_entry = copy_entry->next;
		}

		// Set progress to 100%
		sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 100);
		sceKernelDelayThread(COUNTUP_WAIT);

		// Close
		sceMsgDialogClose();

		dialog_step = DIALOG_STEP_COPIED;
	}

EXIT:
	if (thid >= 0)
		sceKernelWaitThreadEnd(thid, NULL, NULL);

	return sceKernelExitDeleteThread(0);
}