Source code of Windows XP (NT5)
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

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. nttool.c
  5. Abstract:
  6. Implements a stub tool that is designed to run with NT-side
  7. upgrade code.
  8. Author:
  9. <full name> (<alias>) <date>
  10. Revision History:
  11. <alias> <date> <comments>
  12. --*/
  13. #include "pch.h"
  14. #include "setupapi.h"
  15. #include "sputils.h"
  16. #include "setupapi.h"
  17. #include "regstr.h"
  18. BOOL
  19. Init (
  20. VOID
  21. )
  22. {
  23. HINSTANCE hInstance;
  24. DWORD dwReason;
  25. PVOID lpReserved;
  26. //
  27. // Simulate DllMain
  28. //
  29. hInstance = GetModuleHandle (NULL);
  30. dwReason = DLL_PROCESS_ATTACH;
  31. lpReserved = NULL;
  32. //
  33. // Initialize DLL globals
  34. //
  35. if (!FirstInitRoutine (hInstance)) {
  36. return FALSE;
  37. }
  38. //
  39. // Initialize all libraries
  40. //
  41. if (!InitLibs (hInstance, dwReason, lpReserved)) {
  42. return FALSE;
  43. }
  44. //
  45. // Final initialization
  46. //
  47. if (!FinalInitRoutine ()) {
  48. return FALSE;
  49. }
  50. return TRUE;
  51. }
  52. VOID
  53. Terminate (
  54. VOID
  55. )
  56. {
  57. HINSTANCE hInstance;
  58. DWORD dwReason;
  59. PVOID lpReserved;
  60. //
  61. // Simulate DllMain
  62. //
  63. hInstance = GetModuleHandle (NULL);
  64. dwReason = DLL_PROCESS_DETACH;
  65. lpReserved = NULL;
  66. //
  67. // Call the cleanup routine that requires library APIs
  68. //
  69. FirstCleanupRoutine();
  70. //
  71. // Clean up all libraries
  72. //
  73. TerminateLibs (hInstance, dwReason, lpReserved);
  74. //
  75. // Do any remaining clean up
  76. //
  77. FinalCleanupRoutine();
  78. }
  79. #define MyMalloc(s) HeapAlloc(g_hHeap,0,s)
  80. #define MyRealloc(p,s) HeapReAlloc(g_hHeap,0,p,s)
  81. #define MyFree(p) HeapFree(g_hHeap,0,p)
  82. BOOL
  83. FileExists(
  84. IN PCTSTR FileName,
  85. OUT PWIN32_FIND_DATA FindData OPTIONAL
  86. )
  87. /*++
  88. Routine Description:
  89. Determine if a file exists and is accessible.
  90. Errormode is set (and then restored) so the user will not see
  91. any pop-ups.
  92. Arguments:
  93. FileName - supplies full path of file to check for existance.
  94. FindData - if specified, receives find data for the file.
  95. Return Value:
  96. TRUE if the file exists and is accessible.
  97. FALSE if not. GetLastError() returns extended error info.
  98. --*/
  99. {
  100. WIN32_FIND_DATA findData;
  101. HANDLE FindHandle;
  102. UINT OldMode;
  103. DWORD Error;
  104. OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  105. FindHandle = FindFirstFile(FileName,&findData);
  106. if(FindHandle == INVALID_HANDLE_VALUE) {
  107. Error = GetLastError();
  108. } else {
  109. FindClose(FindHandle);
  110. if(FindData) {
  111. *FindData = findData;
  112. }
  113. Error = NO_ERROR;
  114. }
  115. SetErrorMode(OldMode);
  116. SetLastError(Error);
  117. return (Error == NO_ERROR);
  118. }
  119. DWORD
  120. TreeCopy(
  121. IN PCWSTR SourceDir,
  122. IN PCWSTR TargetDir
  123. )
  124. {
  125. DWORD d;
  126. WCHAR Pattern[MAX_PATH];
  127. WCHAR NewTarget[MAX_PATH];
  128. WIN32_FIND_DATA FindData;
  129. HANDLE FindHandle;
  130. //
  131. // First create the target directory if it doesn't already exist.
  132. //
  133. if(!CreateDirectory(TargetDir,NULL)) {
  134. d = GetLastError();
  135. if(d != ERROR_ALREADY_EXISTS) {
  136. return(d);
  137. }
  138. }
  139. //
  140. // Copy each file in the source directory to the target directory.
  141. // If any directories are encountered along the way recurse to copy them
  142. // as they are encountered.
  143. //
  144. // Start by forming the search pattern, which is <sourcedir>\*.
  145. //
  146. lstrcpyn(Pattern,SourceDir,MAX_PATH);
  147. pSetupConcatenatePaths(Pattern,L"*",MAX_PATH,NULL);
  148. //
  149. // Start the search.
  150. //
  151. FindHandle = FindFirstFile(Pattern,&FindData);
  152. if(FindHandle == INVALID_HANDLE_VALUE) {
  153. d = NO_ERROR;
  154. } else {
  155. do {
  156. //
  157. // Form the full name of the file or directory we just found
  158. // as well as its name in the target.
  159. //
  160. lstrcpyn(Pattern,SourceDir,MAX_PATH);
  161. pSetupConcatenatePaths(Pattern,FindData.cFileName,MAX_PATH,NULL);
  162. lstrcpyn(NewTarget,TargetDir,MAX_PATH);
  163. pSetupConcatenatePaths(NewTarget,FindData.cFileName,MAX_PATH,NULL);
  164. if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  165. //
  166. // The current match is a directory. Recurse into it unless
  167. // it's . or ...
  168. //
  169. if(lstrcmp(FindData.cFileName,TEXT("." )) && lstrcmp(FindData.cFileName,TEXT(".."))) {
  170. d = TreeCopy(Pattern,NewTarget);
  171. } else {
  172. d = NO_ERROR;
  173. }
  174. } else {
  175. //
  176. // The current match is not a directory -- so copy it.
  177. //
  178. SetFileAttributes(NewTarget,FILE_ATTRIBUTE_NORMAL);
  179. d = CopyFile(Pattern,NewTarget,FALSE) ? NO_ERROR : GetLastError();
  180. }
  181. } while((d==NO_ERROR) && FindNextFile(FindHandle,&FindData));
  182. FindClose(FindHandle);
  183. }
  184. return(d);
  185. }
  186. VOID
  187. Delnode(
  188. IN PCWSTR Directory
  189. )
  190. {
  191. WCHAR Pattern[MAX_PATH];
  192. WIN32_FIND_DATA FindData;
  193. HANDLE FindHandle;
  194. //
  195. // Delete each file in the given directory, then remove the directory itself.
  196. // If any directories are encountered along the way recurse to delete them
  197. // as they are encountered.
  198. //
  199. // Start by forming the search pattern, which is <currentdir>\*.
  200. //
  201. lstrcpyn(Pattern,Directory,MAX_PATH);
  202. pSetupConcatenatePaths(Pattern,L"*",MAX_PATH,NULL);
  203. //
  204. // Start the search.
  205. //
  206. FindHandle = FindFirstFile(Pattern,&FindData);
  207. if(FindHandle != INVALID_HANDLE_VALUE) {
  208. do {
  209. //
  210. // Form the full name of the file or directory we just found.
  211. //
  212. lstrcpyn(Pattern,Directory,MAX_PATH);
  213. pSetupConcatenatePaths(Pattern,FindData.cFileName,MAX_PATH,NULL);
  214. //
  215. // Remove read-only atttribute if it's there.
  216. //
  217. if(FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
  218. SetFileAttributes(Pattern,FILE_ATTRIBUTE_NORMAL);
  219. }
  220. if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  221. //
  222. // The current match is a directory. Recurse into it unless
  223. // it's . or ...
  224. //
  225. if(lstrcmp(FindData.cFileName,TEXT("." )) && lstrcmp(FindData.cFileName,TEXT(".."))) {
  226. Delnode(Pattern);
  227. }
  228. } else {
  229. //
  230. // The current match is not a directory -- so delete it.
  231. //
  232. if(!DeleteFile(Pattern)) {
  233. }
  234. }
  235. } while(FindNextFile(FindHandle,&FindData));
  236. FindClose(FindHandle);
  237. }
  238. //
  239. // Remove the directory we just emptied out. Ignore errors.
  240. //
  241. SetFileAttributes(Directory,FILE_ATTRIBUTE_NORMAL);
  242. RemoveDirectory(Directory);
  243. }
  244. BOOL
  245. CallDuFunction (
  246. IN PCTSTR SyssetupPath
  247. )
  248. {
  249. BOOL b = FALSE;
  250. HMODULE hSyssetup;
  251. BOOL (*pfn) (
  252. VOID
  253. );
  254. hSyssetup = LoadLibrary (SyssetupPath);
  255. if (hSyssetup) {
  256. (FARPROC)pfn = GetProcAddress (hSyssetup, "DynamicUpdateInstallDuAsms");
  257. if (pfn) {
  258. b = pfn ();
  259. }
  260. FreeLibrary (hSyssetup);
  261. }
  262. return b;
  263. }
  264. INT
  265. __cdecl
  266. wmain (
  267. INT argc,
  268. WCHAR *argv[]
  269. )
  270. {
  271. LONG rc;
  272. if (argc < 2) {
  273. return -1;
  274. }
  275. if (!Init()) {
  276. wprintf (L"Unable to initialize!\n");
  277. return 255;
  278. }
  279. CallDuFunction (argv[1]);
  280. Terminate();
  281. return 0;
  282. }