//---------------------------------------------------------------------------- // // CAB file manipulation for extracting dump files // from dump CABs. // // Copyright (C) Microsoft Corporation, 2001. // //---------------------------------------------------------------------------- #include "pch.hpp" #pragma hdrstop #include #include #include #include #include #include "cmnutil.hpp" #define FDI_HR(Code) MAKE_HRESULT(SEVERITY_ERROR, 0xfd1, ((Code) & 0xffff)) struct FDI_CB_STATE { PSTR DmpFile; PSTR DstDir; ULONG FileFlags; INT_PTR DmpFh; }; PSTR FdiPathTail(PSTR Path) { PSTR Tail = strrchr(Path, '\\'); if (Tail == NULL) { Tail = strrchr(Path, '/'); if (Tail == NULL) { Tail = strrchr(Path, ':'); } } return Tail ? Tail + 1 : Path; } FNALLOC(FdiAlloc) { return malloc(cb); } FNFREE(FdiFree) { free(pv); } FNOPEN(FdiOpen) { return _open(pszFile, oflag, pmode); } FNREAD(FdiRead) { return _read((int)hf, pv, cb); } FNWRITE(FdiWrite) { return _write((int)hf, pv, cb); } FNCLOSE(FdiClose) { return _close((int)hf); } FNSEEK(FdiSeek) { return _lseek((int)hf, dist, seektype); } FNFDINOTIFY(FdiNotify) { FDI_CB_STATE* CbState = (FDI_CB_STATE*)pfdin->pv; PSTR Scan; switch(fdint) { case fdintCOPY_FILE: if (CbState->DmpFh >= 0) { return 0; } Scan = strrchr(pfdin->psz1, '.'); if (Scan == NULL || (_stricmp(Scan, ".dmp") != 0 && _stricmp(Scan, ".mdmp") != 0)) { return 0; } Scan = FdiPathTail(pfdin->psz1); if (*CbState->DstDir) { sprintf(CbState->DmpFile, "%s\\%s", CbState->DstDir, Scan); } else { strcpy(CbState->DmpFile, Scan); } CbState->DmpFh = FdiOpen(CbState->DmpFile, _O_BINARY | _O_WRONLY | CbState->FileFlags, _S_IREAD | _S_IWRITE); return CbState->DmpFh; case fdintCLOSE_FILE_INFO: // Leave the file open. return TRUE; } return 0; } HRESULT ExpandDumpCab(PCSTR CabFile, ULONG FileFlags, PSTR DmpFile, INT_PTR* DmpFh) { FDI_CB_STATE CbState; HFDI Context; ERF Err; BOOL Status; PSTR Env; Env = getenv("TMP"); if (Env == NULL) { Env = getenv("TEMP"); if (Env == NULL) { Env = ""; } } CbState.DmpFile = DmpFile; CbState.DstDir = Env; CbState.FileFlags = FileFlags; CbState.DmpFh = -1; Context = FDICreate(FdiAlloc, FdiFree, FdiOpen, FdiRead, FdiWrite, FdiClose, FdiSeek, cpuUNKNOWN, &Err); if (Context == NULL) { return FDI_HR(Err.erfOper); } Status = FDICopy(Context, "", (PSTR)CabFile, 0, FdiNotify, NULL, &CbState); FDIDestroy(Context); if (!Status) { return FDI_HR(Err.erfOper); } *DmpFh = CbState.DmpFh; return (CbState.DmpFh >= 0) ? S_OK : E_NOINTERFACE; }