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.

1650 lines
48 KiB

  1. /************************************************************************
  2. Copyright (c) Microsoft Corporation 1997-1998
  3. All rights reserved
  4. ***************************************************************************/
  5. #include "pch.h"
  6. #include "setup.h"
  7. #include "check.h"
  8. DEFINE_MODULE("Check");
  9. #define SMALL_BUFFER_SIZE 256
  10. #define FILTER_SIZE 128
  11. #define BIG_BUFFER 4096
  12. //
  13. // Ldap_InitializeConnection( )
  14. //
  15. DWORD
  16. Ldap_InitializeConnection(
  17. PLDAP * LdapHandle )
  18. {
  19. TraceFunc( "Ldap_InitializeConnection( ... )\n" );
  20. PLDAPMessage OperationalAttributeLdapMessage;
  21. PLDAPMessage CurrentEntry;
  22. DWORD LdapError = LDAP_SUCCESS;
  23. if ( !( *LdapHandle ) ) {
  24. ULONG temp = DS_DIRECTORY_SERVICE_REQUIRED |
  25. DS_IP_REQUIRED;
  26. *LdapHandle = ldap_init( NULL, LDAP_PORT);
  27. if ( !*LdapHandle )
  28. {
  29. LdapError = GetLastError( );
  30. goto e0;
  31. }
  32. ldap_set_option( *LdapHandle, LDAP_OPT_GETDSNAME_FLAGS, &temp );
  33. temp = LDAP_VERSION3;
  34. ldap_set_option( *LdapHandle, LDAP_OPT_VERSION, &temp );
  35. //
  36. // our searches should be contained to a single naming context, though
  37. // we should be able to go outside the root of the tree to find the
  38. // naming context we're interested in.
  39. //
  40. temp = LDAP_CHASE_EXTERNAL_REFERRALS;
  41. ldap_set_option( *LdapHandle, LDAP_OPT_REFERRALS, &temp );
  42. LdapError = ldap_connect( *LdapHandle, 0 );
  43. if ( LdapError != LDAP_SUCCESS )
  44. goto e1;
  45. LdapError = ldap_bind_s( *LdapHandle, NULL, NULL, LDAP_AUTH_SSPI );
  46. if ( LdapError != LDAP_SUCCESS )
  47. goto e1;
  48. }
  49. e0:
  50. if ( LdapError != LDAP_SUCCESS ) {
  51. DebugMsg( "!!Error initializing LDAP connection.\n" );
  52. }
  53. RETURN( LdapError );
  54. e1:
  55. ldap_unbind( *LdapHandle );
  56. *LdapHandle = NULL;
  57. goto e0;
  58. }
  59. //
  60. // CheckDSForSCP( )
  61. //
  62. HRESULT
  63. CheckDSForSCP( )
  64. {
  65. TraceFunc( "CheckDSForSCP( )\n" );
  66. HRESULT hr = S_FALSE;
  67. PLDAP LdapHandle = NULL;
  68. DWORD LdapError = LDAP_SUCCESS;
  69. DWORD count;
  70. LPWSTR * ppszPath;
  71. PLDAPMessage CurrentEntry;
  72. PLDAPMessage LdapMessage;
  73. ULONG ulSize;
  74. LPWSTR pMachineDN = NULL;
  75. // Paramters we want from the Computer Object
  76. LPWSTR ComputerAttrs[2];
  77. ComputerAttrs[0] = TEXT("netbootSCPBL");
  78. ComputerAttrs[1] = NULL;
  79. //
  80. // We already detected it
  81. //
  82. if ( g_Options.fBINLSCPFound ) {
  83. Assert( LdapError == LDAP_SUCCESS );
  84. hr = S_OK;
  85. goto e0;
  86. }
  87. if ( !GetComputerObjectName( NameFullyQualifiedDN, NULL, &ulSize ) ) {
  88. DWORD Error = GetLastError( );
  89. MessageBoxFromStrings( NULL, IDS_DOMAINMEMBERSHIP_TITLE, IDS_DOMAINMEMBERSHIP_TEXT, MB_OK );
  90. hr = THR(E_FAIL);
  91. goto e0;
  92. }
  93. pMachineDN = (LPWSTR) TraceAlloc( LPTR, ulSize * sizeof(WCHAR) );
  94. if ( !pMachineDN ) {
  95. hr = THR(E_OUTOFMEMORY);
  96. goto e0;
  97. }
  98. if ( !GetComputerObjectName( NameFullyQualifiedDN, pMachineDN, &ulSize ) ) {
  99. DWORD Error = GetLastError( );
  100. MessageBoxFromStrings( NULL, IDS_DOMAINMEMBERSHIP_TITLE, IDS_DOMAINMEMBERSHIP_TEXT, MB_OK );
  101. hr = THR(E_FAIL);
  102. goto e0;
  103. }
  104. DebugMsg( "Our MAO's DN is %s.\n", pMachineDN );
  105. LdapError = Ldap_InitializeConnection( &LdapHandle );
  106. if ( LdapError != ERROR_SUCCESS ) {
  107. hr = THR( HRESULT_FROM_WIN32( LdapMapErrorToWin32( LdapError ) ) );
  108. MessageBoxFromError( NULL, NULL, LdapMapErrorToWin32(LdapError) );
  109. LdapError = LDAP_SUCCESS;
  110. goto e0;
  111. }
  112. LdapError = ldap_search_ext_s( LdapHandle,
  113. pMachineDN,
  114. LDAP_SCOPE_BASE,
  115. L"(objectClass=computer)",
  116. ComputerAttrs,
  117. FALSE,
  118. NULL,
  119. NULL,
  120. NULL,
  121. 0,
  122. &LdapMessage);
  123. if (LdapError == LDAP_NO_SUCH_ATTRIBUTE ) {
  124. DebugMsg( "SCP not found.\n" );
  125. LdapError = ERROR_SUCCESS;
  126. hr = S_FALSE;
  127. goto e1;
  128. }
  129. count = ldap_count_entries( LdapHandle, LdapMessage );
  130. if (count!= 1) {
  131. //
  132. // What should we do with two entries for the same server?
  133. //
  134. if ( count ) {
  135. Assert(FALSE);
  136. }
  137. DebugMsg( "SCP not found.\n" );
  138. goto e2;
  139. }
  140. CurrentEntry = ldap_first_entry( LdapHandle, LdapMessage );
  141. ppszPath = ldap_get_values( LdapHandle, CurrentEntry, TEXT("netbootSCPBL") );
  142. if ( !ppszPath ) {
  143. DebugMsg( "SCP not found.\n" );
  144. LdapError = LDAP_OTHER;
  145. goto e2;
  146. }
  147. DebugMsg( "SCP found.\n" );
  148. g_Options.fBINLSCPFound = TRUE;
  149. hr = S_OK;
  150. ldap_value_free(ppszPath);
  151. e2:
  152. ldap_msgfree( LdapMessage );
  153. e1:
  154. ldap_unbind( LdapHandle );
  155. e0:
  156. if ( LdapError != LDAP_SUCCESS ) {
  157. hr = S_FALSE;
  158. }
  159. if ( pMachineDN ) {
  160. TraceFree( pMachineDN );
  161. }
  162. HRETURN(hr);
  163. }
  164. //
  165. // CheckDirectoryTree( )
  166. //
  167. HRESULT
  168. CheckDirectoryTree( )
  169. {
  170. HRESULT hr = S_FALSE;
  171. LPSHARE_INFO_502 psi;
  172. WCHAR szPath[ MAX_PATH ];
  173. WCHAR szCreating[ SMALL_BUFFER_SIZE ];
  174. DWORD dwLen;
  175. DWORD dw;
  176. BOOL f;
  177. TraceFunc( "CheckDirectoryTree()\n" );
  178. Assert( g_Options.hinf != INVALID_HANDLE_VALUE );
  179. //
  180. // Try to find the IMIRROR share
  181. //
  182. if ( !g_Options.fIMirrorShareFound ) {
  183. dw = LoadString( g_hinstance, IDS_REMOTEBOOTSHARENAME, szPath, ARRAYSIZE( szPath ));
  184. Assert( dw );
  185. if ( NERR_Success == NetShareGetInfo( NULL, szPath, 502, (LPBYTE *)&psi ) ) {
  186. if ( !g_Options.fIMirrorDirectory ) {
  187. lstrcpy( g_Options.szIntelliMirrorPath, psi->shi502_path );
  188. Assert( wcslen(g_Options.szIntelliMirrorPath) < ARRAYSIZE(g_Options.szInstallationPath) );
  189. g_Options.fIMirrorDirectory = TRUE;
  190. }
  191. g_Options.fIMirrorShareFound = TRUE;
  192. DebugMsg( "Found the IMIRROR share, using it for the IntelliMirror Directory: %s\n", g_Options.szIntelliMirrorPath );
  193. NetApiBufferFree( psi );
  194. }
  195. }
  196. //
  197. // Try to use the TFTPD's reg key to find the IntelliMirror tree.
  198. //
  199. if ( !g_Options.fIMirrorDirectory
  200. && !g_Options.fTFTPDDirectoryFound ) {
  201. //
  202. // Try finding TFTPD's regkey to find the IntelliMirror Directory
  203. //
  204. HKEY hkey;
  205. dw = LoadString( g_hinstance, IDS_TFTPD_SERVICE_PARAMETERS, szPath, ARRAYSIZE( szPath ));
  206. Assert( dw );
  207. if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  208. szPath,
  209. 0, // options
  210. KEY_QUERY_VALUE,
  211. &hkey ) ) {
  212. ULONG l;
  213. DWORD dwType;
  214. LONG lErr;
  215. l = sizeof(g_Options.szTFTPDDirectory);
  216. lErr = RegQueryValueEx( hkey,
  217. L"Directory",
  218. 0, // reserved
  219. &dwType,
  220. (LPBYTE) g_Options.szTFTPDDirectory,
  221. &l );
  222. Assert( wcslen(g_Options.szTFTPDDirectory) < ARRAYSIZE(g_Options.szTFTPDDirectory) );
  223. if ( lErr == ERROR_SUCCESS ) {
  224. DebugMsg( "Found TFTPD's Directory regkey: %s\n", g_Options.szTFTPDDirectory );
  225. g_Options.fTFTPDDirectoryFound = TRUE;
  226. }
  227. RegCloseKey( hkey );
  228. }
  229. }
  230. if ( !g_Options.fIMirrorDirectory
  231. && g_Options.fTFTPDDirectoryFound ) {
  232. StrCpy( g_Options.szIntelliMirrorPath, g_Options.szTFTPDDirectory );
  233. Assert( wcslen(g_Options.szIntelliMirrorPath) < ARRAYSIZE(g_Options.szInstallationPath) );
  234. g_Options.fIMirrorDirectory = TRUE;
  235. DebugMsg( "Used the TFTPD RegKey to find the IntelliMirror Directory.\n" );
  236. }
  237. //
  238. // Did we find the IntelliMirror directory?
  239. //
  240. if ( !g_Options.fIMirrorDirectory ) {
  241. //
  242. // Nope... so figure out which drive we can put it on.
  243. // Find a non-system, fixed disk, drive to place the
  244. // IntelliMirror directory tree
  245. //
  246. WCHAR chSystemDriveLetter;
  247. WCHAR chLargestDriveLetter = 0;
  248. ULARGE_INTEGER uliBiggestFree = { 0 };
  249. WCHAR szRootDrive[ 4 ] = TEXT("C:\\");
  250. DebugMsg( "Could not find the IntelliMirror directory.\n" );
  251. dw = LoadString( g_hinstance, IDS_DEFAULTPATH, szPath, ARRAYSIZE( szPath ) );
  252. Assert( dw );
  253. dw = ExpandEnvironmentStrings( szPath, g_Options.szIntelliMirrorPath, ARRAYSIZE(g_Options.szInstallationPath));
  254. Assert( dw );
  255. // The default string actually contains the system drive letter
  256. chSystemDriveLetter = g_Options.szIntelliMirrorPath[0];
  257. DebugMsg( "Searching for suitable drive:" );
  258. for( ; szRootDrive[0] <= TEXT('Z'); szRootDrive[0]++ )
  259. {
  260. ULARGE_INTEGER uliFree;
  261. ULARGE_INTEGER uliTotal;
  262. ULARGE_INTEGER uliBytesFree;
  263. UINT uDriveType;
  264. DebugMsg( "%s ", szRootDrive );
  265. uDriveType = GetDriveType( szRootDrive );
  266. if ( DRIVE_FIXED != uDriveType
  267. || szRootDrive[0] == chSystemDriveLetter )
  268. continue; // skip non-fixed and non-system drives
  269. if ( !GetDiskFreeSpaceEx( szRootDrive, &uliFree, &uliTotal, &uliBytesFree ) )
  270. continue; // error - skip it.
  271. if ( uliBytesFree.QuadPart > uliBiggestFree.QuadPart )
  272. {
  273. chLargestDriveLetter = szRootDrive[0];
  274. uliBiggestFree = uliBytesFree;
  275. }
  276. }
  277. DebugMsg( "\n" );
  278. if ( !chLargestDriveLetter )
  279. {
  280. g_Options.szIntelliMirrorPath[0] = chSystemDriveLetter;
  281. DebugMsg( "BAD! Using system drive as default.\n" );
  282. }
  283. else
  284. {
  285. g_Options.szIntelliMirrorPath[0] = chLargestDriveLetter;
  286. DebugMsg( "Suggesting %s for the IntelliMirror Drive/Directory.\n", g_Options.szIntelliMirrorPath );
  287. }
  288. goto e0; // skip the tree
  289. }
  290. //
  291. // Check the directory tree.
  292. // If any of these fail, just recreate the whole tree.
  293. //
  294. DebugMsg( "Checking Directory Tree:\n" );
  295. //
  296. // Create
  297. // "D:\IntelliMirror"
  298. //
  299. DebugMsg( "%s\n", g_Options.szIntelliMirrorPath );
  300. if ( 0xFFFFffff == GetFileAttributes( g_Options.szIntelliMirrorPath ) )
  301. goto e0;
  302. //
  303. // Create
  304. // "D:\IntelliMirror\Setup"
  305. //
  306. wcscpy( szPath, g_Options.szIntelliMirrorPath );
  307. ConcatenatePaths( szPath, L"\\Setup" );
  308. Assert( wcslen(szPath) < ARRAYSIZE(szPath));
  309. DebugMsg( "%s\n", szPath );
  310. if ( 0xFFFFffff == GetFileAttributes( szPath ) )
  311. goto e0;
  312. //
  313. // Create the OS Chooser tree
  314. // "D:\IntelliMirror\OSChooser"
  315. //
  316. wcscpy( g_Options.szOSChooserPath, g_Options.szIntelliMirrorPath );
  317. ConcatenatePaths( g_Options.szOSChooserPath, L"\\OSChooser" );
  318. Assert( wcslen(g_Options.szOSChooserPath) < ARRAYSIZE(g_Options.szOSChooserPath) );
  319. DebugMsg( "%s\n", g_Options.szOSChooserPath );
  320. if ( 0xFFFFffff == GetFileAttributes( g_Options.szOSChooserPath ) )
  321. goto e0;
  322. g_Options.fOSChooserDirectory = TRUE;
  323. if ( !g_Options.fOSChooserDirectoryTreeExists ) {
  324. WCHAR szFile[ MAX_PATH ];
  325. BOOL fFound;
  326. INFCONTEXT context;
  327. fFound = SetupFindFirstLine( g_Options.hinf, L"OSChooser", NULL, &context );
  328. AssertMsg( fFound, "Could not find 'OSChooser' section in REMINST.INF.\n" );
  329. while ( fFound
  330. && SetupGetStringField( &context, 1, szFile, ARRAYSIZE(szFile), NULL ) )
  331. {
  332. LPWSTR psz = StrChr( szFile, L'\\' );
  333. if ( psz ) {
  334. *psz = L'\0'; // terminate
  335. wsprintf( szPath,
  336. L"%s\\%s",
  337. g_Options.szOSChooserPath,
  338. szFile );
  339. Assert( wcslen(szPath) < ARRAYSIZE(szPath) );
  340. DebugMsg( "%s\n", szPath );
  341. if ( 0xFFFFffff == GetFileAttributes( szPath ) )
  342. goto e0;
  343. }
  344. fFound = SetupFindNextLine( &context, &context );
  345. }
  346. g_Options.fOSChooserDirectoryTreeExists = TRUE;
  347. }
  348. g_Options.fDirectoryTreeExists = TRUE;
  349. e0:
  350. if ( g_Options.fIMirrorDirectory
  351. && g_Options.fIMirrorShareFound
  352. && g_Options.fDirectoryTreeExists
  353. && g_Options.fOSChooserDirectory
  354. && g_Options.fOSChooserDirectoryTreeExists ) {
  355. DebugMsg( "All directories found.\n" );
  356. hr = S_OK;
  357. } else {
  358. DebugMsg( "Directory tree check failed.\n" );
  359. }
  360. HRETURN(hr);
  361. }
  362. BOOL
  363. CheckService(
  364. SC_HANDLE schSystem,
  365. LPWSTR ServiceName,
  366. LPBOOL Started
  367. )
  368. {
  369. SC_HANDLE sch;
  370. SERVICE_STATUS status;
  371. BOOL b;
  372. sch = OpenService( schSystem,
  373. ServiceName,
  374. SERVICE_ALL_ACCESS );
  375. if ( sch == NULL ) {
  376. DebugMsg( "%ws is NOT installed.\n", ServiceName );
  377. return FALSE;
  378. }
  379. DebugMsg( "%ws is installed.\n", ServiceName );
  380. b = QueryServiceStatus( sch, &status);
  381. *Started = (BOOL)(b && (status.dwCurrentState == SERVICE_RUNNING));
  382. DebugMsg( "%ws is %wsrunning.\n", ServiceName, *Started ? L"" : L"not " );
  383. CloseServiceHandle( sch );
  384. return TRUE;
  385. } // CheckService
  386. //
  387. // CheckBINL( )
  388. //
  389. HRESULT
  390. CheckBINL(
  391. SC_HANDLE schSystem )
  392. {
  393. HRESULT hr = S_FALSE;
  394. WCHAR szPath[ MAX_PATH ];
  395. WCHAR szFiles[ MAX_PATH ];
  396. LPWSTR psz;
  397. DWORD dw;
  398. BOOL started = TRUE;
  399. TraceFunc( "CheckBINL( )\n" );
  400. //
  401. // Check to see if the service manager can find the service
  402. //
  403. if ( !g_Options.fBINLServiceInstalled ) {
  404. if ( CheckService( schSystem, L"BINLSVC", &started ) ) {
  405. g_Options.fBINLServiceInstalled = TRUE;
  406. }
  407. }
  408. //
  409. // Read the REMINST.INF for the files need for the service
  410. //
  411. if ( !g_Options.fBINLFilesFound ) {
  412. WCHAR szSystem32Path[ MAX_PATH ];
  413. WCHAR szFile[ MAX_PATH ];
  414. UINT index;
  415. BOOL b;
  416. INFCONTEXT context;
  417. dw = ExpandEnvironmentStrings( TEXT("%windir%"), szSystem32Path, ARRAYSIZE( szSystem32Path ));
  418. Assert( dw );
  419. StrCat( szSystem32Path, TEXT("\\system32") );
  420. b = SetupFindFirstLine( g_Options.hinf, L"Service.BINLSVC", L"FilesRequired", &context );
  421. Assert( b );
  422. if ( !b )
  423. goto BINLCheckSCP;
  424. index = 1;
  425. while ( SetupGetStringField( &context, index, szFile, ARRAYSIZE( szFile ), NULL ) )
  426. {
  427. WCHAR szPath[ 2 * MAX_PATH ];
  428. wsprintf( szPath,
  429. L"%s\\%s",
  430. szSystem32Path,
  431. szFile );
  432. if ( 0xFFFFffff == GetFileAttributes( szPath ) ) {
  433. DebugMsg( "%s is missing for Service BINLSVC.\n", szPath );
  434. goto BINLCheckSCP;
  435. }
  436. DebugMsg( "%s found.\n", szPath );
  437. index++;
  438. }
  439. g_Options.fBINLFilesFound = TRUE;
  440. }
  441. //
  442. // Check to see if the SCP exists
  443. //
  444. BINLCheckSCP:
  445. hr = CheckDSForSCP( );
  446. if ( hr == S_OK
  447. && g_Options.fBINLFilesFound
  448. && g_Options.fBINLServiceInstalled
  449. && started ) {
  450. DebugMsg( "All BINL services checked out OK.\n");
  451. hr = S_OK;
  452. } else if ( hr == S_OK ) {
  453. DebugMsg( "BINL check found something strange with the SCP. Ignoring.\n" );
  454. hr = S_FALSE;
  455. } else {
  456. DebugMsg( "BINL check failed.\n" );
  457. }
  458. HRETURN(hr);
  459. }
  460. //
  461. // CheckTFTPD( )
  462. //
  463. HRESULT
  464. CheckTFTPD(
  465. SC_HANDLE schSystem )
  466. {
  467. HRESULT hr = S_FALSE;
  468. WCHAR szPath[ MAX_PATH ];
  469. WCHAR szFiles[ MAX_PATH ];
  470. LPWSTR psz;
  471. DWORD dw;
  472. HKEY hkey;
  473. BOOL started = TRUE;
  474. TraceFunc( "CheckTFTPD( )\n" );
  475. //
  476. // Check to see if the service manager can find the service
  477. //
  478. if ( !g_Options.fTFTPDServiceInstalled ) {
  479. if ( CheckService( schSystem, L"TFTPD", &started ) ) {
  480. g_Options.fTFTPDServiceInstalled = TRUE;
  481. }
  482. }
  483. //
  484. // Read the REMINST.INF for the files need for the service
  485. //
  486. if ( !g_Options.fTFTPDFilesFound ) {
  487. WCHAR szSystem32Path[ MAX_PATH ];
  488. WCHAR szFile[ MAX_PATH ];
  489. UINT index;
  490. BOOL b;
  491. INFCONTEXT context;
  492. dw = ExpandEnvironmentStrings( TEXT("%windir%"), szSystem32Path, ARRAYSIZE( szSystem32Path ) );
  493. Assert( dw );
  494. StrCat( szSystem32Path, TEXT("\\system32") );
  495. b = SetupFindFirstLine( g_Options.hinf, L"Service.TFTPD", L"FilesRequired", &context );
  496. Assert( b );
  497. if ( !b )
  498. goto TFTPDCheckReg;
  499. index = 1;
  500. while ( SetupGetStringField( &context, index, szFile, ARRAYSIZE( szFile ), NULL ) )
  501. {
  502. WCHAR szPath[ 2 * MAX_PATH ];
  503. wsprintf( szPath,
  504. L"%s\\%s",
  505. szSystem32Path,
  506. szFile );
  507. if ( 0xFFFFffff == GetFileAttributes( szPath ) ) {
  508. DebugMsg( "%s is missing for Service TFTPD.\n", szPath );
  509. goto TFTPDCheckReg;
  510. }
  511. DebugMsg( "%s found.\n", szPath );
  512. index++;
  513. }
  514. g_Options.fTFTPDFilesFound = TRUE;
  515. }
  516. TFTPDCheckReg:
  517. //
  518. // Check to see if the Directory reg key exists
  519. //
  520. if ( !g_Options.fTFTPDDirectoryFound ) {
  521. dw = LoadString( g_hinstance, IDS_TFTPD_SERVICE_PARAMETERS, szPath, ARRAYSIZE( szPath ));
  522. Assert( dw );
  523. if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  524. szPath,
  525. 0, // options
  526. KEY_QUERY_VALUE,
  527. &hkey ) ) {
  528. ULONG l;
  529. DWORD dwType;
  530. LONG lErr;
  531. l = sizeof(g_Options.szTFTPDDirectory);
  532. lErr = RegQueryValueEx( hkey,
  533. L"Directory",
  534. 0, // reserved
  535. &dwType,
  536. (LPBYTE) g_Options.szTFTPDDirectory,
  537. &l );
  538. if ( lErr == ERROR_SUCCESS ) {
  539. DebugMsg( "TFTPD's Directory RegKey found: %s\n", g_Options.szTFTPDDirectory );
  540. Assert( wcslen(g_Options.szTFTPDDirectory) < ARRAYSIZE(g_Options.szTFTPDDirectory) );
  541. if ( 0xFFFFffff == GetFileAttributes( g_Options.szTFTPDDirectory ) ) {
  542. DebugMsg( "BUT, %s was not found.\n", g_Options.szTFTPDDirectory );
  543. }
  544. g_Options.fTFTPDDirectoryFound = TRUE;
  545. }
  546. RegCloseKey( hkey );
  547. } else {
  548. DebugMsg( "HKLM\\%s not found.\n", szPath );
  549. }
  550. }
  551. if ( g_Options.fTFTPDDirectoryFound
  552. && g_Options.fTFTPDFilesFound
  553. && g_Options.fTFTPDServiceInstalled
  554. && started ) {
  555. DebugMsg( "All TFTPD services checked out OK.\n" );
  556. hr = S_OK;
  557. } else {
  558. DebugMsg( "TFTPD check failed.\n" );
  559. }
  560. HRETURN(hr);
  561. }
  562. //
  563. // CheckSIS( )
  564. //
  565. HRESULT
  566. CheckSIS(
  567. SC_HANDLE schSystem )
  568. {
  569. HRESULT hr = S_FALSE;
  570. WCHAR szPath[ MAX_PATH ];
  571. WCHAR szFiles[ MAX_PATH ];
  572. WCHAR szVolumePath[ MAX_PATH ];
  573. LPWSTR psz;
  574. DWORD dw;
  575. BOOL started = TRUE;
  576. TraceFunc( "CheckSIS( )\n" );
  577. //
  578. // Check to see if the service manager can find the service
  579. //
  580. if ( !g_Options.fSISServiceInstalled ) {
  581. if ( CheckService( schSystem, L"SIS", &started ) ) {
  582. g_Options.fSISServiceInstalled = TRUE;
  583. }
  584. }
  585. //
  586. // Read the REMINST.INF for the files need for the service
  587. //
  588. if ( !g_Options.fSISFilesFound ) {
  589. WCHAR szSystem32Path[ MAX_PATH ];
  590. WCHAR szFile[ MAX_PATH ];
  591. UINT index;
  592. BOOL b;
  593. INFCONTEXT context;
  594. dw = ExpandEnvironmentStrings( TEXT("%windir%"), szSystem32Path, ARRAYSIZE( szSystem32Path ));
  595. Assert( dw );
  596. StrCat( szSystem32Path, TEXT("\\system32") );
  597. b = SetupFindFirstLine( g_Options.hinf, L"Service.SIS", L"FilesRequired", &context );
  598. Assert( b );
  599. if ( !b )
  600. goto SISCheckVolume;
  601. index = 1;
  602. while ( SetupGetStringField( &context, index, szFile, ARRAYSIZE( szFile ), NULL ) )
  603. {
  604. WCHAR szPath[ 2 * MAX_PATH ];
  605. wsprintf( szPath,
  606. L"%s\\%s",
  607. szSystem32Path,
  608. szFile );
  609. if ( 0xFFFFffff == GetFileAttributes( szPath ) ) {
  610. DebugMsg( "%s is missing for Service SIS.\n", szPath );
  611. goto SISCheckVolume;
  612. }
  613. DebugMsg( "%s found.\n", szPath );
  614. index++;
  615. }
  616. g_Options.fSISFilesFound = TRUE;
  617. }
  618. SISCheckVolume:
  619. if ( !g_Options.fSISVolumeCreated ) {
  620. //
  621. // If we know the IMirrorDirectory (and hence the volume), check
  622. // to see if the Common Store Directory has been created.
  623. //
  624. if ( g_Options.fIMirrorDirectory ) {
  625. GetVolumePathName( g_Options.szIntelliMirrorPath, szVolumePath, ARRAYSIZE( szVolumePath ));
  626. wsprintf( szPath, L"%s\\SIS Common Store", szVolumePath );
  627. Assert( wcslen(szPath) < ARRAYSIZE(szPath) );
  628. if ( 0xFFFFffff == GetFileAttributes( szPath ) ) {
  629. DebugMsg( "%s is missing.\n", szPath );
  630. goto e0;
  631. }
  632. DebugMsg( "%s found.\n", szPath );
  633. g_Options.fSISVolumeCreated = TRUE;
  634. }
  635. }
  636. if ( g_Options.fSISVolumeCreated
  637. && g_Options.fSISFilesFound
  638. && g_Options.fSISServiceInstalled
  639. && started ) {
  640. DebugMsg( "All SIS services checked out OK.\n" );
  641. hr = S_OK;
  642. } else {
  643. DebugMsg( "SIS check failed.\n" );
  644. }
  645. e0:
  646. HRETURN(hr);
  647. }
  648. //
  649. // CheckSISGroveler( )
  650. //
  651. HRESULT
  652. CheckSISGroveler(
  653. SC_HANDLE schSystem )
  654. {
  655. HRESULT hr = S_FALSE;
  656. WCHAR szPath[ MAX_PATH ];
  657. WCHAR szFiles[ MAX_PATH ];
  658. LPWSTR psz;
  659. DWORD dw;
  660. BOOL started = TRUE;
  661. TraceFunc( "CheckSISGroveler( )\n" );
  662. //
  663. // Check to see if the service manager can find the service
  664. //
  665. if ( !g_Options.fSISGrovelerServiceInstalled ) {
  666. if ( CheckService( schSystem, L"Groveler", &started ) ) {
  667. g_Options.fSISGrovelerServiceInstalled = TRUE;
  668. }
  669. }
  670. //
  671. // Read the REMINST.INF for the files need for the service
  672. //
  673. if ( !g_Options.fSISGrovelerFilesFound ) {
  674. WCHAR szSystem32Path[ MAX_PATH ];
  675. WCHAR szFile[ MAX_PATH ];
  676. UINT index;
  677. BOOL b;
  678. INFCONTEXT context;
  679. dw = ExpandEnvironmentStrings( TEXT("%windir%"), szSystem32Path, ARRAYSIZE( szSystem32Path ));
  680. Assert( dw );
  681. StrCat( szSystem32Path, TEXT("\\system32") );
  682. b = SetupFindFirstLine( g_Options.hinf, L"Service.SISGroveler", L"FilesRequired", &context );
  683. Assert( b );
  684. if ( !b )
  685. goto e0;
  686. index = 1;
  687. while ( SetupGetStringField( &context, index, szFile, ARRAYSIZE( szFile ), NULL ) )
  688. {
  689. WCHAR szPath[ 2 * MAX_PATH ];
  690. wsprintf( szPath,
  691. L"%s\\%s",
  692. szSystem32Path,
  693. szFile );
  694. if ( 0xFFFFffff == GetFileAttributes( szPath ) ) {
  695. DebugMsg( "%s is missing for Service SIS Groveler.\n", szPath );
  696. goto e0;
  697. }
  698. DebugMsg( "%s found.\n", szPath );
  699. index++;
  700. }
  701. g_Options.fSISGrovelerFilesFound = TRUE;
  702. }
  703. if ( g_Options.fSISGrovelerFilesFound
  704. && g_Options.fSISGrovelerServiceInstalled
  705. && started ) {
  706. DebugMsg( "All SIS Groveler services checked out OK.\n" );
  707. hr = S_OK;
  708. } else {
  709. DebugMsg( "SIS Groveler check failed.\n" );
  710. }
  711. e0:
  712. HRETURN(hr);
  713. }
  714. //
  715. // CheckRegSrvDlls( )
  716. //
  717. HRESULT
  718. CheckRegSrvDlls( )
  719. {
  720. HRESULT hr = S_FALSE;
  721. WCHAR szSection[ SMALL_BUFFER_SIZE ];
  722. WCHAR szRegSrv[ SMALL_BUFFER_SIZE ];
  723. WCHAR szFile[ MAX_PATH ];
  724. WCHAR szSystem32Path[ MAX_PATH ];
  725. DWORD dw;
  726. INT index;
  727. BOOL fMissingDll = FALSE;
  728. BOOL fRegistrationFailed = FALSE;
  729. BOOL b;
  730. INFCONTEXT context;
  731. TraceFunc( "CheckRegSrvDlls( )\n" );
  732. if ( !g_Options.fRegSrvDllsFilesFound ||
  733. ! g_Options.fRegSrvDllsRegistered ) {
  734. dw = ExpandEnvironmentStrings( TEXT("%windir%"), szSystem32Path, ARRAYSIZE( szSystem32Path ));
  735. Assert( dw );
  736. StrCat( szSystem32Path, TEXT("\\system32") );
  737. dw = LoadString( g_hinstance, IDS_INF_SECTION, szSection, ARRAYSIZE( szSection ));
  738. Assert( dw );
  739. b = SetupInstallFromInfSection(NULL, // hwndOwner
  740. g_Options.hinf, // inf handle
  741. szSection, // name of component
  742. SPINST_REGSVR,
  743. NULL, // relative key root
  744. NULL, // source root path
  745. 0, // copy flags
  746. NULL, // callback routine
  747. NULL, // callback routine context
  748. NULL, // device info set
  749. NULL); // device info struct
  750. if ( !b )
  751. {
  752. DWORD dwErr = GetLastError( );
  753. DebugMsg( "SetupInstallFromInfSection failed - error 0x%08x\n", dwErr );
  754. //
  755. // For now do extra work and try both copying and re-registering the DLL,
  756. // otw if we want to optimize we might be able to use the error code to
  757. // determine which to do. However, this case is extremely rare, so the
  758. // simple extra work is not a burden.
  759. //
  760. fMissingDll = TRUE;
  761. fRegistrationFailed = TRUE;
  762. }
  763. g_Options.fRegSrvDllsFilesFound = !fMissingDll;
  764. g_Options.fRegSrvDllsRegistered = !(fMissingDll || fRegistrationFailed);
  765. }
  766. if ( g_Options.fRegSrvDllsFilesFound
  767. && g_Options.fRegSrvDllsRegistered ) {
  768. DebugMsg( "All DLLs found and registered.\n" );
  769. hr = S_OK;
  770. }
  771. HRETURN(hr);
  772. }
  773. //
  774. // CheckOSChooser( )
  775. //
  776. HRESULT
  777. CheckOSChooser( )
  778. {
  779. HRESULT hr = S_FALSE;
  780. WCHAR szOSChooserScreensPath[ MAX_PATH ];
  781. DWORD dw;
  782. TraceFunc( "CheckOSChooser( )\n" );
  783. //
  784. // Make sure the OS Chooser files for all platforms
  785. // are installed
  786. //
  787. if ( !g_Options.fOSChooserInstalled
  788. && g_Options.fOSChooserDirectory ) {
  789. WCHAR szFile[ MAX_PATH ];
  790. BOOL fFound;
  791. INFCONTEXT context;
  792. fFound = SetupFindFirstLine( g_Options.hinf, L"OSChooser", NULL, &context );
  793. Assert( fFound );
  794. if ( !fFound ) {
  795. DebugMsg( "Could not find 'OSChooser' section in REMINST.INF.\n" );
  796. goto OSChooserCheckScreens;
  797. }
  798. while ( fFound
  799. && SetupGetStringField( &context, 1, szFile, ARRAYSIZE(szFile), NULL ) )
  800. {
  801. WCHAR szPath[ MAX_PATH ];
  802. wsprintf( szPath,
  803. L"%s\\%s",
  804. g_Options.szOSChooserPath,
  805. szFile );
  806. Assert( wcslen(szPath) < ARRAYSIZE(szPath) );
  807. if ( 0xFFFFffff == GetFileAttributes( szPath ) ) {
  808. DebugMsg( "%s is missing for OS Chooser.\n", szPath );
  809. goto OSChooserCheckScreens;
  810. }
  811. fFound = SetupFindNextLine( &context, &context );
  812. }
  813. DebugMsg( "All OS Chooser files found.\n" );
  814. g_Options.fOSChooserInstalled = TRUE;
  815. }
  816. OSChooserCheckScreens:
  817. //
  818. // Check to see if all the screens are present
  819. //
  820. // Make the check only if we have a language set.
  821. if ( g_Options.fLanguageSet ) {
  822. // First check for the directory
  823. if ( !g_Options.fOSChooserScreensDirectory ) {
  824. WCHAR szOSChooserScreensPath[ MAX_PATH ];
  825. wsprintf( szOSChooserScreensPath,
  826. L"%s\\%s",
  827. g_Options.szOSChooserPath,
  828. g_Options.szLanguage );
  829. Assert( wcslen(szOSChooserScreensPath) < ARRAYSIZE(szOSChooserScreensPath) );
  830. if ( 0xFFFFffff == GetFileAttributes( szOSChooserScreensPath ) ) {
  831. DebugMsg( "%s directory not found.\n", szOSChooserScreensPath );
  832. goto OSChooserExitCheckScreens;
  833. }
  834. DebugMsg( "%s directory found.\n", szOSChooserScreensPath );
  835. g_Options.fOSChooserScreensDirectory = TRUE;
  836. }
  837. // now check for files
  838. if ( !g_Options.fOSChooserScreens
  839. && g_Options.fOSChooserScreensDirectory ) {
  840. WCHAR szFile[ MAX_PATH ];
  841. BOOL fFound;
  842. INFCONTEXT context;
  843. fFound = SetupFindFirstLine( g_Options.hinf, L"OSChooser Screens", NULL, &context );
  844. Assert( fFound );
  845. if ( !fFound )
  846. goto OSChooserExitCheckScreens;
  847. while ( fFound
  848. && SetupGetStringField( &context, 1, szFile, ARRAYSIZE(szFile), NULL ) )
  849. {
  850. WCHAR szPath[ MAX_PATH ];
  851. wsprintf( szPath,
  852. L"%s\\%s\\%s",
  853. g_Options.szOSChooserPath,
  854. g_Options.szLanguage,
  855. szFile );
  856. Assert( wcslen(szPath) < ARRAYSIZE(szPath) );
  857. if ( 0xFFFFffff == GetFileAttributes( szPath ) ) {
  858. DebugMsg( "%s is missing for OS Chooser.\n", szPath );
  859. goto OSChooserExitCheckScreens;
  860. }
  861. fFound = SetupFindNextLine( &context, &context );
  862. }
  863. g_Options.fOSChooserScreens = TRUE;
  864. DebugMsg( "All OS Chooser screens found for language %s.\n", g_Options.szLanguage );
  865. }
  866. }
  867. OSChooserExitCheckScreens:
  868. if ( g_Options.fOSChooserDirectory
  869. && g_Options.fOSChooserInstalled
  870. && ( !g_Options.fLanguageSet
  871. || ( g_Options.fOSChooserScreensDirectory
  872. && g_Options.fOSChooserScreens ) ) ) {
  873. DebugMsg( "All OS Chooser services checked out OK.\n" );
  874. hr = S_OK;
  875. } else {
  876. DebugMsg( "OS Chooser check failed.\n" );
  877. }
  878. HRETURN(hr);
  879. }
  880. //
  881. // CheckServerVersion( )
  882. //
  883. HRESULT
  884. CheckServerVersion( )
  885. {
  886. HRESULT hr = S_OK;
  887. TraceFunc( "CheckServerVersion( )\n" );
  888. // DebugMsg( "Fudging Server Version check...\n" );
  889. // g_Options.fServerCompatible = TRUE;
  890. if ( !g_Options.fServerCompatible
  891. && g_Options.szWorkstationRemBootInfPath[0] ) {
  892. OSVERSIONINFO osver;
  893. hr = E_FAIL;
  894. osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  895. if ( GetVersionEx( &osver ) ) {
  896. WCHAR szSection[ MAX_PATH ];
  897. WCHAR szBestBuild[ MAX_PATH ];
  898. WCHAR szPath[ MAX_PATH ];
  899. WCHAR szServerMajor[ 10 ];
  900. WCHAR szServerMinor[ 10 ];
  901. WCHAR szServerBuild[ 10 ];
  902. DWORD dw;
  903. BOOL fFound;
  904. HINF hinf;
  905. UINT uLineNum;
  906. INFCONTEXT context;
  907. dw = LoadString( g_hinstance, IDS_COMPATIBILITY, szSection, ARRAYSIZE( szSection ));
  908. Assert( dw );
  909. wsprintf( szServerMajor, L"%u", osver.dwMajorVersion );
  910. wsprintf( szServerMinor, L"%u", osver.dwMinorVersion );
  911. wsprintf( szServerBuild, L"%u", osver.dwBuildNumber );
  912. DebugMsg( "Server Version: %u.%u Build: %u Service Pack: %s\n",
  913. osver.dwMajorVersion,
  914. osver.dwMinorVersion,
  915. osver.dwMinorVersion,
  916. osver.szCSDVersion );
  917. hinf = SetupOpenInfFile( g_Options.szWorkstationRemBootInfPath, NULL, INF_STYLE_WIN4, &uLineNum);
  918. if ( hinf == INVALID_HANDLE_VALUE ) {
  919. ErrorBox( NULL, g_Options.szWorkstationRemBootInfPath );
  920. goto Error;
  921. }
  922. fFound = SetupFindFirstLine( hinf, szSection, NULL, &context );
  923. if ( !fFound ) {
  924. ErrorBox( NULL, g_Options.szWorkstationRemBootInfPath );
  925. goto Error;
  926. }
  927. while ( fFound )
  928. {
  929. WCHAR szMajor[ SMALL_BUFFER_SIZE ];
  930. WCHAR szMinor[ SMALL_BUFFER_SIZE ];
  931. WCHAR szBuild[ SMALL_BUFFER_SIZE ];
  932. WCHAR szServicePack[ SMALL_BUFFER_SIZE ];
  933. fFound = SetupGetStringField( &context, 1, szMajor, ARRAYSIZE(szMajor), NULL );
  934. Assert( fFound );
  935. if (!fFound)
  936. break;
  937. fFound = SetupGetStringField( &context, 2, szMinor, ARRAYSIZE(szMinor), NULL );
  938. Assert( fFound );
  939. if (!fFound)
  940. break;
  941. fFound = SetupGetStringField( &context, 3, szBuild, ARRAYSIZE(szBuild), NULL );
  942. Assert( fFound );
  943. if (!fFound)
  944. break;
  945. fFound = SetupGetStringField( &context, 4, szServicePack, ARRAYSIZE(szServicePack), NULL );
  946. Assert( fFound );
  947. if (!fFound)
  948. break;
  949. // Does it correspond to the server version?
  950. if ( StrCmpI( szServerMajor, szMajor ) >= 0 // must match or greater
  951. && StrCmpI( szServerMinor, szMinor ) >= 0 // must match or greater
  952. && StrCmpI( szServerBuild, szBuild ) >= 0 // must match or server build is greater
  953. && ( szServicePack[0] == L'\0' // ignore service pack if not specified
  954. || StrCmpI( osver.szCSDVersion, szServicePack ) == 0 ) ) {
  955. // found match
  956. DebugMsg( "Server is compatiable with Workstation.\n");
  957. hr = S_OK;
  958. break;
  959. }
  960. fFound = SetupFindNextLine( &context, &context );
  961. }
  962. if ( FAILED(hr) ) {
  963. WCHAR szTitle[ MAX_PATH ];
  964. WCHAR szCaption[ 4096 ];
  965. WCHAR szBuf[ 4096 ];
  966. WCHAR szMajor[ SMALL_BUFFER_SIZE ];
  967. WCHAR szMinor[ SMALL_BUFFER_SIZE ];
  968. WCHAR szBuild[ SMALL_BUFFER_SIZE ];
  969. WCHAR szServicePack[ SMALL_BUFFER_SIZE ];
  970. INFCONTEXT context;
  971. DebugMsg( "Server doesn't look like it is compatiable with the Workstation Build.\n" );
  972. fFound = SetupFindFirstLine( hinf, szSection, NULL, &context );
  973. Assert( fFound );
  974. fFound = SetupGetStringField( &context, 1, szMajor, ARRAYSIZE(szMajor), NULL );
  975. Assert( fFound );
  976. fFound = SetupGetStringField( &context, 2, szMinor, ARRAYSIZE(szMinor), NULL );
  977. Assert( fFound );
  978. fFound = SetupGetStringField( &context, 3, szBuild, ARRAYSIZE(szBuild), NULL );
  979. Assert( fFound );
  980. fFound = SetupGetStringField( &context, 4, szServicePack, ARRAYSIZE(szServicePack), NULL );
  981. Assert( fFound );
  982. dw = LoadString( g_hinstance, IDS_INCOMPATIBLE_SERVER_VERSION_TITLE, szTitle, ARRAYSIZE( szTitle ));
  983. Assert( dw );
  984. dw = LoadString( g_hinstance, IDS_INCOMPATIBLE_SERVER_VERSION_CAPTION, szBuf, ARRAYSIZE( szBuf ));
  985. Assert( dw );
  986. wsprintf( szCaption, szBuf, szMajor, szMinor, szBuild, szServicePack );
  987. MessageBox( NULL, szCaption, szTitle, MB_OK );
  988. Assert( hr == E_FAIL );
  989. }
  990. Error:
  991. if ( hinf != INVALID_HANDLE_VALUE ) {
  992. SetupCloseInfFile( hinf );
  993. }
  994. }
  995. g_Options.fServerCompatible = ( hr == S_OK );
  996. }
  997. if (g_Options.fServerCompatible ) {
  998. DebugMsg( "Server compatibility checked out OK.\n" );
  999. hr = S_OK;
  1000. } else {
  1001. DebugMsg( "Server compatibility failed.\n" );
  1002. }
  1003. HRETURN(hr);
  1004. }
  1005. //
  1006. // CheckFirstInstall( )
  1007. //
  1008. // This really checks for the existence of the REMINST directory
  1009. // under the system32 directory which was created during OCM setup.
  1010. //
  1011. HRESULT
  1012. CheckFirstInstall( )
  1013. {
  1014. HRESULT hr = S_OK;
  1015. TraceFunc( "CheckFirstInstall( )\n" );
  1016. if ( !g_Options.fRemBootDirectory ) {
  1017. DWORD dw;
  1018. WCHAR szFilePath[ MAX_PATH ];
  1019. dw = ExpandEnvironmentStrings( TEXT("%windir%"), g_Options.szRemBootDirectory, ARRAYSIZE(g_Options.szRemBootDirectory) );
  1020. Assert( dw );
  1021. wcscpy( szFilePath, g_Options.szRemBootDirectory );
  1022. wcscat( szFilePath, L"\\System32\\reminst.inf" );
  1023. StrCat( g_Options.szRemBootDirectory, L"\\System32\\REMINST" );
  1024. Assert( wcslen(g_Options.szRemBootDirectory) < ARRAYSIZE(g_Options.szRemBootDirectory) );
  1025. if ( 0xFFFFffff != GetFileAttributes( g_Options.szRemBootDirectory ) )
  1026. {
  1027. DebugMsg( "Found the %s directory.\n", g_Options.szRemBootDirectory );
  1028. HINF hinf = INVALID_HANDLE_VALUE;
  1029. INFCONTEXT context;
  1030. // now check to see if the files are still in there.
  1031. hinf = SetupOpenInfFile( szFilePath, NULL, INF_STYLE_WIN4, NULL );
  1032. if ( hinf != INVALID_HANDLE_VALUE )
  1033. {
  1034. WCHAR szFile[ MAX_PATH ];
  1035. BOOL fFound;
  1036. fFound = SetupFindFirstLine( hinf, L"OSChooser", NULL, &context );
  1037. Assert( fFound );
  1038. if ( !fFound ) {
  1039. DebugMsg( "Could not find 'OSChooser' section in REMINST.INF.\n" );
  1040. hr = S_FALSE;
  1041. goto bail;
  1042. }
  1043. wcscpy( szFilePath, g_Options.szRemBootDirectory );
  1044. wcscat( szFilePath, L"\\" );
  1045. dw = wcslen( szFilePath );
  1046. while ( fFound )
  1047. {
  1048. fFound = SetupGetStringField( &context, 2, szFile, ARRAYSIZE(szFile), NULL );
  1049. if ( !fFound )
  1050. {
  1051. fFound = SetupGetStringField( &context, 2, szFile, ARRAYSIZE(szFile), NULL );
  1052. if ( !fFound )
  1053. goto skipit;
  1054. }
  1055. wcscpy( &szFilePath[ dw ], szFile );
  1056. Assert( wcslen(szFilePath) < ARRAYSIZE(szFilePath) );
  1057. if ( 0xFFFFffff == GetFileAttributes( szFilePath ) ) {
  1058. DebugMsg( "%s is missing.\n", szFilePath );
  1059. goto bail;
  1060. }
  1061. skipit:
  1062. fFound = SetupFindNextLine( &context, &context );
  1063. }
  1064. DebugMsg( "All REMINST files found.\n" );
  1065. g_Options.fRemBootDirectory = TRUE;
  1066. }
  1067. else
  1068. {
  1069. DebugMsg( "File not found. Error 0x%08x\n", GetLastError( ) );
  1070. }
  1071. bail:
  1072. if ( hinf != INVALID_HANDLE_VALUE )
  1073. {
  1074. SetupCloseInfFile( hinf );
  1075. }
  1076. }
  1077. }
  1078. if ( g_Options.fRemBootDirectory )
  1079. {
  1080. DebugMsg( "REMINST directory checked out OK.\n" );
  1081. }
  1082. else
  1083. {
  1084. DebugMsg( "REMINST directory is missing or missing files. This may require the server CD.\n ");
  1085. }
  1086. HRETURN(hr);
  1087. }
  1088. //
  1089. // CheckRegistry( )
  1090. //
  1091. HRESULT
  1092. CheckRegistry( )
  1093. {
  1094. HRESULT hr = S_FALSE;
  1095. WCHAR szSection[ SMALL_BUFFER_SIZE ];
  1096. INFCONTEXT context;
  1097. BOOL fFound;
  1098. DWORD dw;
  1099. BOOL b;
  1100. UINT uLineNum;
  1101. INT index;
  1102. TraceFunc( "CheckRegistry( )\n" );
  1103. if ( !g_Options.fRegistryIntact ) {
  1104. dw = LoadString( g_hinstance, IDS_INF_SECTION, szSection, ARRAYSIZE( szSection ) );
  1105. Assert( dw );
  1106. fFound = SetupFindFirstLine( g_Options.hinf, szSection, L"AddReg", &context );
  1107. Assert( fFound );
  1108. if ( !fFound )
  1109. goto Error;
  1110. // Assume SUCCESS and use it to exit the loop early
  1111. g_Options.fRegistryIntact = TRUE;
  1112. DebugMsg( "Checking Registry:\n" );
  1113. index = 1;
  1114. while ( g_Options.fRegistryIntact
  1115. && SetupGetStringField( &context, index, szSection, ARRAYSIZE(szSection), NULL ) )
  1116. {
  1117. INFCONTEXT subcontext;
  1118. fFound = SetupFindFirstLine( g_Options.hinf, szSection, NULL, &subcontext );
  1119. Assert( fFound );
  1120. while ( fFound && g_Options.fRegistryIntact )
  1121. {
  1122. WCHAR szRootKey[ 10 ];
  1123. WCHAR szBaseKey[ MAX_PATH ];
  1124. WCHAR szValueName[ MAX_PATH ];
  1125. HKEY hkeyRoot = NULL;
  1126. HKEY hkeyBase;
  1127. LONG lResult;
  1128. SetupGetStringField( &subcontext, 1, szRootKey, ARRAYSIZE(szRootKey), NULL );
  1129. SetupGetStringField( &subcontext, 2, szBaseKey, ARRAYSIZE(szBaseKey), NULL );
  1130. SetupGetStringField( &subcontext, 3, szValueName, ARRAYSIZE(szValueName), NULL );
  1131. DebugMsg( "%s, %s, %s - ", szRootKey, szBaseKey, szValueName );
  1132. if ( StrCmpI( szRootKey, L"HKLM" ) == 0 ) {
  1133. hkeyRoot = HKEY_LOCAL_MACHINE;
  1134. } else if ( StrCmpI( szRootKey, L"HKCU" ) == 0 ) {
  1135. hkeyRoot = HKEY_CURRENT_USER;
  1136. } else if ( StrCmpI( szRootKey, L"HKCC" ) == 0 ) {
  1137. hkeyRoot = HKEY_CURRENT_CONFIG;
  1138. } else if ( StrCmpI( szRootKey, L"HKCR" ) == 0 ) {
  1139. hkeyRoot = HKEY_CLASSES_ROOT;
  1140. }
  1141. //
  1142. // If this Assert() fires, it is because the INF is malformed
  1143. //
  1144. Assert( hkeyRoot );
  1145. if ( hkeyRoot == NULL )
  1146. continue;
  1147. lResult = RegOpenKeyEx( hkeyRoot, szBaseKey, 0, KEY_QUERY_VALUE, &hkeyBase );
  1148. if ( lResult == ERROR_SUCCESS )
  1149. {
  1150. lResult = RegQueryValueEx( hkeyBase, szValueName, 0, NULL, NULL, NULL );
  1151. if ( lResult != ERROR_SUCCESS ) {
  1152. DebugMsg("NOT " );
  1153. g_Options.fRegistryIntact = FALSE;
  1154. hr = S_FALSE;
  1155. }
  1156. RegCloseKey( hkeyBase );
  1157. } else {
  1158. DebugMsg("NOT " );
  1159. g_Options.fRegistryIntact = FALSE;
  1160. hr = S_FALSE;
  1161. }
  1162. DebugMsg("found.\n" );
  1163. fFound = SetupFindNextLine( &subcontext, &subcontext );
  1164. }
  1165. index++;
  1166. }
  1167. }
  1168. if ( g_Options.fRegistryIntact ) {
  1169. DebugMsg( "Registry checked out OK.\n" );
  1170. hr = S_OK;
  1171. } else {
  1172. DebugMsg( "Registry check failed.\n" );
  1173. }
  1174. Error:
  1175. HRETURN(hr);
  1176. }
  1177. //
  1178. // Paranoid( )
  1179. //
  1180. // Catch all for double checking that common things across services
  1181. // match up.
  1182. //
  1183. HRESULT
  1184. Paranoid( )
  1185. {
  1186. HRESULT hr = S_OK;
  1187. TraceFunc( "Paranoid( )\n" );
  1188. // Make sure that the IntelliMirror directory are the same
  1189. // for TFTPD and for the IMIRROR share (binlsvc uses this).
  1190. if ( g_Options.fIMirrorDirectory
  1191. && g_Options.fTFTPDDirectoryFound
  1192. && StrCmpI( g_Options.szIntelliMirrorPath, g_Options.szTFTPDDirectory ) != 0 ) {
  1193. //
  1194. // If they are not the same, force the registry to modify the TFTPD key.
  1195. //
  1196. DebugMsg( "TFTPD doesn't agree with IMIRROR share. Forcing TFTPD registry update.\n" );
  1197. g_Options.fTFTPDDirectoryFound = FALSE;
  1198. hr = S_FALSE;
  1199. }
  1200. if ( hr != S_OK ) {
  1201. DebugMsg( "Paranoid found a problem.\n" );
  1202. } else {
  1203. DebugMsg( "Paranoid is happy. 8~)\n" );
  1204. }
  1205. HRETURN( hr );
  1206. }
  1207. //
  1208. // CheckInstallation( )
  1209. //
  1210. HRESULT
  1211. CheckInstallation( )
  1212. {
  1213. HRESULT hr = S_OK;
  1214. BOOL fSomethingbroke = FALSE;
  1215. BOOL fSomethingFailed = FALSE;
  1216. DWORD dw;
  1217. DWORD dwLen;
  1218. UINT uLineNum;
  1219. SC_HANDLE schSystem;
  1220. WCHAR szServerRemBootInfPath[ MAX_PATH ];
  1221. CWaitCursor Wait;
  1222. TraceFunc( "CheckInstallation( )\n");
  1223. szServerRemBootInfPath[0] = L'\0';
  1224. dw = ExpandEnvironmentStrings( TEXT("%SystemRoot%"), szServerRemBootInfPath, ARRAYSIZE( szServerRemBootInfPath ));
  1225. Assert( dw );
  1226. dwLen = lstrlen( szServerRemBootInfPath );
  1227. StrCpy( &szServerRemBootInfPath[dwLen], L"\\System32\\" );
  1228. dwLen = lstrlen( szServerRemBootInfPath );
  1229. dw = LoadString( g_hinstance, IDS_REMBOOTINF, &szServerRemBootInfPath[dwLen], ARRAYSIZE( szServerRemBootInfPath ) - dwLen );
  1230. Assert( dw );
  1231. if ( 0xFFFFffff == GetFileAttributes( szServerRemBootInfPath ) ) {
  1232. MessageBoxFromStrings( NULL,
  1233. IDS_MISSING_INF_TITLE,
  1234. IDS_MISSING_INF_MESSAGE,
  1235. MB_OK );
  1236. fSomethingbroke = TRUE;
  1237. goto e0;
  1238. }
  1239. if ( g_Options.hinf == INVALID_HANDLE_VALUE ) {
  1240. g_Options.hinf = SetupOpenInfFile( szServerRemBootInfPath, NULL, INF_STYLE_WIN4, &uLineNum);
  1241. Assert( g_Options.hinf != INVALID_HANDLE_VALUE );
  1242. if ( g_Options.hinf == INVALID_HANDLE_VALUE ) {
  1243. fSomethingbroke = TRUE;
  1244. goto e0;
  1245. }
  1246. }
  1247. hr = CheckServerVersion( );
  1248. if ( FAILED(hr) ) {
  1249. fSomethingbroke = TRUE;
  1250. goto e0;
  1251. }
  1252. if ( hr == S_FALSE ) {
  1253. fSomethingFailed = TRUE;
  1254. }
  1255. hr = CheckFirstInstall( );
  1256. if ( FAILED(hr) ) {
  1257. fSomethingbroke = TRUE;
  1258. }
  1259. if ( hr == S_FALSE ) {
  1260. fSomethingFailed = TRUE;
  1261. }
  1262. hr = CheckDirectoryTree( );
  1263. if ( FAILED(hr) ) {
  1264. fSomethingbroke = TRUE;
  1265. }
  1266. if ( hr == S_FALSE ) {
  1267. fSomethingFailed = TRUE;
  1268. }
  1269. schSystem = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
  1270. if ( !schSystem ) {
  1271. hr = THR(E_FAIL);
  1272. fSomethingbroke = TRUE;
  1273. WCHAR szCaption[SMALL_BUFFER_SIZE];
  1274. DWORD dw;
  1275. dw = LoadString( g_hinstance, IDS_OPENING_SERVICE_MANAGER_TITLE, szCaption, ARRAYSIZE( szCaption ));
  1276. Assert( dw );
  1277. ErrorBox( NULL, szCaption );
  1278. goto e0;
  1279. }
  1280. Assert( schSystem );
  1281. if ( schSystem ) {
  1282. hr = CheckBINL( schSystem );
  1283. if ( FAILED(hr) ) {
  1284. fSomethingbroke = TRUE;
  1285. }
  1286. if ( hr == S_FALSE ) {
  1287. fSomethingFailed = TRUE;
  1288. }
  1289. hr = CheckTFTPD( schSystem );
  1290. if ( FAILED(hr) ) {
  1291. fSomethingbroke = TRUE;
  1292. }
  1293. if ( hr == S_FALSE ) {
  1294. fSomethingFailed = TRUE;
  1295. }
  1296. hr = CheckSIS( schSystem );
  1297. if ( FAILED(hr) ) {
  1298. fSomethingbroke = TRUE;
  1299. }
  1300. if ( hr == S_FALSE ) {
  1301. fSomethingFailed = TRUE;
  1302. }
  1303. hr = CheckSISGroveler( schSystem );
  1304. if ( FAILED(hr) ) {
  1305. fSomethingbroke = TRUE;
  1306. }
  1307. if ( hr == S_FALSE ) {
  1308. fSomethingFailed = TRUE;
  1309. }
  1310. CloseServiceHandle( schSystem );
  1311. }
  1312. hr = CheckRegSrvDlls( );
  1313. if ( FAILED(hr) ) {
  1314. fSomethingbroke = TRUE;
  1315. }
  1316. if ( hr == S_FALSE ) {
  1317. fSomethingFailed = TRUE;
  1318. }
  1319. hr = CheckRegistry( );
  1320. if ( FAILED(hr) ) {
  1321. fSomethingbroke = TRUE;
  1322. }
  1323. if ( hr == S_FALSE ) {
  1324. fSomethingFailed = TRUE;
  1325. }
  1326. hr = CheckOSChooser( );
  1327. if ( FAILED(hr) ) {
  1328. fSomethingbroke = TRUE;
  1329. }
  1330. if ( hr == S_FALSE ) {
  1331. fSomethingFailed = TRUE;
  1332. }
  1333. hr = Paranoid( );
  1334. if ( FAILED(hr) ) {
  1335. fSomethingbroke = TRUE;
  1336. }
  1337. if ( hr == S_FALSE ) {
  1338. fSomethingFailed = TRUE;
  1339. }
  1340. e0:
  1341. if ( fSomethingbroke ) {
  1342. DebugMsg( "Something is broken. Installation check failed to complete.\n" );
  1343. hr = E_FAIL;
  1344. } else if ( fSomethingFailed ) {
  1345. DebugMsg( "Installation check found something wrong.\n" );
  1346. hr = S_FALSE;
  1347. } else {
  1348. DebugMsg( "Installation check succeeded.\n" );
  1349. hr = S_OK;
  1350. }
  1351. HRETURN(hr);
  1352. }