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.

677 lines
14 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. appladmin.cpp
  5. Abstract:
  6. This file contains implementation of:
  7. CAppPoolMethod, CWebAppMethod
  8. Author:
  9. ???
  10. Revision History:
  11. Mohit Srivastava 21-Jan-01
  12. --*/
  13. #include "iisprov.h"
  14. #include "appladmin.h"
  15. #include "MultiSzHelper.h"
  16. #include "iiswmimsg.h"
  17. //
  18. // CApplAdmin
  19. //
  20. CAppPoolMethod::CAppPoolMethod()
  21. {
  22. m_pIABase = (IMSAdminBase2*)metabase;
  23. HRESULT hr = CoCreateInstance(
  24. CLSID_WamAdmin,
  25. NULL,
  26. CLSCTX_ALL,
  27. IID_IIISApplicationAdmin,
  28. (void**)&m_spAppAdmin);
  29. THROW_ON_ERROR(hr);
  30. }
  31. CAppPoolMethod::~CAppPoolMethod()
  32. {
  33. }
  34. void CAppPoolMethod::GetCurrentMode(
  35. VARIANT* io_pvtServerMode)
  36. /*++
  37. Synopsis:
  38. This method, unlike the others, is actually on the IIsWebService node.
  39. Arguments: [io_pvtServerMode] -
  40. --*/
  41. {
  42. DBG_ASSERT(io_pvtServerMode != NULL);
  43. DWORD dwServerMode = 0;
  44. VariantInit(io_pvtServerMode);
  45. HRESULT hr = m_spAppAdmin->GetProcessMode(&dwServerMode);
  46. THROW_ON_ERROR(hr);
  47. io_pvtServerMode->vt = VT_I4;
  48. io_pvtServerMode->lVal = dwServerMode;
  49. }
  50. void CAppPoolMethod::Start(
  51. LPCWSTR i_wszMbPath)
  52. {
  53. DBG_ASSERT(i_wszMbPath != NULL);
  54. m_wszPath = i_wszMbPath;
  55. HRESULT hr = ExecMethod(MD_APPPOOL_COMMAND_START);
  56. THROW_ON_ERROR(hr);
  57. }
  58. void CAppPoolMethod::Stop(
  59. LPCWSTR i_wszMbPath)
  60. {
  61. DBG_ASSERT(i_wszMbPath != NULL);
  62. m_wszPath = i_wszMbPath;
  63. HRESULT hr = ExecMethod(MD_APPPOOL_COMMAND_STOP);
  64. THROW_ON_ERROR(hr);
  65. }
  66. void CAppPoolMethod::RecycleAppPool(
  67. LPCWSTR i_wszMbPath)
  68. {
  69. DBG_ASSERT(i_wszMbPath != NULL);
  70. LPCWSTR wszAppPool = NULL;
  71. GetPtrToAppPool(i_wszMbPath, &wszAppPool);
  72. HRESULT hr = m_spAppAdmin->RecycleApplicationPool(wszAppPool);
  73. THROW_ON_ERROR(hr);
  74. }
  75. void CAppPoolMethod::EnumAppsInPool(
  76. LPCWSTR i_wszMbPath,
  77. VARIANT* io_pvtApps)
  78. /*++
  79. Synopsis:
  80. Arguments: [i_wszMbPath] -
  81. [io_pvtApps] - Will be an array of strings
  82. --*/
  83. {
  84. DBG_ASSERT(i_wszMbPath != NULL);
  85. DBG_ASSERT(io_pvtApps != NULL);
  86. CComBSTR sbstrApps = NULL;
  87. VariantInit(io_pvtApps);
  88. LPCWSTR wszAppPool = NULL;
  89. GetPtrToAppPool(i_wszMbPath, &wszAppPool);
  90. HRESULT hr = m_spAppAdmin->EnumerateApplicationsInPool(
  91. wszAppPool,
  92. &sbstrApps);
  93. THROW_ON_ERROR(hr);
  94. CMultiSz MultiSz;
  95. hr = MultiSz.ToWmiForm(
  96. sbstrApps,
  97. io_pvtApps);
  98. THROW_ON_ERROR(hr);
  99. }
  100. void CAppPoolMethod::DeleteAppPool(
  101. LPCWSTR i_wszMbPath)
  102. {
  103. DBG_ASSERT(i_wszMbPath);
  104. LPCWSTR wszAppPool = NULL;
  105. GetPtrToAppPool(i_wszMbPath, &wszAppPool);
  106. HRESULT hr = m_spAppAdmin->DeleteApplicationPool(wszAppPool);
  107. THROW_ON_ERROR(hr);
  108. }
  109. //
  110. // CAppPoolMethod - private methods
  111. //
  112. void CAppPoolMethod::GetPtrToAppPool(
  113. LPCWSTR i_wszMbPath,
  114. LPCWSTR* o_pwszAppPool)
  115. /*++
  116. Synopsis:
  117. Arguments: [i_wszMbPath] -
  118. [o_wszAppPool] - This is a ptr to i_wszMbPath. Does not need to be
  119. freed by caller.
  120. --*/
  121. {
  122. DBG_ASSERT(i_wszMbPath);
  123. DBG_ASSERT(o_pwszAppPool);
  124. DBG_ASSERT(*o_pwszAppPool == NULL);
  125. DBG_ASSERT(i_wszMbPath[0] == L'/');
  126. DBG_ASSERT(i_wszMbPath[1] != L'\0');
  127. LPWSTR wszAppPool = (LPWSTR)wcsrchr(i_wszMbPath, L'/');
  128. if (NULL == wszAppPool)
  129. {
  130. CIIsProvException e;
  131. e.SetMC(WBEM_E_FAILED, IISWMI_INVALID_APPPOOL_CONTAINER, i_wszMbPath);
  132. throw e;
  133. }
  134. *wszAppPool = L'\0';
  135. if(_wcsicmp(i_wszMbPath, L"/LM/w3svc/AppPools") != 0)
  136. {
  137. *wszAppPool = L'/';
  138. CIIsProvException e;
  139. e.SetMC(WBEM_E_FAILED, IISWMI_INVALID_APPPOOL_CONTAINER, i_wszMbPath);
  140. throw e;
  141. }
  142. *wszAppPool = L'/';
  143. //
  144. // Set out params on success
  145. //
  146. *o_pwszAppPool = wszAppPool + 1;
  147. }
  148. HRESULT
  149. CAppPoolMethod::IISGetAppPoolState(
  150. METADATA_HANDLE hObjHandle,
  151. PDWORD pdwState
  152. )
  153. {
  154. HRESULT hr = S_OK;
  155. DWORD dwBufferSize = sizeof(DWORD);
  156. METADATA_RECORD mdrMDData;
  157. LPBYTE pBuffer = (LPBYTE)pdwState;
  158. MD_SET_DATA_RECORD(&mdrMDData,
  159. MD_APPPOOL_STATE, // server state
  160. METADATA_NO_ATTRIBUTES,
  161. IIS_MD_UT_SERVER,
  162. DWORD_METADATA,
  163. dwBufferSize,
  164. pBuffer);
  165. hr = m_pIABase->GetData(
  166. hObjHandle,
  167. m_wszPath,
  168. &mdrMDData,
  169. &dwBufferSize
  170. );
  171. if( hr == MD_ERROR_DATA_NOT_FOUND )
  172. {
  173. //
  174. // If the data is not there, but the path exists, then the
  175. // most likely cause is that the app pool is not running and
  176. // this object was just created.
  177. //
  178. // Since MD_APPPOOL_STATE would be set as stopped if the
  179. // app pool were running when the key is added, we'll just
  180. // say that it's stopped.
  181. //
  182. *pdwState = MD_APPPOOL_STATE_STOPPED;
  183. hr = S_FALSE;
  184. }
  185. else
  186. {
  187. if(FAILED(hr))
  188. {
  189. goto error;
  190. }
  191. }
  192. error:
  193. return(hr);
  194. }
  195. HRESULT
  196. CAppPoolMethod::IISGetAppPoolWin32Error(
  197. METADATA_HANDLE hObjHandle,
  198. HRESULT* phrError)
  199. {
  200. DBG_ASSERT(phrError != NULL);
  201. long lWin32Error = 0;
  202. DWORD dwLen;
  203. METADATA_RECORD mr = {
  204. MD_WIN32_ERROR,
  205. METADATA_NO_ATTRIBUTES,
  206. IIS_MD_UT_SERVER,
  207. DWORD_METADATA,
  208. sizeof(DWORD),
  209. (unsigned char*)&lWin32Error,
  210. 0
  211. };
  212. HRESULT hr = m_pIABase->GetData(
  213. hObjHandle,
  214. m_wszPath,
  215. &mr,
  216. &dwLen);
  217. if(hr == MD_ERROR_DATA_NOT_FOUND)
  218. {
  219. hr = S_FALSE;
  220. }
  221. //
  222. // Set out param
  223. //
  224. *phrError = HRESULT_FROM_WIN32(lWin32Error);
  225. return hr;
  226. }
  227. HRESULT CAppPoolMethod::ExecMethod(
  228. DWORD dwControl)
  229. {
  230. DWORD dwTargetState;
  231. DWORD dwState = 0;
  232. DWORD dwSleepTotal = 0L;
  233. HRESULT hr = S_OK;
  234. HRESULT hrMbNode = S_OK;
  235. METADATA_HANDLE hKey = 0;
  236. switch(dwControl)
  237. {
  238. case MD_APPPOOL_COMMAND_STOP:
  239. dwTargetState = MD_APPPOOL_STATE_STOPPED;
  240. break;
  241. case MD_APPPOOL_COMMAND_START:
  242. dwTargetState = MD_APPPOOL_STATE_STARTED;
  243. break;
  244. default:
  245. hr = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  246. if(FAILED(hr))
  247. {
  248. goto error;
  249. }
  250. }
  251. hr = IISGetAppPoolState(METADATA_MASTER_ROOT_HANDLE, &dwState);
  252. if(FAILED(hr))
  253. {
  254. goto error;
  255. }
  256. if (dwState == dwTargetState)
  257. {
  258. return (hr);
  259. }
  260. //
  261. // Write the command to the metabase
  262. //
  263. hr = m_pIABase->OpenKey(
  264. METADATA_MASTER_ROOT_HANDLE,
  265. m_wszPath,
  266. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  267. DEFAULT_TIMEOUT_VALUE, // 30 seconds
  268. &hKey);
  269. if(FAILED(hr))
  270. {
  271. goto error;
  272. }
  273. hr = IISSetDword(hKey, MD_WIN32_ERROR, 0);
  274. if(FAILED(hr))
  275. {
  276. m_pIABase->CloseKey(hKey);
  277. goto error;
  278. }
  279. hr = IISSetDword(hKey, MD_APPPOOL_COMMAND, dwControl);
  280. if(FAILED(hr))
  281. {
  282. m_pIABase->CloseKey(hKey);
  283. goto error;
  284. }
  285. m_pIABase->CloseKey(hKey);
  286. while (dwSleepTotal < MAX_SLEEP_INST)
  287. {
  288. hr = IISGetAppPoolState(METADATA_MASTER_ROOT_HANDLE, &dwState);
  289. if(FAILED(hr))
  290. {
  291. goto error;
  292. }
  293. hrMbNode = 0;
  294. hr = IISGetAppPoolWin32Error(METADATA_MASTER_ROOT_HANDLE, &hrMbNode);
  295. if(FAILED(hr))
  296. {
  297. goto error;
  298. }
  299. //
  300. // Done one way or another
  301. //
  302. if (dwState == dwTargetState)
  303. {
  304. break;
  305. }
  306. //
  307. // If we haven't check the Win32 Error from the metabase
  308. //
  309. if(FAILED(hrMbNode))
  310. {
  311. hr = hrMbNode;
  312. goto error;
  313. }
  314. //
  315. // Still pending...
  316. //
  317. ::Sleep(SLEEP_INTERVAL);
  318. dwSleepTotal += SLEEP_INTERVAL;
  319. }
  320. if (dwSleepTotal >= MAX_SLEEP_INST)
  321. {
  322. //
  323. // Timed out. If there is a real error in the metabase
  324. // use it, otherwise use a generic timeout error
  325. //
  326. hr = HRESULT_FROM_WIN32(ERROR_SERVICE_REQUEST_TIMEOUT);
  327. }
  328. error :
  329. return (hr);
  330. }
  331. HRESULT
  332. CAppPoolMethod::IISSetDword(
  333. METADATA_HANDLE hKey,
  334. DWORD dwPropId,
  335. DWORD dwValue
  336. )
  337. {
  338. HRESULT hr = S_OK;
  339. DWORD dwBufferSize = sizeof(DWORD);
  340. METADATA_RECORD mdrMDData;
  341. LPBYTE pBuffer = (LPBYTE)&dwValue;
  342. if (MD_WIN32_ERROR == dwPropId) {
  343. MD_SET_DATA_RECORD(&mdrMDData,
  344. dwPropId,
  345. METADATA_VOLATILE,
  346. IIS_MD_UT_SERVER,
  347. DWORD_METADATA,
  348. dwBufferSize,
  349. pBuffer);
  350. }
  351. else {
  352. MD_SET_DATA_RECORD(&mdrMDData,
  353. dwPropId,
  354. METADATA_NO_ATTRIBUTES,
  355. IIS_MD_UT_SERVER,
  356. DWORD_METADATA,
  357. dwBufferSize,
  358. pBuffer);
  359. }
  360. hr = m_pIABase->SetData(
  361. hKey,
  362. L"",
  363. &mdrMDData
  364. );
  365. if(FAILED(hr))
  366. {
  367. goto error;
  368. }
  369. error:
  370. return(hr);
  371. }
  372. //
  373. // CWebAppMethod
  374. //
  375. CWebAppMethod::CWebAppMethod()
  376. {
  377. HRESULT hr = CoCreateInstance(
  378. CLSID_WamAdmin,
  379. NULL,
  380. CLSCTX_ALL,
  381. IID_IIISApplicationAdmin,
  382. (void**)&m_pAppAdmin
  383. );
  384. hr = CoCreateInstance(
  385. CLSID_WamAdmin,
  386. NULL,
  387. CLSCTX_ALL,
  388. IID_IWamAdmin2,
  389. (void**)&m_pWamAdmin2
  390. );
  391. THROW_ON_ERROR(hr);
  392. }
  393. CWebAppMethod::~CWebAppMethod()
  394. {
  395. if(m_pAppAdmin)
  396. m_pAppAdmin->Release();
  397. if(m_pWamAdmin2)
  398. m_pWamAdmin2->Release();
  399. }
  400. HRESULT CWebAppMethod::AppCreate(
  401. LPCWSTR szMetaBasePath,
  402. bool bInProcFlag
  403. )
  404. {
  405. HRESULT hr;
  406. LPWSTR szActualName = NULL;
  407. BOOL bActualCreation = FALSE;
  408. hr = m_pAppAdmin->CreateApplication(
  409. szMetaBasePath,
  410. bInProcFlag ? 0 : 1, // 0 for InProc, 1 for Out of Proc
  411. szActualName,
  412. bActualCreation // Don't create - DefaultAppPool should already be there
  413. );
  414. return hr;
  415. }
  416. HRESULT CWebAppMethod::AppCreate2(
  417. LPCWSTR szMetaBasePath,
  418. long lAppMode
  419. )
  420. {
  421. HRESULT hr;
  422. LPWSTR szActualName = NULL;
  423. BOOL bActualCreation = FALSE;
  424. hr = m_pAppAdmin->CreateApplication(
  425. szMetaBasePath,
  426. lAppMode,
  427. szActualName,
  428. bActualCreation // Don't create - DefaultAppPool should already be there
  429. );
  430. return hr;
  431. }
  432. HRESULT CWebAppMethod::AppCreate3(
  433. LPCWSTR szMetaBasePath,
  434. long lAppMode,
  435. LPCWSTR szAppPoolName,
  436. bool bCreatePool
  437. )
  438. {
  439. HRESULT hr;
  440. LPWSTR szActualName;
  441. BOOL bActualCreation = FALSE;
  442. if (szAppPoolName) {
  443. szActualName = (LPWSTR)szAppPoolName;
  444. }
  445. else {
  446. szActualName = NULL;
  447. }
  448. if (bCreatePool != true) {
  449. bActualCreation = FALSE;
  450. }
  451. else {
  452. bActualCreation = TRUE;
  453. }
  454. hr = m_pAppAdmin->CreateApplication(
  455. szMetaBasePath,
  456. lAppMode,
  457. szActualName,
  458. bActualCreation // Don't create - DefaultAppPool should already be there
  459. );
  460. return hr;
  461. }
  462. HRESULT CWebAppMethod::AppDelete(
  463. LPCWSTR szMetaBasePath,
  464. bool bRecursive
  465. )
  466. {
  467. HRESULT hr;
  468. hr = m_pAppAdmin->DeleteApplication(
  469. szMetaBasePath,
  470. bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
  471. );
  472. return hr;
  473. }
  474. HRESULT CWebAppMethod::AppUnLoad(
  475. LPCWSTR szMetaBasePath,
  476. bool bRecursive
  477. )
  478. {
  479. HRESULT hr;
  480. hr = m_pWamAdmin2->AppUnLoad(
  481. szMetaBasePath,
  482. bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
  483. );
  484. return hr;
  485. }
  486. HRESULT CWebAppMethod::AppDisable(
  487. LPCWSTR szMetaBasePath,
  488. bool bRecursive
  489. )
  490. {
  491. HRESULT hr;
  492. hr = m_pWamAdmin2->AppDeleteRecoverable(
  493. szMetaBasePath,
  494. bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
  495. );
  496. return hr;
  497. }
  498. HRESULT CWebAppMethod::AppEnable(
  499. LPCWSTR szMetaBasePath,
  500. bool bRecursive
  501. )
  502. {
  503. HRESULT hr;
  504. hr = m_pWamAdmin2->AppRecover(
  505. szMetaBasePath,
  506. bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
  507. );
  508. return hr;
  509. }
  510. HRESULT CWebAppMethod::AppGetStatus(
  511. LPCWSTR szMetaBasePath,
  512. DWORD* pdwStatus
  513. )
  514. {
  515. HRESULT hr;
  516. hr = m_pWamAdmin2->AppGetStatus(
  517. szMetaBasePath,
  518. pdwStatus);
  519. return hr;
  520. }
  521. HRESULT CWebAppMethod::AspAppRestart(
  522. LPCWSTR a_szMetaBasePath
  523. )
  524. {
  525. HRESULT hr = S_OK;
  526. DWORD dwState = 0;
  527. METADATA_HANDLE t_hKey = NULL;
  528. CMetabase t_mb;
  529. // open key
  530. t_hKey = t_mb.OpenKey(a_szMetaBasePath, true);
  531. // check app
  532. hr = t_mb.WebAppCheck(t_hKey);
  533. THROW_ON_ERROR(hr);
  534. // get state
  535. hr = t_mb.WebAppGetStatus(t_hKey, &dwState);
  536. THROW_ON_ERROR(hr);
  537. // change state value
  538. dwState = dwState ? 0 : 1;
  539. hr = t_mb.WebAppSetStatus(t_hKey, dwState);
  540. THROW_ON_ERROR(hr);
  541. // re-set back state value
  542. dwState = dwState ? 0 : 1;
  543. hr = t_mb.WebAppSetStatus(t_hKey, dwState);
  544. THROW_ON_ERROR(hr);
  545. t_mb.CloseKey(t_hKey);
  546. return hr;
  547. }