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.

685 lines
14 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 2001
  5. //
  6. // File: capool.cxx
  7. //
  8. // Contents: Contains methods for CIISApplicationPool object
  9. //
  10. // History: 11-09-2000 BrentMid Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "iisext.hxx"
  14. #pragma hdrstop
  15. // Class CIISApplicationPool
  16. DEFINE_IPrivateDispatch_Implementation(CIISApplicationPool)
  17. DEFINE_DELEGATING_IDispatch_Implementation(CIISApplicationPool)
  18. DEFINE_CONTAINED_IADs_Implementation(CIISApplicationPool)
  19. DEFINE_IADsExtension_Implementation(CIISApplicationPool)
  20. CIISApplicationPool::CIISApplicationPool():
  21. _pUnkOuter(NULL),
  22. _pADs(NULL),
  23. _pszServerName(NULL),
  24. _pszPoolName(NULL),
  25. _pszMetaBasePath(NULL),
  26. _pAdminBase(NULL),
  27. _pDispMgr(NULL),
  28. _fDispInitialized(FALSE)
  29. {
  30. ENLIST_TRACKING(CIISApplicationPool);
  31. }
  32. HRESULT
  33. CIISApplicationPool::CreateApplicationPool(
  34. IUnknown *pUnkOuter,
  35. REFIID riid,
  36. void **ppvObj
  37. )
  38. {
  39. CCredentials Credentials;
  40. CIISApplicationPool FAR * pApplicationPool = NULL;
  41. HRESULT hr = S_OK;
  42. BSTR bstrAdsPath = NULL;
  43. OBJECTINFO ObjectInfo;
  44. POBJECTINFO pObjectInfo = &ObjectInfo;
  45. CLexer * pLexer = NULL;
  46. LPWSTR pszIISPathName = NULL;
  47. LPWSTR *pszPoolName;
  48. hr = AllocateApplicationPoolObject(pUnkOuter, Credentials, &pApplicationPool);
  49. BAIL_ON_FAILURE(hr);
  50. //
  51. // get ServerName and pszPath
  52. //
  53. hr = pApplicationPool->_pADs->get_ADsPath(&bstrAdsPath);
  54. BAIL_ON_FAILURE(hr);
  55. pLexer = new CLexer();
  56. hr = pLexer->Initialize(bstrAdsPath);
  57. BAIL_ON_FAILURE(hr);
  58. //
  59. // Parse the pathname
  60. //
  61. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  62. hr = ADsObject(pLexer, pObjectInfo);
  63. BAIL_ON_FAILURE(hr);
  64. pszIISPathName = AllocADsStr(bstrAdsPath);
  65. if (!pszIISPathName) {
  66. hr = E_OUTOFMEMORY;
  67. BAIL_ON_FAILURE(hr);
  68. }
  69. *pszIISPathName = L'\0';
  70. hr = BuildIISPathFromADsPath(
  71. pObjectInfo,
  72. pszIISPathName
  73. );
  74. BAIL_ON_FAILURE(hr);
  75. pszPoolName = &(ObjectInfo.ComponentArray[ObjectInfo.NumComponents-1].szComponent);
  76. hr = pApplicationPool->InitializeApplicationPoolObject(
  77. pObjectInfo->TreeName,
  78. pszIISPathName,
  79. *pszPoolName );
  80. BAIL_ON_FAILURE(hr);
  81. //
  82. // pass non-delegating IUnknown back to the aggregator
  83. //
  84. *ppvObj = (INonDelegatingUnknown FAR *) pApplicationPool;
  85. if (bstrAdsPath)
  86. {
  87. ADsFreeString(bstrAdsPath);
  88. }
  89. if (pLexer) {
  90. delete pLexer;
  91. }
  92. if (pszIISPathName ) {
  93. FreeADsStr( pszIISPathName );
  94. }
  95. FreeObjectInfo( &ObjectInfo );
  96. RRETURN(hr);
  97. error:
  98. if (bstrAdsPath) {
  99. ADsFreeString(bstrAdsPath);
  100. }
  101. if (pLexer) {
  102. delete pLexer;
  103. }
  104. if (pszIISPathName ) {
  105. FreeADsStr( pszIISPathName );
  106. }
  107. FreeObjectInfo( &ObjectInfo );
  108. *ppvObj = NULL;
  109. delete pApplicationPool;
  110. RRETURN(hr);
  111. }
  112. CIISApplicationPool::~CIISApplicationPool( )
  113. {
  114. if (_pszServerName) {
  115. FreeADsStr(_pszServerName);
  116. }
  117. if (_pszMetaBasePath) {
  118. FreeADsStr(_pszMetaBasePath);
  119. }
  120. if (_pszPoolName) {
  121. FreeADsStr(_pszPoolName);
  122. }
  123. delete _pDispMgr;
  124. }
  125. STDMETHODIMP
  126. CIISApplicationPool::QueryInterface(
  127. REFIID iid,
  128. LPVOID FAR* ppv
  129. )
  130. {
  131. HRESULT hr = S_OK;
  132. hr = _pUnkOuter->QueryInterface(iid,ppv);
  133. RRETURN(hr);
  134. }
  135. HRESULT
  136. CIISApplicationPool::AllocateApplicationPoolObject(
  137. IUnknown *pUnkOuter,
  138. CCredentials& Credentials,
  139. CIISApplicationPool ** ppApplicationPool
  140. )
  141. {
  142. CIISApplicationPool FAR * pApplicationPool = NULL;
  143. IADs FAR * pADs = NULL;
  144. CAggregateeDispMgr FAR * pDispMgr = NULL;
  145. HRESULT hr = S_OK;
  146. pApplicationPool = new CIISApplicationPool();
  147. if (pApplicationPool == NULL) {
  148. hr = E_OUTOFMEMORY;
  149. }
  150. BAIL_ON_FAILURE(hr);
  151. pDispMgr = new CAggregateeDispMgr;
  152. if (pDispMgr == NULL) {
  153. hr = E_OUTOFMEMORY;
  154. }
  155. BAIL_ON_FAILURE(hr);
  156. hr = pDispMgr->LoadTypeInfoEntry(
  157. LIBID_IISExt,
  158. IID_IISApplicationPool,
  159. (IISApplicationPool *)pApplicationPool,
  160. DISPID_REGULAR
  161. );
  162. BAIL_ON_FAILURE(hr);
  163. //
  164. // Store the IADs Pointer, but again do NOT ref-count
  165. // this pointer - we keep the pointer around, but do
  166. // a release immediately.
  167. //
  168. hr = pUnkOuter->QueryInterface(IID_IADs, (void **)&pADs);
  169. pADs->Release();
  170. pApplicationPool->_pADs = pADs;
  171. //
  172. // Store the pointer to the pUnkOuter object
  173. // AND DO NOT add ref this pointer
  174. //
  175. pApplicationPool->_pUnkOuter = pUnkOuter;
  176. pApplicationPool->_Credentials = Credentials;
  177. pApplicationPool->_pDispMgr = pDispMgr;
  178. *ppApplicationPool = pApplicationPool;
  179. RRETURN(hr);
  180. error:
  181. delete pDispMgr;
  182. delete pApplicationPool;
  183. RRETURN(hr);
  184. }
  185. HRESULT
  186. CIISApplicationPool::InitializeApplicationPoolObject(
  187. LPWSTR pszServerName,
  188. LPWSTR pszPath,
  189. LPWSTR pszPoolName
  190. )
  191. {
  192. HRESULT hr = S_OK;
  193. if (pszServerName) {
  194. _pszServerName = AllocADsStr(pszServerName);
  195. if (!_pszServerName) {
  196. hr = E_OUTOFMEMORY;
  197. BAIL_ON_FAILURE(hr);
  198. }
  199. }
  200. if (pszPath) {
  201. _pszMetaBasePath = AllocADsStr(pszPath);
  202. if (!_pszMetaBasePath) {
  203. hr = E_OUTOFMEMORY;
  204. BAIL_ON_FAILURE(hr);
  205. }
  206. }
  207. if (pszPoolName) {
  208. _pszPoolName = AllocADsStr(pszPoolName);
  209. if (!_pszPoolName) {
  210. hr = E_OUTOFMEMORY;
  211. BAIL_ON_FAILURE(hr);
  212. }
  213. }
  214. hr = InitServerInfo(pszServerName, &_pAdminBase);
  215. BAIL_ON_FAILURE(hr);
  216. error:
  217. RRETURN(hr);
  218. }
  219. STDMETHODIMP
  220. CIISApplicationPool::ADSIInitializeDispatchManager(
  221. long dwExtensionId
  222. )
  223. {
  224. HRESULT hr = S_OK;
  225. if (_fDispInitialized) {
  226. RRETURN(E_FAIL);
  227. }
  228. hr = _pDispMgr->InitializeDispMgr(dwExtensionId);
  229. if (SUCCEEDED(hr)) {
  230. _fDispInitialized = TRUE;
  231. }
  232. RRETURN(hr);
  233. }
  234. STDMETHODIMP
  235. CIISApplicationPool::ADSIInitializeObject(
  236. THIS_ BSTR lpszUserName,
  237. BSTR lpszPassword,
  238. long lnReserved
  239. )
  240. {
  241. CCredentials NewCredentials(lpszUserName, lpszPassword, lnReserved);
  242. _Credentials = NewCredentials;
  243. RRETURN(S_OK);
  244. }
  245. STDMETHODIMP
  246. CIISApplicationPool::ADSIReleaseObject()
  247. {
  248. delete this;
  249. RRETURN(S_OK);
  250. }
  251. STDMETHODIMP
  252. CIISApplicationPool::NonDelegatingQueryInterface(
  253. REFIID iid,
  254. LPVOID FAR* ppv
  255. )
  256. {
  257. ASSERT(ppv);
  258. if (IsEqualIID(iid, IID_IISApplicationPool)) {
  259. *ppv = (IADsUser FAR *) this;
  260. } else if (IsEqualIID(iid, IID_IADsExtension)) {
  261. *ppv = (IADsExtension FAR *) this;
  262. } else if (IsEqualIID(iid, IID_IUnknown)) {
  263. //
  264. // probably not needed since our 3rd party extension does not stand
  265. // alone and provider does not ask for this, but to be safe
  266. //
  267. *ppv = (INonDelegatingUnknown FAR *) this;
  268. } else {
  269. *ppv = NULL;
  270. return E_NOINTERFACE;
  271. }
  272. //
  273. // Delegating AddRef to aggregator for IADsExtesnion and IISApplicationPool.
  274. // AddRef on itself for IPrivateUnknown. (both tested.)
  275. //
  276. ((IUnknown *) (*ppv)) -> AddRef();
  277. return S_OK;
  278. }
  279. //
  280. // IADsExtension::Operate()
  281. //
  282. STDMETHODIMP
  283. CIISApplicationPool::Operate(
  284. THIS_ DWORD dwCode,
  285. VARIANT varUserName,
  286. VARIANT varPassword,
  287. VARIANT varFlags
  288. )
  289. {
  290. RRETURN(E_NOTIMPL);
  291. }
  292. HRESULT
  293. CIISApplicationPool::SetState(
  294. METADATA_HANDLE hObjHandle,
  295. DWORD dwState
  296. )
  297. {
  298. HRESULT hr = S_OK;
  299. DWORD dwBufferSize = sizeof(DWORD);
  300. METADATA_RECORD mdrMDData;
  301. LPBYTE pBuffer = (LPBYTE)&dwState;
  302. MD_SET_DATA_RECORD(&mdrMDData,
  303. MD_APPPOOL_COMMAND,
  304. METADATA_VOLATILE,
  305. IIS_MD_UT_SERVER,
  306. DWORD_METADATA,
  307. dwBufferSize,
  308. pBuffer);
  309. hr = _pAdminBase->SetData(
  310. hObjHandle,
  311. L"",
  312. &mdrMDData
  313. );
  314. RRETURN(hr);
  315. }
  316. STDMETHODIMP
  317. CIISApplicationPool::Start(THIS)
  318. {
  319. HRESULT hr = S_OK;
  320. METADATA_HANDLE hObjHandle = NULL;
  321. hr = OpenAdminBaseKey(
  322. _pszServerName,
  323. _pszMetaBasePath,
  324. METADATA_PERMISSION_WRITE,
  325. &_pAdminBase,
  326. &hObjHandle
  327. );
  328. BAIL_ON_FAILURE(hr);
  329. hr = SetState(hObjHandle, MD_APPPOOL_COMMAND_START);
  330. BAIL_ON_FAILURE(hr);
  331. error:
  332. if (hObjHandle) {
  333. CloseAdminBaseKey(_pAdminBase, hObjHandle);
  334. }
  335. RRETURN(hr);
  336. }
  337. STDMETHODIMP
  338. CIISApplicationPool::Stop(THIS)
  339. {
  340. HRESULT hr = S_OK;
  341. METADATA_HANDLE hObjHandle = NULL;
  342. hr = OpenAdminBaseKey(
  343. _pszServerName,
  344. _pszMetaBasePath,
  345. METADATA_PERMISSION_WRITE,
  346. &_pAdminBase,
  347. &hObjHandle
  348. );
  349. BAIL_ON_FAILURE(hr);
  350. hr = SetState(hObjHandle, MD_APPPOOL_COMMAND_STOP);
  351. BAIL_ON_FAILURE(hr);
  352. error:
  353. if (hObjHandle) {
  354. CloseAdminBaseKey(_pAdminBase, hObjHandle);
  355. }
  356. RRETURN(hr);
  357. }
  358. STDMETHODIMP
  359. CIISApplicationPool::Recycle(THIS)
  360. {
  361. HRESULT hr = S_OK;
  362. COSERVERINFO csiName;
  363. COSERVERINFO *pcsiParam = &csiName;
  364. IClassFactory * pcsfFactory = NULL;
  365. IIISApplicationAdmin * pAppAdmin = NULL;
  366. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  367. //
  368. // special case to handle "localhost" to work-around ole32 bug
  369. //
  370. if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) {
  371. pcsiParam->pwszName = NULL;
  372. }
  373. else {
  374. pcsiParam->pwszName = _pszServerName;
  375. }
  376. csiName.pAuthInfo = NULL;
  377. pcsiParam = &csiName;
  378. hr = CoGetClassObject(
  379. CLSID_WamAdmin,
  380. CLSCTX_SERVER,
  381. pcsiParam,
  382. IID_IClassFactory,
  383. (void**) &pcsfFactory
  384. );
  385. BAIL_ON_FAILURE(hr);
  386. hr = pcsfFactory->CreateInstance(
  387. NULL,
  388. IID_IIISApplicationAdmin,
  389. (void **) &pAppAdmin
  390. );
  391. BAIL_ON_FAILURE(hr);
  392. hr = pAppAdmin->RecycleApplicationPool( _pszPoolName );
  393. BAIL_ON_FAILURE(hr);
  394. error:
  395. if (pcsfFactory) {
  396. pcsfFactory->Release();
  397. }
  398. if (pAppAdmin) {
  399. pAppAdmin->Release();
  400. }
  401. RRETURN(hr);
  402. }
  403. STDMETHODIMP
  404. CIISApplicationPool::EnumApps(
  405. VARIANT FAR* pvBuffer
  406. )
  407. {
  408. HRESULT hr = S_OK;
  409. COSERVERINFO csiName;
  410. COSERVERINFO *pcsiParam = &csiName;
  411. IClassFactory * pcsfFactory = NULL;
  412. IIISApplicationAdmin * pAppAdmin = NULL;
  413. BSTR bstr = NULL;
  414. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  415. //
  416. // special case to handle "localhost" to work-around ole32 bug
  417. //
  418. if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) {
  419. pcsiParam->pwszName = NULL;
  420. }
  421. else {
  422. pcsiParam->pwszName = _pszServerName;
  423. }
  424. csiName.pAuthInfo = NULL;
  425. pcsiParam = &csiName;
  426. hr = CoGetClassObject(
  427. CLSID_WamAdmin,
  428. CLSCTX_SERVER,
  429. pcsiParam,
  430. IID_IClassFactory,
  431. (void**) &pcsfFactory
  432. );
  433. BAIL_ON_FAILURE(hr);
  434. hr = pcsfFactory->CreateInstance(
  435. NULL,
  436. IID_IIISApplicationAdmin,
  437. (void **) &pAppAdmin
  438. );
  439. BAIL_ON_FAILURE(hr);
  440. hr = pAppAdmin->EnumerateApplicationsInPool( _pszPoolName, &bstr );
  441. BAIL_ON_FAILURE(hr);
  442. hr = MakeVariantFromStringArray( (LPWSTR)bstr, pvBuffer);
  443. BAIL_ON_FAILURE(hr);
  444. error:
  445. if (pcsfFactory) {
  446. pcsfFactory->Release();
  447. }
  448. if (pAppAdmin) {
  449. pAppAdmin->Release();
  450. }
  451. RRETURN(hr);
  452. }
  453. HRESULT
  454. CIISApplicationPool::MakeVariantFromStringArray(
  455. LPWSTR pszList,
  456. VARIANT *pvVariant
  457. )
  458. {
  459. HRESULT hr = S_OK;
  460. SAFEARRAY *aList = NULL;
  461. SAFEARRAYBOUND aBound;
  462. LPWSTR pszStrList;
  463. WCHAR wchPath[MAX_PATH];
  464. if (pszList != NULL)
  465. {
  466. long nCount = 0;
  467. long i = 0;
  468. pszStrList = pszList;
  469. if (*pszStrList == L'\0') {
  470. nCount = 1;
  471. pszStrList++;
  472. }
  473. while (*pszStrList != L'\0') {
  474. while (*pszStrList != L'\0') {
  475. pszStrList++;
  476. }
  477. nCount++;
  478. pszStrList++;
  479. }
  480. aBound.lLbound = 0;
  481. aBound.cElements = nCount;
  482. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  483. if ( aList == NULL )
  484. {
  485. hr = E_OUTOFMEMORY;
  486. BAIL_ON_FAILURE(hr);
  487. }
  488. pszStrList = pszList;
  489. for (i = 0; i < nCount; i++ )
  490. {
  491. VARIANT v;
  492. VariantInit(&v);
  493. V_VT(&v) = VT_BSTR;
  494. hr = ADsAllocString( pszStrList, &(V_BSTR(&v)));
  495. BAIL_ON_FAILURE(hr);
  496. hr = SafeArrayPutElement( aList, &i, &v );
  497. VariantClear(&v);
  498. BAIL_ON_FAILURE(hr);
  499. pszStrList += wcslen(pszStrList) + 1;
  500. }
  501. VariantInit( pvVariant );
  502. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  503. V_ARRAY(pvVariant) = aList;
  504. }
  505. else
  506. {
  507. aBound.lLbound = 0;
  508. aBound.cElements = 0;
  509. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  510. if ( aList == NULL )
  511. {
  512. hr = E_OUTOFMEMORY;
  513. BAIL_ON_FAILURE(hr);
  514. }
  515. VariantInit( pvVariant );
  516. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  517. V_ARRAY(pvVariant) = aList;
  518. }
  519. return S_OK;
  520. error:
  521. if ( aList )
  522. SafeArrayDestroy( aList );
  523. return hr;
  524. }