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.

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