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.

308 lines
7.6 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // proxynode.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Defines the class ProxyNode.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/19/2000 Original version.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include <proxypch.h>
  19. #include <proxynode.h>
  20. #include <proxypolicies.h>
  21. #include <servergroups.h>
  22. //////////
  23. // From mmcutility.cpp
  24. //////////
  25. HRESULT IfServiceInstalled(
  26. LPCWSTR lpszMachine,
  27. LPCWSTR lpszService,
  28. BOOL* pBool
  29. );
  30. //////////
  31. // Helper function to get the NT build number of a machine.
  32. //////////
  33. LONG GetBuildNumber(LPCWSTR machineName, PLONG buildNum) throw ()
  34. {
  35. const WCHAR KEY[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion";
  36. const WCHAR VALUE[] = L"CurrentBuildNumber";
  37. LONG error;
  38. HKEY hklm = HKEY_LOCAL_MACHINE;
  39. // Only do a remote connect when machineName is specified.
  40. CRegKey remote;
  41. if (machineName && machineName[0])
  42. {
  43. error = RegConnectRegistryW(
  44. machineName,
  45. HKEY_LOCAL_MACHINE,
  46. &remote.m_hKey
  47. );
  48. if (error) { return error; }
  49. hklm = remote;
  50. }
  51. CRegKey currentVersion;
  52. error = currentVersion.Open(hklm, KEY, KEY_READ);
  53. if (error) { return error; }
  54. WCHAR data[16];
  55. DWORD dataLen = sizeof(data);
  56. error = currentVersion.QueryValue(data, VALUE, &dataLen);
  57. if (error) { return error; }
  58. *buildNum = _wtol(data);
  59. return NO_ERROR;
  60. }
  61. ///////////////////////////////////////////////////////////////////////////////
  62. //
  63. // CLASS
  64. //
  65. // ConnectInfo
  66. //
  67. // DESCRIPTION
  68. //
  69. // Encapsulates the info that needs to be passed to the connect thread.
  70. //
  71. ///////////////////////////////////////////////////////////////////////////////
  72. class ConnectInfo
  73. {
  74. public:
  75. ProxyNode* node;
  76. CComPtr<IConsoleNameSpace2> nameSpace;
  77. CComPtr<IDataObject> dataObject;
  78. HSCOPEITEM relativeID;
  79. };
  80. ProxyNode::ProxyNode(
  81. SnapInView& view,
  82. IDataObject* parentData,
  83. HSCOPEITEM parentId
  84. )
  85. : SnapInPreNamedItem(IDS_PROXY_NODE),
  86. state(CONNECTING),
  87. title(IDS_PROXY_VIEW_TITLE),
  88. body(IDS_PROXY_VIEW_BODY),
  89. worker(NULL)
  90. {
  91. // Save the connect info.
  92. ConnectInfo* info = new (AfxThrow) ConnectInfo;
  93. info->node = this;
  94. info->nameSpace = view.getNameSpace();
  95. info->dataObject = parentData;
  96. info->relativeID = parentId;
  97. // Create the connect thread.
  98. worker = CreateThread(NULL, 0, connectRoutine, info, 0, NULL);
  99. if (!worker)
  100. {
  101. delete info;
  102. AfxThrowLastError();
  103. }
  104. }
  105. HRESULT ProxyNode::getResultViewType(
  106. LPOLESTR* ppViewType,
  107. long* pViewOptions
  108. ) throw ()
  109. {
  110. // Set our result view to the MessageView control.
  111. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  112. return StringFromCLSID(CLSID_MessageView, ppViewType);
  113. }
  114. HRESULT ProxyNode::onExpand(
  115. SnapInView& view,
  116. HSCOPEITEM itemId,
  117. BOOL expanded
  118. )
  119. {
  120. if (!expanded || state != CONNECTED) { return S_FALSE; }
  121. SCOPEDATAITEM sdi;
  122. memset(&sdi, 0, sizeof(sdi));
  123. sdi.mask = SDI_STR |
  124. SDI_PARAM |
  125. SDI_IMAGE |
  126. SDI_OPENIMAGE |
  127. SDI_CHILDREN |
  128. SDI_PARENT;
  129. sdi.displayname = MMC_CALLBACK;
  130. sdi.cChildren = 0;
  131. sdi.relativeID = itemId;
  132. // Create the ProxyPolicies node ...
  133. policies = new (AfxThrow) ProxyPolicies(connection);
  134. // ... and insert.
  135. sdi.nImage = IMAGE_CLOSED_PROXY_POLICY_NODE;
  136. sdi.nOpenImage = IMAGE_OPEN_PROXY_POLICY_NODE;
  137. sdi.lParam = (LPARAM)(SnapInDataItem*)policies;
  138. CheckError(view.getNameSpace()->InsertItem(&sdi));
  139. policies->setScopeId(sdi.ID);
  140. // Create the ServerGroups node ...
  141. groups = new (AfxThrow) ServerGroups(connection);
  142. // ... and insert.
  143. sdi.nImage = IMAGE_CLOSED_SERVER_GROUP_NODE;
  144. sdi.nOpenImage = IMAGE_OPEN_SERVER_GROUPS_NODE;
  145. sdi.lParam = (LPARAM)(SnapInDataItem*)groups;
  146. CheckError(view.getNameSpace()->InsertItem(&sdi));
  147. groups->setScopeId(sdi.ID);
  148. // All went well.
  149. state = EXPANDED;
  150. return S_OK;
  151. }
  152. HRESULT ProxyNode::onShow(
  153. SnapInView& view,
  154. HSCOPEITEM itemId,
  155. BOOL selected
  156. )
  157. {
  158. if (!selected) { return S_FALSE; }
  159. // Get the IMessageView interface ...
  160. CComPtr<IUnknown> unk;
  161. CheckError(view.getConsole()->QueryResultView(&unk));
  162. CComPtr<IMessageView> msgView;
  163. CheckError(unk->QueryInterface(
  164. __uuidof(IMessageView),
  165. (PVOID*)&msgView
  166. ));
  167. // ... and set our information. We don't care if this fails.
  168. msgView->SetIcon(Icon_Information);
  169. msgView->SetTitleText(title);
  170. msgView->SetBodyText(body);
  171. return S_OK;
  172. }
  173. HRESULT ProxyNode::onContextHelp(SnapInView& view) throw ()
  174. {
  175. return view.displayHelp(L"ias_ops.chm::/sag_ias_crp_node.htm");
  176. }
  177. ProxyNode::~ProxyNode() throw ()
  178. {
  179. if (worker)
  180. {
  181. WaitForSingleObject(worker, INFINITE);
  182. CloseHandle(worker);
  183. }
  184. }
  185. void ProxyNode::connect(ConnectInfo& info) throw ()
  186. {
  187. HGLOBAL global = NULL;
  188. // We'll assume that the node is suppressed until we've verified that the
  189. // target machine (1) has IAS installed and (2) supports proxy policies.
  190. State newState = SUPPRESSED;
  191. try
  192. {
  193. // Extract the machine name from the parentData.
  194. UINT cf = RegisterClipboardFormatW(L"MMC_SNAPIN_MACHINE_NAME");
  195. ExtractData(
  196. info.dataObject,
  197. (CLIPFORMAT)cf,
  198. 4096,
  199. &global
  200. );
  201. PCWSTR machine = (PCWSTR)global;
  202. // Get the build number of the machine.
  203. LONG error, buildNum;
  204. error = GetBuildNumber(machine, &buildNum);
  205. if (error) { AfxThrowOleException(HRESULT_FROM_WIN32(error)); }
  206. // If the machine supports proxy policies, ...
  207. if (buildNum >= 2220)
  208. {
  209. // ... ensure that IAS is actually installed.
  210. BOOL installed;
  211. CheckError(IfServiceInstalled(machine, L"IAS", &installed));
  212. if (installed)
  213. {
  214. connection.connect(machine);
  215. newState = CONNECTED;
  216. }
  217. }
  218. }
  219. catch (...)
  220. {
  221. // Something went wrong.
  222. newState = FAILED;
  223. }
  224. GlobalFree(global);
  225. // Don't add the node if we're suppressed.
  226. if (newState != SUPPRESSED)
  227. {
  228. SCOPEDATAITEM sdi;
  229. ZeroMemory(&sdi, sizeof(SCOPEDATAITEM));
  230. sdi.mask = SDI_STR |
  231. SDI_IMAGE |
  232. SDI_OPENIMAGE |
  233. SDI_CHILDREN |
  234. SDI_PARENT |
  235. SDI_PARAM;
  236. sdi.displayname = MMC_CALLBACK;
  237. sdi.lParam = (LPARAM)this;
  238. sdi.relativeID = info.relativeID;
  239. if (newState == CONNECTED)
  240. {
  241. sdi.nImage = IMAGE_CLOSED_PROXY_NODE;
  242. sdi.nOpenImage = IMAGE_OPEN_PROXY_NODE;
  243. sdi.cChildren = 2;
  244. }
  245. else
  246. {
  247. sdi.nImage = IMAGE_CLOSED_BAD_PROXY_NODE;
  248. sdi.nOpenImage = IMAGE_OPEN_BAD_PROXY_NODE;
  249. }
  250. info.nameSpace->InsertItem(&sdi);
  251. }
  252. // We don't update the state until everything is finished.
  253. state = newState;
  254. }
  255. DWORD ProxyNode::connectRoutine(LPVOID param) throw ()
  256. {
  257. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  258. ConnectInfo* info = (ConnectInfo*)param;
  259. info->node->connect(*info);
  260. delete info;
  261. CoUninitialize();
  262. return 0;
  263. }