|
|
//----------------------------------------------------------------------------
//
// CAB file manipulation for extracting dump files
// from dump CABs.
//
// Copyright (C) Microsoft Corporation, 2001.
//
//----------------------------------------------------------------------------
#include "pch.hpp"
#pragma hdrstop
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <share.h>
#include <fdi.h>
#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; }
|