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.

300 lines
7.8 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. inline ProxyNode::Connector::Connector()
  62. {
  63. }
  64. void ProxyNode::Connector::BeginConnect(
  65. ProxyNode& owner,
  66. SnapInView& view,
  67. IDataObject* parentData,
  68. HSCOPEITEM parentId
  69. ) throw ()
  70. {
  71. node = &owner;
  72. nameSpace = view.getNameSpace();
  73. dataObject = parentData;
  74. relativeID = parentId;
  75. Start();
  76. }
  77. LPARAM ProxyNode::Connector::DoWork() throw ()
  78. {
  79. return static_cast<LPARAM>(node->connect(dataObject));
  80. }
  81. void ProxyNode::Connector::OnComplete(LPARAM result) throw ()
  82. {
  83. node->setConnectResult(
  84. nameSpace,
  85. relativeID,
  86. static_cast<ProxyNode::State>(result)
  87. );
  88. }
  89. ProxyNode::ProxyNode(
  90. SnapInView& view,
  91. IDataObject* parentData,
  92. HSCOPEITEM parentId
  93. )
  94. : SnapInPreNamedItem(IDS_PROXY_NODE),
  95. state(CONNECTING),
  96. title(IDS_PROXY_VIEW_TITLE),
  97. body(IDS_PROXY_VIEW_BODY)
  98. {
  99. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  100. // Begin the connect action.
  101. worker.BeginConnect(*this, view, parentData, parentId);
  102. }
  103. HRESULT ProxyNode::getResultViewType(
  104. LPOLESTR* ppViewType,
  105. long* pViewOptions
  106. ) throw ()
  107. {
  108. // Set our result view to the MessageView control.
  109. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  110. return StringFromCLSID(CLSID_MessageView, ppViewType);
  111. }
  112. HRESULT ProxyNode::onExpand(
  113. SnapInView& view,
  114. HSCOPEITEM itemId,
  115. BOOL expanded
  116. )
  117. {
  118. if (!expanded || state != CONNECTED) { return S_FALSE; }
  119. SCOPEDATAITEM sdi;
  120. memset(&sdi, 0, sizeof(sdi));
  121. sdi.mask = SDI_STR |
  122. SDI_PARAM |
  123. SDI_IMAGE |
  124. SDI_OPENIMAGE |
  125. SDI_CHILDREN |
  126. SDI_PARENT;
  127. sdi.displayname = MMC_CALLBACK;
  128. sdi.cChildren = 0;
  129. sdi.relativeID = itemId;
  130. // Create the ProxyPolicies node ...
  131. policies = new (AfxThrow) ProxyPolicies(connection);
  132. // ... and insert.
  133. sdi.nImage = IMAGE_CLOSED_PROXY_POLICY_NODE;
  134. sdi.nOpenImage = IMAGE_OPEN_PROXY_POLICY_NODE;
  135. sdi.lParam = (LPARAM)(SnapInDataItem*)policies;
  136. CheckError(view.getNameSpace()->InsertItem(&sdi));
  137. policies->setScopeId(sdi.ID);
  138. // Create the ServerGroups node ...
  139. groups = new (AfxThrow) ServerGroups(connection);
  140. // ... and insert.
  141. sdi.nImage = IMAGE_CLOSED_SERVER_GROUP_NODE;
  142. sdi.nOpenImage = IMAGE_OPEN_SERVER_GROUPS_NODE;
  143. sdi.lParam = (LPARAM)(SnapInDataItem*)groups;
  144. CheckError(view.getNameSpace()->InsertItem(&sdi));
  145. groups->setScopeId(sdi.ID);
  146. // All went well.
  147. state = EXPANDED;
  148. return S_OK;
  149. }
  150. HRESULT ProxyNode::onShow(
  151. SnapInView& view,
  152. HSCOPEITEM itemId,
  153. BOOL selected
  154. )
  155. {
  156. if (!selected) { return S_FALSE; }
  157. // Get the IMessageView interface ...
  158. CComPtr<IUnknown> unk;
  159. CheckError(view.getConsole()->QueryResultView(&unk));
  160. CComPtr<IMessageView> msgView;
  161. CheckError(unk->QueryInterface(
  162. __uuidof(IMessageView),
  163. (PVOID*)&msgView
  164. ));
  165. // ... and set our information. We don't care if this fails.
  166. msgView->SetIcon(Icon_Information);
  167. msgView->SetTitleText(title);
  168. msgView->SetBodyText(body);
  169. return S_OK;
  170. }
  171. HRESULT ProxyNode::onContextHelp(SnapInView& view) throw ()
  172. {
  173. return view.displayHelp(L"ias_ops.chm::/sag_ias_crp_node.htm");
  174. }
  175. ProxyNode::State ProxyNode::connect(IDataObject* dataObject) throw ()
  176. {
  177. HGLOBAL global = NULL;
  178. // We'll assume that the node is suppressed until we've verified that the
  179. // target machine (1) has IAS installed and (2) supports proxy policies.
  180. State newState = SUPPRESSED;
  181. try
  182. {
  183. // Extract the machine name from the parentData.
  184. UINT cf = RegisterClipboardFormatW(L"MMC_SNAPIN_MACHINE_NAME");
  185. ExtractData(
  186. dataObject,
  187. (CLIPFORMAT)cf,
  188. 4096,
  189. &global
  190. );
  191. PCWSTR machine = (PCWSTR)global;
  192. // Get the build number of the machine.
  193. LONG error, buildNum;
  194. error = GetBuildNumber(machine, &buildNum);
  195. if (error) { AfxThrowOleException(HRESULT_FROM_WIN32(error)); }
  196. // If the machine supports proxy policies, ...
  197. if (buildNum >= 2220)
  198. {
  199. // ... ensure that IAS is actually installed.
  200. BOOL installed;
  201. CheckError(IfServiceInstalled(machine, L"IAS", &installed));
  202. if (installed)
  203. {
  204. connection.connect(machine);
  205. newState = CONNECTED;
  206. }
  207. }
  208. }
  209. catch (...)
  210. {
  211. // Something went wrong.
  212. newState = FAILED;
  213. }
  214. GlobalFree(global);
  215. return newState;
  216. }
  217. void ProxyNode::setConnectResult(
  218. IConsoleNameSpace2* nameSpace,
  219. HSCOPEITEM relativeID,
  220. State newState
  221. ) throw ()
  222. {
  223. // Don't add the node if we're suppressed.
  224. if (newState != SUPPRESSED)
  225. {
  226. SCOPEDATAITEM sdi;
  227. ZeroMemory(&sdi, sizeof(SCOPEDATAITEM));
  228. sdi.mask = SDI_STR |
  229. SDI_IMAGE |
  230. SDI_OPENIMAGE |
  231. SDI_CHILDREN |
  232. SDI_PARENT |
  233. SDI_PARAM;
  234. sdi.displayname = MMC_CALLBACK;
  235. sdi.lParam = (LPARAM)this;
  236. sdi.relativeID = relativeID;
  237. if (newState == CONNECTED)
  238. {
  239. sdi.nImage = IMAGE_CLOSED_PROXY_NODE;
  240. sdi.nOpenImage = IMAGE_OPEN_PROXY_NODE;
  241. sdi.cChildren = 2;
  242. }
  243. else
  244. {
  245. sdi.nImage = IMAGE_CLOSED_BAD_PROXY_NODE;
  246. sdi.nOpenImage = IMAGE_OPEN_BAD_PROXY_NODE;
  247. }
  248. nameSpace->InsertItem(&sdi);
  249. }
  250. // We don't update the state until everything is finished.
  251. state = newState;
  252. }