Leaked source code of windows server 2003
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

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