windows-nt/Source/XPSP1/NT/base/ntsetup/winnt32/exe/i386/download.c

383 lines
8.5 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#include <windows.h>
#include "download.h"
#include "setupbat.h"
//
// 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
)
/*++
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
Return Value:
TRUE if the copy operation was actually done
--*/
{
DWORD FileAttr;
TCHAR SrcDir[MAX_PATH];
TCHAR DestDir[MAX_PATH];
HANDLE h;
WIN32_FIND_DATA fd;
WIN32_FIND_DATA fdSrc;
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) {
return FALSE;
}
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)) {
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];
PTSTR p;
HANDLE h;
WIN32_FIND_DATA fd;
BOOL Success = TRUE;
if (!NodeName || !*NodeName) {
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;
}
lstrcpy (p + 1, fd.cFileName);
if (!DeleteNode (DestDir)) {
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);
//
// 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)) {
DeleteNode (DownloadDest);
return FALSE;
}
}
if (ExtraFiles) {
while (*ExtraFiles) {
FileName = FindLastWack ((PTSTR)*ExtraFiles);
if (FileName) {
lstrcpy (FullPathName, DownloadDest);
lstrcat (FullPathName, FileName);
CopyFile (*ExtraFiles, FullPathName, FALSE);
}
ExtraFiles++;
}
}
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)) {
DeleteNode (DownloadDest);
return FALSE;
}
}
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);
}
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);
}
return TRUE;
}