/*++ 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: () Revision History: --*/ #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 \*. // 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 \*. // 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; }