static int list_cabinet( char *cab_dir ) { ERF erf; int ret = 0; HFDI fdi = FDICreate( cab_alloc, cab_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_lseek, cpuUNKNOWN, &erf ); if (!FDICopy( fdi, opt_cab_file, cab_dir, 0, list_notify, NULL, NULL )) ret = GetLastError(); FDIDestroy( fdi ); return ret; }
static void test_FDIDestroy(void) { HFDI hfdi; ERF erf; BOOL ret; /* native crashes if hfdi is NULL or invalid */ hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); /* successfully destroy hfdi */ ret = FDIDestroy(hfdi); ok(ret == TRUE, "Expected TRUE, got %d\n", ret); /* native crashes if you try to destroy hfdi twice */ if (0) { /* try to destroy hfdi again */ ret = FDIDestroy(hfdi); ok(ret == TRUE, "Expected TRUE, got %d\n", ret); } }
/*********************************************************************** * extract_cabinet_file * * Extract files from a cab file. */ static BOOL extract_cabinet_file(MSIPACKAGE* package, LPCWSTR source, LPCWSTR path) { HFDI hfdi; ERF erf; BOOL ret; char *cabinet; char *cab_path; CabData data; TRACE("Extracting %s to %s\n",debugstr_w(source), debugstr_w(path)); hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read, cabinet_write, cabinet_close, cabinet_seek, 0, &erf); if (!hfdi) { ERR("FDICreate failed\n"); return FALSE; } if (!(cabinet = strdupWtoA( source ))) { FDIDestroy(hfdi); return FALSE; } if (!(cab_path = strdupWtoA( path ))) { FDIDestroy(hfdi); msi_free(cabinet); return FALSE; } data.package = package; data.cab_path = cab_path; ret = FDICopy(hfdi, cabinet, "", 0, cabinet_notify, NULL, &data); if (!ret) ERR("FDICopy failed\n"); FDIDestroy(hfdi); msi_free(cabinet); msi_free(cab_path); return ret; }
/** * ExtractCabResource **/ UINT __fastcall ExtractCabResource( PSTR pszOutputPath, PSTR pszOutputPathAppend ) { ERF erf; EXTRACTDATA ed = { pszOutputPath, // PSTR pszOutputPath pszOutputPathAppend, // PSTR pszOutputPathAppend 0 // UINT uExtractedFiles }; HFDI hfdi = FDICreate( fdimalloc, fdifree, fdiopen, fdiread, fdiwrite, fdiclose, fdiseek, cpuUNKNOWN, &erf ); if (hfdi) { FDICopy(hfdi, "0", pszOutputPath, 0, fdiNotify, NULL, &ed); FDIDestroy(hfdi); } return(ed.uExtractedFiles); }
VOID TermDiamond( VOID ) { if(FdiContext) { FDIDestroy(FdiContext); FdiContext = NULL; } }
PVOID SfcabExtractMemory( PVOID CabPtr, ULONG CabSize, PULONG ExtractedBytes ) { HFDI hfdi; ERF erf; CHAR text[32]; CHAR name[1]; PVOID Buffer = NULL; CABDATA Data; if (ExtractedBytes == NULL) return NULL; __try { RtlSecureZeroMemory(&erf, sizeof(ERF)); hfdi = FDICreate((PFNALLOC)fdiAlloc, (PFNFREE)fdiFree, (PFNOPEN)fdiOpen, (PFNREAD)fdiRead, (PFNWRITE)fdiWrite, (PFNCLOSE)fdiClose, (PFNSEEK)fdiSeek, cpu80386, &erf); if (hfdi) { g_CabParam.Buffer = CabPtr; g_CabParam.Size = CabSize; g_CabParam.Offset = 0; RtlSecureZeroMemory(&text, sizeof(text)); #ifdef _WIN64 u64tostr_a((ULONG_PTR)&g_CabParam, text); #else ultostr_a((ULONG_PTR)&g_CabParam, text); #endif name[0] = 0; Data.Size = '_'; Data.Buffer = NULL; Data.Offset = 0; if (FDICopy(hfdi, name, text, 0, fdiNotify, 0, &Data)) { Buffer = Data.Buffer; *ExtractedBytes = Data.Size; } FDIDestroy(hfdi); } } __except (EXCEPTION_EXECUTE_HANDLER) { return NULL; } return Buffer; }
static int extract_cabinet( char *cab_dir ) { ERF erf; int ret = 0; HFDI fdi = FDICreate( cab_alloc, cab_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_lseek, cpuUNKNOWN, &erf ); if (!FDICopy( fdi, opt_cab_file, cab_dir, 0, extract_notify, NULL, NULL )) { ret = GetLastError(); WINE_WARN("FDICopy() failed: code %u\n", ret); } FDIDestroy( fdi ); return ret; }
/*********************************************************************** * extract_cabinet_file * * Extract files from a cab file. */ static BOOL extract_cabinet_file(MSIPACKAGE* package, struct media_info *mi) { LPSTR cabinet, cab_path = NULL; LPWSTR ptr; HFDI hfdi; ERF erf; BOOL ret = FALSE; CabData data; TRACE("Extracting %s\n", debugstr_w(mi->source)); hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read, cabinet_write, cabinet_close, cabinet_seek, 0, &erf); if (!hfdi) { ERR("FDICreate failed\n"); return FALSE; } ptr = strrchrW(mi->source, '\\') + 1; cabinet = strdupWtoA(ptr); if (!cabinet) goto done; cab_path = strdupWtoA(mi->source); if (!cab_path) goto done; cab_path[ptr - mi->source] = '\0'; data.package = package; data.mi = mi; ret = FDICopy(hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, &data); if (!ret) ERR("FDICopy failed\n"); done: FDIDestroy(hfdi); msi_free(cabinet); msi_free(cab_path); if (ret) mi->is_extracted = TRUE; return ret; }
static void test_FDICopy(void) { CCAB cabParams; HFDI hfdi; HFCI hfci; ERF erf; BOOL ret; char name[] = "extract.cab"; char path[MAX_PATH + 1]; GetCurrentDirectoryA(MAX_PATH, path); set_cab_parameters(&cabParams); hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open, fci_read, fci_write, fci_close, fci_seek, fci_delete, get_temp_file, &cabParams, NULL); ret = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress); ok(ret, "Failed to flush the cabinet\n"); FCIDestroy(hfci); hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); /* cabinet with no files or folders */ SetLastError(0xdeadbeef); ret = FDICopy(hfdi, name, path, 0, CopyProgress, NULL, 0); ok(ret == FALSE, "Expected FALSE, got %d\n", ret); todo_wine { ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); } FDIDestroy(hfdi); DeleteFileA(name); }
void STDCALL gcabd_destroy( HFDI hfdi ) { FDIDestroy( hfdi ); }
static void test_FDICreate(void) { HFDI hfdi; ERF erf; /* native crashes if pfnalloc is NULL */ /* FDICreate does not crash with a NULL pfnfree, * but FDIDestroy will crash when it tries to access it. */ if (0) { SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, NULL, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper); ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType); ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError); FDIDestroy(hfdi); } SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, fdi_free, NULL, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper); ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType); ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError); FDIDestroy(hfdi); SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, NULL, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper); ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType); ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError); FDIDestroy(hfdi); SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, NULL, fdi_close, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper); ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType); ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError); FDIDestroy(hfdi); SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, fdi_write, NULL, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper); ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType); ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError); FDIDestroy(hfdi); SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, fdi_write, fdi_close, NULL, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper); ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType); ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError); FDIDestroy(hfdi); SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, NULL); /* XP sets hfdi to a non-NULL value, but Vista sets it to NULL! */ ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); /* NULL is passed to FDICreate instead of &erf, so don't retest the erf member values. */ FDIDestroy(hfdi); /* bad cpu type */ SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, 0xcafebabe, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper); ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType); ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError); FDIDestroy(hfdi); /* pfnalloc fails */ SetLastError(0xdeadbeef); erf.erfOper = 0xcafefeed; erf.erfType = 0xdeadbabe; erf.fError = 0xdecaface; hfdi = FDICreate(fdi_alloc_bad, fdi_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi == NULL, "Expected NULL context, got %p\n", hfdi); ok(erf.erfOper == FDIERROR_ALLOC_FAIL, "Expected FDIERROR_ALLOC_FAIL, got %d\n", erf.erfOper); ok(erf.fError == TRUE, "Expected TRUE, got %d\n", erf.fError); todo_wine { ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok(erf.erfType == 0, "Expected 0, got %d\n", erf.erfType); } }
static void test_FDIIsCabinet(void) { ERF erf; BOOL ret; HFDI hfdi; INT_PTR fd; FDICABINETINFO cabinfo; char temp[] = "temp.txt"; char extract[] = "extract.cab"; create_test_files(); create_cab_file(); hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); ok(hfdi != NULL, "Expected non-NULL context\n"); /* native crashes if hfdi or cabinfo are NULL or invalid */ /* invalid file handle */ ZeroMemory(&cabinfo, sizeof(FDICABINETINFO)); SetLastError(0xdeadbeef); ret = FDIIsCabinet(hfdi, -1, &cabinfo); ok(ret == FALSE, "Expected FALSE, got %d\n", ret); ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); ok(cabinfo.cbCabinet == 0, "Expected 0, got %d\n", cabinfo.cbCabinet); ok(cabinfo.cFiles == 0, "Expected 0, got %d\n", cabinfo.cFiles); ok(cabinfo.cFolders == 0, "Expected 0, got %d\n", cabinfo.cFolders); ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet); ok(cabinfo.setID == 0, "Expected 0, got %d\n", cabinfo.setID); createTestFile("temp.txt"); fd = fdi_open(temp, 0, 0); /* file handle doesn't point to a cabinet */ ZeroMemory(&cabinfo, sizeof(FDICABINETINFO)); SetLastError(0xdeadbeef); ret = FDIIsCabinet(hfdi, fd, &cabinfo); ok(ret == FALSE, "Expected FALSE, got %d\n", ret); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok(cabinfo.cbCabinet == 0, "Expected 0, got %d\n", cabinfo.cbCabinet); ok(cabinfo.cFiles == 0, "Expected 0, got %d\n", cabinfo.cFiles); ok(cabinfo.cFolders == 0, "Expected 0, got %d\n", cabinfo.cFolders); ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet); ok(cabinfo.setID == 0, "Expected 0, got %d\n", cabinfo.setID); fdi_close(fd); DeleteFileA("temp.txt"); /* try a real cab */ fd = fdi_open(extract, 0, 0); ZeroMemory(&cabinfo, sizeof(FDICABINETINFO)); SetLastError(0xdeadbeef); ret = FDIIsCabinet(hfdi, fd, &cabinfo); ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); ok(cabinfo.cFiles == 4, "Expected 4, got %d\n", cabinfo.cFiles); ok(cabinfo.cFolders == 1, "Expected 1, got %d\n", cabinfo.cFolders); ok(cabinfo.setID == 0xbeef, "Expected 0xbeef, got %d\n", cabinfo.setID); todo_wine { ok(cabinfo.cbCabinet == 182, "Expected 182, got %d\n", cabinfo.cbCabinet); ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet); } fdi_close(fd); FDIDestroy(hfdi); delete_test_files(); }
/*********************************************************************** * Extract (CABINET.3) * * Extracts the contents of the cabinet file to the specified * destination. * * PARAMS * dest [I/O] Controls the operation of Extract. See NOTES. * szCabName [I] Filename of the cabinet to extract. * * RETURNS * Success: S_OK. * Failure: E_FAIL. * * NOTES * The following members of the dest struct control the operation * of Extract: * FileSize [O] The size of all files extracted up to CurrentFile. * Error [O] The error in case the extract operation fails. * FileList [I] A linked list of filenames. Extract only extracts * files from the cabinet that are in this list. * FileCount [O] Contains the number of files in FileList on * completion. * Operation [I] See Operation. * Destination [I] The destination directory. * CurrentFile [O] The last file extracted. * FilterList [I] A linked list of files that should not be extracted. * * Operation * If Operation contains EXTRACT_FILLFILELIST, then FileList will be * filled with all the files in the cabinet. If Operation contains * EXTRACT_EXTRACTFILES, then only the files in the FileList will * be extracted from the cabinet. EXTRACT_FILLFILELIST can be called * by itself, but EXTRACT_EXTRACTFILES must have a valid FileList * in order to succeed. If Operation contains both EXTRACT_FILLFILELIST * and EXTRACT_EXTRACTFILES, then all the files in the cabinet * will be extracted. */ HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName) { HRESULT res = S_OK; HFDI hfdi; char *str, *end, *path = NULL, *name = NULL; TRACE("(%p, %s)\n", dest, debugstr_a(szCabName)); hfdi = FDICreate(mem_alloc, mem_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &dest->Error); if (!hfdi) return E_FAIL; if (GetFileAttributesA(dest->Destination) == INVALID_FILE_ATTRIBUTES) { res = S_OK; goto end; } /* split the cabinet name into path + name */ str = HeapAlloc(GetProcessHeap(), 0, lstrlenA(szCabName)+1); if (!str) { res = E_OUTOFMEMORY; goto end; } lstrcpyA(str, szCabName); if ((end = strrchr(str, '\\'))) { path = str; end++; name = HeapAlloc( GetProcessHeap(), 0, strlen(end) + 1 ); if (!name) { res = E_OUTOFMEMORY; goto end; } strcpy( name, end ); *end = 0; } else { name = str; path = NULL; } dest->FileSize = 0; if (!FDICopy(hfdi, name, path, 0, fdi_notify_extract, NULL, dest)) res = HRESULT_FROM_WIN32(GetLastError()); end: HeapFree(GetProcessHeap(), 0, path); HeapFree(GetProcessHeap(), 0, name); FDIDestroy(hfdi); return res; }