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.

382 lines
8.5 KiB

  1. #include <windows.h>
  2. #include "download.h"
  3. #include "setupbat.h"
  4. //
  5. // these are the critical files that must be copied locally if the
  6. // upgrade of a Win9x system is performed over a network
  7. //
  8. static PCTSTR g_CriticalFiles[] = {
  9. TEXT("WINNT32.EXE"),
  10. TEXT("WINNT32A.DLL"),
  11. TEXT("WINNTBBA.DLL"),
  12. TEXT("PIDGEN.DLL"),
  13. TEXT("WSDU.DLL"),
  14. TEXT("WSDUENG.DLL"),
  15. TEXT("HWDB.DLL"),
  16. TEXT("WIN9XUPG"),
  17. TEXT("drw")
  18. };
  19. //
  20. // these are the critical files for NEC98 plattform that must be copied
  21. // locally if the upgrade of a Win9x system is performed over a network
  22. //
  23. static PCTSTR g_NEC98_CriticalFiles[] = {
  24. TEXT("98PTN16.DLL"),
  25. TEXT("98PTN32.DLL")
  26. };
  27. //
  28. // these are non-critical files that should be copied locally if the
  29. // upgrade of a Win9x system is performed over a network
  30. //
  31. static PCTSTR g_NonCriticalFiles[] = {
  32. TEXT("IDWLOG.EXE"),
  33. // #define RUN_SYSPARSE = 1
  34. #ifdef RUN_SYSPARSE
  35. TEXT("SYSPARSE.EXE"),
  36. #endif
  37. TEXT("WINNT32.HLP"),
  38. TEXT("DOSNET.INF"),
  39. };
  40. BOOL
  41. pIsSpecialDir (
  42. IN PCTSTR Dir
  43. )
  44. /*++
  45. Routine Description:
  46. pIsSpecialDir decides if the given dir is a special directory, like . or ..
  47. Arguments:
  48. Dir - Specifies the directory name only (no path)
  49. Return Value:
  50. TRUE if the specified dir name is a special name
  51. --*/
  52. {
  53. return
  54. *Dir == TEXT('.') &&
  55. (*(Dir + 1) == 0 || *(Dir + 1) == TEXT('.') && *(Dir + 2) == 0)
  56. ;
  57. }
  58. BOOL
  59. CopyNode (
  60. IN PCTSTR SrcBaseDir,
  61. IN PCTSTR DestBaseDir,
  62. IN PCTSTR NodeName,
  63. IN BOOL FailIfExist
  64. )
  65. /*++
  66. Routine Description:
  67. CopyNode copies NodeName (file or subdir) from SrcBaseDir to DestBaseDir.
  68. Arguments:
  69. SrcBaseDir - Specifies the source base directory name
  70. DestBaseDir - Specifies the destination base directory name
  71. NodeName - Specifies the file or subdirectory name to copy
  72. FailIfExist - Specifies if the operation should fail if there is
  73. already a node with the same name at destination
  74. Return Value:
  75. TRUE if the copy operation was actually done
  76. --*/
  77. {
  78. DWORD FileAttr;
  79. TCHAR SrcDir[MAX_PATH];
  80. TCHAR DestDir[MAX_PATH];
  81. HANDLE h;
  82. WIN32_FIND_DATA fd;
  83. WIN32_FIND_DATA fdSrc;
  84. lstrcpy (SrcDir, SrcBaseDir);
  85. lstrcpy (DestDir, DestBaseDir);
  86. //
  87. // check for "\" at the end of dir name
  88. //
  89. ConcatenatePaths (SrcDir, NodeName);
  90. h = FindFirstFile (SrcDir, &fdSrc);
  91. if (h == INVALID_HANDLE_VALUE) {
  92. return FALSE;
  93. }
  94. CloseHandle (h);
  95. if (GetFileAttributes (DestDir) == -1) {
  96. if (!CreateDirectory (DestDir, NULL)) {
  97. return FALSE;
  98. }
  99. }
  100. if (fdSrc.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  101. //
  102. // skip to the end of dir name
  103. //
  104. ConcatenatePaths (DestDir, NodeName);
  105. ConcatenatePaths (SrcDir, TEXT("*"));
  106. h = FindFirstFile (SrcDir, &fd);
  107. *FindLastWack (SrcDir) = 0;
  108. //
  109. // recursively copy all files in that dir
  110. //
  111. if (h != INVALID_HANDLE_VALUE) {
  112. do {
  113. //
  114. // skip over special dirs
  115. //
  116. if (pIsSpecialDir (fd.cFileName)) {
  117. continue;
  118. }
  119. if (!CopyNode (SrcDir, DestDir, fd.cFileName, FailIfExist)) {
  120. return FALSE;
  121. }
  122. } while (FindNextFile (h, &fd));
  123. }
  124. } else {
  125. //
  126. // copy the file
  127. //
  128. ConcatenatePaths (DestDir, NodeName);
  129. if (!CopyFile (SrcDir, DestDir, FailIfExist)) {
  130. return FALSE;
  131. }
  132. //
  133. // set file timestamps to match exactly the ones of the original
  134. // ignore errors in this case
  135. //
  136. SetFileAttributes (DestDir, FILE_ATTRIBUTE_NORMAL);
  137. h = CreateFile (DestDir, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  138. if (h != INVALID_HANDLE_VALUE) {
  139. SetFileTime (h, &fdSrc.ftCreationTime, &fdSrc.ftLastAccessTime, &fdSrc.ftLastWriteTime);
  140. CloseHandle (h);
  141. }
  142. }
  143. return TRUE;
  144. }
  145. BOOL
  146. DeleteNode (
  147. IN PCTSTR NodeName
  148. )
  149. /*++
  150. Routine Description:
  151. DeleteNode deletes NodeName directory and all its subdirectories
  152. Arguments:
  153. NodeName - Specifies the directory name to delete
  154. Return Value:
  155. TRUE if the delete operation was successful; FALSE if only part
  156. of the files/subdirs were deleted
  157. --*/
  158. {
  159. DWORD FileAttr;
  160. TCHAR DestDir[MAX_PATH];
  161. PTSTR p;
  162. HANDLE h;
  163. WIN32_FIND_DATA fd;
  164. BOOL Success = TRUE;
  165. if (!NodeName || !*NodeName) {
  166. return FALSE;
  167. }
  168. FileAttr = GetFileAttributes (NodeName);
  169. if (FileAttr == -1)
  170. return TRUE;
  171. if (!SetFileAttributes (NodeName, FILE_ATTRIBUTE_NORMAL)) {
  172. return FALSE;
  173. }
  174. if (FileAttr & FILE_ATTRIBUTE_DIRECTORY) {
  175. lstrcpy (DestDir, NodeName);
  176. ConcatenatePaths (DestDir, TEXT("*"));
  177. h = FindFirstFile (DestDir, &fd);
  178. p = FindLastWack (DestDir);
  179. //
  180. // recursively copy all files in that dir
  181. //
  182. if (h != INVALID_HANDLE_VALUE) {
  183. do {
  184. //
  185. // skip over special dirs
  186. //
  187. if (pIsSpecialDir (fd.cFileName)) {
  188. continue;
  189. }
  190. lstrcpy (p + 1, fd.cFileName);
  191. if (!DeleteNode (DestDir)) {
  192. Success = FALSE;
  193. }
  194. } while (FindNextFile (h, &fd));
  195. }
  196. //
  197. // now delete the base dir
  198. //
  199. *p = 0;
  200. if (!RemoveDirectory (DestDir)) {
  201. Success = FALSE;
  202. }
  203. } else {
  204. //
  205. // delete the file
  206. //
  207. if (!DeleteFile (NodeName)) {
  208. Success = FALSE;
  209. }
  210. }
  211. return Success;
  212. }
  213. BOOL
  214. DownloadProgramFiles (
  215. IN PCTSTR SourceDir,
  216. IN PCTSTR DownloadDest,
  217. IN PCTSTR* ExtraFiles OPTIONAL
  218. )
  219. /*++
  220. Routine Description:
  221. DownloadProgramFiles copies from SourceDir to DownloadDest
  222. all specific program files (specified in g_CriticalFiles,
  223. g_NEC98_CriticalFiles, and g_NonCriticalFiles arrays).
  224. Arguments:
  225. SourceDir - Specifies the source directory
  226. DownloadDest - Specifies the destination directory
  227. ExtraFiles - Specifies an array of extra files (full paths)
  228. to be copied to the destination directory;
  229. the array must be NULL terminated
  230. Return Value:
  231. TRUE if the download operation was successful and all critical
  232. files were copied locally; FALSE otherwise
  233. --*/
  234. {
  235. TCHAR SourcePath[MAX_PATH];
  236. TCHAR DestPath[MAX_PATH];
  237. INT i;
  238. PTSTR FileName;
  239. TCHAR FullPathName[MAX_PATH];
  240. //
  241. // first delete any old stuff to make place
  242. //
  243. DeleteNode (DownloadDest);
  244. //
  245. // copy there the new stuff
  246. //
  247. lstrcpy (SourcePath, SourceDir);
  248. lstrcpy (DestPath, DownloadDest);
  249. for (i = 0; i < sizeof (g_CriticalFiles) / sizeof (g_CriticalFiles[0]); i++) {
  250. //
  251. // download this one to the destination directory
  252. //
  253. if (!CopyNode (SourcePath, DestPath, g_CriticalFiles[i], FALSE)) {
  254. DeleteNode (DownloadDest);
  255. return FALSE;
  256. }
  257. }
  258. if (ExtraFiles) {
  259. while (*ExtraFiles) {
  260. FileName = FindLastWack ((PTSTR)*ExtraFiles);
  261. if (FileName) {
  262. lstrcpy (FullPathName, DownloadDest);
  263. lstrcat (FullPathName, FileName);
  264. CopyFile (*ExtraFiles, FullPathName, FALSE);
  265. }
  266. ExtraFiles++;
  267. }
  268. }
  269. for (i = 0; i < sizeof (g_CriticalFiles) / sizeof (g_CriticalFiles[0]); i++) {
  270. //
  271. // download this one to the destination directory
  272. //
  273. if (!CopyNode (SourcePath, DestPath, g_CriticalFiles[i], FALSE)) {
  274. DeleteNode (DownloadDest);
  275. return FALSE;
  276. }
  277. }
  278. for (i = 0; i < sizeof (g_NEC98_CriticalFiles) / sizeof (g_NEC98_CriticalFiles[0]); i++) {
  279. //
  280. // download this one to the destination directory
  281. //
  282. // Never check for error. Because winnt32a.dll check plattform and
  283. // sources with NEC98 specific file(98ptn16.dll).
  284. // See winnt32\dll\winnt32.c line 2316.
  285. //
  286. CopyNode (SourcePath, DestPath, g_NEC98_CriticalFiles[i], FALSE);
  287. }
  288. for (i = 0; i < sizeof (g_NonCriticalFiles) / sizeof (g_NonCriticalFiles[0]); i++) {
  289. //
  290. // download this one to the destination directory
  291. //
  292. CopyNode (SourcePath, DestPath, g_NonCriticalFiles[i], FALSE);
  293. }
  294. return TRUE;
  295. }