Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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