Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

413 lines
10 KiB

#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;
}