int Unseven(const char *filename, STRING **list) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; SRes res; ISzAlloc allocImp; ISzAlloc allocTempImp; UInt16 *temp = NULL; size_t tempSize = 0; Bool do_save = (globaldata.gd_inidata->archive_dir && *(globaldata.gd_inidata->archive_dir))? False : True; char *subdir = NULL; // UInt32 parents[NUM_PARENTS_MAX]; // printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); if (!filename || !*filename) return -1; // error #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; #endif allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; #ifdef UNDER_CE if (InFile_OpenW(&archiveStream.file, L"\test.7z")) #else if (InFile_Open(&archiveStream.file, filename)) #endif { PrintError("can not open input file"); return -1; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if (res == SZ_OK) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; // const CSzFileItem *f = db.Files + i; size_t len; unsigned isDir = SzArEx_IsDir(&db, i); len = SzArEx_GetFileNameUtf16(&db, i, NULL); // len = SzArEx_GetFullNameLen(&db, i); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (!temp) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); /* { // progression output static char s[256]; snprintf(s, 255, _("Extracting (%d%%)"), ((i + 1) * 100) / db.NumFiles); HandleSemaphoreText(s, list, !i ? 1 : 0); }*/ if (isDir) ;//printf("/"); else { res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } // write data to disk { CSzFile outFile; size_t processedSize; size_t j; UInt16 *name = (UInt16 *)temp; const UInt16 *destPath = (const UInt16 *)name; WRes wres; for (j = 0; name[j] != 0; j++) if (name[j] == '/') { name[j] = 0; MyCreateDir(name, &subdir, &do_save); name[j] = CHAR_PATH_SEPARATOR; } if (isDir) { MyCreateDir(destPath, &subdir, &do_save); //printf("\n"); continue; } if (do_save == False) continue; wres = OutFile_OpenUtf16(&outFile, destPath, &subdir, &do_save); if (wres == -1) continue; if (wres) { PrintError("can not open output file"); res = SZ_ERROR_FAIL; break; } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { PrintError(_("can not write output file")); res = SZ_ERROR_FAIL; break; } if (File_Close(&outFile)) { PrintError(_("can not close output file")); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.Attribs, i)) SetFileAttributesW(destPath, db.Attribs.Vals[i]); #endif } //printf("\n"); } IAlloc_Free(&allocImp, outBuffer); } SzArEx_Free(&db, &allocImp); SzFree(NULL, temp); File_Close(&archiveStream.file); if (res == SZ_OK) { //printf("\nEverything is Ok\n"); return 0; } if (res == SZ_ERROR_UNSUPPORTED) PrintError(_("decoder doesn't support this archive")); else if (res == SZ_ERROR_MEM) PrintError(_("can not allocate memory")); else if (res == SZ_ERROR_CRC) PrintError(_("CRC error")); else printf("<br />ERROR #%d\n", res); return -1; }
static int sevenzip_parse_file_iterate_step_internal( file_archive_transfer_t *state, char *filename, const uint8_t **cdata, unsigned *cmode, uint32_t *size, uint32_t *csize, uint32_t *checksum, unsigned *payback, struct archive_extract_userdata *userdata) { struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)state->stream; const CSzFileItem *file = sevenzip_context->db.db.Files + sevenzip_context->index; if (sevenzip_context->index < sevenzip_context->db.db.NumFiles) { size_t len = SzArEx_GetFileNameUtf16(&sevenzip_context->db, sevenzip_context->index, NULL); uint64_t compressed_size = 0; if (sevenzip_context->packIndex < sevenzip_context->db.db.NumPackStreams) { compressed_size = sevenzip_context->db.db.PackSizes[sevenzip_context->packIndex]; sevenzip_context->packIndex++; } if (len < PATH_MAX_LENGTH && !file->IsDir) { char infile[PATH_MAX_LENGTH]; SRes res = SZ_ERROR_FAIL; uint16_t *temp = (uint16_t*)malloc(len * sizeof(uint16_t)); if (!temp) return -1; infile[0] = '\0'; SzArEx_GetFileNameUtf16(&sevenzip_context->db, sevenzip_context->index, temp); if (temp) { res = utf16_to_char_string(temp, infile, sizeof(infile)) ? SZ_OK : SZ_ERROR_FAIL; free(temp); } if (res != SZ_OK) return -1; strlcpy(filename, infile, PATH_MAX_LENGTH); *cmode = ARCHIVE_MODE_COMPRESSED; *checksum = file->Crc; *size = file->Size; *csize = compressed_size; } } *payback = 1; return 1; }
const char* _vde7zName(struct VDirEntry* vde) { struct VDirEntry7z* vde7z = (struct VDirEntry7z*) vde; if (!vde7z->utf8) { size_t nameLength = SzArEx_GetFileNameUtf16(&vde7z->vd->db, vde7z->index, 0) * sizeof(UInt16); UInt16* name = malloc(nameLength); SzArEx_GetFileNameUtf16(&vde7z->vd->db, vde7z->index, name); vde7z->utf8 = utf16to8(name, nameLength - sizeof(UInt16)); free(name); } return vde7z->utf8; }
ArchiveFile* SzArchive::OpenFile(const char* name) { u16 fname[512]; for (int i = 0; i < szarchive.NumFiles; i++) { unsigned isDir = SzArEx_IsDir(&szarchive, i); if (isDir) continue; int len = SzArEx_GetFileNameUtf16(&szarchive, i, fname); char szname[512]; int j = 0; for (; j < len && j < sizeof(szname) - 1; j++) szname[j] = fname[j]; szname[j] = 0; if (strcmp(name, szname)) continue; size_t offset = 0; size_t out_size_processed = 0; SRes res = SzArEx_Extract(&szarchive, &lookStream.vt, i, &block_idx, &out_buffer, &out_buffer_size, &offset, &out_size_processed, &g_Alloc, &g_Alloc); if (res != SZ_OK) return NULL; return new SzArchiveFile(out_buffer, offset, (u32)out_size_processed); } return NULL; }
std::wstring C7zip::FileNameIndex (int index) { std::wstring filename; if (m_db == NULL || m_db->FileNameOffsets == 0) { /* no filename */ return filename; } int namelen = SzArEx_GetFileNameUtf16(m_db, index, NULL); if (namelen <= 0) { /* no filename */ return filename; } filename.resize(namelen); SzArEx_GetFileNameUtf16(m_db, index, (UInt16 *)filename.c_str()); return filename; }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, #ifdef UNDER_CE LPWSTR #else LPSTR #endif lpCmdLine, int nCmdShow) #endif { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; SRes res = SZ_OK; ISzAlloc allocImp; ISzAlloc allocTempImp; WCHAR sfxPath[MAX_PATH + 2]; WCHAR path[MAX_PATH * 3 + 2]; #ifndef UNDER_CE WCHAR workCurDir[MAX_PATH + 32]; #endif size_t pathLen; DWORD winRes; const wchar_t *cmdLineParams; const char *errorMessage = NULL; Bool useShellExecute = True; DWORD exitCode = 0; LoadSecurityDlls(); #ifdef _CONSOLE SetConsoleCtrlHandler(HandlerRoutine, TRUE); #else UNUSED_VAR(hInstance); UNUSED_VAR(hPrevInstance); UNUSED_VAR(lpCmdLine); UNUSED_VAR(nCmdShow); #endif CrcGenerateTable(); allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH); if (winRes == 0 || winRes > MAX_PATH) return 1; { cmdLineParams = GetCommandLineW(); #ifndef UNDER_CE { Bool quoteMode = False; for (;; cmdLineParams++) { wchar_t c = *cmdLineParams; if (c == L'\"') quoteMode = !quoteMode; else if (c == 0 || (c == L' ' && !quoteMode)) break; } } #endif } { unsigned i; DWORD d; winRes = GetTempPathW(MAX_PATH, path); if (winRes == 0 || winRes > MAX_PATH) return 1; pathLen = wcslen(path); d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId(); for (i = 0;; i++, d += GetTickCount()) { if (i >= 100) { res = SZ_ERROR_FAIL; break; } wcscpy(path + pathLen, L"7z"); { wchar_t *s = path + wcslen(path); UInt32 value = d; unsigned k; for (k = 0; k < 8; k++) { unsigned t = value & 0xF; value >>= 4; s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10))); } s[k] = '\0'; } if (DoesFileOrDirExist(path)) continue; if (CreateDirectoryW(path, NULL)) { wcscat(path, WSTRING_PATH_SEPARATOR); pathLen = wcslen(path); break; } if (GetLastError() != ERROR_ALREADY_EXISTS) { res = SZ_ERROR_FAIL; break; } } #ifndef UNDER_CE wcscpy(workCurDir, path); #endif if (res != SZ_OK) errorMessage = "Can't create temp folder"; } if (res != SZ_OK) { if (!errorMessage) errorMessage = "Error"; PrintErrorMessage(errorMessage); return 1; } if (InFile_OpenW(&archiveStream.file, sfxPath) != 0) { errorMessage = "can not open input file"; res = SZ_ERROR_FAIL; } else { UInt64 pos = 0; if (!FindSignature(&archiveStream.file, &pos)) res = SZ_ERROR_FAIL; else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0) res = SZ_ERROR_FAIL; if (res != 0) errorMessage = "Can't find 7z archive"; } if (res == SZ_OK) { lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); } SzArEx_Init(&db); if (res == SZ_OK) { res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); } if (res == SZ_OK) { UInt32 executeFileIndex = (UInt32)(Int32)-1; UInt32 minPrice = 1 << 30; UInt32 i; UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; WCHAR *temp; if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH) { res = SZ_ERROR_FAIL; break; } temp = path + pathLen; SzArEx_GetFileNameUtf16(&db, i, temp); { res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } { CSzFile outFile; size_t processedSize; size_t j; size_t nameStartPos = 0; for (j = 0; temp[j] != 0; j++) { if (temp[j] == '/') { temp[j] = 0; MyCreateDir(path); temp[j] = CHAR_PATH_SEPARATOR; nameStartPos = j + 1; } } if (SzArEx_IsDir(&db, i)) { MyCreateDir(path); continue; } else { unsigned extLen; const WCHAR *name = temp + nameStartPos; unsigned len = (unsigned)wcslen(name); unsigned nameLen = FindExt(temp + nameStartPos, &extLen); unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen); unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen); unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12)); if (minPrice > price) { minPrice = price; executeFileIndex = i; useShellExecute = (extPrice != k_EXE_ExtIndex); } if (DoesFileOrDirExist(path)) { errorMessage = "Duplicate file"; res = SZ_ERROR_FAIL; break; } if (OutFile_OpenW(&outFile, path)) { errorMessage = "Can't open output file"; res = SZ_ERROR_FAIL; break; } } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { errorMessage = "Can't write output file"; res = SZ_ERROR_FAIL; } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.MTime, i)) { const CNtfsFileTime *t = db.MTime.Vals + i; FILETIME mTime; mTime.dwLowDateTime = t->Low; mTime.dwHighDateTime = t->High; SetFileTime(outFile.handle, NULL, NULL, &mTime); } #endif { SRes res2 = File_Close(&outFile); if (res != SZ_OK) break; if (res2 != SZ_OK) { res = res2; break; } } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.Attribs, i)) SetFileAttributesW(path, db.Attribs.Vals[i]); #endif } } if (res == SZ_OK) { if (executeFileIndex == (UInt32)(Int32)-1) { errorMessage = "There is no file to execute"; res = SZ_ERROR_FAIL; } else { WCHAR *temp = path + pathLen; UInt32 j; SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp); for (j = 0; temp[j] != 0; j++) if (temp[j] == '/') temp[j] = CHAR_PATH_SEPARATOR; } } IAlloc_Free(&allocImp, outBuffer); } SzArEx_Free(&db, &allocImp); File_Close(&archiveStream.file); if (res == SZ_OK) { HANDLE hProcess = 0; #ifndef UNDER_CE WCHAR oldCurDir[MAX_PATH + 2]; oldCurDir[0] = 0; { DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir); if (needLen == 0 || needLen > MAX_PATH) oldCurDir[0] = 0; SetCurrentDirectory(workCurDir); } #endif if (useShellExecute) { SHELLEXECUTEINFO ei; UINT32 executeRes; BOOL success; memset(&ei, 0, sizeof(ei)); ei.cbSize = sizeof(ei); ei.lpFile = path; ei.fMask = SEE_MASK_NOCLOSEPROCESS #ifndef UNDER_CE | SEE_MASK_FLAG_DDEWAIT #endif /* | SEE_MASK_NO_CONSOLE */ ; if (wcslen(cmdLineParams) != 0) ei.lpParameters = cmdLineParams; ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */ success = ShellExecuteEx(&ei); executeRes = (UINT32)(UINT_PTR)ei.hInstApp; if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */ res = SZ_ERROR_FAIL; else hProcess = ei.hProcess; } else { STARTUPINFOW si; PROCESS_INFORMATION pi; WCHAR cmdLine[MAX_PATH * 3]; wcscpy(cmdLine, path); wcscat(cmdLine, cmdLineParams); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0) res = SZ_ERROR_FAIL; else { CloseHandle(pi.hThread); hProcess = pi.hProcess; } } if (hProcess != 0) { WaitForSingleObject(hProcess, INFINITE); if (!GetExitCodeProcess(hProcess, &exitCode)) exitCode = 1; CloseHandle(hProcess); } #ifndef UNDER_CE SetCurrentDirectory(oldCurDir); #endif } path[pathLen] = L'\0'; RemoveDirWithSubItems(path); if (res == SZ_OK) return (int)exitCode; { if (res == SZ_ERROR_UNSUPPORTED) errorMessage = "Decoder doesn't support this archive"; else if (res == SZ_ERROR_MEM) errorMessage = "Can't allocate required memory"; else if (res == SZ_ERROR_CRC) errorMessage = "CRC error"; else { if (!errorMessage) errorMessage = "ERROR"; } if (errorMessage) PrintErrorMessage(errorMessage); } return 1; }
int MY_CDECL main(int numargs, char *args[]) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; SRes res; ISzAlloc allocImp; ISzAlloc allocTempImp; UInt16 *temp = NULL; size_t tempSize = 0; // UInt32 parents[NUM_PARENTS_MAX]; printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); if (numargs == 1) { printf( "Usage: 7zDec <command> <archive_name>\n\n" "<Commands>\n" " e: Extract files from archive (without using directory names)\n" " l: List contents of archive\n" " t: Test integrity of archive\n" " x: eXtract files with full paths\n"); return 0; } if (numargs < 3) { PrintError("incorrect command"); return 1; } #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; #endif allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; #ifdef UNDER_CE if (InFile_OpenW(&archiveStream.file, L"\test.7z")) #else if (InFile_Open(&archiveStream.file, args[2])) #endif { PrintError("can not open input file"); return 1; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if (res == SZ_OK) { char *command = args[1]; int listCommand = 0, testCommand = 0, fullPaths = 0; if (strcmp(command, "l") == 0) listCommand = 1; else if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "e") == 0) { } else if (strcmp(command, "x") == 0) { fullPaths = 1; } else { PrintError("incorrect command"); res = SZ_ERROR_FAIL; } if (res == SZ_OK) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; // const CSzFileItem *f = db.Files + i; size_t len; unsigned isDir = SzArEx_IsDir(&db, i); if (listCommand == 0 && isDir && !fullPaths) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); // len = SzArEx_GetFullNameLen(&db, i); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (!temp) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); /* if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp) { res = SZ_ERROR_FAIL; break; } */ if (listCommand) { char attr[8], s[32], t[32]; UInt64 fileSize; GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr); fileSize = SzArEx_GetFileSize(&db, i); UInt64ToStr(fileSize, s); if (SzBitWithVals_Check(&db.MTime, i)) ConvertFileTimeToString(&db.MTime.Vals[i], t); else { size_t j; for (j = 0; j < 19; j++) t[j] = ' '; t[j] = '\0'; } printf("%s %s %10s ", t, attr, s); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) printf("/"); printf("\n"); continue; } fputs(testCommand ? "Testing ": "Extracting ", stdout); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) printf("/"); else { res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } if (!testCommand) { CSzFile outFile; size_t processedSize; size_t j; UInt16 *name = (UInt16 *)temp; const UInt16 *destPath = (const UInt16 *)name; for (j = 0; name[j] != 0; j++) if (name[j] == '/') { if (fullPaths) { name[j] = 0; MyCreateDir(name); name[j] = CHAR_PATH_SEPARATOR; } else destPath = name + j + 1; } if (isDir) { MyCreateDir(destPath); printf("\n"); continue; } else if (OutFile_OpenUtf16(&outFile, destPath)) { PrintError("can not open output file"); res = SZ_ERROR_FAIL; break; } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZ_ERROR_FAIL; break; } if (File_Close(&outFile)) { PrintError("can not close output file"); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.Attribs, i)) SetFileAttributesW(destPath, db.Attribs.Vals[i]); #endif } printf("\n"); } IAlloc_Free(&allocImp, outBuffer); } } SzArEx_Free(&db, &allocImp); SzFree(NULL, temp); File_Close(&archiveStream.file); if (res == SZ_OK) { printf("\nEverything is Ok\n"); return 0; } if (res == SZ_ERROR_UNSUPPORTED) PrintError("decoder doesn't support this archive"); else if (res == SZ_ERROR_MEM) PrintError("can not allocate memory"); else if (res == SZ_ERROR_CRC) PrintError("CRC error"); else printf("\nERROR #%d\n", res); return 1; }
void ExtractPayload(const void* payload, size_t payloadSize, const WCHAR* prefix) { CMemInStream memStream; MemInStream_Init(&memStream, payload, payloadSize); CrcGenerateTable(); ISzAlloc alloc = { SzAlloc, SzFree }; CSzArEx db; SzArEx_Init(&db); SRes res = SzArEx_Open(&db, &memStream.s, &alloc, &alloc); if (res != SZ_OK) { SzArEx_Free(&db, &alloc); return; } WCHAR buffer[MAX_PATH]; UInt32 blockIndex = 0xFFFFFFFF; Byte* outBuffer = 0; size_t outBufferSize = 0; for (UInt32 i = 0; i < db.db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; const CSzFileItem* f = db.db.Files + i; SzArEx_GetFileNameUtf16(&db, i, (UInt16*)buffer); WCHAR* destPath = buffer; if (wcsncmp(destPath, prefix, 3) == 0 || wcsncmp(destPath, L"ALL", 3) == 0) { // Skip the prefix (X64/X32/ALL) and the path separater. destPath += 4; } else { // This file isn't for this arch. continue; } if (!f->IsDir) { res = SzArEx_Extract( &db, &memStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &alloc, &alloc); if (res != SZ_OK) { break; } } for (size_t j = 0; destPath[j] != L'\0'; ++j) { if (destPath[j] == L'/') { destPath[j] = L'\0'; CreateDirectory(destPath, NULL); destPath[j] = CHAR_PATH_SEPARATOR; } } if (f->IsDir) { CreateDirectory(destPath, NULL); continue; } CSzFile outFile; if (OutFile_OpenW(&outFile, destPath)) { res = SZ_ERROR_FAIL; break; } size_t processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { res = SZ_ERROR_FAIL; break; } if (File_Close(&outFile)) { res = SZ_ERROR_FAIL; break; } if (f->AttribDefined) SetFileAttributesW(destPath, f->Attrib); } IAlloc_Free(&alloc, outBuffer); SzArEx_Free(&db, &alloc); if (res == SZ_OK) { // Success. } }
ASM(LONG) sz_GetInfo(REG(a0, struct xadArchiveInfo *ai), REG(a6, struct xadMasterBase *xadMasterBase)) #endif { #ifdef __amigaos4__ IExec = (struct ExecIFace *)(*(struct ExecBase **)4)->MainInterface; newlibbase = OpenLibrary("newlib.library", 52); if(newlibbase) INewlib = GetInterface(newlibbase, "main", 1, NULL); #elif defined(__AROS__) if(!(aroscbase = OpenLibrary("arosc.library", 41))) return(XADERR_RESOURCE); #else SysBase = *(struct ExecBase **)4; #endif ai->xai_PrivateClient = xadAllocVec(sizeof(struct xad7zprivate),MEMF_PRIVATE | MEMF_CLEAR); struct xad7zprivate *xad7z = ai->xai_PrivateClient; struct xadFileInfo *fi; long err=XADERR_OK; long res=SZ_OK; size_t namelen; UBYTE *namebuf; // was UWORD CFileXadInStream *archiveStream = &xad7z->archiveStream; CSzArEx *db = &xad7z->db; /* 7z archive database structure */ ISzAlloc allocImp; /* memory functions for main pool */ ISzAlloc allocTempImp; /* memory functions for temporary pool */ CLookToRead *lookStream = &xad7z->lookStream; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; archiveStream->ai = ai; #ifdef __amigaos4__ archiveStream->IxadMaster = IxadMaster; #else archiveStream->xadMasterBase = xadMasterBase; #endif archiveStream->InStream.Read = SzFileReadImp; archiveStream->InStream.Seek = SzFileSeekImp; if(namebuf = AllocVec(1024, MEMF_PRIVATE)) { LookToRead_CreateVTable(lookStream, False); lookStream->realStream = (ISeekInStream *)&archiveStream->InStream; LookToRead_Init(lookStream); xad7z->blockIndex = 0xfffffff; xad7z->outBuffer = 0; xad7z->outBufferSize = 0; CrcGenerateTable(); SzArEx_Init(db); res = SzArEx_Open(db, &lookStream->s, &allocImp, &allocTempImp); if(res == SZ_OK) { UInt32 i; for (i = 0; i < db->db.NumFiles; i++) { fi = (struct xadFileInfo *) xadAllocObjectA(XADOBJ_FILEINFO, NULL); if (!fi) return(XADERR_NOMEMORY); CSzFileItem *f = db->db.Files + i; fi->xfi_DataPos = 0; //ai->xai_InPos; // i fi->xfi_Size = f->Size; namelen = SzArEx_GetFileNameUtf16(db, i, namebuf); // & if (!(fi->xfi_FileName = xadConvertName(CHARSET_HOST, #if defined(__AROS__) && (AROS_BIG_ENDIAN == 0) XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_LITTLEENDIAN, #else XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_BIGENDIAN, #endif XAD_STRINGSIZE, namelen, XAD_CSTRING, namebuf, // no * TAG_DONE))) return(XADERR_NOMEMORY); xadConvertDates(XAD_DATEAMIGA,ConvertFileTime(&f->MTime), XAD_GETDATEXADDATE,&fi->xfi_Date, TAG_DONE); fi->xfi_CrunchSize = 0; //(long) (db->Database.PackSizes[i] << 32); //fi->xfi_Size; fi->xfi_Flags = 0; if(f->IsDir) { fi->xfi_Flags |= XADFIF_DIRECTORY; } if ((err = xadAddFileEntryA(fi, ai, NULL))) return(XADERR_NOMEMORY); } } FreeVec(namebuf); } return(sztoxaderr(res)); }
static size_t FolderOutStream_Write2(CFolderOutStream *p, const void *data, size_t size) { SizeT processedSize = 0; UInt16 *fullPath = NULL; SizeT pathLen = 0; SizeT curSize = 0; SRes res = SZ_OK; UInt32 i; SizeT dirLen = 0; if(p->outputDir) dirLen = wcslen(p->outputDir); while(size != 0) { if(p->file.handle == INVALID_HANDLE_VALUE) { UInt16 *filename; UInt32 index = p->startIndex + p->currentIndex; const CSzFileItem *fileItem = p->ar->db.Files + index; SizeT len = SzArEx_GetFileNameUtf16(p->ar, index, NULL); if(len + dirLen > pathLen) { free(fullPath); pathLen = len + dirLen; fullPath = (UInt16*)malloc(pathLen * sizeof(fullPath[0])); if(fullPath == 0) { res = SZ_ERROR_MEM; break; } if(p->outputDir) wcscpy_s(fullPath,pathLen,p->outputDir); } filename = fullPath + dirLen; SzArEx_GetFileNameUtf16(p->ar, index, filename); for (i = 0; fullPath[i] != 0 && i<pathLen; i++) if (fullPath[i] == '/') { fullPath[i] = 0; CreateDirectoryW(fullPath,NULL); fullPath[i] = CHAR_PATH_SEPARATOR; } if (fileItem->IsDir) { CreateDirectoryW(fullPath,NULL); continue; } else if(OutFile_OpenW(&p->file, fullPath)) { res = SZ_ERROR_FAIL; break; } #ifdef _SZ_ALLOC_DEBUG wprintf(L"\nExtract: %s", fullPath); #endif p->fileSize = fileItem->Size; p->checkCrc = fileItem->CrcDefined; p->crc = CRC_INIT_VAL; } curSize = size < p->fileSize ? size : (SizeT)p->fileSize; if(S_OK != File_Write(&p->file, data, &curSize)) { File_Close(&p->file); res = SZ_ERROR_FAIL; break; } if(p->checkCrc) p->crc = CrcUpdate(p->crc,data,curSize); data = (const Byte*)data + curSize; size -= curSize; p->fileSize -= curSize; p->folderSize -= curSize; processedSize += curSize; if(p->fileSize == 0) { UInt32 index = p->startIndex + p->currentIndex; const CSzFileItem *fileItem = p->ar->db.Files + index; p->currentIndex += 1; if(fileItem->MTimeDefined) SetFileTime(p->file.handle,NULL,NULL,(const FILETIME*)&fileItem->MTime); File_Close(&p->file); if(fileItem->AttribDefined) SetFileAttributesW(fullPath, fileItem->Attrib); if(fileItem->CrcDefined && CRC_GET_DIGEST(p->crc) != fileItem->Crc) { res = SZ_ERROR_CRC; break; } } } free(fullPath); return processedSize; }
bool SZFilePack::open(const char* packFileName) { close(); UInt32 i; SRes res; UInt16 *temp = NULL; size_t tempSize = 0; CBuf buf; buf.data = new byte[MAX_PATH]; buf.size = MAX_PATH; mPackFileName = packFileName; if ( InFile_Open(&mArchiveStream.file, packFileName) ) { PrintError("can not open input file"); return false; } FileInStream_CreateVTable(&mArchiveStream); LookToRead_CreateVTable(&mLookStream, False); mLookStream.realStream = &mArchiveStream.s; LookToRead_Init(&mLookStream); CrcGenerateTable(); SzArEx_Init(&mDb); res = SzArEx_Open(&mDb, &mLookStream.s, &mAllocImp, &mAllocTempImp); if (res == SZ_OK) { for (i = 0; i < mDb.db.NumFiles; i++) { size_t len; const CSzFileItem *f = mDb.db.Files + i; if (f->IsDir) continue; len = SzArEx_GetFileNameUtf16(&mDb, i, NULL); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&mDb, i, temp); if (res != SZ_OK) break; // 保存所有文件的索引号到hash表中 res = Utf16_To_Char(&buf, temp, 0); if (res != SZ_OK) break; //名字转成小写 _strlwr((char*)buf.data); string key = (const char*)buf.data; mIndexMap[key] = i; } } SzFree(NULL, temp); delete[] buf.data; mIsPackOpened = true; return true; }
int cli_7unz (cli_ctx *ctx, size_t offset) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; SRes res; UInt16 utf16buf[UTFBUFSZ], *utf16name = utf16buf; int namelen = UTFBUFSZ, found = CL_CLEAN; Int64 begin_of_archive = offset; UInt32 viruses_found = 0; /* Replacement for FileInStream_CreateVTable(&archiveStream); */ archiveStream.s.Read = FileInStream_fmap_Read; archiveStream.s.Seek = FileInStream_fmap_Seek; archiveStream.s.curpos = 0; archiveStream.file.fmap = *ctx->fmap; LookToRead_CreateVTable(&lookStream, False); if(archiveStream.s.Seek(&archiveStream.s, &begin_of_archive, SZ_SEEK_SET) != 0) return CL_CLEAN; lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); SzArEx_Init(&db); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if(res == SZ_OK) { UInt32 i, blockIndex = 0xFFFFFFFF; Byte *outBuffer = 0; size_t outBufferSize = 0; unsigned int encrypted = 0; for (i = 0; i < db.db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; const CSzFileItem *f = db.db.Files + i; char *name; size_t j; int newnamelen, fd; if((found = cli_checklimits("7unz", ctx, 0, 0, 0))) break; if (f->IsDir) continue; if(cli_checklimits("7unz", ctx, f->Size, 0, 0)) continue; if (!db.FileNameOffsets) newnamelen = 0; /* no filename */ else { newnamelen = SzArEx_GetFileNameUtf16(&db, i, NULL); if (newnamelen > namelen) { if(namelen > UTFBUFSZ) free(utf16name); utf16name = cli_malloc(newnamelen*2); if(!utf16name) { found = CL_EMEM; break; } namelen = newnamelen; } SzArEx_GetFileNameUtf16(&db, i, utf16name); } name = (char *)utf16name; for(j=0; j<(size_t)newnamelen; j++) /* FIXME */ name[j] = utf16name[j]; name[j] = 0; cli_dbgmsg("cli_7unz: extracting %s\n", name); res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if(res == SZ_ERROR_ENCRYPTED) { encrypted = 1; if(DETECT_ENCRYPTED) { cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n"); cli_append_virus(ctx, "Heuristics.Encrypted.7Zip"); viruses_found++; if(!SCAN_ALL) { found = CL_VIRUS; break; } } } if(cli_matchmeta(ctx, name, 0, f->Size, encrypted, i, f->CrcDefined ? f->Crc : 0, NULL)) { found = CL_VIRUS; viruses_found++; if (!SCAN_ALL) break; } if (res != SZ_OK) cli_dbgmsg("cli_unz: extraction failed with %d\n", res); else { if((found = cli_gentempfd(ctx->engine->tmpdir, &name, &fd))) break; cli_dbgmsg("cli_7unz: Saving to %s\n", name); if((size_t)cli_writen(fd, outBuffer + offset, outSizeProcessed) != outSizeProcessed) found = CL_EWRITE; else if ((found = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) viruses_found++; close(fd); if(!ctx->engine->keeptmp && cli_unlink(name)) found = CL_EUNLINK; free(name); if(found != CL_CLEAN) if (!(SCAN_ALL && found == CL_VIRUS)) break; } } IAlloc_Free(&allocImp, outBuffer); } SzArEx_Free(&db, &allocImp); if(namelen > UTFBUFSZ) free(utf16name); if (res == SZ_OK) cli_dbgmsg("cli_7unz: completed successfully\n"); else if (res == SZ_ERROR_UNSUPPORTED) cli_dbgmsg("cli_7unz: unsupported\n"); else if (res == SZ_ERROR_MEM) cli_dbgmsg("cli_7unz: oom\n"); else if (res == SZ_ERROR_CRC) cli_dbgmsg("cli_7unz: crc mismatch\n"); else cli_dbgmsg("cli_7unz: error %d\n", res); if (SCAN_ALL && viruses_found) return CL_VIRUS; return found; }
static struct string_list *compressed_7zip_file_list_new( const char *path, const char* ext) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; ISzAlloc allocImp; ISzAlloc allocTempImp; size_t temp_size = 0; struct string_list *list = NULL; /* These are the allocation routines - currently using * the non-standard 7zip choices. */ allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; if (InFile_Open(&archiveStream.file, path)) { RARCH_ERR("Could not open %s as 7z archive.\n",path); return NULL; } list = string_list_new(); if (!list) { File_Close(&archiveStream.file); return NULL; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK) { uint32_t i; struct string_list *ext_list = ext ? string_split(ext, "|"): NULL; SRes res = SZ_OK; uint16_t *temp = NULL; for (i = 0; i < db.db.NumFiles; i++) { union string_list_elem_attr attr; char infile[PATH_MAX_LENGTH]; const char *file_ext = NULL; size_t len = 0; bool supported_by_core = false; const CSzFileItem *f = db.db.Files + i; /* we skip over everything, which is a directory. */ if (f->IsDir) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); if (len > temp_size) { free(temp); temp_size = len; temp = (uint16_t *)malloc(temp_size * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); res = utf16_to_char_string(temp, infile, sizeof(infile)) ? SZ_OK : SZ_ERROR_FAIL; file_ext = path_get_extension(infile); if (string_list_find_elem_prefix(ext_list, ".", file_ext)) supported_by_core = true; /* * Currently we only support files without subdirs in the archives. * Folders are not supported (differences between win and lin. * Archives within archives should imho never be supported. */ if (!supported_by_core) continue; attr.i = RARCH_COMPRESSED_FILE_IN_ARCHIVE; if (!string_list_append(list, infile, attr)) { res = SZ_ERROR_MEM; break; } } string_list_free(ext_list); free(temp); if (res != SZ_OK) { /* Error handling */ RARCH_ERR("Failed to open compressed_file: \"%s\"\n", path); string_list_free(list); list = NULL; } } SzArEx_Free(&db, &allocImp); File_Close(&archiveStream.file); return list; }
int _7z_search_crc_match(_7z_file *new_7z, UINT32 search_crc, const char* search_filename, int search_filename_length, bool matchcrc, bool matchname) { UInt16 *temp = NULL; size_t tempSize = 0; for (int i = 0; i < new_7z->db.db.NumFiles; i++) { const CSzFileItem *f = new_7z->db.db.Files + i; size_t len; len = SzArEx_GetFileNameUtf16(&new_7z->db, i, NULL); // if it's a directory entry we don't care about it.. if (f->IsDir) continue; if (len > tempSize) { SZipFree(NULL, temp); tempSize = len; temp = (UInt16 *)SZipAlloc(NULL, tempSize * sizeof(temp[0])); if (temp == 0) { return -1; // memory error } } bool crcmatch = false; bool namematch = false; UINT64 size = f->Size; UINT32 crc = f->Crc; /* Check for a name match */ SzArEx_GetFileNameUtf16(&new_7z->db, i, temp); if (len == search_filename_length+1) { int j; for (j=0;j<search_filename_length;j++) { UINT8 sn = search_filename[j]; UINT16 zn = temp[j]; // these are utf16 // MAME filenames are always lowercase so be case insensitive if ((zn>=0x41) && (zn<=0x5a)) zn+=0x20; if (sn != zn) break; } if (j==search_filename_length) namematch = true; } /* Check for a CRC match */ if (crc==search_crc) crcmatch = true; bool found = false; if (matchcrc && matchname) { if (crcmatch && namematch) found = true; } else if (matchcrc) { if (crcmatch) found = true; } else if (matchname) { if (namematch) found = true; } if (found) { // printf("found %S %d %08x %08x %08x %s %d\n", temp, len, crc, search_crc, size, search_filename, search_filename_length); new_7z->curr_file_idx = i; new_7z->uncompressed_length = size; new_7z->crc = crc; SZipFree(NULL, temp); return i; } } SZipFree(NULL, temp); return -1; }
int MY_CDECL main(int numargs, char *args[]) { ISzAlloc allocImp; ISzAlloc allocTempImp; CFileInStream archiveStream; CLookToRead2 lookStream; CSzArEx db; SRes res; UInt16 *temp = NULL; size_t tempSize = 0; // UInt32 parents[NUM_PARENTS_MAX]; Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"); if (numargs == 1) { Print( "Usage: 7zDec <command> <archive_name>\n\n" "<Commands>\n" " e: Extract files from archive (without using directory names)\n" " l: List contents of archive\n" " t: Test integrity of archive\n" " x: eXtract files with full paths\n"); return 0; } if (numargs < 3) { PrintError("incorrect command"); return 1; } #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; #endif allocImp = g_Alloc; allocTempImp = g_Alloc; #ifdef UNDER_CE if (InFile_OpenW(&archiveStream.file, L"\test.7z")) #else if (InFile_Open(&archiveStream.file, args[2])) #endif { PrintError("can not open input file"); return 1; } FileInStream_CreateVTable(&archiveStream); LookToRead2_CreateVTable(&lookStream, False); lookStream.buf = NULL; res = SZ_OK; { lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize); if (!lookStream.buf) res = SZ_ERROR_MEM; else { lookStream.bufSize = kInputBufSize; lookStream.realStream = &archiveStream.vt; LookToRead2_Init(&lookStream); } } CrcGenerateTable(); SzArEx_Init(&db); if (res == SZ_OK) { res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp); } if (res == SZ_OK) { char *command = args[1]; int listCommand = 0, testCommand = 0, fullPaths = 0; if (strcmp(command, "l") == 0) listCommand = 1; else if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "e") == 0) { } else if (strcmp(command, "x") == 0) { fullPaths = 1; } else { PrintError("incorrect command"); res = SZ_ERROR_FAIL; } if (res == SZ_OK) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; // const CSzFileItem *f = db.Files + i; size_t len; unsigned isDir = SzArEx_IsDir(&db, i); if (listCommand == 0 && isDir && !fullPaths) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); // len = SzArEx_GetFullNameLen(&db, i); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (!temp) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); /* if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp) { res = SZ_ERROR_FAIL; break; } */ if (listCommand) { char attr[8], s[32], t[32]; UInt64 fileSize; GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr); fileSize = SzArEx_GetFileSize(&db, i); UInt64ToStr(fileSize, s, 10); if (SzBitWithVals_Check(&db.MTime, i)) ConvertFileTimeToString(&db.MTime.Vals[i], t); else { size_t j; for (j = 0; j < 19; j++) t[j] = ' '; t[j] = '\0'; } Print(t); Print(" "); Print(attr); Print(" "); Print(s); Print(" "); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) Print("/"); PrintLF(); continue; } Print(testCommand ? "Testing ": "Extracting "); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) Print("/"); else { res = SzArEx_Extract(&db, &lookStream.vt, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } if (!testCommand) { CSzFile outFile; size_t processedSize; size_t j; UInt16 *name = (UInt16 *)temp; const UInt16 *destPath = (const UInt16 *)name; for (j = 0; name[j] != 0; j++) if (name[j] == '/') { if (fullPaths) { name[j] = 0; MyCreateDir(name); name[j] = CHAR_PATH_SEPARATOR; } else destPath = name + j + 1; } if (isDir) { MyCreateDir(destPath); PrintLF(); continue; } else if (OutFile_OpenUtf16(&outFile, destPath)) { PrintError("can not open output file"); res = SZ_ERROR_FAIL; break; } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE { FILETIME mtime, ctime; FILETIME *mtimePtr = NULL; FILETIME *ctimePtr = NULL; if (SzBitWithVals_Check(&db.MTime, i)) { const CNtfsFileTime *t = &db.MTime.Vals[i]; mtime.dwLowDateTime = (DWORD)(t->Low); mtime.dwHighDateTime = (DWORD)(t->High); mtimePtr = &mtime; } if (SzBitWithVals_Check(&db.CTime, i)) { const CNtfsFileTime *t = &db.CTime.Vals[i]; ctime.dwLowDateTime = (DWORD)(t->Low); ctime.dwHighDateTime = (DWORD)(t->High); ctimePtr = &ctime; } if (mtimePtr || ctimePtr) SetFileTime(outFile.handle, ctimePtr, NULL, mtimePtr); } #endif if (File_Close(&outFile)) { PrintError("can not close output file"); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.Attribs, i)) { UInt32 attrib = db.Attribs.Vals[i]; /* p7zip stores posix attributes in high 16 bits and adds 0x8000 as marker. We remove posix bits, if we detect posix mode field */ if ((attrib & 0xF0000000) != 0) attrib &= 0x7FFF; SetFileAttributesW((LPCWSTR)destPath, attrib); } #endif } PrintLF(); } ISzAlloc_Free(&allocImp, outBuffer); } } SzFree(NULL, temp); SzArEx_Free(&db, &allocImp); ISzAlloc_Free(&allocImp, lookStream.buf); File_Close(&archiveStream.file); if (res == SZ_OK) { Print("\nEverything is Ok\n"); return 0; } if (res == SZ_ERROR_UNSUPPORTED) PrintError("decoder doesn't support this archive"); else if (res == SZ_ERROR_MEM) PrintError("can not allocate memory"); else if (res == SZ_ERROR_CRC) PrintError("CRC error"); else { char s[32]; UInt64ToStr(res, s, 0); PrintError(s); } return 1; }
bool Qt7zPackage::open() { if (m_p->m_isOpen) { return false; } SRes res; UInt16 *temp = NULL; size_t tempSize = 0; if (InFile_Open(&(m_p->m_archiveStream.file), m_p->m_packagePath.toUtf8().data())) { qDebug() << "Can not open file: " << m_p->m_packagePath; m_p->m_isOpen = false; return false; } FileInStream_CreateVTable(&(m_p->m_archiveStream)); LookToRead_CreateVTable(&(m_p->m_lookStream), False); m_p->m_lookStream.realStream = &(m_p->m_archiveStream.s); LookToRead_Init(&(m_p->m_lookStream)); CrcGenerateTable(); SzArEx_Init(&(m_p->m_db)); res = SzArEx_Open(&(m_p->m_db), &(m_p->m_lookStream.s), &(m_p->m_allocImp), &(m_p->m_allocTempImp)); if (res == SZ_OK) { for (UInt32 i = 0; i < m_p->m_db.db.NumFiles; i++) { size_t len = SzArEx_GetFileNameUtf16(&(m_p->m_db), i, NULL); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&(m_p->m_db), i, temp); // TODO: Codec? QString fileName = QString::fromUtf16(temp); m_p->m_fileNameList << fileName; const CSzFileItem &fileItem = m_p->m_db.db.Files[i]; Qt7zFileInfo fileInfo; fileInfo.fileName = fileName; fileInfo.arcName = m_p->m_packagePath; fileInfo.size = fileItem.Size; fileInfo.isDir = fileItem.IsDir; fileInfo.isCrcDefined = fileItem.CrcDefined; fileInfo.crc = fileItem.Crc; m_p->m_fileInfoList << fileInfo; if (res != SZ_OK) break; } } SzFree(NULL, temp); if (res == SZ_OK) { m_p->m_isOpen = true; return true; } else { m_p->m_isOpen = false; return false; } }
struct VFile* _vd7zOpenFile(struct VDir* vd, const char* path, int mode) { UNUSED(mode); // TODO: support truncating, appending and creating, and write struct VDir7z* vd7z = (struct VDir7z*) vd; if ((mode & O_RDWR) == O_RDWR) { // Read/Write support is not yet implemented. return 0; } if (mode & O_WRONLY) { // Write support is not yet implemented. return 0; } size_t pathLength = strlen(path); UInt32 i; for (i = 0; i < vd7z->db.NumFiles; ++i) { if (SzArEx_IsDir(&vd7z->db, i)) { continue; } size_t nameLength = SzArEx_GetFileNameUtf16(&vd7z->db, i, 0) * sizeof(UInt16); UInt16* name = malloc(nameLength); SzArEx_GetFileNameUtf16(&vd7z->db, i, name); if (utfcmp(name, path, nameLength - sizeof(UInt16), pathLength) == 0) { free(name); break; } free(name); } if (i == vd7z->db.NumFiles) { return 0; // No file found } struct VFile7z* vf = malloc(sizeof(struct VFile7z)); vf->vd = vd7z; size_t outBufferSize; UInt32 blockIndex; vf->outBuffer = 0; SRes res = SzArEx_Extract(&vd7z->db, &vd7z->lookStream.s, i, &blockIndex, &vf->outBuffer, &outBufferSize, &vf->bufferOffset, &vf->size, &vd7z->allocImp, &vd7z->allocTempImp); if (res != SZ_OK) { free(vf); return 0; } vf->d.close = _vf7zClose; vf->d.seek = _vf7zSeek; vf->d.read = _vf7zRead; vf->d.readline = VFileReadline; vf->d.write = _vf7zWrite; vf->d.map = _vf7zMap; vf->d.unmap = _vf7zUnmap; vf->d.truncate = _vf7zTruncate; vf->d.size = _vf7zSize; return &vf->d; }
/* Extract the relative path (needle) from a 7z archive * (path) and allocate a buf for it to write it in. * If optional_outfile is set, extract to that instead * and don't allocate buffer. */ static int content_7zip_file_read( const char *path, const char *needle, void **buf, const char *optional_outfile) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; ISzAlloc allocImp; ISzAlloc allocTempImp; uint8_t *output = 0; long outsize = -1; /*These are the allocation routines. * Currently using the non-standard 7zip choices. */ allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; if (InFile_Open(&archiveStream.file, path)) { RARCH_ERR("Could not open %s as 7z archive\n.", path); return -1; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK) { uint32_t i; bool file_found = false; uint16_t *temp = NULL; size_t temp_size = 0; uint32_t block_index = 0xFFFFFFFF; SRes res = SZ_OK; for (i = 0; i < db.db.NumFiles; i++) { size_t len; char infile[PATH_MAX_LENGTH]; size_t offset = 0; size_t outSizeProcessed = 0; const CSzFileItem *f = db.db.Files + i; /* We skip over everything which is not a directory. * FIXME: Why continue then if f->IsDir is true?*/ if (f->IsDir) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); if (len > temp_size) { free(temp); temp_size = len; temp = (uint16_t *)malloc(temp_size * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); res = utf16_to_char_string(temp, infile, sizeof(infile)) ? SZ_OK : SZ_ERROR_FAIL; if (string_is_equal(infile, needle)) { size_t output_size = 0; RARCH_LOG_OUTPUT("Opened archive %s. Now trying to extract %s\n", path, needle); /* C LZMA SDK does not support chunked extraction - see here: * sourceforge.net/p/sevenzip/discussion/45798/thread/6fb59aaf/ * */ file_found = true; res = SzArEx_Extract(&db, &lookStream.s, i, &block_index, &output, &output_size, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; /* This goes to the error section. */ outsize = outSizeProcessed; if (optional_outfile != NULL) { const void *ptr = (const void*)(output + offset); if (!retro_write_file(optional_outfile, ptr, outsize)) { RARCH_ERR("Could not open outfilepath %s.\n", optional_outfile); res = SZ_OK; file_found = true; outsize = -1; } } else { /*We could either use the 7Zip allocated buffer, * or create our own and use it. * We would however need to realloc anyways, because RetroArch * expects a \0 at the end, therefore we allocate new, * copy and free the old one. */ *buf = malloc(outsize + 1); ((char*)(*buf))[outsize] = '\0'; memcpy(*buf,output + offset,outsize); } break; } } free(temp); IAlloc_Free(&allocImp, output); if (!(file_found && res == SZ_OK)) { /* Error handling */ if (!file_found) RARCH_ERR("File %s not found in %s\n", needle, path); RARCH_ERR("Failed to open compressed file inside 7zip archive.\n"); outsize = -1; } } SzArEx_Free(&db, &allocImp); File_Close(&archiveStream.file); return outsize; }
int SzExtractFromBuf(const void* pBuf, unsigned int nBufLength, wchar_t* cUnPackPath, DWORD dwPathLength) { if(pBuf==NULL || nBufLength<=0) return 1; SRes res = SZ_OK; CBufInStream archiveStream; CLookToRead lookStream; CSzArEx db; ISzAlloc allocImp; ISzAlloc allocTempImp; const char *errorMessage = NULL; wchar_t path[MAX_PATH * 3 + 2] = {0}; size_t pathLen = wcslen(cUnPackPath); wcscpy_s(path,MAX_PATH * 3 + 2, cUnPackPath); if (cUnPackPath[pathLen - 1] != '\\') { wcscat_s(path, L"\\"); pathLen = wcslen(path); } CrcGenerateTable(); allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; BufInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); if (InBuf_Init(&archiveStream.buf, pBuf, nBufLength) != 0) { errorMessage = "can not open input file"; res = SZ_ERROR_FAIL; } else { UInt64 pos = 0; if (!FindSignature(&archiveStream.buf, &pos)) res = SZ_ERROR_FAIL; else if (InBuf_Seek(&archiveStream.buf, (Int64 *)&pos, SZ_SEEK_SET) != 0) res = SZ_ERROR_FAIL; if (res != 0) errorMessage = "Can't find 7z archive"; } if (res == SZ_OK) { lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); } SzArEx_Init(&db); if (res == SZ_OK) { res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); } if (res == SZ_OK) { UInt32 executeFileIndex = (UInt32)(Int32)-1; UInt32 minPrice = 1 << 30; UInt32 i; UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; const CSzFileItem *f = db.db.Files + i; size_t len; wchar_t *temp; len = SzArEx_GetFileNameUtf16(&db, i, NULL); if (len >= MAX_PATH) { res = SZ_ERROR_FAIL; break; } temp = path + pathLen; SzArEx_GetFileNameUtf16(&db, i, reinterpret_cast<UInt16*>(temp)); { res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } { CSzFile outFile; size_t processedSize; size_t j; size_t nameStartPos = 0; for (j = 0; temp[j] != 0; j++) { if (temp[j] == '/') { temp[j] = 0; MyCreateDir(path); temp[j] = CHAR_PATH_SEPARATOR; nameStartPos = j + 1; } } if (f->IsDir) { MyCreateDir(path); continue; } else { if (DoesFileOrDirExist(path)) { errorMessage = "Duplicate file"; res = SZ_ERROR_FAIL; break; } if (OutFile_OpenW(&outFile, path)) { errorMessage = "Can't open output file"; res = SZ_ERROR_FAIL; break; } } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { errorMessage = "Can't write output file"; res = SZ_ERROR_FAIL; } #ifdef USE_WINDOWS_FILE if (f->MTimeDefined) { FILETIME mTime; mTime.dwLowDateTime = f->MTime.Low; mTime.dwHighDateTime = f->MTime.High; SetFileTime(outFile.handle, NULL, NULL, &mTime); } #endif { SRes res2 = File_Close(&outFile); if (res != SZ_OK) break; if (res2 != SZ_OK) { res = res2; break; } } #ifdef USE_WINDOWS_FILE if (f->AttribDefined) SetFileAttributesW(path, f->Attrib); #endif } } IAlloc_Free(&allocImp, outBuffer); } SzArEx_Free(&db, &allocImp); if (res == SZ_OK) { _tcscpy_s(cUnPackPath, dwPathLength, path); return 0; } else return 1; }
bool F7ZFile::Open(bool quiet) { Archive = new C7zArchive(Reader); int skipped = 0; SRes res; res = Archive->Open(); if (res != SZ_OK) { delete Archive; Archive = NULL; if (!quiet) { Printf("\n" TEXTCOLOR_RED "%s: ", Filename); if (res == SZ_ERROR_UNSUPPORTED) { Printf("Decoder does not support this archive\n"); } else if (res == SZ_ERROR_MEM) { Printf("Cannot allocate memory\n"); } else if (res == SZ_ERROR_CRC) { Printf("CRC error\n"); } else { Printf("error #%d\n", res); } } return false; } NumLumps = Archive->DB.db.NumFiles; Lumps = new F7ZLump[NumLumps]; F7ZLump *lump_p = Lumps; TArray<UInt16> nameUTF16; TArray<char> nameASCII; for (DWORD i = 0; i < NumLumps; ++i) { CSzFileItem *file = &Archive->DB.db.Files[i]; // skip Directories if (file->IsDir) { skipped++; continue; } const size_t nameLength = SzArEx_GetFileNameUtf16(&Archive->DB, i, NULL); if (0 == nameLength) { ++skipped; continue; } nameUTF16.Resize(nameLength); nameASCII.Resize(nameLength); SzArEx_GetFileNameUtf16(&Archive->DB, i, &nameUTF16[0]); for (size_t c = 0; c < nameLength; ++c) { nameASCII[c] = static_cast<char>(nameUTF16[c]); } FixPathSeperator(&nameASCII[0]); FString name = &nameASCII[0]; name.ToLower(); lump_p->LumpNameSetup(name); lump_p->LumpSize = int(file->Size); lump_p->Owner = this; lump_p->Flags = LUMPF_ZIPFILE; lump_p->Position = i; lump_p->CheckEmbedded(); lump_p++; } // Resize the lump record array to its actual size NumLumps -= skipped; if (NumLumps > 0) { // Quick check for unsupported compression method TArray<char> temp; temp.Resize(Lumps[0].LumpSize); if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { if (!quiet) Printf("\n%s: unsupported 7z/LZMA file!\n", Filename); return false; } } if (!quiet) Printf(", %d lumps\n", NumLumps); // Entries in archives are sorted alphabetically qsort(&Lumps[0], NumLumps, sizeof(F7ZLump), lumpcmp); return true; }
/*! * \brief * Decompresses a single file from a 7zip archive. * * \param archive_file * Path to the archive to extract the file from. * * \param file_name * The fine within the archive to extract. * * \param uncompressed_data * Reference parameter to set the uncompressed datas pointer to. * * \param uncompressed_data_size * Reference parameter to set the uncompressed data size to. * * \returns * Returns true if the decompresseion was successfull, otherwise returns false. * * Decompresses a single file from a 7zip archive. */ bool DecompressFileEntry(cstring archive_file, cstring file_name, byte*& uncompressed_data, size_t& uncompressed_data_size) { CFileInStream archive_stream; CLookToRead look_stream; CSzArEx archive_desc; SRes result; ISzAlloc alloc_imp; wchar_t wide_file_name[MAX_PATH] = L""; // open the archive for reading if (InFile_Open(&archive_stream.file, archive_file)) return false; // convert the search file name to a wide char string for comparison later if(-1 == swprintf_s(wide_file_name, MAX_PATH, L"%S", file_name)) return false; // set up the memory handling functions alloc_imp.Alloc = AllocFunc; alloc_imp.Free = FreeFunc; FileInStream_CreateVTable(&archive_stream); LookToRead_CreateVTable(&look_stream, False); look_stream.realStream = &archive_stream.s; LookToRead_Init(&look_stream); CrcGenerateTable(); SzArEx_Init(&archive_desc); result = SzArEx_Open(&archive_desc, &look_stream.s, &alloc_imp, &alloc_imp); if(result == SZ_OK) { int index = -1; // search for the file in the archive for (uint32 i = 0; (index == -1) && (i < archive_desc.db.NumFiles); i++) { if(archive_desc.db.Files[i].IsDir) continue; // get the name of the file in the archive uint32 name_length = SzArEx_GetFileNameUtf16(&archive_desc, i, NULL); wchar_t* archive_file_name = new wchar_t[name_length]; SzArEx_GetFileNameUtf16(&archive_desc, i, (UInt16*)archive_file_name); // compare the file names if(wcscmp(wide_file_name, archive_file_name) == 0) index = i; // delete allocated memory delete [] archive_file_name; } if(index > -1) { // file found, so decompress it result = Decompress(archive_stream, archive_desc, look_stream, index, uncompressed_data, uncompressed_data_size); } } SzArEx_Free(&archive_desc, &alloc_imp); File_Close(&archive_stream.file); return result == SZ_OK; }