Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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