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.

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