|
|
/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name: cabbing.cpp
Abstract: FDU main
Revision History: created derekm 02/23/00
******************************************************************************/
#include <stdafx.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <fci.h>
#include <fdi.h>
#include "pfarray.h"
#include "pfcab.h"
/////////////////////////////////////////////////////////////////////////////
// tracing
#ifdef THIS_FILE
#undef THIS_FILE
#endif
static char __szTraceSourceFile[] = __FILE__; #define THIS_FILE __szTraceSourceFile
/////////////////////////////////////////////////////////////////////////////
// structs
struct SPFFileInfo { LPSTR szCab; LPSTR szDestFile; LPSTR szFileName; BOOL fFound; };
/////////////////////////////////////////////////////////////////////////////
// utility
// **************************************************************************
static MyCabGetLastError() { DWORD dwErr; // this function assumes that it is called in an error state, so it will
// never return ERROR_SUCCESS
dwErr = GetLastError(); if (dwErr == ERROR_SUCCESS) { dwErr = _doserrno; if (dwErr == ERROR_SUCCESS) dwErr = ERROR_TOO_MANY_OPEN_FILES; }
return dwErr; }
// **************************************************************************
static void DeleteFromFileList(LPVOID pv) { SysFreeString((BSTR)pv); }
// **************************************************************************
static void SplitPath(LPCSTR szFullPath, LPSTR szPath, LPSTR szName) { LPSTR szEnd; szEnd = strrchr(szFullPath, '\\'); if (szEnd == NULL) { strcpy(szPath, ""); strcpy(szName, szFullPath); }
else { DWORD cb; cb = (DWORD)(LONG_PTR)(szEnd - szFullPath) + 1; strcpy(szName, szEnd + 1); strncpy(szPath, szFullPath, cb); szPath[cb] = 0; } }
/////////////////////////////////////////////////////////////////////////////
//
// **************************************************************************
static LPVOID DIAMONDAPI mem_alloc(ULONG cb) { return MyAlloc(cb); }
// **************************************************************************
static void DIAMONDAPI mem_free(LPVOID pv) { MyFree(pv); }
/////////////////////////////////////////////////////////////////////////////
//
// **************************************************************************
static INT_PTR DIAMONDAPI fci_open(LPSTR pszFile, int oflag, int pmode, int *err, LPVOID pv) { int result; result = _open(pszFile, oflag, pmode); if (result == -1) *err = errno;
return result; }
// **************************************************************************
static UINT DIAMONDAPI fci_read(INT_PTR hf, LPVOID memory, UINT cb, int *err, LPVOID pv) { UINT result; result = (UINT)_read((int)hf, memory, cb);
if (result != cb) *err = errno;
return result; }
// **************************************************************************
static UINT DIAMONDAPI fci_write(INT_PTR hf, LPVOID memory, UINT cb, int *err, LPVOID pv) { UINT result;
result = (UINT)_write((int)hf, memory, cb);
if (result != cb) *err = errno;
return result; }
// **************************************************************************
static int DIAMONDAPI fci_close(INT_PTR hf, int *err, LPVOID pv) { int result; result = _close((int)hf);
if (result != 0) *err = errno;
return result; }
// **************************************************************************
static long DIAMONDAPI fci_seek(INT_PTR hf, long dist, int seektype, int *err, LPVOID pv) { long result; result = _lseek((int)hf, dist, seektype);
if (result == -1) *err = errno;
return result; }
// **************************************************************************
static int DIAMONDAPI fci_delete(LPSTR pszFile, int *err, LPVOID pv) { int result; result = remove(pszFile);
if (result != 0) *err = errno;
return result; }
/////////////////////////////////////////////////////////////////////////////
//
// **************************************************************************
static int DIAMONDAPI fci_file_placed(PCCAB pccab, LPSTR pszFile, long cbFile, BOOL fContinuation, LPVOID pv) { return 0; }
// **************************************************************************
static BOOL DIAMONDAPI fci_get_temp_file(LPSTR pszTempName, int cbTempName, LPVOID pv) { char *psz = _tempnam("", "PCHPF"); // Get a name
BOOL res = FALSE;
if (psz != NULL) { if(strlen(psz) < (size_t)cbTempName) { strcpy(pszTempName, psz); // Copy to caller's buffer
res = TRUE; }
free(psz); }
return res; }
// **************************************************************************
static long DIAMONDAPI fci_progress(UINT typeStatus, ULONG cb1, ULONG cb2, LPVOID pv) { return 0; }
// **************************************************************************
static BOOL DIAMONDAPI fci_get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, LPVOID pv) { SPFFileInfo *ppffi = (SPFFileInfo *)pv;
SplitPath(ppffi->szDestFile, pccab->szCabPath, pccab->szCab); return TRUE; }
// **************************************************************************
static INT_PTR DIAMONDAPI fci_get_open_info(LPSTR pszName, USHORT *pdate, USHORT *ptime, USHORT *pattribs, int *err, LPVOID pv) { BY_HANDLE_FILE_INFORMATION finfo; FILETIME filetime; HANDLE handle; DWORD attrs; int hf = -1;
// Need a Win32 type handle to get file date/time using the Win32 APIs,
// even though the handle we will be returning is of the type compatible
// with _open
handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (handle != INVALID_HANDLE_VALUE) { if (GetFileInformationByHandle(handle, &finfo)) { FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime); FileTimeToDosDateTime(&filetime, pdate, ptime);
attrs = GetFileAttributes(pszName); if (attrs == (DWORD)-1) { // failure
*pattribs = 0; } else { // Mask out all other bits except these four, since other
// bits are used by the cabinet format to indicate a
// special meaning.
*pattribs = (int)(attrs & (_A_RDONLY | _A_SYSTEM | _A_HIDDEN | _A_ARCH)); } }
CloseHandle(handle); }
// Return handle using _open
hf = _open( pszName, _O_RDONLY | _O_BINARY ); if(hf == -1) { return -1; // abort on error
}
return hf; }
/////////////////////////////////////////////////////////////////////////////
//
// **************************************************************************
static INT_PTR DIAMONDAPI fdi_open(LPSTR pszFile, int oflag, int pmode) { return _open(pszFile, oflag, pmode); }
// **************************************************************************
static UINT DIAMONDAPI fdi_read(INT_PTR hf, LPVOID pv, UINT cb) { return _read((int)hf, pv, cb); }
// **************************************************************************
static UINT DIAMONDAPI fdi_write(INT_PTR hf, LPVOID pv, UINT cb) { return _write((int)hf, pv, cb); }
// **************************************************************************
static int DIAMONDAPI fdi_close(INT_PTR hf) { return _close((int)hf); }
// **************************************************************************
static long DIAMONDAPI fdi_seek(INT_PTR hf, long dist, int seektype) { return _lseek((int)hf, dist, seektype); }
// **************************************************************************
static INT_PTR DIAMONDAPI fdi_notify_copy(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { SPFFileInfo *ppffi = (SPFFileInfo *)pfdin->pv; switch(fdint) { // file to be copied
case fdintCOPY_FILE: // is it an exact match?
if (_stricmp(pfdin->psz1, ppffi->szFileName) == 0) { ppffi->fFound = TRUE; return fdi_open(ppffi->szDestFile, _O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL, _S_IREAD | _S_IWRITE); }
// are we looking for a wildcard?
else if (ppffi->szFileName[0] == '*' && ppffi->szFileName[1] == '.' && ppffi->szFileName[2] != '\0' && ppffi->szFileName[3] != '\0' && ppffi->szFileName[4] != '\0' && ppffi->szFileName[5] == '\0') { // compare the suffix's
char *p; p = strrchr(pfdin->psz1, '.');
if (p != NULL && _stricmp(p, &(ppffi->szFileName[1])) == 0) { ppffi->fFound = TRUE; return fdi_open(ppffi->szDestFile, _O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL, _S_IREAD | _S_IWRITE); } } break;
// close the file, set relevant info
case fdintCLOSE_FILE_INFO: fdi_close(pfdin->hf); return TRUE; }
return 0; }
// **************************************************************************
static INT_PTR DIAMONDAPI fdi_notify_enum(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { if (fdint == fdintCOPY_FILE) { CPFArrayBSTR *rgFiles = (CPFArrayBSTR *)pfdin->pv; CComBSTR bstr;
bstr = pfdin->psz1; if (bstr.m_str != NULL && rgFiles != NULL) { if (SUCCEEDED(rgFiles->Append(bstr.m_str))) bstr.Detach(); }
}
return 0; }
/////////////////////////////////////////////////////////////////////////////
// our exposed functions
// **************************************************************************
HRESULT PFExtractFromCab(LPWSTR wszCab, LPWSTR wszDestFile, LPWSTR wszFileToFind) { USES_CONVERSION; USE_TRACING("PFExtractFromCabinet");
SPFFileInfo pffi; HRESULT hr = NOERROR; BOOL fRes = FALSE; HFDI hfdi = NULL; char szCabName[MAX_PATH]; char szCabPath[MAX_PATH]; BOOL fOk; ERF erf;
VALIDATEPARM(hr, (wszCab == NULL || wszDestFile == NULL || wszFileToFind == NULL)); if (FAILED(hr)) goto done;
// create the cab handle
hfdi = FDICreate(mem_alloc, mem_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); VALIDATEEXPR(hr, (hfdi == NULL), Err2HR(MyCabGetLastError())); if (FAILED(hr)) goto done;
__try { pffi.szCab = W2A(wszCab); pffi.szDestFile = W2A(wszDestFile); pffi.szFileName = W2A(wszFileToFind); pffi.fFound = FALSE; } __except(1) { hr = E_OUTOFMEMORY; } if (FAILED(hr)) goto done;
SplitPath(pffi.szCab, szCabPath, szCabName); fOk = FDICopy(hfdi, szCabName, szCabPath, 0, fdi_notify_copy, NULL, &pffi); VALIDATEEXPR(hr, (fOk == FALSE), Err2HR(MyCabGetLastError())); if (FAILED(hr)) goto done;
hr = (pffi.fFound) ? NOERROR : S_FALSE;
done: if (hfdi != NULL) FDIDestroy(hfdi);
return hr; }
// **************************************************************************
HRESULT PFGetCabFileList(LPWSTR wszCabName, CPFArrayBSTR &rgFiles) { USES_CONVERSION; USE_TRACING("PFGetCabFiles");
CComBSTR bstr; HRESULT hr = NOERROR; HFDI hfdi = NULL; char szCabName[MAX_PATH], szCabPath[MAX_PATH], *pszCab = NULL; BOOL fOk; ERF erf;
rgFiles.RemoveAll();
VALIDATEPARM(hr, (wszCabName == NULL)); if (FAILED(hr)) goto done;
__try { pszCab = W2A(wszCabName); _ASSERT(pszCab != NULL); } __except(1) { hr = E_OUTOFMEMORY; } if (FAILED(hr)) goto done; hfdi = FDICreate(mem_alloc, mem_free, fdi_open, fdi_read, fdi_write, fdi_close, fdi_seek, cpuUNKNOWN, &erf); VALIDATEEXPR(hr, (hfdi == NULL), Err2HR(MyCabGetLastError())); if (FAILED(hr)) goto done;
SplitPath(pszCab, szCabPath, szCabName); fOk = FDICopy(hfdi, szCabName, szCabPath, 0, fdi_notify_enum, NULL, &rgFiles); VALIDATEEXPR(hr, (fOk == FALSE), Err2HR(MyCabGetLastError())); if (FAILED(hr)) goto done;
done: if (hfdi != NULL) FDIDestroy(hfdi); return hr; }
|