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.

1177 lines
38 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <tchar.h>
  4. // for the SH...
  5. #include <shlwapi.h>
  6. #include <shlobj.h>
  7. #include "network.h"
  8. #include "idw_dbg.h"
  9. #include "service.h"
  10. #include "machines.h"
  11. #include "server.h"
  12. #include "files.h"
  13. #include "idwlog.h"
  14. /*++
  15. Filename : idwlog.cpp
  16. Description: Main for idwlog.cpp
  17. Created by: Wally Ho
  18. History: Created on 31/01/2000.
  19. Made the machineID only 9 chars long 18/08/2000
  20. Contains these functions:
  21. 03.29.2001 Joe Holman Made the code work on Win9x.
  22. 09.19.2001 Joe Holman fixes for idwlog bugs 409338, 399178, and 352810
  23. 09.20.2001 Joe Holman Added code to copy machine's setuperr.log to a server location for analysis.
  24. --*/
  25. // Global data
  26. INSTALL_DATA g_InstallData;
  27. TCHAR g_szServerData[4096];
  28. INT WINAPI
  29. WinMain (HINSTANCE hInstance,
  30. HINSTANCE hPrev,
  31. LPSTR lpCmdLine,
  32. INT nCmdShow)
  33. {
  34. BOOL b;
  35. MACHINE_DETAILS md;
  36. INSTALL_DATA d;
  37. GetBuildInfoFromOSAndBldFile(&d,1);
  38. __try{
  39. // By doing this everything boolean is set to FALSE
  40. ZeroMemory((LPINSTALL_DATA) &g_InstallData,sizeof(INSTALL_DATA));
  41. ZeroMemory((LPMACHINE_DETAILS) &md,sizeof(md));
  42. // Set the error codes so that nothing will show up
  43. // if this fails.
  44. SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
  45. //Setup up a command parser.
  46. // by using else if statements we are assured of only the first one
  47. // being executed and no further code check initiated.
  48. //____<installing service>_____________________________________________________
  49. if (FALSE != _tcsstr(GetCommandLine(), TEXT("-install") )) {
  50. RemoveIdwlogDebugFile(WRITE_SERVICE_DBG);
  51. OpenIdwlogDebugFile(WRITE_SERVICE_DBG);
  52. // if -install specified then we'll register the service.
  53. TCHAR szServiceExe[ MAX_PATH ];
  54. GetModuleFileName(NULL, szServiceExe, MAX_PATH);
  55. /*
  56. LPTSTR p;
  57. p = _tcsrchr(szServiceExe,TEXT('\\'));
  58. if (NULL == p) {
  59. return FALSE;
  60. }
  61. *p = TEXT('\0');
  62. _tcscat( szServiceExe, TEXT("\\s.exe"));
  63. */
  64. InstallService(SCM_SERVICE_NAME , SCM_DISPLAY_NAME, szServiceExe);
  65. CloseIdwlogDebugFile();
  66. }
  67. //____<removing service>_______________________________________________________
  68. else if (FALSE !=_tcsstr(GetCommandLine(), TEXT("-remove") )) {
  69. OpenIdwlogDebugFile(WRITE_SERVICE_DBG);
  70. // if -remove specified then we'll flag it for removal.
  71. RemoveService( SCM_SERVICE_NAME );
  72. CloseIdwlogDebugFile();
  73. }
  74. //____<Idwlog -1 or 2 >_____________________________________________________________
  75. else if (FALSE != _tcsstr(GetCommandLine(), TEXT("-1")) ||
  76. FALSE != _tcsstr(GetCommandLine(), TEXT("-0")) ) {
  77. g_InstallData.bCancel = ( _tcsstr (GetCommandLine(), TEXT("-0")) ? TRUE : FALSE );
  78. // Setting Instance Mutex.
  79. b = SetInstanceMutex();
  80. if (TRUE == b && g_InstallData.bCancel == FALSE) {
  81. //already exists exit.
  82. return FALSE;
  83. }
  84. g_InstallData.bFindBLDFile = TRUE;
  85. if (FALSE == g_InstallData.bCancel) {
  86. RemoveIdwlogDebugFile(WRITE_NORMAL_DBG);
  87. OpenIdwlogDebugFile(WRITE_NORMAL_DBG);
  88. Idwlog(TEXT("STARTED -- [IDWLOG: Stage1 - Initial Install]\n"));
  89. // Initially clean out the link.
  90. // We should delete the shortcut to idwlog from startup group.
  91. RemoveStartupLink(IDWLOG_LINK_SHORTCUT);
  92. // This is to prevent multiple 1 files going through if the user backs up
  93. // and goes again fo whatever reasons.
  94. LPINSTALL_DATA pid = (LPINSTALL_DATA)malloc(sizeof(INSTALL_DATA));
  95. if ( NULL == pid ) {
  96. Idwlog(TEXT("Failed to allocate memory. Exiting.\n"));
  97. return FALSE;
  98. }
  99. b = ReadIdwlogCookie (pid);
  100. pid->iStageSequence = 1;
  101. if (TRUE == b) {
  102. DeleteDatafile (pid);
  103. DeleteCookieFile();
  104. Idwlog(TEXT("Dash 1 repeated. Clean 1 file from server and/ or put 0 file on it.\n"));
  105. Idwlog(TEXT("Dash 1 repeated. Server file: %s \n"), pid->szIdwlogServer);
  106. } else {
  107. Idwlog(TEXT("No old cookie file. Fresh dash 1.\n"));
  108. }
  109. free (pid);
  110. g_InstallData.iStageSequence = 1;
  111. // If this returned false its because the /? case was executed.
  112. if (FALSE == IdwlogClient(&g_InstallData, &md)) {
  113. // Check if we don't fild a BLD file we write a cookie anyway
  114. // Why? So that in part 2 if we don't find a cookie we assume
  115. // a CD BOOT install took place and Part 1 never ran.
  116. if (FALSE == g_InstallData.bFindBLDFile) {
  117. WriteIdwlogCookie( &g_InstallData );
  118. }
  119. // Close the debug file.
  120. CloseIdwlogDebugFile();
  121. ClearInstanceMutex();
  122. return FALSE;
  123. }
  124. //Set a mutex for cancel by same process.
  125. SetCancelMutex ();
  126. // Write out the idwlog cookie file.
  127. // We will specify a nonexistent server so we can get the cookie right away.
  128. // Then if if all goes well we'll write the correct one.
  129. // If not then the service and -3 will do a server probe.
  130. //
  131. _tcscpy(g_InstallData.szIdwlogServer, TEXT("\\\\Bogus\\Bogus"));
  132. WriteIdwlogCookie(&g_InstallData);
  133. // This forces a server probe immediately.
  134. g_InstallData.szIdwlogServer[0] = TEXT('\0');
  135. // Create the idwlog.cookie file.
  136. // At this point, the id struct should be full of necessary data.
  137. // Write the client 1 file.
  138. // At this point, we have a NULL szIdwlogServer. This will make it search.
  139. ServerWriteMaximum (&g_InstallData, &md);
  140. // Write out the idwlog cookie file.
  141. // This must be called after ServerWriteMaximum as it
  142. // loads the server the file eventually gets to.
  143. WriteIdwlogCookie(&g_InstallData);
  144. ClearCancelMutex();
  145. Idwlog(TEXT("ENDED ---- [IDWLOG: Stage1 - Initial Install]\n"));
  146. // Close the debug file.
  147. CloseIdwlogDebugFile();
  148. ClearInstanceMutex();
  149. // Here is where we can consider launching other test processes when someone call's winnt32.exe.
  150. //
  151. // newjoe.
  152. // We will grab the Server data file with the list of programs to launch.
  153. // We will not return until each is performed.
  154. // However, we need to add code to winnt32.exe wizard.c that will:
  155. // - keep the idwlog -1 process id
  156. // - kill this process if it timesout -- see the sysparse code.
  157. // - we need to pass down if upgrade, cdrom, net, msi, etc. appropriately.
  158. //
  159. // Need routine to insert program's paths to call on the logon side of things into the registry.
  160. //
  161. // Requirments of test application: no UI, windows app.
  162. //
  163. /*
  164. in winnt32.exe's wizard.c, just before calling the idwlog -0, if the process of idwlog -1 still exists, timeout on it similar to as we do with the sysparse item.
  165. in winnt32.c, we need to do the same as all the code surrounding the SysParseDlgProc for when we are shutting down the system.
  166. we will need to force any test program down.
  167. */
  168. // end of newjoe.
  169. }
  170. else {
  171. // This is for the cancel case.
  172. // That is where winnt32.exe's wizard is in it's cancel code, so we want to
  173. // cancel out also.
  174. //
  175. // if return == false then write idwlogcookie has already happened
  176. if (FALSE == PauseForMutex()) {
  177. g_InstallData.iStageSequence = 1;
  178. OpenIdwlogDebugFile(WRITE_NORMAL_DBG);
  179. Idwlog(TEXT("STARTED -- [IDWLOG: Stage1 - CANCEL utilized]\n"));
  180. b = ReadIdwlogCookie (&g_InstallData);
  181. if (TRUE == b) {
  182. // Delete for the new behaviour
  183. DeleteDatafile (&g_InstallData);
  184. DeleteCookieFile();
  185. Idwlog(TEXT("Successfully canceled and propagated server delete file. Cookie deleted.\n"));
  186. Idwlog(TEXT("Server file: %s \n"), g_InstallData.szIdwlogServer);
  187. } else {
  188. Idwlog(TEXT("Canceled failed to delete server file. Cookie could not be read.\n"));
  189. }
  190. }
  191. Idwlog(TEXT("ENDED ---- [IDWLOG: Stage1 - CANCEL utilized]\n"));
  192. // Close the debug file.
  193. CloseIdwlogDebugFile();
  194. ClearInstanceMutex();
  195. }
  196. }
  197. //____<Idwlog -3 >_____________________________________________________________
  198. else if (FALSE != _tcsstr(GetCommandLine(), TEXT("-3"))) {
  199. INSTALL_DATA id3;
  200. BOOL bSafeBuild = FALSE;
  201. // HINF hinfLang = NULL;
  202. // LANGID langidValue = 0;
  203. TCHAR szFileName[MAX_PATH];
  204. TCHAR szWindowsDirectory[MAX_PATH];
  205. TCHAR szOEMFileToDelete[MAX_PATH]; // this is our special file to denote an OEM image, we need to delete it
  206. UINT ui;
  207. TCHAR szBuf[MAX_PATH];
  208. ZeroMemory((LPINSTALL_DATA) &id3, sizeof(id3));
  209. // if -3 specified then we know its at stage 3.
  210. //First set the Write to know this is a *.3 file.
  211. g_InstallData.iStageSequence = 3;
  212. OpenIdwlogDebugFile(WRITE_NORMAL_DBG);
  213. Idwlog(TEXT("STARTED -- [IDWLOG: Stage3 - Final Logon]\n"));
  214. IdwlogClient(&g_InstallData,&md);
  215. // We want to track what language'd builds are being installed.
  216. // Although the above IdwlogClient call provides the locale information that was selected,
  217. // we are going to override that information for now. At some time, we likely will want to
  218. // make the structure contain both locale and language SKU, but perhaps not, when we have "one" language shipping.
  219. //
  220. ui = GetWindowsDirectory ( szWindowsDirectory, MAX_PATH );
  221. if ( ui == 0 ) {
  222. Idwlog ( TEXT("build language - ERROR - GetWindowsDirectory gle = %ld\n"), GetLastError());
  223. // leave locale data in.
  224. }
  225. else {
  226. long l = 666;
  227. // Change locale data to system build language.
  228. //
  229. _stprintf(szFileName, TEXT("%s\\inf\\intl.inf"), szWindowsDirectory );
  230. Idwlog ( TEXT("szFileName = %s\n"), szFileName );
  231. GetPrivateProfileString ( TEXT("DefaultValues"),
  232. TEXT("Locale"),
  233. TEXT("ERROR"),
  234. szBuf,
  235. MAX_PATH,
  236. szFileName );
  237. Idwlog ( TEXT("szBuf = %s\n"), szBuf );
  238. l = _tcstol ( szBuf, NULL, 16 );
  239. if ( l == 0 ) {
  240. Idwlog ( TEXT("ERROR - Buffer translated = %x(hex) %d(dec)\n"), l, l );
  241. }
  242. Idwlog ( TEXT("Buffer translated = %x(hex) %d(dec)\n"), l, l );
  243. if ( FALSE == GetLocaleInfo( l, LOCALE_SABBREVLANGNAME, g_InstallData.szLocaleId, sizeof( g_InstallData.szLocaleId ))) {
  244. Idwlog(TEXT("ERROR GetLocaleInfo: gle = %ld\n"), GetLastError() );
  245. }
  246. else {
  247. Idwlog(TEXT("Got the abbreviation: %s\n"), g_InstallData.szLocaleId );
  248. }
  249. Idwlog(TEXT("g_InstallData.szLocaleId = %s\n"), &g_InstallData.szLocaleId );
  250. }
  251. // The below will overwrite fields that are filled in as wrong
  252. // from the above call.
  253. //
  254. g_InstallData.bFindBLDFile = TRUE;
  255. b = ReadIdwlogCookie (&g_InstallData);
  256. if (TRUE == b && TRUE == g_InstallData.bFindBLDFile) {
  257. Idwlog(TEXT("Server from cookie is %s.\n"), g_InstallData.szIdwlogServer);
  258. /*
  259. "If the current build number is less than the build number in the file,
  260. chances are the last setup attempt failed and this current build
  261. is the "safe" build. So do nothing. We get burned if the build lab
  262. doesn't put the right version on the builds. --Dshiflet"
  263. This fact is impossible with my imagehlp.dll version probe.
  264. It's always updated. Wallyho.
  265. */
  266. /*****************************************************************************************************************
  267. if (DTC == FALSE) {
  268. GetCurrentSystemBuildInfo(&id3);
  269. // This case if safebuild it running
  270. if (id3.dwSystemBuild < g_InstallData.dwSystemBuild)
  271. bSafeBuild = TRUE;
  272. else
  273. bSafeBuild = FALSE;
  274. // This case is same build but different deltas
  275. if (id3.dwSystemBuild == g_InstallData.dwSystemBuild &&
  276. id3.dwSystemBuildDelta < g_InstallData.dwSystemBuildDelta)
  277. bSafeBuild = TRUE;
  278. else
  279. bSafeBuild = FALSE;
  280. if (TRUE == bSafeBuild) {
  281. Idwlog(TEXT("The Current build or delta on the machine is less than the installed build.\n"));
  282. Idwlog(TEXT("Most likely the last attempt failed. So we are in a safe build.\n"));
  283. // What do do in this case? Wally ho
  284. // I think we'll write nothing as this is a fail.
  285. // Commented out for now as testing will fail this.
  286. //Remove the CookieFile.
  287. DeleteCookieFile();
  288. Idwlog(TEXT("ENDED ---- [IDWLOG -3]\n"));
  289. CloseIdwlogDebugFile();
  290. return FALSE;
  291. }
  292. }
  293. *****************************************************************************************************************/
  294. // If this returns fail we leave the link
  295. // and the file intact upon next boot.
  296. if (FALSE == ServerWriteMaximum (&g_InstallData, &md)) {
  297. // Copy the machine's Setup error log file to our Server to analyze.
  298. //
  299. CopySetupErrorLog (&g_InstallData);
  300. Idwlog(TEXT("ENDED ---- [IDWLOG: Stage3 - Final Logon]\n"));
  301. CloseIdwlogDebugFile();
  302. return FALSE;
  303. }
  304. } else {
  305. //If we are here we have read the cookie and
  306. // found that NO_BUILD_DATA was in the cookie.
  307. // Which means part one didn't find a bld file.
  308. // and the cookie is empty.
  309. // What we do now is make an assumption. This being
  310. // That the system build is the current build that
  311. // we either couldn't get to begin with or that
  312. // a CD BOOT happened. Both cases we distinguish.
  313. // We get the current system information and then
  314. // send it as the installing build.
  315. // of course we blank out the data for everything else.
  316. GetCurrentSystemBuildInfo(&id3);
  317. g_InstallData.dwSystemBuild = 0;
  318. g_InstallData.dwSystemBuildDelta = 0;
  319. g_InstallData.dwSystemSPBuild = 0;
  320. _tcscpy(g_InstallData.szInstallingBuildSourceLocation, TEXT("No_Build_Lab_Information"));
  321. g_InstallData.dwInstallingBuild = id3.dwSystemBuild ;
  322. g_InstallData.dwInstallingBuildDelta = id3.dwSystemBuildDelta;
  323. g_InstallData.dwInstallingSPBuild = id3.dwSystemBuildDelta;
  324. _tcscpy(g_InstallData.szInstallingBuildSourceLocation, id3.szSystemBuildSourceLocation);
  325. g_InstallData.bFindBLDFile = g_InstallData.bFindBLDFile;
  326. if (FALSE == g_InstallData.bFindBLDFile) {
  327. g_InstallData.bCDBootInstall = FALSE;
  328. // If there was no build file found.
  329. Idwlog(TEXT("There was no build file in stage 1; logging as such.\n"));
  330. //Remove the CookieFile.
  331. DeleteCookieFile();
  332. // Copy the machine's Setup error log file to our Server to analyze.
  333. //
  334. CopySetupErrorLog (&g_InstallData);
  335. Idwlog(TEXT("ENDED ---- [IDWLOG: Stage3 - Final Logon]\n"));
  336. CloseIdwlogDebugFile();
  337. return FALSE;
  338. } else {
  339. // We will probe the machine as it is now to get a build number
  340. // then we will send a minimal server file over to the server.
  341. // This will have a build number machine id name of computer
  342. // on the file name. But will have a delta inside.
  343. g_InstallData.bCDBootInstall = TRUE;
  344. Idwlog(TEXT("This is a CD Boot Install logging as such.\n"));
  345. // This forces a server probe immediately.
  346. g_InstallData.szIdwlogServer[0] = TEXT('\0');
  347. if (FALSE == ServerWriteMinimum (&g_InstallData, &md)) {
  348. // Copy the machine's Setup error log file to our Server to analyze.
  349. //
  350. CopySetupErrorLog (&g_InstallData);
  351. Idwlog(TEXT("ENDED ---- [IDWLOG: Stage3 - Final Logon]\n"));
  352. CloseIdwlogDebugFile();
  353. return FALSE;
  354. }
  355. }
  356. // Idwlog(TEXT("Failed to read cookie. Writing minimal success file to server.\n"));
  357. // Idwlog(TEXT("This will correct CD installs that don't generate a *.1.\n"));
  358. }
  359. //Clean up.
  360. // We should delete the shortcut to idwlog from startup group.
  361. RemoveStartupLink(IDWLOG_LINK_SHORTCUT);
  362. // If this is idwlog.exe, delete the program.
  363. // We only need to write once.
  364. /*
  365. GetModuleFileName (NULL, szExePath, MAX_PATH);
  366. if (_tcsstr(CharLower(szExePath), TEXT("idwlog.exe")))
  367. MoveFileEx (szExePath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
  368. */
  369. //Remove the CookieFile.
  370. DeleteCookieFile();
  371. // Copy the machine's Setup error log file to our Server to analyze.
  372. //
  373. CopySetupErrorLog (&g_InstallData);
  374. Idwlog(TEXT("ENDED ---- [IDWLOG: Stage3 - Final Logon]\n"));
  375. CloseIdwlogDebugFile();
  376. }
  377. else {
  378. //____<running service>_____________________________________________________
  379. // default is to start as a service.
  380. SERVICE_TABLE_ENTRY st[] ={
  381. { SCM_DISPLAY_NAME , (LPSERVICE_MAIN_FUNCTION)ServiceMain},
  382. { NULL, NULL}
  383. };
  384. Idwlog(TEXT("Start the StartServiceCtrlDispatcher %lu.\n"),GetLastError());
  385. b = StartServiceCtrlDispatcher(st);
  386. }
  387. }__except (EXCEPTION_EXECUTE_HANDLER) {
  388. // This is here as for some reason this faults in NT 4.0.
  389. Idwlog(TEXT("Unhandled Exception Fault. Exiting.. EC %lu!\n"), GetLastError());
  390. CloseIdwlogDebugFile();
  391. }
  392. return FALSE;
  393. }
  394. DWORD GetSkuFromSystem ( VOID ) {
  395. OSVERSIONINFOEX osv;
  396. BOOL b;
  397. /*
  398. case 0: // Professional
  399. case 1: // Server
  400. case 2: // Advanced Server
  401. case 3: // DataCenter
  402. case 4: // Home Edition
  403. case 5: // Blade Server
  404. case 6: // Small Business Server
  405. */
  406. // We call this routine only in the -3 phase so we are logging on on XP+ builds. Thus,
  407. // we can call the EX version of this routine.
  408. //
  409. osv.dwOSVersionInfoSize = sizeof ( OSVERSIONINFOEX );
  410. b = GetVersionEx ( (OSVERSIONINFO * ) &osv );
  411. if ( !b ) {
  412. Idwlog(TEXT("ERROR GetSkuFromSystem - GetVersionEx rc = %ld\n"), GetLastError());
  413. return 666;
  414. }
  415. // OK. We have these products we need to look for:
  416. //
  417. // Home Edition (NT 5.1 and greater).
  418. // DataCenter
  419. // Enterprise
  420. // Server
  421. // Professional
  422. //
  423. //
  424. //
  425. // We'll start from the top here, because some are based upon Suite masks, not product type, as some are.
  426. //
  427. if ( osv.wSuiteMask & VER_SUITE_SMALLBUSINESS ) {
  428. Idwlog(TEXT("GetSkuFromSystem - System is SBS\n"));
  429. return 6;
  430. }
  431. if ( osv.wSuiteMask & VER_SUITE_BLADE ) {
  432. Idwlog(TEXT("GetSkuFromSystem - System is BLADE\n"));
  433. return 5;
  434. }
  435. if ( osv.wSuiteMask & VER_SUITE_PERSONAL ) {
  436. Idwlog(TEXT("GetSkuFromSystem - System is HOME EDITION\n"));
  437. return 4;
  438. }
  439. if ( osv.wSuiteMask & VER_SUITE_DATACENTER ) {
  440. Idwlog(TEXT("GetSkuFromSystem - System is DATACENTER\n"));
  441. return 3;
  442. }
  443. if ( osv.wSuiteMask & VER_SUITE_ENTERPRISE ) {
  444. Idwlog(TEXT("GetSkuFromSystem - System is ENTERPRISE\n"));
  445. return 2;
  446. }
  447. // Note: don't have to use VER_NT_SERVER, because this value is
  448. // a combination of bit 1 and bit 0 (workstation). We are
  449. // just interested in the the "server" part.
  450. //
  451. if ( osv.wProductType & VER_NT_DOMAIN_CONTROLLER ) {
  452. Idwlog(TEXT("GetSkuFromSystem - System is SERVER\n"));
  453. return 1;
  454. }
  455. if ( osv.wProductType & VER_NT_WORKSTATION ) {
  456. Idwlog(TEXT("GetSkuFromSystem - System is PROFESSIONAL\n"));
  457. return 0;
  458. }
  459. Idwlog(TEXT("ERROR GetSkuFromSystem - We didn't find the system type (%x,%x)\n"), osv.wSuiteMask, osv.wProductType);
  460. return 666;
  461. }
  462. BOOL
  463. IdwlogClient( LPINSTALL_DATA pId,
  464. LPMACHINE_DETAILS pMd)
  465. /*++
  466. Author: Wallyho.
  467. Routine Description:
  468. This load system information into the structures for the
  469. Install Data and the Machine Details.
  470. Arguments:
  471. Two pointer to two created structures.
  472. Return Value:
  473. TRUE for success.
  474. FALSE for failure.
  475. --*/
  476. {
  477. OSVERSIONINFO osVer;
  478. DWORD dwComputerNameLen;
  479. SYSTEM_INFO SysInfo ;
  480. MEMORYSTATUS msRAM;
  481. TCHAR szHelpMessage[MAX_PATH];
  482. Idwlog(TEXT("IdwLogClient - entered.\n") );
  483. // if -1 specified then we'll use Part 1.
  484. // Spray up a simple help screen for /?
  485. if ( FALSE != _tcsstr(GetCommandLine(), TEXT("/?")) ||
  486. FALSE != _tcsstr(GetCommandLine(), TEXT("-?")) ) {
  487. Idwlog(TEXT("STARTED -- [IDWLOG: Stage1 - HELP called]\n"));
  488. _stprintf(szHelpMessage,
  489. TEXT("idwlog -1 upgrade cancel cdrom MSI sp_remove sp_patch sp_update sp_full oemimage\0") );
  490. _stprintf (szHelpMessage+_tcsclen(szHelpMessage),
  491. TEXT("idwlog -3 \0") );
  492. MessageBox(NULL,szHelpMessage,
  493. TEXT("Help Parameters"),MB_ICONQUESTION | MB_OK);
  494. Idwlog(TEXT("ENDED ---- [IDWLOG: Stage1 - HELP called]\n"));
  495. return FALSE;
  496. }
  497. // Load the command line booleans for the below items.
  498. // We need these here because the image loading for build #s is depenedent upon it for SPs.
  499. //
  500. pId->bSPUninst= ( _tcsstr (GetCommandLine(), TEXT("sp_remove")) ? TRUE : FALSE );
  501. pId->bSPPatch = ( _tcsstr (GetCommandLine(), TEXT("sp_patch")) ? TRUE : FALSE );
  502. pId->bSPUpdate= ( _tcsstr (GetCommandLine(), TEXT("sp_update")) ? TRUE : FALSE );
  503. pId->bSPFull = ( _tcsstr (GetCommandLine(), TEXT("sp_full")) ? TRUE : FALSE );
  504. pId->bOEMImage= ( _tcsstr (GetCommandLine(), TEXT("oemimage")) ? TRUE : FALSE );
  505. Idwlog(TEXT("IdwLogClient - pId->bSPFull = %ld\n"), pId->bSPFull );
  506. osVer.dwOSVersionInfoSize= sizeof( osVer );
  507. GetVersionEx( &osVer );
  508. switch (osVer.dwPlatformId) {
  509. case VER_PLATFORM_WIN32_NT:
  510. //refine it to earlier versions
  511. switch (osVer.dwMajorVersion) {
  512. case 3:
  513. _tcscpy(pId->szPlatform,TEXT("Windows NT 3.51"));
  514. Idwlog(TEXT("This is for winver %s.\n"),pId->szPlatform);
  515. pId->dwSystemBuild = osVer.dwBuildNumber;
  516. pId->dwSystemBuildDelta = 0;
  517. pId->dwSystemSPBuild = 0;
  518. pId->dwSystemMajorVersion = osVer.dwMajorVersion;
  519. pId->dwSystemMinorVersion = osVer.dwMinorVersion;
  520. _stprintf(pId->szSystemBuildSourceLocation, TEXT("%s"),
  521. TEXT("No_Build_Lab_Information"));
  522. // fix the number of displays for non Windows 2000 systems
  523. pMd->iNumDisplays = 1;
  524. Idwlog(TEXT("Getting Displays Info.\n"));
  525. break;
  526. case 4:
  527. _tcscpy(pId->szPlatform,TEXT("Windows NT 4.0"));
  528. Idwlog(TEXT("This is for winver %s.\n"),pId->szPlatform);
  529. pId->dwSystemBuild = osVer.dwBuildNumber;
  530. pId->dwSystemBuildDelta = 0;
  531. pId->dwSystemSPBuild = 0;
  532. pId->dwSystemMajorVersion = osVer.dwMajorVersion;
  533. pId->dwSystemMinorVersion = osVer.dwMinorVersion;
  534. _stprintf(pId->szSystemBuildSourceLocation, TEXT("%s"),
  535. TEXT("No_Build_Lab_Information"));
  536. // fix the number of displays for non Windows 2000 systems
  537. pMd->iNumDisplays = 1;
  538. Idwlog(TEXT("Getting Displays Info.\n"));
  539. break;
  540. case 5:
  541. //This is the current build of the machine its
  542. // running on. So this will be the previous
  543. // build as we see it and not the current installing build.
  544. _tcscpy(pId->szPlatform, TEXT("Windows 2000, XP, or .NET Server"));
  545. Idwlog(TEXT("This is for winver %s.\n"),pId->szPlatform);
  546. pMd->iNumDisplays = GetSystemMetrics(SM_CMONITORS);
  547. Idwlog(TEXT("Getting Displays Info.\n"));
  548. if (FALSE == GetCurrentSystemBuildInfo(pId)) {
  549. if (pId->iStageSequence == 1) {
  550. Idwlog(TEXT("Failed getting build, build delta, VBL location.\n"));
  551. return FALSE;
  552. }
  553. } else
  554. Idwlog(TEXT("Succeded in getting build, build delta, VBL location. Build %lu Delta %lu.\n"),
  555. pId->dwSystemBuild,
  556. pId->dwSystemBuildDelta);
  557. break;
  558. default:
  559. // if the size is > 5 (Mostlikely won't be less that 3)
  560. //_itoa (osVer.dwBuildNumber, szCurBld, sizeof(szCurBld));
  561. _tcscpy(pId->szPlatform, TEXT("Windows 64? Future?"));
  562. Idwlog(TEXT("This is for winver %s.\n"),pId->szPlatform);
  563. if (FALSE == GetCurrentSystemBuildInfo(pId)) {
  564. if (pId->iStageSequence == 1) {
  565. Idwlog(TEXT("Failed getting build, build delta, VBL location.\n"));
  566. return FALSE;
  567. }
  568. } else
  569. Idwlog(TEXT("Succeded in getting build, build delta, VBL location. Build %lu Delta %lu.\n"),
  570. pId->dwSystemBuild,
  571. pId->dwSystemBuildDelta);
  572. pId->dwSystemBuild = osVer.dwBuildNumber;
  573. }
  574. GetEnvironmentVariable ( TEXT("NUMBER_OF_PROCESSORS"), pId->szCpu, 6);
  575. GetEnvironmentVariable ( TEXT("PROCESSOR_ARCHITECTURE"), pId->szArch, 20);
  576. break;
  577. case VER_PLATFORM_WIN32_WINDOWS:
  578. _tcscpy(pId->szPlatform,TEXT("Windows 9x"));
  579. _tcscpy(pId->szArch, TEXT("X86"));
  580. pId->dwSystemBuild = osVer.dwBuildNumber;
  581. pId->dwSystemBuildDelta = 0;
  582. pId->dwSystemSPBuild = 0;
  583. pId->dwSystemMajorVersion = osVer.dwMajorVersion;
  584. pId->dwSystemMinorVersion = osVer.dwMinorVersion;
  585. // fix the number of displays for non Windows 2000 systems
  586. pMd->iNumDisplays = GetSystemMetrics(SM_CMONITORS);
  587. if (pMd->iNumDisplays == 0)
  588. pMd->iNumDisplays = 1;
  589. Idwlog(TEXT("Getting Displays Info.\n"));
  590. _stprintf(pId->szSystemBuildSourceLocation, TEXT("%s"),
  591. TEXT("No_Build_Lab_Information"));
  592. break;
  593. default:
  594. _tcscpy(pId->szPlatform,TEXT("Unknown Platform"));
  595. _tcscpy(pId->szArch, TEXT("Unknown Arch"));
  596. pId->dwSystemBuild = 0;
  597. pId->dwSystemBuildDelta = 0;
  598. pId->dwSystemSPBuild = 0;
  599. pId->dwSystemMajorVersion = 0;
  600. pId->dwSystemMinorVersion = 0;
  601. _stprintf(pId->szSystemBuildSourceLocation, TEXT("%s"),
  602. TEXT("No_Build_Lab_Information"));
  603. pMd->iNumDisplays = 1;
  604. break;
  605. }
  606. Idwlog(TEXT("Identified OS version as %s\n"),pId->szPlatform);
  607. // Get the Sku from the dosnet.inf
  608. // This will show what build we are trying to go to.
  609. if (pId->iStageSequence == 1) {
  610. if (FALSE == GetSkuFromDosNetInf(pId)) {
  611. Idwlog(TEXT("IdwLogClient ERROR - Failed getting sku from dosnet.inf.\n"));
  612. return FALSE;
  613. } else
  614. Idwlog(TEXT("Succeded in getting sku from dosnet.inf.\n"));
  615. }
  616. else if ( pId->iStageSequence == 3 ) {
  617. pId->dwSku = GetSkuFromSystem ();
  618. }
  619. //Get the Current build thats is being installed if its windows 2000
  620. if (FALSE == GetCurrentInstallingBuildInfo(pId)) {
  621. if (pId->iStageSequence == 1) {
  622. Idwlog(TEXT("Failed getting build, build delta, VBL location.\n"));
  623. pId->bFindBLDFile = FALSE;
  624. return FALSE;
  625. }
  626. } else
  627. Idwlog(TEXT("Succeded in getting build, build delta, VBL location. Build %lu Delta %lu.\n"),
  628. pId->dwInstallingBuild,
  629. pId->dwInstallingBuildDelta);
  630. Idwlog(TEXT("Loading the booleans with install data.\n"));
  631. pId->bCancel = ( _tcsstr (GetCommandLine(), TEXT("cancel")) ? TRUE : FALSE );
  632. pId->bCdrom = ( _tcsstr (GetCommandLine(), TEXT("cdrom")) ? TRUE : FALSE );
  633. pId->bNetwork = !pId->bCdrom;
  634. pId->bUpgrade = ( _tcsstr (GetCommandLine(), TEXT("upgrade")) ? TRUE : FALSE );
  635. pId->bClean = !pId->bUpgrade;
  636. pId->bMsi = ( _tcsstr (GetCommandLine(), TEXT("MSI")) ? TRUE : FALSE );
  637. //Get the computerName
  638. //
  639. dwComputerNameLen = sizeof(pId->szComputerName);
  640. if ( FALSE == GetComputerName (pId->szComputerName, &dwComputerNameLen)) {
  641. Idwlog(TEXT("Could not get the computer name. Default NoComputerName.\n"));
  642. _tcscpy(pId->szComputerName,TEXT("NoComputerName"));
  643. } else {
  644. // TCHAR szDest[MAX_PATH];
  645. Idwlog(TEXT("IdwLogClient - Computer name is: %s\n"), pId->szComputerName );
  646. /*** this is bogus, we are ansi right now...
  647. // Because idwlog's backend processing can't handle Unicode compternames (log file names),
  648. // we will convert to ansi.
  649. //
  650. if ( 0 == WideCharToMultiByte( CP_ACP, 0, pId->szComputerName, -1, szDest, MAX_PATH, NULL, NULL ) ) {
  651. // Error converting, just keep unicode name.
  652. //
  653. Idwlog(TEXT("IdwLogClient - WideCharToMultiByte FAILed rc = %ld, pId->szComputerName is: %s\n"),
  654. GetLastError(), pId->szComputerName );
  655. } else {
  656. // No error converting, copy the ansi name back into the location.
  657. //
  658. _tcscpy (pId->szComputerName, szDest );
  659. Idwlog(TEXT("IdwLogClient - Computer name is (after Unicode to Ansi conversion): %s\n"), pId->szComputerName );
  660. }
  661. ***/
  662. }
  663. //Generate the MachineId
  664. pId->dwMachineID = RandomMachineID();
  665. Idwlog(TEXT("Generating the Machine Id: %lu.\n"), pId->dwMachineID);
  666. //Get the UserName
  667. if (FALSE ==
  668. GetEnvironmentVariable (TEXT("Username"), pId->szUserName, 30)) {
  669. Idwlog(TEXT("Failed to get the UserName! Setting default Unknown."));
  670. _tcscpy (pId->szUserName, TEXT("Unknown"));
  671. } else
  672. Idwlog(TEXT("Getting User Name: %s.\n"), pId->szUserName);
  673. //Get the UserDomain
  674. if (FALSE ==
  675. GetEnvironmentVariable (TEXT("Userdomain"), pId->szUserDomain, 30)) {
  676. Idwlog(TEXT("Failed to get the Userdomain! Setting default Unknown."));
  677. _tcscpy (pId->szUserDomain, TEXT("Unknown"));
  678. } else
  679. Idwlog(TEXT("Getting User domain: %s.\n"), pId->szUserDomain);
  680. // Get the Processor Architecture
  681. //
  682. if (FALSE == GetEnvironmentVariable (TEXT("PROCESSOR_ARCHITECTURE"), pId->szArch, 20)) {
  683. // Assumes we set szArch above in Win9x case. But, we don't want to overwrite it now since Win9x
  684. // does not have this environment variable set.
  685. //
  686. if ( osVer.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS ) {
  687. Idwlog(TEXT("Failed to get the Proc_Architecture! Setting default Unknown."));
  688. _tcscpy (pId->szArch, TEXT("Unknown"));
  689. }
  690. else {
  691. Idwlog(TEXT("szArch Env Win9x case. Will not give error since it should be filled in above code."));
  692. }
  693. } else
  694. Idwlog(TEXT("Getting processor Architecture: %s.\n"), pId->szArch);
  695. // Get locale abbreviation so we know about language pack usage
  696. if ( FALSE == GetLocaleInfo( LOCALE_SYSTEM_DEFAULT, LOCALE_SABBREVLANGNAME, pId->szLocaleId, sizeof( pId->szLocaleId ))) {
  697. Idwlog(TEXT("Could not get the locale abbreviation. Settingto default of unknown."));
  698. _tcscpy(pId->szLocaleId, TEXT("UKNW"));
  699. } else
  700. Idwlog(TEXT("Getting locale: %s.\n"), pId->szLocaleId);
  701. //Get the system Information.
  702. GetSystemInfo( &SysInfo );
  703. pMd->dwNumberOfProcessors = SysInfo.dwNumberOfProcessors;
  704. pMd->dwProcessorType = SysInfo.dwProcessorType;
  705. pMd->dwProcessorLevel = (DWORD)SysInfo.wProcessorLevel;
  706. pMd->dwProcessorRevision = (DWORD)SysInfo.wProcessorRevision;
  707. Idwlog(TEXT("Getting System Info.\n"));
  708. //Get the Memory Config on the system
  709. msRAM.dwLength = sizeof (msRAM);
  710. GlobalMemoryStatus (&msRAM);
  711. pMd->dwPhysicalRamInMB = (DWORD) msRAM.dwTotalPhys/ (1024 *1024);
  712. Idwlog(TEXT("Getting Ram size.\n"));
  713. //Get the Video Chip type, Memory and DAC type.
  714. /*
  715. Because we have a problem on Terminal Server sp6 on one machine
  716. Bogdana's suggestion was to not do this for NT4.
  717. */
  718. if (4 != pId->dwSystemMajorVersion) {
  719. GetVidInfo (pMd);
  720. Idwlog(TEXT("Getting Video Info.\n"));
  721. } else {
  722. // Set some defaults in case we encounter this problem.
  723. _tcscpy(pMd->szVideoDisplayName,TEXT("Unknown"));
  724. pMd->szVideoInfo[0] = TEXT('\0');
  725. Idwlog(TEXT("Because of a problem on Terminal Server sp6 we will not get the Video Info.\n"));
  726. }
  727. //Get the Sound information
  728. GetNTSoundInfo(pMd);
  729. Idwlog(TEXT("Geting Sound Info.\n"));
  730. //Get Network/SCSI/ Modem PNP stuff.
  731. GetPNPDevices(pMd);
  732. Idwlog(TEXT("Getting Network scsi modem pnp Info.\n"));
  733. //Get the Terminal server information.
  734. pId->bHydra = IsHydra ();
  735. Idwlog(TEXT("Getting Hydra Info.\n"));
  736. return TRUE;
  737. }
  738. //
  739. // For SHGetFolderPath LoadLibrary/GetProcAddress
  740. //
  741. typedef HRESULT (*SHGETFOLDERPATH) (HWND, int, HANDLE, DWORD, LPTSTR);
  742. BOOL
  743. RemoveStartupLink( LPTSTR szLinkToRemove )
  744. /*++
  745. Author: Wallyho.
  746. Routine Description:
  747. Arguments:
  748. Return Value:
  749. --*/
  750. {
  751. TCHAR szProfileDir[ MAX_PATH ];
  752. TCHAR sz[ MAX_PATH ];
  753. BOOL bDeleted = FALSE;
  754. SHGETFOLDERPATH pSHGetFolderPath = NULL;
  755. HMODULE hModule = NULL;
  756. BOOL b1 = TRUE, b2 = TRUE;
  757. // If the current build is 2195 or greater
  758. // Then this is NT50 and we kill the link.
  759. // Otherwise we don't care.
  760. if (GetCurrentMachinesBuildNumber() >= 2195) {
  761. //
  762. // Make sure the strings are not hard-coded in English...
  763. //
  764. hModule = LoadLibrary(TEXT("SHFolder.dll"));
  765. if (hModule) {
  766. #ifdef UNICODE
  767. pSHGetFolderPath = (SHGETFOLDERPATH)GetProcAddress(hModule, TEXT("SHGetFolderPathW"));
  768. #else
  769. pSHGetFolderPath = (SHGETFOLDERPATH)GetProcAddress(hModule, TEXT("SHGetFolderPathA"));
  770. #endif
  771. }
  772. if (pSHGetFolderPath) {
  773. Idwlog(TEXT("Will use SHGetFolderPath.\n"));
  774. // This will get from startup All Users.
  775. (*pSHGetFolderPath) (NULL, CSIDL_COMMON_STARTUP, NULL, 0, szProfileDir);
  776. // SHGetSpecialFolderPath (NULL, szExePath, CSIDL_COMMON_STARTUP, FALSE );
  777. PathAppend (szProfileDir, szLinkToRemove);
  778. if (FALSE == DeleteFile (szProfileDir) ) {
  779. b1 = FALSE;
  780. }
  781. Idwlog(TEXT("%s in removing %s.\n"), (b1 ? TEXT("Succedeed"): TEXT("Failed")), szProfileDir);
  782. // This will get it for the current user.
  783. // SHGetSpecialFolderPath (NULL, szExePath, CSIDL_STARTUP, FALSE );
  784. (*pSHGetFolderPath) (NULL, CSIDL_STARTUP , NULL, 0, szProfileDir);
  785. PathAppend (szProfileDir, szLinkToRemove);
  786. if (FALSE == DeleteFile (szProfileDir) ) {
  787. b2 = FALSE;
  788. }
  789. Idwlog(TEXT("%s in removing %s.\n"), (b2 ? TEXT("Succedeed"): TEXT("Failed")), szProfileDir);
  790. if ( b1 == FALSE || b2 == FALSE)
  791. return FALSE;
  792. else
  793. return TRUE;
  794. } else {
  795. //
  796. // Default to the old and broken behavior (this should never happen,
  797. // but just in case...)
  798. //
  799. //
  800. Idwlog(TEXT("Will use hardcoded strings.\n"));
  801. // Kill it from the Allusers directory.
  802. // The link can be in only 2 places.
  803. // Upon upgrade its in windir\profiles\All Users\Start Menu\Programs\Startup
  804. // Upon Clean install it is
  805. // sysdrive:\Documents and Settings\All Users\Start Menu\Programs\Startup
  806. GetWindowsDirectory(szProfileDir, MAX_PATH);
  807. _stprintf( sz,
  808. TEXT("\\profiles\\All Users\\Start Menu\\Programs\\Startup\\%s"),
  809. szLinkToRemove);
  810. _tcscat( szProfileDir, sz);
  811. bDeleted = DeleteFile (szProfileDir);
  812. if (FALSE == bDeleted) {
  813. // Kill the all user one if its there.
  814. GetEnvironmentVariable(TEXT("allusersprofile"),szProfileDir, MAX_PATH);
  815. _stprintf( sz,
  816. TEXT("\\Start Menu\\Programs\\Startup\\%s"),
  817. szLinkToRemove);
  818. _tcscat( szProfileDir, sz);
  819. bDeleted = DeleteFile (szProfileDir);
  820. }
  821. if (FALSE == bDeleted) {
  822. // Kill the user one too if its there.
  823. GetEnvironmentVariable(TEXT("userprofile"),szProfileDir, MAX_PATH);
  824. _stprintf( sz,
  825. TEXT("\\Start Menu\\Programs\\Startup\\%s"),
  826. szLinkToRemove);
  827. _tcscat( szProfileDir, sz);
  828. bDeleted = DeleteFile (szProfileDir);
  829. }
  830. if (FALSE == bDeleted ) {
  831. if (2 == GetLastError()) {
  832. Idwlog(TEXT("The link is not found.\n"));
  833. } else {
  834. Idwlog(TEXT("Problems removing the startup link. Error %lu.\n"), GetLastError());
  835. }
  836. return FALSE;
  837. } else {
  838. Idwlog(TEXT("Startup link removed sucessfully.\n"));
  839. return TRUE;
  840. }
  841. }
  842. /* Doesn't work for all NT4.0
  843. */
  844. } else {
  845. Idwlog(TEXT("W2k Startup link removal. Nothing done.\n"));
  846. return TRUE;
  847. }
  848. }
  849. VOID
  850. GlobalInit(VOID)
  851. /*++
  852. Author: Wallyho.
  853. Routine Description:
  854. Initializes global Values.
  855. Arguments:
  856. NONE
  857. Return Value:
  858. NONE
  859. --*/
  860. {
  861. //
  862. // Do some global initializations.
  863. //
  864. }