|
|
//+----------------------------------------------------------------------------
//
// File: cmfdi.cpp
//
// Module: CMDL32.EXE
//
// Synopsis: CFdi class implementations
//
// Copyright (c) 1996-1999 Microsoft Corporation
//
// Author: nickball Created 04/08/98
//
//+----------------------------------------------------------------------------
#include "cmmaster.h"
#include <fcntl.h>
#include <sys\stat.h>
const TCHAR* const c_pszExeFile = TEXT("PBUPDATE.EXE"); // for detecting itExeInCab
const TCHAR* const c_pszInfFile = TEXT("PBUPDATE.INF"); // for detecting itInfInCab
const TCHAR* const c_pszVerFile = TEXT("PBUPDATE.VER"); // version string in .CAB
const TCHAR* const c_pszPbr = TEXT("PBR"); // regions file extension
//
// CFDIFile Implementation
//
CFDIFile::~CFDIFile() { // nothing
}
DWORD CFDIFile::Read(LPVOID pv, DWORD cb) { return 0; }
DWORD CFDIFile::Write(LPVOID pv, DWORD cb) { return 0; }
long CFDIFile::Seek(long dist, int seektype) { return 0; }
int CFDIFile::Close() { return 0; }
HANDLE CFDIFile::GetHandle() { return (INVALID_HANDLE_VALUE); }
//
// CFDIFileFile Implementation
//
CFDIFileFile::CFDIFileFile() {
m_hFile = INVALID_HANDLE_VALUE; }
CFDIFileFile::~CFDIFileFile() {
if (m_hFile != INVALID_HANDLE_VALUE) { MYDBG(("CFDIFileFile::~CFDIFileFile() destructor called while file still open.")); Close(); } }
BOOL CFDIFileFile::CreateFile(LPCTSTR pszFile, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, DWORD dwFileSize) { // Make sure the files isn't in use
if (m_hFile != INVALID_HANDLE_VALUE) { MYDBG(("CFDIFileFile::CreateFile() file is already open.")); SetLastError(ERROR_OUT_OF_STRUCTURES); return (FALSE); } // Open Create/Open the file
m_hFile = ::CreateFile(pszFile,dwDesiredAccess,dwShareMode,NULL,dwCreationDistribution,dwFlagsAndAttributes,NULL); if (m_hFile == INVALID_HANDLE_VALUE) { MYDBG(("CFDIFileFile::CreateFile() CreateFile(pszFile=%s,dwDesiredAccess=%u,dwShareMode=%u,dwCreationDistribution=%u,dwFlagsAndAttributes=%u) failed, GLE=%u.", pszFile,dwDesiredAccess,dwShareMode,dwCreationDistribution,dwFlagsAndAttributes,GetLastError())); return (FALSE); } // If dwFileSize is specified, move the pointer by dwFileSize bytes
if (dwFileSize) { BOOL bRes; DWORD dwRes; dwRes = SetFilePointer(m_hFile,dwFileSize,NULL,FILE_BEGIN); MYDBGTST(dwRes==INVALID_SET_FILE_POINTER ,("CFDIFileFile::CreateFile() SetFilePointer() failed, GLE=%u.",GetLastError())); // If that worked, set the end of file at the file pointer position
if (dwRes != INVALID_SET_FILE_POINTER) { bRes = SetEndOfFile(m_hFile); MYDBGTST(!bRes,("CFDIFileFile::CreateFile() SetEndOfFile() failed, GLE=%u.",GetLastError())); } // Reset the file pointer to the beginning
if ((dwRes != INVALID_SET_FILE_POINTER ) && bRes) { dwRes = SetFilePointer(m_hFile,0,NULL,FILE_BEGIN); MYDBGTST(dwRes==INVALID_SET_FILE_POINTER ,("CFDIFileFile::CreateFile() SetFilePointer() failed, GLE=%u.",GetLastError())); } // Close the file and bail if we failed the above
if ((dwRes == INVALID_SET_FILE_POINTER ) || !bRes) { bRes = CloseHandle(m_hFile); MYDBGTST(!bRes,("CFDIFileFile::CreateFile() CloseHandle() failed, GLE=%u.",GetLastError())); m_hFile = INVALID_HANDLE_VALUE; return (-1); } } return (TRUE); }
BOOL CFDIFileFile::CreateUniqueFile(LPTSTR pszFile, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwFlagsAndAttributes) { DWORD dwIdx; TCHAR szFile[MAX_PATH+1];
if (m_hFile != INVALID_HANDLE_VALUE) { MYDBG(("CFDIFileFile::CreateUniqueFile() file is already open.")); SetLastError(ERROR_OUT_OF_STRUCTURES); return (FALSE); } dwIdx = 0; while (1) { wsprintf(szFile,"%08u.tmp",dwIdx); m_hFile = ::CreateFile(szFile,dwDesiredAccess,dwShareMode,NULL,CREATE_NEW,dwFlagsAndAttributes,NULL); if (m_hFile != INVALID_HANDLE_VALUE) { break; } if (IsErrorForUnique(GetLastError(), szFile)) { MYDBG(("CFDIFileFile::CreateUniqueFile() CreateFile() failed, GLE=%u.",GetLastError())); return (FALSE); } dwIdx++; } lstrcpy(pszFile,szFile); return (TRUE); }
DWORD CFDIFileFile::Read(LPVOID pv, DWORD cb) { BOOL bRes; DWORD dwRes;
bRes = ReadFile(m_hFile,pv,cb,&dwRes,NULL); if (!bRes) { MYDBG(("CFDIFileFile::Read() ReadFile() failed, GLE=%u.",GetLastError())); return ((UINT) -1); } return (dwRes); }
DWORD CFDIFileFile::Write(LPVOID pv, DWORD cb) { BOOL bRes; DWORD dwRes;
bRes = WriteFile(m_hFile,pv,cb,&dwRes,NULL); if (!bRes) { MYDBG(("CFDIFileFile::Write() WriteFile() failed, GLE=%u.",GetLastError())); return ((UINT) -1); } return (dwRes); }
long CFDIFileFile::Seek(long dist, int seektype) { DWORD dwRes;
dwRes = SetFilePointer(m_hFile,dist,NULL,seektype); if (dwRes == INVALID_SET_FILE_POINTER) { MYDBG(("CFDIFileFile::Seek() SetFilePointer() failed, GLE=%u.",GetLastError())); return (-1); } return ((long) dwRes); }
int CFDIFileFile::Close() { BOOL bRes;
bRes = CloseHandle(m_hFile); if (!bRes) { MYDBG(("CFDIFileFile::Close() CloseHandle() failed, GLE=%u.",GetLastError())); return (-1); } m_hFile = INVALID_HANDLE_VALUE; return (0); }
HANDLE CFDIFileFile::GetHandle() { return (m_hFile); }
//
// FDI wrapper routines
//
void HUGE * FAR DIAMONDAPI fdi_alloc(ULONG cb) { return (CmMalloc(cb)); }
void FAR DIAMONDAPI fdi_free(void HUGE *pv) { CmFree(pv); }
INT_PTR FAR DIAMONDAPI fdi_open(char FAR *pszFile, int oflag, int pmode) { TCHAR szTempFileName[MAX_PATH+1]; DWORD dwDesiredAccess; DWORD dwShareMode = FILE_SHARE_READ; DWORD dwCreationDistribution; DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; DWORD dwFileSize = 0; DWORD dwRes; BOOL bRes;
CFDIFileFile *pfff = NULL;
pfff = new CFDIFileFile; if (!pfff) { MYDBG(("fdi_open() new CFDIFileFile failed.")); return (-1); }
switch (oflag & (_O_RDONLY|_O_WRONLY|_O_RDWR)) {
case _O_RDONLY: dwDesiredAccess = GENERIC_READ; break;
case _O_WRONLY: dwDesiredAccess = GENERIC_WRITE; break;
case _O_RDWR: dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; break;
default: MYDBG(("fdi_open() invalid read/write flags, oflag=%u.",oflag)); delete pfff; return (-1); } if (oflag & _O_CREAT) { if (!(pmode & _S_IWRITE)) { dwFlagsAndAttributes |= FILE_ATTRIBUTE_READONLY; } } if (oflag & (_O_CREAT | _O_EXCL)) { dwCreationDistribution = CREATE_NEW; } else if (oflag & (_O_CREAT | _O_TRUNC)) { dwCreationDistribution = CREATE_ALWAYS; } else if (oflag & _O_CREAT) { dwCreationDistribution = OPEN_ALWAYS; } else if (oflag & _O_TRUNC) { dwCreationDistribution = TRUNCATE_EXISTING; } else { dwCreationDistribution = OPEN_EXISTING; } if (*pszFile == '*') { PFDISPILLFILE pfsf = (PFDISPILLFILE) pszFile; TCHAR szTempPath[MAX_PATH+1];
ZeroMemory(szTempPath,sizeof(szTempPath)); ZeroMemory(szTempFileName,sizeof(szTempFileName)); dwRes = GetTempPath(sizeof(szTempPath)/sizeof(TCHAR)-1,szTempPath); MYDBGTST(!dwRes,("fdi_open() GetTempPath() failed, GLE=%u.",GetLastError())); dwRes = GetTempFileName(szTempPath,TEXT("ctf"),0,szTempFileName); MYDBGTST(!dwRes,("fdi_open() GetTempFileName() failed, GLE=%u.",GetLastError())); MYDBGTST(!dwRes,("fdi_open() GetTempFileName() failed, GLE=%u.",GetLastError())); pszFile = szTempFileName; dwFileSize = pfsf->cbFile; dwFlagsAndAttributes |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE; } bRes = pfff->CreateFile(pszFile,dwDesiredAccess,dwShareMode,dwCreationDistribution,dwFlagsAndAttributes,dwFileSize);
if (!bRes) { delete pfff; return (-1); } return ((INT_PTR)pfff); }
UINT FAR DIAMONDAPI fdi_read(INT_PTR hf, void FAR *pv, UINT cb) { return (((CFDIFile *) hf)->Read(pv,cb)); }
UINT FAR DIAMONDAPI fdi_write(INT_PTR hf, void FAR *pv, UINT cb) { return (((CFDIFile *) hf)->Write(pv,cb)); }
long FAR DIAMONDAPI fdi_seek(INT_PTR hf, long dist, int seektype) { return (((CFDIFile *) hf)->Seek(dist,seektype)); }
int FAR DIAMONDAPI fdi_close(INT_PTR hf) { int nRes;
CFDIFile *pff = (CFDIFile *) hf; nRes = pff->Close(); delete pff; return (nRes); }
INT_PTR FAR DIAMONDAPI fdi_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { NotifyArgs *pnaArgs = (NotifyArgs *) pfdin->pv; BOOL bRes;
switch (fdint) { case fdintCOPY_FILE: { InstallType itType; TCHAR szTmp[MAX_PATH+1]; LPTSTR pszExt; // file extension
PFILEPROCESSINFO pFPI;
MYDBG(("fdi_notify() fdint=fdintCOPY_FILE, psz1=%s, cb=%u.",pfdin->psz1,pfdin->cb)); if (lstrlen(pnaArgs->pdaArgs->szCabDir)+lstrlen(pfdin->psz1)+1>sizeof(szTmp)/sizeof(TCHAR)-1) { MYDBG(("fdi_notify() szCabDir=%s+pszFile=%s exceeds MAX_PATH.",pnaArgs->pdaArgs->szCabDir,pfdin->psz1)); return (-1); } lstrcpy(szTmp,pnaArgs->pdaArgs->szCabDir); if (szTmp[0] && (GetLastChar(szTmp) != '\\')) { lstrcat(szTmp,TEXT("\\")); } lstrcat(szTmp,pfdin->psz1); if (!(pnaArgs->dwAppFlags & AF_NO_EXEINCAB) && (lstrcmpi(pfdin->psz1,c_pszExeFile) == 0)) { //
// Its a .EXE, note the fact for later processing
//
itType = itInvalid; // currently an invalid type
pnaArgs->pdaArgs->fContainsExeOrInf = TRUE; } else if (!(pnaArgs->dwAppFlags & AF_NO_INFINCAB) && (lstrcmpi(pfdin->psz1,c_pszInfFile) == 0)) { //
// Its a .INF, note the fact for later processing
//
itType = itInvalid; // currently an invalid type
pnaArgs->pdaArgs->fContainsExeOrInf = TRUE; } else if (!(pnaArgs->dwAppFlags & AF_NO_PBDINCAB) && (lstrcmpi(pfdin->psz1,c_pszPbdFile) == 0)) { //
// Its a .PBD, note the fact for later processing
//
itType = itPbdInCab; } else if ((pszExt = CmStrchr(pfdin->psz1, TEXT('.'))) && (lstrcmpi(pszExt+1, c_pszPbk) == 0)) { *pszExt = TEXT('\0'); // if the PBK is not for this service, we don't use it.
if (lstrcmpi(pfdin->psz1, pnaArgs->pdaArgs->pszPhoneBookName) != 0) { itType = itInvalid; } else { itType = itPbkInCab; } // restore the filename
*pszExt = TEXT('.'); } else if ((pszExt = CmStrchr(pfdin->psz1, TEXT('.'))) && (lstrcmpi(pszExt+1, c_pszPbr) == 0)) { *pszExt = TEXT('\0'); // if the PBR is not for this service, we don't use it.
if (lstrcmpi(pfdin->psz1, pnaArgs->pdaArgs->pszPhoneBookName) != 0) { itType = itInvalid; } else { itType = itPbrInCab; } // restore the filename
*pszExt = TEXT('.'); // save the name in pdaArgs
// if (!(pnaArgs->pdaArgs->pszNewPbrFile = CmStrCpyAlloc(pfdin->psz1)))
// {
// MYDBG((TEXT("fdi_notify(): CmStrCpyAlloc for pszNewPbrFile failed.")));
// return -1;
// }
} else if (lstrcmpi(pfdin->psz1, c_pszVerFile) == 0) { // a version file - we don't process it. We'll read the version in fdintCLOSE_FILE_INFO
itType = itInvalid; } else { itType = itInvalid; } // create a file process info. add one to the existing list.
if (itType != itInvalid) { if (!pnaArgs->pdaArgs->rgfpiFileProcessInfo) pFPI = (PFILEPROCESSINFO)CmMalloc(sizeof(FILEPROCESSINFO)); else pFPI = (PFILEPROCESSINFO)CmRealloc(pnaArgs->pdaArgs->rgfpiFileProcessInfo, (pnaArgs->pdaArgs->dwNumFilesToProcess+1)*sizeof(FILEPROCESSINFO)); if (!pFPI) { MYDBG((TEXT("fdi_notify(): Malloc(FILEPROCESSINFO) failed."))); return -1; }
pnaArgs->pdaArgs->rgfpiFileProcessInfo = pFPI; pnaArgs->pdaArgs->dwNumFilesToProcess++; pFPI[pnaArgs->pdaArgs->dwNumFilesToProcess-1].itType = itType; pFPI[pnaArgs->pdaArgs->dwNumFilesToProcess-1].pszFile = CmStrCpyAlloc(pfdin->psz1); }
// Do standard fdintCOPY_FILE processing, create the file and return the handle
CFDIFileFile *pfff;
pfff = new CFDIFileFile; if (!pfff) { MYDBG(("fdi_notify() new CFDIFileFile failed.")); return (-1); } bRes = pfff->CreateFile(szTmp,GENERIC_WRITE,FILE_SHARE_READ,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,0); if (!bRes) { delete pfff; return (-1); } return ((INT_PTR)pfff); }
case fdintCLOSE_FILE_INFO: { int iRes; TCHAR szTmp[MAX_PATH+1];
// Append file name to cab dir
lstrcpy(szTmp,pnaArgs->pdaArgs->szCabDir); if (szTmp[0] && (GetLastChar(szTmp) != '\\')) { lstrcat(szTmp,TEXT("\\")); } lstrcat(szTmp,pfdin->psz1);
// Set the date and time to the original file time not the current time
FILETIME ftTmp; FILETIME ftTime;
bRes = DosDateTimeToFileTime(pfdin->date,pfdin->time,&ftTmp); MYDBGTST(!bRes,("fdi_notify() DosDateTimeToFileTime(%u,%u) failed, GLE=%u.",pfdin->date,pfdin->time,GetLastError())); bRes = LocalFileTimeToFileTime(&ftTmp,&ftTime); MYDBGTST(!bRes,("fdi_notify() LocalFileTimeToFileTime() failed, GLE=%u.",GetLastError())); bRes = SetFileTime(((CFDIFile *) (pfdin->hf))->GetHandle(),&ftTime,&ftTime,&ftTime); MYDBGTST(!bRes,("fdi_notify() SetFileTime() failed, GLE=%u.",GetLastError()));
iRes = fdi_close(pfdin->hf);
// If this is the version file, get the version number
if (lstrcmpi(pfdin->psz1,c_pszVerFile) == 0) { pnaArgs->pdaArgs->pszVerNew = GetVersionFromFile(szTmp); }
// Set file attributes according to original file attribs
bRes = SetFileAttributes(szTmp,pfdin->attribs); MYDBGTST(!bRes,("fdi_notify() SetFileAttributes(%s,%u) failed, GLE=%u.",szTmp,pfdin->attribs,GetLastError())); return ((iRes==0)?TRUE:FALSE); }
case fdintNEXT_CABINET: MYDBG(("fdi_notify_scan() spanning cabinets is not supported.")); return (-1);
default: MYDBG(("fdi_notify_scan() fdint=%u.",fdint)); break; } return (0); }
|