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.

422 lines
9.9 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. ServiceMethod.cpp
  5. Abstract:
  6. Implements the CServiceMethod class.
  7. All the methods in this class return HRESULTs and do not throw exceptions.
  8. Author:
  9. Mohit Srivastava 25-March-01
  10. Revision History:
  11. --*/
  12. #include "WebServiceMethod.h"
  13. #include "MultiSzHelper.h"
  14. #include "Utils.h"
  15. #include "SmartPointer.h"
  16. #include <dbgutil.h>
  17. #include <iiscnfg.h>
  18. #include <atlbase.h>
  19. #include <iwamreg.h>
  20. CServiceMethod::CServiceMethod(
  21. eSC_SUPPORTED_SERVICES i_eServiceId)
  22. {
  23. m_bInit = false;
  24. m_pSiteCreator = NULL;
  25. m_eServiceId = i_eServiceId;
  26. DBG_ASSERT(m_eServiceId == SC_W3SVC || m_eServiceId == SC_MSFTPSVC);
  27. }
  28. CServiceMethod::~CServiceMethod()
  29. {
  30. if(m_pSiteCreator)
  31. {
  32. delete m_pSiteCreator;
  33. m_pSiteCreator = NULL;
  34. }
  35. }
  36. HRESULT CServiceMethod::Init()
  37. /*++
  38. Synopsis:
  39. Should be called immediately after constructor.
  40. Return Value:
  41. --*/
  42. {
  43. DBG_ASSERT(m_bInit == false);
  44. m_pSiteCreator = new CSiteCreator();
  45. if(m_pSiteCreator == NULL)
  46. {
  47. return WBEM_E_OUT_OF_MEMORY;
  48. }
  49. m_bInit = true;
  50. return WBEM_S_NO_ERROR;
  51. }
  52. HRESULT CServiceMethod::CreateNewSite(
  53. LPCWSTR i_wszServerComment,
  54. PDWORD o_pdwSiteId,
  55. PDWORD i_pdwRequestedSiteId) // default value NULL
  56. /*++
  57. Synopsis:
  58. This is the CreateNewSite called when someone does a Put on a Server w/o
  59. specifying a SiteId.
  60. Arguments: [o_pdwSiteId] -
  61. [i_pdwRequestedSiteId] -
  62. Return Value:
  63. HRESULT
  64. --*/
  65. {
  66. DBG_ASSERT(m_bInit);
  67. DBG_ASSERT(o_pdwSiteId != NULL);
  68. HRESULT hr = S_OK;
  69. //
  70. // Call API
  71. //
  72. hr = m_pSiteCreator->CreateNewSite(
  73. m_eServiceId,
  74. (i_wszServerComment == NULL) ? L"" : i_wszServerComment,
  75. o_pdwSiteId,
  76. i_pdwRequestedSiteId);
  77. return hr;
  78. }
  79. HRESULT CServiceMethod::CreateNewSite(
  80. CWbemServices* i_pNamespace,
  81. LPCWSTR i_wszMbPath,
  82. IWbemContext* i_pCtx,
  83. WMI_CLASS* i_pClass,
  84. WMI_METHOD* i_pMethod,
  85. IWbemClassObject* i_pInParams,
  86. IWbemClassObject** o_ppRetObj)
  87. /*++
  88. Synopsis:
  89. This is the CreateNewSite called by the WMI Method of the same name.
  90. Arguments: [i_pNamespace] -
  91. [i_wszMbPath] - needed for creating WMI return object
  92. [i_pCtx] - needed for creating WMI return object
  93. [i_pClass] - needed for creating WMI return object
  94. [i_pMethod] - needed for creating WMI return object
  95. [i_pInParams] -
  96. [o_ppRetObj] -
  97. Return Value:
  98. HRESULT
  99. --*/
  100. {
  101. DBG_ASSERT(m_bInit);
  102. DBG_ASSERT(i_pNamespace != NULL);
  103. DBG_ASSERT(i_wszMbPath != NULL);
  104. DBG_ASSERT(i_pCtx != NULL);
  105. DBG_ASSERT(i_pClass != NULL);
  106. DBG_ASSERT(i_pMethod != NULL);
  107. DBG_ASSERT(i_pInParams != NULL);
  108. DBG_ASSERT(o_ppRetObj != NULL);
  109. DBG_ASSERT(*o_ppRetObj == NULL);
  110. HRESULT hr = WBEM_S_NO_ERROR;
  111. CComVariant vtServerId, vtServerComment, vtServerBindings, vtPath;
  112. //
  113. // get in params
  114. //
  115. hr = InternalGetInParams(
  116. i_pInParams,
  117. vtServerId,
  118. vtServerComment,
  119. vtServerBindings,
  120. vtPath);
  121. if(FAILED(hr))
  122. {
  123. return hr;
  124. }
  125. //
  126. // Set pdwRequestedSite based on whether the user specified a site
  127. //
  128. DWORD dwRequestedSiteId = 0;
  129. PDWORD pdwRequestedSiteId = NULL;
  130. if(vtServerId.vt == VT_I4)
  131. {
  132. pdwRequestedSiteId = &dwRequestedSiteId;
  133. dwRequestedSiteId = vtServerId.lVal;
  134. }
  135. //
  136. // Create the new site
  137. //
  138. CComPtr<IIISApplicationAdmin> spAppAdmin;
  139. if(m_eServiceId == SC_W3SVC)
  140. {
  141. hr = CoCreateInstance(
  142. CLSID_WamAdmin,
  143. NULL,
  144. CLSCTX_ALL,
  145. IID_IIISApplicationAdmin,
  146. (void**)&spAppAdmin);
  147. if(FAILED(hr))
  148. {
  149. DBGPRINTF((DBG_CONTEXT, "[%s] CoCreateInstance failed, hr=0x%x\n", __FUNCTION__, hr));
  150. return hr;
  151. }
  152. }
  153. DWORD dwSiteId = 0;
  154. hr = InternalCreateNewSite(
  155. *i_pNamespace,
  156. vtServerComment,
  157. vtServerBindings,
  158. vtPath,
  159. spAppAdmin,
  160. &dwSiteId,
  161. pdwRequestedSiteId);
  162. if(FAILED(hr))
  163. {
  164. DBGPRINTF((DBG_CONTEXT, "[%s] InternalCreateNewSite failed, hr=0x%x\n", __FUNCTION__, hr));
  165. return hr;
  166. }
  167. //
  168. // convert dwSiteId to a metabase path
  169. //
  170. WCHAR wszServerId[11] = {0};
  171. _itow(dwSiteId, wszServerId, 10);
  172. SIZE_T cchMbPath = wcslen(i_wszMbPath);
  173. SIZE_T cchServerId = wcslen(wszServerId);
  174. SIZE_T cchKeyPath = cchMbPath + 1 + cchServerId;
  175. TSmartPointerArray<WCHAR> swszKeyPath = new WCHAR[cchKeyPath+1];
  176. if(swszKeyPath == NULL)
  177. {
  178. return WBEM_E_OUT_OF_MEMORY;
  179. }
  180. LPWSTR pEnd = NULL;
  181. memcpy(pEnd = swszKeyPath, i_wszMbPath, sizeof(WCHAR) * cchMbPath);
  182. memcpy(pEnd += cchMbPath, L"/", sizeof(WCHAR) * 1);
  183. memcpy(pEnd += 1, wszServerId, sizeof(WCHAR) * (cchServerId+1));
  184. //
  185. // From sbstrKeyPath, get sbstrRetVal, a full obj path.
  186. // This is our return value.
  187. //
  188. WMI_CLASS* pServer = (m_eServiceId == SC_MSFTPSVC) ?
  189. &WMI_CLASS_DATA::s_FtpServer : &WMI_CLASS_DATA::s_WebServer;
  190. CComBSTR sbstrRetVal;
  191. hr = CUtils::ConstructObjectPath(
  192. swszKeyPath,
  193. pServer,
  194. &sbstrRetVal);
  195. if(FAILED(hr))
  196. {
  197. return hr;
  198. }
  199. //
  200. // Create WMI return object
  201. //
  202. CComPtr<IWbemClassObject> spOutParams;
  203. hr = CUtils::CreateEmptyMethodInstance(
  204. i_pNamespace,
  205. i_pCtx,
  206. i_pClass->pszClassName,
  207. i_pMethod->pszMethodName,
  208. &spOutParams);
  209. if(FAILED(hr))
  210. {
  211. return hr;
  212. }
  213. //
  214. // Put treats vtRetVal as RO.
  215. // Deliberately not using smart variant.
  216. //
  217. VARIANT vtRetVal;
  218. vtRetVal.vt = VT_BSTR;
  219. vtRetVal.bstrVal = sbstrRetVal;
  220. hr = spOutParams->Put(L"ReturnValue", 0, &vtRetVal, 0);
  221. if(FAILED(hr))
  222. {
  223. return hr;
  224. }
  225. //
  226. // Set out parameters if everything succeeded
  227. //
  228. *o_ppRetObj = spOutParams.Detach();
  229. return hr;
  230. }
  231. //
  232. // private
  233. //
  234. HRESULT CServiceMethod::InternalGetInParams(
  235. IWbemClassObject* i_pInParams,
  236. VARIANT& io_refServerId,
  237. VARIANT& io_refServerComment,
  238. VARIANT& io_refServerBindings,
  239. VARIANT& io_refPath)
  240. /*++
  241. Synopsis:
  242. Given in parameters from the WMI method call, return the values of the
  243. parameters in variants.
  244. Arguments: [i_pInParams] -
  245. [io_refServerId] -
  246. [io_refServerComment] -
  247. [io_refServerBindings] -
  248. [io_refPath] -
  249. Return Value:
  250. --*/
  251. {
  252. DBG_ASSERT(i_pInParams);
  253. HRESULT hr = WBEM_S_NO_ERROR;
  254. LPWSTR awszParamNames[] = {
  255. WMI_METHOD_PARAM_DATA::s_ServerId.pszParamName,
  256. WMI_METHOD_PARAM_DATA::s_ServerComment.pszParamName,
  257. WMI_METHOD_PARAM_DATA::s_ServerBindings.pszParamName,
  258. WMI_METHOD_PARAM_DATA::s_PathOfRootVirtualDir.pszParamName,
  259. NULL
  260. };
  261. VARIANT* apvtParamValues[] = {
  262. &io_refServerId, &io_refServerComment, &io_refServerBindings, &io_refPath, NULL
  263. };
  264. //
  265. // get in params
  266. //
  267. for(ULONG i = 0; awszParamNames[i] != NULL; i++)
  268. {
  269. hr = i_pInParams->Get(awszParamNames[i], 0, apvtParamValues[i], NULL, NULL);
  270. if(FAILED(hr))
  271. {
  272. return hr;
  273. }
  274. }
  275. return hr;
  276. }
  277. HRESULT CServiceMethod::InternalCreateNewSite(
  278. CWbemServices& i_refNamespace,
  279. const VARIANT& i_refServerComment,
  280. const VARIANT& i_refServerBindings,
  281. const VARIANT& i_refPathOfRootVirtualDir,
  282. IIISApplicationAdmin* i_pIApplAdmin,
  283. PDWORD o_pdwSiteId,
  284. PDWORD i_pdwRequestedSiteId) // default value NULL
  285. /*++
  286. Synopsis:
  287. Private method that calls the API
  288. Arguments: [i_refNamespace] -
  289. [i_refServerComment] -
  290. [i_refServerBindings] -
  291. [i_refPathOfRootVirtualDir] -
  292. [o_pdwSiteId] -
  293. [i_pdwRequestedSiteId] -
  294. Return Value:
  295. --*/
  296. {
  297. DBG_ASSERT(m_bInit);
  298. DBG_ASSERT(o_pdwSiteId != NULL);
  299. HRESULT hr = S_OK;
  300. LPWSTR mszServerBindings = NULL;
  301. DWORD dwTemp = 0;
  302. LPWSTR wszServerComment = NULL;
  303. LPWSTR wszPathOfRootVirtualDir = NULL;
  304. if(i_refServerBindings.vt == (VT_ARRAY | VT_UNKNOWN))
  305. {
  306. CMultiSz MultiSz(&METABASE_PROPERTY_DATA::s_ServerBindings, &i_refNamespace);
  307. hr = MultiSz.ToMetabaseForm(
  308. &i_refServerBindings,
  309. &mszServerBindings,
  310. &dwTemp);
  311. if(FAILED(hr))
  312. {
  313. DBGPRINTF((DBG_CONTEXT, "[%s] MultiSz.ToMetabaseForm failed, hr=0x%x\n", __FUNCTION__, hr));
  314. goto exit;
  315. }
  316. }
  317. try
  318. {
  319. wszServerComment = CUtils::ExtractBstrFromVt(&i_refServerComment);
  320. wszPathOfRootVirtualDir = CUtils::ExtractBstrFromVt(&i_refPathOfRootVirtualDir);
  321. }
  322. catch(HRESULT ehr)
  323. {
  324. hr = ehr;
  325. goto exit;
  326. }
  327. catch(...)
  328. {
  329. DBG_ASSERT(false && "Should not be throwing unknown exception");
  330. hr = WBEM_E_FAILED;
  331. goto exit;
  332. }
  333. hr = m_pSiteCreator->CreateNewSite2(
  334. m_eServiceId,
  335. (wszServerComment == NULL) ? L"" : wszServerComment,
  336. mszServerBindings,
  337. wszPathOfRootVirtualDir,
  338. i_pIApplAdmin,
  339. o_pdwSiteId,
  340. i_pdwRequestedSiteId);
  341. if(FAILED(hr))
  342. {
  343. DBGPRINTF((DBG_CONTEXT, "[%s] CreateNewSite2 failed, hr=0x%x\n", __FUNCTION__, hr));
  344. goto exit;
  345. }
  346. exit:
  347. delete [] mszServerBindings;
  348. mszServerBindings = NULL;
  349. return hr;
  350. }