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.

531 lines
12 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. MakeVariantFromStringArray(
  29. LPWSTR pszList,
  30. VARIANT *pvVariant
  31. )
  32. {
  33. HRESULT hr = S_OK;
  34. SAFEARRAY *aList = NULL;
  35. SAFEARRAYBOUND aBound;
  36. LPWSTR pszStrList;
  37. WCHAR wchPath[MAX_PATH];
  38. if (pszList != NULL)
  39. {
  40. long nCount = 0;
  41. long i = 0;
  42. pszStrList = pszList;
  43. if (*pszStrList == L'\0') {
  44. nCount = 1;
  45. pszStrList++;
  46. }
  47. while (*pszStrList != L'\0') {
  48. while (*pszStrList != L'\0') {
  49. pszStrList++;
  50. }
  51. nCount++;
  52. pszStrList++;
  53. }
  54. aBound.lLbound = 0;
  55. aBound.cElements = nCount;
  56. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  57. if ( aList == NULL )
  58. {
  59. hr = E_OUTOFMEMORY;
  60. BAIL_ON_FAILURE(hr);
  61. }
  62. pszStrList = pszList;
  63. for (i = 0; i < nCount; i++ )
  64. {
  65. VARIANT v;
  66. VariantInit(&v);
  67. V_VT(&v) = VT_BSTR;
  68. hr = ADsAllocString( pszStrList, &(V_BSTR(&v)));
  69. BAIL_ON_FAILURE(hr);
  70. hr = SafeArrayPutElement( aList, &i, &v );
  71. VariantClear(&v);
  72. BAIL_ON_FAILURE(hr);
  73. pszStrList += wcslen(pszStrList) + 1;
  74. }
  75. VariantInit( pvVariant );
  76. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  77. V_ARRAY(pvVariant) = aList;
  78. }
  79. else
  80. {
  81. aBound.lLbound = 0;
  82. aBound.cElements = 0;
  83. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  84. if ( aList == NULL )
  85. {
  86. hr = E_OUTOFMEMORY;
  87. BAIL_ON_FAILURE(hr);
  88. }
  89. VariantInit( pvVariant );
  90. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  91. V_ARRAY(pvVariant) = aList;
  92. }
  93. return S_OK;
  94. error:
  95. if ( aList )
  96. SafeArrayDestroy( aList );
  97. return hr;
  98. }
  99. HRESULT
  100. ReCacheAdminBase(
  101. IN LPWSTR pszServerName,
  102. IN OUT IMSAdminBase **ppAdminBase
  103. )
  104. {
  105. HRESULT hr = S_OK;
  106. SERVER_CACHE_ITEM * item = NULL;
  107. DWORD dwThreadId;
  108. IMSAdminBase * pAdminBase = *ppAdminBase;
  109. IMSAdminBase * pOldAdminBase = *ppAdminBase;
  110. // RPC error caused this function to be called, so try to
  111. // recover the connection
  112. hr = InitAdminBase(pszServerName, &pAdminBase);
  113. BAIL_ON_FAILURE(hr);
  114. // we will return this one, so save it in the OUT param
  115. *ppAdminBase = pAdminBase;
  116. // update the cache
  117. dwThreadId = GetCurrentThreadId();
  118. item = g_pServerCache->Find(pszServerName, dwThreadId);
  119. if (item != NULL)
  120. {
  121. UninitAdminBase(pOldAdminBase);
  122. item->UpdateAdminBase(pAdminBase, dwThreadId);
  123. }
  124. error :
  125. RRETURN(hr);
  126. }
  127. HRESULT
  128. OpenAdminBaseKey(
  129. IN LPWSTR pszServerName,
  130. IN LPWSTR pszPathName,
  131. IN DWORD dwAccessType,
  132. IN OUT IMSAdminBase **ppAdminBase,
  133. OUT METADATA_HANDLE *phHandle
  134. )
  135. {
  136. HRESULT hr;
  137. IMSAdminBase *pAdminBase = *ppAdminBase;
  138. METADATA_HANDLE RootHandle = NULL;
  139. DWORD dwThreadId;
  140. hr = pAdminBase->OpenKey(
  141. METADATA_MASTER_ROOT_HANDLE,
  142. pszPathName,
  143. dwAccessType,
  144. DEFAULT_TIMEOUT_VALUE,
  145. &RootHandle
  146. );
  147. if (FAILED(hr)) {
  148. if ((HRESULT_CODE(hr) == RPC_S_SERVER_UNAVAILABLE) ||
  149. ((HRESULT_CODE(hr) >= RPC_S_NO_CALL_ACTIVE) &&
  150. (HRESULT_CODE(hr) <= RPC_S_CALL_FAILED_DNE)) ||
  151. hr == RPC_E_DISCONNECTED) {
  152. hr = ReCacheAdminBase(pszServerName, &pAdminBase);
  153. BAIL_ON_FAILURE(hr);
  154. *ppAdminBase = pAdminBase;
  155. hr = pAdminBase->OpenKey(
  156. METADATA_MASTER_ROOT_HANDLE,
  157. pszPathName,
  158. dwAccessType,
  159. DEFAULT_TIMEOUT_VALUE,
  160. &RootHandle
  161. );
  162. BAIL_ON_FAILURE(hr);
  163. }
  164. }
  165. error :
  166. if (FAILED(hr)) {
  167. if (pAdminBase && RootHandle) {
  168. pAdminBase->CloseKey(RootHandle);
  169. }
  170. }
  171. else {
  172. *phHandle = RootHandle;
  173. }
  174. RRETURN(hr);
  175. }
  176. VOID
  177. CloseAdminBaseKey(
  178. IN IMSAdminBase *pAdminBase,
  179. IN METADATA_HANDLE hHandle
  180. )
  181. {
  182. HRESULT hr;
  183. if (pAdminBase) {
  184. hr = pAdminBase->CloseKey(hHandle);
  185. }
  186. return;
  187. }
  188. HRESULT
  189. InitAdminBase(
  190. IN LPWSTR pszServerName,
  191. OUT IMSAdminBase **ppAdminBase
  192. )
  193. {
  194. HRESULT hr = S_OK;
  195. COSERVERINFO csiName;
  196. COSERVERINFO *pcsiParam = &csiName;
  197. IClassFactory * pcsfFactory = NULL;
  198. IMSAdminBase * pAdminBase = NULL;
  199. IMSAdminBase * pAdminBaseT = NULL;
  200. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  201. //
  202. // special case to handle "localhost" to work-around ole32 bug
  203. //
  204. if (pszServerName == NULL || _wcsicmp(pszServerName,L"localhost") == 0) {
  205. pcsiParam->pwszName = NULL;
  206. }
  207. else {
  208. pcsiParam->pwszName = pszServerName;
  209. }
  210. csiName.pAuthInfo = NULL;
  211. pcsiParam = &csiName;
  212. hr = CoGetClassObject(
  213. CLSID_MSAdminBase,
  214. CLSCTX_SERVER,
  215. pcsiParam,
  216. IID_IClassFactory,
  217. (void**) &pcsfFactory
  218. );
  219. BAIL_ON_FAILURE(hr);
  220. hr = pcsfFactory->CreateInstance(
  221. NULL,
  222. IID_IMSAdminBase,
  223. (void **) &pAdminBaseT
  224. );
  225. BAIL_ON_FAILURE(hr);
  226. hr = pAdminBaseT->UnmarshalInterface((IMSAdminBaseW **)&pAdminBase);
  227. pAdminBaseT->Release();
  228. pAdminBaseT = NULL;
  229. BAIL_ON_FAILURE(hr);
  230. *ppAdminBase = pAdminBase;
  231. error:
  232. if (pcsfFactory) {
  233. pcsfFactory->Release();
  234. }
  235. RRETURN(hr);
  236. }
  237. VOID
  238. UninitAdminBase(
  239. IN IMSAdminBase * pAdminBase
  240. )
  241. {
  242. if (pAdminBase != NULL) {
  243. pAdminBase->Release();
  244. }
  245. }
  246. HRESULT
  247. InitServerInfo(
  248. IN LPWSTR pszServerName,
  249. OUT IMSAdminBase ** ppObject
  250. )
  251. {
  252. HRESULT hr = S_OK;
  253. IMSAdminBase * pAdminBase = NULL;
  254. SERVER_CACHE_ITEM * item;
  255. BOOL Success;
  256. DWORD dwThreadId;
  257. ASSERT(g_pServerCache != NULL);
  258. //
  259. // We'll return the localhost machine config to the users if
  260. // pszServerName == NULL, e.g. IIS:
  261. //
  262. if (pszServerName == NULL) {
  263. pszServerName = L"Localhost";
  264. }
  265. dwThreadId = GetCurrentThreadId();
  266. if ((item = g_pServerCache->Find(pszServerName, dwThreadId)) == NULL) {
  267. //
  268. // get pAdminBase
  269. //
  270. hr = InitAdminBase(pszServerName, &pAdminBase);
  271. BAIL_ON_FAILURE(hr);
  272. item = new SERVER_CACHE_ITEM(pszServerName,
  273. pAdminBase,
  274. dwThreadId,
  275. Success);
  276. if (item == NULL || !Success) {
  277. if (item != NULL) {
  278. UninitAdminBase(pAdminBase);
  279. delete item;
  280. }
  281. RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
  282. }
  283. if (g_pServerCache->Insert(item) == FALSE) {
  284. UninitAdminBase(pAdminBase);
  285. delete item;
  286. RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
  287. }
  288. }
  289. *ppObject = item->pAdminBase;
  290. error :
  291. RRETURN(hr);
  292. }
  293. HRESULT
  294. InitWamAdmin(
  295. IN LPWSTR pszServerName,
  296. OUT IWamAdmin2 **ppWamAdmin
  297. )
  298. {
  299. HRESULT hr = S_OK;
  300. COSERVERINFO csiName;
  301. COSERVERINFO *pcsiParam = &csiName;
  302. IClassFactory * pcsfFactory = NULL;
  303. IWamAdmin2 * pWamAdmin = NULL;
  304. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  305. //
  306. // special case to handle "localhost" to work-around ole32 bug
  307. //
  308. if (pszServerName == NULL || _wcsicmp(pszServerName,L"localhost") == 0) {
  309. pcsiParam->pwszName = NULL;
  310. }
  311. else {
  312. pcsiParam->pwszName = pszServerName;
  313. }
  314. csiName.pAuthInfo = NULL;
  315. pcsiParam = &csiName;
  316. hr = CoGetClassObject(
  317. CLSID_WamAdmin,
  318. CLSCTX_SERVER,
  319. pcsiParam,
  320. IID_IClassFactory,
  321. (void**) &pcsfFactory
  322. );
  323. BAIL_ON_FAILURE(hr);
  324. hr = pcsfFactory->CreateInstance(
  325. NULL,
  326. IID_IWamAdmin2,
  327. (void **) &pWamAdmin
  328. );
  329. BAIL_ON_FAILURE(hr);
  330. *ppWamAdmin = pWamAdmin;
  331. error:
  332. if (pcsfFactory) {
  333. pcsfFactory->Release();
  334. }
  335. RRETURN(hr);
  336. }
  337. VOID
  338. UninitWamAdmin(
  339. IN IWamAdmin2 *pWamAdmin
  340. )
  341. {
  342. if (pWamAdmin != NULL) {
  343. pWamAdmin->Release();
  344. }
  345. }
  346. HRESULT
  347. BuildIISPathFromADsPath(
  348. POBJECTINFO pObjectInfo,
  349. LPWSTR pszIISPathName
  350. )
  351. {
  352. DWORD dwNumComponents = 0;
  353. DWORD i = 0;
  354. dwNumComponents = pObjectInfo->NumComponents;
  355. //
  356. // wcscat "LM" to IIS Metabase path
  357. //
  358. wcscat(pszIISPathName, L"/LM/");
  359. if (dwNumComponents) {
  360. for (i = 0; i < dwNumComponents; i++) {
  361. if (wcscmp(pObjectInfo->ComponentArray[i].szComponent, L"[Root]")){
  362. wcscat(pszIISPathName, pObjectInfo->ComponentArray[i].szComponent);
  363. }
  364. else {
  365. if( i == dwNumComponents -1 ) {
  366. wcscat(pszIISPathName, L"/");
  367. }
  368. }
  369. if( i < dwNumComponents -1 ) {
  370. wcscat(pszIISPathName,L"/");
  371. }
  372. }
  373. }
  374. RRETURN(S_OK);
  375. }
  376. VOID
  377. FreeObjectInfo(
  378. POBJECTINFO pObjectInfo
  379. )
  380. {
  381. if ( !pObjectInfo )
  382. return;
  383. if (pObjectInfo->ProviderName)
  384. {
  385. FreeADsStr( pObjectInfo->ProviderName );
  386. }
  387. if (pObjectInfo->TreeName)
  388. {
  389. FreeADsStr( pObjectInfo->TreeName );
  390. }
  391. if ((pObjectInfo->ComponentArray) && (pObjectInfo->NumComponents))
  392. {
  393. for ( DWORD i = 0; i < pObjectInfo->NumComponents; i++ ) {
  394. if (pObjectInfo->ComponentArray[i].szComponent) {
  395. FreeADsStr( pObjectInfo->ComponentArray[i].szComponent );
  396. }
  397. if (pObjectInfo->ComponentArray[i].szValue) {
  398. FreeADsStr( pObjectInfo->ComponentArray[i].szValue );
  399. }
  400. }
  401. }
  402. if (pObjectInfo->ComponentArray) {
  403. FreeADsMem(pObjectInfo->ComponentArray);
  404. }
  405. // We don't need to free pObjectInfo since the object is always a static
  406. // variable on the stack.
  407. }