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 void _7z_close(ar_archive *ar) { ar_archive_7z *_7z = (ar_archive_7z *)ar; free(_7z->entry_name); SzArEx_Free(&_7z->data, &gSzAlloc); IAlloc_Free(&gSzAlloc, _7z->uncomp.buffer); }
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) { SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); if (res != SZ_OK) SzArEx_Free(p, allocMain); return res; }
void Qt7zPackage::close() { if (m_p->m_isOpen) { SzArEx_Free(&(m_p->m_db), &(m_p->m_allocImp)); File_Close(&(m_p->m_archiveStream.file)); m_p->m_isOpen = false; } }
~C7zArchive() { if (OutBuffer != NULL) { IAlloc_Free(&g_Alloc, OutBuffer); } SzArEx_Free(&DB, &g_Alloc); }
void SZFilePack::close() { if (mIsPackOpened) { SzArEx_Free(&mDb, &mAllocImp); File_Close(&mArchiveStream.file); mIndexMap.clear(); mIsPackOpened = false; } }
CArchive7Zip::~CArchive7Zip() { if (outBuffer) { IAlloc_Free(&allocImp, outBuffer); } if (isOpen) { File_Close(&archiveStream.file); } SzArEx_Free(&db, &allocImp); }
SzArchive::~SzArchive() { if (lookStream.buf != NULL) { File_Close(&archiveStream.file); ISzAlloc_Free(&g_Alloc, lookStream.buf); if (out_buffer != NULL) ISzAlloc_Free(&g_Alloc, out_buffer); SzArEx_Free(&szarchive, &g_Alloc); } }
bool _vd7zClose(struct VDir* vd) { struct VDir7z* vd7z = (struct VDir7z*) vd; SzArEx_Free(&vd7z->db, &vd7z->allocImp); File_Close(&vd7z->archiveStream.file); free(vd7z->dirent.utf8); vd7z->dirent.utf8 = 0; free(vd7z); return true; }
ASM(void) sz_Free(REG(a0, struct xadArchiveInfo *ai), REG(a6, struct xadMasterBase *xadMasterBase)) #endif { /* This function needs to free all the stuff allocated in info or unarchive function. It may be called multiple times, so clear freed entries! */ ISzAlloc allocImp; /* memory functions for main pool */ ISzAlloc allocTempImp; /* memory functions for temporary pool */ allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; struct xad7zprivate *xad7z = ai->xai_PrivateClient; CSzArEx *db = &xad7z->db; UInt32 *blockIndex = &xad7z->blockIndex; Byte **outBuffer = &xad7z->outBuffer; size_t *outBufferSize = &xad7z->outBufferSize; // allocImp.Free(NULL,*outBuffer); SzArEx_Free(db, &allocImp); *outBuffer=0; *blockIndex = 0xfffffff; *outBufferSize = 0; if(g_buffer) { FreeVec(g_buffer); g_buffer = NULL; } // CrcFreeTable(); xadFreeObjectA(ai->xai_PrivateClient,NULL); ai->xai_PrivateClient = NULL; #ifdef __amigaos4__ DropInterface(INewlib); CloseLibrary(newlibbase); INewlib = NULL; newlibbase = NULL; #endif #ifdef __AROS__ CloseLibrary(aroscbase); aroscbase = NULL; #endif }
static void free__7z_file(_7z_file *_7z) { if (_7z != NULL) { if (_7z->archiveStream.file._7z_osdfile != NULL) osd_close(_7z->archiveStream.file._7z_osdfile); if (_7z->filename != NULL) free((void *)_7z->filename); if (_7z->outBuffer) IAlloc_Free(&_7z->allocImp, _7z->outBuffer); if (_7z->inited) SzArEx_Free(&_7z->db, &_7z->allocImp); free(_7z); } }
static void sevenzip_stream_free(void *data) { struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)data; if (!sevenzip_context) return; if (sevenzip_context->output) { IAlloc_Free(&sevenzip_context->allocImp, sevenzip_context->output); sevenzip_context->output = NULL; sevenzip_context->handle->data = NULL; } SzArEx_Free(&sevenzip_context->db, &sevenzip_context->allocImp); File_Close(&sevenzip_context->archiveStream.file); }
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. } }
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; }
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; }
static void finalize_sevenzip_in_file(value sevenzip) { CSzArEx db = sevenzip_in_file_val(sevenzip); SzArEx_Free(&db, &allocImp); }
int auxio_load_archive(const char *filename, unsigned char **dataout, int *datasize, int *dataoffset, const char *filetoload, char *outname) { FILE *f; unsigned char idbuf[4]; int filesFound = 0; std::vector<char *> filelist; // list of files we can load in this archive // default case: outname is filename if (outname) { strcpy(outname, filename); } f = fopen(filename, "rb"); if (!f) { return 0; // no good } fread(idbuf, 4, 1, f); fclose(f); // printf("ID bytes %c %c %x %x\n", idbuf[0], idbuf[1], idbuf[2], idbuf[3]); if ((idbuf[0] == 'P') && (idbuf[1] == 'K') && (idbuf[2] == 0x03) && (idbuf[3] == 0x04)) { // it's zip unzFile zipArchive; char file_name[1024]; unz_file_info info; int nlen; int ret = 0; zipArchive = unzOpen(filename); if (!zipArchive) { return 0; } unzGoToFirstFile(zipArchive); for (;;) { if (unzGetCurrentFileInfo(zipArchive, &info, file_name, 1024, NULL, 0, NULL, 0) == UNZ_OK) { if (filetoload != NULL) { if (!strcasecmp(filetoload, file_name)) { int length; unsigned char *buffer; unzOpenCurrentFile(zipArchive); length = info.uncompressed_size; buffer = (unsigned char *)malloc(length); ret = unzReadCurrentFile(zipArchive, buffer, length); if (ret != length) { free(buffer); return 0; } unzCloseCurrentFile(zipArchive); unzClose(zipArchive); *datasize = length; *dataout = buffer; *dataoffset = 0; return 1; } } else { if (checkExtension(file_name)) { char *tmpstr; tmpstr = (char *)malloc(strlen(file_name)+1); strcpy(tmpstr, file_name); // add to the file list filelist.push_back(tmpstr); filesFound++; } } } else { break; } ret = unzGoToNextFile(zipArchive); if (ret == UNZ_END_OF_LIST_OF_FILE) { break; } if (ret != UNZ_OK) { unzClose(zipArchive); return 0; } } unzClose(zipArchive); } else if ((idbuf[0] == '7') && (idbuf[1] == 'z') && (idbuf[2] == 0xbc) && (idbuf[3] == 0xaf)) { // it's 7zip CFileInStream archiveStream; SRes res; CSzArEx db; /* 7z archive database structure */ ISzAlloc allocImp; /* memory functions for main pool */ ISzAlloc allocTempImp; /* memory functions for temporary pool */ archiveStream.File = fopen(filename, "rb"); if (!archiveStream.File) { return 0; } archiveStream.InStream.Read = SzFileReadImp; archiveStream.InStream.Seek = SzFileSeekImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; // init 7zip internals CrcGenerateTable(); SzArEx_Init(&db); res = SzArEx_Open(&db, &archiveStream.InStream, &allocImp, &allocTempImp); if (res == SZ_OK) { int i; for (i = 0; i < db.db.NumFiles; i++) { CSzFileItem *item = db.db.Files + i; if (!item->IsDirectory) { if (filetoload != NULL) { if (!strcasecmp(filetoload, item->Name)) { 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) */ size_t offset; size_t outSizeProcessed; res = SzAr_Extract(&db, &archiveStream.InStream, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res == SZ_OK) { SzArEx_Free(&db, &allocImp); fclose(archiveStream.File); *datasize = (int)outBufferSize; *dataout = (unsigned char *)outBuffer; *dataoffset = (int)offset; return 1; } else { std::cout << "Error extracting 7zip!\n"; } } } if (checkExtension(item->Name)) { char *tmpstr; tmpstr = (char *)malloc(strlen(item->Name)+1); strcpy(tmpstr, item->Name); // add to the file list filelist.push_back(tmpstr); filesFound++; } } } SzArEx_Free(&db, &allocImp); fclose(archiveStream.File); } } else if ((idbuf[0] == 'R') && (idbuf[1] == 'a') && (idbuf[2] == 'r') && (idbuf[3] == '!')) { // it's rar } // if we found any files and weren't forced to load them, handle accordingly if (filesFound) { // only 1 file found, just run it if (filesFound == 1) { char fname[512]; strcpy(fname, filelist[0]); free(filelist[0]); filelist.clear(); strcpy(outname, fname); return auxio_load_archive(filename, dataout, datasize, dataoffset, fname, NULL); } else // multiple files we can handle found, give the user a choice { int sel; char fname[512]; filepicker = create_archselect(); tree = lookup_widget(filepicker, "archtree"); gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW (tree), FALSE); g_signal_connect(G_OBJECT(tree), "button_press_event", G_CALLBACK(check_list_double), NULL); // set up our tree store treestore = gtk_tree_store_new(1, G_TYPE_STRING); // attach the store to the tree gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(treestore)); // create a cell renderer using the stock text one renderer = gtk_cell_renderer_text_new(); // create a display column using the renderer column = gtk_tree_view_column_new_with_attributes ("NES file", renderer, "text", 0, NULL); // add the display column and renderer to the tree view gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); // get the selection object too selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); // add the filenames for (int fn = 0; fn < filelist.size(); fn++) { gtk_tree_store_insert(treestore, &treeiters[fn], NULL, 999999); gtk_tree_store_set(treestore, &treeiters[fn], 0, filelist[fn], -1); } gtk_widget_show(filepicker); run_picker = true; cancelled = false; while (run_picker) { gtk_main_iteration_do(FALSE); } sel = find_current_selection(); gtk_widget_destroy(filepicker); // was something picked? if ((sel != -1) && (!cancelled)) { strcpy(fname, filelist[sel]); } // free all the temp filenames for (int fn = 0; fn < filelist.size(); fn++) { free(filelist[fn]); } // and wipe the vector filelist.clear(); if ((sel != -1) && (!cancelled)) { if (outname) { strcpy(outname, fname); } return auxio_load_archive(filename, dataout, datasize, dataoffset, fname, NULL); } } } return 0; }
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; }
/* 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; }
/*! * \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; }
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 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; }
BOOL main_unpack(CHAR *patch_file, struct MemoryStruct *patch, CHAR *grf) { CHAR mes[256]; CMemInStream memory_stream; CLookToRead lookStream; CSzArEx db; SRes res; ISzAlloc allocImp; ISzAlloc allocTempImp; memory_stream.buf = patch->memory; memory_stream.ptr = memory_stream.buf; memory_stream.size = patch->size; memory_stream.s.Read = &lzma_memory_read; memory_stream.s.Seek = &lzma_memory_seek; sprintf_s(mes, sizeof(mes), "Распаковка: %s...", patch_file); dialog_set_status(mes); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &memory_stream.s; LookToRead_Init(&lookStream); allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; SzArEx_Init(&db); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if (res == SZ_OK) { UInt32 i; UInt32 blockIndex = 0xFFFFFFFF; Byte *outBuffer = 0; size_t outBufferSize = 0; void *grf_handle; // if we are working with grf we should // open grf-file first if (grf != NULL) { grf_handle = grf_load(grf, TRUE); if (grf_handle == NULL) grf_handle = grf_new(grf, TRUE); if (grf_handle == NULL) { SzArEx_Free(&db, &allocImp); sprintf_s(mes, sizeof(mes), "Невозможно ни открыть, ни создать GRF-файл: %s", grf); dialog_set_status(mes); return RES_FAIL; } } for (i = 0; i < db.db.NumFiles; i++) { BOOL res; size_t offset; size_t outSizeProcessed; CSzFileItem *f = db.db.Files + i; if (!f->IsDir) { res = SzAr_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } res = (grf != NULL) ? main_target_grf(grf_handle, (WCHAR *)f->Name, f->IsDir, outBuffer + offset, outSizeProcessed) : main_target_fs((WCHAR *)f->Name, f->IsDir, outBuffer + offset, outSizeProcessed); if (res) { IAlloc_Free(&allocImp, outBuffer); SzArEx_Free(&db, &allocImp); return RES_FAIL; } } // if we're working with grf // close it if (grf != NULL) grf_free(grf_handle); IAlloc_Free(&allocImp, outBuffer); } SzArEx_Free(&db, &allocImp); if (res != SZ_OK) { if (res == SZ_ERROR_UNSUPPORTED) sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: Архив не поддерживается", patch_file); else if (res == SZ_ERROR_MEM) sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: Невозможно зарезервировать память", patch_file); else if (res == SZ_ERROR_CRC) sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: ошибка CRC", patch_file); else sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: ошибка #%d", patch_file, res); dialog_set_status(mes); return RES_FAIL; } return RES_OK; }
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; }