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.

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