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.

3080 lines
74 KiB

  1. //
  2. // Microsoft Windows
  3. // Copyright (C) Microsoft Corporation, 1992 - 1996
  4. //
  5. // File: cschema.cxx
  6. //
  7. // Contents: Windows NT 4.0
  8. //
  9. //
  10. // History: 01-09-98 sophiac Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "iis.hxx"
  14. #pragma hdrstop
  15. #define PROP_RW 0x0000001
  16. SCHEMAOBJPROPS g_pClassObjProps[] = {
  17. {L"PrimaryInterface", IIS_SYNTAX_ID_STRING, CLASS_PRIMARY_INTERFACE},
  18. {L"CLSID", IIS_SYNTAX_ID_STRING, CLASS_CLSID},
  19. {L"OID", IIS_SYNTAX_ID_STRING, CLASS_OID},
  20. {L"Abstract", IIS_SYNTAX_ID_BOOL, CLASS_ABSTRACT},
  21. {L"Auxiliary", IIS_SYNTAX_ID_BOOL, CLASS_AUXILIARY},
  22. {L"MandatoryProperties", IIS_SYNTAX_ID_STRING, CLASS_MAND_PROPERTIES},
  23. {L"OptionalProperties", IIS_SYNTAX_ID_STRING, CLASS_OPT_PROPERTIES},
  24. {L"NamingProperties", IIS_SYNTAX_ID_STRING, CLASS_NAMING_PROPERTIES},
  25. {L"DerivedFrom", IIS_SYNTAX_ID_STRING, CLASS_DERIVEDFROM},
  26. {L"AuxDerivedFrom", IIS_SYNTAX_ID_STRING, CLASS_AUX_DERIVEDFROM},
  27. {L"PossibleSuperiors", IIS_SYNTAX_ID_STRING, CLASS_POSS_SUPERIORS},
  28. {L"Containment", IIS_SYNTAX_ID_STRING, CLASS_CONTAINMENT},
  29. {L"Container", IIS_SYNTAX_ID_BOOL, CLASS_CONTAINER},
  30. {L"HelpFileName", IIS_SYNTAX_ID_STRING, CLASS_HELPFILENAME},
  31. {L"HelpFileContext", IIS_SYNTAX_ID_DWORD, CLASS_HELPFILECONTEXT}
  32. };
  33. SCHEMAOBJPROPS g_pPropertyObjProps[] = {
  34. {L"OID", IIS_SYNTAX_ID_STRING, PROP_OID},
  35. {L"Syntax", IIS_SYNTAX_ID_STRING, PROP_SYNTAX},
  36. {L"MaxRange", IIS_SYNTAX_ID_DWORD, PROP_MAXRANGE},
  37. {L"MinRange", IIS_SYNTAX_ID_DWORD, PROP_MINRANGE},
  38. {L"MultiValued", IIS_SYNTAX_ID_BOOL, PROP_MULTIVALUED},
  39. {L"PropName", IIS_SYNTAX_ID_STRING, PROP_PROPNAME},
  40. {L"MetaId", IIS_SYNTAX_ID_DWORD, PROP_METAID},
  41. {L"UserType", IIS_SYNTAX_ID_DWORD, PROP_USERTYPE},
  42. {L"AllAttributes", IIS_SYNTAX_ID_DWORD, PROP_ALLATTRIBUTES},
  43. {L"Inherit", IIS_SYNTAX_ID_BOOL, PROP_INHERIT},
  44. {L"PartialPath", IIS_SYNTAX_ID_BOOL, PROP_PARTIALPATH},
  45. {L"Secure", IIS_SYNTAX_ID_BOOL, PROP_SECURE},
  46. {L"Reference", IIS_SYNTAX_ID_BOOL, PROP_REFERENCE},
  47. {L"Volatile", IIS_SYNTAX_ID_BOOL, PROP_VOLATILE},
  48. {L"Isinherit", IIS_SYNTAX_ID_BOOL, PROP_ISINHERIT},
  49. {L"InsertPath", IIS_SYNTAX_ID_BOOL, PROP_INSERTPATH},
  50. {L"Default", IIS_SYNTAX_ID_STRING_DWORD, PROP_DEFAULT}
  51. };
  52. DWORD g_cPropertyObjProps (sizeof(g_pPropertyObjProps)/sizeof(SCHEMAOBJPROPS));
  53. DWORD g_cClassObjProps (sizeof(g_pClassObjProps)/sizeof(SCHEMAOBJPROPS));
  54. /******************************************************************/
  55. /* Class CIISClass
  56. /******************************************************************/
  57. DEFINE_IDispatch_Implementation(CIISClass)
  58. DEFINE_IADs_Implementation(CIISClass)
  59. CIISClass::CIISClass()
  60. : _pDispMgr( NULL ),
  61. _bstrCLSID( NULL ),
  62. _bstrOID( NULL ),
  63. _bstrPrimaryInterface( NULL ),
  64. _fAbstract( FALSE ),
  65. _fContainer( FALSE ),
  66. _bstrHelpFileName( NULL ),
  67. _lHelpFileContext( 0 ),
  68. _bExistClass(FALSE),
  69. _pSchema(NULL),
  70. _pszServerName(NULL),
  71. _pszClassName(NULL),
  72. _pAdminBase(NULL)
  73. {
  74. VariantInit( &_vMandatoryProperties );
  75. VariantInit( &_vOptionalProperties );
  76. VariantInit( &_vPossSuperiors );
  77. VariantInit( &_vContainment );
  78. ENLIST_TRACKING(CIISClass);
  79. }
  80. CIISClass::~CIISClass()
  81. {
  82. if ( _bstrCLSID ) {
  83. ADsFreeString( _bstrCLSID );
  84. }
  85. if ( _bstrOID ) {
  86. ADsFreeString( _bstrOID );
  87. }
  88. if ( _bstrPrimaryInterface ) {
  89. ADsFreeString( _bstrPrimaryInterface );
  90. }
  91. if ( _bstrHelpFileName ) {
  92. ADsFreeString( _bstrHelpFileName );
  93. }
  94. if (_pszServerName) {
  95. FreeADsStr(_pszServerName);
  96. }
  97. if (_pszClassName) {
  98. FreeADsStr(_pszClassName);
  99. }
  100. VariantClear( &_vMandatoryProperties );
  101. VariantClear( &_vOptionalProperties );
  102. VariantClear( &_vPossSuperiors );
  103. VariantClear( &_vContainment );
  104. delete _pDispMgr;
  105. }
  106. HRESULT
  107. CIISClass::CreateClass(
  108. BSTR bstrParent,
  109. BSTR bstrRelative,
  110. DWORD dwObjectState,
  111. REFIID riid,
  112. void **ppvObj
  113. )
  114. {
  115. CIISClass FAR *pClass = NULL;
  116. HRESULT hr = S_OK;
  117. CCredentials localCred;
  118. BSTR bstrTmp = NULL;
  119. CLASSINFO *pClassInfo;
  120. OBJECTINFO ObjectInfo;
  121. POBJECTINFO pObjectInfo = &ObjectInfo;
  122. CLexer Lexer(bstrParent);
  123. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  124. hr = AllocateClassObject( &pClass );
  125. BAIL_ON_FAILURE(hr);
  126. hr = ADsObject(&Lexer, pObjectInfo);
  127. BAIL_ON_FAILURE(hr);
  128. hr = InitServerInfo(localCred,
  129. pObjectInfo->TreeName,
  130. &pClass->_pAdminBase,
  131. &pClass->_pSchema);
  132. BAIL_ON_FAILURE(hr);
  133. pClass->_pszServerName = AllocADsStr(pObjectInfo->TreeName);
  134. if (!pClass->_pszServerName) {
  135. hr = E_OUTOFMEMORY;
  136. BAIL_ON_FAILURE(hr);
  137. }
  138. pClass->_pszClassName = AllocADsStr(bstrRelative);
  139. if (!pClass->_pszClassName) {
  140. hr = E_OUTOFMEMORY;
  141. BAIL_ON_FAILURE(hr);
  142. }
  143. pClassInfo = pClass->_pSchema->GetClassInfo(bstrRelative);
  144. //
  145. // an existing class
  146. //
  147. if (pClassInfo) {
  148. pClass->_bExistClass = TRUE;
  149. pClass->_lHelpFileContext = pClassInfo->lHelpFileContext;
  150. pClass->_fContainer = (VARIANT_BOOL)pClassInfo->fContainer;
  151. pClass->_fAbstract = (VARIANT_BOOL)pClassInfo->fAbstract;
  152. if (pClassInfo->pPrimaryInterfaceGUID) {
  153. hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pPrimaryInterfaceGUID),
  154. &bstrTmp );
  155. BAIL_ON_FAILURE(hr);
  156. hr = ADsAllocString( bstrTmp,
  157. &pClass->_bstrPrimaryInterface);
  158. BAIL_ON_FAILURE(hr);
  159. CoTaskMemFree(bstrTmp);
  160. bstrTmp = NULL;
  161. }
  162. if (pClassInfo->pCLSID) {
  163. hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pCLSID),
  164. &bstrTmp );
  165. BAIL_ON_FAILURE(hr);
  166. hr = ADsAllocString( bstrTmp,
  167. &pClass->_bstrCLSID );
  168. BAIL_ON_FAILURE(hr);
  169. CoTaskMemFree(bstrTmp);
  170. bstrTmp = NULL;
  171. }
  172. hr = ADsAllocString( pClassInfo->bstrOID, &pClass->_bstrOID);
  173. BAIL_ON_FAILURE(hr);
  174. hr = MakeVariantFromStringList( pClassInfo->bstrMandatoryProperties,
  175. &(pClass->_vMandatoryProperties));
  176. BAIL_ON_FAILURE(hr);
  177. hr = MakeVariantFromStringList( pClassInfo->bstrOptionalProperties,
  178. &(pClass->_vOptionalProperties));
  179. BAIL_ON_FAILURE(hr);
  180. hr = MakeVariantFromStringList( pClassInfo->bstrPossSuperiors,
  181. &(pClass->_vPossSuperiors));
  182. BAIL_ON_FAILURE(hr);
  183. hr = MakeVariantFromStringList( pClassInfo->bstrContainment,
  184. &(pClass->_vContainment));
  185. BAIL_ON_FAILURE(hr);
  186. hr = ADsAllocString(pClassInfo->bstrHelpFileName,
  187. &pClass->_bstrHelpFileName);
  188. BAIL_ON_FAILURE(hr);
  189. }
  190. hr = pClass->InitializeCoreObject(
  191. bstrParent,
  192. bstrRelative,
  193. CLASS_CLASS_NAME,
  194. NO_SCHEMA,
  195. CLSID_IISClass,
  196. dwObjectState );
  197. BAIL_ON_FAILURE(hr);
  198. hr = pClass->QueryInterface( riid, ppvObj );
  199. BAIL_ON_FAILURE(hr);
  200. pClass->Release();
  201. FreeObjectInfo(pObjectInfo);
  202. RRETURN(hr);
  203. error:
  204. if ( bstrTmp != NULL )
  205. CoTaskMemFree(bstrTmp);
  206. *ppvObj = NULL;
  207. delete pClass;
  208. FreeObjectInfo(pObjectInfo);
  209. RRETURN(hr);
  210. }
  211. STDMETHODIMP
  212. CIISClass::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  213. {
  214. if (IsEqualIID(iid, IID_IUnknown))
  215. {
  216. *ppv = (IADsClass FAR * ) this;
  217. }
  218. else if (IsEqualIID(iid, IID_IDispatch))
  219. {
  220. *ppv = (IADs FAR *) this;
  221. }
  222. else if (IsEqualIID(iid, IID_IADs))
  223. {
  224. *ppv = (IADs FAR *) this;
  225. }
  226. else if (IsEqualIID(iid, IID_IADsClass))
  227. {
  228. *ppv = (IADsClass FAR *) this;
  229. }
  230. else
  231. {
  232. *ppv = NULL;
  233. return E_NOINTERFACE;
  234. }
  235. AddRef();
  236. return NOERROR;
  237. }
  238. /* IADs methods */
  239. STDMETHODIMP
  240. CIISClass::SetInfo(THIS)
  241. {
  242. HRESULT hr = S_OK;
  243. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  244. hr = IISCreateObject();
  245. BAIL_ON_FAILURE(hr);
  246. //
  247. // If the create succeeded, set the object type to bound
  248. //
  249. SetObjectState(ADS_OBJECT_BOUND);
  250. }
  251. hr = IISSetObject();
  252. BAIL_ON_FAILURE(hr);
  253. error:
  254. RRETURN(hr);
  255. }
  256. /* INTRINSA suppress=null_pointers, uninitialized */
  257. HRESULT
  258. CIISClass::IISSetObject()
  259. {
  260. HRESULT hr = S_OK;
  261. METADATA_HANDLE hObjHandle = NULL;
  262. PMETADATA_RECORD pMetaDataArray = NULL;
  263. DWORD dwMDNumDataEntries = 0;
  264. CLASSINFO ClassInfo;
  265. LPBYTE pBuffer = NULL;
  266. CCredentials localCred;
  267. memset(&ClassInfo, 0, sizeof(CLASSINFO));
  268. //
  269. // Add SetObject functionality : sophiac
  270. //
  271. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  272. hr = E_ADS_OBJECT_UNBOUND;
  273. BAIL_ON_FAILURE(hr);
  274. }
  275. hr = OpenAdminBaseKey(
  276. localCred,
  277. _pszServerName,
  278. SCHEMA_CLASS_METABASE_PATH,
  279. METADATA_PERMISSION_WRITE,
  280. &_pAdminBase,
  281. &hObjHandle
  282. );
  283. BAIL_ON_FAILURE(hr);
  284. hr = MakeStringFromVariantArray(&_vMandatoryProperties, (LPBYTE*)&pBuffer);
  285. BAIL_ON_FAILURE(hr);
  286. hr = ValidateProperties((LPWSTR)pBuffer, TRUE);
  287. BAIL_ON_FAILURE(hr);
  288. hr = CheckDuplicateNames((LPWSTR)pBuffer);
  289. BAIL_ON_FAILURE(hr);
  290. ClassInfo.bstrMandatoryProperties = (BSTR)pBuffer;
  291. pBuffer = NULL;
  292. hr = MakeStringFromVariantArray(&_vOptionalProperties, (LPBYTE*)&pBuffer);
  293. BAIL_ON_FAILURE(hr);
  294. hr = ValidateProperties((LPWSTR)pBuffer, FALSE);
  295. BAIL_ON_FAILURE(hr);
  296. hr = CheckDuplicateNames((LPWSTR)pBuffer);
  297. BAIL_ON_FAILURE(hr);
  298. ClassInfo.bstrOptionalProperties = (BSTR)pBuffer;
  299. pBuffer = NULL;
  300. hr = MakeStringFromVariantArray(&_vContainment, (LPBYTE*)&pBuffer);
  301. BAIL_ON_FAILURE(hr);
  302. hr = ValidateClassNames((LPWSTR)pBuffer);
  303. BAIL_ON_FAILURE(hr);
  304. hr = CheckDuplicateNames((LPWSTR)pBuffer);
  305. BAIL_ON_FAILURE(hr);
  306. ClassInfo.bstrContainment = (BSTR)pBuffer;
  307. pBuffer = NULL;
  308. ClassInfo.fContainer = _fContainer;
  309. //
  310. // validate data
  311. //
  312. if ((ClassInfo.fContainer && !ClassInfo.bstrContainment) ||
  313. (!ClassInfo.fContainer && ClassInfo.bstrContainment) ) {
  314. hr = E_ADS_SCHEMA_VIOLATION;
  315. BAIL_ON_FAILURE(hr);
  316. }
  317. // Things are okay, so reset the _v members just incase things have changed
  318. hr = MakeVariantFromStringList( ClassInfo.bstrMandatoryProperties,
  319. &(_vMandatoryProperties));
  320. BAIL_ON_FAILURE(hr);
  321. hr = MakeVariantFromStringList( ClassInfo.bstrOptionalProperties,
  322. &(_vOptionalProperties));
  323. BAIL_ON_FAILURE(hr);
  324. hr = MakeVariantFromStringList( ClassInfo.bstrContainment,
  325. &(_vContainment));
  326. BAIL_ON_FAILURE(hr);
  327. hr = IISMarshallClassProperties(
  328. &ClassInfo,
  329. &pMetaDataArray,
  330. &dwMDNumDataEntries
  331. );
  332. BAIL_ON_FAILURE(hr);
  333. hr = MetaBaseSetAllData(
  334. _pAdminBase,
  335. hObjHandle,
  336. _pszClassName,
  337. (PMETADATA_RECORD)pMetaDataArray,
  338. dwMDNumDataEntries
  339. );
  340. BAIL_ON_FAILURE(hr);
  341. //
  342. // update schema cache
  343. //
  344. _pSchema->SetClassInfo(_pszClassName, &ClassInfo);
  345. BAIL_ON_FAILURE(hr);
  346. _bExistClass = TRUE;
  347. error:
  348. //
  349. // if failed to create properties for new class, delete class node
  350. //
  351. if (FAILED(hr) && !_bExistClass && hObjHandle) {
  352. MetaBaseDeleteObject(
  353. _pAdminBase,
  354. hObjHandle,
  355. (LPWSTR)_pszClassName
  356. );
  357. }
  358. if (ClassInfo.bstrOptionalProperties) {
  359. FreeADsMem(ClassInfo.bstrOptionalProperties);
  360. }
  361. if (ClassInfo.bstrMandatoryProperties) {
  362. FreeADsMem(ClassInfo.bstrMandatoryProperties);
  363. }
  364. if (ClassInfo.bstrContainment) {
  365. FreeADsMem(ClassInfo.bstrContainment);
  366. }
  367. if (pBuffer) {
  368. FreeADsMem(pBuffer);
  369. }
  370. if (pMetaDataArray) {
  371. FreeADsMem(pMetaDataArray);
  372. }
  373. if (_pAdminBase && hObjHandle) {
  374. CloseAdminBaseKey(_pAdminBase, hObjHandle);
  375. }
  376. RRETURN(hr);
  377. }
  378. HRESULT
  379. CIISClass::IISCreateObject()
  380. {
  381. HRESULT hr = S_OK;
  382. METADATA_HANDLE hObjHandle = NULL;
  383. CCredentials localCred;
  384. //
  385. // Add CreateObject functionality : sophiac
  386. //
  387. hr = OpenAdminBaseKey(
  388. localCred,
  389. _pszServerName,
  390. SCHEMA_CLASS_METABASE_PATH,
  391. METADATA_PERMISSION_WRITE,
  392. &_pAdminBase,
  393. &hObjHandle
  394. );
  395. BAIL_ON_FAILURE(hr);
  396. //
  397. // Pass in full path
  398. //
  399. hr = MetaBaseCreateObject(
  400. _pAdminBase,
  401. hObjHandle,
  402. _pszClassName
  403. );
  404. BAIL_ON_FAILURE(hr);
  405. error:
  406. if (_pAdminBase && hObjHandle) {
  407. CloseAdminBaseKey(_pAdminBase, hObjHandle);
  408. }
  409. RRETURN(hr);
  410. }
  411. STDMETHODIMP
  412. CIISClass::GetInfo(THIS)
  413. {
  414. HRESULT hr = S_OK;
  415. PCLASSINFO pClassInfo = NULL;
  416. //
  417. // free up memory first
  418. //
  419. VariantClear( &_vMandatoryProperties );
  420. VariantClear( &_vOptionalProperties );
  421. VariantClear( &_vContainment );
  422. //
  423. // get classinfo from schema cache
  424. //
  425. pClassInfo = _pSchema->GetClassInfo(_pszClassName);
  426. if (pClassInfo) {
  427. _fContainer = (VARIANT_BOOL)pClassInfo->fContainer;
  428. hr = MakeVariantFromStringList( pClassInfo->bstrMandatoryProperties,
  429. &_vMandatoryProperties);
  430. BAIL_ON_FAILURE(hr);
  431. hr = MakeVariantFromStringList( pClassInfo->bstrOptionalProperties,
  432. &_vOptionalProperties);
  433. BAIL_ON_FAILURE(hr);
  434. hr = MakeVariantFromStringList( pClassInfo->bstrContainment,
  435. &_vContainment);
  436. BAIL_ON_FAILURE(hr);
  437. }
  438. error:
  439. RRETURN(hr);
  440. }
  441. /* IADsClass methods */
  442. STDMETHODIMP
  443. CIISClass::Get(
  444. THIS_ BSTR bstrName,
  445. VARIANT FAR* pvProp
  446. )
  447. {
  448. HRESULT hr = S_OK;
  449. DWORD dwSyntaxId;
  450. DWORD dwID;
  451. //
  452. // check if property is a supported property
  453. //
  454. hr = ValidateClassObjProps(bstrName, &dwSyntaxId, &dwID);
  455. BAIL_ON_FAILURE(hr);
  456. switch(dwID) {
  457. case CLASS_OPT_PROPERTIES:
  458. hr = get_OptionalProperties(pvProp);
  459. break;
  460. case CLASS_CONTAINMENT:
  461. hr = get_Containment(pvProp);
  462. break;
  463. case CLASS_CONTAINER:
  464. pvProp->vt = VT_BOOL;
  465. pvProp->boolVal = _fContainer? VARIANT_TRUE : VARIANT_FALSE;
  466. break;
  467. default:
  468. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  469. }
  470. error:
  471. RRETURN(hr);
  472. }
  473. HRESULT
  474. CIISClass::Put(
  475. THIS_ BSTR bstrName,
  476. VARIANT vProp
  477. )
  478. {
  479. HRESULT hr = S_OK;
  480. DWORD dwSyntaxId = 0;
  481. DWORD dwID;
  482. VARIANT vVar;
  483. //
  484. // check if property is a supported property and
  485. // loop up its syntax id
  486. //
  487. hr = ValidateClassObjProps(bstrName, &dwSyntaxId, &dwID);
  488. BAIL_ON_FAILURE(hr);
  489. VariantInit(&vVar);
  490. hr = VariantCopyInd(&vVar, &vProp);
  491. BAIL_ON_FAILURE(hr);
  492. //
  493. // update both classinfo and member variables
  494. //
  495. switch(dwID) {
  496. case CLASS_OPT_PROPERTIES:
  497. if (vVar.vt != VT_EMPTY &&
  498. !((V_VT(&vVar) & VT_VARIANT) && V_ISARRAY(&vVar))) {
  499. hr = E_ADS_CANT_CONVERT_DATATYPE;
  500. BAIL_ON_FAILURE(hr);
  501. }
  502. hr = VariantCopy(&_vOptionalProperties, &vVar);
  503. BAIL_ON_FAILURE(hr);
  504. break;
  505. case CLASS_CONTAINMENT:
  506. if (vVar.vt != VT_EMPTY &&
  507. !((V_VT(&vVar) & VT_VARIANT) && V_ISARRAY(&vVar))) {
  508. hr = E_ADS_CANT_CONVERT_DATATYPE;
  509. BAIL_ON_FAILURE(hr);
  510. }
  511. hr = VariantCopy(&_vContainment, &vVar);
  512. BAIL_ON_FAILURE(hr);
  513. break;
  514. case CLASS_CONTAINER:
  515. hr = CheckVariantDataType(&vProp, VT_BOOL);
  516. BAIL_ON_FAILURE(hr);
  517. _fContainer = (vProp.boolVal == VARIANT_TRUE) ? true : false;
  518. break;
  519. default:
  520. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  521. }
  522. error:
  523. VariantClear(&vVar);
  524. RRETURN(hr);
  525. }
  526. STDMETHODIMP
  527. CIISClass::GetEx(
  528. THIS_ BSTR bstrName,
  529. VARIANT FAR* pvProp
  530. )
  531. {
  532. HRESULT hr = S_OK;
  533. //
  534. // Get and GetEx are the same for class schema object
  535. //
  536. hr = Get(bstrName, pvProp);
  537. RRETURN(hr);
  538. }
  539. STDMETHODIMP
  540. CIISClass::PutEx(
  541. THIS_ long lnControlCode,
  542. BSTR bstrName,
  543. VARIANT vProp
  544. )
  545. {
  546. RRETURN(E_NOTIMPL);
  547. }
  548. HRESULT
  549. CIISClass::ValidateProperties(
  550. LPWSTR pszList,
  551. BOOL bMandatory
  552. )
  553. {
  554. WCHAR *pszNewList;
  555. WCHAR szName[MAX_PATH];
  556. LPWSTR ObjectList = (LPWSTR)pszList;
  557. HRESULT hr;
  558. if (pszList == NULL) RRETURN(S_OK);
  559. // need to allocate +2 = 1 for null, 1 for extra comma
  560. pszNewList = new WCHAR[wcslen(pszList)+2];
  561. if (pszNewList == NULL) RRETURN(E_OUTOFMEMORY);
  562. wcscpy(pszNewList, L"");
  563. while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
  564. if (*szName != L'\0') {
  565. hr = _pSchema->ValidatePropertyName(szName);
  566. if (hr == E_ADS_PROPERTY_NOT_SUPPORTED) {
  567. hr = PropertyInMetabase(szName, bMandatory);
  568. }
  569. else {
  570. // form the new list
  571. wcscat(pszNewList, szName);
  572. wcscat(pszNewList, L",");
  573. }
  574. BAIL_ON_FAILURE(hr); // if it's a legit bad name
  575. }
  576. }
  577. // get rid of the last comma
  578. pszNewList[wcslen(pszNewList) - 1] = 0;
  579. wcscpy(pszList, pszNewList);
  580. delete [] pszNewList;
  581. RRETURN(S_OK);
  582. error:
  583. //
  584. // return E_ADS_SCHEMA_VIOLATION if property not found in global list
  585. //
  586. delete [] pszNewList;
  587. RRETURN(E_ADS_SCHEMA_VIOLATION);
  588. }
  589. HRESULT
  590. CIISClass::PropertyInMetabase(
  591. LPWSTR szPropName,
  592. BOOL bMandatory
  593. )
  594. {
  595. // Oops - somethings wrong. What do we do? Depends...
  596. //
  597. // Check to see if the bad property name exists in the associated list
  598. // in the metabase.
  599. //
  600. // If so (case 1), then we are trying to SetInfo after having deleted a property from
  601. // the schema - so just silently remove the name from metabase & the cached class.
  602. //
  603. // If not (case 2), we are trying to SetInfo w/ a bogus property name,
  604. // so throw an exception.
  605. HRESULT hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  606. CLASSINFO *pClassInfo;
  607. LPWSTR ObjectList;
  608. WCHAR szTestProp[MAX_PATH];
  609. pClassInfo = _pSchema->GetClassInfo(_pszClassName);
  610. if (pClassInfo == NULL) {
  611. RRETURN(hr);
  612. }
  613. if (bMandatory == TRUE) {
  614. ObjectList = pClassInfo->bstrMandatoryProperties;
  615. }
  616. else {
  617. ObjectList = pClassInfo->bstrOptionalProperties;
  618. }
  619. while ((ObjectList = grabProp(szTestProp, ObjectList)) != NULL) {
  620. if (wcscmp(szTestProp, szPropName) == 0) {
  621. hr = S_OK; // clear the error - we'll fix it (case 1)
  622. }
  623. }
  624. RRETURN(hr);
  625. }
  626. HRESULT
  627. CIISClass::ValidateClassNames(
  628. LPWSTR pszList
  629. )
  630. {
  631. WCHAR szName[MAX_PATH];
  632. LPWSTR ObjectList = (LPWSTR)pszList;
  633. HRESULT hr;
  634. while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
  635. if (*szName != L'\0') {
  636. hr = _pSchema->ValidateClassName(szName);
  637. if (FAILED(hr)) {
  638. if (_wcsicmp(szName, _pszClassName)) {
  639. BAIL_ON_FAILURE(hr);
  640. }
  641. }
  642. }
  643. }
  644. RRETURN(S_OK);
  645. error:
  646. //
  647. // return E_ADS_SCHEMA_VIOLATION if classname not found in global list
  648. //
  649. RRETURN(E_ADS_SCHEMA_VIOLATION);
  650. }
  651. STDMETHODIMP
  652. CIISClass::get_PrimaryInterface( THIS_ BSTR FAR *pbstrGUID )
  653. {
  654. RRETURN(E_NOTIMPL);
  655. }
  656. STDMETHODIMP
  657. CIISClass::get_CLSID( THIS_ BSTR FAR *pbstrCLSID )
  658. {
  659. RRETURN(E_NOTIMPL);
  660. }
  661. STDMETHODIMP
  662. CIISClass::put_CLSID( THIS_ BSTR bstrCLSID )
  663. {
  664. RRETURN(E_NOTIMPL);
  665. }
  666. STDMETHODIMP
  667. CIISClass::get_OID( THIS_ BSTR FAR *pbstrOID )
  668. {
  669. RRETURN(E_NOTIMPL);
  670. }
  671. STDMETHODIMP
  672. CIISClass::put_OID( THIS_ BSTR bstrOID )
  673. {
  674. RRETURN(E_NOTIMPL);
  675. }
  676. STDMETHODIMP
  677. CIISClass::get_Abstract( THIS_ VARIANT_BOOL FAR *pfAbstract )
  678. {
  679. RRETURN(E_NOTIMPL);
  680. }
  681. STDMETHODIMP
  682. CIISClass::put_Abstract( THIS_ VARIANT_BOOL fAbstract )
  683. {
  684. RRETURN(E_NOTIMPL);
  685. }
  686. STDMETHODIMP
  687. CIISClass::get_Auxiliary( THIS_ VARIANT_BOOL FAR *pfAuxiliary)
  688. {
  689. RRETURN(E_NOTIMPL);
  690. }
  691. STDMETHODIMP
  692. CIISClass::put_Auxiliary( THIS_ VARIANT_BOOL fAuxiliary )
  693. {
  694. RRETURN(E_NOTIMPL);
  695. }
  696. STDMETHODIMP
  697. CIISClass::get_NamingProperties( THIS_ VARIANT FAR *retval )
  698. {
  699. RRETURN(E_NOTIMPL);
  700. }
  701. STDMETHODIMP
  702. CIISClass::put_NamingProperties( THIS_ VARIANT vNamingProperties )
  703. {
  704. RRETURN(E_NOTIMPL);
  705. }
  706. STDMETHODIMP
  707. CIISClass::get_MandatoryProperties( THIS_ VARIANT FAR *retval )
  708. {
  709. if ( !retval )
  710. RRETURN(E_ADS_BAD_PARAMETER);
  711. VariantInit( retval );
  712. RRETURN(VariantCopy(retval, &_vMandatoryProperties));
  713. }
  714. STDMETHODIMP
  715. CIISClass::put_MandatoryProperties( THIS_ VARIANT vMandatoryProperties )
  716. {
  717. RRETURN(E_NOTIMPL);
  718. }
  719. STDMETHODIMP
  720. CIISClass::get_OptionalProperties( THIS_ VARIANT FAR *retval )
  721. {
  722. if ( !retval )
  723. RRETURN(E_ADS_BAD_PARAMETER);
  724. VariantInit( retval );
  725. RRETURN(VariantCopy(retval, &_vOptionalProperties));
  726. }
  727. STDMETHODIMP
  728. CIISClass::put_OptionalProperties( THIS_ VARIANT vOptionalProperties )
  729. {
  730. HRESULT hr = put_VARIANT_Property( this, TEXT("OptionalProperties"),
  731. vOptionalProperties );
  732. if ( hr == E_ADS_CANT_CONVERT_DATATYPE )
  733. {
  734. hr = E_NOTIMPL;
  735. }
  736. RRETURN(hr);
  737. }
  738. STDMETHODIMP
  739. CIISClass::get_DerivedFrom( THIS_ VARIANT FAR *pvDerivedFrom )
  740. {
  741. RRETURN(E_NOTIMPL);
  742. }
  743. STDMETHODIMP
  744. CIISClass::put_DerivedFrom( THIS_ VARIANT vDerivedFrom )
  745. {
  746. RRETURN(E_NOTIMPL);
  747. }
  748. STDMETHODIMP
  749. CIISClass::get_AuxDerivedFrom( THIS_ VARIANT FAR *pvAuxDerivedFrom )
  750. {
  751. RRETURN(E_NOTIMPL);
  752. }
  753. STDMETHODIMP
  754. CIISClass::put_AuxDerivedFrom( THIS_ VARIANT vAuxDerivedFrom )
  755. {
  756. RRETURN(E_NOTIMPL);
  757. }
  758. STDMETHODIMP
  759. CIISClass::get_PossibleSuperiors( THIS_ VARIANT FAR *pvPossSuperiors )
  760. {
  761. RRETURN(E_NOTIMPL);
  762. }
  763. STDMETHODIMP
  764. CIISClass::put_PossibleSuperiors( THIS_ VARIANT vPossSuperiors )
  765. {
  766. RRETURN(E_NOTIMPL);
  767. }
  768. STDMETHODIMP
  769. CIISClass::get_Containment( THIS_ VARIANT FAR *pvContainment )
  770. {
  771. if ( !pvContainment )
  772. RRETURN(E_ADS_BAD_PARAMETER);
  773. VariantInit( pvContainment );
  774. RRETURN( VariantCopy( pvContainment, &_vContainment ));
  775. }
  776. STDMETHODIMP
  777. CIISClass::put_Containment( THIS_ VARIANT vContainment )
  778. {
  779. HRESULT hr = put_VARIANT_Property( this, TEXT("Containment"),
  780. vContainment );
  781. if ( hr == E_ADS_CANT_CONVERT_DATATYPE )
  782. {
  783. hr = E_NOTIMPL;
  784. }
  785. RRETURN(hr);
  786. }
  787. STDMETHODIMP
  788. CIISClass::get_Container( THIS_ VARIANT_BOOL FAR *pfContainer )
  789. {
  790. if ( !pfContainer )
  791. RRETURN(E_ADS_BAD_PARAMETER);
  792. *pfContainer = _fContainer? VARIANT_TRUE : VARIANT_FALSE;
  793. RRETURN(S_OK);
  794. }
  795. STDMETHODIMP
  796. CIISClass::put_Container( THIS_ VARIANT_BOOL fContainer )
  797. {
  798. HRESULT hr = put_VARIANT_BOOL_Property( this, TEXT("Container"),
  799. fContainer );
  800. RRETURN(hr);
  801. }
  802. STDMETHODIMP
  803. CIISClass::get_HelpFileName( THIS_ BSTR FAR *pbstrHelpFileName )
  804. {
  805. RRETURN(E_NOTIMPL);
  806. }
  807. STDMETHODIMP
  808. CIISClass::put_HelpFileName( THIS_ BSTR bstrHelpFile )
  809. {
  810. RRETURN(E_NOTIMPL);
  811. }
  812. STDMETHODIMP
  813. CIISClass::get_HelpFileContext( THIS_ long FAR *plHelpContext )
  814. {
  815. RRETURN(E_NOTIMPL);
  816. }
  817. STDMETHODIMP
  818. CIISClass::put_HelpFileContext( THIS_ long lHelpContext )
  819. {
  820. RRETURN(E_NOTIMPL);
  821. }
  822. STDMETHODIMP
  823. CIISClass::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers)
  824. {
  825. RRETURN(E_NOTIMPL);
  826. }
  827. HRESULT
  828. CIISClass::AllocateClassObject(CIISClass FAR * FAR * ppClass)
  829. {
  830. CIISClass FAR *pClass = NULL;
  831. CAggregatorDispMgr FAR *pDispMgr = NULL;
  832. CPropertyCache FAR * pPropertyCache = NULL;
  833. HRESULT hr = S_OK;
  834. pClass = new CIISClass();
  835. if ( pClass == NULL )
  836. hr = E_OUTOFMEMORY;
  837. BAIL_ON_FAILURE(hr);
  838. pDispMgr = new CAggregatorDispMgr;
  839. if ( pDispMgr == NULL )
  840. hr = E_OUTOFMEMORY;
  841. BAIL_ON_FAILURE(hr);
  842. hr = pDispMgr->LoadTypeInfoEntry(
  843. LIBID_ADs,
  844. IID_IADs,
  845. (IADs *) pClass,
  846. DISPID_REGULAR );
  847. BAIL_ON_FAILURE(hr);
  848. hr = pDispMgr->LoadTypeInfoEntry(
  849. LIBID_ADs,
  850. IID_IADsClass,
  851. (IADsClass *) pClass,
  852. DISPID_REGULAR );
  853. BAIL_ON_FAILURE(hr);
  854. pClass->_pDispMgr = pDispMgr;
  855. *ppClass = pClass;
  856. RRETURN(hr);
  857. error:
  858. delete pDispMgr;
  859. delete pClass;
  860. RRETURN(hr);
  861. }
  862. /******************************************************************/
  863. /* Class CIISProperty
  864. /******************************************************************/
  865. DEFINE_IDispatch_Implementation(CIISProperty)
  866. DEFINE_IADs_Implementation(CIISProperty)
  867. CIISProperty::CIISProperty()
  868. : _pDispMgr( NULL ),
  869. _bstrOID( NULL ),
  870. _bstrSyntax( NULL ),
  871. _lMaxRange( 0 ),
  872. _lMinRange( 0 ),
  873. _fMultiValued( FALSE ),
  874. _lMetaId( 0 ),
  875. _lUserType(IIS_MD_UT_SERVER ),
  876. _lAllAttributes( 0),
  877. _dwSyntaxId( IIS_SYNTAX_ID_DWORD ),
  878. _dwFlags( PROP_RW ),
  879. _dwMask( 0 ),
  880. _dwPropID( 0 ),
  881. _bExistProp(FALSE),
  882. _pSchema(NULL),
  883. _pszServerName(NULL),
  884. _pszPropName(NULL),
  885. _pAdminBase(NULL)
  886. {
  887. VariantInit(&_vDefault);
  888. ADsAllocString(L"Integer", &_bstrSyntax);
  889. ENLIST_TRACKING(CIISProperty);
  890. }
  891. CIISProperty::~CIISProperty()
  892. {
  893. if ( _bstrOID ) {
  894. ADsFreeString( _bstrOID );
  895. }
  896. if ( _bstrSyntax ) {
  897. ADsFreeString( _bstrSyntax );
  898. }
  899. if (_pszServerName) {
  900. FreeADsStr(_pszServerName);
  901. }
  902. if (_pszPropName) {
  903. FreeADsStr(_pszPropName);
  904. }
  905. VariantClear( &_vDefault );
  906. delete _pDispMgr;
  907. }
  908. /* #pragma INTRINSA suppress=all */
  909. HRESULT
  910. CIISProperty::CreateProperty(
  911. BSTR bstrParent,
  912. BSTR bstrRelative,
  913. DWORD dwObjectState,
  914. REFIID riid,
  915. void **ppvObj
  916. )
  917. {
  918. CIISProperty FAR * pProperty = NULL;
  919. HRESULT hr = S_OK;
  920. CCredentials localCred;
  921. PROPERTYINFO *pPropertyInfo;
  922. OBJECTINFO ObjectInfo;
  923. POBJECTINFO pObjectInfo = NULL;
  924. CLexer Lexer(bstrParent);
  925. hr = AllocatePropertyObject( &pProperty );
  926. BAIL_ON_FAILURE(hr);
  927. pObjectInfo = &ObjectInfo;
  928. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  929. hr = ADsObject(&Lexer, pObjectInfo);
  930. BAIL_ON_FAILURE(hr);
  931. hr = InitServerInfo(localCred,
  932. pObjectInfo->TreeName,
  933. &pProperty->_pAdminBase,
  934. &pProperty->_pSchema);
  935. BAIL_ON_FAILURE(hr);
  936. pProperty->_pszServerName = AllocADsStr(pObjectInfo->TreeName);
  937. if (!pProperty->_pszServerName) {
  938. hr = E_OUTOFMEMORY;
  939. BAIL_ON_FAILURE(hr);
  940. }
  941. pProperty->_pszPropName = AllocADsStr(bstrRelative);
  942. if (!pProperty->_pszPropName) {
  943. hr = E_OUTOFMEMORY;
  944. BAIL_ON_FAILURE(hr);
  945. }
  946. pPropertyInfo = pProperty->_pSchema->GetPropertyInfo(bstrRelative);
  947. if (pPropertyInfo) {
  948. LPWSTR pszSyntax;
  949. pProperty->_bExistProp = TRUE;
  950. hr = ADsAllocString( pPropertyInfo->bstrOID, &pProperty->_bstrOID);
  951. BAIL_ON_FAILURE(hr);
  952. pProperty->_lMaxRange = pPropertyInfo->lMaxRange;
  953. pProperty->_lMinRange = pPropertyInfo->lMinRange;
  954. pProperty->_fMultiValued = (VARIANT_BOOL)pPropertyInfo->fMultiValued;
  955. pProperty->_lMetaId = pPropertyInfo->dwMetaID;
  956. pProperty->_lUserType = pPropertyInfo->dwUserGroup;
  957. pProperty->_lAllAttributes = pPropertyInfo->dwMetaFlags;
  958. pProperty->_dwSyntaxId = pPropertyInfo->dwSyntaxId;
  959. pProperty->_dwFlags = pPropertyInfo->dwFlags;
  960. pProperty->_dwMask = pPropertyInfo->dwMask;
  961. pProperty->_dwPropID = pPropertyInfo->dwPropID;
  962. pszSyntax = SyntaxIdToString(pProperty->_dwSyntaxId);
  963. hr = ADsAllocString(pszSyntax, &(pProperty->_bstrSyntax));
  964. BAIL_ON_FAILURE(hr);
  965. if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_DWORD ||
  966. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_IPSECLIST ||
  967. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_NTACL ||
  968. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BINARY ) {
  969. (pProperty->_vDefault).vt = VT_I4;
  970. (pProperty->_vDefault).lVal = pPropertyInfo->dwDefault;
  971. }
  972. else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL ||
  973. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) {
  974. (pProperty->_vDefault).vt = VT_BOOL;
  975. (pProperty->_vDefault).boolVal =
  976. pPropertyInfo->dwDefault ? VARIANT_TRUE : VARIANT_FALSE;
  977. }
  978. else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MULTISZ ||
  979. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ) {
  980. LPWSTR pszStr = pPropertyInfo->szDefault;
  981. hr = MakeVariantFromStringArray(NULL,
  982. pszStr,
  983. &(pProperty->_vDefault));
  984. BAIL_ON_FAILURE(hr);
  985. }
  986. else {
  987. (pProperty->_vDefault).vt = VT_BSTR;
  988. hr = ADsAllocString( pPropertyInfo->szDefault,
  989. &(pProperty->_vDefault.bstrVal));
  990. BAIL_ON_FAILURE(hr);
  991. }
  992. }
  993. hr = pProperty->InitializeCoreObject(
  994. bstrParent,
  995. bstrRelative,
  996. PROPERTY_CLASS_NAME,
  997. NO_SCHEMA,
  998. CLSID_IISProperty,
  999. dwObjectState );
  1000. BAIL_ON_FAILURE(hr);
  1001. hr = pProperty->QueryInterface( riid, ppvObj );
  1002. BAIL_ON_FAILURE(hr);
  1003. pProperty->Release();
  1004. FreeObjectInfo(pObjectInfo);
  1005. RRETURN(hr);
  1006. error:
  1007. *ppvObj = NULL;
  1008. delete pProperty;
  1009. FreeObjectInfo(pObjectInfo);
  1010. RRETURN(hr);
  1011. }
  1012. STDMETHODIMP
  1013. CIISProperty::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  1014. {
  1015. if (IsEqualIID(iid, IID_IUnknown))
  1016. {
  1017. *ppv = (IADsProperty FAR *) this;
  1018. }
  1019. else if (IsEqualIID(iid, IID_IDispatch))
  1020. {
  1021. *ppv = (IADs FAR *) this;
  1022. }
  1023. else if (IsEqualIID(iid, IID_IADs))
  1024. {
  1025. *ppv = (IADs FAR *) this;
  1026. }
  1027. else if (IsEqualIID(iid, IID_IISSchemaObject))
  1028. {
  1029. *ppv = (IISSchemaObject FAR *) this;
  1030. }
  1031. else if (IsEqualIID(iid, IID_IADsProperty))
  1032. {
  1033. *ppv = (IADsProperty FAR *) this;
  1034. }
  1035. else
  1036. {
  1037. *ppv = NULL;
  1038. return E_NOINTERFACE;
  1039. }
  1040. AddRef();
  1041. return NOERROR;
  1042. }
  1043. /* IADs methods */
  1044. STDMETHODIMP
  1045. CIISProperty::SetInfo(THIS)
  1046. {
  1047. HRESULT hr = S_OK;
  1048. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  1049. //
  1050. // fill in all unset fields
  1051. //
  1052. // User set an explicit the MetaID for a new object
  1053. // we need to validate it.
  1054. if( _lMetaId != 0 &&
  1055. !IsMetaIdAvailable( _lMetaId )
  1056. )
  1057. {
  1058. return E_ADS_SCHEMA_VIOLATION;
  1059. }
  1060. if (!_bstrSyntax) {
  1061. LPWSTR pszSyntax;
  1062. pszSyntax = SyntaxIdToString(_dwSyntaxId);
  1063. hr = ADsAllocString(pszSyntax, &_bstrSyntax);
  1064. BAIL_ON_FAILURE(hr);
  1065. }
  1066. //
  1067. // If the create succeded, set the object type to bound
  1068. //
  1069. SetObjectState(ADS_OBJECT_BOUND);
  1070. }
  1071. hr = IISSetObject();
  1072. BAIL_ON_FAILURE(hr);
  1073. error:
  1074. RRETURN(hr);
  1075. }
  1076. HRESULT
  1077. CIISProperty::IISSetObject()
  1078. {
  1079. HRESULT hr = S_OK;
  1080. METADATA_HANDLE hObjHandle = NULL;
  1081. METADATA_RECORD mdr;
  1082. PropValue pv;
  1083. CCredentials localCred;
  1084. PROPERTYINFO PropertyInfo;
  1085. memset(&PropertyInfo, 0, sizeof(PROPERTYINFO));
  1086. //
  1087. // Add SetObject functionality : sophiac
  1088. //
  1089. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  1090. hr = E_ADS_OBJECT_UNBOUND;
  1091. BAIL_ON_FAILURE(hr);
  1092. }
  1093. //
  1094. // validate data
  1095. //
  1096. switch(_dwSyntaxId) {
  1097. case IIS_SYNTAX_ID_DWORD:
  1098. if (_vDefault.vt != VT_EMPTY) {
  1099. hr = CheckVariantDataType(&_vDefault, VT_I4);
  1100. if (FAILED(hr)) {
  1101. hr = E_ADS_SCHEMA_VIOLATION;
  1102. }
  1103. BAIL_ON_FAILURE(hr);
  1104. }
  1105. if (_lMaxRange < _lMinRange) {
  1106. hr = E_ADS_SCHEMA_VIOLATION;
  1107. BAIL_ON_FAILURE(hr);
  1108. }
  1109. break;
  1110. case IIS_SYNTAX_ID_BOOL:
  1111. case IIS_SYNTAX_ID_BOOL_BITMASK:
  1112. if ((_vDefault.vt != VT_EMPTY && _vDefault.vt != VT_BOOL) ||
  1113. _lMaxRange != 0 || _lMinRange != 0 ) {
  1114. hr = E_ADS_SCHEMA_VIOLATION;
  1115. BAIL_ON_FAILURE(hr);
  1116. }
  1117. break;
  1118. case IIS_SYNTAX_ID_STRING:
  1119. case IIS_SYNTAX_ID_EXPANDSZ:
  1120. if ((_vDefault.vt != VT_EMPTY && _vDefault.vt != VT_BSTR) ||
  1121. _lMaxRange != 0 || _lMinRange != 0 ) {
  1122. hr = E_ADS_SCHEMA_VIOLATION;
  1123. BAIL_ON_FAILURE(hr);
  1124. }
  1125. break;
  1126. case IIS_SYNTAX_ID_MIMEMAP:
  1127. case IIS_SYNTAX_ID_MULTISZ:
  1128. if ((_vDefault.vt != VT_EMPTY &&
  1129. _vDefault.vt != VT_VARIANT &&
  1130. !((V_VT(&_vDefault) & VT_VARIANT) && V_ISARRAY(&_vDefault))) ||
  1131. _lMaxRange != 0 || _lMinRange != 0 ) {
  1132. hr = E_ADS_SCHEMA_VIOLATION;
  1133. BAIL_ON_FAILURE(hr);
  1134. }
  1135. break;
  1136. case IIS_SYNTAX_ID_IPSECLIST:
  1137. if (_vDefault.vt != VT_EMPTY || _lMaxRange != 0 || _lMinRange != 0 ) {
  1138. hr = E_ADS_SCHEMA_VIOLATION;
  1139. BAIL_ON_FAILURE(hr);
  1140. }
  1141. break;
  1142. case IIS_SYNTAX_ID_BINARY:
  1143. case IIS_SYNTAX_ID_NTACL:
  1144. if (_vDefault.vt != VT_EMPTY || _lMaxRange != 0 || _lMinRange != 0 ) {
  1145. hr = E_ADS_SCHEMA_VIOLATION;
  1146. BAIL_ON_FAILURE(hr);
  1147. }
  1148. break;
  1149. default:
  1150. break;
  1151. }
  1152. //
  1153. // set property Default values
  1154. //
  1155. PropertyInfo.lMaxRange = _lMaxRange;
  1156. PropertyInfo.lMinRange = _lMinRange;
  1157. PropertyInfo.fMultiValued = _fMultiValued;
  1158. PropertyInfo.dwFlags = _dwFlags;
  1159. PropertyInfo.dwSyntaxId = _dwSyntaxId;
  1160. PropertyInfo.dwMask = _dwMask;
  1161. PropertyInfo.dwMetaFlags = _lAllAttributes;
  1162. PropertyInfo.dwUserGroup = _lUserType;
  1163. hr = ConvertDefaultValue(&_vDefault, &PropertyInfo);
  1164. BAIL_ON_FAILURE(hr);
  1165. hr = SetMetaID();
  1166. BAIL_ON_FAILURE(hr);
  1167. PropertyInfo.dwMetaID = _lMetaId;
  1168. PropertyInfo.dwPropID = _dwPropID;
  1169. hr = OpenAdminBaseKey(
  1170. localCred,
  1171. _pszServerName,
  1172. SCHEMA_PROP_METABASE_PATH,
  1173. METADATA_PERMISSION_WRITE,
  1174. &_pAdminBase,
  1175. &hObjHandle
  1176. );
  1177. BAIL_ON_FAILURE(hr);
  1178. //
  1179. // set property name under Properties/Names
  1180. //
  1181. MD_SET_DATA_RECORD(&mdr,
  1182. (DWORD)_lMetaId,
  1183. METADATA_NO_ATTRIBUTES,
  1184. IIS_MD_UT_SERVER,
  1185. STRING_METADATA,
  1186. ((DWORD)wcslen((LPWSTR)_pszPropName)+1)*2,
  1187. (unsigned char *)_pszPropName);
  1188. hr = _pAdminBase->SetData(hObjHandle, L"Names", &mdr);
  1189. BAIL_ON_FAILURE(hr);
  1190. //
  1191. // set property attributes/types under Properties/Types
  1192. //
  1193. InitPropValue(&pv, &PropertyInfo);
  1194. mdr.dwMDDataType = BINARY_METADATA;
  1195. mdr.dwMDDataLen = sizeof(PropValue);
  1196. mdr.pbMDData = (unsigned char *)&pv;
  1197. hr = _pAdminBase->SetData(hObjHandle, L"Types", &mdr);
  1198. BAIL_ON_FAILURE(hr);
  1199. DataForSyntaxID(&PropertyInfo, &mdr);
  1200. hr = _pAdminBase->SetData(hObjHandle, L"Defaults", &mdr);
  1201. BAIL_ON_FAILURE(hr);
  1202. //
  1203. // update schema cache
  1204. //
  1205. hr = _pSchema->SetPropertyInfo(_pszPropName, &PropertyInfo);
  1206. BAIL_ON_FAILURE(hr);
  1207. _bExistProp = TRUE;
  1208. error:
  1209. if (PropertyInfo.szDefault) {
  1210. if (PropertyInfo.dwSyntaxId == IIS_SYNTAX_ID_STRING ||
  1211. PropertyInfo.dwSyntaxId == IIS_SYNTAX_ID_EXPANDSZ) {
  1212. FreeADsStr(PropertyInfo.szDefault );
  1213. }
  1214. else if (PropertyInfo.dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) {
  1215. FreeADsMem(PropertyInfo.szDefault );
  1216. }
  1217. }
  1218. //
  1219. // if validation failed and new prop, delete class node
  1220. //
  1221. if (FAILED(hr) && !_bExistProp && hObjHandle) {
  1222. _pAdminBase->DeleteData(
  1223. hObjHandle,
  1224. (LPWSTR)L"Names",
  1225. _lMetaId,
  1226. ALL_METADATA
  1227. );
  1228. _pAdminBase->DeleteData(
  1229. hObjHandle,
  1230. (LPWSTR)L"Types",
  1231. _lMetaId,
  1232. ALL_METADATA
  1233. );
  1234. _pAdminBase->DeleteData(
  1235. hObjHandle,
  1236. (LPWSTR)L"Defaults",
  1237. _lMetaId,
  1238. ALL_METADATA
  1239. );
  1240. }
  1241. if (_pAdminBase && hObjHandle) {
  1242. CloseAdminBaseKey(_pAdminBase, hObjHandle);
  1243. }
  1244. RRETURN(hr);
  1245. }
  1246. STDMETHODIMP
  1247. CIISProperty::GetInfo(THIS)
  1248. {
  1249. HRESULT hr = S_OK;
  1250. PROPERTYINFO *pPropertyInfo = NULL;
  1251. //
  1252. // free up memory first
  1253. //
  1254. VariantClear( &_vDefault );
  1255. if ( _bstrOID ) {
  1256. ADsFreeString( _bstrOID );
  1257. }
  1258. if ( _bstrSyntax ) {
  1259. ADsFreeString( _bstrSyntax );
  1260. }
  1261. pPropertyInfo = _pSchema->GetPropertyInfo(_pszPropName);
  1262. if (pPropertyInfo) {
  1263. hr = ADsAllocString( pPropertyInfo->bstrOID, &_bstrOID);
  1264. BAIL_ON_FAILURE(hr);
  1265. hr = ADsAllocString( pPropertyInfo->bstrSyntax, &_bstrSyntax);
  1266. BAIL_ON_FAILURE(hr);
  1267. _lMaxRange = pPropertyInfo->lMaxRange;
  1268. _lMinRange = pPropertyInfo->lMinRange;
  1269. _fMultiValued = (VARIANT_BOOL)pPropertyInfo->fMultiValued;
  1270. _lMetaId = pPropertyInfo->dwMetaID;
  1271. _lUserType = pPropertyInfo->dwUserGroup;
  1272. _lAllAttributes = pPropertyInfo->dwMetaFlags;
  1273. _dwSyntaxId = pPropertyInfo->dwSyntaxId;
  1274. _dwFlags = pPropertyInfo->dwFlags;
  1275. _dwMask = pPropertyInfo->dwMask;
  1276. _dwPropID = pPropertyInfo->dwPropID;
  1277. if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_DWORD ||
  1278. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_IPSECLIST ||
  1279. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_NTACL ||
  1280. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BINARY ) {
  1281. _vDefault.vt = VT_I4;
  1282. _vDefault.lVal = pPropertyInfo->dwDefault;
  1283. }
  1284. else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL ||
  1285. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) {
  1286. _vDefault.vt = VT_BOOL;
  1287. _vDefault.boolVal =
  1288. pPropertyInfo->dwDefault ? VARIANT_TRUE : VARIANT_FALSE;
  1289. }
  1290. else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MULTISZ ||
  1291. pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ) {
  1292. LPWSTR pszStr = pPropertyInfo->szDefault;
  1293. hr = MakeVariantFromStringArray(NULL,
  1294. pszStr,
  1295. &_vDefault);
  1296. BAIL_ON_FAILURE(hr);
  1297. }
  1298. else {
  1299. _vDefault.vt = VT_BSTR;
  1300. hr = ADsAllocString( pPropertyInfo->szDefault, &(_vDefault.bstrVal));
  1301. BAIL_ON_FAILURE(hr);
  1302. }
  1303. }
  1304. error:
  1305. RRETURN(hr);
  1306. }
  1307. STDMETHODIMP
  1308. CIISProperty::Get(
  1309. THIS_ BSTR bstrName,
  1310. VARIANT FAR* pvProp
  1311. )
  1312. {
  1313. HRESULT hr = S_OK;
  1314. DWORD dwSyntaxId;
  1315. DWORD dwID;
  1316. //
  1317. // check if property is a supported property
  1318. //
  1319. hr = ValidatePropertyObjProps(bstrName, &dwSyntaxId, &dwID);
  1320. BAIL_ON_FAILURE(hr);
  1321. switch(dwID) {
  1322. case PROP_SYNTAX:
  1323. pvProp->vt = VT_BSTR;
  1324. hr = ADsAllocString( _bstrSyntax, &pvProp->bstrVal);
  1325. break;
  1326. case PROP_MAXRANGE:
  1327. pvProp->vt = VT_I4;
  1328. pvProp->lVal = _lMaxRange;
  1329. break;
  1330. case PROP_MINRANGE:
  1331. pvProp->vt = VT_I4;
  1332. pvProp->lVal = _lMinRange;
  1333. break;
  1334. case PROP_MULTIVALUED:
  1335. pvProp->vt = VT_BOOL;
  1336. pvProp->boolVal = _fMultiValued? VARIANT_TRUE : VARIANT_FALSE;
  1337. break;
  1338. case PROP_PROPNAME:
  1339. pvProp->vt = VT_BSTR;
  1340. hr = ADsAllocString( _pszPropName, &pvProp->bstrVal);
  1341. break;
  1342. case PROP_METAID:
  1343. if (_lMetaId == 0) {
  1344. hr = E_ADS_PROPERTY_NOT_SET;
  1345. }
  1346. else {
  1347. pvProp->vt = VT_I4;
  1348. pvProp->lVal = _lMetaId;
  1349. }
  1350. break;
  1351. case PROP_USERTYPE:
  1352. pvProp->vt = VT_I4;
  1353. pvProp->lVal = _lUserType;
  1354. break;
  1355. case PROP_ALLATTRIBUTES:
  1356. pvProp->vt = VT_I4;
  1357. pvProp->lVal = _lAllAttributes;
  1358. break;
  1359. case PROP_INHERIT:
  1360. pvProp->vt = VT_BOOL;
  1361. pvProp->boolVal = _lAllAttributes & METADATA_INHERIT ?
  1362. VARIANT_TRUE : VARIANT_FALSE;
  1363. break;
  1364. case PROP_SECURE:
  1365. pvProp->vt = VT_BOOL;
  1366. pvProp->boolVal = _lAllAttributes & METADATA_SECURE ?
  1367. VARIANT_TRUE : VARIANT_FALSE;
  1368. break;
  1369. case PROP_REFERENCE:
  1370. pvProp->vt = VT_BOOL;
  1371. pvProp->boolVal = _lAllAttributes & METADATA_REFERENCE ?
  1372. VARIANT_TRUE : VARIANT_FALSE;
  1373. break;
  1374. case PROP_VOLATILE:
  1375. pvProp->vt = VT_BOOL;
  1376. pvProp->boolVal = _lAllAttributes & METADATA_VOLATILE ?
  1377. VARIANT_TRUE : VARIANT_FALSE;
  1378. break;
  1379. case PROP_INSERTPATH:
  1380. pvProp->vt = VT_BOOL;
  1381. pvProp->boolVal = _lAllAttributes & METADATA_INSERT_PATH ?
  1382. VARIANT_TRUE : VARIANT_FALSE;
  1383. break;
  1384. case PROP_DEFAULT:
  1385. hr = VariantCopy(pvProp, &_vDefault);
  1386. BAIL_ON_FAILURE(hr);
  1387. break;
  1388. default:
  1389. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  1390. }
  1391. error:
  1392. RRETURN(hr);
  1393. }
  1394. HRESULT
  1395. CIISProperty::Put(
  1396. THIS_ BSTR bstrName,
  1397. VARIANT vProp
  1398. )
  1399. {
  1400. HRESULT hr = S_OK;
  1401. DWORD dwSyntaxId = 0;
  1402. DWORD dwID;
  1403. VARIANT vVar;
  1404. //
  1405. // check if property is a supported property
  1406. //
  1407. hr = ValidatePropertyObjProps(bstrName, &dwSyntaxId, &dwID);
  1408. BAIL_ON_FAILURE(hr);
  1409. switch(dwID) {
  1410. case PROP_SYNTAX:
  1411. if (_bExistProp) {
  1412. hr = E_ADS_SCHEMA_VIOLATION;
  1413. BAIL_ON_FAILURE(hr);
  1414. }
  1415. hr = ValidateSyntaxName(vProp.bstrVal, &dwSyntaxId);
  1416. BAIL_ON_FAILURE(hr);
  1417. hr = ADsReAllocString( &_bstrSyntax,
  1418. vProp.bstrVal ? vProp.bstrVal: TEXT("") );
  1419. BAIL_ON_FAILURE(hr);
  1420. _dwSyntaxId = dwSyntaxId;
  1421. if (_dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ||
  1422. _dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) {
  1423. _fMultiValued = VARIANT_TRUE;
  1424. }
  1425. break;
  1426. case PROP_MAXRANGE:
  1427. hr = CheckVariantDataType(&vProp, VT_I4);
  1428. BAIL_ON_FAILURE(hr);
  1429. _lMaxRange = vProp.lVal;
  1430. break;
  1431. case PROP_MINRANGE:
  1432. hr = CheckVariantDataType(&vProp, VT_I4);
  1433. BAIL_ON_FAILURE(hr);
  1434. _lMinRange = vProp.lVal;
  1435. break;
  1436. case PROP_USERTYPE:
  1437. hr = CheckVariantDataType(&vProp, VT_I4);
  1438. BAIL_ON_FAILURE(hr);
  1439. _lUserType = vProp.lVal;
  1440. break;
  1441. case PROP_INHERIT:
  1442. hr = CheckVariantDataType(&vProp, VT_BOOL);
  1443. BAIL_ON_FAILURE(hr);
  1444. if (vProp.boolVal == VARIANT_TRUE) {
  1445. _lAllAttributes |= METADATA_INHERIT;
  1446. }
  1447. else {
  1448. _lAllAttributes &= ~METADATA_INHERIT;
  1449. }
  1450. break;
  1451. case PROP_PARTIALPATH:
  1452. hr = CheckVariantDataType(&vProp, VT_BOOL);
  1453. BAIL_ON_FAILURE(hr);
  1454. if (vProp.boolVal == VARIANT_TRUE) {
  1455. _lAllAttributes |= METADATA_PARTIAL_PATH;
  1456. }
  1457. else {
  1458. _lAllAttributes &= ~METADATA_PARTIAL_PATH;
  1459. }
  1460. break;
  1461. case PROP_SECURE:
  1462. hr = CheckVariantDataType(&vProp, VT_BOOL);
  1463. BAIL_ON_FAILURE(hr);
  1464. if (vProp.boolVal == VARIANT_TRUE) {
  1465. _lAllAttributes |= METADATA_SECURE;
  1466. }
  1467. else {
  1468. _lAllAttributes &= ~METADATA_SECURE;
  1469. }
  1470. break;
  1471. case PROP_REFERENCE:
  1472. hr = CheckVariantDataType(&vProp, VT_BOOL);
  1473. BAIL_ON_FAILURE(hr);
  1474. if (vProp.boolVal == VARIANT_TRUE) {
  1475. _lAllAttributes |= METADATA_REFERENCE;
  1476. }
  1477. else {
  1478. _lAllAttributes &= ~METADATA_REFERENCE;
  1479. }
  1480. break;
  1481. case PROP_VOLATILE:
  1482. hr = CheckVariantDataType(&vProp, VT_BOOL);
  1483. BAIL_ON_FAILURE(hr);
  1484. if (vProp.boolVal == VARIANT_TRUE) {
  1485. _lAllAttributes |= METADATA_VOLATILE;
  1486. }
  1487. else {
  1488. _lAllAttributes &= ~METADATA_VOLATILE;
  1489. }
  1490. break;
  1491. case PROP_ISINHERIT:
  1492. hr = CheckVariantDataType(&vProp, VT_BOOL);
  1493. BAIL_ON_FAILURE(hr);
  1494. if (vProp.boolVal == VARIANT_TRUE) {
  1495. _lAllAttributes |= METADATA_ISINHERITED;
  1496. }
  1497. else {
  1498. _lAllAttributes &= ~METADATA_ISINHERITED;
  1499. }
  1500. break;
  1501. case PROP_INSERTPATH:
  1502. hr = CheckVariantDataType(&vProp, VT_BOOL);
  1503. BAIL_ON_FAILURE(hr);
  1504. if (vProp.boolVal == VARIANT_TRUE) {
  1505. _lAllAttributes |= METADATA_INSERT_PATH;
  1506. }
  1507. else {
  1508. _lAllAttributes &= ~METADATA_INSERT_PATH;
  1509. }
  1510. break;
  1511. case PROP_DEFAULT:
  1512. VariantInit(&vVar);
  1513. hr = VariantCopyInd(&vVar, &vProp);
  1514. BAIL_ON_FAILURE(hr);
  1515. VariantClear( &_vDefault );
  1516. _vDefault = vVar;
  1517. break;
  1518. case PROP_METAID:
  1519. hr = CheckVariantDataType(&vProp, VT_I4);
  1520. BAIL_ON_FAILURE(hr);
  1521. hr = put_MetaId( vProp.lVal );
  1522. break;
  1523. default:
  1524. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  1525. }
  1526. error:
  1527. RRETURN(hr);
  1528. }
  1529. STDMETHODIMP
  1530. CIISProperty::GetEx(
  1531. THIS_ BSTR bstrName,
  1532. VARIANT FAR* pvProp
  1533. )
  1534. {
  1535. HRESULT hr = S_OK;
  1536. //
  1537. // Get and GetEx are the same for property schema object
  1538. //
  1539. hr = Get(bstrName, pvProp);
  1540. RRETURN(hr);
  1541. }
  1542. STDMETHODIMP
  1543. CIISProperty::PutEx(
  1544. THIS_ long lnControlCode,
  1545. BSTR bstrName,
  1546. VARIANT vProp
  1547. )
  1548. {
  1549. RRETURN(E_NOTIMPL);
  1550. }
  1551. HRESULT
  1552. CIISProperty::ConvertDefaultValue(
  1553. PVARIANT pVar,
  1554. PROPERTYINFO *pPropInfo
  1555. )
  1556. {
  1557. HRESULT hr = S_OK;
  1558. LPBYTE *pBuffer;
  1559. if (pVar->vt != VT_EMPTY) {
  1560. if (pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_DWORD ||
  1561. pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_IPSECLIST ||
  1562. pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_NTACL ||
  1563. pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_BINARY ) {
  1564. pPropInfo->dwDefault = (DWORD)pVar->lVal;
  1565. }
  1566. else if (pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL ||
  1567. pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) {
  1568. pPropInfo->dwDefault = pVar->boolVal ? 1 : 0;
  1569. }
  1570. else if (pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_MULTISZ ||
  1571. pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ) {
  1572. hr = MakeMultiStringFromVariantArray(pVar,
  1573. (LPBYTE*)&pBuffer);
  1574. BAIL_ON_FAILURE(hr);
  1575. pPropInfo->szDefault = (LPWSTR) pBuffer;
  1576. }
  1577. else {
  1578. if (pVar->vt == VT_BSTR && pVar->bstrVal && *(pVar->bstrVal)) {
  1579. pPropInfo->szDefault = AllocADsStr(pVar->bstrVal);
  1580. if (!pPropInfo->szDefault) {
  1581. hr = E_OUTOFMEMORY;
  1582. BAIL_ON_FAILURE(hr);
  1583. }
  1584. }
  1585. }
  1586. }
  1587. error:
  1588. RRETURN(hr);
  1589. }
  1590. HRESULT
  1591. CIISProperty::ValidateSyntaxName(
  1592. LPWSTR pszName,
  1593. PDWORD pdwSyntax
  1594. )
  1595. {
  1596. HRESULT hr = S_OK;
  1597. DWORD i;
  1598. //
  1599. // Look for the given syntax name
  1600. //
  1601. for ( i = 0; i < g_cIISSyntax; i++ )
  1602. {
  1603. if ( _wcsicmp( g_aIISSyntax[i].bstrName, pszName ) == 0 ) {
  1604. *pdwSyntax = g_aIISSyntax[i].dwIISSyntaxId;
  1605. RRETURN(S_OK);
  1606. }
  1607. }
  1608. RRETURN(E_ADS_BAD_PARAMETER);
  1609. }
  1610. /* IADsProperty methods */
  1611. STDMETHODIMP
  1612. CIISProperty::get_OID( THIS_ BSTR FAR *pbstrOID )
  1613. {
  1614. RRETURN(E_NOTIMPL);
  1615. }
  1616. STDMETHODIMP
  1617. CIISProperty::put_OID( THIS_ BSTR bstrOID )
  1618. {
  1619. RRETURN(E_NOTIMPL);
  1620. }
  1621. STDMETHODIMP
  1622. CIISProperty::get_Syntax( THIS_ BSTR FAR *pbstrSyntax )
  1623. {
  1624. if ( !pbstrSyntax )
  1625. RRETURN(E_ADS_BAD_PARAMETER);
  1626. RRETURN( ADsAllocString( _bstrSyntax, pbstrSyntax ));
  1627. }
  1628. STDMETHODIMP
  1629. CIISProperty::put_Syntax( THIS_ BSTR bstrSyntax )
  1630. {
  1631. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1632. if (SUCCEEDED(hr_check)) {
  1633. RRETURN(E_FAIL);
  1634. }
  1635. HRESULT hr;
  1636. DWORD dwSyntaxId;
  1637. if (_bExistProp) {
  1638. RRETURN(E_ADS_SCHEMA_VIOLATION);
  1639. }
  1640. hr = ValidateSyntaxName(bstrSyntax, &dwSyntaxId);
  1641. BAIL_ON_FAILURE(hr);
  1642. hr = ADsReAllocString( &_bstrSyntax, bstrSyntax);
  1643. BAIL_ON_FAILURE(hr);
  1644. _dwSyntaxId = dwSyntaxId;
  1645. if (_dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ||
  1646. _dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) {
  1647. _fMultiValued = VARIANT_TRUE;
  1648. }
  1649. error:
  1650. RRETURN(hr);
  1651. }
  1652. STDMETHODIMP
  1653. CIISProperty::get_MaxRange( THIS_ long FAR *plMaxRange )
  1654. {
  1655. if ( !plMaxRange )
  1656. RRETURN(E_ADS_BAD_PARAMETER);
  1657. *plMaxRange = _lMaxRange;
  1658. RRETURN(S_OK);
  1659. }
  1660. STDMETHODIMP
  1661. CIISProperty::put_MaxRange( THIS_ long lMaxRange )
  1662. {
  1663. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1664. if (SUCCEEDED(hr_check)) {
  1665. RRETURN(E_FAIL);
  1666. }
  1667. _lMaxRange = lMaxRange;
  1668. RRETURN(S_OK);
  1669. }
  1670. STDMETHODIMP
  1671. CIISProperty::get_MinRange( THIS_ long FAR *plMinRange )
  1672. {
  1673. if ( !plMinRange )
  1674. RRETURN(E_ADS_BAD_PARAMETER);
  1675. *plMinRange = _lMinRange;
  1676. RRETURN(S_OK);
  1677. }
  1678. STDMETHODIMP
  1679. CIISProperty::put_MinRange( THIS_ long lMinRange )
  1680. {
  1681. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1682. if (SUCCEEDED(hr_check)) {
  1683. RRETURN(E_FAIL);
  1684. }
  1685. _lMinRange = lMinRange;
  1686. RRETURN(S_OK);
  1687. }
  1688. STDMETHODIMP
  1689. CIISProperty::get_MultiValued( THIS_ VARIANT_BOOL FAR *pfMultiValued )
  1690. {
  1691. if ( !pfMultiValued )
  1692. RRETURN(E_ADS_BAD_PARAMETER);
  1693. *pfMultiValued = _fMultiValued;
  1694. RRETURN(S_OK);
  1695. }
  1696. STDMETHODIMP
  1697. CIISProperty::put_MultiValued( THIS_ VARIANT_BOOL fMultiValued )
  1698. {
  1699. RRETURN(E_NOTIMPL);
  1700. }
  1701. STDMETHODIMP
  1702. CIISProperty::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers)
  1703. {
  1704. RRETURN(E_NOTIMPL);
  1705. }
  1706. HRESULT
  1707. CIISProperty::AllocatePropertyObject(CIISProperty FAR * FAR * ppProperty)
  1708. {
  1709. CIISProperty FAR *pProperty = NULL;
  1710. CPropertyCache FAR * pPropertyCache = NULL;
  1711. CAggregatorDispMgr FAR *pDispMgr = NULL;
  1712. HRESULT hr = S_OK;
  1713. pProperty = new CIISProperty();
  1714. if ( pProperty == NULL )
  1715. hr = E_OUTOFMEMORY;
  1716. BAIL_ON_FAILURE(hr);
  1717. pDispMgr = new CAggregatorDispMgr;
  1718. if ( pDispMgr == NULL )
  1719. hr = E_OUTOFMEMORY;
  1720. BAIL_ON_FAILURE(hr);
  1721. hr = pDispMgr->LoadTypeInfoEntry(
  1722. LIBID_ADs,
  1723. IID_IADs,
  1724. (IADs *) pProperty,
  1725. DISPID_REGULAR );
  1726. BAIL_ON_FAILURE(hr);
  1727. hr = pDispMgr->LoadTypeInfoEntry(
  1728. LIBID_ADs,
  1729. IID_IADsProperty,
  1730. (IADsProperty *) pProperty,
  1731. DISPID_REGULAR );
  1732. BAIL_ON_FAILURE(hr);
  1733. hr = pDispMgr->LoadTypeInfoEntry(
  1734. LIBID_IISOle,
  1735. IID_IISPropertyAttribute,
  1736. (IISPropertyAttribute *)pProperty,
  1737. DISPID_REGULAR
  1738. );
  1739. BAIL_ON_FAILURE(hr);
  1740. pProperty->_pDispMgr = pDispMgr;
  1741. *ppProperty = pProperty;
  1742. RRETURN(hr);
  1743. error:
  1744. delete pDispMgr;
  1745. delete pProperty;
  1746. RRETURN(hr);
  1747. }
  1748. STDMETHODIMP
  1749. CIISProperty::get_PropName(THIS_ BSTR FAR * retval)
  1750. {
  1751. HRESULT hr = S_OK;
  1752. hr = ADsAllocString((LPWSTR)_pszPropName, retval);
  1753. RRETURN(hr);
  1754. }
  1755. STDMETHODIMP
  1756. CIISProperty::get_MetaId(THIS_ LONG FAR * retval)
  1757. {
  1758. HRESULT hr = S_OK;
  1759. if (_lMetaId == 0) {
  1760. hr = E_ADS_PROPERTY_NOT_SET;
  1761. }
  1762. else {
  1763. *retval = _lMetaId;
  1764. }
  1765. RRETURN(hr);
  1766. }
  1767. STDMETHODIMP
  1768. CIISProperty::put_MetaId(THIS_ LONG lMetaId)
  1769. {
  1770. if (GetObjectState() != ADS_OBJECT_UNBOUND)
  1771. {
  1772. // Only valid for unsaved objects
  1773. RRETURN( E_ADS_OBJECT_EXISTS );
  1774. }
  1775. if( lMetaId < 0 )
  1776. {
  1777. // Never a valid metabase id
  1778. RRETURN( E_ADS_BAD_PARAMETER );
  1779. }
  1780. if( !IsMetaIdAvailable( (DWORD)lMetaId ) )
  1781. {
  1782. // This id is already in use
  1783. RRETURN( E_ADS_SCHEMA_VIOLATION );
  1784. }
  1785. _lMetaId = (DWORD)lMetaId;
  1786. RRETURN(S_OK);
  1787. }
  1788. STDMETHODIMP
  1789. CIISProperty::get_UserType(THIS_ LONG FAR * retval)
  1790. {
  1791. *retval = _lUserType;
  1792. RRETURN(S_OK);
  1793. }
  1794. STDMETHODIMP
  1795. CIISProperty::put_UserType(THIS_ LONG lUserType)
  1796. {
  1797. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1798. if (SUCCEEDED(hr_check)) {
  1799. RRETURN(E_FAIL);
  1800. }
  1801. _lUserType = (DWORD)lUserType;
  1802. RRETURN(S_OK);
  1803. }
  1804. STDMETHODIMP
  1805. CIISProperty::get_AllAttributes(THIS_ LONG FAR * retval)
  1806. {
  1807. *retval = _lAllAttributes;
  1808. RRETURN(S_OK);
  1809. }
  1810. STDMETHODIMP
  1811. CIISProperty::get_Inherit(THIS_ VARIANT_BOOL FAR * retval)
  1812. {
  1813. *retval = _lAllAttributes & METADATA_INHERIT ?
  1814. VARIANT_TRUE : VARIANT_FALSE;
  1815. RRETURN(S_OK);
  1816. }
  1817. STDMETHODIMP
  1818. CIISProperty::put_Inherit(THIS_ VARIANT_BOOL bInherit)
  1819. {
  1820. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1821. if (SUCCEEDED(hr_check)) {
  1822. RRETURN(E_FAIL);
  1823. }
  1824. if (bInherit == VARIANT_TRUE) {
  1825. _lAllAttributes |= METADATA_INHERIT;
  1826. }
  1827. else {
  1828. _lAllAttributes &= ~METADATA_INHERIT;
  1829. }
  1830. RRETURN(S_OK);
  1831. }
  1832. STDMETHODIMP
  1833. CIISProperty::get_PartialPath(THIS_ VARIANT_BOOL FAR * retval)
  1834. {
  1835. RRETURN(E_NOTIMPL);
  1836. }
  1837. STDMETHODIMP
  1838. CIISProperty::put_PartialPath(THIS_ VARIANT_BOOL bPartialPath)
  1839. {
  1840. RRETURN(E_NOTIMPL);
  1841. }
  1842. STDMETHODIMP
  1843. CIISProperty::get_Reference(THIS_ VARIANT_BOOL FAR * retval)
  1844. {
  1845. *retval = _lAllAttributes & METADATA_REFERENCE ?
  1846. VARIANT_TRUE : VARIANT_FALSE;
  1847. RRETURN(S_OK);
  1848. }
  1849. STDMETHODIMP
  1850. CIISProperty::put_Reference(THIS_ VARIANT_BOOL bReference)
  1851. {
  1852. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1853. if (SUCCEEDED(hr_check)) {
  1854. RRETURN(E_FAIL);
  1855. }
  1856. if (bReference == VARIANT_TRUE) {
  1857. _lAllAttributes |= METADATA_REFERENCE;
  1858. }
  1859. else {
  1860. _lAllAttributes &= ~METADATA_REFERENCE;
  1861. }
  1862. RRETURN(S_OK);
  1863. }
  1864. STDMETHODIMP
  1865. CIISProperty::get_Secure(THIS_ VARIANT_BOOL FAR * retval)
  1866. {
  1867. *retval = _lAllAttributes & METADATA_SECURE ?
  1868. VARIANT_TRUE : VARIANT_FALSE;
  1869. RRETURN(S_OK);
  1870. }
  1871. STDMETHODIMP
  1872. CIISProperty::put_Secure(THIS_ VARIANT_BOOL bSecure)
  1873. {
  1874. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1875. if (SUCCEEDED(hr_check)) {
  1876. RRETURN(E_FAIL);
  1877. }
  1878. if (bSecure == VARIANT_TRUE) {
  1879. _lAllAttributes |= METADATA_SECURE;
  1880. }
  1881. else {
  1882. _lAllAttributes &= ~METADATA_SECURE;
  1883. }
  1884. RRETURN(S_OK);
  1885. }
  1886. STDMETHODIMP
  1887. CIISProperty::get_Volatile(THIS_ VARIANT_BOOL FAR * retval)
  1888. {
  1889. *retval = _lAllAttributes & METADATA_VOLATILE ?
  1890. VARIANT_TRUE : VARIANT_FALSE;
  1891. RRETURN(S_OK);
  1892. }
  1893. STDMETHODIMP
  1894. CIISProperty::put_Volatile(THIS_ VARIANT_BOOL bVolatile)
  1895. {
  1896. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1897. if (SUCCEEDED(hr_check)) {
  1898. RRETURN(E_FAIL);
  1899. }
  1900. if (bVolatile == VARIANT_TRUE) {
  1901. _lAllAttributes |= METADATA_VOLATILE;
  1902. }
  1903. else {
  1904. _lAllAttributes &= ~METADATA_VOLATILE;
  1905. }
  1906. RRETURN(S_OK);
  1907. }
  1908. STDMETHODIMP
  1909. CIISProperty::get_Isinherit(THIS_ VARIANT_BOOL FAR * retval)
  1910. {
  1911. RRETURN(E_NOTIMPL);
  1912. }
  1913. STDMETHODIMP
  1914. CIISProperty::put_Isinherit(THIS_ VARIANT_BOOL bIsinherit)
  1915. {
  1916. RRETURN(E_NOTIMPL);
  1917. }
  1918. STDMETHODIMP
  1919. CIISProperty::get_InsertPath(THIS_ VARIANT_BOOL FAR * retval)
  1920. {
  1921. *retval = _lAllAttributes & METADATA_INSERT_PATH ?
  1922. VARIANT_TRUE : VARIANT_FALSE;
  1923. RRETURN(S_OK);
  1924. }
  1925. STDMETHODIMP
  1926. CIISProperty::put_InsertPath(THIS_ VARIANT_BOOL bInsertPath)
  1927. {
  1928. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1929. if (SUCCEEDED(hr_check)) {
  1930. RRETURN(E_FAIL);
  1931. }
  1932. if (bInsertPath == VARIANT_TRUE) {
  1933. _lAllAttributes |= METADATA_INSERT_PATH;
  1934. }
  1935. else {
  1936. _lAllAttributes &= ~METADATA_INSERT_PATH;
  1937. }
  1938. RRETURN(S_OK);
  1939. }
  1940. STDMETHODIMP
  1941. CIISProperty::get_Default(THIS_ VARIANT FAR * retval)
  1942. {
  1943. VariantInit(retval);
  1944. RRETURN(VariantCopy(retval, &_vDefault));
  1945. }
  1946. STDMETHODIMP
  1947. CIISProperty::put_Default(THIS_ VARIANT vVarDefault)
  1948. {
  1949. HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
  1950. if (SUCCEEDED(hr_check)) {
  1951. RRETURN(E_FAIL);
  1952. }
  1953. VariantClear(&_vDefault);
  1954. RRETURN(VariantCopy(&_vDefault, &vVarDefault));
  1955. }
  1956. HRESULT
  1957. CIISProperty::SetMetaID()
  1958. {
  1959. HRESULT hr = S_OK;
  1960. DWORD dwMetaId;
  1961. //
  1962. // get metaid
  1963. //
  1964. if (_lMetaId == 0) {
  1965. hr = _pSchema->LookupMetaID(_pszPropName, &dwMetaId);
  1966. //
  1967. // generate a meta id for this property
  1968. //
  1969. if (FAILED(hr)) {
  1970. hr = GenerateNewMetaID(_pszServerName, _pAdminBase, &dwMetaId);
  1971. BAIL_ON_FAILURE(hr);
  1972. //
  1973. // since we don't support bit mask property for ext. schema,
  1974. // propid == metaid
  1975. //
  1976. _dwPropID = dwMetaId;
  1977. }
  1978. else {
  1979. hr = _pSchema->LookupPropID(_pszPropName, &_dwPropID);
  1980. ASSERT(hr);
  1981. }
  1982. //
  1983. // assign new metaid to property
  1984. //
  1985. _lMetaId = (LONG)dwMetaId;
  1986. }
  1987. error:
  1988. RRETURN(hr);
  1989. }
  1990. BOOL
  1991. CIISProperty::IsMetaIdAvailable(
  1992. DWORD MetaId
  1993. )
  1994. /*++
  1995. Routine Description:
  1996. Determine if the ID is valid to set on a new property.
  1997. The determinination is based on whether the id is not
  1998. currently in use.
  1999. NOTE - We will not respect ranges of IDs reserved for
  2000. the base object. Unless that value is already defined
  2001. (per vanvan)
  2002. Arguments:
  2003. MetaId - The ID to validate
  2004. Return Value:
  2005. TRUE if the specified id is valid to set, FALSE otherwise
  2006. --*/
  2007. {
  2008. BOOL fRet = FALSE;
  2009. HRESULT hr = NOERROR;
  2010. CCredentials localCred;
  2011. METADATA_HANDLE hObjHandle = NULL;
  2012. // Is the property specified by MetaId defined in the schema
  2013. hr = OpenAdminBaseKey(
  2014. localCred,
  2015. _pszServerName,
  2016. SCHEMA_PROP_METABASE_PATH,
  2017. METADATA_PERMISSION_READ,
  2018. &_pAdminBase,
  2019. &hObjHandle
  2020. );
  2021. if( SUCCEEDED(hr) )
  2022. {
  2023. METADATA_RECORD mdr;
  2024. WCHAR wcsPropertyName[MAX_PATH + 1];
  2025. DWORD cb;
  2026. MD_SET_DATA_RECORD( &mdr,
  2027. MetaId,
  2028. METADATA_NO_ATTRIBUTES,
  2029. IIS_MD_UT_SERVER,
  2030. STRING_METADATA,
  2031. sizeof(wcsPropertyName),
  2032. (unsigned char *)wcsPropertyName
  2033. );
  2034. hr = _pAdminBase->GetData( hObjHandle, L"Names", &mdr, &cb );
  2035. if( MD_ERROR_DATA_NOT_FOUND == hr )
  2036. {
  2037. fRet = TRUE;
  2038. }
  2039. CloseAdminBaseKey(_pAdminBase, hObjHandle);
  2040. }
  2041. return fRet;
  2042. }
  2043. /******************************************************************/
  2044. /* Class CIISSyntax
  2045. /******************************************************************/
  2046. DEFINE_IDispatch_Implementation(CIISSyntax)
  2047. DEFINE_IADs_Implementation(CIISSyntax)
  2048. DEFINE_IADs_PutGetUnImplementation(CIISSyntax)
  2049. CIISSyntax::CIISSyntax() : _pSchema(NULL),
  2050. _pDispMgr(NULL)
  2051. {
  2052. ENLIST_TRACKING(CIISSyntax);
  2053. }
  2054. CIISSyntax::~CIISSyntax()
  2055. {
  2056. delete _pDispMgr;
  2057. }
  2058. HRESULT
  2059. CIISSyntax::CreateSyntax(
  2060. BSTR bstrParent,
  2061. SYNTAXINFO *pSyntaxInfo,
  2062. DWORD dwObjectState,
  2063. REFIID riid,
  2064. void **ppvObj
  2065. )
  2066. {
  2067. CIISSyntax FAR *pSyntax = NULL;
  2068. HRESULT hr = S_OK;
  2069. hr = AllocateSyntaxObject( &pSyntax );
  2070. BAIL_ON_FAILURE(hr);
  2071. hr = pSyntax->InitializeCoreObject(
  2072. bstrParent,
  2073. pSyntaxInfo->bstrName,
  2074. SYNTAX_CLASS_NAME,
  2075. NO_SCHEMA,
  2076. CLSID_IISSyntax,
  2077. dwObjectState );
  2078. BAIL_ON_FAILURE(hr);
  2079. pSyntax->_lOleAutoDataType = pSyntaxInfo->lOleAutoDataType;
  2080. hr = pSyntax->QueryInterface( riid, ppvObj );
  2081. BAIL_ON_FAILURE(hr);
  2082. pSyntax->Release();
  2083. RRETURN(hr);
  2084. error:
  2085. delete pSyntax;
  2086. RRETURN(hr);
  2087. }
  2088. STDMETHODIMP
  2089. CIISSyntax::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  2090. {
  2091. if (IsEqualIID(iid, IID_IUnknown))
  2092. {
  2093. *ppv = (IADs FAR *) this;
  2094. }
  2095. else if (IsEqualIID(iid, IID_IDispatch))
  2096. {
  2097. *ppv = (IADs FAR *) this;
  2098. }
  2099. else if (IsEqualIID(iid, IID_IADs))
  2100. {
  2101. *ppv = (IADs FAR *) this;
  2102. }
  2103. else if (IsEqualIID(iid, IID_IADsSyntax))
  2104. {
  2105. *ppv = (IADsSyntax FAR *) this;
  2106. }
  2107. else
  2108. {
  2109. *ppv = NULL;
  2110. return E_NOINTERFACE;
  2111. }
  2112. AddRef();
  2113. return NOERROR;
  2114. }
  2115. /* IADs methods */
  2116. STDMETHODIMP
  2117. CIISSyntax::SetInfo(THIS)
  2118. {
  2119. RRETURN(E_NOTIMPL);
  2120. }
  2121. STDMETHODIMP
  2122. CIISSyntax::GetInfo(THIS)
  2123. {
  2124. RRETURN(S_OK);
  2125. }
  2126. HRESULT
  2127. CIISSyntax::AllocateSyntaxObject(CIISSyntax FAR * FAR * ppSyntax)
  2128. {
  2129. CIISSyntax FAR *pSyntax = NULL;
  2130. CAggregatorDispMgr FAR *pDispMgr = NULL;
  2131. HRESULT hr = S_OK;
  2132. pSyntax = new CIISSyntax();
  2133. if ( pSyntax == NULL )
  2134. hr = E_OUTOFMEMORY;
  2135. BAIL_ON_FAILURE(hr);
  2136. pDispMgr = new CAggregatorDispMgr;
  2137. if ( pDispMgr == NULL )
  2138. {
  2139. hr = E_OUTOFMEMORY;
  2140. if (pSyntax)
  2141. {
  2142. delete pSyntax;
  2143. }
  2144. }
  2145. BAIL_ON_FAILURE(hr);
  2146. hr = pDispMgr->LoadTypeInfoEntry(
  2147. LIBID_ADs,
  2148. IID_IADsSyntax,
  2149. (IADsSyntax *) pSyntax,
  2150. DISPID_REGULAR );
  2151. BAIL_ON_FAILURE(hr);
  2152. pSyntax->_pDispMgr = pDispMgr;
  2153. *ppSyntax = pSyntax;
  2154. RRETURN(hr);
  2155. error:
  2156. delete pDispMgr;
  2157. delete pSyntax;
  2158. RRETURN(hr);
  2159. }
  2160. STDMETHODIMP
  2161. CIISSyntax::get_OleAutoDataType( THIS_ long FAR *plOleAutoDataType )
  2162. {
  2163. if ( !plOleAutoDataType )
  2164. RRETURN(E_ADS_BAD_PARAMETER);
  2165. *plOleAutoDataType = _lOleAutoDataType;
  2166. RRETURN(S_OK);
  2167. }
  2168. STDMETHODIMP
  2169. CIISSyntax::put_OleAutoDataType( THIS_ long lOleAutoDataType )
  2170. {
  2171. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  2172. }
  2173. /******************************************************************/
  2174. /* Misc Helpers
  2175. /******************************************************************/
  2176. HRESULT
  2177. MakeVariantFromStringList(
  2178. BSTR bstrList,
  2179. VARIANT *pvVariant
  2180. )
  2181. {
  2182. HRESULT hr = S_OK;
  2183. SAFEARRAY *aList = NULL;
  2184. SAFEARRAYBOUND aBound;
  2185. BSTR pszTempList = NULL;
  2186. if ( bstrList != NULL )
  2187. {
  2188. // If bstrList is not null, then there we consider there
  2189. // to be one element
  2190. long nCount = 1;
  2191. long i = 0;
  2192. TCHAR c;
  2193. BSTR pszSrc;
  2194. hr = ADsAllocString( bstrList, &pszTempList );
  2195. BAIL_ON_FAILURE(hr);
  2196. c = pszTempList[i];
  2197. while ( c )
  2198. {
  2199. if ( c == TEXT(','))
  2200. {
  2201. pszTempList[i] = 0;
  2202. nCount++;
  2203. }
  2204. i++;
  2205. c = pszTempList[i];
  2206. }
  2207. aBound.lLbound = 0;
  2208. aBound.cElements = nCount;
  2209. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  2210. if ( aList == NULL )
  2211. {
  2212. hr = E_OUTOFMEMORY;
  2213. BAIL_ON_FAILURE(hr);
  2214. }
  2215. pszSrc = pszTempList;
  2216. for ( i = 0; i < nCount; i++ )
  2217. {
  2218. VARIANT v;
  2219. VariantInit(&v);
  2220. V_VT(&v) = VT_BSTR;
  2221. hr = ADsAllocString( pszSrc, &(V_BSTR(&v)));
  2222. BAIL_ON_FAILURE(hr);
  2223. hr = SafeArrayPutElement( aList,
  2224. &i,
  2225. &v );
  2226. VariantClear(&v);
  2227. BAIL_ON_FAILURE(hr);
  2228. pszSrc += _tcslen( pszSrc ) + 1;
  2229. }
  2230. VariantInit( pvVariant );
  2231. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  2232. V_ARRAY(pvVariant) = aList;
  2233. ADsFreeString( pszTempList );
  2234. pszTempList = NULL;
  2235. }
  2236. else
  2237. {
  2238. aBound.lLbound = 0;
  2239. aBound.cElements = 0;
  2240. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  2241. if ( aList == NULL )
  2242. {
  2243. hr = E_OUTOFMEMORY;
  2244. BAIL_ON_FAILURE(hr);
  2245. }
  2246. VariantInit( pvVariant );
  2247. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  2248. V_ARRAY(pvVariant) = aList;
  2249. }
  2250. RRETURN(S_OK);
  2251. error:
  2252. if ( pszTempList )
  2253. ADsFreeString( pszTempList );
  2254. if ( aList )
  2255. SafeArrayDestroy( aList );
  2256. RRETURN(hr);
  2257. }
  2258. HRESULT
  2259. ValidateClassObjProps(
  2260. LPWSTR pszName,
  2261. PDWORD pdwSyntax,
  2262. PDWORD pdwID
  2263. )
  2264. {
  2265. DWORD i;
  2266. //
  2267. // Look for the given syntax name
  2268. //
  2269. for ( i = 0; i < g_cClassObjProps; i++ )
  2270. {
  2271. if ( _wcsicmp( g_pClassObjProps[i].szObjectName, pszName) == 0 ) {
  2272. *pdwSyntax = g_pClassObjProps[i].dwSyntaxId;
  2273. *pdwID = g_pClassObjProps[i].dwID;
  2274. RRETURN(S_OK);
  2275. }
  2276. }
  2277. RRETURN(E_ADS_BAD_PARAMETER);
  2278. }
  2279. HRESULT
  2280. ValidatePropertyObjProps(
  2281. LPWSTR pszName,
  2282. PDWORD pdwSyntax,
  2283. PDWORD pdwID
  2284. )
  2285. {
  2286. DWORD i;
  2287. //
  2288. // Look for the given syntax name
  2289. //
  2290. for ( i = 0; i < g_cPropertyObjProps; i++ )
  2291. {
  2292. if ( _wcsicmp( g_pPropertyObjProps[i].szObjectName, pszName) == 0 ) {
  2293. *pdwSyntax = g_pPropertyObjProps[i].dwSyntaxId;
  2294. *pdwID = g_pPropertyObjProps[i].dwID;
  2295. RRETURN(S_OK);
  2296. }
  2297. }
  2298. RRETURN(E_ADS_BAD_PARAMETER);
  2299. }
  2300. HRESULT
  2301. IISMarshallClassProperties(
  2302. CLASSINFO *pClassInfo,
  2303. PMETADATA_RECORD * ppMetaDataRecords,
  2304. PDWORD pdwMDNumDataEntries
  2305. )
  2306. {
  2307. HRESULT hr = S_OK;
  2308. PMETADATA_RECORD pMetaDataArray = NULL;
  2309. static BOOL bTemp = FALSE;
  2310. //
  2311. // set to 4 because we're supporting 4 properties only
  2312. //
  2313. *pdwMDNumDataEntries = 4;
  2314. pMetaDataArray = (PMETADATA_RECORD) AllocADsMem(
  2315. *pdwMDNumDataEntries * sizeof(METADATA_RECORD));
  2316. if (!pMetaDataArray ) {
  2317. hr = E_OUTOFMEMORY;
  2318. BAIL_ON_FAILURE(hr);
  2319. }
  2320. *ppMetaDataRecords = pMetaDataArray;
  2321. //
  2322. // setting Containment and Container property for classes
  2323. //
  2324. pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINER;
  2325. pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES;
  2326. pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER;
  2327. pMetaDataArray->dwMDDataType = DWORD_METADATA;
  2328. pMetaDataArray->dwMDDataLen = sizeof(DWORD);
  2329. if (pClassInfo) {
  2330. pMetaDataArray->pbMDData = (unsigned char*)&(pClassInfo->fContainer);
  2331. }
  2332. else {
  2333. pMetaDataArray->pbMDData = (BYTE*)&bTemp;
  2334. }
  2335. pMetaDataArray++;
  2336. pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINMENT;
  2337. pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES;
  2338. pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER;
  2339. pMetaDataArray->dwMDDataType = STRING_METADATA;
  2340. if (pClassInfo && pClassInfo->bstrContainment) {
  2341. pMetaDataArray->dwMDDataLen = ((DWORD)wcslen((LPWSTR)pClassInfo->bstrContainment)+ 1)*2;
  2342. pMetaDataArray->pbMDData = (unsigned char *)pClassInfo->bstrContainment;
  2343. }
  2344. else {
  2345. pMetaDataArray->dwMDDataLen = 0;
  2346. pMetaDataArray->pbMDData = NULL;
  2347. }
  2348. pMetaDataArray++;
  2349. //
  2350. // setting Optional and Mandatory Properties
  2351. //
  2352. pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_MAND_PROPERTIES;
  2353. pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES;
  2354. pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER;
  2355. pMetaDataArray->dwMDDataType = STRING_METADATA;
  2356. if (pClassInfo && pClassInfo->bstrMandatoryProperties) {
  2357. pMetaDataArray->dwMDDataLen = ((DWORD)wcslen((LPWSTR)pClassInfo->bstrMandatoryProperties)+1)*2;
  2358. pMetaDataArray->pbMDData = (unsigned char *)pClassInfo->bstrMandatoryProperties;
  2359. }
  2360. else {
  2361. pMetaDataArray->dwMDDataLen = 0;
  2362. pMetaDataArray->pbMDData = NULL;
  2363. }
  2364. pMetaDataArray++;
  2365. pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_OPT_PROPERTIES;
  2366. pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES;
  2367. pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER;
  2368. pMetaDataArray->dwMDDataType = STRING_METADATA;
  2369. if (pClassInfo && pClassInfo->bstrOptionalProperties) {
  2370. pMetaDataArray->dwMDDataLen = ((DWORD)wcslen((LPWSTR)pClassInfo->bstrOptionalProperties)+1)*2;
  2371. pMetaDataArray->pbMDData = (unsigned char *)pClassInfo->bstrOptionalProperties;
  2372. }
  2373. else {
  2374. pMetaDataArray->dwMDDataLen = 0;
  2375. pMetaDataArray->pbMDData = NULL;
  2376. }
  2377. error:
  2378. RRETURN(hr);
  2379. }
  2380. HRESULT
  2381. GenerateNewMetaID(
  2382. LPWSTR pszServerName,
  2383. IMSAdminBase *pAdminBase,
  2384. PDWORD pdwMetaID
  2385. )
  2386. {
  2387. HRESULT hr = S_OK;
  2388. DWORD dwMetaId = 0;
  2389. METADATA_HANDLE hObjHandle = NULL;
  2390. DWORD dwBufferSize = sizeof(DWORD);
  2391. METADATA_RECORD mdrMDData;
  2392. CCredentials localCred;
  2393. LPBYTE pBuffer = (LPBYTE)&dwMetaId;
  2394. hr = OpenAdminBaseKey(
  2395. localCred,
  2396. pszServerName,
  2397. IIS_MD_ADSI_SCHEMA_PATH_W,
  2398. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  2399. &pAdminBase,
  2400. &hObjHandle
  2401. );
  2402. BAIL_ON_FAILURE(hr);
  2403. MD_SET_DATA_RECORD(&mdrMDData,
  2404. MD_SCHEMA_METAID,
  2405. METADATA_NO_ATTRIBUTES,
  2406. IIS_MD_UT_SERVER,
  2407. DWORD_METADATA,
  2408. dwBufferSize,
  2409. pBuffer);
  2410. hr = pAdminBase->GetData(
  2411. hObjHandle,
  2412. L"",
  2413. &mdrMDData,
  2414. &dwBufferSize
  2415. );
  2416. BAIL_ON_FAILURE(hr);
  2417. *pdwMetaID = dwMetaId;
  2418. //
  2419. // increment metaid by 1 for next property
  2420. //
  2421. dwMetaId++;
  2422. hr = pAdminBase->SetData(
  2423. hObjHandle,
  2424. L"",
  2425. &mdrMDData
  2426. );
  2427. BAIL_ON_FAILURE(hr);
  2428. error:
  2429. if (hObjHandle) {
  2430. CloseAdminBaseKey(pAdminBase, hObjHandle);
  2431. }
  2432. RRETURN(hr);
  2433. }
  2434. HRESULT
  2435. CheckDuplicateNames(
  2436. LPWSTR pszNames
  2437. )
  2438. {
  2439. WCHAR szName[MAX_PATH];
  2440. WCHAR szName2[MAX_PATH];
  2441. LPWSTR ObjectList = (LPWSTR)pszNames;
  2442. LPWSTR CheckList = (LPWSTR)pszNames;
  2443. DWORD dwCount = 0;
  2444. if (ObjectList == NULL ||
  2445. (ObjectList != NULL && *ObjectList == NULL)) {
  2446. RRETURN(S_OK);
  2447. }
  2448. while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
  2449. if (*szName != L'\0') {
  2450. CheckList = pszNames;
  2451. while ((CheckList = grabProp(szName2, CheckList)) != NULL) {
  2452. if (*szName2 != L'\0') {
  2453. if (!_wcsicmp(szName, szName2)) {
  2454. dwCount++;
  2455. }
  2456. }
  2457. }
  2458. if (dwCount > 1) {
  2459. RRETURN(E_ADS_BAD_PARAMETER);
  2460. }
  2461. dwCount = 0;
  2462. }
  2463. }
  2464. RRETURN(S_OK);
  2465. }