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.

409 lines
14 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1997 **/
  4. /**********************************************************************/
  5. /*
  6. admsub.cxx
  7. This module contains IISADMIN subroutines.
  8. FILE HISTORY:
  9. 7/7/97 michth created
  10. */
  11. #define INITGUID
  12. extern "C"
  13. {
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. }
  18. #include <dbgutil.h>
  19. #include <apiutil.h>
  20. #include <loadadm.hxx>
  21. #include <ole2.h>
  22. #include <inetsvcs.h>
  23. #include <ntsec.h>
  24. #include <string.hxx>
  25. #pragma warning(push, 3)
  26. #include <stringau.hxx>
  27. #pragma warning(pop)
  28. #include <iadmext.h>
  29. #include <admsub.hxx>
  30. #include <imd.h>
  31. #include <iiscnfg.h>
  32. #include <initguid.h>
  33. // IVANPASH
  34. // It is just imposible to include the headers files defining the CLSID of the
  35. // service extensions here. So I have to copy the definition.
  36. // CLSID_WmRgSrv = {763A6C86-F30F-11D0-9953-00C04FD919C1}
  37. // defined in iis\svcs\wam\wamreg\wmrgsv.idl
  38. DEFINE_GUID(CLSID_WmRgSrv, 0X763A6C86, 0XF30F, 0X11D0, 0X99, 0X53, 0X00, 0XC0, 0X4F, 0XD9, 0X19, 0XC1);
  39. // CLSID_ADMEXT = {C4376B00-F87B-11D0-A6A6-00A0C922E752}
  40. // defined in iis\svcs\admex\secex\bootimp.hxx
  41. // The extension is removed from IIS6/IIS5.1
  42. // DEFINE_GUID(CLSID_ADMEXT, 0XC4376B00, 0XF87B, 0X11D0, 0XA6, 0XA6, 0X0, 0XA0, 0XC9, 0X22, 0XE7, 0X52);
  43. // CLSID_W3EXTEND = {FCC764A0-2A38-11D1-B9C6-00A0C922E750}
  44. // defined in iis\svcs\infocomm\extend\coimp.hxx
  45. DEFINE_GUID(CLSID_W3EXTEND, 0XFCC764A0, 0X2A38, 0X11D1, 0XB9, 0XC6, 0X0, 0XA0, 0XC9, 0X22, 0XE7, 0X50);
  46. static const CLSID *g_rgpclsidExtension[]=
  47. {
  48. &CLSID_W3EXTEND,
  49. &CLSID_WmRgSrv
  50. };
  51. static const DWORD g_cExtensions = sizeof(g_rgpclsidExtension)/sizeof(*g_rgpclsidExtension);
  52. PIADMEXT_CONTAINER g_piaecHead = NULL;
  53. HRESULT AddServiceExtension(IADMEXT *piaeExtension)
  54. {
  55. HRESULT hresReturn = ERROR_SUCCESS;
  56. PIADMEXT_CONTAINER piaecExtension = new IADMEXT_CONTAINER;
  57. if (piaecExtension == NULL) {
  58. hresReturn = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  59. }
  60. else {
  61. piaecExtension->piaeInstance = piaeExtension;
  62. piaecExtension->NextPtr = g_piaecHead;
  63. g_piaecHead = piaecExtension;
  64. }
  65. return hresReturn;
  66. }
  67. HRESULT
  68. StartServiceExtension(
  69. const CLSID *pclsidExtension)
  70. {
  71. HRESULT hr = S_OK;
  72. IADMEXT *piaeExtension = NULL;
  73. // Check args
  74. if ( pclsidExtension == NULL )
  75. {
  76. hr = E_INVALIDARG;
  77. goto exit;
  78. }
  79. // Create the extension
  80. hr = CoCreateInstance( *pclsidExtension,
  81. NULL,
  82. CLSCTX_INPROC_SERVER,
  83. IID_IADMEXT,
  84. (void**) &piaeExtension );
  85. if ( FAILED(hr) )
  86. {
  87. // IVANPASH
  88. // Not all service extensions are always registered.
  89. // For example wamreg is registered when w3svc is installed.
  90. // So if we cannot create a service extension, because the
  91. // it is not registered yet, just ignore the error.
  92. if ( hr == REGDB_E_CLASSNOTREG )
  93. {
  94. hr = S_OK;
  95. }
  96. goto exit;
  97. }
  98. // Initialize the extension
  99. hr = piaeExtension->Initialize();
  100. if ( FAILED(hr) )
  101. {
  102. goto exit;
  103. }
  104. // Add the extension to the list of the running extensions
  105. hr = AddServiceExtension(piaeExtension);
  106. if ( FAILED(hr) )
  107. {
  108. goto exit;
  109. }
  110. // Do not clear the extension
  111. piaeExtension = NULL;
  112. exit:
  113. DBG_ASSERT( SUCCEEDED(hr) );
  114. // Cleanup
  115. if ( piaeExtension != NULL )
  116. {
  117. StopServiceExtension( piaeExtension );
  118. piaeExtension = NULL;
  119. }
  120. return hr;
  121. }
  122. HRESULT
  123. StartServiceExtensions()
  124. {
  125. HRESULT hr = S_OK;
  126. DWORD dwIndex;
  127. DBG_ASSERT(g_piaecHead == NULL);
  128. for ( dwIndex = 0; dwIndex < g_cExtensions; dwIndex++ )
  129. {
  130. hr = StartServiceExtension( g_rgpclsidExtension[dwIndex] );
  131. if ( FAILED(hr) )
  132. {
  133. goto exit;
  134. }
  135. }
  136. exit:
  137. DBG_ASSERT( SUCCEEDED(hr) );
  138. // If failed
  139. if ( FAILED(hr) )
  140. {
  141. // Stop all service extenstions
  142. StopServiceExtensions();
  143. }
  144. return hr;
  145. }
  146. BOOL
  147. RemoveServiceExtension(IADMEXT **ppiaeExtension)
  148. {
  149. BOOL bReturn = FALSE;
  150. if (g_piaecHead != NULL) {
  151. PIADMEXT_CONTAINER piaecExtension = g_piaecHead;
  152. *ppiaeExtension = g_piaecHead->piaeInstance;
  153. g_piaecHead = g_piaecHead->NextPtr;
  154. delete piaecExtension;
  155. bReturn = TRUE;
  156. }
  157. return bReturn;
  158. }
  159. VOID
  160. StopServiceExtension(IADMEXT *piaeExtension)
  161. {
  162. piaeExtension->Terminate();
  163. piaeExtension->Release();
  164. }
  165. VOID StopServiceExtensions()
  166. {
  167. IADMEXT *piaeExtension;
  168. while (RemoveServiceExtension(&piaeExtension)) {
  169. StopServiceExtension(piaeExtension);
  170. }
  171. DBG_ASSERT(g_piaecHead == NULL);
  172. }
  173. HRESULT
  174. AddClsidToBuffer(CLSID clsidDcomExtension,
  175. BUFFER *pbufCLSIDs,
  176. DWORD *pdwMLSZLen,
  177. LPMALLOC pmallocOle)
  178. {
  179. HRESULT hresReturn = S_OK;
  180. LPWSTR pszCLSID;
  181. if (!pbufCLSIDs->Resize((*pdwMLSZLen + CLSID_LEN) * sizeof(WCHAR))) {
  182. hresReturn = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  183. }
  184. else {
  185. if (SUCCEEDED(StringFromCLSID(clsidDcomExtension, &pszCLSID))) {
  186. DBG_ASSERT(wcslen(pszCLSID) + 1 == CLSID_LEN);
  187. memcpy(((LPWSTR)pbufCLSIDs->QueryPtr()) + *pdwMLSZLen, pszCLSID, CLSID_LEN * sizeof(WCHAR));
  188. (*pdwMLSZLen) += CLSID_LEN;
  189. if (pmallocOle != NULL) {
  190. pmallocOle->Free(pszCLSID);
  191. }
  192. }
  193. }
  194. return hresReturn;
  195. }
  196. VOID
  197. RegisterServiceExtensionCLSIDs()
  198. {
  199. HRESULT hresMDError;
  200. HRESULT hresExtensionError;
  201. HRESULT hresBufferError;
  202. HRESULT hresCom;
  203. CLSID clsidDcomExtension;
  204. DWORD i;
  205. IMDCOM * pcCom = NULL;
  206. METADATA_HANDLE mdhRoot;
  207. METADATA_HANDLE mdhExtension;
  208. METADATA_RECORD mdrData;
  209. PIADMEXT_CONTAINER piaecExtension;
  210. BUFFER bufCLSIDs;
  211. DWORD dwMLSZLen = 0;
  212. BOOL bAreCLSIDs = FALSE;
  213. LPMALLOC pmallocOle = NULL;
  214. hresCom = CoGetMalloc(1, &pmallocOle);
  215. if( SUCCEEDED(hresCom) ) {
  216. hresMDError = CoCreateInstance(CLSID_MDCOM,
  217. NULL,
  218. CLSCTX_INPROC_SERVER,
  219. IID_IMDCOM,
  220. (void**) &pcCom);
  221. if (SUCCEEDED(hresMDError)) {
  222. hresMDError = pcCom->ComMDInitialize();
  223. if (SUCCEEDED(hresMDError)) {
  224. hresMDError = pcCom->ComMDOpenMetaObject(
  225. METADATA_MASTER_ROOT_HANDLE,
  226. (PBYTE)IISADMIN_EXTENSIONS_CLSID_MD_KEY,
  227. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
  228. MD_OPEN_DEFAULT_TIMEOUT_VALUE,
  229. &mdhExtension);
  230. if (hresMDError == RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND)) {
  231. hresMDError = pcCom->ComMDOpenMetaObject(
  232. METADATA_MASTER_ROOT_HANDLE,
  233. NULL,
  234. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
  235. MD_OPEN_DEFAULT_TIMEOUT_VALUE,
  236. &mdhRoot);
  237. if (SUCCEEDED(hresMDError)) {
  238. hresMDError = pcCom->ComMDAddMetaObject(
  239. mdhRoot,
  240. (PBYTE)IISADMIN_EXTENSIONS_CLSID_MD_KEY);
  241. pcCom->ComMDCloseMetaObject(mdhRoot);
  242. if (SUCCEEDED(hresMDError)) {
  243. hresMDError = pcCom->ComMDOpenMetaObject(
  244. METADATA_MASTER_ROOT_HANDLE,
  245. (PBYTE)IISADMIN_EXTENSIONS_CLSID_MD_KEY,
  246. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
  247. MD_OPEN_DEFAULT_TIMEOUT_VALUE,
  248. &mdhExtension);
  249. }
  250. }
  251. }
  252. if (SUCCEEDED(hresMDError)) {
  253. for (piaecExtension = g_piaecHead, hresBufferError = S_OK;
  254. (piaecExtension != NULL) && (SUCCEEDED(hresBufferError));
  255. piaecExtension = piaecExtension->NextPtr) {
  256. hresMDError = ERROR_SUCCESS;
  257. for (i = 0;
  258. SUCCEEDED(hresExtensionError =
  259. piaecExtension->piaeInstance->EnumDcomCLSIDs(&clsidDcomExtension,
  260. i));
  261. i++) {
  262. bAreCLSIDs = TRUE;
  263. hresBufferError = AddClsidToBuffer(clsidDcomExtension,
  264. &bufCLSIDs,
  265. &dwMLSZLen,
  266. pmallocOle);
  267. if (FAILED(hresBufferError)) {
  268. break;
  269. }
  270. }
  271. }
  272. BOOL fNeedToWrite = TRUE;
  273. // If we failed to deal with the buffer above then we won't
  274. // be trying to write new clsids below, but we will need to delete
  275. // the old clsids.
  276. if ( SUCCEEDED (hresBufferError) )
  277. {
  278. // Figure out if the clsids have changed.
  279. BUFFER MbBuffer;
  280. DWORD dwBufferRequiredSize = 0;
  281. if (MbBuffer.Resize( (dwMLSZLen + 1) * sizeof(WCHAR) ) )
  282. {
  283. METADATA_RECORD mdrDataRetrieve;
  284. mdrDataRetrieve.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  285. mdrDataRetrieve.dwMDUserType = IIS_MD_UT_SERVER;
  286. mdrDataRetrieve.dwMDDataType = MULTISZ_METADATA;
  287. mdrDataRetrieve.dwMDDataLen = (dwMLSZLen + 1) * sizeof(WCHAR);
  288. mdrDataRetrieve.pbMDData = (PBYTE)MbBuffer.QueryPtr();
  289. mdrDataRetrieve.dwMDIdentifier = IISADMIN_EXTENSIONS_CLSID_MD_ID;
  290. hresMDError = pcCom->ComMDGetMetaDataW( mdhExtension,
  291. NULL,
  292. &mdrDataRetrieve,
  293. &dwBufferRequiredSize );
  294. //
  295. // if we succeeded in getting info then check if the info
  296. // is of the right size and matches the data we all ready have.
  297. //
  298. if ( SUCCEEDED ( hresMDError ) )
  299. {
  300. // if we succeeded then we had enough space, so we can
  301. // check the full size that we thought should match.
  302. // then check the content of the data
  303. if ( memcmp ( MbBuffer.QueryPtr(), bufCLSIDs.QueryPtr(), (dwMLSZLen + 1) * sizeof(WCHAR) ) == 0 )
  304. {
  305. fNeedToWrite = FALSE;
  306. }
  307. }
  308. }
  309. }
  310. if ( fNeedToWrite )
  311. {
  312. //
  313. // We need to remove the old clsids.
  314. //
  315. pcCom->ComMDDeleteMetaData(
  316. mdhExtension,
  317. NULL,
  318. MD_IISADMIN_EXTENSIONS,
  319. MULTISZ_METADATA);
  320. //
  321. // Now we decide if we want to write the
  322. // new clsids.
  323. //
  324. if (bAreCLSIDs && SUCCEEDED(hresBufferError)) {
  325. if (bufCLSIDs.Resize((dwMLSZLen + 1) * sizeof(WCHAR))) {
  326. *(((LPWSTR)bufCLSIDs.QueryPtr()) + dwMLSZLen) = (WCHAR)'\0';
  327. mdrData.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  328. mdrData.dwMDUserType = IIS_MD_UT_SERVER;
  329. mdrData.dwMDDataType = MULTISZ_METADATA;
  330. mdrData.dwMDDataLen = (dwMLSZLen + 1) * sizeof(WCHAR);
  331. mdrData.pbMDData = (PBYTE)bufCLSIDs.QueryPtr();
  332. mdrData.dwMDIdentifier = IISADMIN_EXTENSIONS_CLSID_MD_ID;
  333. hresMDError = pcCom->ComMDSetMetaDataW(
  334. mdhExtension,
  335. NULL,
  336. &mdrData);
  337. } // end of writting because we had to.
  338. } // end of clsids
  339. } // end of needing to write
  340. pcCom->ComMDCloseMetaObject(mdhExtension);
  341. }
  342. pcCom->ComMDTerminate(TRUE);
  343. }
  344. pcCom->Release();
  345. }
  346. if (pmallocOle != NULL) {
  347. pmallocOle->Release();
  348. }
  349. }
  350. }