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