|
|
#include "precomp.h"
#pragma hdrstop
/* File: filecm.c */ /*************************************************************************
** Install: File Copying commands. **************************************************************************/
extern HWND hwndFrame; extern HANDLE hinstShell;
extern HWND hwndProgressGizmo; extern CHP rgchBufTmpLong[];
/* Globals */ CHP szFullPathSrc[cchpFullPathBuf] = "\0"; CHP szFullPathDst[cchpFullPathBuf] = "\0"; CHP szFullPathBak[cchpFullPathBuf] = "\0";
CHAR GaugeText1[50], GaugeText2[50]; BOOL fNTUpgradeSetup,fInitialSetup;
SZ APIENTRY SzGetSrcDollar(SZ szFullPathSrc,CHAR ch);
PSTR LOCAL_SOURCE_DIRECTORY = "\\$WIN_NT$.~LS";
int DetermineDriveType( IN CHAR DriveLetter );
BOOL FGetFileSecurity( PCHAR File, PSECURITY_DESCRIPTOR *SdBuf, CB *SdLen );
BOOL FSetFileSecurity( PCHAR File, PSECURITY_DESCRIPTOR SdBuf );
VOID ValidateAndChecksumFile( IN PSTR Filename, OUT PBOOLEAN IsNtImage, OUT PULONG Checksum, OUT PBOOLEAN Valid );
BOOL DoesFileReplaceThirdPartyFile( SZ szFullPathDst );
/*
** Purpose: ** Copies all files in the current copy list and resets the list to ** empty. Copying is sorted by source disk to limit potential disk ** swapping. ** Arguments: ** hInstance: non-NULL instance handle for getting strings from ** resources for SwapDisk message Box. ** Returns: ** Returns fTrue if all copies successful, fFalse otherwise. ** **************************************************************************/ BOOL APIENTRY FCopyFilesInCopyList(hInstance) HANDLE hInstance; { DID did; PCLN pclnCur; PPCLN ppclnPrev; LONG lTotalSize; PPCLN ppclnHead; PPPCLN pppclnTail; PSDLE psdle; BOOL fSilentSystem = FGetSilent(); UINT fuModeSav; PINFPERMINFO pPermInfo; PSDLE psdleGlobalHead = (PSDLE)NULL; PSDLE psdleGlobalEnd = (PSDLE)NULL; PSDLE psdleGlobal; DID didGlobalCur; BOOL fCopyStatus = fFalse; SZ sz;
if(!InitDiamond()) { return(fFalse); }
fInitialSetup = fFalse; fNTUpgradeSetup = fFalse;
if (!fSilentSystem) { ProOpen(hwndFrame, 0); ProSetBarRange(10000); }
//
// Determine if we are in initial setup
//
if ((sz = SzFindSymbolValueInSymTab("!STF_INSTALL_TYPE")) != (SZ)NULL && (CrcStringCompareI(sz, "SETUPBOOTED") == crcEqual)) {
fInitialSetup = fTrue; }
//
// Determine if we are an NT upgrade setup
//
if (fInitialSetup && (sz = SzFindSymbolValueInSymTab("!STF_NTUPGRADE")) != (SZ)NULL && (CrcStringCompareI(sz, "YES") == crcEqual)) {
fNTUpgradeSetup = fTrue; }
//
// Go through all the disk media descriptions and assign universal
// ids for all source media. This is necessary because two infs
// may refer to the same disk using different ids.
//
pPermInfo = pInfPermInfoHead; didGlobalCur = didMin; while ( pPermInfo ) {
//
// If the INF has a source media description list, go through list
//
psdle = pPermInfo->psdleHead; while ( psdle ) {
//
// search all the global psdles for a match with the current
// disk. search based on disk label ( which is hopefully unique )
//
psdleGlobal = psdleGlobalHead; while ( psdleGlobal ) { if( !CrcStringCompareI( psdleGlobal->szLabel, psdle->szLabel ) ) { break; } psdleGlobal = psdleGlobal->psdleNext; }
if ( psdleGlobal == NULL ) { PSDLE psdleNew; if ((psdleNew = PsdleAlloc()) == (PSDLE)NULL || (psdleNew->szLabel = SzDupl(psdle->szLabel)) == (SZ)NULL || (psdle->szTagFile != NULL && ((psdleNew->szTagFile = SzDupl(psdle->szTagFile)) == (SZ)NULL)) || (psdle->szNetPath != NULL && ((psdleNew->szNetPath = SzDupl(psdle->szNetPath)) == (SZ)NULL))) { goto CopyFailed; } psdleNew->psdleNext = (PSDLE)NULL; if ( !psdleGlobalHead ) { psdleGlobalHead = psdleGlobalEnd = psdleNew; } else { psdleGlobalEnd->psdleNext = psdleNew; psdleGlobalEnd = psdleNew; } psdleGlobal = psdleNew; psdleGlobal->didGlobal = didGlobalCur++; } psdle->didGlobal = psdleGlobal->didGlobal; psdle = psdle->psdleNext; } pPermInfo = pPermInfo->pNext; }
//
// Go through the copy list of all infs and calculate total copy
// list cost
//
pPermInfo = pInfPermInfoHead; lTotalSize = 0L; while ( pPermInfo ) {
//
// If the INF has a source media description list, look at the
// copy list
//
if ( pPermInfo->psdleHead ) {
Assert(FValidCopyList( pPermInfo ));
ppclnHead = PpclnHeadList( pPermInfo ); pppclnTail = PppclnTailList( pPermInfo );
#if DBG
*pppclnTail = NULL; /* for FValidCopyList() calls */ #endif
pclnCur = *ppclnHead; //
// Traverse the copy list and determine the total size of the
// files to copy.
//
while (pclnCur != (PCLN)NULL) {
if (pclnCur->psfd->oer.ctuCopyTime > 0) { lTotalSize += pclnCur->psfd->oer.ctuCopyTime; } else { lTotalSize += pclnCur->psfd->oer.lSize; } pclnCur = pclnCur->pclnNext; } } pPermInfo = pPermInfo->pNext; }
if (lTotalSize == 0L) { lTotalSize = 1L; }
//
// Show gauge stuff if not in silent mode.
//
if (!fSilentSystem) {
SZ szText;
ProSetBarPos(0);
szText = SzFindSymbolValueInSymTab("ProText1"); if( szText ) { strcpy(GaugeText1, szText); } else { strcpy(GaugeText1, ""); }
szText = SzFindSymbolValueInSymTab("ProText2"); if( szText ) { strcpy(GaugeText2, szText); } else { strcpy(GaugeText2, ""); }
ProSetText(ID_STATUS3, ""); ProSetText(ID_STATUS4, ""); }
//
// Copy the files
//
psdleGlobal = psdleGlobalHead; while (psdleGlobal ) {
didGlobalCur = psdleGlobal->didGlobal; pPermInfo = pInfPermInfoHead; while ( pPermInfo ) {
//
// Verify that this INF has a copy list
//
if ((psdle = pPermInfo->psdleHead) == (PSDLE)NULL ) { Assert( !*PpclnHeadList( pPermInfo ) ); pPermInfo = pPermInfo->pNext; continue; } Assert(FValidCopyList( pPermInfo ));
//
// If it does, go through its source media descriptions finding
// all disks that match the current global disk id and copy all
// files which are described by the disks found
//
while ( psdle ) {
if( psdle->didGlobal != didGlobalCur ) { psdle = psdle->psdleNext; continue; } did = psdle->did;
ppclnHead = PpclnHeadList( pPermInfo ); pppclnTail = PppclnTailList( pPermInfo );
#if DBG
*pppclnTail = NULL; /* for FValidCopyList() calls */ #endif
ppclnPrev = ppclnHead; pclnCur = *ppclnHead;
//
// Now traverse the copy list, copying all
// the files that match the disk id
//
while (pclnCur != (PCLN)NULL) {
if ( (pclnCur->psfd->did != did) || (pclnCur->psfd->InfId != pPermInfo->InfId ) ) { ppclnPrev = &(pclnCur->pclnNext); pclnCur = pclnCur->pclnNext; continue; }
fuModeSav = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
if(!FCopyListFile(hInstance,pclnCur,psdle,lTotalSize)) {
SetErrorMode(fuModeSav); goto CopyFailed; }
SetErrorMode(fuModeSav);
//
// File copied, delete its entry from the copy list
//
*ppclnPrev = pclnCur->pclnNext; EvalAssert(FFreePcln(pclnCur)); pclnCur = *ppclnPrev;
Assert(FValidCopyList( pPermInfo )); }
psdle = psdle->psdleNext; } pPermInfo = pPermInfo->pNext; } psdleGlobal = psdleGlobal->psdleNext; } if (!fSilentSystem) { ProSetBarPos(10000 - 1); } fCopyStatus = fTrue;
CopyFailed:
if (!fSilentSystem) { ProClose(hwndFrame); UpdateWindow(hwndFrame); }
pPermInfo = pInfPermInfoHead; while ( pPermInfo ) { EvalAssert(FFreeCopyList( pPermInfo )); pPermInfo = pPermInfo->pNext; }
psdleGlobal = psdleGlobalHead; while ( psdleGlobal ) { PSDLE psdleNext = psdleGlobal->psdleNext; FFreePsdle( psdleGlobal ); psdleGlobal = psdleNext; }
TermDiamond(); RestoreDiskLoggingDone();
return(fCopyStatus);
}
/*
** Purpose: ** To determine if the given file is read only. ** Arguments: ** szFullPathDst : a non-Null, zero-terminated string containing the fully ** qualified valid path (including the drive) to the file in ** question. File must exist. ** Returns: ** ynrcYes if the file is read only, ynrcNo otherwise. ** **************************************************************************/ YNRC APIENTRY YnrcFileReadOnly(szFullPathDst) SZ szFullPathDst; { BOOL fOkay = fTrue; unsigned uiAttrib;
ChkArg(szFullPathDst != (SZ)NULL && FValidPath(szFullPathDst) && FFileFound(szFullPathDst), 1, ynrcErr1);
if ((uiAttrib = GetFileAttributes(szFullPathDst)) == -1) fOkay = fFalse;
if (!fOkay) return(ynrcErr1);
return((uiAttrib & FILE_ATTRIBUTE_READONLY) ? ynrcYes : ynrcNo); }
/*
** Purpose: ** To set the read only status of a file to either read only or normal. ** Arguments: ** szFullPathDst: a non-Null, zero-terminated string containing the fully ** qualified valid path (including drive) whose status is to be ** set. File must already exist. ** fReadOnly: fTrue if the status is to be set to read only, fFalse ** if the status is to be set to normal ** Returns: ** fTrue if the function succeeds in setting the status as specified, ** fFalse otherwise. ** **************************************************************************/ BOOL APIENTRY FSetFileReadOnlyStatus(SZ szFullPathDst,BOOL fReadOnly) { BOOL fRet = fFalse; DWORD uiAttrib; DWORD newAttrib;
ChkArg(szFullPathDst != (SZ)NULL && FValidPath(szFullPathDst) && FFileFound(szFullPathDst), 1, fFalse);
if ((uiAttrib = GetFileAttributes(szFullPathDst)) != -1) {
if(fReadOnly) { newAttrib = uiAttrib | FILE_ATTRIBUTE_READONLY; } else { newAttrib = uiAttrib & ~FILE_ATTRIBUTE_READONLY; }
if((newAttrib == uiAttrib) || SetFileAttributes(szFullPathDst, newAttrib)) { fRet = fTrue; } }
return(fRet); }
/*
** Purpose: ** To determine if there is already a destination file that is "newer" than ** the source file. ** Arguments: ** dateSrc: valid date value in unsigned int form extracted from INF. ** szFullPathDst: a non-Null, zero terminated string containing the fully ** qualified valid path (including disk drive) to the destination ** file. File must exist. ** dwVerSrcMS: Most significant 32 bits of source file version stamp. ** dwVerSrcLS: Least significant 32 bits of source file version stamp. ** Returns: ** ynrcYes if the destination file already exists and is newer than ** the source file. ** ynrcErr1, ynrcErr2, or ynrcErr3 in errors. ** ynrcNo otherwise. ** **************************************************************************/ YNRC APIENTRY YnrcNewerExistingFile(USHORT dateSrc, SZ szFullPathDst, DWORD dwVerSrcMS, DWORD dwVerSrcLS) { USHORT dateDst, timeDst; PFH pfhDst; FILETIME WriteTime; DWORD dwVerDstMS; DWORD dwVerDstLS;
ChkArg(szFullPathDst != (SZ)NULL && FValidPath(szFullPathDst) && FFileFound(szFullPathDst), 2, ynrcErr1);
if ( (dwVerSrcMS != 0L || dwVerSrcLS != 0L) && FGetFileVersion(szFullPathDst, &dwVerDstMS, &dwVerDstLS)) {
if (dwVerDstMS > dwVerSrcMS || (dwVerDstMS == dwVerSrcMS && dwVerDstLS > dwVerSrcLS)) {
return(ynrcYes); } else { return(ynrcNo); }
} else { if ((pfhDst = PfhOpenFile(szFullPathDst, ofmRead)) == NULL) { return(ynrcErr1); }
if (!GetFileTime((HANDLE)LongToHandle(pfhDst->iDosfh), NULL, NULL, &WriteTime) || !FileTimeToDosDateTime(&WriteTime, &dateDst, &timeDst)) {
FCloseFile(pfhDst); return(ynrcErr2); }
if (!FCloseFile(pfhDst)) { return(ynrcErr3); }
if (dateDst > dateSrc) { return(ynrcYes); } }
return(ynrcNo); }
/*
** Purpose: ** Gets the file version values from the given file and sets the ** given pdwMS/pdwLS variables. ** Arguments: ** szFullPath: a zero terminated character string containing the fully ** qualified path (including disk drive) to the file. ** pdwMS: Most significant 32 bits of source file version stamp. ** pdwLS: Least significant 32 bits of source file version stamp. ** Returns: ** fTrue if file and file version resource found and retrieved, ** fFalse if not. +++ ** Implementation: **************************************************************************/ BOOL APIENTRY FGetFileVersion(szFullPath, pdwMS, pdwLS) SZ szFullPath; DWORD * pdwMS; DWORD * pdwLS; { BOOL fRet = fFalse; DWORD dwHandle; DWORD dwLen; LPSTR lpData;
ChkArg(szFullPath != (SZ)NULL, 1, fFalse); ChkArg(pdwMS != (DWORD *)NULL, 2, fFalse); ChkArg(pdwLS != (DWORD *)NULL, 3, fFalse);
//
// Get the file version info size
//
if ((dwLen = GetFileVersionInfoSize((LPSTR)szFullPath, &dwHandle)) == 0) { return (fRet); }
//
// Allocate enough size to hold version info
//
while ((lpData = (LPSTR)SAlloc((CB)dwLen)) == (LPSTR)NULL) { if (!FHandleOOM(hwndFrame)) { return (fRet); } }
//
// Get the version info
//
fRet = GetFileVersionInfo((LPSTR)szFullPath, dwHandle, dwLen, lpData);
if (fRet) { VS_FIXEDFILEINFO *pvsfi; DWORD dwLen;
fRet = VerQueryValue( (LPVOID)lpData, (LPSTR)"\\", (LPVOID *)&pvsfi, &dwLen );
if (fRet) { *pdwMS = pvsfi->dwFileVersionMS; *pdwLS = pvsfi->dwFileVersionLS; } }
SFree(lpData); return (fRet);
}
/*
** Purpose: ** Renames the given destination file as a backup file based on ** the backup file name given. If a backup file with the given ** name already exists, the function does nothing and returns. ** Arguments: ** szDst: a zero terminated char string containing the fully ** qualified path to the file to be backed up. ** szBackup: a zero terminated char string containing the file name ** of the file that will be the backup copy of szDst. This is ** not a fully qualified path, or subpath, it is only the filename ** (i.e. primary.ext). ** psfd: pointer to the Section-File Description(SFD) structure of ** the file being backed up. ** Returns: ** ynrcNo: if the backup file name is invalid or if unable to create ** the backup and user chooses to abort. ** ynrcErr1: if unable to create the backup and the user chooses ignore. ** ynrcYes: if the backup is successfully created or already exists. ** **************************************************************************/ YNRC APIENTRY YnrcBackupFile(szDst, szBackup, psfd) SZ szDst; SZ szBackup; PSFD psfd; { YNRC ynrcRet = ynrcYes;
Unused(szBackup);
Assert(psfd->oer.szAppend == (SZ)NULL);
if (!FBuildFullBakPath(szFullPathBak, szDst, psfd) || !FValidPath(szFullPathBak)) return(ynrcNo);
/* If the backup file already exists, leave the existing backup
** and return. (Either the user made it and we don't want to kill ** his, or we made it and we don't need to make another one.) */ if (FFileFound(szFullPathBak)) return(ynrcYes);
while (rename(szFullPathDst, szFullPathBak)) { EERC eerc;
if ((eerc = EercErrorHandler(hwndFrame, grcRenameFileErr, psfd->oer.oef & oefVital, szFullPathDst, szFullPathBak, 0)) == eercAbort) { ynrcRet = ynrcNo; break; } else if (eerc == eercIgnore) { ynrcRet = ynrcErr1; break; } Assert(eerc == eercRetry); }
return(ynrcRet); }
/*
**************************************************************************/ USHORT APIENTRY DateFromSz(SZ sz) { USHORT usAns, usYear, usMonth, usDay;
ChkArg(sz == (SZ)NULL || FValidOerDate(sz), 1, 0);
if (sz == (SZ)NULL) { usYear = 1980; usMonth = 1; usDay = 1; } else { usYear = (USHORT)atoi(sz); usMonth = (USHORT)atoi(sz + 5); usDay = (USHORT)atoi(sz + 8); }
Assert(usYear >= 1980 && usYear <= 2099); Assert(usMonth >= 1 && usMonth <= 12); Assert(usDay >= 1 && usDay <= 31);
usAns = usDay + (usMonth << 5) + ((usYear - (USHORT)1980) << 9);
return(usAns); }
BOOL CreateTargetAsLinkToMaster( IN SZ FullSourceFilename, IN SZ FullTargetFilename, IN BOOL TargetExists ) { //BUGBUG: handle case of target file in use.
//BUGBUG: handle case of target already exists.
//BUGBUG: handle owm modes
//BUGBUG: The following code is written to work with the prototype COW
// server, not with the real SIS server. If the target file
// exists, we assume it is the correct version (in the master
// tree) and don't do the copy.
//
if ( TargetExists ) { //DbgPrint( "SIS: Target %s exists; not copying\n", FullTargetFilename );
return NO_ERROR; // target exists; don't copy
} //DbgPrint( "SIS: Target %s doesn't exist; copying\n", FullTargetFilename );
return ERROR_FILE_NOT_FOUND; // target doesn't exist; copy by usual means
}
/*
** Purpose: ** Performs the copy defined by the given copy list node. ** Arguments: ** hInstance: non-NULL instance handle for getting strings from ** resources for SwapDisk message Box. ** pcln: pointer to the Copy List Node (CLN) of the file to be ** copied. ** psdle: non-NULL Source-Description-List-Element pointer to be ** used by FPromptForDisk(). ** lTotalSize: the total of all of the sizes (i.e. oer.ctuCopyTime or ** oer.lSize) for all of the files on the disk currently being copied. ** Returns: ** fTrue if the copy was successful, fFalse otherwise. ** **************************************************************************/ BOOL APIENTRY FCopyListFile( HANDLE hInstance, PCLN pcln, PSDLE psdle, LONG lTotalSize ) { PSFD psfd = pcln->psfd; POER poer = &(psfd->oer); BOOL fDstExists, fCompressedName; SZ szSrcDollar = NULL; BOOL fVital = poer->oef & oefVital; EERC eerc; int Removable; LONG lSize; USHORT dateSrc = DateFromSz(poer->szDate); PSECURITY_DESCRIPTOR Sd = NULL; CB SdLen; CHP szNonCompressedFullPathSrc[cchpFullPathBuf] = "\0"; SZ SymbolValue; CHAR szSrcDrive[10];
ChkArg(pcln != (PCLN)NULL, 1, fFalse); ChkArg(psdle != (PSDLE)NULL, 2, fFalse);
//
// Only if a drive is removable do we check for the tagfile, in the case
// of a net drive the error is caught later on when we look for the src
// file. Note that the tag file is relative to the root of the removable
// drive.
//
// Because of a bug in 3.51 there are CD's which expect the tagfile to be
// locatable in a subdirectory. We'll use a hack based on STF_CWDDIR
// to make that work.
//
Removable = DetermineDriveType(*(pcln->szSrcDir)); if((Removable < 0) && psdle->szTagFile) {
strcpy(szSrcDrive,"?:\\"); szSrcDrive[0] = *(pcln->szSrcDir);
if(!FBuildFullSrcPath(szFullPathSrc,szSrcDrive,psdle->szTagFile,NULL)) { EercErrorHandler(hwndFrame,grcInvalidPathErr,fVital,szSrcDrive,psdle->szTagFile,0); return(!fVital); }
if((Removable == -2) && (SymbolValue = SzFindSymbolValueInSymTab("!STF_CWDDIR"))) { if(!FBuildFullSrcPath(szFullPathDst,SymbolValue,psdle->szTagFile,NULL)) { szFullPathDst[0] = 0; } } else { szFullPathDst[0] = 0; }
//
// Strip the backslash off the drive letter.
//
szSrcDrive[2] = '\0';
//
// If we can't find the tag file at the root then also look in
// STF_CWDDIR, if there is one.
//
while(!FFileFound(szFullPathSrc) && (!szFullPathDst[0] || !FFileFound(szFullPathDst))) {
MessageBeep(0); ShowOwnedPopups(hwndFrame,FALSE); if(FPromptForDisk(hInstance, psdle->szLabel, szSrcDrive)) { ShowOwnedPopups(hwndFrame,TRUE); } else {
HWND hwndSav = GetFocus(); BOOL b; CCHL szTmpText[cchpBufTmpLongMax];
//
// Make sure this is what he *really* wants to do.
//
LoadString(hInstance, IDS_SURECANCEL, rgchBufTmpLong, cchpBufTmpLongMax); LoadString(hInstance, IDS_ERROR, (LPSTR)szTmpText, cchpBufTmpLongMax); b = (MessageBox(hwndFrame, rgchBufTmpLong, (LPSTR)szTmpText, MB_YESNO|MB_TASKMODAL) == IDYES); ShowOwnedPopups(hwndFrame,TRUE); SetFocus(hwndSav); SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L); if(b) { return(fFalse); } } } }
if (!FBuildFullSrcPath(szFullPathSrc, pcln->szSrcDir, psfd->szFile, (Removable < 0) ? NULL : psdle->szNetPath)) { EvalAssert(EercErrorHandler(hwndFrame, grcInvalidPathErr, fVital, pcln->szSrcDir, psfd->szFile, 0) == eercAbort); return(!fVital); }
//
// Determine the source file name:
// Check to see if source file exists as the regular name or
// a compressed name
//
lstrcpy( szNonCompressedFullPathSrc, szFullPathSrc ); fCompressedName = fFalse; while (!FFileFound( szFullPathSrc )) { if (szSrcDollar == (SZ)NULL) { while ((szSrcDollar = SzGetSrcDollar(szFullPathSrc,'_')) == (SZ)NULL) { if (!FHandleOOM(hwndFrame)) { return(!fVital); } } }
if (FFileFound( szSrcDollar )) { lstrcpy( szFullPathSrc, szSrcDollar ); fCompressedName = fTrue; break; }
#define DOLLAR_NAME
#ifdef DOLLAR_NAME
SFree(szSrcDollar); while((szSrcDollar = SzGetSrcDollar(szFullPathSrc,'$')) == (SZ)NULL) { if (!FHandleOOM(hwndFrame)) { return(!fVital); } } if(FFileFound(szSrcDollar)) { lstrcpy(szFullPathSrc,szSrcDollar); fCompressedName = fTrue; break; } #endif
SFree( szSrcDollar); szSrcDollar = NULL;
//
// Unable to locate the source file.
// If we are supposed to skip missing files, ignore it.
// Text setup sets a symbol called SMF to YES if we are
// supposed to skip missing files.
//
if((SymbolValue = SzFindSymbolValueInSymTab("!SMF")) && !lstrcmpi(SymbolValue,"YES")) { return(fTrue); }
//
// If the file exists on the target and this is a winnt
// non-upgrade setup, just assume the file was already copied.
//
if(/*fInitialSetup &&*/ !fNTUpgradeSetup && !_strnicmp(szFullPathSrc+2,LOCAL_SOURCE_DIRECTORY,lstrlen(LOCAL_SOURCE_DIRECTORY))) { if(!FBuildFullDstPath(szFullPathDst, pcln->szDstDir, psfd, FALSE)) { if (!FHandleOOM(hwndFrame)) { return(!fVital); } }
if(FFileExists(szFullPathDst)) { return(fTrue); } }
if ((eerc = EercErrorHandler(hwndFrame, grcOpenFileErr, fVital, szFullPathSrc, 0, 0)) != eercRetry) { return(eerc == eercIgnore); }
} if (szSrcDollar) { SFree( szSrcDollar); szSrcDollar = (SZ)NULL; }
//
// Determine the destination file name:
//
if (!FBuildFullDstPath(szFullPathDst, pcln->szDstDir, psfd, fCompressedName) || !FValidPath(szFullPathDst)) { EvalAssert(EercErrorHandler(hwndFrame, grcInvalidPathErr, fVital, pcln->szDstDir, psfd->szFile, 0) == eercAbort); return(!fVital); }
fDstExists = FFileFound(szFullPathDst);
#ifdef REMOTE_BOOT
if (1) { //BUGBUG: how to turn on SIS check here?
DWORD rc; if (!fCompressedName) { rc = CreateTargetAsLinkToMaster( szFullPathSrc, szFullPathDst, fDstExists ); if (rc == NO_ERROR) { return TRUE; } } } #endif
if (fDstExists != fFalse) { OWM owm; YNRC ynrc;
//
// Check overwrite mode. The overwrite mode can be:
//
// 1. Never : No further checking. The file is not copied
//
// 2. Unprotected: Check to see if file on destination is readonly.
//
// 3. Older : The release version / date is checked against the
// the destination file
//
// 4. VerifySourceOlder: The checking is postponed till we have actually
// found the source file. The source time is then
// compared against the destination time and only
// if the destination is older the file is copied.
if ((owm = poer->owm) & owmNever) {
return(fTrue);
} else if (owm & owmUnprotected) {
while ((ynrc = YnrcFileReadOnly(szFullPathDst)) == ynrcErr1) { if ((eerc = EercErrorHandler(hwndFrame, grcReadFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { return(eerc == eercIgnore); } }
if (ynrc == ynrcYes) { return(fTrue); }
} else if (owm & owmOlder) {
while ((ynrc = YnrcNewerExistingFile(dateSrc, szFullPathDst, poer->ulVerMS, poer->ulVerLS)) != ynrcYes && ynrc != ynrcNo) { if (ynrc == ynrcErr1 && (eerc = EercErrorHandler(hwndFrame, grcOpenFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) return(eerc == eercIgnore); else if (ynrc == ynrcErr2 && (eerc = EercErrorHandler(hwndFrame, grcReadFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) return(eerc == eercIgnore); else if (ynrc == ynrcErr3 && (eerc = EercErrorHandler(hwndFrame, grcCloseFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) return(eerc == eercIgnore); }
if (ynrc == ynrcYes) return(fTrue); Assert(ynrc == ynrcNo);
}
} else {
//
// Destination doesn't exist, check to see if we are in upgradeonly
// mode, in which case we need not copy the file and we can just
// return.
OEF oef = poer->oef;
if ( oef & oefUpgradeOnly ) { return( fTrue ); }
}
//
// If destination exists then we need to preserve the security that is
// there on the file. We read the security on the existing file
// and once the new file is copied over then we set the security read
// on the new file. Note that we don't do this for initial setup since
// we are going to fix permissions on the file anyway.
//
if(fDstExists && !fInitialSetup) { if(!FGetFileSecurity(szFullPathDst, &Sd, &SdLen)) { return( fFalse ); } }
if (fDstExists && poer->szBackup != NULL) { YNRC ynrc;
if ((ynrc = YnrcBackupFile(szFullPathDst, poer->szBackup, psfd)) != ynrcYes) return(ynrc != ynrcNo); fDstExists = FFileFound(szFullPathDst); }
if (fDstExists) { while (!FSetFileReadOnlyStatus(szFullPathDst, fOff)) { if ((eerc = EercErrorHandler(hwndFrame, grcWriteFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) return(eerc == eercIgnore); } }
if(!fSilentSystem) {
LPSTR p; CHAR chSave;
EvalAssert((p = SzFindFileFromPath(szFullPathSrc)) != NULL); if(!p) { p = szFullPathSrc; } wsprintf(rgchBufTmpLong,"%s %s",GaugeText1,p); ProSetText(ID_STATUS1,rgchBufTmpLong);
EvalAssert((p = SzFindFileFromPath(szFullPathDst)) != NULL); if(p) { if(!ISUNC(szFullPathDst) && (p - szFullPathDst != 3)) { // account for file in root
p--; } chSave = *p; *p = '\0'; wsprintf(rgchBufTmpLong,"%s %s",GaugeText2,szFullPathDst); *p = chSave; } else { rgchBufTmpLong[0] = '\0'; } ProSetText(ID_STATUS2,rgchBufTmpLong); }
lSize = (poer->ctuCopyTime > 0) ? (LONG)(poer->ctuCopyTime) : poer->lSize; if (!FCopy(szFullPathSrc, szFullPathDst, poer->oef, poer->owm, (poer->szAppend != NULL), (int)((DWORD)10000 * lSize / lTotalSize), dateSrc,psdle,szNonCompressedFullPathSrc)) return(fFalse);
if( Sd ) { //
// BUGBUG -
//
// Preservation of file security is broken, since the most files
// were overwritten during textmode setup.
// So this is currently disabled.
//
// BOOL Status;
// Status = FSetFileSecurity(szFullPathDst, Sd);
SFree(Sd); // return(Status);
}
return(fTrue); }
/*
** Purpose: ** Uses the Compression DollarSign translation algorithm on its argument. ** If the file has no extension, then '._' is added. If the extension ** has less than 3 characters, then a '_' is appended. Otherwise, the ** third character of the extension is replaced by a dollarsign. ** Arguments: ** szFullPathSrc: a zero terminated character string containing the fully ** qualified path (including drive) for the source file. ** Returns: ** **************************************************************************/ SZ APIENTRY SzGetSrcDollar(SZ szFullPathSrc,CHAR ch) { SZ szDot = (SZ)NULL; SZ szCur = szFullPathSrc; CHAR dotch[3];
dotch[0] = '.'; dotch[1] = ch; dotch[2] = 0;
ChkArg(szFullPathSrc != (SZ)NULL, 1, (SZ)NULL);
while (*szCur != '\0') { if (*szCur == '.') szDot = szCur; else if (*szCur == '\\') szDot = (SZ)NULL; szCur = SzNextChar(szCur); }
Assert(szDot == (SZ)NULL || *szDot == '.'); if (szDot == (SZ)NULL) { if ((szDot = (SZ)SAlloc(strlen(szFullPathSrc) + 3)) != (SZ)NULL) { EvalAssert(strcpy(szDot, szFullPathSrc) == szDot); EvalAssert(SzStrCat(szDot, dotch) == szDot); } } else { CHP chpSav = '\0'; SZ szRest; CB cb;
if (*(szCur = ++szDot) != '\0' && *(szCur = SzNextChar(szCur)) != '\0' && *(szCur = SzNextChar(szCur)) != '\0') { chpSav = *szCur; szRest = SzNextChar(szCur); *szCur = '\0'; }
cb = strlen(szFullPathSrc) + 2; if (chpSav != '\0') { Assert(szRest != (SZ)NULL); cb += strlen(szRest); }
if ((szDot = (SZ)SAlloc(cb)) != (SZ)NULL) { EvalAssert(strcpy(szDot, szFullPathSrc) == szDot); EvalAssert(SzStrCat(szDot, &dotch[1]) == szDot);
if (chpSav != '\0') { Assert(szRest != (SZ)NULL); EvalAssert(SzStrCat(szDot, szRest) == szDot); *szCur = chpSav; } } }
return(szDot); }
static int iTickMax = 0; static int iTickCur = 0;
int far WFromW(int iTick) { if (iTick > iTickMax - iTickCur) iTick = iTickMax - iTickCur;
if (iTick > 0) { ProDeltaPos(iTick); iTickCur += iTick; }
return(1); }
/*
** Purpose: ** To physically copy the source file to the destination file. This ** can include several options including appending, open and closing src ** and dst files, but not actually copying the contents of the files, ** decompressing, timestamping the dst file, and setting the read only ** status of the dst file. ** Arguments: ** szFullPathSrc: a zero terminated character string containing the fully ** qualified path (including drive) for the source file. ** szFullPathDst: a zero terminated character string containing the fully ** qualified path (including drive) for the destination file. ** oef: option element flags for the Section-File Description ** The valid flags include oefVital, oefCopy, oefUndo, ** oefRoot, oefDecompress, oefTimeStamp, oefReadOnly, ** oefNone and oefAll. ** fAppend: fTrue if the contents of szFullPathSrc are to be ** appended to the contents of szFullPathDst. ** cProgTicks: number of ticks to advance Progress Gizmo. ** dateSrc: DATE value from INF for src file. ** Returns: ** fTrue if the copy is successfully completed, fFalse otherwise. ** **************************************************************************/ BOOL APIENTRY FCopy( SZ szFullPathSrc, SZ szFullPathDst, OEF oef, OWM owm, BOOL fAppend, int cProgTicks, USHORT dateSrc, PSDLE psdle, SZ szNonCompressedFullPathSrc ) { #if 0
CB cbSize; CB cbActual; #endif
PB pbBuffer = NULL; PFH pfhSrc = NULL; PFH pfhDst = NULL; LFA lfaDst = 0L; HANDLE hSource = NULL; BOOL fVital = oef & oefVital; BOOL fDecomp = oef & oefDecompress; BOOL fRet = !fVital; BOOL fRemovePartialFile = fFalse; EERC eerc; YNRC ynrc; FILETIME CreateTime, AccessTime, WriteTime; BOOL fSilentSystem = FGetSilent(); LONG lRet; ULONG Checksum = 0; BOOL fThirdPartyFile = oef & oefThirdPartyFile; BOOL OnLocalSource; BOOLEAN IsValid; BOOLEAN IsNtImage; BOOL fCsdInstall = oef & oefCsdInstall; SZ szActiveFileTmpName = NULL;
if( fCsdInstall && DoesFileReplaceThirdPartyFile( szFullPathDst+2 ) ) { return( TRUE ); }
OnLocalSource = (_strnicmp(szFullPathSrc+2,LOCAL_SOURCE_DIRECTORY,lstrlen(LOCAL_SOURCE_DIRECTORY)) == 0);
do { while ((pfhSrc = PfhOpenFile(szFullPathSrc, ofmRead)) == (PFH)NULL) {
if ((eerc = EercErrorHandler(hwndFrame, grcOpenFileErr, fVital, szFullPathSrc, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } }
while (!GetFileTime((HANDLE)LongToHandle(pfhSrc->iDosfh), &CreateTime, &AccessTime, &WriteTime)) { if ((eerc = EercErrorHandler(hwndFrame, grcReadFileErr, fVital, szFullPathSrc, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } }
if (!(oef & oefCopy)) { if (!FCloseFile(pfhSrc)) while ((eerc = EercErrorHandler(hwndFrame, grcCloseFileErr, fVital, szFullPathSrc, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } pfhSrc = NULL;
if (cProgTicks > 0 && !fSilentSystem) ProDeltaPos(cProgTicks);
fRet = fTrue; goto DelSrc; }
if(FFileFound(szFullPathDst)) {
//
// We need to check if we have been asked to compare actual file times
//
if ( owm & owmVerifySourceOlder ) {
PFH pfh; FILETIME DstWriteTime; BOOL Older = fFalse;
if ((pfh = PfhOpenFile(szFullPathDst, ofmRead)) != NULL) {
if (GetFileTime((HANDLE)LongToHandle(pfh->iDosfh), NULL, NULL, &DstWriteTime)) {
if( CompareFileTime( &DstWriteTime, &WriteTime ) == -1 ) { Older = fTrue; }
} FCloseFile(pfh); }
if( !Older ) {
FCloseFile(pfhSrc); pfhSrc = NULL;
if (cProgTicks > 0 && !fSilentSystem) ProDeltaPos(cProgTicks);
fRet = fTrue; goto DelSrc; } }
//
// if this is a CSD, then we need to back up the old file in case
// the copy fails for some reason. (We also gotta make sure that
// the files aren't the same, otherwise we'll get a bogus error)
//
if( fCsdInstall && lstrcmpi(szFullPathSrc, szFullPathDst) ) { //
// We don't want to back up the file again, if we're retrying
//
if(!szActiveFileTmpName) { while(!(szActiveFileTmpName = FRenameActiveFile(szFullPathDst))) {
//
// Error opening, present critical error to user
//
if ((eerc = EercErrorHandler(hwndFrame, grcOpenFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) {
fRet = (eerc == eercIgnore); goto LCopyError; } } } } }
if ((ynrc = YnrcEnsurePathExists(szFullPathDst, fVital, NULL)) != ynrcYes) { fRet = (ynrc == ynrcErr1); goto LCopyError; }
while ((pfhDst = PfhOpenFile(szFullPathDst, (OFM)(fAppend ? ofmReadWrite : ofmCreate))) == NULL) {
DWORD dw;
dw = GetLastError();
//
// if it is a sharing violation and this is because both the source
// and destination are the same, then present the error to the user.
//
if (dw == ERROR_SHARING_VIOLATION && !lstrcmpi(szFullPathSrc, szFullPathDst)) { if ((eerc = EercErrorHandler(hwndFrame, grcOpenSameFileErr, fFalse, szFullPathDst, 0, 0)) != eercRetry) {
fRet = (eerc == eercIgnore); goto LCopyError; } else { continue; } }
//
// For active files access will be denied
//
if(((dw == ERROR_ACCESS_DENIED) || (dw == ERROR_SHARING_VIOLATION) || (dw == ERROR_USER_MAPPED_FILE)) && !fAppend) { //
// make sure we don't already have a backup (if this is a retry)
//
if((szActiveFileTmpName) || (szActiveFileTmpName = FRenameActiveFile(szFullPathDst))) { continue; } }
//
// Error opening, present critical error to user
//
if ((eerc = EercErrorHandler(hwndFrame, grcOpenFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) {
fRet = (eerc == eercIgnore); goto LCopyError; }
}
fRemovePartialFile = fTrue;
if (fAppend) { USHORT dateDst, timeDst;
while(!GetFileTime((HANDLE)LongToHandle(pfhDst->iDosfh), NULL, NULL, &WriteTime) || !FileTimeToDosDateTime(&WriteTime, &dateDst, &timeDst)) { if ((eerc = EercErrorHandler(hwndFrame, grcReadFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } }
if (dateDst != dateSrc || timeDst != 0) { fRet = fTrue; fRemovePartialFile = fFalse; goto LCopyError; }
while ((lfaDst = LfaSeekFile(pfhDst, 0, sfmEnd)) == (LFA)(-1)) { if ((eerc = EercErrorHandler(hwndFrame, grcReadFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } } }
if (fDecomp) { INT rc; while ((rc = LZInit( pfhSrc->iDosfh) ) < 0) { GRC grc;
switch (rc) {
case LZERROR_UNKNOWNALG: grc = grcDecompUnknownAlgErr; break;
case LZERROR_GLOBLOCK: case LZERROR_READ: case LZERROR_BADINHANDLE: grc = grcReadFileErr; break;
case LZERROR_GLOBALLOC: grc = grcOutOfMemory; break;
default: grc = grcDecompGenericErr; break;
}
if ((eerc = EercErrorHandler(hwndFrame, grc, fVital, szFullPathSrc, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); hSource = NULL; goto LCopyError; } } hSource = (HANDLE)LongToHandle(rc); } else { hSource = (HANDLE)LongToHandle(pfhSrc->iDosfh); }
if (fDecomp) {
BOOL isDiamondFile;
iTickMax = cProgTicks; iTickCur = 0;
//
// Determine whether the file is a diamond cabinet/compressed file.
// If it is, we'll call a separate diamond decompressor. If it isn't,
// we'll call the lz routine, which will decompress an lz file or copy
// a non-lz (and non-diamond) file.
//
isDiamondFile = IsDiamondFile(szFullPathSrc);
do {
if(isDiamondFile) { lRet = DecompDiamondFile( szFullPathSrc, (HANDLE)LongToHandle(pfhDst->iDosfh), fSilentSystem ? NULL: WFromW, cProgTicks ); } else { lRet = LcbDecompFile( hSource, (HANDLE)LongToHandle(pfhDst->iDosfh), fSilentSystem ? NULL: WFromW, cProgTicks ); }
if(lRet < 0) {
GRC grc; SZ sz = szFullPathSrc;
switch (lRet) {
case rcReadError: case rcReadSeekError: grc = grcReadFileErr; break;
case rcWriteError: case rcWriteSeekError: grc = grcWriteFileErr; sz = szFullPathDst; break;
case rcOutOfMemory: grc = grcOutOfMemory; break; case rcDiskFull: grc = grcDiskFull; fVital = TRUE; break;
case rcUserQuit: fRet = fFalse; goto LCopyError; break;
default: grc = grcDecompGenericErr; break; }
if ((eerc = EercErrorHandler(hwndFrame, grc, fVital, sz)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; }
//
// Before retrying we need to rewind the destination pointer to
// the place where we began the write
//
while (LfaSeekFile(pfhDst, lfaDst, sfmSet) == (LFA)(-1)) { if ((eerc = EercErrorHandler(hwndFrame, grcReadFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } } } } while(lRet < 0);
Assert(iTickCur <= cProgTicks); cProgTicks -= iTickCur; } else { iTickMax = cProgTicks; iTickCur = 0; while ((lRet = LcbCopyFile( hSource, (HANDLE)LongToHandle(pfhDst->iDosfh), fSilentSystem ? NULL: WFromW, cProgTicks )) < 0) {
GRC grc; SZ sz = szFullPathSrc;
switch (lRet) {
case rcReadError: case rcReadSeekError: grc = grcReadFileErr; break;
case rcWriteError: case rcWriteSeekError: grc = grcWriteFileErr; sz = szFullPathDst; break;
case rcOutOfMemory: grc = grcOutOfMemory; break; case rcDiskFull: grc = grcDiskFull; fVital = TRUE; break;
case rcUserQuit: fRet = fFalse; goto LCopyError; break;
default: grc = grcDecompGenericErr; break; }
if ((eerc = EercErrorHandler(hwndFrame, grc, fVital, sz)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; }
//
// Before retrying we need to rewind the destination pointer to
// the place where we began the write
//
while (LfaSeekFile(pfhDst, lfaDst, sfmSet) == (LFA)(-1)) { if ((eerc = EercErrorHandler(hwndFrame, grcReadFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } } }
Assert(iTickCur <= cProgTicks); cProgTicks -= iTickCur;
}
if (oef & oefTimeStamp) while (!SetFileTime((HANDLE)LongToHandle(pfhDst->iDosfh), &CreateTime, &AccessTime, &WriteTime)) if ((eerc = EercErrorHandler(hwndFrame, grcWriteFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; }
if (fDecomp) { LZClose ( HandleToUlong(hSource) ); FreePfh ( pfhSrc ); hSource = NULL; pfhSrc = NULL;
} else { while (!FCloseFile(pfhSrc)) { if ((eerc = EercErrorHandler(hwndFrame, grcCloseFileErr, fVital, szFullPathSrc, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } } pfhSrc = NULL; }
//
// If we get here, the file was copied successfully.
// Close the file before we get the checksum
//
while (!FCloseFile(pfhDst)) { if ((eerc = EercErrorHandler(hwndFrame, grcCloseFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } } pfhDst = NULL;
ValidateAndChecksumFile( szFullPathDst, &IsNtImage, &Checksum, &IsValid );
if(!IsValid) { if ((eerc = EercErrorHandler(hwndFrame, grcVerifyFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } }
} while(!IsValid);
fRemovePartialFile = fFalse;
//
// At this point, we can delete the backup file we made (if we made one)
//
if(szActiveFileTmpName) { if(!FRemoveFile(szActiveFileTmpName)) { //
// It must be locked, so set it to be deleted on reboot
//
AddFileToDeleteList(szActiveFileTmpName); } free(szActiveFileTmpName); szActiveFileTmpName = NULL; }
if (oef & oefReadOnly) while (!FSetFileReadOnlyStatus(szFullPathDst, fOn)) { if ((eerc = EercErrorHandler(hwndFrame, grcWriteFileErr, fVital, szFullPathDst, 0, 0)) != eercRetry) { fRet = (eerc == eercIgnore); goto LCopyError; } }
fRet = fTrue;
LCopyError:
//
// Log the file.
//
if(psdle && !(oef & oefNoLog) && !fCsdInstall) { LogOneFile( szNonCompressedFullPathSrc, szFullPathDst, psdle->szLabel, Checksum, psdle->szTagFile, fThirdPartyFile ); }
if (pbBuffer != (PB)NULL) { SFree(pbBuffer); }
if (fDecomp && hSource != (HANDLE)NULL) { LZClose (HandleToUlong(hSource)); FreePfh (pfhSrc); } else if (pfhSrc != (PFH)NULL) { EvalAssert(FCloseFile(pfhSrc)); }
if (pfhDst != (PFH)NULL) { EvalAssert(FCloseFile(pfhDst)); }
if (fRemovePartialFile) {
FRemoveFile(szFullPathDst);
if(szActiveFileTmpName) { MoveFile(szActiveFileTmpName, szFullPathDst); free(szActiveFileTmpName); } }
//
// If we have any remaining ticks on the gauge for this file,
// go ahead and do them. This could happen if the file copy was
// aborted part way through.
//
if (cProgTicks > 0 && !fSilentSystem) { ProDeltaPos(cProgTicks); }
DelSrc:
//
// Determine whether we are supposed to delete the source file. This
// is the case when it is coming from a local source as created by the
// DOS Setup program, and is not marked oefNoDeleteSource.
//
if(!fNTUpgradeSetup && OnLocalSource && !(oef & oefNoDeleteSource)) { if (NULL == SzFindSymbolValueInSymTab("!STF_NETDELETEOVERIDE")) { DeleteFile(szFullPathSrc); } }
return(fRet); }
/*
** Purpose: ** To find a pointer to the beginning of the file name (i.e. primary.ext) ** at the end of a fully qualified pathname. ** Arguments: ** szFullPath: a non-Null, zero-terminated string containing a ** pathname ending in a file name. ** Returns: ** an SZ which is a pointer to the beginning of the file name within the ** argument SZ. ** **************************************************************************/ SZ APIENTRY SzFindFileFromPath(szFullPath) SZ szFullPath; { SZ sz; SZ szSave = szFullPath;
ChkArg(szFullPath != (SZ)NULL && *szFullPath != '\0' && *SzLastChar(szFullPath) != '\\', 1, (SZ)NULL);
for (sz = szFullPath; *sz != '\0'; sz = SzNextChar(sz)) if (*sz == '\\') szSave = sz;
Assert(szSave != NULL); if (*szSave == '\\') szSave = SzNextChar(szSave); Assert(szSave != NULL && *szSave != '\0');
return(szSave); }
/*
** Purpose: ** To find the beginning the beginning of the extension part of the file ** name within a string containing a file name (without the preceeding ** path name). ** Arguments: ** szFile: a zero terminated character string containing a valid file ** name (without the preceeding path name). ** Returns: ** an SZ that points to the '.' that begins the extension or '\0' if the ** file has no extension. ** **************************************************************************/ SZ APIENTRY SzFindExt(szFile) SZ szFile; { ChkArg(szFile != (SZ)NULL, 1, (SZ)NULL);
for ( ; *szFile != '\0' && *szFile != '.'; szFile = SzNextChar(szFile)) ;
return(szFile); }
/*
** Purpose: ** Build full path (check for ROOT and RENAME options) ** Arguments: ** szPath: non-NULL buffer to fill with full path. ** szDst: non-NULL string for szDstDir supplied on script line. ** psfd: non-NULL pointer to the Section-File Description structure(SFD). ** Assumes: ** szPath large enough for result. ** Returns: ** fTrue if successfully able to create the path, fFalse otherwise. ** **************************************************************************/ BOOL APIENTRY FBuildFullDstPath( SZ szPath, SZ szDst, PSFD psfd, BOOL fCompressedName ) { SZ szFile; SZ szFileDollar = NULL; POER poer = &(psfd->oer); BOOL bStatus;
ChkArg(szPath != (SZ)NULL, 1, fFalse); ChkArg(szDst != (SZ)NULL && FValidDir(szDst), 2, fFalse); ChkArg(psfd != (PSFD)NULL, 3, fFalse);
if (poer->szDest != NULL) { szDst = poer->szDest; }
if (poer->szAppend != NULL) { szFile = poer->szAppend; } else if (poer->szRename != NULL) { szFile = poer->szRename; } else { if (poer->oef & oefRoot) { szFile = SzFindFileFromPath(psfd->szFile); } else { szFile = psfd->szFile; }
if (!(poer->oef & oefDecompress) && fCompressedName) { while ((szFileDollar = SzGetSrcDollar(szFile,'_')) == (SZ)NULL) { if (!FHandleOOM(hwndFrame)) { return(fFalse); } } szFile = szFileDollar; } } bStatus = FMakePathFromDirAndSubPath(szDst, szFile, szPath, cchpFullPathBuf); if ( szFileDollar ) { SFree( szFileDollar); } return(bStatus); }
/*
** Purpose: ** Build full source path ** Arguments: ** szPath: non-NULL buffer to store result in. ** szDst: non-NULL valid subpath for dest. ** szFile: non-NULL file name. ** szNetPath: string pointer for netpath to use; NULL to ignore. ** Assumes: ** szPath large enough for result. ** Returns: ** fTrue if the path is built correctly, fFalse otherwise. ** **************************************************************************/ BOOL APIENTRY FBuildFullSrcPath(szPath, szDst, szFile, szNetPath) SZ szPath; SZ szDst; SZ szFile; SZ szNetPath; { CHP szPathTmp[cchpFullPathBuf];
ChkArg(szPath != (SZ)NULL, 1, fFalse); ChkArg(szDst != (SZ)NULL, 2, fFalse); ChkArg(szFile != (SZ)NULL, 3, fFalse);
if (szNetPath == NULL) return(FMakePathFromDirAndSubPath(szDst, szFile, szPath, cchpFullPathBuf)); else if (FMakePathFromDirAndSubPath(szDst, szNetPath, szPathTmp, cchpFullPathBuf) && FMakePathFromDirAndSubPath(szPathTmp, szFile, szPath, cchpFullPathBuf)) return(fTrue); else return(fFalse); }
/*
** Purpose: ** Build full BackupPath ** Arguments: ** szPath: non-NULL buffer to store result in. ** szDst: non-NULL valid subpath for dest. ** psfd: non-NULL SFD pointer. ** Assumes: ** szPath large enough for result. ** Returns: ** fTrue if successful; fFalse otherwise. ** **************************************************************************/ BOOL APIENTRY FBuildFullBakPath(szPath, szDst, psfd) SZ szPath; SZ szDst; PSFD psfd; { SZ sz;
ChkArg(szPath != (SZ)NULL, 1, fFalse); ChkArg(szDst != (SZ)NULL && *szDst != '\0', 2, fFalse); ChkArg(psfd != (PSFD)NULL && (psfd->oer).szBackup != NULL, 3, fFalse);
EvalAssert(szPath == szDst || strcpy(szPath, szDst) == szPath); sz = SzFindFileFromPath(szPath); Assert(sz != NULL && *sz != '\0');
if (*((psfd->oer).szBackup) == '*') { sz = SzFindExt(szPath); *sz++ = '.'; *sz++ = 'B'; /* REVIEW INTL */ *sz++ = 'A'; *sz++ = 'K'; *sz++ = '\0'; return(fTrue); }
*sz = '\0'; return(FMakePathFromDirAndSubPath(szPath, (psfd->oer).szBackup, szPath, cchpFullPathBuf)); }
/*
** Purpose: ** Verifies given file actually exists. ** Arguments: ** Returns: ** **************************************************************************/ BOOL APIENTRY FFileFound(szPath) SZ szPath; { WIN32_FIND_DATA ffd; HANDLE SearchHandle;
ChkArg(szPath != (SZ)NULL && *szPath != '\0', 1, fFalse);
if ( (SearchHandle = FindFirstFile( szPath, &ffd )) == INVALID_HANDLE_VALUE ) { return( fFalse ); } else { FindClose( SearchHandle ); return( fTrue ); } }
/*
** Purpose: ** Arguments: ** Returns: ** **************************************************************************/ BOOL APIENTRY FYield(VOID) { MSG msg; BOOL fRet = fTrue;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (hwndProgressGizmo != NULL && IsDialogMessage(hwndProgressGizmo, &msg)) continue;
if (msg.message == WM_QUIT) fRet = fFalse;
// if (CheckSpecialKeys(&msg))
// continue;
TranslateMessage(&msg); DispatchMessage(&msg); }
return(fRet); }
/*
** Purpose: ** To check and see if the directory specified in szFullPathDst exists. ** If not, it will create the directory (including any intermediate ** directories). For example if szFullPathDst = "c:\\a\\b\\File" and ** none of these directories exist (i.e. a or b) they will all be ** created so that the complete path exists (File is not created). ** Arguments: ** szFullPathDst: The complete pathname (including drive) of the directory ** in question. ** fCritical: if fTrue success of this operation is required for ** success of the setup program as a whole. Setup will be terminated ** if fCritical is fTrue and this function fails. ** szMsg: The complete pathname (including drive) of the directory ** to display in an error. If NULL use szFullPathDst. ** Returns: ** a YNRC error code (see _filecm.h) indicating the outcome of this ** function. ** **************************************************************************/ YNRC APIENTRY YnrcEnsurePathExists(szFullPathDst, fCritical, szMsg) SZ szFullPathDst; BOOL fCritical; SZ szMsg; { CHP szTmp[cchpFullPathBuf]; SZ sz; DWORD Attr; EERC eerc; YNRC ynrc = ynrcYes;
ChkArg(FValidPath(szFullPathDst),1,ynrcNo);
if (szMsg == (SZ)NULL) { szMsg = szFullPathDst; }
EvalAssert(strcpy((SZ)szTmp, szFullPathDst) == (SZ)szTmp);
EvalAssert((sz = SzFindFileFromPath(szTmp)) != (SZ)NULL); EvalAssert((sz = SzPrevChar(szTmp, sz)) != (SZ)NULL); Assert(*sz == '\\'); *sz = '\0';
while ( !( ((Attr = GetFileAttributes(szTmp)) != 0xFFFFFFFF && (Attr & FILE_ATTRIBUTE_DIRECTORY )) || CreateDirectory( szTmp, NULL ) ) ) { if ((eerc = EercErrorHandler(hwndFrame, grcCreateDirErr, fCritical, szMsg, 0, 0)) != eercRetry) { ynrc = (eerc == eercIgnore) ? ynrcErr1 : ynrcNo; break; } } return( ynrc ); }
int DetermineDriveType( IN CHAR DriveLetter )
/*++
Routine Description:
Determine whether a drive is removable media -- which can be a floppy or a CD-ROM. Removeable hard drives are NOT considered removeable by this routine.
Arguments:
DriveLetter - supplies drive letter of drive to check. If this is not a valid alpha char, FALSE is returned.
Return Value:
-2 - Drive is a CD-ROM -1 - Drive is some other removeable type (such as floppy) 0 - Drive is not removeable (or we couldn't tell)
--*/
{ CHAR Name[4]; UINT DriveType; CHAR DevicePath[MAX_PATH];
Name[0] = DriveLetter; Name[1] = ':'; Name[2] = '\\'; Name[3] = 0;
DriveType = GetDriveType(Name);
if(DriveType == DRIVE_REMOVABLE) {
Name[2] = 0;
if(QueryDosDevice(Name,DevicePath,MAX_PATH)) { CharUpper(DevicePath); if(strstr(DevicePath,"HARDDISK")) { DriveType = DRIVE_FIXED; } } }
if(DriveType == DRIVE_REMOVABLE) { return(-1); }
if(DriveType == DRIVE_CDROM) { return(-2); }
return(0); }
/*
** Purpose: ** Arguments: ** hInstance: non-NULL instance handle for getting strings from ** resources for SwapDisk message Box. ** szLabel: non-Null zero-terminated ANSI string to display as the ** label of the diskette to prompt for. ** szSrcDir: non-Null zero-terminated ANSI string to display as the ** drive/directory the user is to insert the diskette into. ** Returns: ** **************************************************************************/ BOOL APIENTRY FPromptForDisk(hInstance, szLabel, szSrcDir) HANDLE hInstance; SZ szLabel; SZ szSrcDir; { CHAR szTmpText[cchpBufTmpLongMax]; CHAR rgchBuf[3*cchpFullPathBuf]; BOOL fRet; HWND hwndSav;
ChkArg(hInstance,1,fFalse); ChkArg(szLabel && *szLabel && strlen(szLabel) <= cchpFullPathMax, 2, fFalse); ChkArg(szSrcDir && *szSrcDir && strlen(szSrcDir) <= cchpFullPathMax, 3, fFalse);
EvalAssert(LoadString(hInstance, IDS_INS_DISK, rgchBuf,3*cchpFullPathBuf)); EvalAssert(SzStrCat(rgchBuf, szLabel) == rgchBuf); EvalAssert(LoadString(hInstance, IDS_INTO, szTmpText, cchpBufTmpLongMax)); EvalAssert(SzStrCat(rgchBuf, szTmpText) == rgchBuf); EvalAssert(SzStrCat(rgchBuf, szSrcDir) == rgchBuf);
EvalAssert(LoadString(hInstance, IDS_ERROR, szTmpText, cchpBufTmpLongMax));
hwndSav = GetFocus(); fRet = (MessageBox(hwndFrame,rgchBuf,szTmpText,MB_OKCANCEL|MB_TASKMODAL) == IDOK); SetFocus(hwndSav); SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L);
return(fRet); }
/*
** Purpose: ** To rename an active file as an del????.tmp file which will be deleted if ** the new file is copied successfully. ** Arguments: ** szFullPath: Full pathname of active file ** Returns: ** The name of the renamed file, or NULL if unsuccessful. ** **************************************************************************/ SZ APIENTRY FRenameActiveFile( SZ szFullPath ) { SZ szTmpName; CHP szDir[MAX_PATH]; SZ sz;
ChkArg ( szFullPath != NULL, 1, NULL);
//
// Try to find a temp filename we can use in the destination directory
//
lstrcpy( szDir, szFullPath ); if( !(sz = strrchr( szDir, '\\')) ) { return NULL; } *sz = '\0';
if(!(szTmpName = malloc((lstrlen(szDir) + 14) * sizeof(CHP)))) { return NULL; }
if(!GetTempFileName( szDir, "del", 0, szTmpName )) { goto FileRenameFailed; }
//
// GetTempFileName creates the temp file. It needs to be deleted
//
if (FFileFound(szTmpName) && !FRemoveFile(szTmpName)) { goto FileRenameFailed; }
//
// Rename the original file to this filename
//
if( MoveFile( szFullPath, szTmpName ) ) { return szTmpName; }
FileRenameFailed:
free(szTmpName); return NULL; }
BOOL FGetFileSecurity( PCHAR File, PSECURITY_DESCRIPTOR *SdBuf, CB *SdLen ) { #define CBSDBUF 1024
SECURITY_INFORMATION Si; PSECURITY_DESCRIPTOR Sd, SdNew; DWORD cbSd = CBSDBUF; DWORD cbSdReq; BOOL FirstTime = fTrue; DWORD dw1, dw2; EERC eerc;
static CHAR Root[MAX_PATH] = "\0"; static BOOL IsNtfs = FALSE; CHAR VolumeFSName[MAX_PATH];
//
// Initialize
//
*SdBuf = NULL;
//
// Check if the volume information is in the cache, if not so get the
// volume information and put it in the cache
//
if( Root[0] == '\0' ) { if( !ISUNC( File ) ) { strncpy( Root, File, 3 ); Root[3] = '\0'; } else { PCHAR p; ULONG n;
p = File + 2; if( ( ( p = strchr( p, '\\' ) ) == NULL ) || ( ( p = strchr( p + 1, '\\' ) ) == NULL ) ) { return( FALSE ); } n = (ULONG)(p - File + 1); strncpy( Root, File, n ); Root[ n ] = '\0'; } while(!GetVolumeInformation( Root, NULL, 0, NULL, &dw1, &dw2, VolumeFSName, MAX_PATH )) { if ((eerc = EercErrorHandler(hwndFrame, grcGetVolInfo, FALSE, Root, File, 0)) != eercRetry) { return(eerc == eercIgnore); } } IsNtfs = !lstrcmpi( VolumeFSName, "NTFS" ); }
if(!IsNtfs) { return(TRUE); }
//
// Allocate memory for the security descriptor
//
while ((Sd = SAlloc(cbSd)) == NULL ) { if (!FHandleOOM(hwndFrame)) { return(fFalse); } }
//
// Get the security information from the source file
//
Si = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; while(!GetFileSecurity(File,Si,Sd,cbSd,&cbSdReq)) { if( FirstTime && (cbSdReq > cbSd) ) { while(!(SdNew = SRealloc(Sd,cbSdReq))) { if (!FHandleOOM(hwndFrame)) { SFree(Sd); return(fFalse); } } cbSd = cbSdReq; Sd = SdNew; } else { if ((eerc = EercErrorHandler(hwndFrame, grcGetFileSecurity, FALSE, File, 0, 0)) != eercRetry) { SFree(Sd); return(eerc == eercIgnore); } } FirstTime = fFalse; }
*SdBuf = Sd; *SdLen = cbSd; return(TRUE); }
BOOL FSetFileSecurity( PCHAR File, PSECURITY_DESCRIPTOR SdBuf ) { EERC eerc; SECURITY_INFORMATION Si;
//
// Set the Security on the dest file
//
Si = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; while(!SetFileSecurity(File, Si, SdBuf)) { #if 0
//
// BUGBUG - This is to find an error in DaveC's machine
//
CHAR DbgBuffer[256]; ULONG Error;
Error = GetLastError(); sprintf( DbgBuffer, "SetFileSecurity() failed. \nFile = %s. \nError = %d \n\nPlease contact JaimeS at x65903", File, Error ); MessageBox(NULL, DbgBuffer, "Debug Message", MB_OK | MB_ICONHAND); #endif
if ((eerc = EercErrorHandler(hwndFrame, grcSetFileSecurity, FALSE, File, 0, 0)) != eercRetry) { return(eerc == eercIgnore); } } return(TRUE); }
BOOL DoesFileReplaceThirdPartyFile( SZ szFullPathDst )
{ CHAR SetupLogFilePath[ MAX_PATH ]; PSTR SectionName; CHAR ReturnBuffer[512]; PSTR DefaultString = ""; PSTR SectionsToSearch[] = { "Files.WinNt", "Files.SystemPartition" }; ULONG Count; BOOL ReplaceThirdParty;
*SetupLogFilePath = '\0'; GetWindowsDirectory( SetupLogFilePath, sizeof( SetupLogFilePath ) ); strcat( SetupLogFilePath, SETUP_REPAIR_DIRECTORY ); strcat( SetupLogFilePath, SETUP_LOG_FILE );
for( Count = 0; Count < sizeof( SectionsToSearch ) / sizeof( PSTR ); Count++ ) {
SectionName = SectionsToSearch[Count]; *ReturnBuffer = '\0'; GetPrivateProfileString( SectionName, szFullPathDst, DefaultString, ReturnBuffer, sizeof( ReturnBuffer ), SetupLogFilePath );
if( *ReturnBuffer != '\0' ) { break; } }
ReplaceThirdParty = FALSE; if( *ReturnBuffer != 0 ) { PSTR SourceFileName; PSTR ChkSumString; PSTR DirectoryOnSourceDevice; PSTR DiskDescription; PSTR DiskTag; PSTR Delimiters = "\" ,";
SourceFileName = strtok( ReturnBuffer, Delimiters ); SourceFileName = strtok( NULL, Delimiters ); ChkSumString = strtok( NULL, Delimiters ); DirectoryOnSourceDevice = strtok( NULL, Delimiters ); DiskDescription = strtok( NULL, Delimiters ); DiskTag = strtok( NULL, Delimiters );
if( ( DiskDescription != NULL ) || ( DiskTag != NULL ) ) { ReplaceThirdParty = TRUE; } } return( ReplaceThirdParty ); }
|