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.

342 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. extcom.cxx
  5. Abstract:
  6. IIS Services IISADMIN Extension
  7. Main COM interface.
  8. Class CadmExt
  9. CLSID = CLSID_W3EXTEND
  10. IID = IID_IADMEXT
  11. Author:
  12. Michael W. Thomas 16-Sep-97
  13. --*/
  14. #include <cominc.hxx>
  15. #ifdef _IIS_6_0
  16. #include "w3ssl_config.hxx"
  17. #include <iismap.hxx>
  18. #endif
  19. DECLARE_DEBUG_PRINTS_OBJECT();
  20. PFNCREATECOMPLUSAPPLICATION g_pfnCreateCOMPlusApplication = NULL;
  21. static const CHAR c_szWamReg[] = "wamreg.dll";
  22. static const CHAR c_szCreateCOMPlusApplication[] = "CreateCOMPlusApplication";
  23. CAdmExt::CAdmExt():
  24. m_dwRefCount(0),
  25. m_pcCom(NULL),
  26. m_dwSinkCookie(0),
  27. m_pConnPoint(NULL)
  28. {
  29. }
  30. CAdmExt::~CAdmExt()
  31. {
  32. #ifndef _NO_TRACING_
  33. DELETE_DEBUG_PRINT_OBJECT();
  34. #endif
  35. }
  36. HRESULT
  37. CAdmExt::QueryInterface(
  38. REFIID riid,
  39. void **ppObject)
  40. {
  41. if ( ppObject == NULL )
  42. {
  43. return E_INVALIDARG;
  44. }
  45. *ppObject = NULL;
  46. if ( riid==IID_IUnknown || riid==IID_IADMEXT )
  47. {
  48. *ppObject = (IADMEXT *) this;
  49. }
  50. else
  51. {
  52. return E_NOINTERFACE;
  53. }
  54. AddRef();
  55. return S_OK;
  56. }
  57. ULONG
  58. CAdmExt::AddRef()
  59. {
  60. DWORD dwRefCount;
  61. InterlockedIncrement((long *)&g_dwRefCount);
  62. dwRefCount = InterlockedIncrement((long *)&m_dwRefCount);
  63. return dwRefCount;
  64. }
  65. ULONG
  66. CAdmExt::Release()
  67. {
  68. DWORD dwRefCount;
  69. InterlockedDecrement((long *)&g_dwRefCount);
  70. dwRefCount = InterlockedDecrement((long *)&m_dwRefCount);
  71. //
  72. // This is now a member of class factory.
  73. // It is not dynamically allocated, so don't delete it.
  74. //
  75. return dwRefCount;
  76. }
  77. HRESULT STDMETHODCALLTYPE
  78. CAdmExt::Initialize(void)
  79. {
  80. HRESULT hresReturn = S_OK;
  81. HMODULE hmodWamReg = NULL;
  82. CREATE_DEBUG_PRINT_OBJECT( "svcext" );
  83. LOAD_DEBUG_FLAGS_FROM_REG_STR( "System\\CurrentControlSet\\Services\\iisadmin\\Parameters", 0 );
  84. hmodWamReg = LoadLibraryA( c_szWamReg );
  85. if ( hmodWamReg != NULL )
  86. {
  87. g_pfnCreateCOMPlusApplication = (PFNCREATECOMPLUSAPPLICATION)GetProcAddress( hmodWamReg, c_szCreateCOMPlusApplication );
  88. DBG_ASSERT( g_pfnCreateCOMPlusApplication != NULL );
  89. if ( g_pfnCreateCOMPlusApplication == NULL )
  90. {
  91. DBGPRINTF(( DBG_CONTEXT,
  92. "Loaded %s, but failed to get %s.\n",
  93. c_szWamReg,
  94. c_szCreateCOMPlusApplication ));
  95. FreeLibrary( hmodWamReg );
  96. hmodWamReg = NULL;
  97. hresReturn = E_FAIL;
  98. return hresReturn;
  99. }
  100. else
  101. {
  102. DBGPRINTF(( DBG_CONTEXT,
  103. "Loaded %s and got %s.\n",
  104. c_szWamReg,
  105. c_szCreateCOMPlusApplication ));
  106. // We need to keep the wamreg.dll loaded as if importing CreateCOMPlusApplication
  107. hmodWamReg = NULL;
  108. }
  109. }
  110. else
  111. {
  112. DBGPRINTF(( DBG_CONTEXT,
  113. "Failed to load %s.\n",
  114. c_szWamReg ));
  115. // If wamreg is not installed do NOT fail.
  116. // This is a valid case if we have only ftp installed, but no www.
  117. }
  118. #ifdef _IIS_6_0
  119. ImportIISCertMappingsToIIS6();
  120. hresReturn = W3SSL_CONFIG::Initialize();
  121. //
  122. // based on the IIS mode adjust the image path of HTTPFilter service
  123. //
  124. if ( FAILED(hresReturn) )
  125. {
  126. return hresReturn;
  127. }
  128. //
  129. // ImagePath of HTTPFilter must be changed asynchronously here
  130. // The reason is that in this moment the service database is locked
  131. // because iisadmin is in START_PENDING and if we tried to change
  132. // image path of HTTPFilter synchronously it would cause deadlock
  133. // Note: Changing asynchronously has a side effect that after iisadmin
  134. // reports that service started, it is not guaranteed that image path
  135. // of HTTPFilter was already changed
  136. W3SSL_CONFIG::StartAsyncAdjustHTTPFilterImagePath();
  137. #endif
  138. hresReturn = CoCreateInstance(CLSID_MDCOM,
  139. NULL,
  140. CLSCTX_SERVER,
  141. IID_IMDCOM,
  142. (void**) &m_pcCom);
  143. if (SUCCEEDED(hresReturn))
  144. {
  145. //
  146. // First, set the state of all servers to Stopped.
  147. //
  148. SetServerState(L"/LM/W3SVC");
  149. SetServerState(L"/LM/MSFTPSVC");
  150. //
  151. // Set up a sink for special processing.
  152. //
  153. IConnectionPointContainer* pConnPointContainer = NULL;
  154. CSvcExtImpIMDCOMSINK *pEventSink = new CSvcExtImpIMDCOMSINK(m_pcCom);
  155. if (pEventSink != NULL)
  156. {
  157. // First query the object for its Connection Point Container. This
  158. // essentially asks the object in the server if it is connectable.
  159. hresReturn = m_pcCom->QueryInterface(
  160. IID_IConnectionPointContainer,
  161. (PVOID *)&pConnPointContainer);
  162. if SUCCEEDED(hresReturn)
  163. {
  164. // Find the requested Connection Point. This AddRef's the
  165. // returned pointer.
  166. hresReturn = pConnPointContainer->FindConnectionPoint(IID_IMDCOMSINK_W, &m_pConnPoint);
  167. if (SUCCEEDED(hresReturn))
  168. {
  169. hresReturn = m_pConnPoint->Advise((IUnknown *)pEventSink, &m_dwSinkCookie);
  170. }
  171. pConnPointContainer->Release();
  172. }
  173. pEventSink->Release();
  174. }
  175. else
  176. {
  177. hresReturn = E_OUTOFMEMORY;
  178. }
  179. }
  180. UpdateUsers();
  181. return hresReturn;
  182. }
  183. HRESULT STDMETHODCALLTYPE
  184. CAdmExt::EnumDcomCLSIDs(
  185. CLSID *,
  186. DWORD )
  187. {
  188. return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  189. }
  190. HRESULT STDMETHODCALLTYPE
  191. CAdmExt::Terminate(void)
  192. {
  193. #ifdef _IIS_6_0
  194. //
  195. // terminate W3SSL_CONFIG before unadvising because
  196. // that will enable to unblock calls to W3SSL_CONFIG that
  197. // may have happen from sink callbacks
  198. //
  199. W3SSL_CONFIG::Terminate();
  200. #endif
  201. if (m_pcCom != NULL)
  202. {
  203. if (m_pConnPoint != NULL)
  204. {
  205. if (m_dwSinkCookie != 0)
  206. {
  207. m_pConnPoint->Unadvise(m_dwSinkCookie);
  208. }
  209. m_pConnPoint->Release();
  210. }
  211. m_pcCom->Release();
  212. }
  213. return S_OK;
  214. }
  215. VOID
  216. CAdmExt::SetServerState(
  217. LPWSTR pszPath)
  218. {
  219. HRESULT hresReturn;
  220. HRESULT hresTempReturn;
  221. TCHAR pszNameBuf[METADATA_MAX_NAME_LEN];
  222. int i;
  223. METADATA_RECORD mdrData;
  224. DWORD dwData;
  225. DWORD dwRequiredDataLen;
  226. METADATA_HANDLE mdhCurrent;
  227. hresReturn = m_pcCom->ComMDOpenMetaObject(METADATA_MASTER_ROOT_HANDLE,
  228. pszPath,
  229. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
  230. OPEN_TIMEOUT_VALUE,
  231. &mdhCurrent);
  232. if (SUCCEEDED(hresReturn))
  233. {
  234. for (i=0;hresReturn == ERROR_SUCCESS;i++)
  235. {
  236. //
  237. // enumerate children
  238. //
  239. hresReturn = m_pcCom->ComMDEnumMetaObjects(mdhCurrent,
  240. TEXT(""),
  241. pszNameBuf,
  242. i);
  243. if (SUCCEEDED(hresReturn))
  244. {
  245. MD_SET_DATA_RECORD_EXT(&mdrData,
  246. MD_SERVER_STATE,
  247. METADATA_NO_ATTRIBUTES,
  248. 0,
  249. DWORD_METADATA,
  250. sizeof(DWORD),
  251. (PBYTE)&dwData)
  252. //
  253. // See if Server State exists at this node,
  254. // and pick up the current attributes, etc.
  255. //
  256. hresTempReturn = m_pcCom->ComMDGetMetaData(mdhCurrent,
  257. pszNameBuf,
  258. &mdrData,
  259. &dwRequiredDataLen);
  260. //
  261. // PREFIX
  262. // ComMDGetMetaData should not return success without setting the data
  263. // value pointed to by dwData. I'm not sure if PREFIX is incapable of
  264. // recognizing the extra level of indirection or if there is some path
  265. // that I missed in reviewing ComMDGetMetaData. I'm going to shut down
  266. // this warning, but I'll open an issue with the PREFIX guys.
  267. //
  268. /* INTRINSA suppress = uninitialized */
  269. if ((SUCCEEDED(hresTempReturn)) && (dwData != MD_SERVER_STATE_STOPPED))
  270. {
  271. //
  272. // Set the new data
  273. //
  274. dwData = MD_SERVER_STATE_STOPPED;
  275. hresTempReturn = m_pcCom->ComMDSetMetaData(mdhCurrent,
  276. pszNameBuf,
  277. &mdrData);
  278. }
  279. }
  280. }
  281. hresReturn = m_pcCom->ComMDCloseMetaObject(mdhCurrent);
  282. }
  283. }