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.

2200 lines
48 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 "iis.hxx"
  14. extern SERVER_CACHE * g_pServerCache;
  15. extern WIN32_CRITSEC * g_pGlobalLock;
  16. #pragma hdrstop
  17. FILTERS Filters[] = {
  18. {L"user", IIS_USER_ID},
  19. {L"group", IIS_GROUP_ID},
  20. {L"queue", IIS_PRINTER_ID},
  21. {L"domain", IIS_DOMAIN_ID},
  22. {L"computer", IIS_COMPUTER_ID},
  23. {L"service", IIS_SERVICE_ID},
  24. {L"fileservice", IIS_FILESERVICE_ID},
  25. {L"fileshare", IIS_FILESHARE_ID},
  26. {L"class", IIS_CLASS_ID},
  27. {L"functionalset", IIS_FUNCTIONALSET_ID},
  28. {L"syntax", IIS_SYNTAX_ID},
  29. {L"property", IIS_PROPERTY_ID},
  30. {L"tree", IIS_TREE_ID},
  31. {L"Organizational Unit", IIS_OU_ID},
  32. {L"Organization", IIS_O_ID},
  33. {L"Locality", IIS_LOCALITY_ID}
  34. };
  35. #define MAX_FILTERS (sizeof(Filters)/sizeof(FILTERS))
  36. #define DEFAULT_TIMEOUT_VALUE 30000
  37. PFILTERS gpFilters = Filters;
  38. DWORD gdwMaxFilters = MAX_FILTERS;
  39. extern WCHAR * szProviderName;
  40. //+------------------------------------------------------------------------
  41. //
  42. // Class: Common
  43. //
  44. // Purpose: Contains Winnt routines and properties that are common to
  45. // all Winnt objects. Winnt objects get the routines and
  46. // properties through C++ inheritance.
  47. //
  48. //-------------------------------------------------------------------------
  49. HRESULT
  50. BuildADsPath(
  51. BSTR Parent,
  52. BSTR Name,
  53. BSTR *pADsPath
  54. )
  55. {
  56. LPWSTR lpADsPath = NULL;
  57. WCHAR ProviderName[MAX_PATH];
  58. HRESULT hr = S_OK;
  59. DWORD dwLen = 0;
  60. //
  61. // We will assert if bad parameters are passed to us.
  62. // This is because this should never be the case. This
  63. // is an internal call
  64. //
  65. ADsAssert(Parent && Name);
  66. ADsAssert(pADsPath);
  67. //
  68. // Special case the Namespace object; if
  69. // the parent is L"ADs:", then Name = ADsPath
  70. //
  71. if (!_wcsicmp(Parent, L"ADs:")) {
  72. RRETURN(ADsAllocString( Name, pADsPath));
  73. }
  74. //
  75. // Allocate the right side buffer
  76. // 2 for // + a buffer of MAX_PATH
  77. //
  78. dwLen = (DWORD)(wcslen(Parent) + wcslen(Name)) + 2 + MAX_PATH;
  79. lpADsPath = (LPWSTR)AllocADsMem(dwLen*sizeof(WCHAR));
  80. if (!lpADsPath) {
  81. RRETURN(E_OUTOFMEMORY);
  82. }
  83. //
  84. // The rest of the cases we expect valid data,
  85. // Path, Parent and Name are read-only, the end-user
  86. // cannot modify this data
  87. //
  88. //
  89. // For the first object, the domain object we do not add
  90. // the first backslash; so we examine that the parent is
  91. // L"WinNT:" and skip the slash otherwise we start with
  92. // the slash
  93. //
  94. wsprintf(ProviderName, L"%s:", szProviderName);
  95. wcscpy(lpADsPath, Parent);
  96. if (_wcsicmp(lpADsPath, ProviderName)) {
  97. wcscat(lpADsPath, L"/");
  98. }else {
  99. wcscat(lpADsPath, L"//");
  100. }
  101. wcscat(lpADsPath, Name);
  102. hr = ADsAllocString( lpADsPath, pADsPath);
  103. if (lpADsPath) {
  104. FreeADsMem(lpADsPath);
  105. }
  106. RRETURN(hr);
  107. }
  108. HRESULT
  109. BuildSchemaPath(
  110. BSTR bstrADsPath,
  111. BSTR bstrClass,
  112. BSTR *pSchemaPath
  113. )
  114. {
  115. WCHAR ADsSchema[MAX_PATH];
  116. OBJECTINFO ObjectInfo;
  117. POBJECTINFO pObjectInfo = &ObjectInfo;
  118. CLexer Lexer(bstrADsPath);
  119. HRESULT hr = S_OK;
  120. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  121. wcscpy(ADsSchema, L"");
  122. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  123. if (bstrClass && *bstrClass) {
  124. hr = ADsObject(&Lexer, pObjectInfo);
  125. BAIL_ON_FAILURE(hr);
  126. if (pObjectInfo->TreeName) {
  127. wsprintf(ADsSchema,L"%s://",pObjectInfo->ProviderName);
  128. wcscat(ADsSchema, pObjectInfo->TreeName);
  129. wcscat(ADsSchema,L"/schema/");
  130. wcscat(ADsSchema, bstrClass);
  131. }
  132. }
  133. hr = ADsAllocString( ADsSchema, pSchemaPath);
  134. error:
  135. if (pObjectInfo) {
  136. FreeObjectInfo( pObjectInfo );
  137. }
  138. RRETURN(hr);
  139. }
  140. HRESULT
  141. BuildADsGuid(
  142. REFCLSID clsid,
  143. BSTR *pADsClass
  144. )
  145. {
  146. WCHAR ADsClass[MAX_PATH];
  147. StringFromGUID2(clsid, ADsClass, 256);
  148. RRETURN(ADsAllocString( ADsClass, pADsClass));
  149. }
  150. HRESULT
  151. ValidateOutParameter(
  152. BSTR * retval
  153. )
  154. {
  155. if (!retval) {
  156. RRETURN(E_ADS_BAD_PARAMETER);
  157. }
  158. RRETURN(S_OK);
  159. }
  160. HRESULT
  161. OpenAdminBaseKey(
  162. IN CCredentials& Credentials,
  163. IN LPWSTR pszServerName,
  164. IN LPWSTR pszPathName,
  165. IN DWORD dwAccessType,
  166. IN OUT IMSAdminBase **ppAdminBase,
  167. OUT METADATA_HANDLE *phHandle
  168. )
  169. {
  170. HRESULT hr;
  171. IMSAdminBase *pAdminBase = *ppAdminBase;
  172. METADATA_HANDLE RootHandle = NULL;
  173. DWORD dwThreadId;
  174. hr = pAdminBase->OpenKey(
  175. METADATA_MASTER_ROOT_HANDLE,
  176. pszPathName,
  177. dwAccessType,
  178. DEFAULT_TIMEOUT_VALUE,
  179. &RootHandle
  180. );
  181. if (FAILED(hr)) {
  182. if ((HRESULT_CODE(hr) == RPC_S_SERVER_UNAVAILABLE) ||
  183. ((HRESULT_CODE(hr) >= RPC_S_NO_CALL_ACTIVE) &&
  184. (HRESULT_CODE(hr) <= RPC_S_CALL_FAILED_DNE)) ||
  185. hr == RPC_E_DISCONNECTED) {
  186. SERVER_CACHE_ITEM * item = NULL;
  187. IMSAdminBase * pOldAdminBase = pAdminBase;
  188. //
  189. // RPC error, try to recover connection
  190. //
  191. hr = InitAdminBase(Credentials, pszServerName, &pAdminBase);
  192. BAIL_ON_FAILURE(hr);
  193. *ppAdminBase = pAdminBase;
  194. hr = pAdminBase->OpenKey(
  195. METADATA_MASTER_ROOT_HANDLE,
  196. pszPathName,
  197. dwAccessType,
  198. DEFAULT_TIMEOUT_VALUE,
  199. &RootHandle
  200. );
  201. //
  202. // update cache item
  203. //
  204. dwThreadId = GetCurrentThreadId();
  205. item = g_pServerCache->Find(pszServerName, dwThreadId);
  206. ASSERT(item != NULL);
  207. if (item != NULL)
  208. {
  209. UninitAdminBase(pOldAdminBase);
  210. item->UpdateAdminBase(pAdminBase, dwThreadId);
  211. }
  212. }
  213. }
  214. error :
  215. if (FAILED(hr)) {
  216. if (pAdminBase && RootHandle) {
  217. pAdminBase->CloseKey(RootHandle);
  218. }
  219. }
  220. else {
  221. *phHandle = RootHandle;
  222. }
  223. RRETURN(hr);
  224. }
  225. VOID
  226. CloseAdminBaseKey(
  227. IN IMSAdminBase *pAdminBase,
  228. IN METADATA_HANDLE hHandle
  229. )
  230. {
  231. HRESULT hr;
  232. if (pAdminBase) {
  233. hr = pAdminBase->CloseKey(hHandle);
  234. }
  235. return;
  236. }
  237. HRESULT
  238. MetaBaseGetAllData(
  239. IN IMSAdminBase *pAdminBase,
  240. IN METADATA_HANDLE hObjHandle,
  241. IN LPWSTR pszIISPathName,
  242. IN DWORD dwMDAttributes,
  243. IN DWORD dwMDUserType,
  244. IN DWORD dwMDDataType,
  245. OUT PDWORD pdwMDNumDataEntries,
  246. OUT PDWORD pdwMDDataSetNumber,
  247. OUT LPBYTE * ppBuffer
  248. )
  249. {
  250. LPBYTE pBuffer = NULL;
  251. HRESULT hr = S_OK;
  252. DWORD dwBufferSize = 0;
  253. DWORD dwReqdBufferSize = 0;
  254. hr = pAdminBase->GetAllData(
  255. hObjHandle,
  256. pszIISPathName,
  257. dwMDAttributes,
  258. dwMDUserType,
  259. dwMDDataType,
  260. pdwMDNumDataEntries,
  261. pdwMDDataSetNumber,
  262. dwBufferSize,
  263. (LPBYTE)"",
  264. &dwReqdBufferSize
  265. );
  266. pBuffer = (LPBYTE) AllocADsMem(dwReqdBufferSize);
  267. if (!pBuffer) {
  268. hr = HRESULT_FROM_WIN32(GetLastError());
  269. BAIL_ON_FAILURE(hr);
  270. }
  271. dwBufferSize = dwReqdBufferSize;
  272. hr = pAdminBase->GetAllData(
  273. hObjHandle,
  274. pszIISPathName,
  275. dwMDAttributes,
  276. dwMDUserType,
  277. dwMDDataType,
  278. pdwMDNumDataEntries,
  279. pdwMDDataSetNumber,
  280. dwBufferSize,
  281. pBuffer,
  282. &dwReqdBufferSize
  283. );
  284. BAIL_ON_FAILURE(hr);
  285. *ppBuffer = pBuffer;
  286. RRETURN(hr);
  287. error:
  288. if (pBuffer) {
  289. FreeADsMem(pBuffer);
  290. }
  291. RRETURN(hr);
  292. }
  293. HRESULT
  294. MetaBaseSetAllData(
  295. IN IMSAdminBase *pAdminBase,
  296. IN METADATA_HANDLE hObjHandle,
  297. IN LPWSTR pszIISPathName,
  298. IN PMETADATA_RECORD pMetaDataArray,
  299. IN DWORD dwNumEntries
  300. )
  301. {
  302. HRESULT hr = S_OK;
  303. PMETADATA_RECORD pTemp = NULL;
  304. METADATA_RECORD mdrMDData;
  305. DWORD i;
  306. //
  307. // Set each METADATA record one at a time
  308. //
  309. for (i = 0; i < dwNumEntries; i++) {
  310. pTemp = pMetaDataArray + i;
  311. mdrMDData.dwMDIdentifier = pTemp->dwMDIdentifier;
  312. mdrMDData.dwMDAttributes = pTemp->dwMDAttributes;
  313. mdrMDData.dwMDUserType = pTemp->dwMDUserType;
  314. mdrMDData.dwMDDataType = pTemp->dwMDDataType;
  315. mdrMDData.dwMDDataLen = pTemp->dwMDDataLen;
  316. mdrMDData.dwMDDataTag = pTemp->dwMDDataTag;
  317. mdrMDData.pbMDData = pTemp->pbMDData;
  318. hr = pAdminBase->SetData(
  319. hObjHandle,
  320. pszIISPathName,
  321. &mdrMDData
  322. );
  323. BAIL_ON_FAILURE(hr);
  324. }
  325. error:
  326. RRETURN(hr);
  327. }
  328. HRESULT
  329. MetaBaseDeleteObject(
  330. IN IMSAdminBase * pAdminBase,
  331. IN METADATA_HANDLE hObjHandle,
  332. IN LPWSTR pszIISPathName
  333. )
  334. {
  335. HRESULT hr = S_OK;
  336. hr = pAdminBase->DeleteKey(
  337. hObjHandle,
  338. pszIISPathName
  339. );
  340. RRETURN(hr);
  341. }
  342. HRESULT
  343. MetaBaseCreateObject(
  344. IN IMSAdminBase * pAdminBase,
  345. IN METADATA_HANDLE hObjHandle,
  346. IN LPWSTR pszIISPathName
  347. )
  348. {
  349. HRESULT hr = S_OK;
  350. hr = pAdminBase->AddKey(
  351. hObjHandle,
  352. pszIISPathName
  353. );
  354. RRETURN(hr);
  355. }
  356. HRESULT
  357. MetaBaseCopyObject(
  358. IN IMSAdminBase * pAdminBase,
  359. IN METADATA_HANDLE hSrcObjHandle,
  360. IN LPWSTR pszIISSrcPathName,
  361. IN METADATA_HANDLE hDestObjHandle,
  362. IN LPWSTR pszIISDestPathName
  363. )
  364. {
  365. HRESULT hr = S_OK;
  366. hr = pAdminBase->CopyKey(
  367. hSrcObjHandle,
  368. pszIISSrcPathName,
  369. hDestObjHandle,
  370. pszIISDestPathName,
  371. TRUE,
  372. TRUE
  373. );
  374. RRETURN(hr);
  375. }
  376. HRESULT
  377. MetaBaseMoveObject(
  378. IN IMSAdminBase * pAdminBase,
  379. IN METADATA_HANDLE hSrcObjHandle,
  380. IN LPWSTR pszIISSrcPathName,
  381. IN METADATA_HANDLE hDestObjHandle,
  382. IN LPWSTR pszIISDestPathName
  383. )
  384. {
  385. HRESULT hr = S_OK;
  386. hr = pAdminBase->CopyKey(
  387. hSrcObjHandle,
  388. pszIISSrcPathName,
  389. hDestObjHandle,
  390. pszIISDestPathName,
  391. FALSE,
  392. FALSE
  393. );
  394. RRETURN(hr);
  395. }
  396. HRESULT
  397. MetaBaseGetAdminACL(
  398. IN IMSAdminBase * pAdminBase,
  399. IN METADATA_HANDLE hObjHandle,
  400. IN LPWSTR pszIISPathName,
  401. OUT LPBYTE *ppBuffer
  402. )
  403. {
  404. HRESULT hr = S_OK;
  405. DWORD dwBufferSize = 0;
  406. METADATA_RECORD mdrMDData;
  407. LPBYTE pBuffer = NULL;
  408. MD_SET_DATA_RECORD(&mdrMDData,
  409. MD_ADMIN_ACL, // admin acl
  410. METADATA_INHERIT,
  411. IIS_MD_UT_FILE,
  412. BINARY_METADATA,
  413. dwBufferSize,
  414. pBuffer);
  415. hr = pAdminBase->GetData(
  416. hObjHandle,
  417. pszIISPathName,
  418. &mdrMDData,
  419. &dwBufferSize
  420. );
  421. pBuffer = (LPBYTE) AllocADsMem(dwBufferSize);
  422. if (!pBuffer) {
  423. hr = HRESULT_FROM_WIN32(GetLastError());
  424. BAIL_ON_FAILURE(hr);
  425. }
  426. MD_SET_DATA_RECORD(&mdrMDData,
  427. MD_ADMIN_ACL, // admin acl
  428. METADATA_INHERIT,
  429. IIS_MD_UT_FILE,
  430. BINARY_METADATA,
  431. dwBufferSize,
  432. pBuffer);
  433. hr = pAdminBase->GetData(
  434. hObjHandle,
  435. pszIISPathName,
  436. &mdrMDData,
  437. &dwBufferSize
  438. );
  439. BAIL_ON_FAILURE(hr);
  440. *ppBuffer = pBuffer;
  441. RRETURN(hr);
  442. error:
  443. if (pBuffer) {
  444. FreeADsMem(pBuffer);
  445. }
  446. RRETURN(hr);
  447. }
  448. HRESULT
  449. MetaBaseDetectKey(
  450. IN IMSAdminBase *pAdminBase,
  451. IN LPCWSTR pszIISPathName
  452. )
  453. {
  454. HRESULT hr = S_OK;
  455. FILETIME ft;
  456. hr = pAdminBase->GetLastChangeTime( METADATA_MASTER_ROOT_HANDLE,
  457. pszIISPathName,
  458. &ft,
  459. FALSE
  460. );
  461. RRETURN(hr);
  462. }
  463. HRESULT
  464. MetaBaseGetADsClass(
  465. IN IMSAdminBase *pAdminBase,
  466. IN LPWSTR pszIISPathName,
  467. IN IIsSchema *pSchema,
  468. OUT LPWSTR pszDataBuffer,
  469. IN DWORD dwBufferLen
  470. )
  471. /*++
  472. Routine Description:
  473. Get the ADsClass from the metabase path.
  474. Arguments:
  475. IN pAdminBase : the metabase
  476. IN pszIISPathName : the full metabase path (may be upcased)
  477. IN pSchema : schema against which to validate
  478. OUT pszDataBuffer : the class name
  479. IN dwBufferLen : number of characters allocated for class name
  480. Return Value:
  481. --*/
  482. {
  483. // CODEWORK - There are at least two other places that do essentially
  484. // the same thing. It should be possible to replace that code with a
  485. // call to this routine
  486. HRESULT hr = S_OK;
  487. METADATA_HANDLE hObjHandle = NULL;
  488. METADATA_RECORD mdrData;
  489. DWORD dwReqdBufferLen = 0;
  490. hr = pAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  491. pszIISPathName,
  492. METADATA_PERMISSION_READ,
  493. DEFAULT_TIMEOUT_VALUE,
  494. &hObjHandle
  495. );
  496. BAIL_ON_FAILURE(hr);
  497. //
  498. // Find out Class Name
  499. //
  500. mdrData.dwMDIdentifier = MD_KEY_TYPE;
  501. mdrData.dwMDDataType = STRING_METADATA;
  502. mdrData.dwMDUserType = ALL_METADATA;
  503. mdrData.dwMDAttributes = METADATA_INHERIT;
  504. mdrData.dwMDDataLen = dwBufferLen * sizeof(WCHAR);
  505. mdrData.pbMDData = (PBYTE)pszDataBuffer;
  506. hr = pAdminBase->GetData(
  507. hObjHandle,
  508. L"",
  509. &mdrData,
  510. &dwReqdBufferLen
  511. );
  512. if (FAILED(hr))
  513. {
  514. if (hr == MD_ERROR_DATA_NOT_FOUND)
  515. {
  516. //
  517. // If the key does not have a KeyType we will do our best
  518. // to guess. This is pretty bogus, but there is existing code
  519. // that depends on this behavior.
  520. //
  521. _wcsupr(pszIISPathName);
  522. if (wcsstr(pszIISPathName, L"W3SVC") != NULL)
  523. {
  524. wcscpy( pszDataBuffer, WEBDIR_CLASS_W );
  525. }
  526. else if (wcsstr(pszIISPathName, L"MSFTPSVC") != NULL)
  527. {
  528. wcscpy( pszDataBuffer, FTPVDIR_CLASS_W );
  529. }
  530. else
  531. {
  532. wcscpy( pszDataBuffer, DEFAULT_SCHEMA_CLASS_W );
  533. }
  534. hr = S_FALSE;
  535. }
  536. else
  537. {
  538. BAIL_ON_FAILURE(hr);
  539. }
  540. }
  541. else
  542. {
  543. hr = pSchema->ValidateClassName( pszDataBuffer );
  544. if (hr == E_ADS_UNKNOWN_OBJECT)
  545. {
  546. wcscpy( pszDataBuffer, DEFAULT_SCHEMA_CLASS_W );
  547. }
  548. }
  549. error:
  550. //
  551. // Close the handle now
  552. //
  553. if (hObjHandle)
  554. {
  555. CloseAdminBaseKey(pAdminBase, hObjHandle);
  556. hObjHandle = NULL;
  557. }
  558. RRETURN(hr);
  559. }
  560. static HRESULT
  561. GetSchema(
  562. CCredentials& Credentials,
  563. LPWSTR machineNameW,
  564. IIsSchema **out
  565. )
  566. /*++
  567. Routine Description:
  568. Creates and initializes a new IIsSchema object.
  569. Arguments:
  570. Return Value:
  571. Notes:
  572. This routine should only be used internally. If it is necessary
  573. to get a reference to the schema for the current machine, use
  574. InitServerInfo().
  575. --*/
  576. {
  577. IIsSchema *schema=NULL;
  578. HRESULT hr = S_OK;
  579. schema = new IIsSchema();
  580. if (schema) {
  581. hr = schema->InitSchema(machineNameW, Credentials);
  582. if (FAILED(hr)) {
  583. delete schema;
  584. schema = 0;
  585. *out = 0;
  586. return hr;
  587. }
  588. }
  589. else {
  590. return E_OUTOFMEMORY;
  591. }
  592. *out = schema;
  593. return hr;
  594. }
  595. HRESULT
  596. FreeMetaDataRecordArray(
  597. PMETADATA_RECORD pMetaDataArray,
  598. DWORD dwNumEntries
  599. )
  600. {
  601. DWORD i;
  602. DWORD dwIISType;
  603. PMETADATA_RECORD pMetaData;
  604. for (i = 0; i < dwNumEntries; i++ ) {
  605. pMetaData = pMetaDataArray + i;
  606. dwIISType = pMetaData->dwMDDataType;
  607. switch(dwIISType) {
  608. case DWORD_METADATA:
  609. break;
  610. case STRING_METADATA:
  611. case EXPANDSZ_METADATA:
  612. FreeADsStr((LPWSTR)pMetaData->pbMDData);
  613. break;
  614. case MULTISZ_METADATA:
  615. case BINARY_METADATA:
  616. FreeADsMem(pMetaData->pbMDData);
  617. break;
  618. default:
  619. break;
  620. }
  621. }
  622. FreeADsMem(pMetaDataArray);
  623. RRETURN(S_OK);
  624. }
  625. HRESULT
  626. InitAdminBase(
  627. IN CCredentials& Credentials,
  628. IN LPWSTR pszServerName,
  629. OUT IMSAdminBase **ppAdminBase
  630. )
  631. {
  632. HRESULT hr = S_OK;
  633. COSERVERINFO csiName;
  634. COSERVERINFO *pcsiParam = &csiName;
  635. IClassFactory * pcsfFactory = NULL;
  636. IMSAdminBase * pAdminBase = NULL;
  637. IMSAdminBase * pAdminBaseT = NULL;
  638. LPWSTR pszUserName = NULL;
  639. LPWSTR pszPassword = NULL;
  640. hr = Credentials.GetUserName(&pszUserName);
  641. if (FAILED(hr))
  642. {
  643. return hr;
  644. }
  645. hr = Credentials.GetPassword(&pszPassword);
  646. if (FAILED(hr))
  647. {
  648. return hr;
  649. }
  650. CComAuthInfo localAuthInfo(pszServerName,
  651. pszUserName,
  652. pszPassword);
  653. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  654. pcsiParam = localAuthInfo.CreateServerInfoStruct();
  655. hr = CoGetClassObject(
  656. CLSID_MSAdminBase,
  657. CLSCTX_SERVER,
  658. pcsiParam,
  659. IID_IClassFactory,
  660. (void**) &pcsfFactory
  661. );
  662. BAIL_ON_FAILURE(hr);
  663. hr = localAuthInfo.ApplyProxyBlanket(pcsfFactory);
  664. BAIL_ON_FAILURE(hr);
  665. hr = pcsfFactory->CreateInstance(
  666. NULL,
  667. IID_IMSAdminBase,
  668. (void **) &pAdminBaseT
  669. );
  670. BAIL_ON_FAILURE(hr);
  671. hr = localAuthInfo.ApplyProxyBlanket(pAdminBaseT);
  672. BAIL_ON_FAILURE(hr);
  673. hr = pAdminBaseT->UnmarshalInterface((IMSAdminBaseW **)&pAdminBase);
  674. pAdminBaseT->Release();
  675. pAdminBaseT = NULL;
  676. BAIL_ON_FAILURE(hr);
  677. hr = localAuthInfo.ApplyProxyBlanket(pAdminBase);
  678. BAIL_ON_FAILURE(hr);
  679. *ppAdminBase = pAdminBase;
  680. localAuthInfo.FreeServerInfoStruct(pcsiParam);
  681. error:
  682. if (pcsfFactory) {
  683. pcsfFactory->Release();
  684. }
  685. RRETURN(hr);
  686. }
  687. VOID
  688. UninitAdminBase(
  689. IN IMSAdminBase * pAdminBase
  690. )
  691. {
  692. if (pAdminBase != NULL) {
  693. pAdminBase->Release();
  694. }
  695. }
  696. HRESULT
  697. InitServerInfo(
  698. IN CCredentials& Credentials,
  699. IN LPWSTR pszServerName,
  700. OUT IMSAdminBase ** ppObject,
  701. OUT IIsSchema **ppSchema
  702. )
  703. {
  704. HRESULT hr = S_OK;
  705. IMSAdminBase * pAdminBase = NULL;
  706. IIsSchema * pSchema = NULL;
  707. SERVER_CACHE_ITEM * item;
  708. BOOL Success;
  709. DWORD dwThreadId;
  710. ASSERT(g_pServerCache != NULL);
  711. //
  712. // We'll return the localhost machine config to the users if
  713. // pszServerName == NULL, e.g. IIS:
  714. //
  715. if (pszServerName == NULL) {
  716. pszServerName = L"Localhost";
  717. }
  718. dwThreadId = GetCurrentThreadId();
  719. if ((item = g_pServerCache->Find(pszServerName, dwThreadId)) == NULL) {
  720. //
  721. // get pAdminBase and pSchema
  722. //
  723. hr = InitAdminBase(Credentials, pszServerName, &pAdminBase);
  724. BAIL_ON_FAILURE(hr);
  725. hr = GetSchema(Credentials, pszServerName, &pSchema);
  726. if( ERROR_PATH_NOT_FOUND == HRESULT_CODE(hr) ||
  727. MD_ERROR_DATA_NOT_FOUND == hr
  728. )
  729. {
  730. // Return custom error.
  731. hr = MD_ERROR_IISAO_INVALID_SCHEMA;
  732. }
  733. BAIL_ON_FAILURE(hr);
  734. item = new SERVER_CACHE_ITEM(pszServerName,
  735. pAdminBase,
  736. pSchema,
  737. dwThreadId,
  738. Success);
  739. if (item == NULL || !Success) {
  740. if (item != NULL) {
  741. delete pSchema;
  742. UninitAdminBase(pAdminBase);
  743. delete item;
  744. }
  745. RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
  746. }
  747. if (g_pServerCache->Insert(item) == FALSE) {
  748. delete pSchema;
  749. UninitAdminBase(pAdminBase);
  750. delete item;
  751. RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
  752. }
  753. }
  754. *ppSchema = item->pSchema;
  755. *ppObject = item->pAdminBase;
  756. error :
  757. RRETURN(hr);
  758. }
  759. HRESULT
  760. MetaBaseGetDataPaths(
  761. IN IMSAdminBase *pAdminBase,
  762. IN METADATA_HANDLE hObjHandle,
  763. IN DWORD dwMDMetaID,
  764. OUT LPBYTE * ppBuffer
  765. )
  766. {
  767. LPBYTE pBuffer = NULL;
  768. HRESULT hr = S_OK;
  769. DWORD dwBufferSize = 0;
  770. DWORD dwReqdBufferSize = 0;
  771. hr = pAdminBase->GetDataPaths(
  772. hObjHandle,
  773. (LPWSTR)L"",
  774. dwMDMetaID,
  775. ALL_METADATA,
  776. dwBufferSize,
  777. (LPWSTR)L"",
  778. &dwReqdBufferSize
  779. );
  780. pBuffer = (LPBYTE) AllocADsMem(dwReqdBufferSize*sizeof(WCHAR));
  781. if (!pBuffer) {
  782. hr = HRESULT_FROM_WIN32(GetLastError());
  783. BAIL_ON_FAILURE(hr);
  784. }
  785. dwBufferSize = dwReqdBufferSize;
  786. hr = pAdminBase->GetDataPaths(
  787. hObjHandle,
  788. (LPWSTR)L"",
  789. dwMDMetaID,
  790. ALL_METADATA,
  791. dwBufferSize,
  792. (LPWSTR)pBuffer,
  793. &dwReqdBufferSize
  794. );
  795. BAIL_ON_FAILURE(hr);
  796. *ppBuffer = pBuffer;
  797. RRETURN(hr);
  798. error:
  799. if (pBuffer) {
  800. FreeADsMem(pBuffer);
  801. }
  802. RRETURN(hr);
  803. }
  804. HRESULT
  805. MakeVariantFromStringArray(
  806. LPWSTR pszStr,
  807. LPWSTR pszList,
  808. VARIANT *pvVariant
  809. )
  810. {
  811. HRESULT hr = S_OK;
  812. SAFEARRAY *aList = NULL;
  813. SAFEARRAYBOUND aBound;
  814. LPWSTR pszStrList;
  815. WCHAR wchPath[MAX_PATH];
  816. if (pszList != NULL)
  817. {
  818. long nCount = 0;
  819. long i = 0;
  820. pszStrList = pszList;
  821. if (*pszStrList == L'\0') {
  822. nCount = 1;
  823. pszStrList++;
  824. }
  825. while (*pszStrList != L'\0') {
  826. while (*pszStrList != L'\0') {
  827. pszStrList++;
  828. }
  829. nCount++;
  830. pszStrList++;
  831. }
  832. aBound.lLbound = 0;
  833. aBound.cElements = nCount;
  834. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  835. if ( aList == NULL )
  836. {
  837. hr = E_OUTOFMEMORY;
  838. BAIL_ON_FAILURE(hr);
  839. }
  840. pszStrList = pszList;
  841. for (i = 0; i < nCount; i++ )
  842. {
  843. VARIANT v;
  844. VariantInit(&v);
  845. V_VT(&v) = VT_BSTR;
  846. if (pszStr) {
  847. wcscpy((LPWSTR)wchPath, pszStr);
  848. wcscat((LPWSTR)wchPath, pszStrList);
  849. hr = ADsAllocString((LPWSTR)wchPath, &(V_BSTR(&v)));
  850. }
  851. else {
  852. hr = ADsAllocString( pszStrList, &(V_BSTR(&v)));
  853. }
  854. BAIL_ON_FAILURE(hr);
  855. hr = SafeArrayPutElement( aList, &i, &v );
  856. VariantClear(&v);
  857. BAIL_ON_FAILURE(hr);
  858. pszStrList += wcslen(pszStrList) + 1;
  859. }
  860. VariantInit( pvVariant );
  861. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  862. V_ARRAY(pvVariant) = aList;
  863. }
  864. else
  865. {
  866. aBound.lLbound = 0;
  867. aBound.cElements = 0;
  868. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  869. if ( aList == NULL )
  870. {
  871. hr = E_OUTOFMEMORY;
  872. BAIL_ON_FAILURE(hr);
  873. }
  874. VariantInit( pvVariant );
  875. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  876. V_ARRAY(pvVariant) = aList;
  877. }
  878. return S_OK;
  879. error:
  880. if ( aList )
  881. SafeArrayDestroy( aList );
  882. return hr;
  883. }
  884. HRESULT
  885. MakeVariantFromPathArray(
  886. LPWSTR pszStr,
  887. LPWSTR pszList,
  888. VARIANT *pvVariant
  889. )
  890. {
  891. HRESULT hr = S_OK;
  892. SAFEARRAY *aList = NULL;
  893. SAFEARRAYBOUND aBound;
  894. LPWSTR pszStrList;
  895. LPWSTR pszConcatBuffer = NULL;
  896. DWORD cbConcatBuffer = 0;
  897. DWORD cbRequiredConcatBuffer = 0;
  898. DWORD nStrLen = 0;
  899. DWORD nPathStrLen = 0;
  900. if (pszList != NULL)
  901. {
  902. //
  903. // Count strings in pszList
  904. //
  905. long nCount = 0;
  906. long i = 0;
  907. pszStrList = pszList;
  908. while (*pszStrList != L'\0') {
  909. while (*pszStrList != L'\0') {
  910. pszStrList++;
  911. }
  912. nCount++;
  913. pszStrList++;
  914. }
  915. //
  916. // Allocate output array
  917. //
  918. aBound.lLbound = 0;
  919. aBound.cElements = nCount;
  920. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  921. if ( aList == NULL )
  922. {
  923. hr = E_OUTOFMEMORY;
  924. BAIL_ON_FAILURE(hr);
  925. }
  926. //
  927. // Prepare to copy our values from pszList to aList
  928. //
  929. if( pszStr )
  930. {
  931. nStrLen = (DWORD)wcslen( pszStr );
  932. }
  933. pszStrList = pszList;
  934. while ( *pszStrList != L'\0' )
  935. {
  936. VARIANT v;
  937. VariantInit(&v);
  938. V_VT(&v) = VT_BSTR;
  939. if (pszStr)
  940. {
  941. //
  942. // Reallocate our string buffer. Since the strings are
  943. // generally increasing in size, we'll allocate more space
  944. // than we need so we don't have to reallocate every time.
  945. //
  946. nPathStrLen = (DWORD)wcslen(pszStrList);
  947. cbRequiredConcatBuffer = ( nStrLen + nPathStrLen + 1 )
  948. * sizeof(WCHAR);
  949. if( cbRequiredConcatBuffer > cbConcatBuffer )
  950. {
  951. pszConcatBuffer = (LPWSTR)ReallocADsMem(
  952. pszConcatBuffer,
  953. cbConcatBuffer,
  954. 2 * cbRequiredConcatBuffer
  955. );
  956. if( pszConcatBuffer == NULL )
  957. {
  958. hr = E_OUTOFMEMORY;
  959. BAIL_ON_FAILURE(hr);
  960. }
  961. if( cbConcatBuffer == 0 )
  962. {
  963. // This is our first time through.
  964. wcscpy(pszConcatBuffer, pszStr);
  965. }
  966. cbConcatBuffer = 2 * cbRequiredConcatBuffer;
  967. }
  968. //
  969. // Copy the returned value into the buffer.
  970. //
  971. wcscpy(pszConcatBuffer + nStrLen, pszStrList);
  972. if (pszConcatBuffer[nStrLen + nPathStrLen - 1] == L'/')
  973. {
  974. pszConcatBuffer[nStrLen + nPathStrLen - 1] = L'\0';
  975. }
  976. hr = ADsAllocString(pszConcatBuffer, &(V_BSTR(&v)));
  977. }
  978. else {
  979. hr = ADsAllocString( pszStrList, &(V_BSTR(&v)));
  980. }
  981. BAIL_ON_FAILURE(hr);
  982. hr = SafeArrayPutElement( aList, &i, &v );
  983. VariantClear(&v);
  984. BAIL_ON_FAILURE(hr);
  985. pszStrList += wcslen(pszStrList) + 1;
  986. i++;
  987. }
  988. VariantInit( pvVariant );
  989. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  990. V_ARRAY(pvVariant) = aList;
  991. }
  992. else
  993. {
  994. aBound.lLbound = 0;
  995. aBound.cElements = 0;
  996. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  997. if ( aList == NULL )
  998. {
  999. hr = E_OUTOFMEMORY;
  1000. BAIL_ON_FAILURE(hr);
  1001. }
  1002. VariantInit( pvVariant );
  1003. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  1004. V_ARRAY(pvVariant) = aList;
  1005. }
  1006. if( pszConcatBuffer )
  1007. {
  1008. FreeADsMem( pszConcatBuffer );
  1009. }
  1010. return S_OK;
  1011. error:
  1012. if( pszConcatBuffer )
  1013. {
  1014. FreeADsMem( pszConcatBuffer );
  1015. }
  1016. if ( aList )
  1017. SafeArrayDestroy( aList );
  1018. return hr;
  1019. }
  1020. HRESULT
  1021. InitWamAdmin(
  1022. IN LPWSTR pszServerName,
  1023. OUT IWamAdmin2 **ppWamAdmin
  1024. )
  1025. {
  1026. HRESULT hr = S_OK;
  1027. COSERVERINFO csiName;
  1028. COSERVERINFO *pcsiParam = &csiName;
  1029. IClassFactory * pcsfFactory = NULL;
  1030. IWamAdmin2 * pWamAdmin = NULL;
  1031. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  1032. //
  1033. // special case to handle "localhost" to work-around ole32 bug
  1034. //
  1035. if (pszServerName == NULL || _wcsicmp(pszServerName,L"localhost") == 0) {
  1036. pcsiParam->pwszName = NULL;
  1037. }
  1038. else {
  1039. pcsiParam->pwszName = pszServerName;
  1040. }
  1041. csiName.pAuthInfo = NULL;
  1042. pcsiParam = &csiName;
  1043. hr = CoGetClassObject(
  1044. CLSID_WamAdmin,
  1045. CLSCTX_SERVER,
  1046. pcsiParam,
  1047. IID_IClassFactory,
  1048. (void**) &pcsfFactory
  1049. );
  1050. BAIL_ON_FAILURE(hr);
  1051. hr = pcsfFactory->CreateInstance(
  1052. NULL,
  1053. IID_IWamAdmin2,
  1054. (void **) &pWamAdmin
  1055. );
  1056. BAIL_ON_FAILURE(hr);
  1057. *ppWamAdmin = pWamAdmin;
  1058. error:
  1059. if (pcsfFactory) {
  1060. pcsfFactory->Release();
  1061. }
  1062. RRETURN(hr);
  1063. }
  1064. VOID
  1065. UninitWamAdmin(
  1066. IN IWamAdmin2 *pWamAdmin
  1067. )
  1068. {
  1069. if (pWamAdmin != NULL) {
  1070. pWamAdmin->Release();
  1071. }
  1072. }
  1073. HRESULT
  1074. ConvertDispatchToVariantArray(
  1075. VARIANT varDispatch,
  1076. PVARIANT * ppVarArray,
  1077. PDWORD pdwNumVariants
  1078. )
  1079. {
  1080. HRESULT hr = S_OK;
  1081. VARIANT vVar;
  1082. WCHAR* wComma = NULL;
  1083. WCHAR* wHolder = NULL;
  1084. DWORD dwNumVariants = 0;
  1085. VARIANT * pVarArray = NULL;
  1086. VariantInit(&vVar);
  1087. hr = VariantCopyInd(&vVar, &varDispatch);
  1088. BAIL_ON_FAILURE(hr);
  1089. // Output here is VT_BSTR, of format: "str_1,str_2,str_3, ... str_n\0"
  1090. hr = VariantChangeType( &vVar, &vVar, 0, VT_BSTR );
  1091. BAIL_ON_FAILURE(hr);
  1092. // count the number of comma separated entries
  1093. wHolder = wComma = vVar.bstrVal;
  1094. while (wComma) {
  1095. wComma = wcsstr(wHolder, L",");
  1096. dwNumVariants++;
  1097. if (wComma) {
  1098. wComma++;
  1099. wHolder = wComma;
  1100. }
  1101. }
  1102. if (!dwNumVariants)
  1103. {
  1104. hr = E_FAIL;
  1105. BAIL_ON_FAILURE(hr);
  1106. }
  1107. pVarArray = (PVARIANT)AllocADsMem(
  1108. sizeof(VARIANT)*dwNumVariants
  1109. );
  1110. if (!pVarArray) {
  1111. hr = E_OUTOFMEMORY;
  1112. BAIL_ON_FAILURE(hr);
  1113. }
  1114. DWORD i = 0;
  1115. wHolder = wComma = vVar.bstrVal;
  1116. while (wHolder) {
  1117. wComma = wcsstr(wHolder, L",");
  1118. if (wComma) {
  1119. *wComma = 0; // change the comma to null char
  1120. wComma++;
  1121. }
  1122. if (*wHolder) {
  1123. // use wHolder here
  1124. VariantInit(pVarArray + i);
  1125. V_VT(pVarArray + i) = VT_BSTR;
  1126. hr = ADsAllocString(wHolder, &(V_BSTR(pVarArray + i)));
  1127. BAIL_ON_FAILURE(hr);
  1128. i++;
  1129. }
  1130. else {
  1131. dwNumVariants--;
  1132. }
  1133. wHolder = wComma;
  1134. }
  1135. *ppVarArray = pVarArray;
  1136. *pdwNumVariants = dwNumVariants;
  1137. error:
  1138. VariantClear(&vVar);
  1139. RRETURN(hr);
  1140. }
  1141. HRESULT
  1142. ConvertArrayToVariantArray(
  1143. VARIANT varSafeArray,
  1144. PVARIANT * ppVarArray,
  1145. PDWORD pdwNumVariants
  1146. )
  1147. {
  1148. HRESULT hr = S_OK;
  1149. DWORD dwSLBound = 0;
  1150. DWORD dwSUBound = 0;
  1151. DWORD dwNumVariants = 0;
  1152. DWORD i = 0;
  1153. VARIANT * pVarArray = NULL;
  1154. SAFEARRAY * pArray = NULL;
  1155. *pdwNumVariants = 0;
  1156. *ppVarArray = 0;
  1157. if(!(V_ISARRAY(&varSafeArray)))
  1158. RRETURN(E_FAIL);
  1159. //
  1160. // This handles by-ref and regular SafeArrays.
  1161. //
  1162. if (V_VT(&varSafeArray) & VT_BYREF)
  1163. pArray = *(V_ARRAYREF(&varSafeArray));
  1164. else
  1165. pArray = V_ARRAY(&varSafeArray);
  1166. //
  1167. // Check that there is only one dimension in this array
  1168. //
  1169. if (pArray && pArray->cDims != 1) {
  1170. hr = E_FAIL;
  1171. BAIL_ON_FAILURE(hr);
  1172. }
  1173. //
  1174. // Check that there is at least one element in this array
  1175. //
  1176. if (!pArray ||
  1177. ( pArray->rgsabound[0].cElements == 0) ) {
  1178. dwNumVariants = 1;
  1179. pVarArray = (PVARIANT)AllocADsMem(
  1180. sizeof(VARIANT)*dwNumVariants
  1181. );
  1182. if (!pVarArray) {
  1183. hr = E_OUTOFMEMORY;
  1184. BAIL_ON_FAILURE(hr);
  1185. }
  1186. VariantInit(pVarArray);
  1187. pVarArray->vt = VT_BSTR;
  1188. pVarArray->bstrVal = NULL;
  1189. }
  1190. else {
  1191. //
  1192. // We know that this is a valid single dimension array
  1193. //
  1194. hr = SafeArrayGetLBound(pArray,
  1195. 1,
  1196. (long FAR *)&dwSLBound
  1197. );
  1198. BAIL_ON_FAILURE(hr);
  1199. hr = SafeArrayGetUBound(pArray,
  1200. 1,
  1201. (long FAR *)&dwSUBound
  1202. );
  1203. BAIL_ON_FAILURE(hr);
  1204. dwNumVariants = dwSUBound - dwSLBound + 1;
  1205. pVarArray = (PVARIANT)AllocADsMem(
  1206. sizeof(VARIANT)*dwNumVariants
  1207. );
  1208. if (!pVarArray) {
  1209. hr = E_OUTOFMEMORY;
  1210. BAIL_ON_FAILURE(hr);
  1211. }
  1212. for (i = dwSLBound; i <= dwSUBound; i++) {
  1213. VariantInit(pVarArray + i);
  1214. hr = SafeArrayGetElement(pArray,
  1215. (long FAR *)&i,
  1216. (pVarArray + i)
  1217. );
  1218. CONTINUE_ON_FAILURE(hr);
  1219. }
  1220. }
  1221. *ppVarArray = pVarArray;
  1222. *pdwNumVariants = dwNumVariants;
  1223. error:
  1224. RRETURN(hr);
  1225. }
  1226. //
  1227. // Property helper functions
  1228. //
  1229. //
  1230. #define VALIDATE_PTR(pPtr) \
  1231. if (!pPtr) { \
  1232. hr = E_ADS_BAD_PARAMETER;\
  1233. }\
  1234. BAIL_ON_FAILURE(hr);
  1235. HRESULT
  1236. put_BSTR_Property(
  1237. IADs * pADsObject,
  1238. BSTR bstrPropertyName,
  1239. BSTR pSrcStringProperty
  1240. )
  1241. {
  1242. HRESULT hr = S_OK;
  1243. VARIANT varInputData;
  1244. hr = PackStringinVariant(
  1245. pSrcStringProperty,
  1246. &varInputData
  1247. );
  1248. BAIL_ON_FAILURE(hr);
  1249. hr = pADsObject->Put(
  1250. bstrPropertyName,
  1251. varInputData
  1252. );
  1253. BAIL_ON_FAILURE(hr);
  1254. error:
  1255. VariantClear( &varInputData );
  1256. RRETURN(hr);
  1257. }
  1258. HRESULT
  1259. get_BSTR_Property(
  1260. IADs * pADsObject,
  1261. BSTR bstrPropertyName,
  1262. BSTR *ppDestStringProperty
  1263. )
  1264. {
  1265. HRESULT hr = S_OK;
  1266. VARIANT varOutputData;
  1267. VALIDATE_PTR( ppDestStringProperty );
  1268. VariantInit( &varOutputData );
  1269. hr = pADsObject->Get(
  1270. bstrPropertyName,
  1271. &varOutputData
  1272. );
  1273. BAIL_ON_FAILURE(hr);
  1274. hr = UnpackStringfromVariant(
  1275. varOutputData,
  1276. ppDestStringProperty
  1277. );
  1278. BAIL_ON_FAILURE(hr);
  1279. error:
  1280. VariantClear( &varOutputData );
  1281. RRETURN(hr);
  1282. }
  1283. HRESULT
  1284. put_LONG_Property(
  1285. IADs * pADsObject,
  1286. BSTR bstrPropertyName,
  1287. LONG lSrcProperty
  1288. )
  1289. {
  1290. HRESULT hr = S_OK;
  1291. VARIANT varInputData;
  1292. hr = PackLONGinVariant(
  1293. lSrcProperty,
  1294. &varInputData
  1295. );
  1296. BAIL_ON_FAILURE(hr);
  1297. hr = pADsObject->Put(
  1298. bstrPropertyName,
  1299. varInputData
  1300. );
  1301. BAIL_ON_FAILURE(hr);
  1302. error:
  1303. VariantClear( &varInputData );
  1304. RRETURN(hr);
  1305. }
  1306. HRESULT
  1307. get_LONG_Property(
  1308. IADs * pADsObject,
  1309. BSTR bstrPropertyName,
  1310. PLONG plDestProperty
  1311. )
  1312. {
  1313. HRESULT hr = S_OK;
  1314. VARIANT varOutputData;
  1315. VALIDATE_PTR( plDestProperty );
  1316. VariantInit( &varOutputData );
  1317. hr = pADsObject->Get(
  1318. bstrPropertyName,
  1319. &varOutputData
  1320. );
  1321. BAIL_ON_FAILURE(hr);
  1322. hr = UnpackLONGfromVariant(
  1323. varOutputData,
  1324. plDestProperty
  1325. );
  1326. BAIL_ON_FAILURE(hr);
  1327. error:
  1328. VariantClear( &varOutputData );
  1329. RRETURN(hr);
  1330. }
  1331. HRESULT
  1332. put_DATE_Property(
  1333. IADs * pADsObject,
  1334. BSTR bstrPropertyName,
  1335. DATE daSrcProperty
  1336. )
  1337. {
  1338. HRESULT hr = S_OK;
  1339. VARIANT varInputData;
  1340. hr = PackDATEinVariant(
  1341. daSrcProperty,
  1342. &varInputData
  1343. );
  1344. BAIL_ON_FAILURE(hr);
  1345. hr = pADsObject->Put(
  1346. bstrPropertyName,
  1347. varInputData
  1348. );
  1349. BAIL_ON_FAILURE(hr);
  1350. error:
  1351. VariantClear( &varInputData );
  1352. RRETURN(hr);
  1353. }
  1354. HRESULT
  1355. put_VARIANT_BOOL_Property(
  1356. IADs * pADsObject,
  1357. BSTR bstrPropertyName,
  1358. VARIANT_BOOL fSrcProperty
  1359. )
  1360. {
  1361. HRESULT hr = S_OK;
  1362. VARIANT varInputData;
  1363. hr = PackVARIANT_BOOLinVariant(
  1364. fSrcProperty,
  1365. &varInputData
  1366. );
  1367. BAIL_ON_FAILURE(hr);
  1368. hr = pADsObject->Put(
  1369. bstrPropertyName,
  1370. varInputData
  1371. );
  1372. BAIL_ON_FAILURE(hr);
  1373. error:
  1374. VariantClear( &varInputData );
  1375. RRETURN(hr);
  1376. }
  1377. HRESULT
  1378. get_VARIANT_BOOL_Property(
  1379. IADs * pADsObject,
  1380. BSTR bstrPropertyName,
  1381. PVARIANT_BOOL pfDestProperty
  1382. )
  1383. {
  1384. HRESULT hr = S_OK;
  1385. VARIANT varOutputData;
  1386. VALIDATE_PTR( pfDestProperty );
  1387. VariantInit( &varOutputData );
  1388. hr = pADsObject->Get(
  1389. bstrPropertyName,
  1390. &varOutputData
  1391. );
  1392. BAIL_ON_FAILURE(hr);
  1393. hr = UnpackVARIANT_BOOLfromVariant(
  1394. varOutputData,
  1395. pfDestProperty
  1396. );
  1397. BAIL_ON_FAILURE(hr);
  1398. error:
  1399. VariantClear( &varOutputData );
  1400. RRETURN(hr);
  1401. }
  1402. HRESULT
  1403. put_VARIANT_Property(
  1404. IADs * pADsObject,
  1405. BSTR bstrPropertyName,
  1406. VARIANT vSrcProperty
  1407. )
  1408. {
  1409. HRESULT hr = S_OK;
  1410. VARIANT varInputData;
  1411. hr = PackVARIANTinVariant(
  1412. vSrcProperty,
  1413. &varInputData
  1414. );
  1415. BAIL_ON_FAILURE(hr);
  1416. hr = pADsObject->Put(
  1417. bstrPropertyName,
  1418. varInputData
  1419. );
  1420. BAIL_ON_FAILURE(hr);
  1421. error:
  1422. VariantClear( &varInputData );
  1423. RRETURN(hr);
  1424. }
  1425. HRESULT
  1426. get_VARIANT_Property(
  1427. IADs * pADsObject,
  1428. BSTR bstrPropertyName,
  1429. PVARIANT pvDestProperty
  1430. )
  1431. {
  1432. HRESULT hr = S_OK;
  1433. VARIANT varOutputData;
  1434. VALIDATE_PTR( pvDestProperty );
  1435. VariantInit( &varOutputData );
  1436. hr = pADsObject->Get(
  1437. bstrPropertyName,
  1438. &varOutputData
  1439. );
  1440. BAIL_ON_FAILURE(hr);
  1441. hr = UnpackVARIANTfromVariant(
  1442. varOutputData,
  1443. pvDestProperty
  1444. );
  1445. BAIL_ON_FAILURE(hr);
  1446. error:
  1447. VariantClear( &varOutputData );
  1448. RRETURN(hr);
  1449. }
  1450. HRESULT
  1451. MetaBaseGetStringData(
  1452. IN IMSAdminBase * pAdminBase,
  1453. IN METADATA_HANDLE hObjHandle,
  1454. IN LPWSTR pszIISPathName,
  1455. IN DWORD dwMetaId,
  1456. OUT LPBYTE *ppBuffer
  1457. )
  1458. {
  1459. HRESULT hr = S_OK;
  1460. DWORD dwBufferSize = 0;
  1461. METADATA_RECORD mdrMDData;
  1462. LPBYTE pBuffer = NULL;
  1463. MD_SET_DATA_RECORD(&mdrMDData,
  1464. dwMetaId,
  1465. METADATA_NO_ATTRIBUTES,
  1466. ALL_METADATA,
  1467. STRING_METADATA,
  1468. dwBufferSize,
  1469. pBuffer);
  1470. hr = pAdminBase->GetData(
  1471. hObjHandle,
  1472. pszIISPathName,
  1473. &mdrMDData,
  1474. &dwBufferSize
  1475. );
  1476. pBuffer = (LPBYTE) AllocADsMem(dwBufferSize);
  1477. if (!pBuffer) {
  1478. hr = HRESULT_FROM_WIN32(GetLastError());
  1479. BAIL_ON_FAILURE(hr);
  1480. }
  1481. MD_SET_DATA_RECORD(&mdrMDData,
  1482. dwMetaId,
  1483. METADATA_NO_ATTRIBUTES,
  1484. ALL_METADATA,
  1485. STRING_METADATA,
  1486. dwBufferSize,
  1487. pBuffer);
  1488. hr = pAdminBase->GetData(
  1489. hObjHandle,
  1490. pszIISPathName,
  1491. &mdrMDData,
  1492. &dwBufferSize
  1493. );
  1494. BAIL_ON_FAILURE(hr);
  1495. *ppBuffer = pBuffer;
  1496. RRETURN(hr);
  1497. error:
  1498. if (pBuffer) {
  1499. FreeADsMem(pBuffer);
  1500. }
  1501. RRETURN(hr);
  1502. }
  1503. HRESULT
  1504. MetaBaseGetDwordData(
  1505. IN IMSAdminBase * pAdminBase,
  1506. IN METADATA_HANDLE hObjHandle,
  1507. IN LPWSTR pszIISPathName,
  1508. IN DWORD dwMetaId,
  1509. OUT PDWORD pdwData
  1510. )
  1511. {
  1512. HRESULT hr = S_OK;
  1513. DWORD dwBufferSize = sizeof(DWORD);
  1514. METADATA_RECORD mdrMDData;
  1515. LPBYTE pBuffer = (LPBYTE)pdwData;
  1516. MD_SET_DATA_RECORD(&mdrMDData,
  1517. dwMetaId,
  1518. METADATA_NO_ATTRIBUTES,
  1519. IIS_MD_UT_SERVER,
  1520. DWORD_METADATA,
  1521. dwBufferSize,
  1522. pBuffer);
  1523. hr = pAdminBase->GetData(
  1524. hObjHandle,
  1525. pszIISPathName,
  1526. &mdrMDData,
  1527. &dwBufferSize
  1528. );
  1529. RRETURN(hr);
  1530. }
  1531. HRESULT
  1532. MakeStringFromVariantArray(
  1533. VARIANT *pvVariant,
  1534. LPBYTE* ppBuffer
  1535. )
  1536. {
  1537. HRESULT hr = S_OK;
  1538. DWORD i;
  1539. DWORD dwLen = 0;
  1540. VARIANT *pVar;
  1541. LPBYTE pBuffer = NULL;
  1542. DWORD dwNumVars = 0;
  1543. VARIANT * pVarArray = NULL;
  1544. pVar = pvVariant;
  1545. if (pVar->vt == VT_EMPTY) {
  1546. RRETURN(S_OK);
  1547. }
  1548. hr = ConvertArrayToVariantArray(
  1549. *pVar,
  1550. &pVarArray,
  1551. &dwNumVars
  1552. );
  1553. BAIL_ON_FAILURE(hr);
  1554. if (dwNumVars == 0) {
  1555. RRETURN(S_OK);
  1556. }
  1557. //
  1558. // find out total length
  1559. //
  1560. pVar = pVarArray;
  1561. for (i = 0; i < dwNumVars; i++ ) {
  1562. //
  1563. // add 1 for comma
  1564. //
  1565. if (pVar->vt == VT_BSTR || pVar->vt == VT_EMPTY) {
  1566. if (pVar->bstrVal && *(pVar->bstrVal)) {
  1567. //
  1568. // validate parameter; check for ','
  1569. //
  1570. if (wcschr(pVar->bstrVal, L',')) {
  1571. hr = E_ADS_BAD_PARAMETER;
  1572. BAIL_ON_FAILURE(hr);
  1573. }
  1574. dwLen += ((DWORD)wcslen(pVar->bstrVal) + 1);
  1575. }
  1576. }
  1577. else {
  1578. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1579. BAIL_ON_FAILURE(hr);
  1580. }
  1581. pVar++;
  1582. }
  1583. //
  1584. // if there are non-empty entries found in the array, copy them to buffer
  1585. //
  1586. if (dwLen != 0) {
  1587. pBuffer = (LPBYTE) AllocADsMem(dwLen*sizeof(WCHAR));
  1588. if (!pBuffer) {
  1589. hr = E_OUTOFMEMORY;
  1590. BAIL_ON_FAILURE(hr);
  1591. }
  1592. *ppBuffer = pBuffer;
  1593. pVar = pVarArray;
  1594. for (i = 0; i < dwNumVars; i++, pVar++ ) {
  1595. if (pVar->bstrVal && *(pVar->bstrVal)) {
  1596. memcpy(pBuffer, pVar->bstrVal,
  1597. wcslen(pVar->bstrVal)*sizeof(WCHAR));
  1598. pBuffer = pBuffer + wcslen(pVar->bstrVal)*sizeof(WCHAR);
  1599. if (i != dwNumVars -1) {
  1600. memcpy(pBuffer, L",", sizeof(WCHAR));
  1601. pBuffer = pBuffer + sizeof(WCHAR);
  1602. }
  1603. }
  1604. }
  1605. if (*ppBuffer == pBuffer - dwLen*sizeof(WCHAR)) {
  1606. pBuffer -= sizeof(WCHAR);
  1607. *pBuffer = L'\0';
  1608. }
  1609. else {
  1610. *pBuffer = L'\0';
  1611. }
  1612. }
  1613. error:
  1614. if (pVarArray) {
  1615. for (i = 0; i < dwNumVars; i++) {
  1616. VariantClear(pVarArray + i);
  1617. }
  1618. FreeADsMem(pVarArray);
  1619. }
  1620. if (FAILED(hr) && pBuffer) {
  1621. FreeADsMem(pBuffer);
  1622. }
  1623. RRETURN(hr);
  1624. }
  1625. HRESULT
  1626. CheckVariantDataType(
  1627. PVARIANT pVar,
  1628. VARTYPE vt
  1629. )
  1630. {
  1631. HRESULT hr;
  1632. hr = VariantChangeType(pVar,
  1633. pVar,
  1634. 0,
  1635. vt);
  1636. if (FAILED(hr)) {
  1637. if (hr == E_OUTOFMEMORY) {
  1638. RRETURN(hr);
  1639. }
  1640. RRETURN(hr = E_ADS_CANT_CONVERT_DATATYPE);
  1641. }
  1642. RRETURN(hr);
  1643. }
  1644. HRESULT
  1645. MakeMultiStringFromVariantArray(
  1646. VARIANT *pvVariant,
  1647. LPBYTE* ppBuffer
  1648. )
  1649. {
  1650. HRESULT hr = S_OK;
  1651. DWORD i;
  1652. DWORD dwLen = 0;
  1653. VARIANT *pVar;
  1654. LPBYTE pBuffer = NULL;
  1655. DWORD dwNumVars = 0;
  1656. VARIANT * pVarArray = NULL;
  1657. pVar = pvVariant;
  1658. if (pVar->vt == VT_EMPTY) {
  1659. RRETURN(S_OK);
  1660. }
  1661. hr = ConvertArrayToVariantArray(
  1662. *pVar,
  1663. &pVarArray,
  1664. &dwNumVars
  1665. );
  1666. BAIL_ON_FAILURE(hr);
  1667. if (dwNumVars == 0) {
  1668. RRETURN(S_OK);
  1669. }
  1670. //
  1671. // find out total length
  1672. //
  1673. pVar = pVarArray;
  1674. for (i = 0; i < dwNumVars; i++ ) {
  1675. if (pVar->vt == VT_BSTR) {
  1676. if (pVar->bstrVal && *(pVar->bstrVal)) {
  1677. dwLen += ((DWORD)wcslen(pVar->bstrVal) + 1);
  1678. }
  1679. else {
  1680. //
  1681. // add 1 for \0
  1682. //
  1683. dwLen++;
  1684. }
  1685. }
  1686. else {
  1687. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1688. BAIL_ON_FAILURE(hr);
  1689. }
  1690. pVar++;
  1691. }
  1692. //
  1693. // +1 for extra \0
  1694. //
  1695. dwLen++;
  1696. //
  1697. // copy entries to buffer
  1698. //
  1699. if (dwLen != 0) {
  1700. pBuffer = (LPBYTE) AllocADsMem(dwLen*sizeof(WCHAR));
  1701. if (!pBuffer) {
  1702. hr = E_OUTOFMEMORY;
  1703. BAIL_ON_FAILURE(hr);
  1704. }
  1705. *ppBuffer = pBuffer;
  1706. pVar = pVarArray;
  1707. for (i = 0; i < dwNumVars; i++, pVar++ ) {
  1708. if (pVar->bstrVal && *(pVar->bstrVal)) {
  1709. memcpy(pBuffer, pVar->bstrVal,
  1710. wcslen(pVar->bstrVal)*sizeof(WCHAR));
  1711. pBuffer = pBuffer + wcslen(pVar->bstrVal)*sizeof(WCHAR);
  1712. }
  1713. memcpy(pBuffer, L"\0", sizeof(WCHAR));
  1714. pBuffer = pBuffer + sizeof(WCHAR);
  1715. }
  1716. *pBuffer = L'\0';
  1717. }
  1718. error:
  1719. if (pVarArray) {
  1720. for (i = 0; i < dwNumVars; i++) {
  1721. VariantClear(pVarArray + i);
  1722. }
  1723. FreeADsMem(pVarArray);
  1724. }
  1725. if (FAILED(hr) && pBuffer) {
  1726. FreeADsMem(pBuffer);
  1727. }
  1728. RRETURN(hr);
  1729. }