windows-nt/Source/XPSP1/NT/sdktools/debuggers/dbg-common/cab.cpp
2020-09-26 16:20:57 +08:00

172 lines
3.2 KiB
C++

//----------------------------------------------------------------------------
//
// 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;
}