|
|
#include <windows.h>
#include "download.h"
#include "setupbat.h"
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
//
// these are the critical files that must be copied locally if the
// upgrade of a Win9x system is performed over a network
//
static PCTSTR g_CriticalFiles[] = { TEXT("WINNT32.EXE"), TEXT("WINNT32A.DLL"), TEXT("WINNTBBA.DLL"), TEXT("PIDGEN.DLL"), TEXT("WSDU.DLL"), TEXT("WSDUENG.DLL"), TEXT("HWDB.DLL"), TEXT("WIN9XUPG"), TEXT("drw") };
//
// these are the critical files for NEC98 plattform that must be copied
// locally if the upgrade of a Win9x system is performed over a network
//
static PCTSTR g_NEC98_CriticalFiles[] = { TEXT("98PTN16.DLL"), TEXT("98PTN32.DLL") };
//
// these are non-critical files that should be copied locally if the
// upgrade of a Win9x system is performed over a network
//
static PCTSTR g_NonCriticalFiles[] = { TEXT("IDWLOG.EXE"), // #define RUN_SYSPARSE = 1
#ifdef RUN_SYSPARSE
TEXT("SYSPARSE.EXE"), #endif
TEXT("WINNT32.HLP"), TEXT("DOSNET.INF"), };
BOOL pIsSpecialDir ( IN PCTSTR Dir )
/*++
Routine Description:
pIsSpecialDir decides if the given dir is a special directory, like . or ..
Arguments:
Dir - Specifies the directory name only (no path)
Return Value:
TRUE if the specified dir name is a special name
--*/
{ return *Dir == TEXT('.') && (*(Dir + 1) == 0 || *(Dir + 1) == TEXT('.') && *(Dir + 2) == 0) ; }
BOOL CopyNode ( IN PCTSTR SrcBaseDir, IN PCTSTR DestBaseDir, IN PCTSTR NodeName, IN BOOL FailIfExist, IN BOOL FailIfSourceDoesntExist )
/*++
Routine Description:
CopyNode copies NodeName (file or subdir) from SrcBaseDir to DestBaseDir.
Arguments:
SrcBaseDir - Specifies the source base directory name
DestBaseDir - Specifies the destination base directory name
NodeName - Specifies the file or subdirectory name to copy
FailIfExist - Specifies if the operation should fail if there is already a node with the same name at destination
FailIfSourceDoesntExist - Specifies if the operation should fail if NO source node exists
Return Value:
TRUE if the copy operation was actually done
--*/
{ DWORD FileAttr; TCHAR SrcDir[MAX_PATH]; //note: ConcatenatePaths inserts a wack, wack, *.
TCHAR DestDir[MAX_PATH]; //note: ConcatenatePaths inserts 1 wack later on.
HANDLE h; WIN32_FIND_DATA fd; WIN32_FIND_DATA fdSrc; DWORD attribs; UINT nameLen;
nameLen = lstrlen(NodeName);
if(lstrlen(SrcBaseDir) + nameLen + 3 >= ARRAYSIZE(SrcDir) || //3 <== wack, wack, *
lstrlen(DestBaseDir) + nameLen + 1 >= ARRAYSIZE(DestDir)){ //1 <== wack
return FALSE; } lstrcpy (SrcDir, SrcBaseDir); lstrcpy (DestDir, DestBaseDir);
//
// check for "\" at the end of dir name
//
ConcatenatePaths (SrcDir, NodeName);
h = FindFirstFile (SrcDir, &fdSrc); if (h == INVALID_HANDLE_VALUE) {
if (GetLastError () != ERROR_FILE_NOT_FOUND) { return FALSE; }
return !FailIfSourceDoesntExist; } CloseHandle (h);
if (GetFileAttributes (DestDir) == -1) { if (!CreateDirectory (DestDir, NULL)) { return FALSE; } }
if (fdSrc.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
//
// skip to the end of dir name
//
ConcatenatePaths (DestDir, NodeName);
ConcatenatePaths (SrcDir, TEXT("*"));
h = FindFirstFile (SrcDir, &fd);
*FindLastWack (SrcDir) = 0;
//
// recursively copy all files in that dir
//
if (h != INVALID_HANDLE_VALUE) { do { //
// skip over special dirs
//
if (pIsSpecialDir (fd.cFileName)) { continue; }
if (!CopyNode (SrcDir, DestDir, fd.cFileName, FailIfExist, FailIfSourceDoesntExist)) { return FALSE; } } while (FindNextFile (h, &fd)); } } else { //
// copy the file
//
ConcatenatePaths (DestDir, NodeName); if (!CopyFile (SrcDir, DestDir, FailIfExist)) { return FALSE; } //
// set file timestamps to match exactly the ones of the original
// ignore errors in this case
//
SetFileAttributes (DestDir, FILE_ATTRIBUTE_NORMAL); h = CreateFile (DestDir, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (h != INVALID_HANDLE_VALUE) { SetFileTime (h, &fdSrc.ftCreationTime, &fdSrc.ftLastAccessTime, &fdSrc.ftLastWriteTime); CloseHandle (h); } }
return TRUE; }
BOOL DeleteNode ( IN PCTSTR NodeName )
/*++
Routine Description:
DeleteNode deletes NodeName directory and all its subdirectories
Arguments:
NodeName - Specifies the directory name to delete
Return Value:
TRUE if the delete operation was successful; FALSE if only part of the files/subdirs were deleted
--*/
{ DWORD FileAttr; TCHAR DestDir[MAX_PATH]; //note: ConcatenatePaths adds: wack, *
PTSTR p; HANDLE h; WIN32_FIND_DATA fd; BOOL Success = TRUE;
if (!NodeName || !*NodeName || (lstrlen(NodeName) + 2 >= ARRAYSIZE(DestDir))) { // 2 <== wack, *
return FALSE; }
FileAttr = GetFileAttributes (NodeName); if (FileAttr == -1) return TRUE;
if (!SetFileAttributes (NodeName, FILE_ATTRIBUTE_NORMAL)) { return FALSE; }
if (FileAttr & FILE_ATTRIBUTE_DIRECTORY) {
lstrcpy (DestDir, NodeName);
ConcatenatePaths (DestDir, TEXT("*"));
h = FindFirstFile (DestDir, &fd);
p = FindLastWack (DestDir);
//
// recursively copy all files in that dir
//
if (h != INVALID_HANDLE_VALUE) { do { //
// skip over special dirs
//
if (pIsSpecialDir (fd.cFileName)) { continue; }
if (SUCCEEDED(StringCchCopy(p + 1, DestDir + ARRAYSIZE(DestDir) - (p + 1), fd.cFileName))) { if (!DeleteNode (DestDir)) { Success = FALSE; } } else { Success = FALSE; } } while (FindNextFile (h, &fd)); }
//
// now delete the base dir
//
*p = 0;
if (!RemoveDirectory (DestDir)) { Success = FALSE; } } else { //
// delete the file
//
if (!DeleteFile (NodeName)) { Success = FALSE; } }
return Success; }
BOOL DownloadProgramFiles ( IN PCTSTR SourceDir, IN PCTSTR DownloadDest, IN PCTSTR* ExtraFiles OPTIONAL )
/*++
Routine Description:
DownloadProgramFiles copies from SourceDir to DownloadDest all specific program files (specified in g_CriticalFiles, g_NEC98_CriticalFiles, and g_NonCriticalFiles arrays).
Arguments:
SourceDir - Specifies the source directory
DownloadDest - Specifies the destination directory
ExtraFiles - Specifies an array of extra files (full paths) to be copied to the destination directory; the array must be NULL terminated
Return Value:
TRUE if the download operation was successful and all critical files were copied locally; FALSE otherwise
--*/
{ TCHAR SourcePath[MAX_PATH]; TCHAR DestPath[MAX_PATH]; INT i; PTSTR FileName; TCHAR FullPathName[MAX_PATH];
//
// first delete any old stuff to make place
//
DeleteNode (DownloadDest);
if(lstrlen(SourceDir) >= ARRAYSIZE(SourcePath) || lstrlen(DownloadDest) >= ARRAYSIZE(DestPath)){ return FALSE; } //
// copy there the new stuff
//
lstrcpy (SourcePath, SourceDir); lstrcpy (DestPath, DownloadDest);
for (i = 0; i < sizeof (g_CriticalFiles) / sizeof (g_CriticalFiles[0]); i++) { //
// download this one to the destination directory
//
if (!CopyNode (SourcePath, DestPath, g_CriticalFiles[i], FALSE, FALSE)) { DeleteNode (DownloadDest); return FALSE; } }
if (ExtraFiles) { while (*ExtraFiles) { FileName = FindLastWack ((PTSTR)*ExtraFiles); if (FileName) {
StringCchCopy(FullPathName, ARRAYSIZE(FullPathName), DownloadDest); if (SUCCEEDED(StringCchCat(FullPathName, ARRAYSIZE(FullPathName), FileName))) { CopyFile (*ExtraFiles, FullPathName, FALSE); } } ExtraFiles++; } }
for (i = 0; i < sizeof (g_NEC98_CriticalFiles) / sizeof (g_NEC98_CriticalFiles[0]); i++) { //
// download this one to the destination directory
//
// Never check for error. Because winnt32a.dll check plattform and
// sources with NEC98 specific file(98ptn16.dll).
// See winnt32\dll\winnt32.c line 2316.
//
CopyNode (SourcePath, DestPath, g_NEC98_CriticalFiles[i], FALSE, FALSE); } for (i = 0; i < sizeof (g_NonCriticalFiles) / sizeof (g_NonCriticalFiles[0]); i++) { //
// download this one to the destination directory
//
CopyNode (SourcePath, DestPath, g_NonCriticalFiles[i], FALSE, FALSE); }
return TRUE; }
|