mirror of https://github.com/tongzx/nt5src
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.
375 lines
7.5 KiB
375 lines
7.5 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
nttool.c
|
|
|
|
Abstract:
|
|
|
|
Implements a stub tool that is designed to run with NT-side
|
|
upgrade code.
|
|
|
|
Author:
|
|
|
|
<full name> (<alias>) <date>
|
|
|
|
Revision History:
|
|
|
|
<alias> <date> <comments>
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include "setupapi.h"
|
|
#include "sputils.h"
|
|
#include "setupapi.h"
|
|
#include "regstr.h"
|
|
|
|
|
|
BOOL
|
|
Init (
|
|
VOID
|
|
)
|
|
{
|
|
HINSTANCE hInstance;
|
|
DWORD dwReason;
|
|
PVOID lpReserved;
|
|
|
|
//
|
|
// Simulate DllMain
|
|
//
|
|
|
|
hInstance = GetModuleHandle (NULL);
|
|
dwReason = DLL_PROCESS_ATTACH;
|
|
lpReserved = NULL;
|
|
|
|
//
|
|
// Initialize DLL globals
|
|
//
|
|
|
|
if (!FirstInitRoutine (hInstance)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Initialize all libraries
|
|
//
|
|
|
|
if (!InitLibs (hInstance, dwReason, lpReserved)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Final initialization
|
|
//
|
|
|
|
if (!FinalInitRoutine ()) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
Terminate (
|
|
VOID
|
|
)
|
|
{
|
|
HINSTANCE hInstance;
|
|
DWORD dwReason;
|
|
PVOID lpReserved;
|
|
|
|
//
|
|
// Simulate DllMain
|
|
//
|
|
|
|
hInstance = GetModuleHandle (NULL);
|
|
dwReason = DLL_PROCESS_DETACH;
|
|
lpReserved = NULL;
|
|
|
|
//
|
|
// Call the cleanup routine that requires library APIs
|
|
//
|
|
|
|
FirstCleanupRoutine();
|
|
|
|
//
|
|
// Clean up all libraries
|
|
//
|
|
|
|
TerminateLibs (hInstance, dwReason, lpReserved);
|
|
|
|
//
|
|
// Do any remaining clean up
|
|
//
|
|
|
|
FinalCleanupRoutine();
|
|
}
|
|
|
|
#define MyMalloc(s) HeapAlloc(g_hHeap,0,s)
|
|
#define MyRealloc(p,s) HeapReAlloc(g_hHeap,0,p,s)
|
|
#define MyFree(p) HeapFree(g_hHeap,0,p)
|
|
|
|
BOOL
|
|
FileExists(
|
|
IN PCTSTR FileName,
|
|
OUT PWIN32_FIND_DATA FindData OPTIONAL
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determine if a file exists and is accessible.
|
|
Errormode is set (and then restored) so the user will not see
|
|
any pop-ups.
|
|
|
|
Arguments:
|
|
|
|
FileName - supplies full path of file to check for existance.
|
|
|
|
FindData - if specified, receives find data for the file.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the file exists and is accessible.
|
|
FALSE if not. GetLastError() returns extended error info.
|
|
|
|
--*/
|
|
|
|
{
|
|
WIN32_FIND_DATA findData;
|
|
HANDLE FindHandle;
|
|
UINT OldMode;
|
|
DWORD Error;
|
|
|
|
OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
|
|
FindHandle = FindFirstFile(FileName,&findData);
|
|
if(FindHandle == INVALID_HANDLE_VALUE) {
|
|
Error = GetLastError();
|
|
} else {
|
|
FindClose(FindHandle);
|
|
if(FindData) {
|
|
*FindData = findData;
|
|
}
|
|
Error = NO_ERROR;
|
|
}
|
|
|
|
SetErrorMode(OldMode);
|
|
|
|
SetLastError(Error);
|
|
return (Error == NO_ERROR);
|
|
}
|
|
|
|
DWORD
|
|
TreeCopy(
|
|
IN PCWSTR SourceDir,
|
|
IN PCWSTR TargetDir
|
|
)
|
|
{
|
|
DWORD d;
|
|
WCHAR Pattern[MAX_PATH];
|
|
WCHAR NewTarget[MAX_PATH];
|
|
WIN32_FIND_DATA FindData;
|
|
HANDLE FindHandle;
|
|
|
|
//
|
|
// First create the target directory if it doesn't already exist.
|
|
//
|
|
if(!CreateDirectory(TargetDir,NULL)) {
|
|
d = GetLastError();
|
|
if(d != ERROR_ALREADY_EXISTS) {
|
|
return(d);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Copy each file in the source directory to the target directory.
|
|
// If any directories are encountered along the way recurse to copy them
|
|
// as they are encountered.
|
|
//
|
|
// Start by forming the search pattern, which is <sourcedir>\*.
|
|
//
|
|
lstrcpyn(Pattern,SourceDir,MAX_PATH);
|
|
pSetupConcatenatePaths(Pattern,L"*",MAX_PATH,NULL);
|
|
|
|
//
|
|
// Start the search.
|
|
//
|
|
FindHandle = FindFirstFile(Pattern,&FindData);
|
|
if(FindHandle == INVALID_HANDLE_VALUE) {
|
|
|
|
d = NO_ERROR;
|
|
|
|
} else {
|
|
|
|
do {
|
|
|
|
//
|
|
// Form the full name of the file or directory we just found
|
|
// as well as its name in the target.
|
|
//
|
|
lstrcpyn(Pattern,SourceDir,MAX_PATH);
|
|
pSetupConcatenatePaths(Pattern,FindData.cFileName,MAX_PATH,NULL);
|
|
|
|
lstrcpyn(NewTarget,TargetDir,MAX_PATH);
|
|
pSetupConcatenatePaths(NewTarget,FindData.cFileName,MAX_PATH,NULL);
|
|
|
|
if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
|
|
//
|
|
// The current match is a directory. Recurse into it unless
|
|
// it's . or ...
|
|
//
|
|
if(lstrcmp(FindData.cFileName,TEXT("." )) && lstrcmp(FindData.cFileName,TEXT(".."))) {
|
|
d = TreeCopy(Pattern,NewTarget);
|
|
} else {
|
|
d = NO_ERROR;
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// The current match is not a directory -- so copy it.
|
|
//
|
|
SetFileAttributes(NewTarget,FILE_ATTRIBUTE_NORMAL);
|
|
d = CopyFile(Pattern,NewTarget,FALSE) ? NO_ERROR : GetLastError();
|
|
}
|
|
} while((d==NO_ERROR) && FindNextFile(FindHandle,&FindData));
|
|
|
|
FindClose(FindHandle);
|
|
}
|
|
|
|
return(d);
|
|
}
|
|
|
|
VOID
|
|
Delnode(
|
|
IN PCWSTR Directory
|
|
)
|
|
{
|
|
WCHAR Pattern[MAX_PATH];
|
|
WIN32_FIND_DATA FindData;
|
|
HANDLE FindHandle;
|
|
|
|
//
|
|
// Delete each file in the given directory, then remove the directory itself.
|
|
// If any directories are encountered along the way recurse to delete them
|
|
// as they are encountered.
|
|
//
|
|
// Start by forming the search pattern, which is <currentdir>\*.
|
|
//
|
|
lstrcpyn(Pattern,Directory,MAX_PATH);
|
|
pSetupConcatenatePaths(Pattern,L"*",MAX_PATH,NULL);
|
|
|
|
//
|
|
// Start the search.
|
|
//
|
|
FindHandle = FindFirstFile(Pattern,&FindData);
|
|
if(FindHandle != INVALID_HANDLE_VALUE) {
|
|
|
|
do {
|
|
|
|
//
|
|
// Form the full name of the file or directory we just found.
|
|
//
|
|
lstrcpyn(Pattern,Directory,MAX_PATH);
|
|
pSetupConcatenatePaths(Pattern,FindData.cFileName,MAX_PATH,NULL);
|
|
|
|
//
|
|
// Remove read-only atttribute if it's there.
|
|
//
|
|
if(FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
|
|
SetFileAttributes(Pattern,FILE_ATTRIBUTE_NORMAL);
|
|
}
|
|
|
|
if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
|
|
//
|
|
// The current match is a directory. Recurse into it unless
|
|
// it's . or ...
|
|
//
|
|
if(lstrcmp(FindData.cFileName,TEXT("." )) && lstrcmp(FindData.cFileName,TEXT(".."))) {
|
|
Delnode(Pattern);
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// The current match is not a directory -- so delete it.
|
|
//
|
|
if(!DeleteFile(Pattern)) {
|
|
}
|
|
}
|
|
} while(FindNextFile(FindHandle,&FindData));
|
|
|
|
FindClose(FindHandle);
|
|
}
|
|
|
|
//
|
|
// Remove the directory we just emptied out. Ignore errors.
|
|
//
|
|
SetFileAttributes(Directory,FILE_ATTRIBUTE_NORMAL);
|
|
RemoveDirectory(Directory);
|
|
}
|
|
|
|
|
|
BOOL
|
|
CallDuFunction (
|
|
IN PCTSTR SyssetupPath
|
|
)
|
|
{
|
|
BOOL b = FALSE;
|
|
HMODULE hSyssetup;
|
|
BOOL (*pfn) (
|
|
VOID
|
|
);
|
|
|
|
hSyssetup = LoadLibrary (SyssetupPath);
|
|
|
|
if (hSyssetup) {
|
|
(FARPROC)pfn = GetProcAddress (hSyssetup, "DynamicUpdateInstallDuAsms");
|
|
if (pfn) {
|
|
b = pfn ();
|
|
}
|
|
|
|
FreeLibrary (hSyssetup);
|
|
}
|
|
|
|
return b;
|
|
}
|
|
|
|
|
|
INT
|
|
__cdecl
|
|
wmain (
|
|
INT argc,
|
|
WCHAR *argv[]
|
|
)
|
|
{
|
|
LONG rc;
|
|
|
|
if (argc < 2) {
|
|
return -1;
|
|
}
|
|
|
|
if (!Init()) {
|
|
|
|
wprintf (L"Unable to initialize!\n");
|
|
return 255;
|
|
}
|
|
|
|
CallDuFunction (argv[1]);
|
|
|
|
Terminate();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|