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.

424 lines
8.9 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997
  5. //
  6. // File: common.cxx
  7. //
  8. // Contents: Microsoft ADs IIS Common routines
  9. //
  10. // History: 28-Feb-97 SophiaC Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "iisext.hxx"
  14. extern SERVER_CACHE * g_pServerCache;
  15. extern WIN32_CRITSEC * g_pGlobalLock;
  16. #pragma hdrstop
  17. #define DEFAULT_TIMEOUT_VALUE 30000
  18. //+------------------------------------------------------------------------
  19. //
  20. // Class: Common
  21. //
  22. // Purpose: Contains Winnt routines and properties that are common to
  23. // all Winnt objects. Winnt objects get the routines and
  24. // properties through C++ inheritance.
  25. //
  26. //-------------------------------------------------------------------------
  27. HRESULT
  28. ReCacheAdminBase(
  29. IN LPWSTR pszServerName,
  30. IN OUT IMSAdminBase **ppAdminBase
  31. )
  32. {
  33. HRESULT hr = S_OK;
  34. SERVER_CACHE_ITEM * item = NULL;
  35. DWORD dwThreadId;
  36. IMSAdminBase * pAdminBase = *ppAdminBase;
  37. IMSAdminBase * pOldAdminBase = *ppAdminBase;
  38. // RPC error caused this function to be called, so try to
  39. // recover the connection
  40. hr = InitAdminBase(pszServerName, &pAdminBase);
  41. BAIL_ON_FAILURE(hr);
  42. // we will return this one, so save it in the OUT param
  43. *ppAdminBase = pAdminBase;
  44. // update the cache
  45. dwThreadId = GetCurrentThreadId();
  46. item = g_pServerCache->Find(pszServerName, dwThreadId);
  47. if (item != NULL)
  48. {
  49. UninitAdminBase(pOldAdminBase);
  50. item->UpdateAdminBase(pAdminBase, dwThreadId);
  51. }
  52. error :
  53. RRETURN(hr);
  54. }
  55. HRESULT
  56. OpenAdminBaseKey(
  57. IN LPWSTR pszServerName,
  58. IN LPWSTR pszPathName,
  59. IN DWORD dwAccessType,
  60. IN OUT IMSAdminBase **ppAdminBase,
  61. OUT METADATA_HANDLE *phHandle
  62. )
  63. {
  64. HRESULT hr;
  65. IMSAdminBase *pAdminBase = *ppAdminBase;
  66. METADATA_HANDLE RootHandle = NULL;
  67. DWORD dwThreadId;
  68. hr = pAdminBase->OpenKey(
  69. METADATA_MASTER_ROOT_HANDLE,
  70. pszPathName,
  71. dwAccessType,
  72. DEFAULT_TIMEOUT_VALUE,
  73. &RootHandle
  74. );
  75. if (FAILED(hr)) {
  76. if ((HRESULT_CODE(hr) == RPC_S_SERVER_UNAVAILABLE) ||
  77. ((HRESULT_CODE(hr) >= RPC_S_NO_CALL_ACTIVE) &&
  78. (HRESULT_CODE(hr) <= RPC_S_CALL_FAILED_DNE)) ||
  79. hr == RPC_E_DISCONNECTED) {
  80. hr = ReCacheAdminBase(pszServerName, &pAdminBase);
  81. BAIL_ON_FAILURE(hr);
  82. hr = pAdminBase->OpenKey(
  83. METADATA_MASTER_ROOT_HANDLE,
  84. pszPathName,
  85. dwAccessType,
  86. DEFAULT_TIMEOUT_VALUE,
  87. &RootHandle
  88. );
  89. BAIL_ON_FAILURE(hr);
  90. }
  91. }
  92. error :
  93. if (FAILED(hr)) {
  94. if (pAdminBase && RootHandle) {
  95. pAdminBase->CloseKey(RootHandle);
  96. }
  97. }
  98. else {
  99. *phHandle = RootHandle;
  100. }
  101. RRETURN(hr);
  102. }
  103. VOID
  104. CloseAdminBaseKey(
  105. IN IMSAdminBase *pAdminBase,
  106. IN METADATA_HANDLE hHandle
  107. )
  108. {
  109. HRESULT hr;
  110. if (pAdminBase) {
  111. hr = pAdminBase->CloseKey(hHandle);
  112. }
  113. return;
  114. }
  115. HRESULT
  116. InitAdminBase(
  117. IN LPWSTR pszServerName,
  118. OUT IMSAdminBase **ppAdminBase
  119. )
  120. {
  121. HRESULT hr = S_OK;
  122. COSERVERINFO csiName;
  123. COSERVERINFO *pcsiParam = &csiName;
  124. IClassFactory * pcsfFactory = NULL;
  125. IMSAdminBase * pAdminBase = NULL;
  126. IMSAdminBase * pAdminBaseT = NULL;
  127. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  128. //
  129. // special case to handle "localhost" to work-around ole32 bug
  130. //
  131. if (pszServerName == NULL || _wcsicmp(pszServerName,L"localhost") == 0) {
  132. pcsiParam->pwszName = NULL;
  133. }
  134. else {
  135. pcsiParam->pwszName = pszServerName;
  136. }
  137. csiName.pAuthInfo = NULL;
  138. pcsiParam = &csiName;
  139. hr = CoGetClassObject(
  140. CLSID_MSAdminBase,
  141. CLSCTX_SERVER,
  142. pcsiParam,
  143. IID_IClassFactory,
  144. (void**) &pcsfFactory
  145. );
  146. BAIL_ON_FAILURE(hr);
  147. hr = pcsfFactory->CreateInstance(
  148. NULL,
  149. IID_IMSAdminBase,
  150. (void **) &pAdminBaseT
  151. );
  152. BAIL_ON_FAILURE(hr);
  153. hr = pAdminBaseT->UnmarshalInterface((IMSAdminBaseW **)&pAdminBase);
  154. pAdminBaseT->Release();
  155. pAdminBaseT = NULL;
  156. BAIL_ON_FAILURE(hr);
  157. *ppAdminBase = pAdminBase;
  158. error:
  159. if (pcsfFactory) {
  160. pcsfFactory->Release();
  161. }
  162. RRETURN(hr);
  163. }
  164. VOID
  165. UninitAdminBase(
  166. IN IMSAdminBase * pAdminBase
  167. )
  168. {
  169. if (pAdminBase != NULL) {
  170. pAdminBase->Release();
  171. }
  172. }
  173. HRESULT
  174. InitServerInfo(
  175. IN LPWSTR pszServerName,
  176. OUT IMSAdminBase ** ppObject
  177. )
  178. {
  179. HRESULT hr = S_OK;
  180. IMSAdminBase * pAdminBase = NULL;
  181. SERVER_CACHE_ITEM * item;
  182. BOOL Success;
  183. DWORD dwThreadId;
  184. ASSERT(g_pServerCache != NULL);
  185. //
  186. // We'll return the localhost machine config to the users if
  187. // pszServerName == NULL, e.g. IIS:
  188. //
  189. if (pszServerName == NULL) {
  190. pszServerName = L"Localhost";
  191. }
  192. dwThreadId = GetCurrentThreadId();
  193. if ((item = g_pServerCache->Find(pszServerName, dwThreadId)) == NULL) {
  194. //
  195. // get pAdminBase
  196. //
  197. hr = InitAdminBase(pszServerName, &pAdminBase);
  198. BAIL_ON_FAILURE(hr);
  199. item = new SERVER_CACHE_ITEM(pszServerName,
  200. pAdminBase,
  201. dwThreadId,
  202. Success);
  203. if (item == NULL || !Success) {
  204. if (item != NULL) {
  205. UninitAdminBase(pAdminBase);
  206. delete item;
  207. }
  208. RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
  209. }
  210. if (g_pServerCache->Insert(item) == FALSE) {
  211. UninitAdminBase(pAdminBase);
  212. delete item;
  213. RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
  214. }
  215. }
  216. *ppObject = item->pAdminBase;
  217. error :
  218. RRETURN(hr);
  219. }
  220. HRESULT
  221. InitWamAdmin(
  222. IN LPWSTR pszServerName,
  223. OUT IWamAdmin2 **ppWamAdmin
  224. )
  225. {
  226. HRESULT hr = S_OK;
  227. COSERVERINFO csiName;
  228. COSERVERINFO *pcsiParam = &csiName;
  229. IClassFactory * pcsfFactory = NULL;
  230. IWamAdmin2 * pWamAdmin = NULL;
  231. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  232. //
  233. // special case to handle "localhost" to work-around ole32 bug
  234. //
  235. if (pszServerName == NULL || _wcsicmp(pszServerName,L"localhost") == 0) {
  236. pcsiParam->pwszName = NULL;
  237. }
  238. else {
  239. pcsiParam->pwszName = pszServerName;
  240. }
  241. csiName.pAuthInfo = NULL;
  242. pcsiParam = &csiName;
  243. hr = CoGetClassObject(
  244. CLSID_WamAdmin,
  245. CLSCTX_SERVER,
  246. pcsiParam,
  247. IID_IClassFactory,
  248. (void**) &pcsfFactory
  249. );
  250. BAIL_ON_FAILURE(hr);
  251. hr = pcsfFactory->CreateInstance(
  252. NULL,
  253. IID_IWamAdmin2,
  254. (void **) &pWamAdmin
  255. );
  256. BAIL_ON_FAILURE(hr);
  257. *ppWamAdmin = pWamAdmin;
  258. error:
  259. if (pcsfFactory) {
  260. pcsfFactory->Release();
  261. }
  262. RRETURN(hr);
  263. }
  264. VOID
  265. UninitWamAdmin(
  266. IN IWamAdmin2 *pWamAdmin
  267. )
  268. {
  269. if (pWamAdmin != NULL) {
  270. pWamAdmin->Release();
  271. }
  272. }
  273. HRESULT
  274. BuildIISPathFromADsPath(
  275. POBJECTINFO pObjectInfo,
  276. LPWSTR pszIISPathName
  277. )
  278. {
  279. DWORD dwNumComponents = 0;
  280. DWORD i = 0;
  281. dwNumComponents = pObjectInfo->NumComponents;
  282. //
  283. // wcscat "LM" to IIS Metabase path
  284. //
  285. wcscat(pszIISPathName, L"/LM/");
  286. if (dwNumComponents) {
  287. for (i = 0; i < dwNumComponents; i++) {
  288. if (wcscmp(pObjectInfo->ComponentArray[i].szComponent, L"[Root]")){
  289. wcscat(pszIISPathName, pObjectInfo->ComponentArray[i].szComponent);
  290. }
  291. else {
  292. if( i == dwNumComponents -1 ) {
  293. wcscat(pszIISPathName, L"/");
  294. }
  295. }
  296. if( i < dwNumComponents -1 ) {
  297. wcscat(pszIISPathName,L"/");
  298. }
  299. }
  300. }
  301. RRETURN(S_OK);
  302. }
  303. VOID
  304. FreeObjectInfo(
  305. POBJECTINFO pObjectInfo
  306. )
  307. {
  308. if ( !pObjectInfo )
  309. return;
  310. FreeADsStr( pObjectInfo->ProviderName );
  311. FreeADsStr( pObjectInfo->TreeName );
  312. for ( DWORD i = 0; i < pObjectInfo->NumComponents; i++ ) {
  313. if (pObjectInfo->ComponentArray[i].szComponent) {
  314. FreeADsStr( pObjectInfo->ComponentArray[i].szComponent );
  315. }
  316. if (pObjectInfo->ComponentArray[i].szValue) {
  317. FreeADsStr( pObjectInfo->ComponentArray[i].szValue );
  318. }
  319. }
  320. if (pObjectInfo->ComponentArray) {
  321. FreeADsMem(pObjectInfo->ComponentArray);
  322. }
  323. // We don't need to free pObjectInfo since the object is always a static
  324. // variable on the stack.
  325. }