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.

1273 lines
34 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1995.
  5. //
  6. // File: shrpage.cxx
  7. //
  8. // Contents: "Sharing" shell property page extension
  9. //
  10. // History: 6-Apr-95 BruceFo Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "headers.hxx"
  14. #pragma hdrstop
  15. #include "resource.h"
  16. #include "helpids.h"
  17. #include "dlgnew.hxx"
  18. #include "acl.hxx"
  19. #include "shrinfo.hxx"
  20. #include "shrpage.hxx"
  21. #include "util.hxx"
  22. ////////////////////////////////////////////////////////////////////////////
  23. ////////////////////////////////////////////////////////////////////////////
  24. //+-------------------------------------------------------------------------
  25. //
  26. // Method: CSharingPropertyPage::DlgProcPage, static public
  27. //
  28. // Synopsis: Dialog Procedure for all CSharingPropertyPage
  29. //
  30. //--------------------------------------------------------------------------
  31. INT_PTR CALLBACK
  32. CSharingPropertyPage::DlgProcPage(
  33. IN HWND hwnd,
  34. IN UINT msg,
  35. IN WPARAM wParam,
  36. IN LPARAM lParam
  37. )
  38. {
  39. CSharingPropertyPage* pThis = NULL;
  40. if (msg==WM_INITDIALOG)
  41. {
  42. SHARE_PROPSHEETPAGE* sprop = (SHARE_PROPSHEETPAGE*)lParam;
  43. pThis = new CSharingPropertyPage(hwnd, sprop->pszMachine, sprop->pszShareName);
  44. if (NULL != pThis)
  45. {
  46. if (FAILED(pThis->InitInstance()))
  47. {
  48. delete pThis;
  49. pThis = NULL;
  50. }
  51. }
  52. SetWindowLongPtr(hwnd,GWLP_USERDATA,(LPARAM)pThis);
  53. }
  54. else
  55. {
  56. pThis = (CSharingPropertyPage*) GetWindowLongPtr(hwnd,GWLP_USERDATA);
  57. }
  58. if (pThis != NULL)
  59. {
  60. return pThis->_PageProc(hwnd,msg,wParam,lParam);
  61. }
  62. else
  63. {
  64. return FALSE;
  65. }
  66. }
  67. //+-------------------------------------------------------------------------
  68. //
  69. // Member: CSharingPropertyPage::SizeWndProc, public
  70. //
  71. // Synopsis: "allow" edit window subclass proc to disallow non-numeric
  72. // characters.
  73. //
  74. // History: 5-Apr-95 BruceFo Created
  75. //
  76. //--------------------------------------------------------------------------
  77. LRESULT CALLBACK
  78. CSharingPropertyPage::SizeWndProc(
  79. IN HWND hwnd,
  80. IN UINT wMsg,
  81. IN WPARAM wParam,
  82. IN LPARAM lParam
  83. )
  84. {
  85. switch (wMsg)
  86. {
  87. case WM_CHAR:
  88. {
  89. WCHAR chCharCode = (WCHAR)wParam;
  90. if ( (chCharCode == TEXT('\t'))
  91. || (chCharCode == TEXT('\b'))
  92. || (chCharCode == TEXT('\n'))
  93. // || (chCharCode == TEXT('\x1b')) // ESCAPE key
  94. )
  95. {
  96. break;
  97. }
  98. if (chCharCode < TEXT('0') || chCharCode > TEXT('9'))
  99. {
  100. // bad key: ignore it
  101. MessageBeep(0xffffffff); // let user know it's an illegal char
  102. return FALSE;
  103. }
  104. break;
  105. }
  106. } // end of switch
  107. CSharingPropertyPage* pThis = (CSharingPropertyPage*)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
  108. appAssert(NULL != pThis);
  109. appAssert(NULL != pThis->_pfnAllowProc);
  110. return CallWindowProc(pThis->_pfnAllowProc, hwnd, wMsg, wParam, lParam);
  111. }
  112. //+--------------------------------------------------------------------------
  113. //
  114. // Method: CSharingPropertyPage::CSharingPropertyPage, public
  115. //
  116. // Synopsis: Constructor
  117. //
  118. //---------------------------------------------------------------------------
  119. CSharingPropertyPage::CSharingPropertyPage(
  120. IN HWND hwndPage,
  121. IN PWSTR pszMachine,
  122. IN PWSTR pszShare
  123. )
  124. :
  125. _hwndPage(hwndPage),
  126. _pszMachine(pszMachine),
  127. _pszShare(pszShare),
  128. _bDirty(FALSE),
  129. _bShareNameChanged(FALSE),
  130. _bPathChanged(FALSE),
  131. _bCommentChanged(FALSE),
  132. _bUserLimitChanged(FALSE),
  133. _bSecDescChanged(FALSE),
  134. _wMaxUsers(DEFAULT_MAX_USERS),
  135. _pCurInfo(NULL),
  136. _pszReplacePath(NULL),
  137. _pfnAllowProc(NULL)
  138. {
  139. INIT_SIG(CSharingPropertyPage);
  140. appAssert(NULL != _pszShare);
  141. }
  142. //+--------------------------------------------------------------------------
  143. //
  144. // Method: CSharingPropertyPage::~CSharingPropertyPage, public
  145. //
  146. // Synopsis: Destructor
  147. //
  148. //---------------------------------------------------------------------------
  149. CSharingPropertyPage::~CSharingPropertyPage()
  150. {
  151. CHECK_SIG(CSharingPropertyPage);
  152. delete _pCurInfo;
  153. _pCurInfo = NULL;
  154. delete[] _pszReplacePath;
  155. _pszReplacePath = NULL;
  156. }
  157. //+-------------------------------------------------------------------------
  158. //
  159. // Method: CSharingPropertyPage::InitInstance, public
  160. //
  161. // Synopsis: Part II of the constuctor process
  162. //
  163. // Notes: We don't want to handle any errors in constuctor, so this
  164. // method is necessary for the second phase error detection.
  165. //
  166. //--------------------------------------------------------------------------
  167. HRESULT
  168. CSharingPropertyPage::InitInstance(
  169. VOID
  170. )
  171. {
  172. CHECK_SIG(CSharingPropertyPage);
  173. appDebugOut((DEB_ITRACE, "CSharingPropertyPage::InitInstance\n"));
  174. SHARE_INFO_502* info502;
  175. NET_API_STATUS ret = NetShareGetInfo(_pszMachine, _pszShare, 502, (LPBYTE*)&info502);
  176. if (ret == NERR_Success)
  177. {
  178. _pCurInfo = new CShareInfo(info502);
  179. if (NULL == _pCurInfo)
  180. {
  181. return E_OUTOFMEMORY;
  182. }
  183. if (!_pCurInfo->TakeOwn())
  184. {
  185. return E_OUTOFMEMORY;
  186. }
  187. NetApiBufferFree(info502);
  188. }
  189. else
  190. {
  191. appDebugOut((DEB_ERROR, "Couldn't get info\n"));
  192. return HRESULT_FROM_WIN32(ret);
  193. }
  194. return S_OK;
  195. }
  196. //+-------------------------------------------------------------------------
  197. //
  198. // Method: CSharingPropertyPage::_PageProc, private
  199. //
  200. // Synopsis: Dialog Procedure for this object
  201. //
  202. //--------------------------------------------------------------------------
  203. INT_PTR
  204. CSharingPropertyPage::_PageProc(
  205. IN HWND hwnd,
  206. IN UINT msg,
  207. IN WPARAM wParam,
  208. IN LPARAM lParam
  209. )
  210. {
  211. CHECK_SIG(CSharingPropertyPage);
  212. static DWORD aHelpIds[] =
  213. {
  214. IDC_SHARE_SHARENAME, HC_SHARE_SHARENAME,
  215. IDC_SHARE_PATH, HC_SHARE_PATH,
  216. IDC_SHARE_COMMENT, HC_SHARE_COMMENT,
  217. IDC_SHARE_MAXIMUM, HC_SHARE_MAXIMUM,
  218. IDC_SHARE_ALLOW, HC_SHARE_ALLOW,
  219. IDC_SHARE_ALLOW_VALUE, HC_SHARE_ALLOW_VALUE,
  220. IDC_SHARE_PERMISSIONS, HC_SHARE_PERMISSIONS,
  221. 0,0
  222. };
  223. switch (msg)
  224. {
  225. case WM_INITDIALOG:
  226. return _OnInitDialog(hwnd, (HWND)wParam, lParam);
  227. case WM_COMMAND:
  228. return _OnCommand(hwnd, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
  229. case WM_NOTIFY:
  230. return _OnNotify(hwnd, (int)wParam, (LPNMHDR)lParam);
  231. case WM_VSCROLL:
  232. // The up/down control changed the edit control: select it again
  233. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  234. return TRUE;
  235. case WM_HELP:
  236. {
  237. LPHELPINFO lphi = (LPHELPINFO)lParam;
  238. if (lphi->iContextType == HELPINFO_WINDOW) // a control
  239. {
  240. WCHAR szHelp[50];
  241. LoadString(g_hInstance, IDS_HELPFILENAME, szHelp, ARRAYLEN(szHelp));
  242. WinHelp(
  243. (HWND)lphi->hItemHandle,
  244. szHelp,
  245. HELP_WM_HELP,
  246. (DWORD_PTR)aHelpIds);
  247. }
  248. break;
  249. }
  250. case WM_CONTEXTMENU:
  251. {
  252. WCHAR szHelp[50];
  253. LoadString(g_hInstance, IDS_HELPFILENAME, szHelp, ARRAYLEN(szHelp));
  254. WinHelp(
  255. (HWND)wParam,
  256. szHelp,
  257. HELP_CONTEXTMENU,
  258. (DWORD_PTR)aHelpIds);
  259. break;
  260. }
  261. case WM_CLOSE:
  262. // BUGBUG: There is a bug where hitting "ESCAPE" with the focus on the
  263. // MLE for the "allow" text doesn't kill the property sheet unless we
  264. // forward the WM_CLOSE message on to the property sheet root dialog.
  265. return SendMessage(GetParent(hwnd), msg, wParam, lParam);
  266. case WM_DESTROY:
  267. // restore original subclass to window.
  268. appAssert(NULL != GetDlgItem(hwnd,IDC_SHARE_ALLOW_VALUE));
  269. SetWindowLongPtr(GetDlgItem(hwnd,IDC_SHARE_ALLOW_VALUE), GWLP_WNDPROC, (LONG_PTR)_pfnAllowProc);
  270. break;
  271. case WM_NCDESTROY:
  272. return _OnNcDestroy(hwnd);
  273. } // end switch (msg)
  274. return FALSE;
  275. }
  276. //+-------------------------------------------------------------------------
  277. //
  278. // Method: CSharingPropertyPage::_OnInitDialog, private
  279. //
  280. // Synopsis: WM_INITDIALOG handler
  281. //
  282. //--------------------------------------------------------------------------
  283. BOOL
  284. CSharingPropertyPage::_OnInitDialog(
  285. IN HWND hwnd,
  286. IN HWND hwndFocus,
  287. IN LPARAM lInitParam
  288. )
  289. {
  290. CHECK_SIG(CSharingPropertyPage);
  291. appDebugOut((DEB_ITRACE, "_OnInitDialog\n"));
  292. SetDialogIconBig(_GetFrameWindow(), IDI_SHARESFLD);
  293. // Subclass allow edit control to disallow non-positive numbers
  294. _pfnAllowProc = (WNDPROC)SetWindowLongPtr(
  295. GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE),
  296. GWLP_WNDPROC,
  297. (LONG_PTR)&SizeWndProc);
  298. // use LanMan API constants to set maximum share name & comment lengths
  299. SendDlgItemMessage(hwnd, IDC_SHARE_SHARENAME, EM_LIMITTEXT, NNLEN, 0L);
  300. SendDlgItemMessage(hwnd, IDC_SHARE_PATH, EM_LIMITTEXT, MAX_PATH-1, 0L);
  301. SendDlgItemMessage(hwnd, IDC_SHARE_COMMENT, EM_LIMITTEXT, MAXCOMMENTSZ, 0L);
  302. _InitializeControls(hwnd);
  303. // #if DBG == 1
  304. // Dump(L"_OnInitDialog finished");
  305. // #endif // DBG == 1
  306. return TRUE;
  307. }
  308. //+-------------------------------------------------------------------------
  309. //
  310. // Method: CSharingPropertyPage::_OnCommand, private
  311. //
  312. // Synopsis: WM_COMMAND handler
  313. //
  314. //--------------------------------------------------------------------------
  315. BOOL
  316. CSharingPropertyPage::_OnCommand(
  317. IN HWND hwnd,
  318. IN WORD wNotifyCode,
  319. IN WORD wID,
  320. IN HWND hwndCtl
  321. )
  322. {
  323. CHECK_SIG(CSharingPropertyPage);
  324. switch (wID)
  325. {
  326. //
  327. // Notifications
  328. //
  329. case IDC_SHARE_SHARENAME:
  330. {
  331. if (EN_CHANGE == wNotifyCode)
  332. {
  333. if (!_fInitializingPage)
  334. {
  335. _bShareNameChanged = TRUE;
  336. _MarkItemDirty();
  337. }
  338. }
  339. return TRUE;
  340. }
  341. case IDC_SHARE_PATH:
  342. {
  343. if (EN_CHANGE == wNotifyCode)
  344. {
  345. if (!_fInitializingPage)
  346. {
  347. _bPathChanged = TRUE;
  348. _MarkItemDirty();
  349. }
  350. }
  351. return TRUE;
  352. }
  353. case IDC_SHARE_COMMENT:
  354. {
  355. if (EN_CHANGE == wNotifyCode)
  356. {
  357. if (!_fInitializingPage)
  358. {
  359. _bCommentChanged = TRUE;
  360. _MarkItemDirty();
  361. }
  362. }
  363. return TRUE;
  364. }
  365. case IDC_SHARE_MAXIMUM:
  366. if (BN_CLICKED == wNotifyCode)
  367. {
  368. // Take away WS_TABSTOP from the "allow users" edit control
  369. HWND hwndEdit = GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE);
  370. SetWindowLong(hwndEdit, GWL_STYLE, GetWindowLong(hwndEdit, GWL_STYLE) & ~WS_TABSTOP);
  371. _CacheMaxUses(hwnd);
  372. SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L"");
  373. _bUserLimitChanged = TRUE;
  374. _MarkItemDirty();
  375. }
  376. return TRUE;
  377. case IDC_SHARE_ALLOW:
  378. if (BN_CLICKED == wNotifyCode)
  379. {
  380. // Give WS_TABSTOP to the "allow users" edit control
  381. HWND hwndEdit = GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE);
  382. SetWindowLong(hwndEdit, GWL_STYLE, GetWindowLong(hwndEdit, GWL_STYLE) | WS_TABSTOP);
  383. // let the spin control set the edit control
  384. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0));
  385. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  386. _bUserLimitChanged = TRUE;
  387. _MarkItemDirty();
  388. }
  389. return TRUE;
  390. case IDC_SHARE_ALLOW_VALUE:
  391. {
  392. if (EN_CHANGE == wNotifyCode)
  393. {
  394. _bUserLimitChanged = TRUE;
  395. _MarkItemDirty();
  396. }
  397. if (EN_SETFOCUS == wNotifyCode)
  398. {
  399. if (1 != IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW))
  400. {
  401. CheckRadioButton(
  402. hwnd,
  403. IDC_SHARE_MAXIMUM,
  404. IDC_SHARE_ALLOW,
  405. IDC_SHARE_ALLOW);
  406. }
  407. // let the spin control set the edit control
  408. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0));
  409. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  410. _bUserLimitChanged = TRUE;
  411. _MarkItemDirty();
  412. }
  413. if (EN_KILLFOCUS == wNotifyCode)
  414. {
  415. _CacheMaxUses(hwnd);
  416. }
  417. return TRUE;
  418. }
  419. case IDC_SHARE_ALLOW_SPIN:
  420. if (UDN_DELTAPOS == wNotifyCode)
  421. {
  422. if (1 != IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW))
  423. {
  424. CheckRadioButton(
  425. hwnd,
  426. IDC_SHARE_MAXIMUM,
  427. IDC_SHARE_ALLOW,
  428. IDC_SHARE_ALLOW);
  429. }
  430. _bUserLimitChanged = TRUE;
  431. _MarkItemDirty();
  432. }
  433. return TRUE;
  434. //
  435. // Commands
  436. //
  437. case IDC_SHARE_PERMISSIONS:
  438. return _OnPermissions(hwnd);
  439. default:
  440. break;
  441. }
  442. return FALSE;
  443. }
  444. //+-------------------------------------------------------------------------
  445. //
  446. // Method: CSharingPropertyPage::_OnNotify, private
  447. //
  448. // Synopsis: WM_NOTIFY handler
  449. //
  450. //--------------------------------------------------------------------------
  451. BOOL
  452. CSharingPropertyPage::_OnNotify(
  453. IN HWND hwnd,
  454. IN int idCtrl,
  455. IN LPNMHDR phdr
  456. )
  457. {
  458. CHECK_SIG(CSharingPropertyPage);
  459. // assume a property sheet notification
  460. return _OnPropertySheetNotify(hwnd, phdr);
  461. }
  462. //+-------------------------------------------------------------------------
  463. //
  464. // Method: CSharingPropertyPage::_OnPropertySheetNotify, private
  465. //
  466. // Synopsis: WM_NOTIFY handler for the property sheet notification
  467. //
  468. //--------------------------------------------------------------------------
  469. BOOL
  470. CSharingPropertyPage::_OnPropertySheetNotify(
  471. IN HWND hwnd,
  472. IN LPNMHDR phdr
  473. )
  474. {
  475. CHECK_SIG(CSharingPropertyPage);
  476. switch (phdr->code)
  477. {
  478. case PSN_RESET: // cancel
  479. if (_DoCancel(hwnd))
  480. {
  481. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); // go away
  482. }
  483. else
  484. {
  485. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
  486. }
  487. return TRUE;
  488. case PSN_KILLACTIVE: // change to another page
  489. if (_ValidatePage(hwnd))
  490. {
  491. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
  492. return FALSE;
  493. }
  494. else
  495. {
  496. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  497. return TRUE;
  498. }
  499. case PSN_APPLY:
  500. if (_DoApply(hwnd))
  501. {
  502. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); // go away
  503. }
  504. else
  505. {
  506. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
  507. }
  508. return TRUE;
  509. } // end switch (phdr->code)
  510. return FALSE;
  511. }
  512. //+-------------------------------------------------------------------------
  513. //
  514. // Method: CSharingPropertyPage::_OnNcDestroy, private
  515. //
  516. // Synopsis: WM_NCDESTROY handler
  517. //
  518. //--------------------------------------------------------------------------
  519. BOOL
  520. CSharingPropertyPage::_OnNcDestroy(
  521. IN HWND hwnd
  522. )
  523. {
  524. CHECK_SIG(CSharingPropertyPage);
  525. delete this; // do this LAST!
  526. return TRUE;
  527. }
  528. //+-------------------------------------------------------------------------
  529. //
  530. // Method: CSharingPropertyPage::_OnPermissions, private
  531. //
  532. // Synopsis: WM_COMMAND handler: the permissions button
  533. //
  534. //--------------------------------------------------------------------------
  535. BOOL
  536. CSharingPropertyPage::_OnPermissions(
  537. IN HWND hwnd
  538. )
  539. {
  540. CHECK_SIG(CSharingPropertyPage);
  541. appAssert(NULL != _pCurInfo);
  542. if (STYPE_SPECIAL & _pCurInfo->GetType())
  543. {
  544. MyErrorDialog(hwnd, IERR_AdminShare);
  545. return TRUE;
  546. }
  547. WCHAR szShareName[NNLEN + 1];
  548. GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName));
  549. // don't trim spaces, this might be an existing share with spaces in its name
  550. PSECURITY_DESCRIPTOR pNewSecDesc = NULL;
  551. PSECURITY_DESCRIPTOR pSecDesc = _pCurInfo->GetSecurityDescriptor();
  552. appAssert(NULL == pSecDesc || IsValidSecurityDescriptor(pSecDesc));
  553. BOOL bSecDescChanged;
  554. LONG err = EditShareAcl(
  555. hwnd,
  556. _pszMachine,
  557. szShareName,
  558. pSecDesc,
  559. &bSecDescChanged,
  560. &pNewSecDesc);
  561. if (bSecDescChanged)
  562. {
  563. _bSecDescChanged = TRUE;
  564. appAssert(IsValidSecurityDescriptor(pNewSecDesc));
  565. _pCurInfo->TransferSecurityDescriptor(pNewSecDesc);
  566. _MarkItemDirty();
  567. }
  568. return TRUE;
  569. }
  570. //+-------------------------------------------------------------------------
  571. //
  572. // Method: CSharingPropertyPage::_InitializeControls, private
  573. //
  574. // Synopsis: Initialize the controls from scratch
  575. //
  576. //--------------------------------------------------------------------------
  577. VOID
  578. CSharingPropertyPage::_InitializeControls(
  579. IN HWND hwnd
  580. )
  581. {
  582. _SetControlsToDefaults(hwnd);
  583. _SetControlsFromData(hwnd);
  584. }
  585. //+-------------------------------------------------------------------------
  586. //
  587. // Method: CSharingPropertyPage::_SetControlsToDefaults, private
  588. //
  589. // Synopsis: Set all the controls on the page to their default values
  590. //
  591. //--------------------------------------------------------------------------
  592. VOID
  593. CSharingPropertyPage::_SetControlsToDefaults(
  594. IN HWND hwnd
  595. )
  596. {
  597. _fInitializingPage = TRUE;
  598. // Make "Maximum" the default number of users, and clear the value field
  599. // (which the spin button set on creation?).
  600. CheckRadioButton(
  601. hwnd,
  602. IDC_SHARE_MAXIMUM,
  603. IDC_SHARE_ALLOW,
  604. IDC_SHARE_MAXIMUM);
  605. SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L"");
  606. // set the spin control range: 1 <--> large number
  607. SendDlgItemMessage(
  608. hwnd,
  609. IDC_SHARE_ALLOW_SPIN,
  610. UDM_SETRANGE,
  611. 0,
  612. MAKELONG(g_uiMaxUsers, 1));
  613. SetDlgItemText(hwnd, IDC_SHARE_SHARENAME, L"");
  614. SetDlgItemText(hwnd, IDC_SHARE_PATH, L"");
  615. SetDlgItemText(hwnd, IDC_SHARE_COMMENT, L"");
  616. SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L"");
  617. _fInitializingPage = FALSE;
  618. }
  619. //+-------------------------------------------------------------------------
  620. //
  621. // Method: CSharingPropertyPage::SetControlsFromData, private
  622. //
  623. // Synopsis: From the class variables and current state of the radio
  624. // buttons, set the enabled/disabled state of the buttons, as
  625. // well as filling the controls with the appropriate values.
  626. //
  627. //--------------------------------------------------------------------------
  628. VOID
  629. CSharingPropertyPage::_SetControlsFromData(
  630. IN HWND hwnd
  631. )
  632. {
  633. appAssert(NULL != _pCurInfo);
  634. _fInitializingPage = TRUE;
  635. SetDlgItemText(hwnd, IDC_SHARE_SHARENAME, _pCurInfo->GetNetname());
  636. SetDlgItemText(hwnd, IDC_SHARE_PATH, _pCurInfo->GetPath());
  637. SetDlgItemText(hwnd, IDC_SHARE_COMMENT, _pCurInfo->GetRemark());
  638. DWORD dwLimit = _pCurInfo->GetMaxUses();
  639. if (dwLimit == SHI_USES_UNLIMITED)
  640. {
  641. _wMaxUsers = DEFAULT_MAX_USERS;
  642. appDebugOut((DEB_ITRACE, "_SetControlsFromData: unlimited users\n"));
  643. CheckRadioButton(
  644. hwnd,
  645. IDC_SHARE_MAXIMUM,
  646. IDC_SHARE_ALLOW,
  647. IDC_SHARE_MAXIMUM);
  648. SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L"");
  649. }
  650. else
  651. {
  652. _wMaxUsers = (WORD)dwLimit;
  653. appDebugOut((DEB_ITRACE,
  654. "_SetControlsFromData: max users = %d\n",
  655. _wMaxUsers));
  656. CheckRadioButton(
  657. hwnd,
  658. IDC_SHARE_MAXIMUM,
  659. IDC_SHARE_ALLOW,
  660. IDC_SHARE_ALLOW);
  661. // let the spin control set the edit control
  662. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0));
  663. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  664. }
  665. // Managine a special share?
  666. if (_pCurInfo->GetType() & STYPE_SPECIAL)
  667. {
  668. // Can't change the path or the name
  669. // Making it read-only makes it easier to read than if it were disabled
  670. SendDlgItemMessage(hwnd, IDC_SHARE_SHARENAME, EM_SETREADONLY, (WPARAM)(BOOL)TRUE, 0);
  671. SendDlgItemMessage(hwnd, IDC_SHARE_PATH, EM_SETREADONLY, (WPARAM)(BOOL)TRUE, 0);
  672. }
  673. _fInitializingPage = FALSE;
  674. }
  675. //+-------------------------------------------------------------------------
  676. //
  677. // Method: CSharingPropertyPage::_MarkItemDirty, private
  678. //
  679. // Synopsis: A change has made such that the current item (and page)
  680. // is now dirty
  681. //
  682. //--------------------------------------------------------------------------
  683. VOID
  684. CSharingPropertyPage::_MarkItemDirty(
  685. VOID
  686. )
  687. {
  688. CHECK_SIG(CSharingPropertyPage);
  689. if (!_fInitializingPage)
  690. {
  691. if (!_bDirty)
  692. {
  693. appDebugOut((DEB_ITRACE, "Marking Sharing page dirty\n"));
  694. _bDirty = TRUE;
  695. PropSheet_Changed(_GetFrameWindow(),_hwndPage);
  696. }
  697. }
  698. }
  699. //+-------------------------------------------------------------------------
  700. //
  701. // Method: CSharingPropertyPage::_ValidatePage, private
  702. //
  703. // Synopsis: Return TRUE if the current page is valid
  704. //
  705. //--------------------------------------------------------------------------
  706. BOOL
  707. CSharingPropertyPage::_ValidatePage(
  708. IN HWND hwnd
  709. )
  710. {
  711. CHECK_SIG(CSharingPropertyPage);
  712. appAssert(NULL != _pCurInfo);
  713. if (!_bDirty)
  714. {
  715. // nothing to validate
  716. return TRUE;
  717. }
  718. if (!_bShareNameChanged)
  719. {
  720. appDebugOut((DEB_ITRACE, "_ValidatePage: share name not changed!\n"));
  721. return TRUE;
  722. }
  723. delete[] _pszReplacePath;
  724. _pszReplacePath = NULL;
  725. WCHAR szShareName[MAX_PATH];
  726. GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName));
  727. TrimLeadingAndTrailingSpaces(szShareName);
  728. WCHAR szPath[MAX_PATH];
  729. GetDlgItemText(hwnd, IDC_SHARE_PATH, szPath, ARRAYLEN(szPath));
  730. // Validate the share
  731. if (0 == wcslen(szShareName))
  732. {
  733. MyErrorDialog(hwnd, IERR_BlankShareName);
  734. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  735. return FALSE;
  736. }
  737. HRESULT uTemp;
  738. if (!IsValidShareName(szShareName, &uTemp))
  739. {
  740. MyErrorDialog(hwnd, uTemp);
  741. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  742. return FALSE;
  743. }
  744. // Trying to create a reserved share?
  745. if ( (0 == _wcsicmp(g_szIpcShare, szShareName))
  746. || (0 == _wcsicmp(g_szAdminShare, szShareName)))
  747. {
  748. MyErrorDialog(hwnd, IERR_SpecialShare);
  749. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  750. return FALSE;
  751. }
  752. // If the user entered some ACL, warn them that we're going to nuke
  753. // it and let the system use its default (since special shares can't
  754. // have their security set).
  755. if (DriveLetterShare(szShareName))
  756. {
  757. if (_bSecDescChanged)
  758. {
  759. DWORD id = MyConfirmationDialog(
  760. hwnd,
  761. MSG_NOSECURITYONSPECIAL,
  762. MB_YESNO | MB_ICONEXCLAMATION);
  763. if (id == IDNO)
  764. {
  765. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  766. return FALSE;
  767. }
  768. _pCurInfo->TransferSecurityDescriptor(NULL);
  769. }
  770. }
  771. // Check for downlevel accessibility
  772. // CODEWORK we should really get rid of this at some point -- JonN 7/18/97
  773. ULONG nType;
  774. if (NERR_Success != NetpPathType(NULL, szShareName, &nType, INPT_FLAGS_OLDPATHS))
  775. {
  776. DWORD id = MyConfirmationDialog(
  777. hwnd,
  778. IERR_InaccessibleByDos,
  779. MB_YESNO | MB_ICONEXCLAMATION,
  780. szShareName);
  781. if (id == IDNO)
  782. {
  783. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  784. return FALSE;
  785. }
  786. }
  787. // Check to see that the same share isn't already used, for either the
  788. // same path or for another path.
  789. SHARE_INFO_502* info502;
  790. NET_API_STATUS ret = NetShareGetInfo(_pszMachine, szShareName, 502, (LPBYTE*)&info502);
  791. if (ret == NERR_Success)
  792. {
  793. // It is already shared. Same path?
  794. if (0 == _wcsicmp(info502->shi502_path, szPath))
  795. {
  796. MyErrorDialog(hwnd, IERR_AlreadyExists, szShareName);
  797. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  798. NetApiBufferFree(info502);
  799. return FALSE;
  800. }
  801. // Shared for a different path. Ask the user if they wish to delete
  802. // the old share and create the new one using the name.
  803. DWORD id = ConfirmReplaceShare(hwnd, szShareName, info502->shi502_path, szPath);
  804. if (id == IDNO)
  805. {
  806. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  807. NetApiBufferFree(info502);
  808. return FALSE;
  809. }
  810. else if (id == IDCANCEL)
  811. {
  812. // EndDialog(hwnd, FALSE); // BUGBUG: nuke page
  813. NetApiBufferFree(info502);
  814. return TRUE;
  815. }
  816. else
  817. {
  818. _pszReplacePath = NewDup(info502->shi502_path);
  819. if (NULL == _pszReplacePath)
  820. {
  821. NetApiBufferFree(info502);
  822. MyErrorDialog(hwnd, E_OUTOFMEMORY);
  823. return FALSE;
  824. }
  825. }
  826. NetApiBufferFree(info502);
  827. }
  828. else
  829. {
  830. // NetShareGetInfo failed. This is probably because there
  831. // is no share by this name, in which case it is a pure rename.
  832. appDebugOut((DEB_TRACE,
  833. "NetShareGetInfo failed, 0x%08lx\n",
  834. ret));
  835. }
  836. #if DBG == 1
  837. Dump(L"_ValidatePage finished");
  838. #endif // DBG == 1
  839. return TRUE;
  840. }
  841. //+-------------------------------------------------------------------------
  842. //
  843. // Method: CSharingPropertyPage::_DoApply, public
  844. //
  845. // Synopsis: If anything has changed, apply the data
  846. //
  847. //--------------------------------------------------------------------------
  848. BOOL
  849. CSharingPropertyPage::_DoApply(
  850. IN HWND hwnd
  851. )
  852. {
  853. CHECK_SIG(CSharingPropertyPage);
  854. if (_bDirty)
  855. {
  856. appAssert(NULL != _pCurInfo);
  857. NET_API_STATUS ret;
  858. HRESULT hr;
  859. // If either the share name changed or the path changed, we need
  860. // to delete the old share. If the share name changed, it is
  861. // because the user is renaming the share. If the path changed,
  862. // it is because the LanMan APIs don't allow a NetShareSetInfo
  863. // to change the shared path.
  864. if (_bShareNameChanged)
  865. {
  866. // The share name was changed. This is either a pure rename, in
  867. // which case the old share should be deleted and a share with
  868. // the new name created, or the user changed the share name to
  869. // the name of an already existing share, in which case both the
  870. // current share name as well as the share to be replaced must be
  871. // deleted.
  872. if (NULL != _pszReplacePath)
  873. {
  874. // user said to replace an existing share
  875. WCHAR szShareName[NNLEN + 1];
  876. GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName));
  877. TrimLeadingAndTrailingSpaces(szShareName);
  878. ret = NetShareDel(_pszMachine, szShareName, 0);
  879. if (ret != NERR_Success)
  880. {
  881. DisplayError(hwnd, IERR_CANT_DEL_SHARE, ret, szShareName);
  882. delete[] _pszReplacePath;
  883. _pszReplacePath = NULL;
  884. return FALSE;
  885. }
  886. else
  887. {
  888. SHChangeNotify(SHCNE_NETUNSHARE, SHCNF_PATH, _pszReplacePath, NULL);
  889. }
  890. delete[] _pszReplacePath;
  891. _pszReplacePath = NULL;
  892. }
  893. }
  894. if (_bShareNameChanged || _bPathChanged)
  895. {
  896. // delete the existing share
  897. ret = NetShareDel(_pszMachine, _pCurInfo->GetNetname(), 0);
  898. if (ret != NERR_Success)
  899. {
  900. DisplayError(hwnd, IERR_CANT_DEL_SHARE, ret, _pCurInfo->GetNetname());
  901. return FALSE;
  902. }
  903. else
  904. {
  905. // Only if the path changed in the rename should the shell
  906. // be notified
  907. if (_bPathChanged)
  908. {
  909. SHChangeNotify(SHCNE_NETUNSHARE, SHCNF_PATH, _pCurInfo->GetPath(), NULL);
  910. }
  911. }
  912. }
  913. if (_bShareNameChanged)
  914. {
  915. // User wants to rename the share.
  916. WCHAR szShareName[NNLEN + 1];
  917. _pCurInfo->SetDirtyFlag(SHARE_FLAG_ADDED); // special case
  918. GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName));
  919. TrimLeadingAndTrailingSpaces(szShareName);
  920. _pCurInfo->SetNetname(szShareName);
  921. }
  922. if (_bPathChanged)
  923. {
  924. WCHAR szPath[MAX_PATH];
  925. _pCurInfo->SetDirtyFlag(SHARE_FLAG_ADDED); // special case
  926. GetDlgItemText(hwnd, IDC_SHARE_PATH, szPath, ARRAYLEN(szPath));
  927. _pCurInfo->SetPath(szPath);
  928. }
  929. if (_bCommentChanged)
  930. {
  931. WCHAR szComment[MAXCOMMENTSZ + 1];
  932. GetDlgItemText(hwnd, IDC_SHARE_COMMENT, szComment, ARRAYLEN(szComment));
  933. _pCurInfo->SetRemark(szComment);
  934. }
  935. if (_bUserLimitChanged)
  936. {
  937. if (1 == IsDlgButtonChecked(hwnd, IDC_SHARE_MAXIMUM))
  938. {
  939. _pCurInfo->SetMaxUses(SHI_USES_UNLIMITED);
  940. }
  941. else if (1 == IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW))
  942. {
  943. _CacheMaxUses(hwnd);
  944. _pCurInfo->SetMaxUses(_wMaxUsers);
  945. }
  946. }
  947. //
  948. // Commit the changes!
  949. //
  950. ret = _pCurInfo->Commit(_pszMachine);
  951. if (ret != NERR_Success)
  952. {
  953. HRESULT hrMsg = 0;
  954. switch (_pCurInfo->GetFlag())
  955. {
  956. case SHARE_FLAG_ADDED: hrMsg = IERR_CANT_ADD_SHARE; break;
  957. case SHARE_FLAG_MODIFY: hrMsg = IERR_CANT_MODIFY_SHARE; break;
  958. default:
  959. appAssert(!"Illegal flag for a failed commit!");
  960. }
  961. DisplayError(hwnd, hrMsg, ret, _pCurInfo->GetNetname());
  962. }
  963. else
  964. {
  965. _pCurInfo->SetDirtyFlag(0); // clear flag on success
  966. }
  967. _bDirty = FALSE;
  968. _bShareNameChanged = FALSE;
  969. _bPathChanged = FALSE;
  970. _bCommentChanged = FALSE;
  971. _bUserLimitChanged = FALSE;
  972. _bSecDescChanged = FALSE;
  973. PropSheet_UnChanged(_GetFrameWindow(),_hwndPage);
  974. SHChangeNotify(SHCNE_NETSHARE, SHCNF_PATH, _pCurInfo->GetPath(), NULL);
  975. _InitializeControls(hwnd);
  976. }
  977. return TRUE;
  978. }
  979. //+-------------------------------------------------------------------------
  980. //
  981. // Method: CSharingPropertyPage::_DoCancel, public
  982. //
  983. // Synopsis: Do whatever is necessary to cancel the changes
  984. //
  985. //--------------------------------------------------------------------------
  986. BOOL
  987. CSharingPropertyPage::_DoCancel(
  988. IN HWND hwnd
  989. )
  990. {
  991. CHECK_SIG(CSharingPropertyPage);
  992. if (_bDirty)
  993. {
  994. _bDirty = FALSE;
  995. _bShareNameChanged = FALSE;
  996. _bPathChanged = FALSE;
  997. _bCommentChanged = FALSE;
  998. _bUserLimitChanged = FALSE;
  999. _bSecDescChanged = FALSE;
  1000. PropSheet_UnChanged(_GetFrameWindow(),_hwndPage);
  1001. }
  1002. return TRUE;
  1003. }
  1004. //+-------------------------------------------------------------------------
  1005. //
  1006. // Method: CSharingPropertyPage::_CacheMaxUses, private
  1007. //
  1008. // Synopsis:
  1009. //
  1010. //--------------------------------------------------------------------------
  1011. VOID
  1012. CSharingPropertyPage::_CacheMaxUses(
  1013. IN HWND hwnd
  1014. )
  1015. {
  1016. CHECK_SIG(CSharingPropertyPage);
  1017. DWORD dwRet = (DWORD)SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_GETPOS, 0, 0);
  1018. if (HIWORD(dwRet) != 0)
  1019. {
  1020. _wMaxUsers = DEFAULT_MAX_USERS;
  1021. // Reset the edit control to the new value
  1022. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0));
  1023. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  1024. }
  1025. else
  1026. {
  1027. _wMaxUsers = LOWORD(dwRet);
  1028. }
  1029. }
  1030. #if DBG == 1
  1031. //+-------------------------------------------------------------------------
  1032. //
  1033. // Method: CSharingPropertyPage::Dump, private
  1034. //
  1035. // Synopsis:
  1036. //
  1037. //--------------------------------------------------------------------------
  1038. VOID
  1039. CSharingPropertyPage::Dump(
  1040. IN PWSTR pszCaption
  1041. )
  1042. {
  1043. CHECK_SIG(CSharingPropertyPage);
  1044. appDebugOut((DEB_TRACE,
  1045. "CSharingPropertyPage::Dump, %ws\n",
  1046. pszCaption));
  1047. appDebugOut((DEB_TRACE | DEB_NOCOMPNAME,
  1048. "\t This: 0x%08lx\n"
  1049. "\t Page: 0x%08lx\n"
  1050. "\t Initializing?: %ws\n"
  1051. "\t Dirty?: %ws\n"
  1052. "\t Share changed?: %ws\n"
  1053. "\t Path changed?: %ws\n"
  1054. "\tComment changed?: %ws\n"
  1055. "\tUsr Lim changed?: %ws\n"
  1056. "\t Max uses: %d\n"
  1057. "\t _pCurInfo: 0x%08lx\n"
  1058. ,
  1059. this,
  1060. _hwndPage,
  1061. _fInitializingPage ? L"yes" : L"no",
  1062. _bDirty ? L"yes" : L"no",
  1063. _bShareNameChanged ? L"yes" : L"no",
  1064. _bPathChanged ? L"yes" : L"no",
  1065. _bCommentChanged ? L"yes" : L"no",
  1066. _bUserLimitChanged ? L"yes" : L"no",
  1067. _wMaxUsers,
  1068. _pCurInfo
  1069. ));
  1070. _pCurInfo->Dump(L"Current");
  1071. }
  1072. #endif // DBG == 1