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.

1574 lines
40 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. * sharebas.cxx
  7. * This file contains the definitions of base share dialog class,
  8. * and some common classes used by the share dialogs,
  9. * including SHARE_DIALOG_BASE, SHARE_LEVEL_PERMISSIONS_DIALOG,
  10. * PERMISSION_GROUP, SHARE_NAME_WITH_PATH_ENUM_ITER,
  11. * SERVER_WITH_PASSWORD_PROMPT and SHARE_NET_NAME.
  12. *
  13. * History:
  14. * Yi-HsinS 8/15/91 Created
  15. * Yi-HsinS 11/15/91 Changed all USHORT to UINT
  16. * Yi-HsinS 12/5/91 Test more thoroughly for invalid
  17. * path name
  18. * Yi-HsinS 12/6/91 Uses NET_NAME
  19. * Yi-HsinS 12/31/91 Unicode work
  20. * Yi-HsinS 1/8/92 Moved SHARE_PROPERTIES_BASE to
  21. * sharewnp.cxx
  22. * Yi-HsinS 3/12/92 Added ACCESS_PERM to PERMISSIONS_GROUP
  23. * Terryk 4/12/92 Change USER limit from UINT to ULONG
  24. * Yi-HsinS 4/21/92 Remove unnecessay code, and remove
  25. * _uiSpecialUserLimit
  26. * Yi-HsinS 5/15/92 Make password dialog show up only if
  27. * focus on share-level servers
  28. * Yi-HsinS 8/6/92 Reorganize to match Winball dialogs.
  29. * ChuckC 8/12/92 Added support for ACLs on Shares.
  30. * Yi-HsinS 11/16/92 Removed SLT_ADMININFO
  31. * YiHsinS 4/2/93 Disable viewing/changing permission on special
  32. * shares ( [A-Z]$, IPC$, ADMIN$ )
  33. */
  34. #define INCL_WINDOWS_GDI
  35. #define INCL_WINDOWS
  36. #define INCL_DOSERRORS
  37. #define INCL_NETERRORS
  38. #define INCL_NETSHARE
  39. #define INCL_NETSERVER
  40. #define INCL_NETWKSTA
  41. #define INCL_NETLIB
  42. #include <lmui.hxx>
  43. extern "C"
  44. {
  45. #include <sharedlg.h>
  46. #include <helpnums.h>
  47. }
  48. #define INCL_BLT_DIALOG
  49. #define INCL_BLT_CONTROL
  50. #define INCL_BLT_MSGPOPUP
  51. #define INCL_BLT_SPIN_GROUP
  52. #define INCL_BLT_GROUP
  53. #include <blt.hxx>
  54. #include <string.hxx>
  55. #include <uitrace.hxx>
  56. #include <dbgstr.hxx>
  57. #include <lmoesh.hxx>
  58. #include <lmoeusr.hxx>
  59. #include <lmosrv.hxx>
  60. #include <lmoshare.hxx>
  61. #include <lmowks.hxx>
  62. #include <strchlit.hxx> // for string and character constants
  63. #include "sharebas.hxx"
  64. #include <shareacl.hxx> // for the function prototypes
  65. #define USERS_DEFAULT 10
  66. #define USERS_MIN 1
  67. #define PERM_DEFAULT_LEN 7 // length of "RWCXDAP"
  68. /*******************************************************************
  69. NAME: SHARE_DIALOG_BASE::SHARE_DIALOG_BASE
  70. SYNOPSIS: Constructor for SHARE_DIALOG_BASE class
  71. ENTRY: pszDlgResource - resource name for DIALOG_WINDOW
  72. hwndParent - handle of parent window
  73. ulMaxUserLimit - the maximum user limit to be set
  74. in the user limit spin button
  75. ulHelpContextBase - the base help context
  76. EXIT:
  77. RETURNS:
  78. NOTES:
  79. HISTORY:
  80. Yi-HsinS 8/15/91 Created
  81. Yi-HsinS 1/17/91 Added _uiSpecialUserLimit
  82. Yi-HsinS 4/25/91 Remove _uiSpecialUserLimit
  83. Yi-HsinS 10/9/92 Added _ulHelpContextBase
  84. ********************************************************************/
  85. SHARE_DIALOG_BASE::SHARE_DIALOG_BASE( const TCHAR *pszDlgResource,
  86. HWND hwndParent,
  87. ULONG ulHelpContextBase,
  88. ULONG ulMaxUserLimit )
  89. : DIALOG_WINDOW ( pszDlgResource, hwndParent ),
  90. _slePath( this, SLE_PATH ),
  91. _sleComment( this, SLE_COMMENT, SHARE_COMMENT_LENGTH ),
  92. _mgrpUserLimit( this, RB_UNLIMITED, 2, RB_UNLIMITED), // 2 buttons
  93. _spsleUsers( this, SLE_USERS, USERS_DEFAULT,
  94. USERS_MIN, ulMaxUserLimit - USERS_MIN + 1, TRUE,
  95. FRAME_USERS ),
  96. _spgrpUsers( this, SB_USERS_GROUP, SB_USERS_UP, SB_USERS_DOWN),
  97. _buttonOK( this, IDOK ),
  98. _buttonCancel( this, IDCANCEL ),
  99. _buttonPermissions( this, BUTTON_PERMISSIONS ),
  100. _pStoredSecDesc( NULL ), // default : NULL
  101. _fSecDescModified( FALSE ), // initially unchanged
  102. _nlsStoredPassword(), // default : empty string
  103. _uiStoredPermissions( ACCESS_READ | ACCESS_EXEC ), // default permission
  104. _fStoredAdminOnly( FALSE ),
  105. _ulHelpContextBase( ulHelpContextBase )
  106. {
  107. if ( QueryError() != NERR_Success )
  108. return;
  109. APIERR err;
  110. if ( ((err = _mgrpUserLimit.QueryError()) != NERR_Success )
  111. || ((err = _spgrpUsers.AddAssociation( &_spsleUsers )) != NERR_Success )
  112. || ((err = _mgrpUserLimit.AddAssociation( RB_USERS, &_spgrpUsers ))
  113. != NERR_Success )
  114. || ((err = _nlsStoredPassword.QueryError()) != NERR_Success )
  115. )
  116. {
  117. ReportError( err );
  118. return;
  119. }
  120. }
  121. /*******************************************************************
  122. NAME: SHARE_DIALOG_BASE::~SHARE_DIALOG_BASE
  123. SYNOPSIS: Destructor for SHARE_DIALOG_BASE class
  124. ENTRY:
  125. EXIT:
  126. RETURNS:
  127. NOTES:
  128. HISTORY:
  129. Yi-HsinS 8/15/91 Created
  130. ********************************************************************/
  131. SHARE_DIALOG_BASE::~SHARE_DIALOG_BASE()
  132. {
  133. delete _pStoredSecDesc;
  134. memsetf((LPVOID)_nlsStoredPassword.QueryPch(),
  135. 0,
  136. _nlsStoredPassword.QueryTextSize()) ;
  137. _pStoredSecDesc = NULL;
  138. }
  139. /*******************************************************************
  140. NAME: SHARE_DIALOG_BASE::ClearStoredInfo
  141. SYNOPSIS: Clear the permission or security description stored
  142. internally.
  143. ENTRY:
  144. EXIT:
  145. RETURNS:
  146. NOTES:
  147. HISTORY:
  148. Yi-HsinS 8/6/92 Created
  149. ********************************************************************/
  150. APIERR SHARE_DIALOG_BASE::ClearStoredInfo( VOID )
  151. {
  152. delete _pStoredSecDesc;
  153. _pStoredSecDesc = NULL;
  154. _nlsStoredPassword = EMPTY_STRING;
  155. _uiStoredPermissions = ACCESS_READ | ACCESS_EXEC;
  156. return _nlsStoredPassword.QueryError();
  157. }
  158. /*******************************************************************
  159. NAME: SHARE_DIALOG_BASE::UpdateInfo
  160. SYNOPSIS: Set the information about the share in the dialog
  161. ENTRY: psvr - pointer to the server object that the share is on
  162. pszShare - the share to display
  163. EXIT:
  164. RETURNS:
  165. NOTES:
  166. HISTORY:
  167. Yi-HsinS 8/15/91 Created
  168. ********************************************************************/
  169. APIERR SHARE_DIALOG_BASE::UpdateInfo( SERVER_WITH_PASSWORD_PROMPT *psvr,
  170. const TCHAR *pszShare )
  171. {
  172. AUTO_CURSOR autocur;
  173. UIASSERT( psvr != NULL );
  174. UIASSERT( pszShare != NULL );
  175. APIERR err;
  176. SHARE_2 sh2( pszShare, psvr->QueryName(), FALSE );
  177. if ( ((err = sh2.QueryError() ) == NERR_Success )
  178. && ((err = sh2.GetInfo()) == NERR_Success )
  179. )
  180. {
  181. if ( _slePath.QueryTextLength() == 0
  182. && NULL != sh2.QueryPath() ) // JonN 01/27/00: PREFIX bug 444916
  183. SetPath( sh2.QueryPath() );
  184. SetComment( sh2.QueryComment() );
  185. SetUserLimit( sh2.QueryMaxUses() );
  186. err = UpdatePermissionsInfo( psvr, &sh2, pszShare );
  187. }
  188. return err;
  189. }
  190. /*******************************************************************
  191. NAME: SHARE_DIALOG_BASE::UpdatePermissionsInfo
  192. SYNOPSIS: Set the permissions information about the share
  193. ENTRY: psvr - pointer to the server object that the share is on
  194. psh2 - pointer to an existing SHARE_2 object
  195. pszShare - the share to display
  196. EXIT:
  197. RETURNS:
  198. NOTES:
  199. HISTORY:
  200. JonN 11/22/93 Created
  201. ********************************************************************/
  202. APIERR SHARE_DIALOG_BASE::UpdatePermissionsInfo(
  203. SERVER_WITH_PASSWORD_PROMPT *psvr,
  204. SHARE_2 * psh2,
  205. const TCHAR *pszShare )
  206. {
  207. AUTO_CURSOR autocur;
  208. UIASSERT( psvr != NULL );
  209. UIASSERT( psh2 != NULL );
  210. UIASSERT( pszShare != NULL );
  211. APIERR err = NERR_Success;
  212. if ( psvr->IsNT() )
  213. {
  214. _fSecDescModified = FALSE ;
  215. if ( psh2->IsAdminOnly() ) // There are no security descriptors in
  216. // special shares.
  217. {
  218. delete _pStoredSecDesc;
  219. _pStoredSecDesc = NULL;
  220. _fStoredAdminOnly = TRUE;
  221. }
  222. else
  223. {
  224. _fStoredAdminOnly = FALSE;
  225. err = QuerySharePermissions( psvr->QueryName(),
  226. pszShare,
  227. &_pStoredSecDesc );
  228. }
  229. }
  230. else if ( psvr->IsShareLevel() ) // LM 2.x share-level server
  231. {
  232. _nlsStoredPassword = psh2->QueryPassword();
  233. _uiStoredPermissions = psh2->QueryPermissions();
  234. err = _nlsStoredPassword.QueryError();
  235. }
  236. //
  237. // Do not need to get permissions on LM2.x user-level server
  238. // because it has no permissions for shares.
  239. //
  240. return err;
  241. }
  242. /*******************************************************************
  243. NAME: SHARE_DIALOG_BASE::OnChangeShareProperty
  244. SYNOPSIS: Helper method to change the properties of the share
  245. ENTRY: psvr - pointer the server object that the share is on
  246. pszShare - the share that we want to change properties on
  247. EXIT:
  248. RETURNS:
  249. NOTES:
  250. HISTORY:
  251. Yi-HsinS 8/15/91 Created
  252. ********************************************************************/
  253. APIERR SHARE_DIALOG_BASE::OnChangeShareProperty(
  254. SERVER_WITH_PASSWORD_PROMPT *psvr,
  255. const TCHAR *pszShare )
  256. {
  257. APIERR err;
  258. UIASSERT( psvr != NULL );
  259. UIASSERT( pszShare != NULL );
  260. //
  261. // Get all information about the share
  262. //
  263. SHARE_2 sh2( pszShare, psvr->QueryName(), FALSE);
  264. NLS_STR nlsComment;
  265. do { // Not a loop
  266. if ( ((err = sh2.QueryError() ) != NERR_Success )
  267. || ((err = sh2.GetInfo()) != NERR_Success )
  268. || ((err = nlsComment.QueryError()) != NERR_Success )
  269. )
  270. {
  271. break;
  272. }
  273. //
  274. // Set validation flag to TRUE to enable checking for invalid
  275. // information set to the share object.
  276. //
  277. sh2.SetValidation( TRUE );
  278. //
  279. // Query, validate and set the comment on the share
  280. //
  281. if ( ((err = QueryComment( &nlsComment )) != NERR_Success )
  282. || ((err = sh2.SetComment( nlsComment )) != NERR_Success )
  283. )
  284. {
  285. err = ( err == ERROR_INVALID_PARAMETER ) ?
  286. (APIERR) IERR_SHARE_INVALID_COMMENT : err;
  287. SetFocusOnComment();
  288. break;
  289. }
  290. //
  291. // Set the max uses on the share
  292. //
  293. if ((err = sh2.SetMaxUses( (UINT) QueryUserLimit())) != NERR_Success )
  294. {
  295. SetFocusOnUserLimit();
  296. break;
  297. }
  298. //
  299. // Set the permissions on the share if it's on LM share level servers
  300. //
  301. if ( !psvr->IsNT() && psvr->IsShareLevel() )
  302. {
  303. //
  304. // Upper case the password => same as netcmd
  305. // since Share-level servers are down level servers only
  306. //
  307. _nlsStoredPassword._strupr();
  308. //
  309. // Give a warning if the user wants to change the password
  310. //
  311. if ( ::stricmpf( _nlsStoredPassword, sh2.QueryPassword() ) != 0 )
  312. {
  313. NLS_STR nlsComputer;
  314. if ( ((err = nlsComputer.QueryError()) != NERR_Success )
  315. || ((err = psvr->QueryDisplayName( &nlsComputer ))
  316. != NERR_Success )
  317. )
  318. {
  319. break;
  320. }
  321. if ( ::MsgPopup( this,
  322. (MSGID) IDS_SHARE_PROP_CHANGE_PASSWD_WARN_TEXT,
  323. MPSEV_WARNING, MP_OKCANCEL,
  324. nlsComputer.QueryPch(),
  325. sh2.QueryName(), MP_CANCEL ) == IDCANCEL )
  326. {
  327. //
  328. // User click CANCEL =>
  329. // Reset password to the original value!
  330. //
  331. _nlsStoredPassword = sh2.QueryPassword();
  332. err = IERR_USER_CLICKED_CANCEL;
  333. break;
  334. }
  335. //
  336. // Set the password on the share
  337. //
  338. if (( err = sh2.SetPassword( _nlsStoredPassword ))
  339. != NERR_Success )
  340. break;
  341. }
  342. //
  343. // We are successful up to this point, so set the permissions
  344. //
  345. if ( (err = sh2.SetPermissions( _uiStoredPermissions ))
  346. != NERR_Success )
  347. break;
  348. }
  349. //
  350. // Write the information out
  351. //
  352. if ( (err = sh2.WriteInfo()) != NERR_Success )
  353. break;
  354. //
  355. // If the share is on an NT server and it is not
  356. // a special share, set the permission to it.
  357. //
  358. if ( psvr->IsNT() && !sh2.IsAdminOnly() )
  359. {
  360. err = ApplySharePermissions( sh2.QueryServer(),
  361. sh2.QueryName(),
  362. QueryStoredSecDesc() );
  363. if (err)
  364. break ;
  365. }
  366. // Falls through if error occurs
  367. }
  368. while (FALSE);
  369. return err;
  370. }
  371. /*******************************************************************
  372. NAME: SHARE_DIALOG_BASE::OnCommand
  373. SYNOPSIS: Handle the case where the user clicked the permission button
  374. ENTRY: event - the CONTROL_EVENT that occurred
  375. EXIT:
  376. RETURNS:
  377. NOTES:
  378. HISTORY:
  379. Yi-HsinS 8/6/92 Created
  380. ********************************************************************/
  381. BOOL SHARE_DIALOG_BASE::OnCommand( const CONTROL_EVENT &event )
  382. {
  383. APIERR err = NERR_Success;
  384. if ( event.QueryCid() == BUTTON_PERMISSIONS )
  385. {
  386. OnPermissions();
  387. return TRUE;
  388. }
  389. return DIALOG_WINDOW::OnCommand( event );
  390. }
  391. /*******************************************************************
  392. NAME: SHARE_DIALOG_BASE::OnPermissions
  393. SYNOPSIS: Helper method to popup the permission dialog
  394. when the permission button is clicked
  395. ENTRY:
  396. EXIT:
  397. RETURNS:
  398. NOTES:
  399. HISTORY:
  400. Yi-HsinS 8/6/92 Created
  401. ********************************************************************/
  402. VOID SHARE_DIALOG_BASE::OnPermissions( VOID )
  403. {
  404. AUTO_CURSOR autocur;
  405. //
  406. // Get the server that the share is on
  407. //
  408. SERVER_WITH_PASSWORD_PROMPT *psvr = NULL;
  409. APIERR err = QueryServer2( &psvr );
  410. if ( err == NERR_Success )
  411. {
  412. if ( psvr->IsNT() ) // On NT servers
  413. {
  414. //
  415. // If we are viewing a admin only share,
  416. // we cannot change permission on it.
  417. //
  418. if ( _fStoredAdminOnly )
  419. {
  420. err = IERR_SPECIAL_SHARE_CANNOT_SET_PERMISSIONS;
  421. }
  422. else
  423. {
  424. NLS_STR nlsShare;
  425. if ( ((err = nlsShare.QueryError()) == NERR_Success )
  426. && ((err = QueryShare( &nlsShare )) == NERR_Success )
  427. )
  428. {
  429. err = EditShareAcl( QueryHwnd(),
  430. psvr->QueryName(),
  431. nlsShare.QueryPch(),
  432. &_fSecDescModified,
  433. &_pStoredSecDesc,
  434. QueryHelpContextBase() ) ;
  435. }
  436. }
  437. }
  438. else if ( psvr->IsShareLevel() ) // On LM share-level server
  439. {
  440. SHARE_LEVEL_PERMISSIONS_DIALOG *pdlg =
  441. new SHARE_LEVEL_PERMISSIONS_DIALOG( QueryHwnd(),
  442. &_nlsStoredPassword,
  443. &_uiStoredPermissions,
  444. QueryHelpContextBase() );
  445. if ( ( pdlg == NULL )
  446. || (( pdlg->QueryError()) != NERR_Success )
  447. || (( pdlg->Process()) != NERR_Success )
  448. )
  449. {
  450. err = err? err: ERROR_NOT_ENOUGH_MEMORY;
  451. }
  452. delete pdlg;
  453. }
  454. else // On LM user-level server
  455. {
  456. err = IERR_CANNOT_SET_PERM_ON_LMUSER_SERVER;
  457. }
  458. }
  459. if ( err != NERR_Success )
  460. {
  461. if ( (err == IERR_CANNOT_SET_PERM_ON_LMUSER_SERVER )
  462. || (err == IERR_SPECIAL_SHARE_CANNOT_SET_PERMISSIONS )
  463. )
  464. {
  465. ::MsgPopup( this, err, MPSEV_WARNING );
  466. }
  467. else
  468. {
  469. ::MsgPopup( this, err );
  470. }
  471. }
  472. }
  473. /*******************************************************************
  474. NAME: SHARE_DIALOG_BASE::SetMaxUserLimit
  475. SYNOPSIS: Set the maximum number of users in the spin button
  476. ENTRY: ulMaxUserLimit - the maximum user limit to be set
  477. in the spin button
  478. EXIT:
  479. RETURNS:
  480. NOTES: We need this because the maximum number of users on
  481. LM servers and on NT servers are different.
  482. HISTORY:
  483. Yi-HsinS 1/17/92 Created
  484. ********************************************************************/
  485. APIERR SHARE_DIALOG_BASE::SetMaxUserLimit( ULONG ulMaxUserLimit )
  486. {
  487. APIERR err = NERR_Success;
  488. if (ulMaxUserLimit < _spsleUsers.QueryValue())
  489. {
  490. // the maximum is less than the default, so adjust the default
  491. err = _spsleUsers.SetSaveValue(ulMaxUserLimit);
  492. }
  493. _spsleUsers.SetRange( ulMaxUserLimit - USERS_MIN + 1);
  494. return err;
  495. }
  496. /*******************************************************************
  497. NAME: SHARE_DIALOG_BASE::QueryUserLimit
  498. SYNOPSIS: Get the user limit from the magic group
  499. ENTRY:
  500. EXIT:
  501. RETURNS: The user limit stored in the user limit magic group
  502. NOTES:
  503. HISTORY:
  504. Yi-HsinS 8/15/91 Created
  505. ********************************************************************/
  506. ULONG SHARE_DIALOG_BASE::QueryUserLimit( VOID ) const
  507. {
  508. ULONG ulUserLimit;
  509. switch ( _mgrpUserLimit.QuerySelection() )
  510. {
  511. case RB_UNLIMITED:
  512. ulUserLimit = (ULONG) SHI_USES_UNLIMITED;
  513. break;
  514. case RB_USERS:
  515. // We don't need to check whether the value is valid or not
  516. // because SPIN_BUTTON checks it.
  517. ulUserLimit = _spsleUsers.QueryValue();
  518. UIASSERT( ( ulUserLimit <= _spsleUsers.QueryMax() )
  519. && ( ulUserLimit >= USERS_MIN )
  520. );
  521. break;
  522. default:
  523. UIASSERT(!SZ("User Limit: This shouldn't have happened!\n\r"));
  524. ulUserLimit = (ULONG) SHI_USES_UNLIMITED;
  525. break;
  526. }
  527. return ulUserLimit;
  528. }
  529. /*******************************************************************
  530. NAME: SHARE_DIALOG_BASE::SetUserLimit
  531. SYNOPSIS: Sets the user limit on the magic group
  532. ENTRY: ulUserLimit - maximum number of users allowed
  533. EXIT:
  534. RETURNS: NERR_Success
  535. NOTES: If the limit is invalid, sets it to "Maximum allowed".
  536. HISTORY:
  537. Yi-HsinS 8/15/91 Created
  538. ********************************************************************/
  539. APIERR SHARE_DIALOG_BASE::SetUserLimit( ULONG ulUserLimit )
  540. {
  541. APIERR err = NERR_Success;
  542. if ( ulUserLimit == (ULONG) SHI_USES_UNLIMITED )
  543. {
  544. // Set selection to the Unlimited button
  545. _mgrpUserLimit.SetSelection( RB_UNLIMITED );
  546. ULONG ulMaxUserLimit = _spsleUsers.QueryMax();
  547. ULONG ulNewUserLimit = (ulMaxUserLimit < USERS_DEFAULT) ? ulMaxUserLimit : USERS_DEFAULT;
  548. _spsleUsers.SetSaveValue( ulNewUserLimit );
  549. }
  550. else if ( ( ulUserLimit >= USERS_MIN)
  551. && ( ulUserLimit <= _spsleUsers.QueryMax())
  552. )
  553. {
  554. // Set the Users button
  555. _mgrpUserLimit.SetSelection( RB_USERS );
  556. _spsleUsers.SetValue( ulUserLimit );
  557. _spsleUsers.Update();
  558. }
  559. else
  560. {
  561. // The user limit wasn't in range. Go back and set the share to
  562. // "maximum allowed".
  563. return SetUserLimit((ULONG)SHI_USES_UNLIMITED);
  564. }
  565. return err;
  566. }
  567. /*******************************************************************
  568. NAME: SHARE_DIALOG_BASE::ApplySharePermissions
  569. SYNOPSIS: Sets the NT permissions of a share (security descriptor)
  570. ENTRY: pszServer - the server that the share is on
  571. pszShare - the share that we want to set permissions on
  572. posSecDesc - the security descriptor to be set to the share
  573. EXIT:
  574. RETURNS:
  575. NOTES:
  576. HISTORY:
  577. ChuckC 8/10/92 Created
  578. ********************************************************************/
  579. APIERR SHARE_DIALOG_BASE::ApplySharePermissions( const TCHAR *pszServer,
  580. const TCHAR *pszShare,
  581. const OS_SECURITY_DESCRIPTOR *
  582. posSecDesc)
  583. {
  584. UIASSERT(pszShare) ;
  585. // if nothing changed, no need to set.
  586. if (!_fSecDescModified)
  587. return NERR_Success ;
  588. return ( ::SetSharePerm(pszServer,
  589. pszShare,
  590. posSecDesc) ) ;
  591. }
  592. /*******************************************************************
  593. NAME: SHARE_DIALOG_BASE::QuerySharePermissions
  594. SYNOPSIS: Gets the NT permissions of a share (security descriptor)
  595. ENTRY: pszServer - the server that the share is on
  596. pszShare - the share that we want to set permissions on
  597. EXIT: posSecDesc - pointer to the security descriptor
  598. of the share
  599. RETURNS:
  600. NOTES:
  601. HISTORY:
  602. ChuckC 8/10/92 Created
  603. ********************************************************************/
  604. APIERR SHARE_DIALOG_BASE::QuerySharePermissions( const TCHAR *pszServer,
  605. const TCHAR *pszShare,
  606. OS_SECURITY_DESCRIPTOR **pposSecDesc)
  607. {
  608. UIASSERT(pszShare) ;
  609. UIASSERT(pposSecDesc) ;
  610. return ( ::GetSharePerm(pszServer,
  611. pszShare,
  612. pposSecDesc) ) ;
  613. }
  614. /*******************************************************************
  615. NAME: SHARE_LEVEL_PERMISSIONS_DIALOG
  616. SYNOPSIS: The permission dialog for LM share-level servers
  617. ENTRY: hwndParent - parent window
  618. pnlsPassword - the initial password to be displayed and
  619. place to return the password typed by the
  620. user
  621. puiPermissions - the initial permission to be displayed and
  622. place to return the permission entered by
  623. the user
  624. ulHelpContextBase - the base help context
  625. EXIT:
  626. RETURNS:
  627. NOTES:
  628. HISTORY:
  629. Yi-HsinS 8/15/91 Created
  630. ********************************************************************/
  631. SHARE_LEVEL_PERMISSIONS_DIALOG::SHARE_LEVEL_PERMISSIONS_DIALOG( HWND hwndParent,
  632. NLS_STR *pnlsPassword,
  633. UINT *puiPermissions,
  634. ULONG ulHelpContextBase )
  635. : DIALOG_WINDOW ( IDD_SHAREPERMDLG, hwndParent ),
  636. _pnlsPassword ( pnlsPassword ),
  637. _puiPermissions( puiPermissions ),
  638. _permgrp ( this, RB_READONLY, SLE_OTHER ),
  639. _slePassword ( this, SLE_PASSWORD, SHPWLEN ),
  640. _ulHelpContextBase( ulHelpContextBase )
  641. {
  642. UIASSERT( pnlsPassword != NULL );
  643. UIASSERT( puiPermissions != NULL );
  644. if ( QueryError() != NERR_Success )
  645. return;
  646. APIERR err;
  647. if ( ((err = _permgrp.QueryError()) != NERR_Success )
  648. || ((err = _permgrp.SetPermission( *_puiPermissions )) != NERR_Success)
  649. )
  650. {
  651. ReportError( err );
  652. return;
  653. }
  654. _slePassword.SetText( *_pnlsPassword );
  655. _permgrp.ClaimFocus();
  656. }
  657. /*******************************************************************
  658. NAME: SHARE_LEVEL_PERMISSION_DIALOG::OnOK
  659. SYNOPSIS: Validate and return the password/permission that
  660. the user entered.
  661. ENTRY:
  662. EXIT:
  663. RETURNS:
  664. NOTES:
  665. HISTORY:
  666. Yi-HsinS 8/25/91 Created
  667. ********************************************************************/
  668. BOOL SHARE_LEVEL_PERMISSIONS_DIALOG::OnOK( VOID )
  669. {
  670. APIERR err = NERR_Success;
  671. UINT uiPerm;
  672. if ( ( err = _permgrp.QueryPermission( &uiPerm ) ) != NERR_Success)
  673. {
  674. err = IERR_SHARE_INVALID_PERMISSIONS;
  675. _permgrp.SetFocusOnOther();
  676. }
  677. else
  678. {
  679. *_puiPermissions = uiPerm;
  680. err = _slePassword.QueryText( _pnlsPassword );
  681. }
  682. if ( err == NERR_Success )
  683. {
  684. Dismiss( TRUE );
  685. }
  686. else
  687. {
  688. ::MsgPopup( this, err );
  689. }
  690. return TRUE;
  691. }
  692. /*******************************************************************
  693. NAME: SHARE_LEVEL_PERMISSIONS_DIALOG::QueryHelpContext
  694. SYNOPSIS: Query the help context of the dialog
  695. ENTRY:
  696. EXIT:
  697. RETURNS: Return the help context of the dialog
  698. NOTES:
  699. HISTORY:
  700. Yi-HsinS 8/25/91 Created
  701. ********************************************************************/
  702. ULONG SHARE_LEVEL_PERMISSIONS_DIALOG::QueryHelpContext( VOID )
  703. {
  704. return _ulHelpContextBase + HC_LMSHARELEVELPERMS;
  705. }
  706. /*******************************************************************
  707. NAME: PERMISSION_GROUP::PERMISSION_GROUP
  708. SYNOPSIS: Constructor for PERMISSION_GROUP
  709. ENTRY: powin - pointer to the parent window
  710. cidBase - CID of first button of the permission group
  711. cidOtherEditField - CID of the Other Edit field
  712. cidInitialSelection - CID of the initial selection
  713. pGroupOwner - pointer to owner group
  714. EXIT:
  715. RETURNS:
  716. NOTES:
  717. HISTORY:
  718. Yi-HsinS 8/15/91 Created
  719. ********************************************************************/
  720. //
  721. // Table for converting permissions from string to UINT and vice versa.
  722. //
  723. static struct {
  724. WCHAR chPerm;
  725. UINT uiPerm;
  726. } permTable[] = {
  727. { READ_CHAR, ACCESS_READ},
  728. { WRITE_CHAR, ACCESS_WRITE},
  729. { CREATE_CHAR, ACCESS_CREATE},
  730. { EXEC_CHAR, ACCESS_EXEC},
  731. { DEL_CHAR, ACCESS_DELETE},
  732. { ACCESS_CHAR, ACCESS_ATRIB},
  733. { PERM_CHAR, ACCESS_PERM}
  734. };
  735. PERMISSION_GROUP::PERMISSION_GROUP( OWNER_WINDOW *powin,
  736. CID cidBase,
  737. CID cidOtherEditField,
  738. CID cidInitialSelection,
  739. CONTROL_GROUP *pGroupOwner)
  740. : _mgrpPermission( powin, cidBase, 3, cidInitialSelection, pGroupOwner),
  741. // 3 is the number of buttons in the magic group
  742. _sleOther(powin, cidOtherEditField, PERM_DEFAULT_LEN )
  743. {
  744. if ( QueryError() != NERR_Success )
  745. return;
  746. APIERR err;
  747. if ( ((err = _mgrpPermission.QueryError()) != NERR_Success )
  748. || ((err = _mgrpPermission.AddAssociation( RB_OTHER, &_sleOther ))
  749. != NERR_Success )
  750. )
  751. {
  752. ReportError( err );
  753. return;
  754. }
  755. }
  756. /*******************************************************************
  757. NAME: PERMISSION_GROUP::GetAndCheckOtherField
  758. SYNOPSIS: Validate the contents in "Other" Edit field
  759. ENTRY:
  760. EXIT: puiPermission - the permission
  761. RETURNS: returns ERROR_INVALID_PARAMETER if the string in
  762. other edit field is not valid
  763. NOTES:
  764. HISTORY:
  765. Yi-HsinS 8/15/91 Created
  766. ********************************************************************/
  767. APIERR PERMISSION_GROUP::GetAndCheckOtherField( UINT *puiPermission ) const
  768. {
  769. APIERR err = NERR_Success;
  770. NLS_STR nlsOther( PERM_DEFAULT_LEN );
  771. if ( (( err = nlsOther.QueryError()) != NERR_Success )
  772. || (( err = _sleOther.QueryText( &nlsOther )) != NERR_Success )
  773. )
  774. {
  775. return err;
  776. }
  777. nlsOther._strupr();
  778. *puiPermission = 0;
  779. ISTR istrOther( nlsOther );
  780. BOOL fFound = FALSE; // A flag indicating whether a valid char is found
  781. // in the permission string.
  782. while ( nlsOther.QueryChar( istrOther) != STRING_TERMINATOR )
  783. {
  784. for ( UINT i = 0; i < PERM_DEFAULT_LEN; i++ )
  785. {
  786. if ( nlsOther.QueryChar( istrOther ) == permTable[i].chPerm )
  787. {
  788. fFound = TRUE;
  789. if ( !(*puiPermission & permTable[i].uiPerm ))
  790. {
  791. *puiPermission |= permTable[i].uiPerm;
  792. break; // break the for loop but continue the while loop
  793. }
  794. else
  795. return ERROR_INVALID_PARAMETER;
  796. }
  797. else if ( nlsOther.QueryChar( istrOther) == SPACE )
  798. fFound = TRUE;
  799. }
  800. //
  801. // If the current character does not belong to "RWCXDAP" or is not
  802. // a space, then error
  803. //
  804. if ( fFound )
  805. fFound = FALSE;
  806. else
  807. return ERROR_INVALID_PARAMETER;
  808. ++istrOther;
  809. }
  810. //
  811. // If the assigned permission is still zero, then the user
  812. // did not type anything in _sleOther.
  813. //
  814. if ( *puiPermission == 0 )
  815. return ERROR_INVALID_PARAMETER;
  816. else
  817. return NERR_Success;
  818. }
  819. /*******************************************************************
  820. NAME: PERMISSION_GROUP::SetPermission
  821. SYNOPSIS: Check the permission to see if it's READ_ONLY or MODIFY.
  822. If yes, set the corresponding radio button. Else convert
  823. the permission to a string of "RWCXDAP" and displayed
  824. it on the Other Edit field
  825. ENTRY: uiPermission - the permission
  826. EXIT:
  827. RETURNS:
  828. NOTES:
  829. HISTORY:
  830. Yi-HsinS 8/15/91 Created
  831. ********************************************************************/
  832. APIERR PERMISSION_GROUP::SetPermission( UINT uiPermission )
  833. {
  834. if ( (uiPermission & ACCESS_ALL ) == (ACCESS_READ | ACCESS_EXEC) )
  835. {
  836. _sleOther.SetText( EMPTY_STRING );
  837. _mgrpPermission.SetSelection( RB_READONLY );
  838. }
  839. else if ( (uiPermission & ACCESS_ALL ) == (ACCESS_ALL & ~ACCESS_PERM))
  840. {
  841. _sleOther.SetText( EMPTY_STRING );
  842. _mgrpPermission.SetSelection( RB_MODIFY );
  843. }
  844. else
  845. {
  846. NLS_STR nlsPermission( PERM_DEFAULT_LEN );
  847. APIERR err = NERR_Success;
  848. if ( ( err = nlsPermission.QueryError()) != NERR_Success )
  849. return err;
  850. for ( UINT i = 0; i < PERM_DEFAULT_LEN; i++ )
  851. {
  852. if ( uiPermission & permTable[i].uiPerm )
  853. {
  854. if ( (err = nlsPermission.AppendChar( permTable[i].chPerm ))
  855. != NERR_Success )
  856. return err;
  857. }
  858. }
  859. _mgrpPermission.SetSelection( RB_OTHER );
  860. _sleOther.SetText( nlsPermission );
  861. }
  862. return NERR_Success;
  863. }
  864. /*******************************************************************
  865. NAME: PERMISSION_GROUP::QueryPermission
  866. SYNOPSIS: Get the permission from the permission group
  867. ENTRY:
  868. EXIT: puiPermission - will contain the permission
  869. RETURNS:
  870. NOTES:
  871. HISTORY:
  872. Yi-HsinS 8/15/91 Created
  873. ********************************************************************/
  874. APIERR PERMISSION_GROUP::QueryPermission( UINT *puiPermission ) const
  875. {
  876. APIERR err = NERR_Success;
  877. switch ( _mgrpPermission.QuerySelection() )
  878. {
  879. case RB_READONLY:
  880. *puiPermission = ACCESS_READ | ACCESS_EXEC;
  881. break;
  882. case RB_MODIFY:
  883. *puiPermission = ACCESS_ALL & ~ACCESS_PERM;
  884. break;
  885. case RB_OTHER:
  886. err = GetAndCheckOtherField( puiPermission );
  887. break;
  888. }
  889. return err;
  890. }
  891. /*******************************************************************
  892. NAME: SHARE_NAME_WITH_PATH_ENUM_ITER::SHARE_NAME_WITH_PATH_ENUM_ITER
  893. SYNOPSIS: Constructor
  894. ENTRY: sh2Enum - The thing to iterate on
  895. nlsActPath - The path we are interested in finding
  896. EXIT:
  897. RETURNS:
  898. NOTES:
  899. HISTORY:
  900. Yi-HsinS 8/15/91 Created
  901. ********************************************************************/
  902. SHARE_NAME_WITH_PATH_ENUM_ITER::SHARE_NAME_WITH_PATH_ENUM_ITER(
  903. SHARE2_ENUM &sh2Enum,
  904. const NLS_STR &nlsActPath)
  905. : _sh2EnumIter( sh2Enum ),
  906. _nlsActPath( nlsActPath )
  907. {
  908. if ( QueryError() != NERR_Success )
  909. return;
  910. APIERR err;
  911. if ( ( err = _nlsActPath.QueryError() ) != NERR_Success )
  912. {
  913. ReportError( err );
  914. return;
  915. }
  916. }
  917. /*******************************************************************
  918. NAME: SHARE_NAME_WITH_PATH_ENUM_ITER::operator()
  919. SYNOPSIS: iterator
  920. ENTRY:
  921. EXIT:
  922. RETURNS: returns the share name if its path matches the _nlsActPath
  923. NOTES:
  924. HISTORY:
  925. Yi-HsinS 8/15/91 Created
  926. ********************************************************************/
  927. const TCHAR *SHARE_NAME_WITH_PATH_ENUM_ITER::operator()( VOID )
  928. {
  929. const SHARE2_ENUM_OBJ *pshi2;
  930. while ( (pshi2 = _sh2EnumIter()) != NULL )
  931. {
  932. if ( ::stricmpf( pshi2->QueryPath(), _nlsActPath) == 0)
  933. return( pshi2->QueryName());
  934. }
  935. return NULL;
  936. }
  937. /*******************************************************************
  938. NAME: SERVER_WITH_PASSWORD_PROMPT::SERVER_WITH_PASSWORD_PROMPT
  939. SYNOPSIS: Constructor
  940. ENTRY:
  941. EXIT: pszServer - Server name
  942. hwndParent - Handle of the parent window
  943. ulHelpContextBase - The base help context
  944. RETURNS:
  945. NOTES:
  946. HISTORY:
  947. Yi-HsinS 8/15/91 Created
  948. ********************************************************************/
  949. SERVER_WITH_PASSWORD_PROMPT::SERVER_WITH_PASSWORD_PROMPT(const TCHAR *pszServer,
  950. HWND hwndParent,
  951. ULONG ulHelpContextBase )
  952. : SERVER_2( pszServer ),
  953. _hwndParent( hwndParent ),
  954. _pprompt( NULL ),
  955. _ulHelpContextBase( ulHelpContextBase )
  956. {
  957. if ( QueryError() != NERR_Success )
  958. return;
  959. }
  960. /*******************************************************************
  961. NAME: SERVER_WITH_PASSWORD_PROMPT::~SERVER_WITH_PASSWORD_PROMPT
  962. SYNOPSIS: Destructor
  963. ENTRY:
  964. EXIT:
  965. RETURNS:
  966. NOTES:
  967. HISTORY:
  968. Yi-HsinS 8/15/91 Created
  969. ********************************************************************/
  970. SERVER_WITH_PASSWORD_PROMPT::~SERVER_WITH_PASSWORD_PROMPT()
  971. {
  972. delete _pprompt;
  973. _pprompt = NULL;
  974. }
  975. /*******************************************************************
  976. NAME: SERVER_WITH_PASSWORD_PROMPT::I_GetInfo
  977. SYNOPSIS: Get the SERVER_2 Info and if the user does not have admin
  978. privilege and the server is a LM share-level server,
  979. it will pop up a dialog asking for password,
  980. make a connection to the server's ADMIN$ with the
  981. password and attempts to get SERVER_2 info again.
  982. ENTRY:
  983. EXIT:
  984. RETURNS:
  985. NOTES:
  986. HISTORY:
  987. Yi-HsinS 8/15/91 Created
  988. ********************************************************************/
  989. APIERR SERVER_WITH_PASSWORD_PROMPT::I_GetInfo( VOID )
  990. {
  991. APIERR errOriginal = SERVER_2::I_GetInfo();
  992. if ( errOriginal == NERR_Success )
  993. return errOriginal;
  994. APIERR err;
  995. switch ( errOriginal )
  996. {
  997. case ERROR_ACCESS_DENIED:
  998. case ERROR_INVALID_PASSWORD:
  999. {
  1000. //
  1001. // Check if the machine is user level or share level
  1002. // Return the original error if it's user level
  1003. //
  1004. LOCATION loc( QueryName() );
  1005. BOOL fNT;
  1006. if ( ((err = loc.QueryError()) == NERR_Success )
  1007. && ((err = loc.CheckIfNT( &fNT )) == NERR_Success )
  1008. )
  1009. {
  1010. if ( fNT ) // Always user level
  1011. {
  1012. err = errOriginal;
  1013. break;
  1014. }
  1015. else
  1016. {
  1017. USER0_ENUM usr0( QueryName() );
  1018. if ((err = usr0.QueryError()) != NERR_Success )
  1019. break;
  1020. //
  1021. // ERROR_NOT_SUPPORTED is returned by share level servers
  1022. //
  1023. if ((err = usr0.GetInfo()) != ERROR_NOT_SUPPORTED )
  1024. {
  1025. // user level
  1026. err = errOriginal;
  1027. break;
  1028. }
  1029. }
  1030. }
  1031. else
  1032. {
  1033. break;
  1034. }
  1035. //
  1036. // Prompt password and connect to the ADMIN$ share of
  1037. // share-level servers.
  1038. //
  1039. NLS_STR nlsServer( QueryName() );
  1040. if ( ((err = nlsServer.QueryError()) != NERR_Success )
  1041. || ((err = QueryDisplayName( &nlsServer )) != NERR_Success)
  1042. )
  1043. {
  1044. break;
  1045. }
  1046. NLS_STR nlsAdmin( nlsServer );
  1047. ALIAS_STR nlsAdminShare( ADMIN_SHARE );
  1048. if ( ((err = nlsAdmin.QueryError()) == NERR_Success )
  1049. && ((err = nlsAdmin.AppendChar( PATH_SEPARATOR)) == NERR_Success)
  1050. && ((err = nlsAdmin.Append( nlsAdminShare )) == NERR_Success )
  1051. )
  1052. {
  1053. _pprompt = new PROMPT_AND_CONNECT( _hwndParent,
  1054. nlsAdmin,
  1055. _ulHelpContextBase
  1056. + HC_SHAREPASSWORDPROMPT,
  1057. SHPWLEN);
  1058. if ( ( _pprompt != NULL )
  1059. && ( (err = _pprompt->QueryError()) == NERR_Success )
  1060. && ( (err = _pprompt->Connect()) == NERR_Success )
  1061. )
  1062. {
  1063. if ( _pprompt->IsConnected() )
  1064. {
  1065. err = SERVER_2::I_GetInfo();
  1066. }
  1067. else // user clicks CANCEL in the password dialog
  1068. {
  1069. err = IERR_USER_CLICKED_CANCEL;
  1070. }
  1071. }
  1072. }
  1073. break;
  1074. }
  1075. case NERR_BadTransactConfig:
  1076. err = (APIERR) IERR_SHARE_REMOTE_ADMIN_NOT_SUPPORTED;
  1077. break;
  1078. default:
  1079. err = errOriginal;
  1080. break;
  1081. }
  1082. return err;
  1083. }
  1084. /*******************************************************************
  1085. NAME: SERVER_WITH_PASSWORD_PROMPT::QueryName
  1086. SYNOPSIS: Query the name of the server
  1087. ENTRY:
  1088. EXIT:
  1089. RETURNS:
  1090. NOTES: Redefine SERVER_2::QueryName because we want to return
  1091. EMPTY_STRING instead of NULL when the server is local.
  1092. HISTORY:
  1093. Yi-HsinS 8/15/91 Created
  1094. ********************************************************************/
  1095. const TCHAR *SERVER_WITH_PASSWORD_PROMPT::QueryName( VOID ) const
  1096. {
  1097. if ( SERVER_2::QueryName() == NULL )
  1098. return EMPTY_STRING;
  1099. else
  1100. return SERVER_2::QueryName();
  1101. }
  1102. /*******************************************************************
  1103. NAME: SERVER_WITH_PASSWORD_PROMPT::IsNT
  1104. SYNOPSIS: Check if the server is an NT server or not.
  1105. ENTRY:
  1106. EXIT:
  1107. RETURNS: TRUE if the server is a NT server, FALSE otherwise.
  1108. NOTES:
  1109. HISTORY:
  1110. Yi-HsinS 8/6/92 Created
  1111. ********************************************************************/
  1112. #define NT_NOS_MAJOR_VER 3
  1113. BOOL SERVER_WITH_PASSWORD_PROMPT::IsNT( VOID ) const
  1114. {
  1115. return ( QueryMajorVer() >= NT_NOS_MAJOR_VER );
  1116. }
  1117. /*******************************************************************
  1118. NAME: SHARE_NET_NAME::SHARE_NET_NAME
  1119. SYNOPSIS: Constructor
  1120. ENTRY:
  1121. EXIT:
  1122. RETURNS:
  1123. NOTES: Report why the local server cannot share directories,
  1124. whether it's because NT server service is not started
  1125. or if the local computer is a WIN16 computer
  1126. HISTORY:
  1127. Yi-HsinS 8/15/91 Created
  1128. ********************************************************************/
  1129. SHARE_NET_NAME::SHARE_NET_NAME( const TCHAR *pszSharePath,
  1130. NETNAME_TYPE netNameType )
  1131. : NET_NAME( pszSharePath, netNameType )
  1132. {
  1133. if ( QueryError() != NERR_Success )
  1134. return;
  1135. APIERR err;
  1136. BOOL fLocal = IsLocal( &err );
  1137. if ( err != NERR_Success )
  1138. {
  1139. ReportError( err );
  1140. return;
  1141. }
  1142. if ( !fLocal )
  1143. return;
  1144. //
  1145. // Check whether the local computer can share directories
  1146. //
  1147. if ( IsSharable( &err ) && ( err == NERR_Success ))
  1148. {
  1149. return;
  1150. }
  1151. else if ( err == NERR_Success ) // Not sharable!
  1152. {
  1153. //
  1154. // Determine the reason why the local computer cannot share directories
  1155. //
  1156. LOCATION loc; // Local Computer
  1157. BOOL fNT;
  1158. if ( ((err = loc.QueryError()) == NERR_Success )
  1159. && ((err = loc.CheckIfNT( &fNT )) == NERR_Success )
  1160. )
  1161. {
  1162. // NOTE: What should we do here if we admin NT from
  1163. // WinBall machine?
  1164. if ( !fNT )
  1165. err = NERR_RemoteOnly;
  1166. else
  1167. err = NERR_ServerNotStarted;
  1168. }
  1169. }
  1170. if ( err != NERR_Success )
  1171. {
  1172. ReportError( err );
  1173. return;
  1174. }
  1175. }