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.

979 lines
21 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 2001
  5. //
  6. // File: cwebservice.cxx
  7. //
  8. // Contents: Contains methods for CIISWebService object
  9. //
  10. // History: 01-15-2001 BrentMid Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "iisext.hxx"
  14. #include <initguid.h>
  15. #include "iwamreg.h"
  16. #include "sitecreator.h"
  17. #include "secconlib.h"
  18. #pragma hdrstop
  19. // Class CIISWebService
  20. DEFINE_IPrivateDispatch_Implementation(CIISWebService)
  21. DEFINE_DELEGATING_IDispatch_Implementation(CIISWebService)
  22. DEFINE_CONTAINED_IADs_Implementation(CIISWebService)
  23. DEFINE_IADsExtension_Implementation(CIISWebService)
  24. CIISWebService::CIISWebService():
  25. _pUnkOuter(NULL),
  26. _pADs(NULL),
  27. _pszServerName(NULL),
  28. _pszMetaBasePath(NULL),
  29. _pAdminBase(NULL),
  30. _pDispMgr(NULL),
  31. _fDispInitialized(FALSE)
  32. {
  33. ENLIST_TRACKING(CIISWebService);
  34. }
  35. HRESULT
  36. CIISWebService::CreateWebService(
  37. IUnknown *pUnkOuter,
  38. REFIID riid,
  39. void **ppvObj
  40. )
  41. {
  42. CCredentials Credentials;
  43. CIISWebService FAR * pWebService = NULL;
  44. HRESULT hr = S_OK;
  45. BSTR bstrAdsPath = NULL;
  46. OBJECTINFO ObjectInfo;
  47. POBJECTINFO pObjectInfo = &ObjectInfo;
  48. CLexer * pLexer = NULL;
  49. LPWSTR pszIISPathName = NULL;
  50. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  51. hr = AllocateWebServiceObject(pUnkOuter, Credentials, &pWebService);
  52. BAIL_ON_FAILURE(hr);
  53. //
  54. // get ServerName and pszPath
  55. //
  56. hr = pWebService->_pADs->get_ADsPath(&bstrAdsPath);
  57. BAIL_ON_FAILURE(hr);
  58. pLexer = new CLexer();
  59. hr = pLexer->Initialize(bstrAdsPath);
  60. BAIL_ON_FAILURE(hr);
  61. //
  62. // Parse the pathname
  63. //
  64. hr = ADsObject(pLexer, pObjectInfo);
  65. BAIL_ON_FAILURE(hr);
  66. pszIISPathName = AllocADsStr(bstrAdsPath);
  67. if (!pszIISPathName) {
  68. hr = E_OUTOFMEMORY;
  69. BAIL_ON_FAILURE(hr);
  70. }
  71. *pszIISPathName = L'\0';
  72. hr = BuildIISPathFromADsPath(
  73. pObjectInfo,
  74. pszIISPathName
  75. );
  76. BAIL_ON_FAILURE(hr);
  77. hr = pWebService->InitializeWebServiceObject(
  78. pObjectInfo->TreeName,
  79. pszIISPathName );
  80. BAIL_ON_FAILURE(hr);
  81. //
  82. // pass non-delegating IUnknown back to the aggregator
  83. //
  84. *ppvObj = (INonDelegatingUnknown FAR *) pWebService;
  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 pWebService;
  110. RRETURN(hr);
  111. }
  112. CIISWebService::~CIISWebService( )
  113. {
  114. if (_pszServerName) {
  115. FreeADsStr(_pszServerName);
  116. }
  117. if (_pszMetaBasePath) {
  118. FreeADsStr(_pszMetaBasePath);
  119. }
  120. delete _pDispMgr;
  121. }
  122. STDMETHODIMP
  123. CIISWebService::QueryInterface(
  124. REFIID iid,
  125. LPVOID FAR* ppv
  126. )
  127. {
  128. HRESULT hr = S_OK;
  129. hr = _pUnkOuter->QueryInterface(iid,ppv);
  130. RRETURN(hr);
  131. }
  132. HRESULT
  133. CIISWebService::AllocateWebServiceObject(
  134. IUnknown *pUnkOuter,
  135. CCredentials& Credentials,
  136. CIISWebService ** ppWebService
  137. )
  138. {
  139. CIISWebService FAR * pWebService = NULL;
  140. IADs FAR * pADs = NULL;
  141. CAggregateeDispMgr FAR * pDispMgr = NULL;
  142. HRESULT hr = S_OK;
  143. pWebService = new CIISWebService();
  144. if (pWebService == NULL) {
  145. hr = E_OUTOFMEMORY;
  146. }
  147. BAIL_ON_FAILURE(hr);
  148. pDispMgr = new CAggregateeDispMgr;
  149. if (pDispMgr == NULL) {
  150. hr = E_OUTOFMEMORY;
  151. }
  152. BAIL_ON_FAILURE(hr);
  153. hr = pDispMgr->LoadTypeInfoEntry(
  154. LIBID_IISExt,
  155. IID_IISWebService,
  156. (IISWebService *)pWebService,
  157. DISPID_REGULAR
  158. );
  159. BAIL_ON_FAILURE(hr);
  160. //
  161. // Store the IADs Pointer, but again do NOT ref-count
  162. // this pointer - we keep the pointer around, but do
  163. // a release immediately.
  164. //
  165. hr = pUnkOuter->QueryInterface(IID_IADs, (void **)&pADs);
  166. pADs->Release();
  167. pWebService->_pADs = pADs;
  168. //
  169. // Store the pointer to the pUnkOuter object
  170. // AND DO NOT add ref this pointer
  171. //
  172. pWebService->_pUnkOuter = pUnkOuter;
  173. pWebService->_Credentials = Credentials;
  174. pWebService->_pDispMgr = pDispMgr;
  175. *ppWebService = pWebService;
  176. RRETURN(hr);
  177. error:
  178. delete pDispMgr;
  179. delete pWebService;
  180. RRETURN(hr);
  181. }
  182. HRESULT
  183. CIISWebService::InitializeWebServiceObject(
  184. LPWSTR pszServerName,
  185. LPWSTR pszPath
  186. )
  187. {
  188. HRESULT hr = S_OK;
  189. if (pszServerName) {
  190. _pszServerName = AllocADsStr(pszServerName);
  191. if (!_pszServerName) {
  192. hr = E_OUTOFMEMORY;
  193. BAIL_ON_FAILURE(hr);
  194. }
  195. }
  196. if (pszPath) {
  197. _pszMetaBasePath = AllocADsStr(pszPath);
  198. if (!_pszMetaBasePath) {
  199. hr = E_OUTOFMEMORY;
  200. BAIL_ON_FAILURE(hr);
  201. }
  202. }
  203. hr = InitServerInfo(pszServerName, &_pAdminBase);
  204. BAIL_ON_FAILURE(hr);
  205. error:
  206. RRETURN(hr);
  207. }
  208. STDMETHODIMP
  209. CIISWebService::ADSIInitializeDispatchManager(
  210. long dwExtensionId
  211. )
  212. {
  213. HRESULT hr = S_OK;
  214. if (_fDispInitialized) {
  215. RRETURN(E_FAIL);
  216. }
  217. hr = _pDispMgr->InitializeDispMgr(dwExtensionId);
  218. if (SUCCEEDED(hr)) {
  219. _fDispInitialized = TRUE;
  220. }
  221. RRETURN(hr);
  222. }
  223. STDMETHODIMP
  224. CIISWebService::ADSIInitializeObject(
  225. THIS_ BSTR lpszUserName,
  226. BSTR lpszPassword,
  227. long lnReserved
  228. )
  229. {
  230. CCredentials NewCredentials(lpszUserName, lpszPassword, lnReserved);
  231. _Credentials = NewCredentials;
  232. RRETURN(S_OK);
  233. }
  234. STDMETHODIMP
  235. CIISWebService::ADSIReleaseObject()
  236. {
  237. delete this;
  238. RRETURN(S_OK);
  239. }
  240. STDMETHODIMP
  241. CIISWebService::NonDelegatingQueryInterface(
  242. REFIID iid,
  243. LPVOID FAR* ppv
  244. )
  245. {
  246. ASSERT(ppv);
  247. if (IsEqualIID(iid, IID_IISWebService)) {
  248. *ppv = (IADsUser FAR *) this;
  249. } else if (IsEqualIID(iid, IID_IADsExtension)) {
  250. *ppv = (IADsExtension FAR *) this;
  251. } else if (IsEqualIID(iid, IID_IUnknown)) {
  252. //
  253. // probably not needed since our 3rd party extension does not stand
  254. // alone and provider does not ask for this, but to be safe
  255. //
  256. *ppv = (INonDelegatingUnknown FAR *) this;
  257. } else {
  258. *ppv = NULL;
  259. return E_NOINTERFACE;
  260. }
  261. //
  262. // Delegating AddRef to aggregator for IADsExtesnion and IISWebService.
  263. // AddRef on itself for IPrivateUnknown. (both tested.)
  264. //
  265. ((IUnknown *) (*ppv)) -> AddRef();
  266. return S_OK;
  267. }
  268. //
  269. // IADsExtension::Operate()
  270. //
  271. STDMETHODIMP
  272. CIISWebService::Operate(
  273. THIS_ DWORD dwCode,
  274. VARIANT varUserName,
  275. VARIANT varPassword,
  276. VARIANT varFlags
  277. )
  278. {
  279. RRETURN(E_NOTIMPL);
  280. }
  281. STDMETHODIMP
  282. CIISWebService::EnableApplication(
  283. BSTR bstrAppName
  284. )
  285. {
  286. HRESULT hr = S_OK;
  287. CSecConLib consoleHelper(_pAdminBase);
  288. hr = consoleHelper.EnableApplication(bstrAppName, _pszMetaBasePath);
  289. return hr;
  290. }
  291. STDMETHODIMP
  292. CIISWebService::RemoveApplication(
  293. BSTR bstrAppName
  294. )
  295. {
  296. HRESULT hr = S_OK;
  297. CSecConLib consoleHelper(_pAdminBase);
  298. hr = consoleHelper.RemoveApplication(bstrAppName, _pszMetaBasePath);
  299. return hr;
  300. }
  301. STDMETHODIMP
  302. CIISWebService::QueryGroupIDStatus(
  303. BSTR bstrGroupID,
  304. VARIANT FAR* pvBuffer
  305. )
  306. {
  307. HRESULT hr = S_OK;
  308. DWORD dwBufSize = 0;
  309. WCHAR* pBuffer = NULL;
  310. CSecConLib consoleHelper(_pAdminBase);
  311. hr = consoleHelper.QueryGroupIDStatus( _pszMetaBasePath, bstrGroupID, &pBuffer, &dwBufSize);
  312. BAIL_ON_FAILURE(hr);
  313. hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer);
  314. BAIL_ON_FAILURE(hr);
  315. error:
  316. if (pBuffer)
  317. {
  318. delete [] pBuffer;
  319. }
  320. return hr;
  321. }
  322. STDMETHODIMP
  323. CIISWebService::ListApplications(
  324. VARIANT FAR* pvBuffer
  325. )
  326. {
  327. HRESULT hr = S_OK;
  328. DWORD dwBufSize = 0;
  329. WCHAR* pBuffer = NULL;
  330. CSecConLib consoleHelper(_pAdminBase);
  331. hr = consoleHelper.ListApplications( _pszMetaBasePath, &pBuffer, &dwBufSize);
  332. BAIL_ON_FAILURE(hr);
  333. hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer);
  334. BAIL_ON_FAILURE(hr);
  335. error:
  336. if (pBuffer)
  337. {
  338. delete [] pBuffer;
  339. }
  340. return hr;
  341. }
  342. STDMETHODIMP
  343. CIISWebService::AddDependency(
  344. BSTR bstrApplication,
  345. BSTR bstrGroupID
  346. )
  347. {
  348. HRESULT hr = S_OK;
  349. CSecConLib consoleHelper(_pAdminBase);
  350. hr = consoleHelper.AddDependency(bstrApplication, bstrGroupID, _pszMetaBasePath);
  351. return hr;
  352. }
  353. STDMETHODIMP
  354. CIISWebService::RemoveDependency(
  355. BSTR bstrApplication,
  356. BSTR bstrGroupID
  357. )
  358. {
  359. HRESULT hr = S_OK;
  360. CSecConLib consoleHelper(_pAdminBase);
  361. hr = consoleHelper.RemoveDependency(bstrApplication, bstrGroupID, _pszMetaBasePath);
  362. return hr;
  363. }
  364. STDMETHODIMP
  365. CIISWebService::EnableWebServiceExtension(
  366. BSTR bstrExtension
  367. )
  368. {
  369. HRESULT hr = S_OK;
  370. CSecConLib consoleHelper(_pAdminBase);
  371. hr = consoleHelper.EnableWebServiceExtension(bstrExtension, _pszMetaBasePath);
  372. return hr;
  373. }
  374. STDMETHODIMP
  375. CIISWebService::DisableWebServiceExtension(
  376. BSTR bstrExtension
  377. )
  378. {
  379. HRESULT hr = S_OK;
  380. CSecConLib consoleHelper(_pAdminBase);
  381. hr = consoleHelper.DisableWebServiceExtension(bstrExtension, _pszMetaBasePath);
  382. return hr;
  383. }
  384. STDMETHODIMP
  385. CIISWebService::ListWebServiceExtensions(
  386. VARIANT FAR* pvBuffer
  387. )
  388. {
  389. HRESULT hr = S_OK;
  390. DWORD dwBufSize = 0;
  391. WCHAR* pBuffer = NULL;
  392. CSecConLib consoleHelper(_pAdminBase);
  393. hr = consoleHelper.ListWebServiceExtensions( _pszMetaBasePath, &pBuffer, &dwBufSize);
  394. BAIL_ON_FAILURE(hr);
  395. hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer);
  396. BAIL_ON_FAILURE(hr);
  397. error:
  398. if (pBuffer)
  399. {
  400. delete [] pBuffer;
  401. }
  402. return hr;
  403. }
  404. STDMETHODIMP
  405. CIISWebService::EnableExtensionFile(
  406. BSTR bstrExtensionFile
  407. )
  408. {
  409. HRESULT hr = S_OK;
  410. CSecConLib consoleHelper(_pAdminBase);
  411. hr = consoleHelper.EnableExtensionFile(bstrExtensionFile, _pszMetaBasePath);
  412. return hr;
  413. }
  414. STDMETHODIMP
  415. CIISWebService::DisableExtensionFile(
  416. BSTR bstrExtensionFile
  417. )
  418. {
  419. HRESULT hr = S_OK;
  420. CSecConLib consoleHelper(_pAdminBase);
  421. hr = consoleHelper.DisableExtensionFile(bstrExtensionFile, _pszMetaBasePath);
  422. return hr;
  423. }
  424. STDMETHODIMP
  425. CIISWebService::AddExtensionFile(
  426. BSTR bstrExtensionFile,
  427. VARIANT bAccess,
  428. BSTR bstrGroupID,
  429. VARIANT bCanDelete,
  430. BSTR bstrDescription
  431. )
  432. {
  433. HRESULT hr = S_OK;
  434. bool boolCanDelete = false;
  435. bool boolAccess = false;
  436. if (bCanDelete.vt == VT_BOOL)
  437. {
  438. if (bCanDelete.boolVal == VARIANT_TRUE)
  439. {
  440. boolCanDelete = true;
  441. }
  442. else
  443. {
  444. boolCanDelete = false;
  445. }
  446. }
  447. if (bAccess.vt == VT_BOOL)
  448. {
  449. if (bAccess.boolVal == VARIANT_TRUE)
  450. {
  451. boolAccess = true;
  452. }
  453. else
  454. {
  455. boolAccess = false;
  456. }
  457. }
  458. CSecConLib consoleHelper(_pAdminBase);
  459. hr = consoleHelper.AddExtensionFile(bstrExtensionFile, boolAccess, bstrGroupID,
  460. boolCanDelete, bstrDescription, _pszMetaBasePath);
  461. return hr;
  462. }
  463. STDMETHODIMP
  464. CIISWebService::DeleteExtensionFileRecord(
  465. BSTR bstrExtensionFile
  466. )
  467. {
  468. HRESULT hr = S_OK;
  469. CSecConLib consoleHelper(_pAdminBase);
  470. hr = consoleHelper.DeleteExtensionFileRecord(bstrExtensionFile, _pszMetaBasePath);
  471. return hr;
  472. }
  473. STDMETHODIMP
  474. CIISWebService::ListExtensionFiles(
  475. VARIANT FAR* pvBuffer
  476. )
  477. {
  478. HRESULT hr = S_OK;
  479. DWORD dwBufSize = 0;
  480. WCHAR* pBuffer = NULL;
  481. CSecConLib consoleHelper(_pAdminBase);
  482. hr = consoleHelper.ListExtensionFiles( _pszMetaBasePath, &pBuffer, &dwBufSize);
  483. BAIL_ON_FAILURE(hr);
  484. hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer);
  485. BAIL_ON_FAILURE(hr);
  486. error:
  487. if (pBuffer)
  488. {
  489. delete [] pBuffer;
  490. }
  491. return hr;
  492. }
  493. STDMETHODIMP
  494. CIISWebService::CreateNewSite(
  495. BSTR bstrServerComment,
  496. VARIANT *pvServerBindings,
  497. BSTR bstrRootVDirPath,
  498. VARIANT vServerID,
  499. VARIANT *pvActualID
  500. )
  501. {
  502. HRESULT hr = S_OK;
  503. DWORD dwSiteID = 0;
  504. DWORD * pdwSiteID = &dwSiteID;
  505. DWORD dwNewSiteID = 0;
  506. IIISApplicationAdmin * pAppAdmin = NULL;
  507. COSERVERINFO csiName;
  508. COSERVERINFO *pcsiParam = &csiName;
  509. IClassFactory * pcsfFactory = NULL;
  510. CSiteCreator SiteCreator(_pAdminBase);
  511. VARIANT vVar;
  512. WCHAR* wszServerBindings = NULL;
  513. WCHAR* pIndex = NULL;
  514. VARIANT * pVarArray = NULL;
  515. DWORD dwNumValues = 0;
  516. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  517. //
  518. // special case to handle "localhost" to work-around ole32 bug
  519. //
  520. if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) {
  521. pcsiParam->pwszName = NULL;
  522. }
  523. else {
  524. pcsiParam->pwszName = _pszServerName;
  525. }
  526. csiName.pAuthInfo = NULL;
  527. pcsiParam = &csiName;
  528. // call VariantChangeType here to convert to VT_I4 and plug into vServerID
  529. hr = VariantChangeType(&vServerID, &vServerID, 0, VT_I4);
  530. BAIL_ON_FAILURE(hr);
  531. if ((vServerID.vt == VT_I4) && (vServerID.lVal != 0)) {
  532. *pdwSiteID = vServerID.lVal;
  533. }
  534. else {
  535. pdwSiteID = NULL;
  536. }
  537. hr = CoGetClassObject(
  538. CLSID_WamAdmin,
  539. CLSCTX_SERVER,
  540. pcsiParam,
  541. IID_IClassFactory,
  542. (void**) &pcsfFactory
  543. );
  544. BAIL_ON_FAILURE(hr);
  545. hr = pcsfFactory->CreateInstance(
  546. NULL,
  547. IID_IIISApplicationAdmin,
  548. (void **) &pAppAdmin
  549. );
  550. BAIL_ON_FAILURE(hr);
  551. VariantInit(&vVar);
  552. hr = VariantCopyInd(&vVar, pvServerBindings);
  553. BAIL_ON_FAILURE(hr);
  554. if ( VT_DISPATCH == V_VT(&vVar) ) // JScript Array
  555. {
  556. // Output here is VT_BSTR, of format: "str_1,str_2,str_3, ... str_n\0"
  557. hr = VariantChangeType( &vVar, &vVar, 0, VT_BSTR );
  558. BAIL_ON_FAILURE(hr);
  559. wszServerBindings = new WCHAR [wcslen(vVar.bstrVal) + 2]; // 1 for NULL, 1 for extra NULL
  560. if (!wszServerBindings) {
  561. hr = E_OUTOFMEMORY;
  562. BAIL_ON_FAILURE(hr);
  563. }
  564. wcscpy(wszServerBindings, vVar.bstrVal);
  565. // change VT_BSTR to MULTISZ format: "str_1\0str_2\0str_3\0 ... str_n\0"
  566. pIndex = wszServerBindings;
  567. while ( *pIndex != 0 )
  568. {
  569. if ( *pIndex == L',' )
  570. {
  571. *pIndex = 0;
  572. }
  573. pIndex++;
  574. }
  575. *(++pIndex) = 0;
  576. }
  577. else if ( (VT_ARRAY | VT_VARIANT) == V_VT(&vVar) ) // VBS Array = SafeArray
  578. {
  579. // Allocates wszServerBindings and puts in MULTISZ format
  580. hr = ConvertArrayToMultiSZ( vVar, &wszServerBindings );
  581. BAIL_ON_FAILURE(hr);
  582. }
  583. else
  584. {
  585. hr = E_INVALIDARG;
  586. BAIL_ON_FAILURE(hr);
  587. }
  588. hr = SiteCreator.CreateNewSite2(SC_W3SVC, bstrServerComment, wszServerBindings,
  589. bstrRootVDirPath, pAppAdmin, &dwNewSiteID, pdwSiteID);
  590. BAIL_ON_FAILURE(hr);
  591. VariantInit( pvActualID );
  592. pvActualID->vt = VT_I4;
  593. pvActualID->lVal = dwNewSiteID;
  594. error:
  595. if (pcsfFactory) {
  596. pcsfFactory->Release();
  597. }
  598. if (pAppAdmin) {
  599. pAppAdmin->Release();
  600. }
  601. if (wszServerBindings) {
  602. delete [] wszServerBindings;
  603. }
  604. RRETURN(hr);
  605. }
  606. HRESULT
  607. CIISWebService::ConvertArrayToMultiSZ(
  608. VARIANT varSafeArray,
  609. WCHAR **pszServerBindings
  610. )
  611. {
  612. HRESULT hr = S_OK;
  613. DWORD dwSLBound = 0;
  614. DWORD dwSUBound = 0;
  615. DWORD i = 0;
  616. SAFEARRAY * pArray = NULL;
  617. DWORD dwLen = 0;
  618. DWORD dwNumVariants = 0;
  619. VARIANT * pVarArray = NULL;
  620. VARIANT pElem;
  621. WCHAR* wszServerBindings = NULL;
  622. if(!(V_ISARRAY(&varSafeArray)))
  623. RRETURN(E_FAIL);
  624. //
  625. // This handles by-ref and regular SafeArrays.
  626. //
  627. if (V_VT(&varSafeArray) & VT_BYREF)
  628. pArray = *(V_ARRAYREF(&varSafeArray));
  629. else
  630. pArray = V_ARRAY(&varSafeArray);
  631. //
  632. // Check that there is only one dimension in this array
  633. //
  634. if (pArray && pArray->cDims != 1) {
  635. hr = E_FAIL;
  636. BAIL_ON_FAILURE(hr);
  637. }
  638. //
  639. // Check that there is at least one element in this array
  640. //
  641. if (!pArray ||
  642. ( pArray->rgsabound[0].cElements == 0) ) {
  643. wszServerBindings = new WCHAR [2];
  644. wszServerBindings[0] = 0;
  645. wszServerBindings[1] = 1;
  646. }
  647. else {
  648. //
  649. // We know that this is a valid single dimension array
  650. //
  651. hr = SafeArrayGetLBound(pArray,
  652. 1,
  653. (long FAR *)&dwSLBound
  654. );
  655. BAIL_ON_FAILURE(hr);
  656. hr = SafeArrayGetUBound(pArray,
  657. 1,
  658. (long FAR *)&dwSUBound
  659. );
  660. BAIL_ON_FAILURE(hr);
  661. dwNumVariants = dwSUBound - dwSLBound + 1;
  662. dwLen = 0;
  663. pVarArray = (PVARIANT)AllocADsMem(
  664. sizeof(VARIANT)*dwNumVariants
  665. );
  666. if (!pVarArray) {
  667. hr = E_OUTOFMEMORY;
  668. BAIL_ON_FAILURE(hr);
  669. }
  670. for (i = dwSLBound; i <= dwSUBound; i++) {
  671. VariantInit(&pElem);
  672. hr = SafeArrayGetElement(pArray,
  673. (long FAR *)&i,
  674. &pElem
  675. );
  676. BAIL_ON_FAILURE(hr);
  677. hr = VariantChangeType(&pElem, &pElem, 0, VT_BSTR);
  678. BAIL_ON_FAILURE(hr);
  679. dwLen = dwLen + wcslen(pElem.bstrVal) + 1;
  680. pVarArray[i] = pElem;
  681. }
  682. wszServerBindings = new WCHAR [dwLen + 1];
  683. WCHAR * pServerBindings = wszServerBindings;
  684. for (i = dwSLBound; i <= dwSUBound; i++) {
  685. wcscpy(pServerBindings, pVarArray[i].bstrVal);
  686. while (*pServerBindings != 0) {
  687. pServerBindings++;
  688. }
  689. pServerBindings++;
  690. }
  691. *pServerBindings = 0;
  692. }
  693. *pszServerBindings = wszServerBindings;
  694. error:
  695. if (pVarArray) {
  696. FreeADsMem(pVarArray);
  697. }
  698. RRETURN(hr);
  699. }
  700. STDMETHODIMP
  701. CIISWebService::GetCurrentMode(
  702. VARIANT FAR* pvServerMode
  703. )
  704. {
  705. HRESULT hr = S_OK;
  706. DWORD dwServerMode = 0;
  707. COSERVERINFO csiName;
  708. COSERVERINFO *pcsiParam = &csiName;
  709. IClassFactory * pcsfFactory = NULL;
  710. IWamAdmin * pWamAdmin = NULL;
  711. IIISApplicationAdmin * pAppAdmin = NULL;
  712. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  713. //
  714. // special case to handle "localhost" to work-around ole32 bug
  715. //
  716. if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) {
  717. pcsiParam->pwszName = NULL;
  718. }
  719. else {
  720. pcsiParam->pwszName = _pszServerName;
  721. }
  722. csiName.pAuthInfo = NULL;
  723. pcsiParam = &csiName;
  724. hr = CoGetClassObject(
  725. CLSID_WamAdmin,
  726. CLSCTX_SERVER,
  727. pcsiParam,
  728. IID_IClassFactory,
  729. (void**) &pcsfFactory
  730. );
  731. BAIL_ON_FAILURE(hr);
  732. hr = pcsfFactory->CreateInstance(
  733. NULL,
  734. IID_IWamAdmin,
  735. (void **) &pWamAdmin
  736. );
  737. BAIL_ON_FAILURE(hr);
  738. // test here for 5.1 compat
  739. hr = pWamAdmin->QueryInterface(
  740. IID_IIISApplicationAdmin,
  741. (void **)&pAppAdmin
  742. );
  743. BAIL_ON_FAILURE(hr);
  744. // Call GetProcessMode - it's returning GetCurrentMode
  745. // after it checks to make sure the W3SVC is running.
  746. hr = pAppAdmin->GetProcessMode( &dwServerMode );
  747. BAIL_ON_FAILURE(hr);
  748. VariantInit( pvServerMode );
  749. pvServerMode->vt = VT_I4;
  750. pvServerMode->lVal = dwServerMode;
  751. error:
  752. if (pcsfFactory) {
  753. pcsfFactory->Release();
  754. }
  755. if (pWamAdmin) {
  756. pWamAdmin->Release();
  757. }
  758. if (pAppAdmin) {
  759. pAppAdmin->Release();
  760. }
  761. RRETURN(hr);
  762. }