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.

1830 lines
38 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. newvol.cxx
  7. This file contains the definition of NEW_VOLUME_DIALOG.
  8. History:
  9. NarenG 11/18/92 Modified SHARE_DIALOG_BASE for
  10. AFPMGR
  11. */
  12. extern "C"
  13. {
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <ntseapi.h>
  17. #include <nturtl.h>
  18. }
  19. #define INCL_WINDOWS_GDI
  20. #define INCL_WINDOWS
  21. #define INCL_DOSERRORS
  22. #define INCL_NET
  23. #define INCL_NETERRORS
  24. #define INCL_NETSHARE
  25. #define INCL_NETSERVER
  26. #define INCL_NETCONS
  27. #define INCL_NETLIB
  28. #define INCL_NETUSE
  29. #define INCL_NETSHARE
  30. #include <lmui.hxx>
  31. #define INCL_BLT_WINDOW
  32. #define INCL_BLT_DIALOG
  33. #define INCL_BLT_CONTROL
  34. #define INCL_BLT_MISC
  35. #define INCL_BLT_CLIENT
  36. #define INCL_BLT_MSGPOPUP
  37. #define INCL_BLT_SPIN_GROUP
  38. #define INCL_BLT_GROUP
  39. #include <blt.hxx>
  40. #include <lmodev.hxx>
  41. #include <lmoshare.hxx>
  42. #include <string.hxx>
  43. #include <uitrace.hxx>
  44. #include <dbgstr.hxx>
  45. #include <netname.hxx>
  46. extern "C"
  47. {
  48. #include <mnet.h>
  49. #include <afpmgr.h>
  50. #include <macfile.h>
  51. extern APIERR ConvertRedirectedDriveToLocal( NLS_STR nlsServer,
  52. NLS_STR * pnlsDrive,
  53. NLS_STR * pnlsPath );
  54. extern BOOL IsDriveGreaterThan2Gig( LPWSTR lpwsVolPath,
  55. APIERR * perr );
  56. }
  57. #include "util.hxx"
  58. #include "perms.hxx"
  59. #include "newvol.hxx"
  60. /*******************************************************************
  61. NAME: NEW_VOLUME_SRVMGR_DIALOG::NEW_VOLUME_SRVMGR_DIALOG
  62. SYNOPSIS: Constructor for NEW_VOLUME_SRVMGR_DIALOG class
  63. ENTRY: hwndParent - handle of parent window
  64. EXIT:
  65. RETURNS:
  66. NOTES:
  67. HISTORY:
  68. NarenG 11/18/92 Modified for AFPMGR
  69. ********************************************************************/
  70. NEW_VOLUME_SRVMGR_DIALOG::NEW_VOLUME_SRVMGR_DIALOG(
  71. HWND hwndParent,
  72. AFP_SERVER_HANDLE hServer,
  73. const TCHAR * pszServerName )
  74. : DIALOG_WINDOW ( MAKEINTRESOURCE(IDD_NEW_VOLUME_DIALOG), hwndParent ),
  75. _sleVolumeName( this, IDNV_SLE_NAME, AFP_VOLNAME_LEN ),
  76. _sleVolumePath( this, IDNV_SLE_PATH ),
  77. _slePassword( this, IDNV_SLE_PASSWORD, AFP_VOLPASS_LEN ),
  78. _slePasswordConfirm( this, IDNV_SLE_CONFIRM_PASSWORD, AFP_VOLPASS_LEN ),
  79. _chkReadOnly( this, IDNV_CHK_READONLY ),
  80. _chkGuestAccess( this, IDNV_CHK_GUEST_ACCESS ),
  81. _mgrpUserLimit( this, IDNV_RB_UNLIMITED, 2, IDNV_RB_UNLIMITED),
  82. _spsleUsers( this, IDNV_SLE_USERS,1,1,AFP_VOLUME_UNLIMITED_USES-1,
  83. TRUE,IDNV_SLE_USERS_GROUP),
  84. _spgrpUsers(this,IDNV_SB_USERS_GROUP,IDNV_SB_USERS_UP,IDNV_SB_USERS_DOWN),
  85. _pbPermissions( this, IDNV_PB_PERMISSIONS ),
  86. _pbOK( this, IDOK ),
  87. _pbCancel( this, IDCANCEL ),
  88. _nlsOwner(),
  89. _nlsGroup(),
  90. _hServer( hServer ),
  91. _nlsServerName( pszServerName ),
  92. _fCommitDirInfo( FALSE )
  93. {
  94. AUTO_CURSOR Cursor;
  95. //
  96. // Make sure everything constructed OK
  97. //
  98. if ( QueryError() != NERR_Success )
  99. return;
  100. APIERR err;
  101. if ( ((err = _mgrpUserLimit.QueryError()) != NERR_Success )
  102. || ((err = _spgrpUsers.AddAssociation( &_spsleUsers )) != NERR_Success )
  103. || ((err = _mgrpUserLimit.AddAssociation( IDNV_RB_USERS, &_spgrpUsers ))
  104. != NERR_Success )
  105. || ((err = _chkReadOnly.QueryError()) != NERR_Success )
  106. || ((err = _chkGuestAccess.QueryError()) != NERR_Success )
  107. || ((err = _nlsServerName.QueryError()) != NERR_Success )
  108. || ((err = _nlsOwner.QueryError()) != NERR_Success )
  109. || ((err = _nlsGroup.QueryError()) != NERR_Success )
  110. )
  111. {
  112. ReportError( err );
  113. return;
  114. }
  115. //
  116. // Set the caption
  117. //
  118. err = ::SetCaption( this, IDS_CAPTION_CREATE_VOLUME, pszServerName );
  119. if ( err != NO_ERROR )
  120. {
  121. ReportError( err );
  122. return;
  123. }
  124. //
  125. // Set the defaults
  126. //
  127. _chkReadOnly.SetCheck( FALSE );
  128. _chkGuestAccess.SetCheck( TRUE );
  129. _mgrpUserLimit.SetSelection( IDNV_RB_UNLIMITED );
  130. _pbPermissions.Enable( FALSE );
  131. }
  132. /*******************************************************************
  133. NAME: NEW_VOLUME_SRVMGR_DIALOG::OnCommand
  134. SYNOPSIS: Handle the case where the user clicked the permission button
  135. ENTRY: event - the CONTROL_EVENT that occurred
  136. EXIT:
  137. RETURNS:
  138. NOTES:
  139. HISTORY:
  140. NarenG 11/18/92 Modified for AFPMGR
  141. ********************************************************************/
  142. BOOL NEW_VOLUME_SRVMGR_DIALOG::OnCommand( const CONTROL_EVENT &event )
  143. {
  144. APIERR err;
  145. if ( event.QueryCid() == IDNV_PB_PERMISSIONS )
  146. {
  147. AUTO_CURSOR Cursor;
  148. //
  149. // Get the volume path and validate it.
  150. //
  151. NLS_STR nlsDisplayPath;
  152. NLS_STR nlsVolumePath;
  153. BOOL fOk;
  154. if ((( err = nlsVolumePath.QueryError() ) != NERR_Success ) ||
  155. (( err = nlsDisplayPath.QueryError() ) != NERR_Success ) ||
  156. (( err = _sleVolumePath.QueryText(&nlsDisplayPath))
  157. != NERR_Success ))
  158. {
  159. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  160. return FALSE;
  161. }
  162. //
  163. // Validate the path.
  164. //
  165. NET_NAME netname( nlsDisplayPath.QueryPch() );
  166. if ( ( err = netname.QueryError() ) != NERR_Success )
  167. {
  168. ::MsgPopup( this, err );
  169. SetFocusOnPath();
  170. return FALSE;
  171. }
  172. if ( netname.QueryType() == TYPE_PATH_UNC )
  173. {
  174. ::MsgPopup( this, IDS_TYPE_LOCAL_PATH );
  175. SetFocusOnPath();
  176. return TRUE;
  177. }
  178. nlsVolumePath.CopyFrom( nlsDisplayPath );
  179. _fCommitDirInfo = TRUE;
  180. DIRECTORY_PERMISSIONS_DLG *pdlg = new DIRECTORY_PERMISSIONS_DLG(
  181. QueryHwnd(),
  182. _hServer,
  183. _nlsServerName.QueryPch(),
  184. TRUE,
  185. nlsVolumePath.QueryPch(),
  186. nlsDisplayPath.QueryPch(),
  187. FALSE,
  188. &_nlsOwner,
  189. &_nlsGroup,
  190. &_dwPerms );
  191. if ( ( pdlg == NULL )
  192. || (( err = pdlg->QueryError()) != NERR_Success )
  193. || (( err = pdlg->Process( &fOk )) != NERR_Success )
  194. )
  195. {
  196. err = (pdlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY : err;
  197. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  198. }
  199. delete pdlg;
  200. if ( ( err != NERR_Success ) || ( !fOk ) )
  201. {
  202. _fCommitDirInfo = FALSE;
  203. }
  204. return TRUE;
  205. }
  206. //
  207. // Enable the permissions button if the path string is filled in.
  208. //
  209. if ( event.QueryCid() == IDNV_SLE_PATH )
  210. {
  211. if ( event.QueryCode() == EN_CHANGE )
  212. {
  213. if ( _sleVolumePath.QueryTextLength() > 0 )
  214. {
  215. _pbOK.MakeDefault();
  216. _pbPermissions.Enable( TRUE );
  217. }
  218. else
  219. {
  220. _pbPermissions.Enable( FALSE );
  221. _pbCancel.MakeDefault();
  222. }
  223. }
  224. return TRUE;
  225. }
  226. return DIALOG_WINDOW::OnCommand( event );
  227. }
  228. /*******************************************************************
  229. NAME: NEW_VOLUME_SRVMGR_DIALOG::OnOK
  230. SYNOPSIS: Validate all the information and create the volume.
  231. ENTRY:
  232. EXIT:
  233. RETURNS:
  234. NOTES:
  235. HISTORY:
  236. NarenG 11/18/92 Modified for AFPMGR
  237. ********************************************************************/
  238. BOOL NEW_VOLUME_SRVMGR_DIALOG::OnOK( VOID )
  239. {
  240. APIERR err;
  241. NLS_STR nlsVolumePath;
  242. NLS_STR nlsVolumeName;
  243. NLS_STR nlsPassword;
  244. NLS_STR nlsPasswordConfirm;
  245. WCHAR szVolPath[CNLEN+6];
  246. WCHAR *wchTemp;
  247. AUTO_CURSOR Cursor;
  248. //
  249. // This is not a loop.
  250. //
  251. do {
  252. //
  253. // Get the volume name.
  254. //
  255. if ( ( err = nlsVolumeName.QueryError() ) != NERR_Success )
  256. break;
  257. if ((err = _sleVolumeName.QueryText( &nlsVolumeName )) != NERR_Success)
  258. break;
  259. //
  260. // Get the volume path.
  261. //
  262. if ( ( err = nlsVolumePath.QueryError() ) != NERR_Success )
  263. break;
  264. if (( err = _sleVolumePath.QueryText(&nlsVolumePath)) != NERR_Success)
  265. break;
  266. //
  267. // Get the password if there is one.
  268. //
  269. if ( ( err = nlsPassword.QueryError() ) != NERR_Success )
  270. break;
  271. if ( ( err = _slePassword.QueryText( &nlsPassword )) != NERR_Success )
  272. break;
  273. //
  274. // Get the password confirmation.
  275. //
  276. if ( ( err = nlsPasswordConfirm.QueryError() ) != NERR_Success )
  277. break;
  278. if ( ( err = _slePasswordConfirm.QueryText( &nlsPasswordConfirm ))
  279. != NERR_Success )
  280. break;
  281. }while( FALSE );
  282. if ( err != NERR_Success )
  283. {
  284. ::MsgPopup( this, err );
  285. return TRUE;
  286. }
  287. //
  288. // Set up the volume structure
  289. //
  290. AFP_VOLUME_INFO AfpVolume;
  291. if ( nlsVolumeName.strlen() > 0 )
  292. {
  293. //
  294. // Validate the volume name
  295. //
  296. ISTR istr( nlsVolumeName );
  297. if ( nlsVolumeName.strchr( &istr, TEXT(':') ) )
  298. {
  299. ::MsgPopup( this, IDS_AFPERR_InvalidVolumeName );
  300. SetFocusOnName();
  301. return FALSE;
  302. }
  303. AfpVolume.afpvol_name = (LPWSTR)(nlsVolumeName.QueryPch());
  304. }
  305. else
  306. {
  307. ::MsgPopup( this, IDS_NEED_VOLUME_NAME );
  308. SetFocusOnName();
  309. return TRUE;
  310. }
  311. //
  312. // Validate the path.
  313. //
  314. NET_NAME netname( nlsVolumePath.QueryPch() );
  315. if ( ( err = netname.QueryError() ) != NERR_Success )
  316. {
  317. ::MsgPopup( this, err );
  318. SetFocusOnPath();
  319. return TRUE;
  320. }
  321. if ( netname.QueryType() == TYPE_PATH_UNC )
  322. {
  323. ::MsgPopup( this, IDS_TYPE_LOCAL_PATH );
  324. SetFocusOnPath();
  325. return TRUE;
  326. }
  327. ::wcscpy(szVolPath, _nlsServerName.QueryPch());
  328. wchTemp = szVolPath + wcslen(szVolPath);
  329. *wchTemp++ = TEXT('\\');
  330. *wchTemp++ = (nlsVolumePath.QueryPch())[0];
  331. *wchTemp++ = TEXT('$');
  332. *wchTemp++ = TEXT('\\');
  333. *wchTemp++ = 0;
  334. BOOL fDriveGreaterThan2Gig = ::IsDriveGreaterThan2Gig( (LPWSTR)(szVolPath), &err );
  335. if ( err != NERR_Success )
  336. {
  337. ::MsgPopup( this, err );
  338. SetFocusOnPath();
  339. return TRUE;
  340. }
  341. if ( fDriveGreaterThan2Gig )
  342. {
  343. if ( ::MsgPopup( this,
  344. IDS_VOLUME_TOO_BIG,
  345. MPSEV_WARNING,
  346. MP_YESNO,
  347. MP_NO ) == IDNO )
  348. {
  349. SetFocusOnPath();
  350. return TRUE;
  351. }
  352. }
  353. AfpVolume.afpvol_path = (LPWSTR)(nlsVolumePath.QueryPch());
  354. //
  355. // Make sure the passwords match.
  356. //
  357. if ( nlsPassword.strcmp( nlsPasswordConfirm ) )
  358. {
  359. ::MsgPopup( this, IDS_PASSWORD_MISMATCH );
  360. SetFocusOnPasswordConfirm();
  361. return TRUE;
  362. }
  363. if ( nlsPassword.strlen() > 0 )
  364. {
  365. AfpVolume.afpvol_password = (LPWSTR)(nlsPassword.QueryPch());
  366. }
  367. else
  368. {
  369. AfpVolume.afpvol_password = (LPWSTR)NULL;
  370. }
  371. AfpVolume.afpvol_props_mask = _chkReadOnly.QueryCheck()
  372. ? AFP_VOLUME_READONLY
  373. : 0;
  374. AfpVolume.afpvol_props_mask = _chkGuestAccess.QueryCheck()
  375. ? (AFP_VOLUME_GUESTACCESS | AfpVolume.afpvol_props_mask)
  376. : AfpVolume.afpvol_props_mask;
  377. AfpVolume.afpvol_max_uses = QueryUserLimit();
  378. //
  379. // Try to create the volume.
  380. //
  381. err = ::AfpAdminVolumeAdd( _hServer, (LPBYTE)&AfpVolume );
  382. if ( err != NO_ERROR )
  383. {
  384. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  385. SetFocusOnPath();
  386. return FALSE;
  387. }
  388. //
  389. // If the user mucked around with the root directory's permissions
  390. // the we have to set it.
  391. //
  392. if ( _fCommitDirInfo )
  393. {
  394. AFP_DIRECTORY_INFO AfpDirInfo;
  395. AfpDirInfo.afpdir_path = (LPWSTR)nlsVolumePath.QueryPch();
  396. AfpDirInfo.afpdir_owner = (LPWSTR)_nlsOwner.QueryPch();
  397. AfpDirInfo.afpdir_group = (LPWSTR)_nlsGroup.QueryPch();
  398. AfpDirInfo.afpdir_perms = _dwPerms;
  399. err = ::AfpAdminDirectorySetInfo( _hServer,
  400. (LPBYTE)&AfpDirInfo,
  401. AFP_DIR_PARMNUM_ALL );
  402. }
  403. else
  404. {
  405. //
  406. // User did not muck arount with the permissions, so we have
  407. // to get and reset the current permissions. This is requred
  408. // to remove everyone as the owner.
  409. //
  410. PAFP_DIRECTORY_INFO pAfpDirInfo;
  411. err = ::AfpAdminDirectoryGetInfo( _hServer,
  412. (LPWSTR)nlsVolumePath.QueryPch(),
  413. (LPBYTE*)&pAfpDirInfo );
  414. if ( err == NO_ERROR )
  415. {
  416. DWORD dwParmNum = AFP_DIR_PARMNUM_PERMS;
  417. pAfpDirInfo->afpdir_path = (LPWSTR)(nlsVolumePath.QueryPch());
  418. if ( pAfpDirInfo->afpdir_owner != (LPWSTR)NULL )
  419. {
  420. dwParmNum |= AFP_DIR_PARMNUM_OWNER;
  421. }
  422. if ( pAfpDirInfo->afpdir_group != (LPWSTR)NULL )
  423. {
  424. dwParmNum |= AFP_DIR_PARMNUM_GROUP;
  425. }
  426. err = ::AfpAdminDirectorySetInfo( _hServer,
  427. (LPBYTE)pAfpDirInfo,
  428. dwParmNum );
  429. ::AfpAdminBufferFree( pAfpDirInfo );
  430. }
  431. }
  432. switch( err )
  433. {
  434. case NO_ERROR:
  435. case AFPERR_SecurityNotSupported:
  436. Dismiss( TRUE );
  437. break;
  438. case AFPERR_NoSuchUser:
  439. case AFPERR_NoSuchGroup:
  440. case AFPERR_NoSuchUserGroup:
  441. case ERROR_NONE_MAPPED:
  442. ::MsgPopup( this, IDS_INVALID_DIR_ACCOUNT, MPSEV_INFO );
  443. Dismiss( TRUE );
  444. break;
  445. case AFPERR_UnsupportedFS:
  446. //
  447. // Ignore this error
  448. //
  449. Dismiss( TRUE );
  450. break;
  451. default:
  452. ::AfpAdminVolumeDelete( _hServer, (LPWSTR)(nlsVolumeName.QueryPch()));
  453. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  454. break;
  455. }
  456. return TRUE;
  457. }
  458. /*******************************************************************
  459. NAME: NEW_VOLUME_SRVMGR_DIALOG::QueryUserLimit
  460. SYNOPSIS: Get the user limit from the magic group
  461. ENTRY:
  462. EXIT:
  463. RETURNS: The user limit stored in the user limit magic group
  464. NOTES:
  465. HISTORY:
  466. NarenG 11/18/92 Modified for AFPMGR
  467. ********************************************************************/
  468. DWORD NEW_VOLUME_SRVMGR_DIALOG::QueryUserLimit( VOID ) const
  469. {
  470. switch ( _mgrpUserLimit.QuerySelection() )
  471. {
  472. case IDNV_RB_UNLIMITED:
  473. return( AFP_VOLUME_UNLIMITED_USES );
  474. case IDNV_RB_USERS:
  475. return( _spsleUsers.QueryValue() );
  476. default:
  477. //
  478. // Should never get here but in case we do, return unlimited
  479. //
  480. return( AFP_VOLUME_UNLIMITED_USES );
  481. }
  482. }
  483. /*******************************************************************
  484. NAME: NEW_VOLUME_SRVMGR_DIALOG::QueryHelpContext
  485. SYNOPSIS: Query the help context of the dialog
  486. ENTRY:
  487. EXIT:
  488. RETURNS: Return the help context of the dialog
  489. NOTES:
  490. HISTORY:
  491. NarenG 11/18/92 Modified for AFPMGR
  492. ********************************************************************/
  493. ULONG NEW_VOLUME_SRVMGR_DIALOG::QueryHelpContext( VOID )
  494. {
  495. return HC_NEW_VOLUME_SRVMGR_DIALOG;
  496. }
  497. /*******************************************************************
  498. NAME: NEW_VOLUME_FILEMGR_DIALOG::NEW_VOLUME_FILEMGR_DIALOG
  499. SYNOPSIS: Constructor for NEW_VOLUME_FILEMGR_DIALOG class
  500. ENTRY: hwndParent - handle of parent window
  501. EXIT:
  502. RETURNS:
  503. NOTES:
  504. HISTORY:
  505. NarenG 11/18/92 Modified for AFPMGR
  506. ********************************************************************/
  507. NEW_VOLUME_FILEMGR_DIALOG::NEW_VOLUME_FILEMGR_DIALOG(
  508. HWND hwndParent,
  509. const TCHAR * pszPath,
  510. BOOL fIsFile )
  511. : DIALOG_WINDOW ( MAKEINTRESOURCE(IDD_NEW_VOLUME_DIALOG), hwndParent ),
  512. _sleVolumeName( this, IDNV_SLE_NAME, AFP_VOLNAME_LEN ),
  513. _sleVolumePath( this, IDNV_SLE_PATH ),
  514. _slePassword( this, IDNV_SLE_PASSWORD, AFP_VOLPASS_LEN ),
  515. _slePasswordConfirm( this, IDNV_SLE_CONFIRM_PASSWORD, AFP_VOLPASS_LEN ),
  516. _chkReadOnly( this, IDNV_CHK_READONLY ),
  517. _chkGuestAccess( this, IDNV_CHK_GUEST_ACCESS ),
  518. _mgrpUserLimit( this, IDNV_RB_UNLIMITED, 2, IDNV_RB_UNLIMITED),
  519. _spsleUsers( this, IDNV_SLE_USERS,1,1,AFP_VOLUME_UNLIMITED_USES-1,
  520. TRUE,IDNV_SLE_USERS_GROUP),
  521. _spgrpUsers(this,IDNV_SB_USERS_GROUP,IDNV_SB_USERS_UP,IDNV_SB_USERS_DOWN),
  522. _pbPermissions( this, IDNV_PB_PERMISSIONS ),
  523. _pbOK( this, IDOK ),
  524. _pbCancel( this, IDCANCEL ),
  525. _nlsOwner(),
  526. _nlsGroup(),
  527. _fCommitDirInfo( FALSE )
  528. {
  529. AUTO_CURSOR Cursor;
  530. //
  531. // Make sure everything constructed OK
  532. //
  533. if ( QueryError() != NERR_Success )
  534. return;
  535. APIERR err;
  536. if ( ((err = _mgrpUserLimit.QueryError()) != NERR_Success )
  537. || ((err = _spgrpUsers.AddAssociation( &_spsleUsers )) != NERR_Success )
  538. || ((err = _mgrpUserLimit.AddAssociation( IDNV_RB_USERS, &_spgrpUsers ))
  539. != NERR_Success )
  540. || ((err = _chkReadOnly.QueryError()) != NERR_Success )
  541. || ((err = _chkGuestAccess.QueryError()) != NERR_Success )
  542. || ((err = _nlsOwner.QueryError()) != NERR_Success )
  543. || ((err = _nlsGroup.QueryError()) != NERR_Success )
  544. )
  545. {
  546. ReportError( err );
  547. return;
  548. }
  549. //
  550. // Set the defaults
  551. //
  552. _chkReadOnly.SetCheck( FALSE );
  553. _chkGuestAccess.SetCheck( TRUE );
  554. _mgrpUserLimit.SetSelection( IDNV_RB_UNLIMITED );
  555. _pbPermissions.Enable( FALSE );
  556. //
  557. // Set the volumename and path if the path drive is NTFS
  558. //
  559. NLS_STR nlsVolumePath( pszPath );
  560. NLS_STR nlsVolumeName;
  561. NLS_STR nlsUNCPath;
  562. if ( (( err = nlsVolumePath.QueryError() ) != NERR_Success ) ||
  563. (( err = nlsVolumeName.QueryError() ) != NERR_Success ) ||
  564. (( err = nlsUNCPath.QueryError() ) != NERR_Success ) )
  565. {
  566. ReportError( err );
  567. return;
  568. }
  569. err = ValidateVolumePath( nlsVolumePath.QueryPch() );
  570. if ( ( err != NO_ERROR ) && ( err != AFPERR_UnsupportedFS ) )
  571. {
  572. ReportError( err );
  573. return;
  574. }
  575. //
  576. // If the drive is an NTFS/CDFS drive, then set the volume name and path
  577. //
  578. if ( err == NO_ERROR )
  579. {
  580. //
  581. // If this is a file then we need to remove the file name from the
  582. // path.
  583. //
  584. if ( fIsFile )
  585. {
  586. ISTR istrVolumePath( nlsVolumePath );
  587. if ( nlsVolumePath.strrchr( &istrVolumePath, TEXT('\\') ))
  588. {
  589. nlsVolumePath.DelSubStr( istrVolumePath );
  590. }
  591. }
  592. //
  593. // Extract the last component of the path and use it to set the
  594. // volume name
  595. //
  596. nlsVolumeName = nlsVolumePath;
  597. ISTR istrStart( nlsVolumeName );
  598. ISTR istrEnd( nlsVolumeName );
  599. if ( nlsVolumeName.strrchr( &istrEnd, TEXT('\\') ))
  600. {
  601. nlsVolumeName.DelSubStr( istrStart, ++istrEnd );
  602. }
  603. if ( nlsVolumeName.QueryTextLength() <= AFP_VOLNAME_LEN )
  604. _sleVolumeName.SetText( nlsVolumeName );
  605. //
  606. // Ok, if the drive is remote then we need to display the UNC path
  607. //
  608. NET_NAME netname( nlsVolumePath );
  609. if ( ( err = netname.QueryError() ) != NERR_Success )
  610. {
  611. ReportError( err );
  612. return;
  613. }
  614. BOOL fIsLocal = netname.IsLocal( &err );
  615. if ( err != NERR_Success )
  616. {
  617. ReportError( err );
  618. return;
  619. }
  620. if ( fIsLocal )
  621. {
  622. _sleVolumePath.SetText( nlsVolumePath );
  623. }
  624. else
  625. {
  626. if ( ( err = netname.QueryUNCPath( &nlsUNCPath ) ) != NERR_Success )
  627. {
  628. ReportError( err );
  629. return;
  630. }
  631. _sleVolumePath.SetText( nlsUNCPath );
  632. }
  633. _pbPermissions.Enable( TRUE );
  634. _sleVolumeName.SelectString();
  635. SetFocusOnName();
  636. }
  637. }
  638. /*******************************************************************
  639. NAME: NEW_VOLUME_FILEMGR_DIALOG::OnCommand
  640. SYNOPSIS: Handle the case where the user clicked the permission button
  641. ENTRY: event - the CONTROL_EVENT that occurred
  642. EXIT:
  643. RETURNS:
  644. NOTES:
  645. HISTORY:
  646. NarenG 11/18/92 Modified for AFPMGR
  647. ********************************************************************/
  648. BOOL NEW_VOLUME_FILEMGR_DIALOG::OnCommand( const CONTROL_EVENT &event )
  649. {
  650. APIERR err;
  651. AFP_SERVER_HANDLE hServer = NULL;
  652. if ( event.QueryCid() == IDNV_PB_PERMISSIONS )
  653. {
  654. AUTO_CURSOR Cursor;
  655. //
  656. // Get the volume path and validate it.
  657. //
  658. NLS_STR nlsDisplayPath;
  659. NLS_STR nlsVolumePath;
  660. NLS_STR nlsComputerName;
  661. NLS_STR nlsDrive;
  662. BOOL fOk;
  663. if ((( err = nlsVolumePath.QueryError() ) != NERR_Success ) ||
  664. (( err = nlsComputerName.QueryError() ) != NERR_Success ) ||
  665. (( err = nlsDrive.QueryError() ) != NERR_Success ) ||
  666. (( err = nlsDisplayPath.QueryError() ) != NERR_Success ) ||
  667. (( err = _sleVolumePath.QueryText(&nlsDisplayPath))
  668. != NERR_Success ))
  669. {
  670. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  671. return FALSE;
  672. }
  673. //
  674. // If the path is not local then we need to get the local
  675. // path.
  676. //
  677. NET_NAME netname( nlsDisplayPath.QueryPch() );
  678. if ( ( err = netname.QueryError() ) != NERR_Success )
  679. {
  680. ::MsgPopup( this, err );
  681. return FALSE;
  682. }
  683. BOOL fIsLocal = netname.IsLocal( &err );
  684. if ( err != NERR_Success )
  685. {
  686. ::MsgPopup( this, err );
  687. return FALSE;
  688. }
  689. //
  690. // Get the computer name for this volume
  691. //
  692. if ((err = netname.QueryComputerName(&nlsComputerName)) != NERR_Success)
  693. {
  694. if ( err == NERR_InvalidDevice )
  695. {
  696. err = ERROR_INVALID_DRIVE;
  697. }
  698. ::MsgPopup( this, err );
  699. return FALSE;
  700. }
  701. if ((!fIsLocal) || (fIsLocal && (netname.QueryType() == TYPE_PATH_UNC)))
  702. {
  703. //
  704. // If the path is remote get the absolute path with
  705. // the drive letter.
  706. //
  707. err = netname.QueryLocalPath( &nlsVolumePath );
  708. if ( err != NERR_Success )
  709. {
  710. ::MsgPopup( this, err );
  711. SetFocusOnPath();
  712. return FALSE;
  713. }
  714. }
  715. else
  716. {
  717. //
  718. // If the path happens to be a loopback redirected drive then we
  719. // replace
  720. // the redirected drive with the action drive.
  721. //
  722. if ( (err = netname.QueryDrive( &nlsDrive )) != NERR_Success )
  723. {
  724. ::MsgPopup( this, err );
  725. SetFocusOnPath();
  726. return TRUE;
  727. }
  728. nlsVolumePath.CopyFrom( nlsDisplayPath );
  729. if ( (err=::ConvertRedirectedDriveToLocal(
  730. nlsComputerName,
  731. &nlsDrive,
  732. &nlsVolumePath ))!= NERR_Success )
  733. {
  734. ::MsgPopup( this, err );
  735. SetFocusOnPath();
  736. return FALSE;
  737. }
  738. }
  739. if ( ( err = ::AfpAdminConnect((LPWSTR)(nlsComputerName.QueryPch()),
  740. &hServer ) ) != NO_ERROR )
  741. {
  742. ::MsgPopup( this, err );
  743. SetFocusOnPath();
  744. return FALSE;
  745. }
  746. _fCommitDirInfo = TRUE;
  747. DIRECTORY_PERMISSIONS_DLG *pdlg = new DIRECTORY_PERMISSIONS_DLG(
  748. QueryHwnd(),
  749. hServer,
  750. NULL,
  751. FALSE,
  752. nlsVolumePath.QueryPch(),
  753. nlsDisplayPath.QueryPch(),
  754. FALSE,
  755. &_nlsOwner,
  756. &_nlsGroup,
  757. &_dwPerms );
  758. if ( ( pdlg == NULL )
  759. || (( err = pdlg->QueryError()) != NERR_Success )
  760. || (( err = pdlg->Process( &fOk )) != NERR_Success )
  761. )
  762. {
  763. err = (pdlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY : err;
  764. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  765. }
  766. delete pdlg;
  767. if ( ( err != NERR_Success ) || ( !fOk ) )
  768. {
  769. _fCommitDirInfo = FALSE;
  770. }
  771. if ( hServer != NULL )
  772. {
  773. ::AfpAdminDisconnect( hServer );
  774. }
  775. return TRUE;
  776. }
  777. //
  778. // Enable the permissions button if the path string is filled in.
  779. //
  780. if ( event.QueryCid() == IDNV_SLE_PATH )
  781. {
  782. if ( event.QueryCode() == EN_CHANGE )
  783. {
  784. if ( _sleVolumePath.QueryTextLength() > 0 )
  785. {
  786. _pbOK.MakeDefault();
  787. _pbPermissions.Enable( TRUE );
  788. }
  789. else
  790. {
  791. _pbPermissions.Enable( FALSE );
  792. _pbCancel.MakeDefault();
  793. }
  794. }
  795. return TRUE;
  796. }
  797. return DIALOG_WINDOW::OnCommand( event );
  798. }
  799. /*******************************************************************
  800. NAME: NEW_VOLUME_FILEMGR_DIALOG::OnOK
  801. SYNOPSIS: Validate all the information and create the volume.
  802. ENTRY:
  803. EXIT:
  804. RETURNS:
  805. NOTES:
  806. HISTORY:
  807. NarenG 11/18/92 Modified for AFPMGR
  808. ********************************************************************/
  809. BOOL NEW_VOLUME_FILEMGR_DIALOG::OnOK( VOID )
  810. {
  811. APIERR err;
  812. NLS_STR nlsVolumePath;
  813. NLS_STR nlsVolumeName;
  814. NLS_STR nlsPassword;
  815. NLS_STR nlsPasswordConfirm;
  816. NLS_STR nlsComputerName;
  817. NLS_STR nlsDrive;
  818. AFP_SERVER_HANDLE hServer = NULL;
  819. AUTO_CURSOR Cursor;
  820. //
  821. // This is not a loop.
  822. //
  823. do {
  824. if ( ( err = nlsComputerName.QueryError() ) != NERR_Success )
  825. break;
  826. if ( ( err = nlsDrive.QueryError() ) != NERR_Success )
  827. break;
  828. //
  829. // Get the volume name.
  830. //
  831. if ( ( err = nlsVolumeName.QueryError() ) != NERR_Success )
  832. break;
  833. if ((err = _sleVolumeName.QueryText( &nlsVolumeName )) != NERR_Success)
  834. break;
  835. //
  836. // Get the volume path.
  837. //
  838. if ( ( err = nlsVolumePath.QueryError() ) != NERR_Success )
  839. break;
  840. if (( err = _sleVolumePath.QueryText(&nlsVolumePath)) != NERR_Success)
  841. break;
  842. //
  843. // Get the password if there is one.
  844. //
  845. if ( ( err = nlsPassword.QueryError() ) != NERR_Success )
  846. break;
  847. if ( ( err = _slePassword.QueryText( &nlsPassword )) != NERR_Success )
  848. break;
  849. //
  850. // Get the password confirmation.
  851. //
  852. if ( ( err = nlsPasswordConfirm.QueryError() ) != NERR_Success )
  853. break;
  854. if ( ( err = _slePasswordConfirm.QueryText( &nlsPasswordConfirm ))
  855. != NERR_Success )
  856. break;
  857. }while( FALSE );
  858. if ( err != NERR_Success )
  859. {
  860. ::MsgPopup( this, err );
  861. return TRUE;
  862. }
  863. //
  864. // Set up the volume structure
  865. //
  866. AFP_VOLUME_INFO AfpVolume;
  867. if ( nlsVolumeName.strlen() > 0 )
  868. {
  869. //
  870. // Validate the volume name
  871. //
  872. ISTR istr( nlsVolumeName );
  873. if ( nlsVolumeName.strchr( &istr, TEXT(':') ) )
  874. {
  875. ::MsgPopup( this, IDS_AFPERR_InvalidVolumeName );
  876. SetFocusOnName();
  877. return FALSE;
  878. }
  879. AfpVolume.afpvol_name = (LPWSTR)(nlsVolumeName.QueryPch());
  880. }
  881. else
  882. {
  883. ::MsgPopup( this, IDS_NEED_VOLUME_NAME );
  884. SetFocusOnName();
  885. return TRUE;
  886. }
  887. //
  888. // If the path is not local then we need to get the local
  889. // path.
  890. //
  891. NET_NAME netname( nlsVolumePath.QueryPch() );
  892. if ( ( err = netname.QueryError() ) != NERR_Success )
  893. {
  894. ::MsgPopup( this, err );
  895. SetFocusOnPath();
  896. return TRUE;
  897. }
  898. BOOL fIsLocal = netname.IsLocal( &err );
  899. if ( err != NERR_Success )
  900. {
  901. ::MsgPopup( this, err );
  902. SetFocusOnPath();
  903. return TRUE;
  904. }
  905. if ( (err = netname.QueryComputerName( &nlsComputerName )) != NERR_Success)
  906. {
  907. if ( err == NERR_InvalidDevice )
  908. {
  909. err = ERROR_INVALID_DRIVE;
  910. }
  911. ::MsgPopup( this, err );
  912. SetFocusOnPath();
  913. return FALSE;
  914. }
  915. BOOL fDriveGreaterThan2Gig = ::IsDriveGreaterThan2Gig( (LPWSTR)(nlsVolumePath.QueryPch()),
  916. &err );
  917. if ( err != NERR_Success )
  918. {
  919. ::MsgPopup( this, err );
  920. SetFocusOnPath();
  921. return TRUE;
  922. }
  923. if ( (!fIsLocal) || (fIsLocal && (netname.QueryType() == TYPE_PATH_UNC)))
  924. {
  925. //
  926. // If the path is remote then get the absolute path and drive letter.
  927. //
  928. err = netname.QueryLocalPath( &nlsVolumePath );
  929. if ( err != NERR_Success )
  930. {
  931. ::MsgPopup( this, err );
  932. SetFocusOnPath();
  933. return FALSE;
  934. }
  935. }
  936. else
  937. {
  938. //
  939. // If the path happens to be a loopback redirected drive then we
  940. // replace
  941. // the redirected drive with the action drive.
  942. //
  943. if ( (err = netname.QueryDrive( &nlsDrive )) != NERR_Success )
  944. {
  945. ::MsgPopup( this, err );
  946. SetFocusOnPath();
  947. return TRUE;
  948. }
  949. if ( (err=::ConvertRedirectedDriveToLocal(
  950. nlsComputerName,
  951. &nlsDrive,
  952. &nlsVolumePath )) != NERR_Success )
  953. {
  954. ::MsgPopup( this, err );
  955. SetFocusOnPath();
  956. return FALSE;
  957. }
  958. }
  959. if ( fDriveGreaterThan2Gig )
  960. {
  961. if ( ::MsgPopup( this,
  962. IDS_VOLUME_TOO_BIG,
  963. MPSEV_WARNING,
  964. MP_YESNO,
  965. MP_NO ) == IDNO )
  966. {
  967. SetFocusOnPath();
  968. return TRUE;
  969. }
  970. }
  971. AfpVolume.afpvol_path = (LPWSTR)(nlsVolumePath.QueryPch());
  972. if ( nlsPassword.strcmp( nlsPasswordConfirm ) )
  973. {
  974. ::MsgPopup( this, IDS_PASSWORD_MISMATCH );
  975. SetFocusOnPasswordConfirm();
  976. return TRUE;
  977. }
  978. if ( nlsPassword.strlen() > 0 )
  979. {
  980. AfpVolume.afpvol_password = (LPWSTR)(nlsPassword.QueryPch());
  981. }
  982. else
  983. {
  984. AfpVolume.afpvol_password = (LPWSTR)NULL;
  985. }
  986. AfpVolume.afpvol_props_mask = _chkReadOnly.QueryCheck()
  987. ? AFP_VOLUME_READONLY
  988. : 0;
  989. AfpVolume.afpvol_props_mask = _chkGuestAccess.QueryCheck()
  990. ? (AFP_VOLUME_GUESTACCESS | AfpVolume.afpvol_props_mask)
  991. : AfpVolume.afpvol_props_mask;
  992. AfpVolume.afpvol_max_uses = QueryUserLimit();
  993. //
  994. // Try to create the volume.
  995. //
  996. err = ::AfpAdminConnect((LPWSTR)(nlsComputerName.QueryPch()), &hServer );
  997. if ( err == NO_ERROR )
  998. {
  999. err = ::AfpAdminVolumeAdd( hServer, (LPBYTE)&AfpVolume );
  1000. }
  1001. if ( err == NO_ERROR )
  1002. {
  1003. //
  1004. // If the user mucked around with the root directory's permissions
  1005. // the we have to set it.
  1006. //
  1007. if ( _fCommitDirInfo )
  1008. {
  1009. AFP_DIRECTORY_INFO AfpDirInfo;
  1010. AfpDirInfo.afpdir_path = (LPWSTR)(nlsVolumePath.QueryPch());
  1011. AfpDirInfo.afpdir_owner = (LPWSTR)(_nlsOwner.QueryPch());
  1012. AfpDirInfo.afpdir_group = (LPWSTR)(_nlsGroup.QueryPch());
  1013. AfpDirInfo.afpdir_perms = _dwPerms;
  1014. err = ::AfpAdminDirectorySetInfo( hServer,
  1015. (LPBYTE)&AfpDirInfo,
  1016. AFP_DIR_PARMNUM_ALL );
  1017. }
  1018. else
  1019. {
  1020. //
  1021. // User did not muck arount with the permissions, so we have
  1022. // to get and reset the current permissions. This is requred
  1023. // to remove everyone as the owner.
  1024. //
  1025. PAFP_DIRECTORY_INFO pAfpDirInfo;
  1026. err = ::AfpAdminDirectoryGetInfo(hServer,
  1027. (LPWSTR)(nlsVolumePath.QueryPch()),
  1028. (LPBYTE*)&pAfpDirInfo );
  1029. if ( err == NO_ERROR )
  1030. {
  1031. DWORD dwParmNum = AFP_DIR_PARMNUM_PERMS;
  1032. pAfpDirInfo->afpdir_path = (LPWSTR)(nlsVolumePath.QueryPch());
  1033. if ( pAfpDirInfo->afpdir_owner != (LPWSTR)NULL )
  1034. {
  1035. dwParmNum |= AFP_DIR_PARMNUM_OWNER;
  1036. }
  1037. if ( pAfpDirInfo->afpdir_group != (LPWSTR)NULL )
  1038. {
  1039. dwParmNum |= AFP_DIR_PARMNUM_GROUP;
  1040. }
  1041. err = ::AfpAdminDirectorySetInfo( hServer,
  1042. (LPBYTE)pAfpDirInfo,
  1043. dwParmNum );
  1044. ::AfpAdminBufferFree( pAfpDirInfo );
  1045. }
  1046. }
  1047. switch( err )
  1048. {
  1049. case NO_ERROR:
  1050. break;
  1051. case AFPERR_SecurityNotSupported:
  1052. err = NO_ERROR;
  1053. break;
  1054. case AFPERR_NoSuchUser:
  1055. case AFPERR_NoSuchGroup:
  1056. case AFPERR_NoSuchUserGroup:
  1057. case ERROR_NONE_MAPPED:
  1058. err = NO_ERROR;
  1059. ::MsgPopup( this, IDS_INVALID_DIR_ACCOUNT, MPSEV_INFO );
  1060. break;
  1061. case AFPERR_UnsupportedFS:
  1062. //
  1063. // Ignore this error
  1064. //
  1065. err = NO_ERROR;
  1066. break;
  1067. default:
  1068. ::AfpAdminVolumeDelete( hServer,
  1069. (LPWSTR)(nlsVolumeName.QueryPch()));
  1070. break;
  1071. }
  1072. }
  1073. if ( hServer != NULL )
  1074. {
  1075. ::AfpAdminDisconnect( hServer );
  1076. }
  1077. if ( err == NO_ERROR )
  1078. {
  1079. Dismiss( TRUE );
  1080. }
  1081. else
  1082. {
  1083. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  1084. SetFocusOnPath();
  1085. }
  1086. return TRUE;
  1087. }
  1088. /*******************************************************************
  1089. NAME: NEW_VOLUME_FILEGMR_DIALOG::QueryUserLimit
  1090. SYNOPSIS: Get the user limit from the magic group
  1091. ENTRY:
  1092. EXIT:
  1093. RETURNS: The user limit stored in the user limit magic group
  1094. NOTES:
  1095. HISTORY:
  1096. NarenG 11/18/92 Modified for AFPMGR
  1097. ********************************************************************/
  1098. DWORD NEW_VOLUME_FILEMGR_DIALOG::QueryUserLimit( VOID ) const
  1099. {
  1100. switch ( _mgrpUserLimit.QuerySelection() )
  1101. {
  1102. case IDNV_RB_UNLIMITED:
  1103. return( AFP_VOLUME_UNLIMITED_USES );
  1104. case IDNV_RB_USERS:
  1105. return( _spsleUsers.QueryValue() );
  1106. default:
  1107. //
  1108. // Should never get here but in case we do, return unlimited
  1109. //
  1110. return( AFP_VOLUME_UNLIMITED_USES );
  1111. }
  1112. }
  1113. /*******************************************************************
  1114. NAME: NEW_VOLUME_FILEMGR_DIALOG::ValidateVolumePath
  1115. SYNOPSIS: Validates the volume path. It makes sure that the
  1116. the path syntax is valid and the volume of the drive
  1117. is either NTFS or CDFS.
  1118. ENTRY: pszPath - Pointer to the volume path
  1119. EXIT:
  1120. RETURNS: Any error encountered. (Path syntax is invalid etc)
  1121. NOTES:
  1122. HISTORY:
  1123. NarenG 11/18/92 Modified for AFPMGR
  1124. ********************************************************************/
  1125. DWORD NEW_VOLUME_FILEMGR_DIALOG::ValidateVolumePath( const WCHAR * pszPath )
  1126. {
  1127. WCHAR wchDrive[5];
  1128. DWORD dwMaxCompSize;
  1129. DWORD dwFlags;
  1130. WCHAR wchFileSystem[10];
  1131. DWORD err = NO_ERROR;
  1132. NET_NAME Path( pszPath );
  1133. if ( ( err = Path.QueryError() ) != NERR_Success )
  1134. {
  1135. return err;
  1136. }
  1137. // Get the drive letter, : and backslash
  1138. //
  1139. ::ZeroMemory( wchDrive, sizeof( wchDrive ) );
  1140. ::wcsncpy( wchDrive, pszPath, 3 );
  1141. if ( !( ::GetVolumeInformation( (LPWSTR)wchDrive,
  1142. NULL,
  1143. 0,
  1144. NULL,
  1145. &dwMaxCompSize,
  1146. &dwFlags,
  1147. (LPWSTR)wchFileSystem,
  1148. sizeof( wchFileSystem ) ) ) ){
  1149. return GetLastError();
  1150. }
  1151. if ( ( ::_wcsicmp( wchFileSystem, SZ("NTFS") ) == 0 ) ||
  1152. ( ::_wcsicmp( wchFileSystem, SZ("CDFS") ) == 0 ) ||
  1153. ( ::_wcsicmp( wchFileSystem, SZ("AHFS") ) == 0 ) )
  1154. return( NO_ERROR );
  1155. else
  1156. return( (DWORD)AFPERR_UnsupportedFS );
  1157. }
  1158. /*******************************************************************
  1159. NAME: NEW_VOLUME_FILEMGR_DIALOG::QueryHelpContext
  1160. SYNOPSIS: Query the help context of the dialog
  1161. ENTRY:
  1162. EXIT:
  1163. RETURNS: Return the help context of the dialog
  1164. NOTES:
  1165. HISTORY:
  1166. NarenG 11/18/92 Modified for AFPMGR
  1167. ********************************************************************/
  1168. ULONG NEW_VOLUME_FILEMGR_DIALOG::QueryHelpContext( VOID )
  1169. {
  1170. return HC_NEW_VOLUME_FILEMGR_DIALOG;
  1171. }
  1172. /*******************************************************************
  1173. NAME: ::ConvertRedirectedDriveToLocal
  1174. SYNOPSIS: Determines if a drive is a loopback redirected drive or
  1175. not. If it is, then the redirected drive is changed to
  1176. the local drive.
  1177. ENTRY:
  1178. EXIT:
  1179. RETURNS: NERR_Success - Success
  1180. Non zero return codes - failure
  1181. NOTES:
  1182. HISTORY:
  1183. NarenG 11/18/92 Modified for AFPMGR
  1184. ********************************************************************/
  1185. APIERR ConvertRedirectedDriveToLocal( NLS_STR nlsServer,
  1186. NLS_STR * pnlsDrive,
  1187. NLS_STR * pnlsPath )
  1188. {
  1189. PBYTE pBuf;
  1190. APIERR err;
  1191. NLS_STR nlsDrive;
  1192. if ( ( err = nlsDrive.QueryError() ) != NERR_Success )
  1193. {
  1194. return err;
  1195. }
  1196. err = ::MNetUseGetInfo(nlsServer.QueryPch(),pnlsDrive->QueryPch(),1,&pBuf);
  1197. if ( err != NERR_Success )
  1198. {
  1199. if ( err == NERR_UseNotFound )
  1200. return NERR_Success;
  1201. else
  1202. return err;
  1203. }
  1204. NET_NAME netname( ((PUSE_INFO_0)pBuf)->ui0_remote );
  1205. ::MNetApiBufferFree( &pBuf );
  1206. if ( ( err = netname.QueryError() ) != NERR_Success )
  1207. {
  1208. return err;
  1209. }
  1210. if ( ( err = netname.QueryLocalPath( pnlsPath ) ) != NERR_Success )
  1211. {
  1212. return err;
  1213. }
  1214. return( NERR_Success );
  1215. }
  1216. /*******************************************************************
  1217. NAME: ::IsDriveGreaterThan2Gig
  1218. SYNOPSIS: Determines if the disk is bigger than 2Gig. If it, return
  1219. TRUE so that a warning can be displayed to the user
  1220. RETURNS: TRUE if disk is larger than 2Gig
  1221. FALSE otherwise
  1222. HISTORY:
  1223. NarenG 11/18/92 Modified for AFPMGR
  1224. ********************************************************************/
  1225. BOOL IsDriveGreaterThan2Gig( LPWSTR lpwsVolPath,
  1226. APIERR * perr )
  1227. {
  1228. DWORD SectorsPerCluster;
  1229. DWORD BytesPerSector;
  1230. DWORD NumberOfFreeClusters;
  1231. DWORD TotalNumberOfClusters;
  1232. LARGE_INTEGER DriveSize;
  1233. LARGE_INTEGER TwoGig = { MAXLONG, 0 };
  1234. LPWSTR lpwsPath;
  1235. LPWSTR lpwsTmp;
  1236. //
  1237. // If this drive volume is greater than 2G then we print warning
  1238. //
  1239. *perr = NERR_Success;
  1240. lpwsPath = (LPWSTR)::LocalAlloc( LPTR, (::wcslen(lpwsVolPath) + 2)*sizeof(WCHAR));
  1241. if (lpwsPath == NULL)
  1242. {
  1243. *perr = ERROR_NOT_ENOUGH_MEMORY;
  1244. return( TRUE );
  1245. }
  1246. ::wcscpy(lpwsPath, lpwsVolPath);
  1247. // if this is a unc path of the type \\foo\bar\path\name then we must
  1248. // generate a string that is "\\foo\bar\"
  1249. if ( lpwsPath[0] == TEXT('\\') && lpwsPath[1] == TEXT('\\'))
  1250. {
  1251. lpwsTmp = lpwsPath;
  1252. lpwsTmp++;
  1253. lpwsTmp++; // point to f in \\foo\bar\path\name
  1254. lpwsTmp = ::wcschr(lpwsTmp, TEXT('\\'));
  1255. lpwsTmp++; // point to b in \\foo\bar\path\name
  1256. lpwsTmp = ::wcschr(lpwsTmp, TEXT('\\'));
  1257. // if the path is \\foo\bar\path\name then
  1258. if (lpwsTmp != NULL)
  1259. {
  1260. lpwsTmp++;
  1261. }
  1262. // else if the path is just \\foo\bar then
  1263. else
  1264. {
  1265. lpwsTmp = lpwsPath + ::wcslen(lpwsPath);
  1266. if ( *(lpwsTmp-1) != TEXT('\\'))
  1267. {
  1268. *lpwsTmp = TEXT('\\');
  1269. lpwsTmp++;
  1270. }
  1271. }
  1272. *(lpwsTmp) = 0;
  1273. }
  1274. // else if this is a local path of the type c:\foo\bar\path\name then
  1275. // we must generate a string that is "c:\"
  1276. else if (lpwsPath[1] == TEXT(':'))
  1277. {
  1278. lpwsPath[2] = TEXT('\\');
  1279. lpwsPath[3] = 0;
  1280. }
  1281. // huh?? how did this happen?
  1282. else
  1283. {
  1284. *perr = ERROR_INVALID_DRIVE;
  1285. ::LocalFree(lpwsPath);
  1286. return( TRUE );
  1287. }
  1288. if ( !::GetDiskFreeSpace( lpwsPath,
  1289. &SectorsPerCluster,
  1290. &BytesPerSector,
  1291. &NumberOfFreeClusters,
  1292. &TotalNumberOfClusters
  1293. ))
  1294. {
  1295. ::LocalFree(lpwsPath);
  1296. // call failed: it's not fatal, treat it like disk size is ok
  1297. return FALSE;
  1298. }
  1299. ::LocalFree(lpwsPath);
  1300. DriveSize = RtlEnlargedIntegerMultiply( SectorsPerCluster * BytesPerSector,
  1301. TotalNumberOfClusters ) ;
  1302. if ( DriveSize.QuadPart > TwoGig.QuadPart )
  1303. {
  1304. return TRUE;
  1305. }
  1306. else
  1307. {
  1308. return FALSE;
  1309. }
  1310. }
  1311.