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.

1207 lines
31 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. // All rights reserved.
  5. //
  6. // File Name:
  7. // copyfil1.c
  8. //
  9. // Description:
  10. // This file has the dlgproc for the CopyFiles1 page. This is the
  11. // page just before the gas-guage.
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "pch.h"
  15. #include "sku.h"
  16. static TCHAR *StrServerCdName;
  17. static TCHAR *StrWorkStationCdName;
  18. static NAMELIST DosnetPaths;
  19. TCHAR szDosnetPath[MAX_PATH + 1];
  20. #define WORKSTATION 0
  21. #define SERVER 1
  22. #define ENTERPRISE 2
  23. #define PERSONAL 4
  24. #define WEBBLADE 5
  25. static LPTSTR s_lpSourceDirs[] =
  26. {
  27. DIR_CD_IA64, // Must be before x86 because ia64 has both dirs.
  28. DIR_CD_X86, // Should always be last in the list.
  29. };
  30. //----------------------------------------------------------------------------
  31. //
  32. // Function: OnMultipleDosnetInitDialog
  33. //
  34. // Purpose: Fill the dosnet list box with the possible path choices for
  35. // the user.
  36. //
  37. // Arguments: IN HWND hwnd - handle to the dialog
  38. //
  39. // Returns: VOID
  40. //
  41. //----------------------------------------------------------------------------
  42. static VOID
  43. OnMultipleDosnetInitDialog( IN HWND hwnd )
  44. {
  45. INT i;
  46. INT nEntries;
  47. TCHAR *pDosnetPath;
  48. nEntries = GetNameListSize( &DosnetPaths );
  49. for( i = 0; i < nEntries; i++ )
  50. {
  51. pDosnetPath = GetNameListName( &DosnetPaths, i );
  52. SendDlgItemMessage( hwnd,
  53. IDC_LB_DOSNET_PATHS,
  54. LB_ADDSTRING,
  55. (WPARAM) 0,
  56. (LPARAM) pDosnetPath );
  57. }
  58. }
  59. //----------------------------------------------------------------------------
  60. //
  61. // Function: OnMultipleDosnetOk
  62. //
  63. // Purpose:
  64. //
  65. // Arguments: IN HWND hwnd - handle to the dialog
  66. //
  67. // Returns: BOOL - TRUE if safe to close the pop-up, FALSE to keep the pop-up
  68. // open
  69. //
  70. //----------------------------------------------------------------------------
  71. static BOOL
  72. OnMultipleDosnetOk( IN HWND hwnd )
  73. {
  74. INT_PTR iRetVal;
  75. iRetVal = SendDlgItemMessage( hwnd,
  76. IDC_LB_DOSNET_PATHS,
  77. LB_GETCURSEL,
  78. 0,
  79. 0 );
  80. if( iRetVal == LB_ERR )
  81. {
  82. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_NO_PATH_CHOSEN );
  83. return( FALSE );
  84. }
  85. else
  86. {
  87. SendDlgItemMessage( hwnd,
  88. IDC_LB_DOSNET_PATHS,
  89. LB_GETTEXT,
  90. (WPARAM) iRetVal,
  91. (LPARAM) szDosnetPath );
  92. return( TRUE );
  93. }
  94. }
  95. //----------------------------------------------------------------------------
  96. //
  97. // Function: MultipleDosnetDlg
  98. //
  99. // Purpose: Dialog procedure for the user to select what windows source file
  100. // dir they want to tree copy.
  101. //
  102. // Arguments: standard Win32 dialog proc arguments
  103. //
  104. // Returns: standard Win32 dialog proc return value -- whether the message
  105. // was handled or not
  106. //
  107. //----------------------------------------------------------------------------
  108. INT_PTR CALLBACK
  109. MultipleDosnetDlg( IN HWND hwnd,
  110. IN UINT uMsg,
  111. IN WPARAM wParam,
  112. IN LPARAM lParam )
  113. {
  114. BOOL bStatus = TRUE;
  115. switch (uMsg) {
  116. case WM_INITDIALOG:
  117. OnMultipleDosnetInitDialog( hwnd );
  118. break;
  119. case WM_COMMAND: {
  120. int nButtonId;
  121. switch ( nButtonId = LOWORD (wParam ) ) {
  122. case IDOK:
  123. {
  124. BOOL bSelectionMade;
  125. bSelectionMade = OnMultipleDosnetOk( hwnd );
  126. if( bSelectionMade )
  127. {
  128. EndDialog( hwnd, TRUE );
  129. }
  130. break;
  131. }
  132. case IDCANCEL:
  133. EndDialog( hwnd, FALSE );
  134. break;
  135. }
  136. }
  137. default:
  138. bStatus = FALSE;
  139. break;
  140. }
  141. return( bStatus );
  142. }
  143. //----------------------------------------------------------------------------
  144. //
  145. // Function: GreyUnGreyCopyFile1
  146. //
  147. // Purpose: Called to grey/ungrey the controls. Call this routine each
  148. // time a radio button is clicked or set.
  149. //
  150. //----------------------------------------------------------------------------
  151. VOID GreyUnGreyCopyFile1(HWND hwnd)
  152. {
  153. BOOL bUnGrey = IsDlgButtonChecked(hwnd, IDC_COPYFROMPATH);
  154. EnableWindow(GetDlgItem(hwnd, IDT_SOURCEPATH), bUnGrey);
  155. EnableWindow(GetDlgItem(hwnd, IDC_BROWSE), bUnGrey);
  156. EnableWindow(GetDlgItem(hwnd, IDC_GREYTEXT), bUnGrey);
  157. }
  158. //----------------------------------------------------------------------------
  159. //
  160. // Function: OnSetActiveCopyFiles1
  161. //
  162. // Purpose: Called at SETACTIVE time
  163. //
  164. //----------------------------------------------------------------------------
  165. VOID OnSetActiveCopyFiles1(HWND hwnd)
  166. {
  167. CheckRadioButton(hwnd,
  168. IDC_COPYFROMCD,
  169. IDC_COPYFROMPATH,
  170. WizGlobals.bCopyFromPath ? IDC_COPYFROMPATH
  171. : IDC_COPYFROMCD);
  172. GreyUnGreyCopyFile1(hwnd);
  173. ZeroMemory( &DosnetPaths, sizeof(NAMELIST) );
  174. WIZ_BUTTONS(hwnd, PSWIZB_BACK | PSWIZB_NEXT);
  175. }
  176. //----------------------------------------------------------------------------
  177. //
  178. // Function: OnRadioButtonCopyFiles1
  179. //
  180. // Purpose: Called when a radio button is pushed. We must grey/ungrey
  181. // controls when this happens.
  182. //
  183. //----------------------------------------------------------------------------
  184. VOID OnRadioButtonCopyFiles1(HWND hwnd, int nButtonId)
  185. {
  186. CheckRadioButton(hwnd,
  187. IDC_COPYFROMCD,
  188. IDC_COPYFROMPATH,
  189. nButtonId);
  190. GreyUnGreyCopyFile1(hwnd);
  191. }
  192. //----------------------------------------------------------------------------
  193. //
  194. // Function: OnBrowseCopyFiles1
  195. //
  196. // Purpose: Called when user pushes the BROWSE button
  197. //
  198. //----------------------------------------------------------------------------
  199. VOID OnBrowseCopyFiles1(HWND hwnd)
  200. {
  201. BOOL bGoodSource = FALSE;
  202. while (!bGoodSource && BrowseForFolder(hwnd, IDS_BROWSEFOLDER, WizGlobals.CopySourcePath, BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_VALIDATE))
  203. {
  204. TCHAR szPath[MAX_PATH] = NULLSTR;
  205. LPTSTR lpEnd,
  206. lpEnd2;
  207. // Make our own copy of the path we got back.
  208. //
  209. lstrcpyn(szPath, WizGlobals.CopySourcePath,AS(szPath));
  210. // First check and see if we have the inf we need right here.
  211. //
  212. lpEnd = szPath + lstrlen(szPath);
  213. AddPathN(szPath, FILE_DOSNET_INF, AS(szPath));
  214. if ( !(bGoodSource = FileExists(szPath)) )
  215. {
  216. DWORD dwSearch;
  217. // Search for all the possible source directories that could be on the CD.
  218. //
  219. for ( dwSearch = 0; !bGoodSource && ( dwSearch < AS(s_lpSourceDirs) ); dwSearch++ )
  220. {
  221. // First test for the directory.
  222. //
  223. *lpEnd = NULLCHR;
  224. AddPathN(szPath, s_lpSourceDirs[dwSearch],AS(szPath));
  225. if ( DirectoryExists(szPath) )
  226. {
  227. // Also make sure that the inf file we need is there.
  228. //
  229. lpEnd2 = szPath + lstrlen(szPath);
  230. AddPathN(szPath, FILE_DOSNET_INF,AS(szPath));
  231. if ( bGoodSource = FileExists(szPath) )
  232. lpEnd = lpEnd2;
  233. }
  234. }
  235. }
  236. // Let the user know that they have a bad source
  237. //
  238. if ( !bGoodSource)
  239. {
  240. MsgBox(GetParent(hwnd), IDS_ERR_BADSOURCE, IDS_APPNAME, MB_ERRORBOX);
  241. }
  242. }
  243. // Set the source in the dialog only if the source was good
  244. //
  245. if ( bGoodSource )
  246. {
  247. SetDlgItemText(hwnd, IDT_SOURCEPATH, WizGlobals.CopySourcePath);
  248. }
  249. }
  250. //----------------------------------------------------------------------------
  251. //
  252. // Function: CanConnectToNetworkShare
  253. //
  254. // Purpose: To determine if the currently logged in user has permission to
  255. // access the UNC path given.
  256. //
  257. // Arguments:
  258. // TCHAR *szSourceFilesPath - path to the source files that contains the
  259. // UNC path to see if we can connect
  260. //
  261. // Returns:
  262. // TRUE if user has permission to access the network share
  263. // FALSE if not
  264. //
  265. //----------------------------------------------------------------------------
  266. static BOOL
  267. CanConnectToNetworkShare( IN TCHAR *pszSourceFilesPath )
  268. {
  269. TCHAR *pPathEnd;
  270. TCHAR szUncPath[MAX_PATH + 1];
  271. INT nBackSlashCount = 0;
  272. DWORD dwResult;
  273. NETRESOURCE NetResource;
  274. //
  275. // Verify it is a UNC path.
  276. //
  277. AssertMsg( ( pszSourceFilesPath[0] == _T('\\') && pszSourceFilesPath[1] == _T('\\') ),
  278. "This is not a UNC path." );
  279. // ISSUE-2002/02/28-stelo- in the next release it would be nice to prompt the user for a
  280. // name and password to connect to the network share
  281. lstrcpyn( szUncPath, pszSourceFilesPath, AS(szUncPath) );
  282. //
  283. // Strip off the extra dir info so we are just left with \\computername\sharename
  284. //
  285. pPathEnd = szUncPath;
  286. //
  287. // Advance past the 2 leading backslashes
  288. //
  289. pPathEnd = pPathEnd + 2;
  290. while( *pPathEnd != _T('\0') )
  291. {
  292. if( *pPathEnd == _T('\\') )
  293. {
  294. if( nBackSlashCount == 0 )
  295. {
  296. //
  297. // Found the backslash that separates the computername and sharename
  298. //
  299. nBackSlashCount++;
  300. }
  301. else // nBackSlashCount >= 1
  302. {
  303. //
  304. // Found the end of the sharename
  305. //
  306. *pPathEnd = _T('\0');
  307. break;
  308. }
  309. }
  310. pPathEnd++;
  311. }
  312. //
  313. // Assign values to the NETRESOURCE structure.
  314. //
  315. NetResource.dwType = RESOURCETYPE_ANY;
  316. NetResource.lpLocalName = NULL;
  317. NetResource.lpRemoteName = (LPTSTR) szUncPath;
  318. NetResource.lpProvider = NULL;
  319. //
  320. // Try to connect as the local user
  321. //
  322. dwResult = WNetAddConnection2( &NetResource, NULL, NULL, FALSE );
  323. switch( dwResult )
  324. {
  325. case NO_ERROR:
  326. case ERROR_ALREADY_ASSIGNED:
  327. return( TRUE );
  328. break;
  329. case ERROR_ACCESS_DENIED:
  330. case ERROR_LOGON_FAILURE:
  331. ReportErrorId( NULL,
  332. MSGTYPE_ERR,
  333. IDS_ERR_NETWORK_ACCESS_DENIED,
  334. szUncPath );
  335. return( FALSE );
  336. break;
  337. case ERROR_NO_NETWORK:
  338. ReportErrorId( NULL,
  339. MSGTYPE_ERR,
  340. IDS_ERR_NETWORK_NO_NETWORK,
  341. szUncPath );
  342. return( FALSE );
  343. break;
  344. default:
  345. //
  346. // some other error
  347. //
  348. ReportErrorId( NULL,
  349. MSGTYPE_ERR,
  350. IDS_ERR_NETWORK_UNKNOWN_ERROR,
  351. szUncPath );
  352. return( FALSE );
  353. break;
  354. }
  355. }
  356. //----------------------------------------------------------------------------
  357. //
  358. // Function: IsCorrectNtVersion
  359. //
  360. // Purpose: Checks the txtsetup.sif to make sure the files are at least NT5
  361. // and that it is the correct version (workstation or server).
  362. //
  363. // Arguments:
  364. // TCHAR *szSourceFilesPath - path to the source files to validate
  365. //
  366. // Returns:
  367. // TRUE if NT version info is correct
  368. // FALSE if not the correct version
  369. //
  370. //----------------------------------------------------------------------------
  371. BOOL
  372. IsCorrectNtVersion( IN HWND hwnd, IN TCHAR *szSourceFilesPath )
  373. {
  374. HINF hTxtsetupSif;
  375. INFCONTEXT TxtsetupSifContext;
  376. TCHAR szTempBuffer[MAX_INILINE_LEN];
  377. INT iMajorVersion;
  378. INT iPlatformType;
  379. TCHAR szMajorVersionNumber[MAX_STRING_LEN];
  380. TCHAR szPlatformType[MAX_STRING_LEN];
  381. TCHAR szTxtsetupSif[MAX_PATH] = _T("");
  382. BOOL bKeepReading = TRUE;
  383. BOOL bFoundVersion = FALSE;
  384. BOOL bFoundProductType = FALSE;
  385. HRESULT hrCat;
  386. lstrcpyn( szTxtsetupSif, szSourceFilesPath, AS(szTxtsetupSif) );
  387. hrCat=StringCchCat( szTxtsetupSif,AS(szTxtsetupSif), _T("\\txtsetup.sif") );
  388. hTxtsetupSif = SetupOpenInfFile( szTxtsetupSif,
  389. NULL,
  390. INF_STYLE_OLDNT | INF_STYLE_WIN4,
  391. NULL );
  392. if( hTxtsetupSif == INVALID_HANDLE_VALUE ) {
  393. // ISSUE-2002/02/28-stelo- alert an error that we couldn't open the file or just
  394. // skip over in this case?
  395. return( FALSE );
  396. }
  397. TxtsetupSifContext.Inf = hTxtsetupSif;
  398. TxtsetupSifContext.CurrentInf = hTxtsetupSif;
  399. bKeepReading = SetupFindFirstLine( hTxtsetupSif,
  400. _T("SetupData"),
  401. NULL,
  402. &TxtsetupSifContext );
  403. //
  404. // Look for the ProductType key and the MajorVersion key
  405. //
  406. while( bKeepReading && ( ! bFoundVersion || ! bFoundProductType ) ) {
  407. SetupGetStringField( &TxtsetupSifContext,
  408. 0,
  409. szTempBuffer,
  410. MAX_INILINE_LEN,
  411. NULL );
  412. if( LSTRCMPI( szTempBuffer, _T("ProductType") ) == 0 ) {
  413. SetupGetStringField( &TxtsetupSifContext,
  414. 1,
  415. szPlatformType,
  416. MAX_STRING_LEN,
  417. NULL );
  418. bFoundProductType = TRUE;
  419. }
  420. if( LSTRCMPI( szTempBuffer, _T("MajorVersion") ) == 0 ) {
  421. SetupGetStringField( &TxtsetupSifContext,
  422. 1,
  423. szMajorVersionNumber,
  424. MAX_STRING_LEN,
  425. NULL );
  426. bFoundVersion = TRUE;
  427. }
  428. //
  429. // move to the next line of the answer file
  430. //
  431. bKeepReading = SetupFindNextLine( &TxtsetupSifContext, &TxtsetupSifContext );
  432. }
  433. SetupCloseInfFile( hTxtsetupSif );
  434. //
  435. // Convert the NT version number and product type from a string to an int
  436. //
  437. iMajorVersion = _wtoi( szMajorVersionNumber );
  438. iPlatformType = _wtoi( szPlatformType );
  439. //
  440. // Make sure it is at least NT5 (Windows 2000) files
  441. //
  442. if( bFoundVersion ) {
  443. if( iMajorVersion < 5 ) {
  444. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_NOT_NT5_FILES );
  445. return( FALSE );
  446. }
  447. }
  448. else {
  449. INT iRet;
  450. iRet = ReportErrorId( hwnd,
  451. MSGTYPE_YESNO,
  452. IDS_ERR_CANNOT_DETERMINE_VERSION );
  453. if( iRet == IDNO ) {
  454. return( FALSE );
  455. }
  456. }
  457. //
  458. // Make sure they are actually giving us workstation files, if they
  459. // specified workstation or server files if they specified server.
  460. //
  461. if( bFoundVersion ) {
  462. if( WizGlobals.iPlatform == PLATFORM_PERSONAL ) {
  463. if( iPlatformType != PERSONAL ) {
  464. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_NOT_PERSONAL_FILES );
  465. return( FALSE );
  466. }
  467. }
  468. else if( WizGlobals.iPlatform == PLATFORM_WORKSTATION ) {
  469. if( iPlatformType != WORKSTATION ) {
  470. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_NOT_WORKSTATION_FILES );
  471. return( FALSE );
  472. }
  473. }
  474. else if( WizGlobals.iPlatform == PLATFORM_SERVER ) {
  475. if( iPlatformType != SERVER ) {
  476. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_NOT_SERVER_FILES );
  477. return( FALSE );
  478. }
  479. }
  480. else if( WizGlobals.iPlatform == PLATFORM_WEBBLADE ) {
  481. if( iPlatformType != WEBBLADE ) {
  482. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_NOT_WEBBLADE_FILES );
  483. return( FALSE );
  484. }
  485. }
  486. else if( WizGlobals.iPlatform == PLATFORM_ENTERPRISE ) {
  487. if( iPlatformType != ENTERPRISE ) {
  488. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_NOT_ENTERPRISE_FILES );
  489. return( FALSE );
  490. }
  491. }
  492. else {
  493. //
  494. // If we get to this page, the product install type has to be either
  495. // workstation or server.
  496. //
  497. AssertMsg( FALSE, "Bad product install type." );
  498. }
  499. }
  500. else {
  501. INT iRet;
  502. iRet = ReportErrorId( hwnd,
  503. MSGTYPE_YESNO,
  504. IDS_ERR_CANNOT_DETERMINE_PRODUCT );
  505. if( iRet == IDNO ) {
  506. return( FALSE );
  507. }
  508. }
  509. return( TRUE );
  510. }
  511. //----------------------------------------------------------------------------
  512. //
  513. // Function: RecurseDirectories
  514. //
  515. // Purpose:
  516. //
  517. // Arguments:
  518. //
  519. // Returns:
  520. //
  521. //----------------------------------------------------------------------------
  522. static VOID
  523. RecurseDirectories( IN HWND hwnd, IN OUT LPTSTR RootBuffer, IN DWORD cbSize )
  524. {
  525. LPTSTR RootPathEnd = RootBuffer + lstrlen( RootBuffer );
  526. HANDLE FindHandle;
  527. WIN32_FIND_DATA FindData;
  528. TCHAR szOriginalPath[MAX_PATH + 1] = _T("");
  529. //
  530. // Backup the original path so it can be restored later
  531. //
  532. lstrcpyn( szOriginalPath, RootBuffer, AS(szOriginalPath) );
  533. //
  534. // Look for * in this dir
  535. //
  536. if( ! ConcatenatePaths( RootBuffer, _T("*") , NULL) )
  537. {
  538. //
  539. // Restore the original path before returning
  540. //
  541. lstrcpyn( RootBuffer, szOriginalPath, cbSize );
  542. return;
  543. }
  544. FindHandle = FindFirstFile( RootBuffer, &FindData );
  545. if( FindHandle == INVALID_HANDLE_VALUE )
  546. {
  547. //
  548. // Restore the original path before returning
  549. //
  550. lstrcpyn( RootBuffer, szOriginalPath, cbSize );
  551. return;
  552. }
  553. do {
  554. *RootPathEnd = _T('\0');
  555. //
  556. // skip over the . and .. entries
  557. //
  558. if( 0 == lstrcmp( FindData.cFileName, _T("." ) ) ||
  559. 0 == lstrcmp( FindData.cFileName, _T("..") ) )
  560. {
  561. continue;
  562. }
  563. if( LSTRCMPI( FindData.cFileName, _T("dosnet.inf") ) == 0 )
  564. {
  565. AddNameToNameList( &DosnetPaths, RootBuffer );
  566. }
  567. else if( FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  568. {
  569. //
  570. // If this is a dirent, recurse.
  571. //
  572. if( ! ConcatenatePaths( RootBuffer, FindData.cFileName, NULL ) )
  573. {
  574. continue;
  575. }
  576. RecurseDirectories( hwnd, RootBuffer, cbSize);
  577. }
  578. } while ( FindNextFile( FindHandle, &FindData ) );
  579. *RootPathEnd = _T('\0');
  580. FindClose( FindHandle );
  581. //
  582. // Restore the original path
  583. //
  584. lstrcpyn( RootBuffer, szOriginalPath, cbSize );
  585. }
  586. //----------------------------------------------------------------------------
  587. //
  588. // Function: FindWindowsSourceFilesPaths
  589. //
  590. // Purpose: Find all the dirs on the CD that contain dosnet.inf. If there
  591. // is more than one pop-up a dialog and have the user pick one.
  592. //
  593. // Arguments:
  594. //
  595. // Returns:
  596. //
  597. //----------------------------------------------------------------------------
  598. static BOOL
  599. FindWindowsSourceFilesPaths( IN HWND hwnd, LPTSTR PathBuffer, DWORD cbSize )
  600. {
  601. TCHAR *pDosnetPath;
  602. RecurseDirectories( hwnd, PathBuffer, cbSize );
  603. if( GetNameListSize( &DosnetPaths ) > 1 )
  604. {
  605. if( DialogBox( FixedGlobals.hInstance,
  606. MAKEINTRESOURCE( IDD_MULTIPLE_DOSNET_POPUP ),
  607. hwnd,
  608. MultipleDosnetDlg ) )
  609. {
  610. lstrcpyn( PathBuffer, szDosnetPath, cbSize );
  611. return( TRUE );
  612. }
  613. else
  614. {
  615. return( FALSE );
  616. }
  617. }
  618. else
  619. {
  620. pDosnetPath = GetNameListName( &DosnetPaths, 0 );
  621. lstrcpyn( PathBuffer, pDosnetPath, cbSize );
  622. if ( PathBuffer[0] )
  623. return(TRUE);
  624. else
  625. return(FALSE);
  626. }
  627. }
  628. //----------------------------------------------------------------------------
  629. //
  630. // Function: GetCdPath
  631. //
  632. // Purpose: Figures out the full pathname of the NT source files on the CD.
  633. //
  634. // Arguments:
  635. // HWND hwnd - current dialog
  636. //
  637. // Returns:
  638. // TRUE if all is ok
  639. // FALSE if errors, Don't let wizard proceed
  640. //
  641. // WizGlobals.CdSourcePath will contain the valid path to the source
  642. // files on success.
  643. //
  644. // Note, we don't override CopySourcePath because it displays to the
  645. // user. He shouldn't see a CD path appear in this edit field when
  646. // choosing to "Copy from CD".
  647. //
  648. // Notes:
  649. // - We look only at the 1st cd drive we find
  650. // - We figure out i386 or alpha based on what is in the drive
  651. //
  652. //----------------------------------------------------------------------------
  653. BOOL GetCdPath(HWND hwnd)
  654. {
  655. TCHAR DriveLetters[MAX_PATH], *p, *pEnd, PathBuffer[MAX_PATH + 1];
  656. int i;
  657. TCHAR *pProductName;
  658. if( WizGlobals.iPlatform == PLATFORM_SERVER )
  659. pProductName = StrServerCdName;
  660. else
  661. pProductName = StrWorkStationCdName;
  662. //
  663. // Find the CD-ROM
  664. //
  665. // GetLogicalDriveStrings() fills in the DriveLetters buffer, and it
  666. // looks like:
  667. //
  668. // c:\(null)d:\(null)x:\(null)(null)
  669. //
  670. // (i.e. double-null at the end)
  671. //
  672. // ISSUE-2002/02/28-stelo- only checks the first CD-ROM drive on this machine
  673. if ( ! GetLogicalDriveStrings(MAX_PATH, DriveLetters) )
  674. DriveLetters[0] = _T('\0');
  675. p = DriveLetters;
  676. while ( *p ) {
  677. if ( GetDriveType(p) == DRIVE_CDROM ) {
  678. lstrcpyn(PathBuffer, p, AS(PathBuffer));
  679. break;
  680. }
  681. while ( *p++ );
  682. }
  683. //
  684. // No cd-rom drive on this machine
  685. //
  686. // ISSUE-2002/02/28-stelo- We should check this earlier and grey out the choice
  687. // if there isn't a CD-ROM drive on the machine. And btw,
  688. // what happens if I connect to a CD over the net???
  689. //
  690. if ( PathBuffer[0] == _T('\0') ) {
  691. ReportErrorId(hwnd, MSGTYPE_ERR, IDS_ERR_NO_CDROM_DRIVE);
  692. return FALSE;
  693. }
  694. /*
  695. //
  696. // We now have D:\ (or E:\ etc) in PathBuffer.
  697. //
  698. // We need to look for and find either:
  699. // d:\i386\dosnet.inf
  700. // d:\alpha\dosnet.inf
  701. //
  702. // Look for both of these files and stop when you find one.
  703. //
  704. pEnd = PathBuffer + lstrlen(PathBuffer);
  705. for ( i=0; i<2; i++ ) {
  706. if ( i == 0 )
  707. lstrcpy(pEnd, I386_DOSNET);
  708. else
  709. lstrcpy(pEnd, ALPHA_DOSNET);
  710. if ( GetFileAttributes(PathBuffer) != (DWORD) -1 )
  711. break;
  712. }
  713. //
  714. // Add the platform
  715. //
  716. if ( i == 0 ) {
  717. lstrcpy(pEnd, I386_DIR);
  718. }
  719. else if ( i == 1 ) {
  720. lstrcpy(pEnd, ALPHA_DIR);
  721. }
  722. else {
  723. ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_INSERT_CD, pProductName );
  724. return( FALSE );
  725. }
  726. */
  727. if( ! FindWindowsSourceFilesPaths( hwnd, PathBuffer, AS(PathBuffer) ) )
  728. {
  729. ReportErrorId(hwnd,
  730. MSGTYPE_ERR,
  731. IDS_ERR_NOTWINDOWSCD);
  732. return( FALSE );
  733. }
  734. lstrcpyn( WizGlobals.CdSourcePath, PathBuffer, AS(WizGlobals.CdSourcePath) );
  735. return( TRUE );
  736. }
  737. //----------------------------------------------------------------------------
  738. //
  739. // Function: OnWizNextCopyFiles1
  740. //
  741. // Purpose: Called when user pushes the NEXT button.
  742. //
  743. //----------------------------------------------------------------------------
  744. BOOL OnWizNextCopyFiles1(HWND hwnd)
  745. {
  746. TCHAR PathBuffer[MAX_PATH];
  747. TCHAR szFilesPath[MAX_PATH] = _T("");
  748. BOOL bStayHere = FALSE;
  749. TCHAR *lpszArchitecture = NULL;
  750. //
  751. // Get the control settings
  752. //
  753. WizGlobals.bCopyFromPath = IsDlgButtonChecked(hwnd, IDC_COPYFROMPATH);
  754. SendDlgItemMessage(hwnd,
  755. IDT_SOURCEPATH,
  756. WM_GETTEXT,
  757. (WPARAM) MAX_PATH,
  758. (LPARAM) WizGlobals.CopySourcePath);
  759. //
  760. // If dosnet.inf doesn't exist, this isn't a good path to the source files
  761. //
  762. if ( WizGlobals.bCopyFromPath ) {
  763. if ( WizGlobals.CopySourcePath[0] == _T('\0') ) {
  764. ReportErrorId(hwnd, MSGTYPE_ERR, IDS_ERR_ENTER_SETUP_PATH);
  765. bStayHere = TRUE;
  766. goto FinishUp;
  767. }
  768. //
  769. // If it is a UNC path, prepend \\?\UNC\ to the front of the path
  770. //
  771. if( WizGlobals.CopySourcePath[0] == _T('\\') &&
  772. WizGlobals.CopySourcePath[1] == _T('\\') )
  773. {
  774. lstrcpyn( szFilesPath, _T("\\\\?\\UNC\\"), AS(szFilesPath) );
  775. //
  776. // Make sure user has access to the share by attempting to
  777. // connect to it
  778. //
  779. if( ! CanConnectToNetworkShare( WizGlobals.CopySourcePath ) )
  780. {
  781. bStayHere = TRUE;
  782. goto FinishUp;
  783. }
  784. }
  785. ConcatenatePaths( szFilesPath, WizGlobals.CopySourcePath, NULL );
  786. lstrcpyn( PathBuffer, szFilesPath, AS(PathBuffer) );
  787. ConcatenatePaths( PathBuffer, _T("dosnet.inf"), NULL );
  788. if ( ! DoesFileExist(PathBuffer) ) {
  789. ReportErrorId(hwnd,
  790. MSGTYPE_ERR,
  791. IDS_ERR_NOT_PRODUCT,
  792. WizGlobals.CopySourcePath);
  793. bStayHere = TRUE;
  794. goto FinishUp;
  795. }
  796. } else {
  797. if ( ! GetCdPath(hwnd) ) {
  798. bStayHere = TRUE;
  799. goto FinishUp;
  800. }
  801. lstrcpyn( szFilesPath, WizGlobals.CdSourcePath, AS(szFilesPath) );
  802. }
  803. if( ! IsCorrectNtVersion( hwnd, szFilesPath ) )
  804. {
  805. bStayHere = TRUE;
  806. goto FinishUp;
  807. }
  808. FinishUp:
  809. // Figure out the architecture (i.e. i386 or alpha) from the SrcPath
  810. // The SrcPath will be something like d:\i386, or \\net\share\foo\bar\i386
  811. // so we just need to strip off the last part of the path string, and append
  812. // it to the dest path
  813. lpszArchitecture = szFilesPath + lstrlen(szFilesPath) - 1;
  814. while ((lpszArchitecture >= szFilesPath) && (*lpszArchitecture != _T('\\')) )
  815. lpszArchitecture--;
  816. // Move forward 1, to get to the next char after the backslash
  817. lpszArchitecture++;
  818. lstrcpyn (WizGlobals.Architecture, lpszArchitecture, AS(WizGlobals.Architecture));
  819. //
  820. // Free the memory in the DosnetPaths namelist
  821. //
  822. ResetNameList( &DosnetPaths );
  823. return ( !bStayHere );
  824. }
  825. //----------------------------------------------------------------------------
  826. //
  827. // Function: DlgCopyFile1Page
  828. //
  829. // Purpose: Dialog procedure for the IDD_COPYFILES1 page
  830. //
  831. //----------------------------------------------------------------------------
  832. INT_PTR CALLBACK DlgCopyFiles1Page(
  833. IN HWND hwnd,
  834. IN UINT uMsg,
  835. IN WPARAM wParam,
  836. IN LPARAM lParam)
  837. {
  838. BOOL bStatus = TRUE;
  839. BOOL bStayHere = FALSE;
  840. switch (uMsg) {
  841. case WM_INITDIALOG:
  842. StrServerCdName = MyLoadString(IDS_SERVER_CD_NAME);
  843. StrWorkStationCdName = MyLoadString(IDS_WORKSTATION_CD_NAME);
  844. break;
  845. case WM_COMMAND:
  846. {
  847. int nButtonId=LOWORD(wParam);
  848. switch ( nButtonId ) {
  849. case IDC_COPYFROMCD:
  850. case IDC_COPYFROMPATH:
  851. if ( HIWORD(wParam) == BN_CLICKED )
  852. OnRadioButtonCopyFiles1(hwnd, nButtonId);
  853. break;
  854. case IDC_BROWSE:
  855. if ( HIWORD(wParam) == BN_CLICKED )
  856. OnBrowseCopyFiles1(hwnd);
  857. break;
  858. default:
  859. bStatus = FALSE;
  860. break;
  861. }
  862. }
  863. break;
  864. case WM_NOTIFY:
  865. {
  866. LPNMHDR pnmh = (LPNMHDR)lParam;
  867. switch( pnmh->code ) {
  868. case PSN_QUERYCANCEL:
  869. WIZ_CANCEL(hwnd);
  870. break;
  871. case PSN_SETACTIVE:
  872. g_App.dwCurrentHelp = IDH_LOC_SETUP;
  873. if ( (WizGlobals.iProductInstall != PRODUCT_UNATTENDED_INSTALL) ||
  874. WizGlobals.bStandAloneScript )
  875. WIZ_SKIP( hwnd );
  876. else
  877. OnSetActiveCopyFiles1(hwnd);
  878. break;
  879. case PSN_WIZBACK:
  880. bStatus = FALSE;
  881. break;
  882. case PSN_WIZNEXT:
  883. if ( !OnWizNextCopyFiles1(hwnd) )
  884. WIZ_FAIL(hwnd);
  885. else
  886. bStatus = FALSE;
  887. break;
  888. case PSN_HELP:
  889. WIZ_HELP();
  890. break;
  891. default:
  892. bStatus = FALSE;
  893. break;
  894. }
  895. }
  896. break;
  897. default:
  898. bStatus = FALSE;
  899. break;
  900. }
  901. return bStatus;
  902. }