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.

567 lines
14 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1994 **
  4. //*********************************************************************
  5. #include "admincfg.h"
  6. #include <choosusr.h>
  7. #include <lmerr.h>
  8. #include <shlobj.h>
  9. #include <shlobjp.h>
  10. #include <getuser.h>
  11. //
  12. // Help ID's
  13. //
  14. #define IDH_ADD_USERS 1
  15. #define IDH_ADD_GROUPS 2
  16. typedef struct tagADDINFO {
  17. DWORD dwType;
  18. DWORD dwPlatformType;
  19. } ADDINFO;
  20. INT_PTR CALLBACK AddThingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  21. LPARAM lParam);
  22. BOOL ProcessAddThingDlg(HWND hDlg);
  23. BOOL OnBrowse(HWND hDlg);
  24. DWORD dwPlatform=0;
  25. #ifndef SV_SECURITY_SHARE
  26. // from dev\inc\svrapi.h
  27. #define SV_SECURITY_SHARE 0 /* Share-level */
  28. #endif
  29. //
  30. // Function typedefs for User Browser on NT
  31. //
  32. typedef HUSERBROW (WINAPI *LPFNOPENUSERBROWSER)(LPUSERBROWSER lpUserParms);
  33. typedef BOOL (WINAPI *LPFNENUMUSERBROWSERSELECTION)( HUSERBROW hHandle,
  34. LPUSERDETAILS lpUser,
  35. DWORD *plBufferSize );
  36. typedef BOOL (WINAPI *LPFNCLOSEUSERBROWSER)(HUSERBROW hHandle);
  37. BOOL DoAddUserDlg(HWND hwndApp,HWND hwndList)
  38. {
  39. ADDINFO AddInfo;
  40. AddInfo.dwType = UT_USER;
  41. DialogBoxParam(ghInst,MAKEINTRESOURCE(DLG_ADDUSER),hwndApp,
  42. AddThingDlgProc,(LPARAM) &AddInfo);
  43. return TRUE;
  44. }
  45. #ifdef INCL_GROUP_SUPPORT
  46. BOOL DoAddGroupDlg(HWND hwndApp,HWND hwndList)
  47. {
  48. ADDINFO AddInfo;
  49. AddInfo.dwType = UT_USER | UF_GROUP;
  50. DialogBoxParam(ghInst,MAKEINTRESOURCE(DLG_ADDUSER),hwndApp,
  51. AddThingDlgProc,(LPARAM) &AddInfo);
  52. return TRUE;
  53. }
  54. #endif
  55. BOOL DoAddComputerDlg(HWND hwndApp,HWND hwndList)
  56. {
  57. ADDINFO AddInfo;
  58. AddInfo.dwType = UT_MACHINE;
  59. DialogBoxParam(ghInst,MAKEINTRESOURCE(DLG_ADDWORKSTATION),hwndApp,
  60. AddThingDlgProc,(LPARAM) &AddInfo);
  61. return TRUE;
  62. }
  63. INT_PTR CALLBACK AddThingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  64. LPARAM lParam)
  65. {
  66. switch (uMsg) {
  67. case WM_INITDIALOG:
  68. {
  69. ADDINFO * pAddInfo = (ADDINFO *) lParam;
  70. // limit edit field length
  71. SendDlgItemMessage(hDlg,IDD_NAME,EM_LIMITTEXT,USERNAMELEN,0L);
  72. if (!g_bWinnt) {
  73. // get the platform type to see if pass-through security
  74. // is enabled
  75. pAddInfo->dwPlatformType = SV_SECURITY_SHARE;
  76. ReadRegistryDWordValue(HKEY_LOCAL_MACHINE,(TCHAR *) szProviderKey,
  77. (TCHAR *) szValuePlatform,&pAddInfo->dwPlatformType);
  78. }
  79. // if no network installed, or this is an "add user" dialog
  80. // and user-level security is not enabled (e.g. can't call
  81. // ChooseUser), then hide "browse" button
  82. if (!fNetworkInstalled ||
  83. (!g_bWinnt &&
  84. (pAddInfo->dwType & UT_USER) &&
  85. (pAddInfo->dwPlatformType == SV_SECURITY_SHARE)) ) {
  86. ShowWindow(GetDlgItem(hDlg,IDD_BROWSE),SW_HIDE);
  87. }
  88. // if this is a group dialog, change the text to say
  89. // "enter the name of the group" (rather than "user")
  90. if (pAddInfo->dwType == (UT_USER | UF_GROUP)) {
  91. TCHAR szTxt[255];
  92. SetWindowText(hDlg,LoadSz(IDS_GROUPDLGTITLE,
  93. szTxt,ARRAYSIZE(szTxt)));
  94. SetDlgItemText(hDlg,IDD_TX2,LoadSz(IDS_GROUPDLGTXT,
  95. szTxt,ARRAYSIZE(szTxt)));
  96. }
  97. // store away pointer to ADDINFO
  98. SetWindowLongPtr(hDlg,DWLP_USER,(LPARAM) pAddInfo);
  99. }
  100. return TRUE;
  101. case WM_COMMAND:
  102. switch (wParam) {
  103. case IDOK:
  104. if (ProcessAddThingDlg(hDlg))
  105. EndDialog(hDlg,TRUE);
  106. return TRUE;
  107. break;
  108. case IDCANCEL:
  109. EndDialog(hDlg,FALSE);
  110. return TRUE;
  111. break;
  112. case IDD_BROWSE:
  113. if (OnBrowse(hDlg))
  114. EndDialog(hDlg,TRUE);
  115. break;
  116. }
  117. break;
  118. default:
  119. return FALSE;
  120. }
  121. return FALSE;
  122. }
  123. BOOL ProcessAddThingDlg(HWND hDlg)
  124. {
  125. TCHAR szName[USERNAMELEN+1];
  126. ADDINFO * pAddInfo;
  127. // fetch the pointer to ADDINFO struct out of window data
  128. pAddInfo = (ADDINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  129. if (!pAddInfo) return FALSE;
  130. // make sure there's an entry, check for duplicates
  131. if (!GetDlgItemText(hDlg,IDD_NAME,szName,ARRAYSIZE(szName))) {
  132. MsgBox(hDlg,(pAddInfo->dwType == UT_USER ?
  133. IDS_NEEDUSERNAME : IDS_NEEDWORKSTANAME),MB_ICONEXCLAMATION,
  134. MB_OK);
  135. SetFocus(GetDlgItem(hDlg,IDD_NAME));
  136. SendDlgItemMessage(hDlg,IDD_NAME,EM_SETSEL,0,(LPARAM) -1);
  137. return FALSE;
  138. }
  139. if (FindUser(hwndUser,szName,pAddInfo->dwType)) {
  140. UINT uID = 0;
  141. switch (pAddInfo->dwType) {
  142. case UT_USER:
  143. uID = IDS_DUPLICATEUSER;
  144. break;
  145. case UT_USER | UF_GROUP:
  146. uID = IDS_DUPLICATEGROUP;
  147. break;
  148. case UT_MACHINE:
  149. uID = IDS_DUPLICATEWORKSTA;
  150. break;
  151. }
  152. MsgBox(hDlg,uID,MB_ICONEXCLAMATION,MB_OK);
  153. SetFocus(GetDlgItem(hDlg,IDD_NAME));
  154. SendDlgItemMessage(hDlg,IDD_NAME,EM_SETSEL,0,(LPARAM) -1);
  155. return FALSE;
  156. }
  157. if (AddUser(hwndUser,szName,pAddInfo->dwType)) {
  158. dwAppState |= AS_FILEDIRTY;
  159. if (pAddInfo->dwType == (UT_USER | UF_GROUP))
  160. AddGroupPriEntry(szName);
  161. EnableMenuItems(hwndMain,dwAppState);
  162. SetStatusItemCount(hwndUser);
  163. } else {
  164. MsgBox(hwndMain,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  165. return FALSE;
  166. }
  167. return TRUE;
  168. }
  169. HGLOBAL FindUser(HWND hwndList,TCHAR * pszName,DWORD dwType)
  170. {
  171. int iStart = -1;
  172. LV_FINDINFO lvfi;
  173. BOOL fFound = FALSE;
  174. HGLOBAL hUser;
  175. USERDATA * pUserData;
  176. lvfi.flags = LVFI_STRING | LVFI_NOCASE;
  177. lvfi.psz = pszName;
  178. // try to find specified user name in policy file. If it's there, use it
  179. while (!fFound && (iStart=ListView_FindItem(hwndUser,iStart,&lvfi)) >= 0) {
  180. hUser=(HGLOBAL) LongToHandle(ListView_GetItemParm(hwndUser,iStart));
  181. if (hUser && (pUserData = (USERDATA *) GlobalLock(hUser))) {
  182. if (pUserData->hdr.dwType == dwType)
  183. fFound = TRUE;
  184. GlobalUnlock(hUser);
  185. }
  186. }
  187. if (fFound)
  188. return hUser;
  189. else return NULL;
  190. }
  191. #define USERBUFSIZE 8192 // 8K buffer to receive names
  192. BOOL OnBrowse(HWND hDlg)
  193. {
  194. HGLOBAL hMem;
  195. UINT nIndex;
  196. HINSTANCE hinstDll=NULL;
  197. LPFNCU lpChooseUser=NULL;
  198. ADDINFO * pAddInfo;
  199. BOOL fError=FALSE,fAdded=FALSE;
  200. #ifndef INCL_GROUP_SUPPORT
  201. BOOL fFoundGroup=FALSE;
  202. #endif
  203. CHOOSEUSER ChooseUserStruct;
  204. LPCHOOSEUSERENTRY lpCUE;
  205. DWORD err;
  206. TCHAR szBtnText[REGBUFLEN];
  207. HKEY hkey=NULL;
  208. // fetch the pointer to ADDINFO struct out of window data
  209. pAddInfo = (ADDINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  210. if (!pAddInfo) return FALSE;
  211. // if this is an "add computer" dialog, browse for computer
  212. if (pAddInfo->dwType & UT_MACHINE) {
  213. BROWSEINFO BrowseInfo;
  214. LPITEMIDLIST pidlComputer;
  215. TCHAR szRemoteName[MAX_PATH];
  216. BrowseInfo.hwndOwner = hDlg;
  217. BrowseInfo.pidlRoot = (LPITEMIDLIST) MAKEINTRESOURCE(CSIDL_NETWORK);
  218. BrowseInfo.pszDisplayName = szRemoteName;
  219. BrowseInfo.lpszTitle = LoadSz(IDS_COMPUTERBROWSETITLE,szSmallBuf,ARRAYSIZE(szSmallBuf));
  220. BrowseInfo.ulFlags = BIF_BROWSEFORCOMPUTER;
  221. BrowseInfo.lpfn = NULL;
  222. if ((pidlComputer = SHBrowseForFolder(&BrowseInfo)) != NULL) {
  223. SHFree(pidlComputer);
  224. if (!AddUser(hwndUser,szRemoteName,UT_MACHINE)) {
  225. MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  226. return FALSE;
  227. }
  228. return TRUE;
  229. }
  230. return FALSE;
  231. }
  232. //
  233. // This is an "Add User" dialog. If we are on NT, then
  234. // we can use the User Browser. For Windows will use
  235. // ChooseUser function.
  236. //
  237. if (g_bWinnt) {
  238. LPFNOPENUSERBROWSER lpOpenUserBrowser;
  239. LPFNENUMUSERBROWSERSELECTION lpEnumUserBrowserSelection;
  240. LPFNCLOSEUSERBROWSER lpCloseUserBrowser;
  241. USERBROWSER UserParms;
  242. HUSERBROW hBrowse;
  243. LPUSERDETAILS lpUserDetails;
  244. DWORD dwSize = 1024;
  245. WCHAR szTitle[100];
  246. TCHAR szUserName[200];
  247. hinstDll = LoadLibrary (TEXT("netui2.dll"));
  248. if (!hinstDll) {
  249. MsgBox(hDlg,IDS_CANTLOADNETUI2,MB_ICONEXCLAMATION,MB_OK);
  250. return FALSE;
  251. }
  252. lpOpenUserBrowser = (LPFNOPENUSERBROWSER) GetProcAddress(hinstDll,
  253. "OpenUserBrowser");
  254. lpEnumUserBrowserSelection = (LPFNENUMUSERBROWSERSELECTION) GetProcAddress(hinstDll,
  255. "EnumUserBrowserSelection");
  256. lpCloseUserBrowser = (LPFNCLOSEUSERBROWSER) GetProcAddress(hinstDll,
  257. "CloseUserBrowser");
  258. if (!lpOpenUserBrowser || !lpEnumUserBrowserSelection ||
  259. !lpCloseUserBrowser) {
  260. return FALSE;
  261. }
  262. lpUserDetails = GlobalAlloc (GPTR, dwSize);
  263. if (!lpUserDetails) {
  264. return FALSE;
  265. }
  266. UserParms.ulStructSize = sizeof(USERBROWSER);
  267. UserParms.fExpandNames = FALSE;
  268. UserParms.hwndOwner = hDlg;
  269. UserParms.pszTitle = szTitle;
  270. UserParms.pszInitialDomain = NULL;
  271. UserParms.pszHelpFileName = L"POLEDIT.CHM";
  272. if (pAddInfo->dwType & UF_GROUP) {
  273. LoadStringW(ghInst, IDS_ADDGROUPS, szTitle, 100);
  274. UserParms.Flags = USRBROWS_SHOW_GROUPS;
  275. UserParms.ulHelpContext = IDH_ADD_GROUPS;
  276. } else {
  277. LoadStringW(ghInst, IDS_ADDUSERS, szTitle, 100);
  278. UserParms.Flags = USRBROWS_SHOW_USERS;
  279. UserParms.ulHelpContext = IDH_ADD_USERS;
  280. }
  281. //
  282. // Display the dialog box
  283. //
  284. hBrowse = lpOpenUserBrowser (&UserParms);
  285. if (!hBrowse) {
  286. GlobalFree (lpUserDetails);
  287. return FALSE;
  288. }
  289. //
  290. // Get the user's selection
  291. //
  292. while (lpEnumUserBrowserSelection (hBrowse, lpUserDetails, &dwSize)) {
  293. #ifdef UNICODE
  294. lstrcpy (szUserName, lpUserDetails->pszAccountName);
  295. #else
  296. WideCharToMultiByte(CP_ACP, 0, lpUserDetails->pszAccountName,
  297. -1, szUserName, 200, NULL, NULL);
  298. #endif
  299. //
  300. // Now add the user or group
  301. //
  302. if (pAddInfo->dwType & UF_GROUP) {
  303. if (AddUser(hwndUser, szUserName, UT_USER | UF_GROUP)) {
  304. fError = TRUE;
  305. AddGroupPriEntry(szUserName);
  306. } else {
  307. MsgBox(hDlg,IDS_ERRORADDINGUSERS,MB_ICONEXCLAMATION,MB_OK);
  308. }
  309. } else {
  310. if (AddUser(hwndUser, szUserName, UT_USER)) {
  311. fError = TRUE;
  312. } else {
  313. MsgBox(hDlg,IDS_ERRORADDINGUSERS,MB_ICONEXCLAMATION,MB_OK);
  314. }
  315. }
  316. }
  317. //
  318. // Cleanup
  319. //
  320. lpCloseUserBrowser (hBrowse);
  321. GlobalFree (lpUserDetails);
  322. return fError;
  323. }
  324. // this an "add user" dialog, call ChooseUser
  325. hMem = GlobalAlloc(GPTR,USERBUFSIZE);
  326. if (!hMem) {
  327. MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONSTOP,MB_OK);
  328. return FALSE;
  329. }
  330. LoadSz(IDS_ADDBUTTON,szBtnText,ARRAYSIZE(szBtnText));
  331. memset(&ChooseUserStruct,0,sizeof(ChooseUserStruct));
  332. ChooseUserStruct.lStructSize = sizeof(ChooseUserStruct);
  333. ChooseUserStruct.hwndOwner = hDlg;
  334. ChooseUserStruct.hInstance = ghInst;
  335. ChooseUserStruct.Flags = 0;
  336. ChooseUserStruct.nBins = 1;
  337. ChooseUserStruct.lpszDialogTitle = NULL;
  338. ChooseUserStruct.lpszProvider = NULL;
  339. ChooseUserStruct.lpszBinButtonText[0] = szBtnText;
  340. ChooseUserStruct.dwBinValue[0] = 1;
  341. ChooseUserStruct.lpBuf = hMem;
  342. ChooseUserStruct.cbBuf = USERBUFSIZE;
  343. hinstDll = LoadLibrary(LoadSz(IDS_CHOOSUSRDLL,szSmallBuf,ARRAYSIZE(szSmallBuf)));
  344. if (hinstDll) {
  345. lpChooseUser = (LPFNCU) GetProcAddress(hinstDll,"ChooseUser");
  346. }
  347. if (!hinstDll || !lpChooseUser) {
  348. MsgBox(hDlg,IDS_CANTLOADCHOOSUSR,MB_ICONEXCLAMATION,MB_OK);
  349. if (hinstDll) FreeLibrary(hinstDll);
  350. return FALSE;
  351. }
  352. lpChooseUser(&ChooseUserStruct);
  353. FreeLibrary(hinstDll);
  354. if ( (err = ChooseUserStruct.dwError) != NERR_Success) {
  355. UINT uMsg;
  356. switch (err) {
  357. case CUERR_NO_AB_PROVIDER:
  358. uMsg = IDS_NOPROVIDER;
  359. break;
  360. case CUERR_INVALID_AB_PROVIDER:
  361. uMsg = IDS_INVALIDPROVIDER;
  362. break;
  363. case CUERR_PROVIDER_ERROR:
  364. default:
  365. uMsg = IDS_PROVIDERERROR;
  366. break;
  367. }
  368. MsgBox(hDlg,uMsg,MB_ICONSTOP,MB_OK);
  369. return FALSE;
  370. }
  371. lpCUE = (LPCHOOSEUSERENTRY) hMem;
  372. for (nIndex = 0;nIndex<ChooseUserStruct.nEntries;nIndex++) {
  373. // see if user is already in listbox
  374. if (lpCUE->lpszShortName &&
  375. !FindUser(hwndUser,lpCUE->lpszShortName,pAddInfo->dwType)) {
  376. // add user to list control. If error, keep going and try to
  377. // add others, report error later
  378. LPTSTR lpszName = lpCUE->lpszShortName;
  379. BOOL fFoundSlash = FALSE;
  380. #ifndef INCL_GROUP_SUPPORT
  381. if (lpCUE->dwEntryAttributes & (CUE_ATTR_GROUP | CUE_ATTR_WORLD)) {
  382. // user tried to add group, not supported
  383. fFoundGroup = TRUE;
  384. lpCUE++;
  385. continue;
  386. }
  387. #endif
  388. // names come back container-qualified from choosusr--
  389. // e.g. <domain>\<user name>. Strip out the container
  390. // qualification
  391. while (*lpszName && !fFoundSlash) {
  392. if (*lpszName == TEXT('\\')) {
  393. fFoundSlash = TRUE;
  394. }
  395. lpszName = CharNext(lpszName);
  396. }
  397. if (!fFoundSlash)
  398. lpszName = lpCUE->lpszShortName;
  399. if (!AddUser(hwndUser,lpszName,(lpCUE->dwEntryAttributes &
  400. (CUE_ATTR_GROUP | CUE_ATTR_WORLD) ? UT_USER | UF_GROUP :
  401. UT_USER) ))
  402. fError = TRUE;
  403. else {
  404. fAdded = TRUE;
  405. #ifdef INCL_GROUP_SUPPORT
  406. if (lpCUE->dwEntryAttributes & (CUE_ATTR_GROUP |
  407. CUE_ATTR_WORLD))
  408. AddGroupPriEntry(lpszName);
  409. #endif
  410. }
  411. }
  412. lpCUE++;
  413. }
  414. GlobalFree(hMem);
  415. if (fError) {
  416. MsgBox(hDlg,IDS_ERRORADDINGUSERS,MB_ICONEXCLAMATION,MB_OK);
  417. }
  418. #ifndef INCL_GROUP_SUPPORT
  419. else if (fFoundGroup) {
  420. MsgBox(hDlg,IDS_GROUPSNOTADDED,MB_ICONINFORMATION,MB_OK);
  421. }
  422. #endif
  423. if (fAdded) {
  424. dwAppState |= AS_FILEDIRTY;
  425. EnableMenuItems(hwndMain,dwAppState);
  426. SetStatusItemCount(hwndUser);
  427. }
  428. return fAdded;
  429. }