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.

429 lines
13 KiB

  1. //
  2. // JonN 12/6/99 created
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1997-2000
  6. //
  7. #include <windows.h>
  8. #include <windowsx.h>
  9. #include <lmcons.h>
  10. #include <atlbase.h>
  11. #include <objsel.h>
  12. #include "chooser2.h"
  13. #include <lmserver.h> // NetServerGetInfo JonN 2002/04/08 585301
  14. #include <lmapibuf.h> // NetApiBufferFree JonN 2002/04/08 585301
  15. //+--------------------------------------------------------------------------
  16. //
  17. // Function: CHOOSER2_InitObjectPickerForComputers
  18. //
  19. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  20. // set it to allow the user to pick a single computer object.
  21. //
  22. // Arguments: [pDsObjectPicker] - object picker interface instance
  23. //
  24. // Returns: Result of calling IDsObjectPicker::Initialize.
  25. //
  26. // History: 10-14-1998 DavidMun Created
  27. // 12-08-1999 JonN Copied from CHOOSER
  28. //
  29. //---------------------------------------------------------------------------
  30. // ISSUE-2002/03/28-JonN Combine this with identical method in chooser.cpp
  31. HRESULT CHOOSER2_InitObjectPickerForComputers(
  32. IDsObjectPicker *pDsObjectPicker)
  33. {
  34. if ( !pDsObjectPicker )
  35. return E_POINTER;
  36. //
  37. // Prepare to initialize the object picker.
  38. // Set up the array of scope initializer structures.
  39. //
  40. static const int SCOPE_INIT_COUNT = 2;
  41. DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
  42. ZeroMemory(aScopeInit, sizeof(aScopeInit)); // JonN 3/28/02
  43. //
  44. // 127399: JonN 10/30/00 JOINED_DOMAIN should be starting scope
  45. //
  46. aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  47. aScopeInit[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  48. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  49. aScopeInit[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  50. aScopeInit[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
  51. aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  52. aScopeInit[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  53. aScopeInit[1].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
  54. | DSOP_SCOPE_TYPE_GLOBAL_CATALOG
  55. | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  56. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
  57. | DSOP_SCOPE_TYPE_WORKGROUP
  58. | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
  59. | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
  60. aScopeInit[1].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
  61. aScopeInit[1].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  62. //
  63. // Put the scope init array into the object picker init array
  64. //
  65. DSOP_INIT_INFO initInfo;
  66. ZeroMemory(&initInfo, sizeof(initInfo));
  67. initInfo.cbSize = sizeof(initInfo);
  68. initInfo.pwzTargetComputer = NULL; // NULL == local machine
  69. initInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  70. initInfo.aDsScopeInfos = aScopeInit;
  71. initInfo.cAttributesToFetch = 1;
  72. static PCWSTR pwszDnsHostName = L"dNSHostName";
  73. initInfo.apwzAttributeNames = &pwszDnsHostName;
  74. //
  75. // Note object picker makes its own copy of initInfo. Also note
  76. // that Initialize may be called multiple times, last call wins.
  77. //
  78. return pDsObjectPicker->Initialize(&initInfo);
  79. }
  80. //+--------------------------------------------------------------------------
  81. //
  82. // Function: CHOOSER2_ProcessSelectedObjects
  83. //
  84. // Synopsis: Retrieve the name of the selected item from the data object
  85. // created by the object picker
  86. //
  87. // Arguments: [pdo] - data object returned by object picker
  88. //
  89. // History: 10-14-1998 DavidMun Created
  90. // 12-08-1999 JonN Copied from CHOOSER
  91. //
  92. //---------------------------------------------------------------------------
  93. // ISSUE-2002/03/28-JonN Combine this with identical method in chooser.cpp
  94. HRESULT CHOOSER2_ProcessSelectedObjects(
  95. IDataObject* pdo,
  96. BSTR* pbstrComputerName)
  97. {
  98. if ( !pdo )
  99. return E_POINTER;
  100. HRESULT hr = S_OK;
  101. static UINT g_cfDsObjectPicker =
  102. RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  103. STGMEDIUM stgmedium =
  104. {
  105. TYMED_HGLOBAL,
  106. NULL,
  107. NULL
  108. };
  109. FORMATETC formatetc =
  110. {
  111. (CLIPFORMAT)g_cfDsObjectPicker,
  112. NULL,
  113. DVASPECT_CONTENT,
  114. -1,
  115. TYMED_HGLOBAL
  116. };
  117. bool fGotStgMedium = false;
  118. do
  119. {
  120. hr = pdo->GetData(&formatetc, &stgmedium);
  121. if ( SUCCEEDED (hr) )
  122. {
  123. fGotStgMedium = true;
  124. PDS_SELECTION_LIST pDsSelList =
  125. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  126. if (!pDsSelList)
  127. {
  128. hr = HRESULT_FROM_WIN32 (GetLastError());
  129. break;
  130. }
  131. if ( 1 == pDsSelList->cItems )
  132. {
  133. PDS_SELECTION psel = &(pDsSelList->aDsSelection[0]);
  134. // ISSUE-2002/03/28-JonN check for NULL == psel
  135. VARIANT* pvarDnsName = &(psel->pvarFetchedAttributes[0]);
  136. if ( NULL == pvarDnsName
  137. || VT_BSTR != pvarDnsName->vt
  138. || NULL == pvarDnsName->bstrVal
  139. || L'\0' == (pvarDnsName->bstrVal)[0] )
  140. {
  141. *pbstrComputerName = SysAllocString(
  142. psel->pwzName);
  143. } else {
  144. *pbstrComputerName = SysAllocString(
  145. pvarDnsName->bstrVal);
  146. //
  147. // JonN 2002/04/08 585301
  148. // Computer management snapin only attempts to use the DnsHostName
  149. // to connect to a remote computer, even when the dns name
  150. // is not valid
  151. //
  152. // Bank of America encounters a problem because they
  153. // set RegisterDnsARecord to 1, turning off client DNS
  154. // records. The dnsHostName is therefore not a valid
  155. // binding name. The fix is to test the dnsHostName.
  156. //
  157. LPBYTE pbDummy = NULL;
  158. NET_API_STATUS err = NetServerGetInfo(
  159. pvarDnsName->bstrVal, 101, &pbDummy );
  160. if (pbDummy)
  161. {
  162. NetApiBufferFree( pbDummy );
  163. pbDummy = NULL;
  164. }
  165. if (NERR_Success != err)
  166. {
  167. err = NetServerGetInfo( psel->pwzName, 101, &pbDummy );
  168. if (pbDummy)
  169. {
  170. NetApiBufferFree( pbDummy );
  171. pbDummy = NULL;
  172. }
  173. if (NERR_Success == err)
  174. {
  175. if (NULL != *pbstrComputerName)
  176. {
  177. ::SysFreeString( *pbstrComputerName );
  178. }
  179. *pbstrComputerName = SysAllocString(
  180. psel->pwzName);
  181. }
  182. }
  183. // end new code: JonN 2002/04/08 585301
  184. }
  185. }
  186. else
  187. hr = E_UNEXPECTED;
  188. GlobalUnlock(stgmedium.hGlobal);
  189. }
  190. } while (0);
  191. if (fGotStgMedium)
  192. {
  193. ReleaseStgMedium(&stgmedium);
  194. }
  195. return hr;
  196. }
  197. ///////////////////////////////////////////////////////////////////////////////
  198. // Generic method for launching a single-select computer picker
  199. //
  200. // Paremeters:
  201. // hwndParent (IN) - window handle of parent window
  202. // computerName (OUT) - computer name returned
  203. //
  204. // Returns S_OK if everything succeeded, S_FALSE if user pressed "Cancel"
  205. //
  206. // History: 12-08-1999 JonN Copied from CHOOSER
  207. //
  208. //////////////////////////////////////////////////////////////////////////////
  209. HRESULT CHOOSER2_ComputerNameFromObjectPicker (
  210. HWND hwndParent,
  211. BSTR* pbstrTargetComputer)
  212. {
  213. //
  214. // Create an instance of the object picker. The implementation in
  215. // objsel.dll is apartment model.
  216. //
  217. CComPtr<IDsObjectPicker> spDsObjectPicker;
  218. HRESULT hr = CoCreateInstance(CLSID_DsObjectPicker,
  219. NULL,
  220. CLSCTX_INPROC_SERVER,
  221. IID_IDsObjectPicker,
  222. (void **) &spDsObjectPicker);
  223. if ( SUCCEEDED (hr) )
  224. {
  225. //
  226. // Initialize the object picker to choose computers
  227. //
  228. hr = CHOOSER2_InitObjectPickerForComputers(spDsObjectPicker);
  229. if ( SUCCEEDED (hr) )
  230. {
  231. //
  232. // Now pick a computer
  233. //
  234. CComPtr<IDataObject> spDataObject;
  235. hr = spDsObjectPicker->InvokeDialog(
  236. hwndParent,
  237. &spDataObject);
  238. if ( S_OK == hr )
  239. {
  240. hr = CHOOSER2_ProcessSelectedObjects(
  241. spDataObject,
  242. pbstrTargetComputer);
  243. }
  244. }
  245. }
  246. return hr;
  247. }
  248. const ULONG g_aHelpIDs_CHOOSER2[]=
  249. {
  250. IDC_CHOOSER2_RADIO_LOCAL_MACHINE, IDC_CHOOSER2_RADIO_LOCAL_MACHINE,
  251. IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE,
  252. IDC_CHOOSER2_EDIT_MACHINE_NAME, IDC_CHOOSER2_EDIT_MACHINE_NAME,
  253. IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES, IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES,
  254. IDD_CHOOSER2, (ULONG)-1,
  255. 0, 0
  256. };
  257. INT_PTR CALLBACK CHOOSER2_TargetComputerDialogFunc(
  258. HWND hwndDlg, // handle to dialog box
  259. UINT uMsg, // message
  260. WPARAM wParam, // first message parameter
  261. LPARAM lParam // second message parameter
  262. )
  263. {
  264. switch (uMsg)
  265. {
  266. case WM_INITDIALOG:
  267. {
  268. Edit_LimitText(
  269. GetDlgItem(hwndDlg,IDC_CHOOSER2_EDIT_MACHINE_NAME),
  270. MAX_PATH+2);
  271. // lParam is pbstrTargetComputer
  272. BSTR* pbstrTargetComputer = (BSTR*)lParam;
  273. (void) SetWindowLongPtr(
  274. hwndDlg,
  275. DWLP_USER,
  276. (LONG_PTR)pbstrTargetComputer );
  277. (void) SendMessage(
  278. GetDlgItem(hwndDlg,IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE),
  279. BM_SETCHECK,
  280. BST_CHECKED,
  281. 0 );
  282. (void) SetFocus(
  283. GetDlgItem(hwndDlg,IDC_CHOOSER2_EDIT_MACHINE_NAME));
  284. }
  285. break;
  286. case WM_COMMAND:
  287. switch (LOWORD(wParam))
  288. {
  289. case IDOK:
  290. if (BST_CHECKED == IsDlgButtonChecked(
  291. hwndDlg,
  292. IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE ))
  293. {
  294. WCHAR achTarget[MAX_PATH+3]; // allow for whackwhack
  295. ZeroMemory( achTarget, sizeof(achTarget) );
  296. GetDlgItemText(
  297. hwndDlg,
  298. IDC_CHOOSER2_EDIT_MACHINE_NAME,
  299. achTarget,
  300. MAX_PATH+2);
  301. BSTR* pbstrTargetComputer =
  302. (BSTR*)GetWindowLongPtr( hwndDlg, DWLP_USER );
  303. LPCWSTR pcszTargetComputer = achTarget;
  304. while (L'\\' == *pcszTargetComputer)
  305. pcszTargetComputer++;
  306. if (L'\0' != *pcszTargetComputer)
  307. *pbstrTargetComputer = SysAllocString(pcszTargetComputer);
  308. }
  309. EndDialog( hwndDlg, 1 );
  310. break;
  311. case IDCANCEL:
  312. EndDialog( hwndDlg, 0 );
  313. break;
  314. case IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES:
  315. {
  316. CComBSTR sbstrTargetComputer;
  317. HRESULT hr = CHOOSER2_ComputerNameFromObjectPicker(
  318. hwndDlg,
  319. &sbstrTargetComputer );
  320. if ( SUCCEEDED(hr) )
  321. {
  322. LPCWSTR pcszTargetComputer =
  323. (!sbstrTargetComputer)
  324. ? NULL
  325. : (LPCWSTR)sbstrTargetComputer;
  326. SetDlgItemText(
  327. hwndDlg,
  328. IDC_CHOOSER2_EDIT_MACHINE_NAME,
  329. pcszTargetComputer );
  330. }
  331. }
  332. break;
  333. case IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE:
  334. case IDC_CHOOSER2_RADIO_LOCAL_MACHINE:
  335. // 671670-2002/07/25-JonN use IsDlgButtonChecked
  336. (void) EnableWindow(
  337. GetDlgItem(hwndDlg,IDC_CHOOSER2_EDIT_MACHINE_NAME),
  338. (IsDlgButtonChecked(hwndDlg, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE))
  339. ? TRUE
  340. : FALSE );
  341. (void) EnableWindow(
  342. GetDlgItem(hwndDlg,
  343. IDC_CHOOSER2_BUTTON_BROWSE_MACHINENAMES),
  344. (IsDlgButtonChecked(hwndDlg, IDC_CHOOSER2_RADIO_SPECIFIC_MACHINE))
  345. ? TRUE
  346. : FALSE );
  347. break;
  348. default:
  349. break;
  350. }
  351. break;
  352. case WM_HELP:
  353. if (NULL != lParam)
  354. {
  355. const LPHELPINFO pHelpInfo = (LPHELPINFO)lParam;
  356. // ISSUE-2002/03/28-JonN check pHelpInfo for NULL
  357. if (pHelpInfo->iContextType == HELPINFO_WINDOW)
  358. {
  359. const HWND hwnd = (HWND)pHelpInfo->hItemHandle;
  360. (void) WinHelp(
  361. hwnd,
  362. _T("chooser.hlp"),
  363. HELP_WM_HELP,
  364. (ULONG_PTR)g_aHelpIDs_CHOOSER2);
  365. }
  366. }
  367. break;
  368. default:
  369. break;
  370. }
  371. return FALSE;
  372. }
  373. bool CHOOSER2_PickTargetComputer(
  374. IN HINSTANCE hinstance,
  375. IN HWND hwndParent,
  376. OUT BSTR* pbstrTargetComputer )
  377. {
  378. if (NULL == pbstrTargetComputer)
  379. return false;
  380. INT_PTR nReturn = ::DialogBoxParam(
  381. hinstance,
  382. MAKEINTRESOURCE(IDD_CHOOSER2),
  383. hwndParent,
  384. CHOOSER2_TargetComputerDialogFunc,
  385. (LPARAM)pbstrTargetComputer );
  386. return (0 < nReturn);
  387. }