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

668 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: dlgnew.cxx
  7. //
  8. // Contents: "New Share" dialog
  9. //
  10. // History: 21-Feb-95 BruceFo Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "headers.hxx"
  14. #pragma hdrstop
  15. #include "resource.h"
  16. #include "helpids.h"
  17. #include "cache.hxx"
  18. #include "dlgnew.hxx"
  19. #include "acl.hxx"
  20. #include "util.hxx"
  21. #include "shrinfo.hxx"
  22. ////////////////////////////////////////////////////////////////////////////
  23. ////////////////////////////////////////////////////////////////////////////
  24. //+-------------------------------------------------------------------------
  25. //
  26. // Member: CDlgNewShare::SizeWndProc, public
  27. //
  28. // Synopsis: "allow" edit window subclass proc to disallow non-numeric
  29. // characters.
  30. //
  31. // History: 5-Apr-95 BruceFo Created
  32. //
  33. //--------------------------------------------------------------------------
  34. // NTRAID#NTBUG9-585729-2002/03/19 JonN Wouldn't it be easier to just use ES_NUMBER?
  35. LRESULT CALLBACK
  36. CDlgNewShare::SizeWndProc(
  37. IN HWND hwnd,
  38. IN UINT wMsg,
  39. IN WPARAM wParam,
  40. IN LPARAM lParam
  41. )
  42. {
  43. switch (wMsg)
  44. {
  45. case WM_CHAR:
  46. {
  47. WCHAR chCharCode = (WCHAR)wParam;
  48. if ( (chCharCode == TEXT('\t'))
  49. || (chCharCode == TEXT('\b'))
  50. || (chCharCode == TEXT('\n'))
  51. )
  52. {
  53. break;
  54. }
  55. if (chCharCode < TEXT('0') || chCharCode > TEXT('9'))
  56. {
  57. // bad key: ignore it
  58. MessageBeep(0xffffffff); // let user know it's an illegal char
  59. return FALSE;
  60. }
  61. break;
  62. }
  63. } // end of switch
  64. CDlgNewShare* pThis = (CDlgNewShare*)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
  65. // 585755-2002/03/21 handle NULL in pThis and pThis->_pfnAllowProc
  66. if (NULL == pThis || NULL == pThis->_pfnAllowProc)
  67. {
  68. appAssert(FALSE);
  69. return FALSE;
  70. }
  71. return CallWindowProc(pThis->_pfnAllowProc, hwnd, wMsg, wParam, lParam);
  72. }
  73. //+-------------------------------------------------------------------------
  74. //
  75. // Method: CDlgNewShare::CDlgNewShare, private
  76. //
  77. // Synopsis: constructor
  78. //
  79. //--------------------------------------------------------------------------
  80. CDlgNewShare::CDlgNewShare(
  81. IN HWND hwndParent
  82. )
  83. :
  84. CDialog(hwndParent, MAKEINTRESOURCE(IDD_NEW_SHARE)),
  85. // 2002/03/21-JonN: initialize m_pInfoList, m_pShareInfo, m_pReplaceList
  86. m_pInfoList(NULL),
  87. m_pShareInfo(NULL),
  88. m_pReplaceList(NULL),
  89. _bShareNameChanged(FALSE),
  90. _bCommentChanged(FALSE),
  91. _wMaxUsers(DEFAULT_MAX_USERS),
  92. _fSecDescModified(FALSE),
  93. _pStoredSecDesc(NULL),
  94. _pfnAllowProc(NULL)
  95. {
  96. INIT_SIG(CDlgNewShare);
  97. }
  98. //+-------------------------------------------------------------------------
  99. //
  100. // Method: CDlgNewShare::~CDlgNewShare, private
  101. //
  102. // Synopsis: destructor
  103. //
  104. // m_pInfoList, m_pShareInfo, and m_pReplaceList belong to the caller
  105. //
  106. //--------------------------------------------------------------------------
  107. CDlgNewShare::~CDlgNewShare()
  108. {
  109. CHECK_SIG(CDlgNewShare);
  110. }
  111. //+-------------------------------------------------------------------------
  112. //
  113. // Method: CDlgNewShare::DlgProc, private
  114. //
  115. // Synopsis: Dialog Procedure for this object
  116. //
  117. //--------------------------------------------------------------------------
  118. INT_PTR
  119. CDlgNewShare::DlgProc(
  120. IN HWND hwnd,
  121. IN UINT msg,
  122. IN WPARAM wParam,
  123. IN LPARAM lParam
  124. )
  125. {
  126. CHECK_SIG(CDlgNewShare);
  127. static DWORD aHelpIds[] =
  128. {
  129. IDOK, HC_OK,
  130. IDCANCEL, HC_CANCEL,
  131. IDC_SHARE_SHARENAME, HC_SHARE_SHARENAME,
  132. IDC_SHARE_SHARENAME_TEXT, HC_SHARE_SHARENAME,
  133. IDC_SHARE_COMMENT, HC_SHARE_COMMENT,
  134. IDC_SHARE_COMMENT_TEXT, HC_SHARE_COMMENT,
  135. IDC_SHARE_MAXIMUM, HC_SHARE_MAXIMUM,
  136. IDC_SHARE_ALLOW, HC_SHARE_ALLOW,
  137. IDC_SHARE_ALLOW_VALUE, HC_SHARE_ALLOW_VALUE,
  138. IDC_SHARE_ALLOW_SPIN, -1L, // 257807 by request of JillZ
  139. IDC_SHARE_PERMISSIONS, HC_SHARE_PERMISSIONS,
  140. IDC_SHARE_LIMIT, HC_SHARE_LIMIT,
  141. 0,0
  142. };
  143. switch (msg)
  144. {
  145. case WM_INITDIALOG:
  146. return _OnInitDialog(hwnd);
  147. case WM_COMMAND:
  148. return _OnCommand(hwnd, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
  149. case WM_VSCROLL:
  150. // The up/down control changed the edit control: select it again
  151. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  152. return TRUE;
  153. case WM_HELP:
  154. {
  155. LPHELPINFO lphi = (LPHELPINFO)lParam;
  156. if (lphi->iContextType == HELPINFO_WINDOW) // a control
  157. {
  158. WCHAR szHelp[50];
  159. LoadString(g_hInstance, IDS_HELPFILENAME, szHelp, ARRAYLEN(szHelp));
  160. WinHelp(
  161. (HWND)lphi->hItemHandle,
  162. szHelp,
  163. HELP_WM_HELP,
  164. (DWORD_PTR)aHelpIds);
  165. }
  166. break;
  167. }
  168. case WM_CONTEXTMENU:
  169. {
  170. WCHAR szHelp[50];
  171. LoadString(g_hInstance, IDS_HELPFILENAME, szHelp, ARRAYLEN(szHelp));
  172. WinHelp(
  173. (HWND)wParam,
  174. szHelp,
  175. HELP_CONTEXTMENU,
  176. (DWORD_PTR)aHelpIds);
  177. break;
  178. }
  179. case WM_DESTROY:
  180. {
  181. // restore original subclass to window.
  182. appAssert(NULL != GetDlgItem(hwnd,IDC_SHARE_ALLOW_VALUE));
  183. SetWindowLongPtr(GetDlgItem(hwnd,IDC_SHARE_ALLOW_VALUE), GWLP_WNDPROC, (LONG_PTR)_pfnAllowProc);
  184. return FALSE;
  185. }
  186. } // end of switch
  187. return FALSE;
  188. }
  189. //+-------------------------------------------------------------------------
  190. //
  191. // Method: CDlgNewShare::_OnInitDialog, private
  192. //
  193. // Synopsis: WM_INITDIALOG handler
  194. //
  195. //--------------------------------------------------------------------------
  196. BOOL
  197. CDlgNewShare::_OnInitDialog(
  198. IN HWND hwnd
  199. )
  200. {
  201. CHECK_SIG(CDlgNewShare);
  202. // Subclass allow edit control to disallow non-positive numbers
  203. _pfnAllowProc = (WNDPROC)SetWindowLongPtr(
  204. GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE),
  205. GWLP_WNDPROC,
  206. (LONG_PTR)&SizeWndProc);
  207. // use LanMan API constants to set maximum share name & comment lengths
  208. SendDlgItemMessage(hwnd, IDC_SHARE_SHARENAME, EM_LIMITTEXT, NNLEN, 0L);
  209. SendDlgItemMessage(hwnd, IDC_SHARE_COMMENT, EM_LIMITTEXT, MAXCOMMENTSZ, 0L);
  210. CheckRadioButton(
  211. hwnd,
  212. IDC_SHARE_MAXIMUM,
  213. IDC_SHARE_ALLOW,
  214. IDC_SHARE_MAXIMUM);
  215. SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L"");
  216. // set the spin control range: 1 <--> large number
  217. SendDlgItemMessage(
  218. hwnd,
  219. IDC_SHARE_ALLOW_SPIN,
  220. UDM_SETRANGE,
  221. 0,
  222. MAKELONG(g_uiMaxUsers, 1));
  223. SetFocus(GetDlgItem(hwnd, IDC_SHARE_SHARENAME));
  224. return FALSE;
  225. }
  226. //+-------------------------------------------------------------------------
  227. //
  228. // Member: CDlgNewShare::_OnCommand, private
  229. //
  230. // Synopsis: WM_COMMAND handler
  231. //
  232. // History: 21-Apr-95 BruceFo Created
  233. //
  234. //--------------------------------------------------------------------------
  235. BOOL
  236. CDlgNewShare::_OnCommand(
  237. IN HWND hwnd,
  238. IN WORD wNotifyCode,
  239. IN WORD wID,
  240. IN HWND hwndCtl
  241. )
  242. {
  243. CHECK_SIG(CDlgNewShare);
  244. switch (wID)
  245. {
  246. //
  247. // Notifications
  248. //
  249. case IDC_SHARE_MAXIMUM:
  250. if (BN_CLICKED == wNotifyCode)
  251. {
  252. // Take away WS_TABSTOP from the "allow users" edit control
  253. HWND hwndEdit = GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE);
  254. SetWindowLong(hwndEdit, GWL_STYLE, GetWindowLong(hwndEdit, GWL_STYLE) & ~WS_TABSTOP);
  255. _CacheMaxUses(hwnd);
  256. SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L"");
  257. }
  258. return TRUE;
  259. case IDC_SHARE_ALLOW:
  260. if (BN_CLICKED == wNotifyCode)
  261. {
  262. // Give WS_TABSTOP to the "allow users" edit control
  263. HWND hwndEdit = GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE);
  264. SetWindowLong(hwndEdit, GWL_STYLE, GetWindowLong(hwndEdit, GWL_STYLE) | WS_TABSTOP);
  265. // let the spin control set the edit control
  266. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0));
  267. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  268. }
  269. return TRUE;
  270. case IDC_SHARE_ALLOW_VALUE:
  271. {
  272. if (EN_SETFOCUS == wNotifyCode)
  273. {
  274. if (1 != IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW))
  275. {
  276. CheckRadioButton(
  277. hwnd,
  278. IDC_SHARE_MAXIMUM,
  279. IDC_SHARE_ALLOW,
  280. IDC_SHARE_ALLOW);
  281. }
  282. // let the spin control set the edit control
  283. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0));
  284. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  285. }
  286. if (EN_KILLFOCUS == wNotifyCode)
  287. {
  288. _CacheMaxUses(hwnd);
  289. }
  290. return TRUE;
  291. }
  292. case IDC_SHARE_ALLOW_SPIN:
  293. if (UDN_DELTAPOS == wNotifyCode)
  294. {
  295. if (1 != IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW))
  296. {
  297. CheckRadioButton(
  298. hwnd,
  299. IDC_SHARE_MAXIMUM,
  300. IDC_SHARE_ALLOW,
  301. IDC_SHARE_ALLOW);
  302. }
  303. }
  304. return TRUE;
  305. case IDC_SHARE_SHARENAME:
  306. {
  307. if (wNotifyCode == EN_CHANGE)
  308. {
  309. _bShareNameChanged = TRUE;
  310. }
  311. return TRUE;
  312. }
  313. case IDC_SHARE_COMMENT:
  314. {
  315. if (wNotifyCode == EN_CHANGE)
  316. {
  317. _bCommentChanged = TRUE;
  318. }
  319. return TRUE;
  320. }
  321. //
  322. // Commands
  323. //
  324. case IDOK:
  325. return _OnOK(hwnd);
  326. case IDCANCEL:
  327. EndDialog(hwnd, FALSE);
  328. return TRUE;
  329. case IDC_SHARE_PERMISSIONS:
  330. return _OnPermissions(hwnd);
  331. } // end of switch (wID)
  332. return FALSE;
  333. }
  334. //+-------------------------------------------------------------------------
  335. //
  336. // Method: CDlgNewShare::_OnOK, private
  337. //
  338. // Synopsis:
  339. //
  340. //--------------------------------------------------------------------------
  341. BOOL
  342. CDlgNewShare::_OnOK(
  343. IN HWND hwnd
  344. )
  345. {
  346. CHECK_SIG(CDlgNewShare);
  347. HRESULT hr;
  348. // Validate the share
  349. WCHAR szShareName[NNLEN + 1];
  350. ZeroMemory( szShareName, sizeof(szShareName) ); // 2002/03/21-JonN initialize
  351. if (0 == GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName)))
  352. {
  353. MyErrorDialog(hwnd, IERR_BlankShareName);
  354. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  355. return TRUE;
  356. }
  357. TrimLeadingAndTrailingSpaces(szShareName);
  358. HRESULT uTemp;
  359. if (!IsValidShareName(szShareName, &uTemp))
  360. {
  361. MyErrorDialog(hwnd, uTemp);
  362. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  363. return TRUE;
  364. }
  365. // Trying to create a reserved share?
  366. if (0 == _wcsicmp(g_szIpcShare, szShareName))
  367. {
  368. MyErrorDialog(hwnd, IERR_SpecialShare);
  369. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  370. return TRUE;
  371. }
  372. if (0 == _wcsicmp(g_szAdminShare, szShareName))
  373. {
  374. // We will let the admin create the admin$ share if they create
  375. // it in the directory specified by GetWindowsDirectory().
  376. WCHAR szWindowsDir[MAX_PATH];
  377. UINT err = GetWindowsDirectory(szWindowsDir, ARRAYLEN(szWindowsDir));
  378. if (err == 0)
  379. {
  380. // oh well, give them this error
  381. MyErrorDialog(hwnd, IERR_SpecialShare);
  382. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  383. return FALSE;
  384. }
  385. if (0 != _wcsicmp(m_pShareInfo->GetPath(), szWindowsDir))
  386. {
  387. MyErrorDialog(hwnd, IERR_SpecialShare);
  388. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  389. return FALSE;
  390. }
  391. // otherwise, it is the right directory. Let them create it.
  392. }
  393. // Check to see that the same share doesn't already exist. We don't allow
  394. // the user to create a share with the same name as a marked-for-delete
  395. // share, because it's easier!
  396. for (CShareInfo* p = (CShareInfo*) m_pInfoList->Next();
  397. p != m_pInfoList;
  398. p = (CShareInfo*) p->Next())
  399. {
  400. if (0 == _wcsicmp(p->GetNetname(), szShareName))
  401. {
  402. MyErrorDialog(hwnd, IERR_AlreadyExists, szShareName);
  403. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  404. return TRUE;
  405. }
  406. }
  407. /* removed JonN 10/5/98
  408. // Check for downlevel accessibility
  409. // we should really get rid of this at some point -- JonN 7/18/97
  410. ULONG nType;
  411. if (NERR_Success != NetpPathType(NULL, szShareName, &nType, INPT_FLAGS_OLDPATHS))
  412. {
  413. DWORD id = MyConfirmationDialog(
  414. hwnd,
  415. IERR_InaccessibleByDos,
  416. MB_YESNO | MB_ICONEXCLAMATION,
  417. szShareName);
  418. if (id == IDNO)
  419. {
  420. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  421. return TRUE;
  422. }
  423. }
  424. */
  425. WCHAR szOldPath[PATHLEN + 1];
  426. if (g_ShareCache.IsExistingShare(szShareName, m_pShareInfo->GetPath(),
  427. szOldPath, ARRAYLEN(szOldPath))) // 585682-2002/04/12-JonN
  428. {
  429. DWORD id = ConfirmReplaceShare(hwnd, szShareName, szOldPath, m_pShareInfo->GetPath());
  430. if (id != IDYES)
  431. {
  432. SetErrorFocus(hwnd, IDC_SHARE_SHARENAME);
  433. return TRUE;
  434. }
  435. // User said to replace the old share. We need to add
  436. // a "delete" record for the old share.
  437. CShareInfo* pOldInfo = new CShareInfo();
  438. if (NULL == pOldInfo)
  439. {
  440. return FALSE;
  441. }
  442. hr = pOldInfo->InitInstance();
  443. CHECK_HRESULT(hr);
  444. if (FAILED(hr))
  445. {
  446. delete pOldInfo;
  447. return FALSE;
  448. }
  449. hr = pOldInfo->SetNetname(szShareName);
  450. CHECK_HRESULT(hr);
  451. if (FAILED(hr))
  452. {
  453. delete pOldInfo;
  454. return FALSE;
  455. }
  456. hr = pOldInfo->SetPath(szOldPath);
  457. CHECK_HRESULT(hr);
  458. if (FAILED(hr))
  459. {
  460. delete pOldInfo;
  461. return FALSE;
  462. }
  463. // NTRAID#NTBUG9-603727-2002/04/15 JonN
  464. // This could happen due to API failure.
  465. // I don't see any good reason to call ReadCacheFlags,
  466. // since we're just going to delete the share anyhow.
  467. NET_API_STATUS ret = pOldInfo->ReadCacheFlags ();
  468. appAssert( NERR_Success == ret );
  469. /*
  470. if ( NERR_Success != ret )
  471. {
  472. delete pOldInfo;
  473. return HRESULT_FROM_WIN32 (ret);
  474. }
  475. */
  476. pOldInfo->SetDirtyFlag(SHARE_FLAG_REMOVE);
  477. pOldInfo->InsertBefore(m_pReplaceList); // add to end of replace list
  478. }
  479. // Everything OK, save away the data
  480. if (_bShareNameChanged)
  481. {
  482. hr = m_pShareInfo->SetNetname(szShareName);
  483. CHECK_HRESULT(hr);
  484. }
  485. if (_bCommentChanged)
  486. {
  487. WCHAR szComment[MAXCOMMENTSZ + 1];
  488. ZeroMemory( szComment, sizeof(szComment) ); // 2002/03/21-JonN initialize
  489. GetDlgItemText(hwnd, IDC_SHARE_COMMENT, szComment, ARRAYLEN(szComment));
  490. hr = m_pShareInfo->SetRemark(szComment);
  491. CHECK_HRESULT(hr);
  492. }
  493. if (1 == IsDlgButtonChecked(hwnd, IDC_SHARE_MAXIMUM))
  494. {
  495. hr = m_pShareInfo->SetMaxUses(SHI_USES_UNLIMITED);
  496. CHECK_HRESULT(hr);
  497. }
  498. else if (1 == IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW))
  499. {
  500. _CacheMaxUses(hwnd);
  501. hr = m_pShareInfo->SetMaxUses(_wMaxUsers);
  502. CHECK_HRESULT(hr);
  503. }
  504. EndDialog(hwnd, TRUE);
  505. return TRUE;
  506. }
  507. //+-------------------------------------------------------------------------
  508. //
  509. // Method: CDlgNewShare::_OnPermissions, private
  510. //
  511. // Synopsis:
  512. //
  513. //--------------------------------------------------------------------------
  514. BOOL
  515. CDlgNewShare::_OnPermissions(
  516. IN HWND hwnd
  517. )
  518. {
  519. CHECK_SIG(CDlgNewShare);
  520. WCHAR szShareName[NNLEN + 1];
  521. ZeroMemory( szShareName, sizeof(szShareName) ); // 2002/03/21-JonN initialize
  522. GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName));
  523. // don't trim spaces, this might be an existing share with spaces in its name
  524. PSECURITY_DESCRIPTOR pNewSecDesc = NULL;
  525. PSECURITY_DESCRIPTOR pSecDesc = m_pShareInfo->GetSecurityDescriptor();
  526. // 2002/03/21-JonN handle these cases
  527. if (!pSecDesc || !IsValidSecurityDescriptor(pSecDesc))
  528. {
  529. appAssert(FALSE);
  530. return FALSE;
  531. }
  532. BOOL bSecDescChanged = FALSE; // 2002/03/21-JonN initialize
  533. LONG err = EditShareAcl(
  534. hwnd,
  535. NULL,
  536. szShareName,
  537. pSecDesc,
  538. &bSecDescChanged,
  539. &pNewSecDesc);
  540. if (bSecDescChanged)
  541. {
  542. _fSecDescModified = TRUE;
  543. appAssert(IsValidSecurityDescriptor(pNewSecDesc));
  544. m_pShareInfo->TransferSecurityDescriptor(pNewSecDesc);
  545. }
  546. return TRUE;
  547. }
  548. //+-------------------------------------------------------------------------
  549. //
  550. // Method: CDlgNewShare::_CacheMaxUses, private
  551. //
  552. // Synopsis:
  553. //
  554. //--------------------------------------------------------------------------
  555. VOID
  556. CDlgNewShare::_CacheMaxUses(
  557. IN HWND hwnd
  558. )
  559. {
  560. DWORD dwRet = (DWORD)SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_GETPOS, 0, 0);
  561. if (HIWORD(dwRet) != 0)
  562. {
  563. _wMaxUsers = DEFAULT_MAX_USERS;
  564. // Reset the edit control to the new value
  565. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0));
  566. SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1);
  567. }
  568. else
  569. {
  570. _wMaxUsers = LOWORD(dwRet);
  571. }
  572. }