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.

658 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. dllentry.c
  5. Abstract:
  6. Code that implements the external DLL routines that interface with WINNT32.
  7. Author:
  8. Jim Schmidt (jimschm) 01-Oct-1996
  9. Revision History:
  10. marcw 23-Sep-1998 Added Winnt32VirusScannerCheck
  11. jimschm 30-Dec-1997 Moved initializion to init.lib
  12. jimschm 21-Nov-1997 Updated for NEC98, cleaned up and commented code
  13. --*/
  14. #include "pch.h"
  15. #include "master.h"
  16. #include "master9x.h"
  17. extern BOOL g_Terminated;
  18. BOOL
  19. WINAPI
  20. DllMain (
  21. IN HINSTANCE hInstance,
  22. IN DWORD dwReason,
  23. IN LPVOID lpReserved
  24. )
  25. /*++
  26. Routine Description:
  27. DllMain cannot be counted on for anything. Do not put any code here!!
  28. Arguments:
  29. hInstance - Specifies the instance handle of the DLL (and not the parent EXE or DLL)
  30. dwReason - Specifies DLL_PROCESS_ATTACH or DLL_PROCESS_DETACH. We specifically
  31. disable DLL_THREAD_ATTACH and DLL_THREAD_DETACH.
  32. lpReserved - Unused.
  33. Return Value:
  34. DLL_PROCESS_ATTACH:
  35. TRUE if initialization completed successfully, or FALSE if an error
  36. occurred. The DLL remains loaded only if TRUE is returned.
  37. DLL_PROCESS_DETACH:
  38. Always TRUE.
  39. other:
  40. unexpected, but always returns TRUE.
  41. --*/
  42. {
  43. if (dwReason == DLL_PROCESS_ATTACH) {
  44. g_hInst = hInstance;
  45. }
  46. return TRUE;
  47. }
  48. DWORD
  49. CALLBACK
  50. Winnt32PluginInit (
  51. IN PWINNT32_PLUGIN_INIT_INFORMATION_BLOCK Info
  52. )
  53. /*++
  54. Routine Description:
  55. Winnt32PluginInit is called when WINNT32 first loads w95upg.dll, before
  56. any wizard pages are displayed. The structure supplies pointers to
  57. WINNT32's variables that will be filled with valid values as WINNT32
  58. runs.
  59. Control is passed to the code in init9x.lib.
  60. Arguments:
  61. Info - Specifies the WINNT32 variables the upgrade module needs access
  62. to. Note that this is actually a PWINNT32_WIN9XUPG_INIT_INFORMATION_BLOCK
  63. (which itself holds the normal initialization block..)
  64. Return Value:
  65. A Win32 status code indicating outcome.
  66. --*/
  67. {
  68. LONG Result = ERROR_SUCCESS;
  69. PWINNT32_WIN9XUPG_INIT_INFORMATION_BLOCK win9xInfo = (PWINNT32_WIN9XUPG_INIT_INFORMATION_BLOCK) Info;
  70. __try {
  71. //
  72. // Get dll path information from the Info block. We need to set this first because
  73. // some initialization routines depend on it being set correctly. Because we may have
  74. // been loaded using dll replacement, we can't assume that the rest of our files are
  75. // in the same directory as us.. Winnt32 provides us with the correct information in
  76. // the UpgradeSourcePath variable of the win9xInfo.
  77. //
  78. MYASSERT (win9xInfo->UpgradeSourcePath && *win9xInfo->UpgradeSourcePath);
  79. StringCopy (g_UpgradeSources, win9xInfo->UpgradeSourcePath);
  80. //
  81. // Initialize DLL globals
  82. //
  83. if (!FirstInitRoutine (g_hInst)) {
  84. Result = ERROR_DLL_INIT_FAILED;
  85. __leave;
  86. }
  87. //
  88. // Initialize all libraries
  89. //
  90. if (!InitLibs (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  91. Result = ERROR_DLL_INIT_FAILED;
  92. __leave;
  93. }
  94. //
  95. // Final initialization
  96. //
  97. if (!FinalInitRoutine ()) {
  98. Result = ERROR_DLL_INIT_FAILED;
  99. __leave;
  100. }
  101. Result = Winnt32Init (win9xInfo);
  102. }
  103. __finally {
  104. if (Result != ERROR_SUCCESS && Result != ERROR_REQUEST_ABORTED) {
  105. Winnt32Cleanup();
  106. }
  107. }
  108. return Result;
  109. }
  110. #define S_VSCANDBINF TEXT("vscandb.inf")
  111. BOOL
  112. CALLBACK
  113. Winnt32VirusScannerCheck (
  114. VOID
  115. )
  116. {
  117. HANDLE snapShot;
  118. PROCESSENTRY32 process;
  119. HANDLE processHandle;
  120. WIN32_FIND_DATA findData;
  121. FILE_HELPER_PARAMS fileParams;
  122. HANDLE findHandle;
  123. PTSTR infFile;
  124. PTSTR p;
  125. UINT i;
  126. UINT size;
  127. g_BadVirusScannerFound = FALSE;
  128. infFile = JoinPaths (g_UpgradeSources, S_VSCANDBINF);
  129. //
  130. // Initialize migdb from vscandb.inf.
  131. //
  132. if (!InitMigDbEx (infFile)) {
  133. DEBUGMSG ((DBG_ERROR, "Could not initialize migdb with virus scanner information. infFile: %s", infFile));
  134. FreePathString (infFile);
  135. return TRUE;
  136. }
  137. FreePathString (infFile);
  138. //
  139. // Take snapshot of the system (will contain a list of all
  140. // the 32 bit processes running)
  141. //
  142. snapShot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
  143. if (snapShot != INVALID_HANDLE_VALUE) {
  144. //
  145. // Enumerate all the processes and check the executables they ran from against the vscandb.
  146. //
  147. process.dwSize = sizeof (PROCESSENTRY32);
  148. if (Process32First (snapShot, &process)) {
  149. do {
  150. //
  151. // We need to fill in the file helper params structure and pass it to migdb to test against
  152. // known bad virus scanners.
  153. //
  154. ZeroMemory (&fileParams, sizeof(FILE_HELPER_PARAMS));
  155. fileParams.FullFileSpec = process.szExeFile;
  156. p = _tcsrchr (process.szExeFile, TEXT('\\'));
  157. if (p) {
  158. *p = 0;
  159. StringCopy (fileParams.DirSpec, process.szExeFile);
  160. *p = TEXT('\\');
  161. }
  162. fileParams.Extension = GetFileExtensionFromPath (process.szExeFile);
  163. findHandle = FindFirstFile (process.szExeFile, &findData);
  164. if (findHandle != INVALID_HANDLE_VALUE) {
  165. fileParams.FindData = &findData;
  166. FindClose (findHandle);
  167. }
  168. fileParams.VirtualFile = FALSE;
  169. //
  170. // Now that we have filled in the necessary information, test the file against
  171. // our database of bad virus scanners. If the process *is* a bad virus scanner,
  172. // then the necessary globals will have been filled in by the migdb action
  173. // associated with these types of incompatibilities.
  174. //
  175. MigDbTestFile (&fileParams);
  176. } while (Process32Next (snapShot, &process));
  177. }
  178. ELSE_DEBUGMSG ((DBG_WARNING, "No processes to enumerate found on the system. No virus scanner checking done."));
  179. //
  180. // Now, terminate any files that were added to the badvirusscanner growlist.
  181. //
  182. size = GrowListGetSize (&g_BadVirusScannerGrowList);
  183. if (!g_BadVirusScannerFound && size && Process32First (snapShot, &process)) {
  184. do {
  185. for (i = 0; i < size; i++) {
  186. p = (PTSTR) GrowListGetString (&g_BadVirusScannerGrowList, i);
  187. if (StringIMatch (p, process.szExeFile)) {
  188. processHandle = OpenProcess (PROCESS_TERMINATE, FALSE, process.th32ProcessID);
  189. if (processHandle == INVALID_HANDLE_VALUE || !TerminateProcess (processHandle, 0)) {
  190. g_BadVirusScannerFound = TRUE;
  191. DEBUGMSG ((DBG_ERROR, "Unable to kill process %s.", process.szExeFile));
  192. }
  193. }
  194. }
  195. } while (Process32Next (snapShot, &process));
  196. }
  197. CloseHandle (snapShot);
  198. }
  199. ELSE_DEBUGMSG ((DBG_WARNING, "Could not enumerate processes on the system. No Virus scanner checking done."));
  200. FreeGrowList (&g_BadVirusScannerGrowList);
  201. CleanupMigDb ();
  202. if (g_BadVirusScannerFound) {
  203. DEBUGMSG ((DBG_WARNING, "Virus scanner found. Setup will not continue until the user deletes this process."));
  204. return FALSE;
  205. }
  206. return TRUE;
  207. }
  208. PTSTR
  209. CALLBACK
  210. Winnt32GetOptionalDirectories (
  211. VOID
  212. )
  213. {
  214. if (!CANCELLED()) {
  215. return GetNeededLangDirs ();
  216. }
  217. else {
  218. return NULL;
  219. }
  220. }
  221. DWORD
  222. CALLBACK
  223. Winnt32PluginGetPages (
  224. OUT UINT *FirstCountPtr,
  225. OUT PROPSHEETPAGE **FirstArray,
  226. OUT UINT *SecondCountPtr,
  227. OUT PROPSHEETPAGE **SecondArray,
  228. OUT UINT *ThirdCountPtr,
  229. OUT PROPSHEETPAGE **ThirdArray
  230. )
  231. /*++
  232. Routine Description:
  233. Winnt32PluginGetPages is called right after Winnt32PluginInit. We return
  234. three arrays of wizard pages, and WINNT32 inserts them into its master
  235. wizard page array. Because no wizard pages have been displayed, the user
  236. has not yet chosen the upgrade or fresh install option. Therefore, all
  237. our wizard pages get called in all cases, so we must remember NOT to do
  238. any processong in fresh install.
  239. Arguments:
  240. FirstCountPtr - Receives the number of pages in FirstArray and can be zero.
  241. FirstArray - Receives a pointer to an array of FirstCountPtr property
  242. sheet page structs.
  243. SecondCountPtr - Receives the number of pages in SecondArray and can be zero.
  244. SecondArray - Receives a pointer to an array of SecondCountPtr property
  245. sheet page structs.
  246. ThirdCountPtr - Receives the number of pages in ThirdArray and can be zero.
  247. ThirdArray - Receives a pointer to an array of ThirdCountPtr property
  248. sheet page structs.
  249. See WINNT32 for more information on where these wizard pages are inserted
  250. into the master wizard page list.
  251. Return Value:
  252. A Win32 status code indicating outcome.
  253. --*/
  254. {
  255. return UI_GetWizardPages (FirstCountPtr,
  256. FirstArray,
  257. SecondCountPtr,
  258. SecondArray,
  259. ThirdCountPtr,
  260. ThirdArray);
  261. }
  262. DWORD
  263. CALLBACK
  264. Winnt32WriteParams (
  265. IN PCTSTR WinntSifFile
  266. )
  267. /*++
  268. Routine Description:
  269. Winnt32WriteParams is called just before WINNT32 begins to modify the
  270. boot sector and copy files. Our job here is to take the specified
  271. WINNT.SIF file, read it in, merge in our changes, and write it back
  272. out.
  273. The actual work is done in the init9x.lib code.
  274. Arguments:
  275. WinntSifFile - Specifies path to WINNT.SIF. By this time, the WINNT.SIF
  276. file has some values already set.
  277. Return Value:
  278. A Win32 status code indicating outcome.
  279. --*/
  280. {
  281. if (UPGRADE()) {
  282. return Winnt32WriteParamsWorker (WinntSifFile);
  283. }
  284. return ERROR_SUCCESS;
  285. }
  286. VOID
  287. CALLBACK
  288. Winnt32Cleanup (
  289. VOID
  290. )
  291. /*++
  292. Routine Description:
  293. If the user cancels Setup, Winnt32Cleanup is called while WINNT32 is
  294. displaying the wizard page "Setup is undoing changes it made to your
  295. computer." We must stop all processing and clean up.
  296. If WINNT32 completes all of its work, Winnt32Cleanup is called as
  297. the process exists.
  298. We get called even on fresh install, so we must verify we are upgrading.
  299. Arguments:
  300. none
  301. Return Value:
  302. none
  303. --*/
  304. {
  305. if (g_Terminated) {
  306. return;
  307. }
  308. if (UPGRADE()) {
  309. Winnt32CleanupWorker();
  310. }
  311. //
  312. // Call the cleanup routine that requires library APIs
  313. //
  314. FirstCleanupRoutine();
  315. //
  316. // Clean up all libraries
  317. //
  318. TerminateLibs (g_hInst, DLL_PROCESS_DETACH, NULL);
  319. //
  320. // Do any remaining clean up
  321. //
  322. FinalCleanupRoutine();
  323. }
  324. BOOL
  325. CALLBACK
  326. Winnt32SetAutoBoot (
  327. IN INT DriveLetter
  328. )
  329. /*++
  330. Routine Description:
  331. Winnt32SetAutoBoot is called by WINNT32 on both upgrade and fresh install
  332. to modify the boot partition of a NEC PC-9800 Partition Control Table.
  333. Control is passed to the init9x.lib code.
  334. Arguments:
  335. DriveLetter - Specifies the boot drive letter
  336. Return Value:
  337. TRUE if the partition control table was updated, or FALSE if it wasn't,
  338. or an error occurred.
  339. --*/
  340. {
  341. return Winnt32SetAutoBootWorker (DriveLetter);
  342. }
  343. BOOL
  344. CALLBACK
  345. Win9xGetIncompDrvs (
  346. OUT PSTR** IncompatibleDrivers
  347. )
  348. {
  349. HARDWARE_ENUM e;
  350. GROWBUFFER listDevicePnpids;
  351. GROWBUFFER listUnsupDrv = GROWBUF_INIT;
  352. PCTSTR multisz;
  353. if (!IncompatibleDrivers) {
  354. SetLastError (ERROR_INVALID_PARAMETER);
  355. return FALSE;
  356. }
  357. *IncompatibleDrivers = NULL;
  358. MYASSERT (g_SourceDirectoriesFromWinnt32 && g_SourceDirectoryCountFromWinnt32);
  359. if (!(g_SourceDirectoriesFromWinnt32 && g_SourceDirectoryCountFromWinnt32)) {
  360. DEBUGMSG ((
  361. DBG_ERROR,
  362. "Win9xAnyNetDevicePresent: upgrade module was not initialized"
  363. ));
  364. return TRUE;
  365. }
  366. if (!CreateNtHardwareList (
  367. g_SourceDirectoriesFromWinnt32,
  368. *g_SourceDirectoryCountFromWinnt32,
  369. NULL,
  370. REGULAR_OUTPUT
  371. )) {
  372. DEBUGMSG ((
  373. DBG_ERROR,
  374. "Win9xupgGetIncompatibleDrivers: CreateNtHardwareList failed!"
  375. ));
  376. return FALSE;
  377. }
  378. //
  379. // ISSUE - is this enumerating unsupported drivers as well?
  380. //
  381. if (EnumFirstHardware (&e, ENUM_INCOMPATIBLE_DEVICES, 0)) {
  382. do {
  383. if (!(e.HardwareID && *e.HardwareID) &&
  384. !(e.CompatibleIDs && *e.CompatibleIDs)) {
  385. continue;
  386. }
  387. LOG ((
  388. LOG_INFORMATION,
  389. "Win9xupgGetIncompatibleDrivers: Found Incompatible Device:\r\n"
  390. "Name: %s\r\nMfg: %s\r\nHardwareID: %s\r\nCompatibleIDs: %s\r\nHWRevision: %s",
  391. e.DeviceDesc,
  392. e.Mfg,
  393. e.HardwareID,
  394. e.CompatibleIDs,
  395. e.HWRevision
  396. ));
  397. ZeroMemory (&listDevicePnpids, sizeof (listDevicePnpids));
  398. if (e.HardwareID && *e.HardwareID) {
  399. AddPnpIdsToGrowBuf (&listDevicePnpids, e.HardwareID);
  400. }
  401. if (e.CompatibleIDs && *e.CompatibleIDs) {
  402. AddPnpIdsToGrowBuf (&listDevicePnpids, e.CompatibleIDs);
  403. }
  404. GrowBufAppendDword (&listUnsupDrv, (DWORD)listDevicePnpids.Buf);
  405. } while (EnumNextHardware (&e));
  406. }
  407. //
  408. // terminate the list with a NULL
  409. //
  410. GrowBufAppendDword (&listUnsupDrv, (DWORD)NULL);
  411. if (listUnsupDrv.Buf) {
  412. *IncompatibleDrivers = (PSTR*)listUnsupDrv.Buf;
  413. }
  414. return TRUE;
  415. }
  416. VOID
  417. CALLBACK
  418. Win9xReleaseIncompDrvs (
  419. IN PSTR* IncompatibleDrivers
  420. )
  421. {
  422. GROWBUFFER listDevicePnpids = GROWBUF_INIT;
  423. GROWBUFFER listUnsupDrv = GROWBUF_INIT;
  424. if (IncompatibleDrivers) {
  425. listUnsupDrv.Buf = (PBYTE)IncompatibleDrivers;
  426. while (*IncompatibleDrivers) {
  427. listDevicePnpids.Buf = (PBYTE)(*IncompatibleDrivers);
  428. FreeGrowBuffer (&listDevicePnpids);
  429. IncompatibleDrivers++;
  430. }
  431. FreeGrowBuffer (&listUnsupDrv);
  432. }
  433. }
  434. BOOL
  435. CALLBACK
  436. Win9xAnyNetDevicePresent (
  437. VOID
  438. )
  439. {
  440. HARDWARE_ENUM e;
  441. #if 0
  442. MYASSERT (g_SourceDirectoriesFromWinnt32 && g_SourceDirectoryCountFromWinnt32);
  443. if (!(g_SourceDirectoriesFromWinnt32 && g_SourceDirectoryCountFromWinnt32)) {
  444. DEBUGMSG ((
  445. DBG_ERROR,
  446. "Win9xAnyNetDevicePresent: upgrade module was not initialized"
  447. ));
  448. return TRUE;
  449. }
  450. if (!CreateNtHardwareList (
  451. g_SourceDirectoriesFromWinnt32,
  452. *g_SourceDirectoryCountFromWinnt32,
  453. NULL,
  454. REGULAR_OUTPUT
  455. )) {
  456. DEBUGMSG ((
  457. DBG_ERROR,
  458. "Win9xAnyNetDevicePresent: failed to create the NT hardware list"
  459. ));
  460. //
  461. // assume there is one
  462. //
  463. return TRUE;
  464. }
  465. #endif
  466. if (EnumFirstHardware (&e, ENUM_ALL_DEVICES, ENUM_DONT_REQUIRE_HARDWAREID)) {
  467. do {
  468. //
  469. // Enumerate all PNP devices of class Net
  470. //
  471. if (e.Class) {
  472. if (StringIMatch (e.Class, TEXT("net")) ||
  473. StringIMatch (e.Class, TEXT("modem"))
  474. ) {
  475. AbortHardwareEnum (&e);
  476. return TRUE;
  477. }
  478. }
  479. } while (EnumNextHardware (&e));
  480. }
  481. return FALSE;
  482. }