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.

1998 lines
46 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996
  5. //
  6. // File: cschema.cxx
  7. //
  8. // Contents: Windows NT 3.51
  9. //
  10. //
  11. // History: 01-09-96 yihsins Created.
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "winnt.hxx"
  15. #pragma hdrstop
  16. /******************************************************************/
  17. /* Class CWinNTSchema
  18. /******************************************************************/
  19. DEFINE_IDispatch_Delegating_Implementation(CWinNTSchema)
  20. DEFINE_IADsExtension_Implementation(CWinNTSchema)
  21. DEFINE_IADs_Implementation(CWinNTSchema)
  22. CWinNTSchema::CWinNTSchema()
  23. {
  24. VariantInit( &_vFilter );
  25. ENLIST_TRACKING(CWinNTSchema);
  26. }
  27. CWinNTSchema::~CWinNTSchema()
  28. {
  29. VariantClear( &_vFilter );
  30. delete _pDispMgr;
  31. }
  32. HRESULT
  33. CWinNTSchema::CreateSchema(
  34. BSTR bstrParent,
  35. BSTR bstrName,
  36. DWORD dwObjectState,
  37. REFIID riid,
  38. CWinNTCredentials& Credentials,
  39. void **ppvObj
  40. )
  41. {
  42. CWinNTSchema FAR *pSchema = NULL;
  43. HRESULT hr = S_OK;
  44. hr = AllocateSchemaObject( &pSchema );
  45. BAIL_ON_FAILURE(hr);
  46. hr = pSchema->InitializeCoreObject(
  47. bstrParent,
  48. bstrName,
  49. SCHEMA_CLASS_NAME,
  50. NO_SCHEMA,
  51. CLSID_WinNTSchema,
  52. dwObjectState );
  53. BAIL_ON_FAILURE(hr);
  54. pSchema->_Credentials = Credentials;
  55. // check if the call is from UMI
  56. if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
  57. //
  58. // we do not pass riid to InitUmiObject below. This is because UMI object
  59. // does not support IDispatch. There are several places in ADSI code where
  60. // riid passed into this function is defaulted to IID_IDispatch -
  61. // IADsContainer::Create for example. To handle these cases, we always
  62. // request IID_IUnknown from the UMI object. Subsequent code within UMI
  63. // will QI for the appropriate interface.
  64. //
  65. if(2 == pSchema->_dwNumComponents) {
  66. pSchema->_CompClasses[0] = L"Computer";
  67. pSchema->_CompClasses[1] = L"Schema";
  68. }
  69. else
  70. BAIL_ON_FAILURE(hr = UMI_E_FAIL);
  71. hr = pSchema->InitUmiObject(
  72. pSchema->_Credentials,
  73. SchemaClass,
  74. g_dwSchemaClassTableSize,
  75. NULL,
  76. (IUnknown *) (INonDelegatingUnknown *) pSchema,
  77. NULL,
  78. IID_IUnknown,
  79. ppvObj
  80. );
  81. BAIL_ON_FAILURE(hr);
  82. //
  83. // UMI object was created and the interface was obtained successfully.
  84. // UMI object now has a reference to the inner unknown of IADs, since
  85. // the call to Release() below is not going to be made in this case.
  86. //
  87. RRETURN(hr);
  88. }
  89. hr = pSchema->QueryInterface( riid, ppvObj );
  90. BAIL_ON_FAILURE(hr);
  91. pSchema->Release();
  92. RRETURN(hr);
  93. error:
  94. delete pSchema;
  95. RRETURN_EXP_IF_ERR(hr);
  96. }
  97. //----------------------------------------------------------------------------
  98. // Function: QueryInterface
  99. //
  100. // Synopsis: If this object is aggregated within another object, then
  101. // all calls will delegate to the outer object. Otherwise, the
  102. // non-delegating QI is called
  103. //
  104. // Arguments:
  105. //
  106. // iid interface requested
  107. // ppInterface Returns pointer to interface requested. NULL if interface
  108. // is not supported.
  109. //
  110. // Returns: S_OK on success. Error code otherwise.
  111. //
  112. // Modifies: *ppInterface to return interface pointer
  113. //
  114. //----------------------------------------------------------------------------
  115. STDMETHODIMP CWinNTSchema::QueryInterface(
  116. REFIID iid,
  117. LPVOID *ppInterface
  118. )
  119. {
  120. if(_pUnkOuter != NULL)
  121. RRETURN(_pUnkOuter->QueryInterface(
  122. iid,
  123. ppInterface
  124. ));
  125. RRETURN(NonDelegatingQueryInterface(
  126. iid,
  127. ppInterface
  128. ));
  129. }
  130. //----------------------------------------------------------------------------
  131. // Function: AddRef
  132. //
  133. // Synopsis: IUnknown::AddRef. If this object is aggregated within
  134. // another, all calls will delegate to the outer object.
  135. // Otherwise, the non-delegating AddRef is called
  136. //
  137. // Arguments:
  138. //
  139. // None
  140. //
  141. // Returns: New reference count
  142. //
  143. // Modifies: Nothing
  144. //
  145. //----------------------------------------------------------------------------
  146. STDMETHODIMP_(ULONG) CWinNTSchema::AddRef(void)
  147. {
  148. if(_pUnkOuter != NULL)
  149. RRETURN(_pUnkOuter->AddRef());
  150. RRETURN(NonDelegatingAddRef());
  151. }
  152. //----------------------------------------------------------------------------
  153. // Function: Release
  154. //
  155. // Synopsis: IUnknown::Release. If this object is aggregated within
  156. // another, all calls will delegate to the outer object.
  157. // Otherwise, the non-delegating Release is called
  158. //
  159. // Arguments:
  160. //
  161. // None
  162. //
  163. // Returns: New reference count
  164. //
  165. // Modifies: Nothing
  166. //
  167. //----------------------------------------------------------------------------
  168. STDMETHODIMP_(ULONG) CWinNTSchema::Release(void)
  169. {
  170. if(_pUnkOuter != NULL)
  171. RRETURN(_pUnkOuter->Release());
  172. RRETURN(NonDelegatingRelease());
  173. }
  174. //----------------------------------------------------------------------------
  175. STDMETHODIMP
  176. CWinNTSchema::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
  177. {
  178. if (ppv == NULL) {
  179. RRETURN(E_POINTER);
  180. }
  181. if (IsEqualIID(iid, IID_IUnknown))
  182. {
  183. *ppv = (IADs FAR *) this;
  184. }
  185. else if (IsEqualIID(iid, IID_IDispatch))
  186. {
  187. *ppv = (IADs FAR *)this;
  188. }
  189. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  190. {
  191. *ppv = (ISupportErrorInfo FAR *)this;
  192. }
  193. else if (IsEqualIID(iid, IID_IADs))
  194. {
  195. *ppv = (IADs FAR *) this;
  196. }
  197. else if (IsEqualIID(iid, IID_IADsContainer))
  198. {
  199. *ppv = (IADsContainer FAR *) this;
  200. }
  201. else if( (_pDispatch != NULL) &&
  202. IsEqualIID(iid, IID_IADsExtension) )
  203. {
  204. *ppv = (IADsExtension *) this;
  205. }
  206. else
  207. {
  208. *ppv = NULL;
  209. return E_NOINTERFACE;
  210. }
  211. AddRef();
  212. return NOERROR;
  213. }
  214. /* ISupportErrorInfo method */
  215. STDMETHODIMP
  216. CWinNTSchema::InterfaceSupportsErrorInfo(
  217. THIS_ REFIID riid
  218. )
  219. {
  220. if (IsEqualIID(riid, IID_IADs) ||
  221. IsEqualIID(riid, IID_IADsContainer)) {
  222. RRETURN(S_OK);
  223. } else {
  224. RRETURN(S_FALSE);
  225. }
  226. }
  227. /* IADs methods */
  228. STDMETHODIMP
  229. CWinNTSchema::SetInfo(THIS)
  230. {
  231. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  232. }
  233. STDMETHODIMP
  234. CWinNTSchema::GetInfo(THIS)
  235. {
  236. RRETURN(S_OK);
  237. }
  238. STDMETHODIMP
  239. CWinNTSchema::ImplicitGetInfo(THIS)
  240. {
  241. RRETURN(S_OK);
  242. }
  243. /* IADsContainer methods */
  244. STDMETHODIMP
  245. CWinNTSchema::get_Count(long FAR* retval)
  246. {
  247. HRESULT hr;
  248. if ( !retval )
  249. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  250. *retval = g_cWinNTClasses + g_cWinNTSyntax;
  251. RRETURN(S_OK);
  252. }
  253. STDMETHODIMP
  254. CWinNTSchema::get_Filter(THIS_ VARIANT FAR* pVar)
  255. {
  256. HRESULT hr;
  257. if ( !pVar )
  258. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  259. VariantInit( pVar );
  260. hr = VariantCopy( pVar, &_vFilter );
  261. RRETURN_EXP_IF_ERR(hr);
  262. }
  263. STDMETHODIMP
  264. CWinNTSchema::put_Filter(THIS_ VARIANT Var)
  265. {
  266. HRESULT hr;
  267. hr = VariantCopy( &_vFilter, &Var );
  268. RRETURN_EXP_IF_ERR(hr);
  269. }
  270. STDMETHODIMP
  271. CWinNTSchema::get_Hints(THIS_ VARIANT FAR* pVar)
  272. {
  273. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  274. }
  275. STDMETHODIMP
  276. CWinNTSchema::put_Hints(THIS_ VARIANT Var)
  277. {
  278. RRETURN_EXP_IF_ERR( E_NOTIMPL);
  279. }
  280. STDMETHODIMP
  281. CWinNTSchema::GetObject(
  282. THIS_ BSTR ClassName,
  283. BSTR RelativeName,
  284. IDispatch * FAR* ppObject)
  285. {
  286. TCHAR szBuffer[MAX_PATH];
  287. DWORD dwLength = 0;
  288. HRESULT hr = S_OK;
  289. if (!RelativeName || !*RelativeName) {
  290. RRETURN_EXP_IF_ERR(E_ADS_UNKNOWN_OBJECT);
  291. }
  292. //
  293. // Make sure we are not going to overflow the string buffer.
  294. // +2 for / and \0
  295. //
  296. dwLength = wcslen(_ADsPath) + wcslen(RelativeName) + 2;
  297. if (dwLength > MAX_PATH) {
  298. BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER);
  299. }
  300. wcscpy(szBuffer, _ADsPath);
  301. wcscat(szBuffer, L"/");
  302. wcscat(szBuffer, RelativeName);
  303. if (ClassName) {
  304. //
  305. // +1 for the ",".
  306. //
  307. dwLength += wcslen(ClassName) + 1;
  308. if (dwLength > MAX_PATH) {
  309. BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER);
  310. }
  311. wcscat(szBuffer,L",");
  312. wcscat(szBuffer, ClassName);
  313. }
  314. hr = ::GetObject(szBuffer, (LPVOID *)ppObject, _Credentials);
  315. BAIL_ON_FAILURE(hr);
  316. error:
  317. RRETURN_EXP_IF_ERR(hr);
  318. }
  319. STDMETHODIMP
  320. CWinNTSchema::get__NewEnum(THIS_ IUnknown * FAR* retval)
  321. {
  322. HRESULT hr;
  323. IEnumVARIANT *penum = NULL;
  324. if ( !retval )
  325. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  326. *retval = NULL;
  327. //
  328. // Create new enumerator for items currently
  329. // in collection and QI for IUnknown
  330. //
  331. hr = CWinNTSchemaEnum::Create( (CWinNTSchemaEnum **)&penum,
  332. _ADsPath,
  333. _Name,
  334. _vFilter,
  335. _Credentials);
  336. BAIL_ON_FAILURE(hr);
  337. hr = penum->QueryInterface( IID_IUnknown, (VOID FAR* FAR*)retval );
  338. BAIL_ON_FAILURE(hr);
  339. if ( penum )
  340. penum->Release();
  341. RRETURN(hr);
  342. error:
  343. if ( penum )
  344. delete penum;
  345. RRETURN_EXP_IF_ERR(hr);
  346. }
  347. STDMETHODIMP
  348. CWinNTSchema::Create(
  349. THIS_ BSTR ClassName,
  350. BSTR RelativeName,
  351. IDispatch * FAR* ppObject)
  352. {
  353. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  354. }
  355. STDMETHODIMP
  356. CWinNTSchema::Delete(THIS_ BSTR SourceName, BSTR Type)
  357. {
  358. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  359. }
  360. STDMETHODIMP
  361. CWinNTSchema::CopyHere(THIS_ BSTR SourceName,
  362. BSTR NewName,
  363. IDispatch * FAR* ppObject)
  364. {
  365. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  366. }
  367. STDMETHODIMP
  368. CWinNTSchema::MoveHere(THIS_ BSTR SourceName,
  369. BSTR NewName,
  370. IDispatch * FAR* ppObject)
  371. {
  372. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  373. }
  374. HRESULT
  375. CWinNTSchema::AllocateSchemaObject(CWinNTSchema FAR * FAR * ppSchema)
  376. {
  377. CWinNTSchema FAR *pSchema = NULL;
  378. CAggregatorDispMgr FAR *pDispMgr = NULL;
  379. HRESULT hr = S_OK;
  380. pSchema = new CWinNTSchema();
  381. if ( pSchema == NULL )
  382. hr = E_OUTOFMEMORY;
  383. BAIL_ON_FAILURE(hr);
  384. pDispMgr = new CAggregatorDispMgr;
  385. if ( pDispMgr == NULL )
  386. hr = E_OUTOFMEMORY;
  387. BAIL_ON_FAILURE(hr);
  388. hr = LoadTypeInfoEntry( pDispMgr,
  389. LIBID_ADs,
  390. IID_IADs,
  391. (IADs *) pSchema,
  392. DISPID_REGULAR );
  393. BAIL_ON_FAILURE(hr);
  394. hr = LoadTypeInfoEntry( pDispMgr,
  395. LIBID_ADs,
  396. IID_IADsContainer,
  397. (IADsContainer *) pSchema,
  398. DISPID_NEWENUM );
  399. BAIL_ON_FAILURE(hr);
  400. pSchema->_pDispMgr = pDispMgr;
  401. *ppSchema = pSchema;
  402. RRETURN(hr);
  403. error:
  404. delete pDispMgr;
  405. delete pSchema;
  406. RRETURN_EXP_IF_ERR(hr);
  407. }
  408. /******************************************************************/
  409. /* Class CWinNTClass
  410. /******************************************************************/
  411. DEFINE_IDispatch_Delegating_Implementation(CWinNTClass)
  412. DEFINE_IADsExtension_Implementation(CWinNTClass)
  413. DEFINE_IADs_Implementation(CWinNTClass)
  414. CWinNTClass::CWinNTClass()
  415. : _pDispMgr( NULL ),
  416. _aPropertyInfo( NULL ),
  417. _cPropertyInfo( 0 ),
  418. _bstrCLSID( NULL ),
  419. _bstrOID( NULL ),
  420. _bstrPrimaryInterface( NULL ),
  421. _fAbstract( FALSE ),
  422. _fContainer( FALSE ),
  423. _bstrHelpFileName( NULL ),
  424. _lHelpFileContext( 0 )
  425. {
  426. VariantInit( &_vMandatoryProperties );
  427. VariantInit( &_vOptionalProperties );
  428. VariantInit( &_vPossSuperiors );
  429. VariantInit( &_vContainment );
  430. VariantInit( &_vFilter );
  431. ENLIST_TRACKING(CWinNTClass);
  432. }
  433. CWinNTClass::~CWinNTClass()
  434. {
  435. if ( _bstrCLSID ) {
  436. ADsFreeString( _bstrCLSID );
  437. }
  438. if ( _bstrOID ) {
  439. ADsFreeString( _bstrOID );
  440. }
  441. if ( _bstrPrimaryInterface ) {
  442. ADsFreeString( _bstrPrimaryInterface );
  443. }
  444. if ( _bstrHelpFileName ) {
  445. ADsFreeString( _bstrHelpFileName );
  446. }
  447. VariantClear( &_vMandatoryProperties );
  448. VariantClear( &_vOptionalProperties );
  449. VariantClear( &_vPossSuperiors );
  450. VariantClear( &_vContainment );
  451. VariantClear( &_vFilter );
  452. delete _pDispMgr;
  453. }
  454. HRESULT
  455. CWinNTClass::CreateClass(
  456. BSTR bstrParent,
  457. CLASSINFO *pClassInfo,
  458. DWORD dwObjectState,
  459. REFIID riid,
  460. CWinNTCredentials& Credentials,
  461. void **ppvObj
  462. )
  463. {
  464. CWinNTClass FAR *pClass = NULL;
  465. HRESULT hr = S_OK;
  466. BSTR bstrTmp = NULL;
  467. hr = AllocateClassObject( &pClass );
  468. BAIL_ON_FAILURE(hr);
  469. pClass->_aPropertyInfo = pClassInfo->aPropertyInfo;
  470. pClass->_cPropertyInfo = pClassInfo->cPropertyInfo;
  471. pClass->_lHelpFileContext = pClassInfo->lHelpFileContext;
  472. pClass->_fContainer = (VARIANT_BOOL)pClassInfo->fContainer;
  473. pClass->_fAbstract = (VARIANT_BOOL)pClassInfo->fAbstract;
  474. hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pPrimaryInterfaceGUID),
  475. &bstrTmp );
  476. BAIL_ON_FAILURE(hr);
  477. hr = ADsAllocString( bstrTmp,
  478. &pClass->_bstrPrimaryInterface);
  479. BAIL_ON_FAILURE(hr);
  480. CoTaskMemFree(bstrTmp);
  481. bstrTmp = NULL;
  482. hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pCLSID),
  483. &bstrTmp );
  484. BAIL_ON_FAILURE(hr);
  485. hr = ADsAllocString( bstrTmp,
  486. &pClass->_bstrCLSID );
  487. BAIL_ON_FAILURE(hr);
  488. CoTaskMemFree(bstrTmp);
  489. bstrTmp = NULL;
  490. hr = ADsAllocString( pClassInfo->bstrOID, &pClass->_bstrOID);
  491. BAIL_ON_FAILURE(hr);
  492. hr = MakeVariantFromStringList( pClassInfo->bstrMandatoryProperties,
  493. &(pClass->_vMandatoryProperties));
  494. BAIL_ON_FAILURE(hr);
  495. hr = MakeVariantFromStringList( pClassInfo->bstrOptionalProperties,
  496. &(pClass->_vOptionalProperties));
  497. BAIL_ON_FAILURE(hr);
  498. hr = MakeVariantFromStringList( pClassInfo->bstrPossSuperiors,
  499. &(pClass->_vPossSuperiors));
  500. BAIL_ON_FAILURE(hr);
  501. hr = MakeVariantFromStringList( pClassInfo->bstrContainment,
  502. &(pClass->_vContainment));
  503. BAIL_ON_FAILURE(hr);
  504. hr = ADsAllocString( pClassInfo->bstrHelpFileName,
  505. &pClass->_bstrHelpFileName);
  506. BAIL_ON_FAILURE(hr);
  507. hr = pClass->InitializeCoreObject(
  508. bstrParent,
  509. pClassInfo->bstrName,
  510. CLASS_CLASS_NAME,
  511. NO_SCHEMA,
  512. CLSID_WinNTClass,
  513. dwObjectState );
  514. BAIL_ON_FAILURE(hr);
  515. pClass->_Credentials = Credentials;
  516. // check if the call is from UMI
  517. if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
  518. //
  519. // we do not pass riid to InitUmiObject below. This is because UMI object
  520. // does not support IDispatch. There are several places in ADSI code where
  521. // riid passed into this function is defaulted to IID_IDispatch -
  522. // IADsContainer::Create for example. To handle these cases, we always
  523. // request IID_IUnknown from the UMI object. Subsequent code within UMI
  524. // will QI for the appropriate interface.
  525. //
  526. if(3 == pClass->_dwNumComponents) {
  527. pClass->_CompClasses[0] = L"Computer";
  528. pClass->_CompClasses[1] = L"Schema";
  529. pClass->_CompClasses[2] = L"Class";
  530. }
  531. else
  532. BAIL_ON_FAILURE(hr = UMI_E_FAIL);
  533. hr = pClass->InitUmiObject(
  534. pClass->_Credentials,
  535. SchClassClass,
  536. g_dwSchClassClassTableSize,
  537. NULL,
  538. (IUnknown *)(INonDelegatingUnknown *) pClass,
  539. NULL,
  540. IID_IUnknown,
  541. ppvObj,
  542. pClassInfo
  543. );
  544. BAIL_ON_FAILURE(hr);
  545. //
  546. // UMI object was created and the interface was obtained successfully.
  547. // UMI object now has a reference to the inner unknown of IADs, since
  548. // the call to Release() below is not going to be made in this case.
  549. //
  550. RRETURN(hr);
  551. }
  552. hr = pClass->QueryInterface( riid, ppvObj );
  553. BAIL_ON_FAILURE(hr);
  554. pClass->Release();
  555. RRETURN(hr);
  556. error:
  557. if ( bstrTmp != NULL )
  558. CoTaskMemFree(bstrTmp);
  559. delete pClass;
  560. RRETURN_EXP_IF_ERR(hr);
  561. }
  562. // called by implicit GetInfo from property cache
  563. STDMETHODIMP
  564. CWinNTClass::GetInfo(
  565. THIS_ DWORD dwApiLevel,
  566. BOOL fExplicit
  567. )
  568. {
  569. RRETURN(S_OK);
  570. }
  571. //----------------------------------------------------------------------------
  572. // Function: QueryInterface
  573. //
  574. // Synopsis: If this object is aggregated within another object, then
  575. // all calls will delegate to the outer object. Otherwise, the
  576. // non-delegating QI is called
  577. //
  578. // Arguments:
  579. //
  580. // iid interface requested
  581. // ppInterface Returns pointer to interface requested. NULL if interface
  582. // is not supported.
  583. //
  584. // Returns: S_OK on success. Error code otherwise.
  585. //
  586. // Modifies: *ppInterface to return interface pointer
  587. //
  588. //----------------------------------------------------------------------------
  589. STDMETHODIMP CWinNTClass::QueryInterface(
  590. REFIID iid,
  591. LPVOID *ppInterface
  592. )
  593. {
  594. if(_pUnkOuter != NULL)
  595. RRETURN(_pUnkOuter->QueryInterface(
  596. iid,
  597. ppInterface
  598. ));
  599. RRETURN(NonDelegatingQueryInterface(
  600. iid,
  601. ppInterface
  602. ));
  603. }
  604. //----------------------------------------------------------------------------
  605. // Function: AddRef
  606. //
  607. // Synopsis: IUnknown::AddRef. If this object is aggregated within
  608. // another, all calls will delegate to the outer object.
  609. // Otherwise, the non-delegating AddRef is called
  610. //
  611. // Arguments:
  612. //
  613. // None
  614. //
  615. // Returns: New reference count
  616. //
  617. // Modifies: Nothing
  618. //
  619. //----------------------------------------------------------------------------
  620. STDMETHODIMP_(ULONG) CWinNTClass::AddRef(void)
  621. {
  622. if(_pUnkOuter != NULL)
  623. RRETURN(_pUnkOuter->AddRef());
  624. RRETURN(NonDelegatingAddRef());
  625. }
  626. //----------------------------------------------------------------------------
  627. // Function: Release
  628. //
  629. // Synopsis: IUnknown::Release. If this object is aggregated within
  630. // another, all calls will delegate to the outer object.
  631. // Otherwise, the non-delegating Release is called
  632. //
  633. // Arguments:
  634. //
  635. // None
  636. //
  637. // Returns: New reference count
  638. //
  639. // Modifies: Nothing
  640. //
  641. //----------------------------------------------------------------------------
  642. STDMETHODIMP_(ULONG) CWinNTClass::Release(void)
  643. {
  644. if(_pUnkOuter != NULL)
  645. RRETURN(_pUnkOuter->Release());
  646. RRETURN(NonDelegatingRelease());
  647. }
  648. //----------------------------------------------------------------------------
  649. STDMETHODIMP
  650. CWinNTClass::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
  651. {
  652. if (ppv == NULL) {
  653. RRETURN(E_POINTER);
  654. }
  655. if (IsEqualIID(iid, IID_IUnknown))
  656. {
  657. *ppv = (IADsClass FAR * ) this;
  658. }
  659. else if (IsEqualIID(iid, IID_IDispatch))
  660. {
  661. *ppv = (IADs FAR *) this;
  662. }
  663. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  664. {
  665. *ppv = (ISupportErrorInfo FAR *)this;
  666. }
  667. else if (IsEqualIID(iid, IID_IADs))
  668. {
  669. *ppv = (IADs FAR *) this;
  670. }
  671. else if (IsEqualIID(iid, IID_IADsClass))
  672. {
  673. *ppv = (IADsClass FAR *) this;
  674. }
  675. else if( (_pDispatch != NULL) &&
  676. IsEqualIID(iid, IID_IADsExtension) )
  677. {
  678. *ppv = (IADsExtension *) this;
  679. }
  680. else
  681. {
  682. *ppv = NULL;
  683. return E_NOINTERFACE;
  684. }
  685. AddRef();
  686. return NOERROR;
  687. }
  688. /* ISupportErrorInfo method */
  689. STDMETHODIMP
  690. CWinNTClass::InterfaceSupportsErrorInfo(
  691. THIS_ REFIID riid
  692. )
  693. {
  694. if (IsEqualIID(riid, IID_IADs) ||
  695. IsEqualIID(riid, IID_IADsClass)) {
  696. RRETURN(S_OK);
  697. } else {
  698. RRETURN(S_FALSE);
  699. }
  700. }
  701. /* IADs methods */
  702. STDMETHODIMP
  703. CWinNTClass::SetInfo(THIS)
  704. {
  705. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  706. }
  707. STDMETHODIMP
  708. CWinNTClass::GetInfo(THIS)
  709. {
  710. RRETURN(S_OK);
  711. }
  712. STDMETHODIMP
  713. CWinNTClass::ImplicitGetInfo(THIS)
  714. {
  715. RRETURN(S_OK);
  716. }
  717. /* IADsClass methods */
  718. STDMETHODIMP
  719. CWinNTClass::get_PrimaryInterface( THIS_ BSTR FAR *pbstrGUID )
  720. {
  721. HRESULT hr;
  722. if ( !pbstrGUID )
  723. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  724. hr = ADsAllocString( _bstrPrimaryInterface, pbstrGUID );
  725. RRETURN_EXP_IF_ERR(hr);
  726. }
  727. STDMETHODIMP
  728. CWinNTClass::get_CLSID( THIS_ BSTR FAR *pbstrCLSID )
  729. {
  730. HRESULT hr;
  731. if ( !pbstrCLSID )
  732. RRETURN(E_ADS_BAD_PARAMETER);
  733. hr = ADsAllocString( _bstrCLSID, pbstrCLSID );
  734. RRETURN_EXP_IF_ERR(hr);
  735. }
  736. STDMETHODIMP
  737. CWinNTClass::put_CLSID( THIS_ BSTR bstrCLSID )
  738. {
  739. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  740. }
  741. STDMETHODIMP
  742. CWinNTClass::get_OID( THIS_ BSTR FAR *pbstrOID )
  743. {
  744. HRESULT hr;
  745. if ( !pbstrOID )
  746. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  747. hr = ADsAllocString( _bstrOID, pbstrOID );
  748. RRETURN_EXP_IF_ERR(hr);
  749. }
  750. STDMETHODIMP
  751. CWinNTClass::put_OID( THIS_ BSTR bstrOID )
  752. {
  753. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  754. }
  755. STDMETHODIMP
  756. CWinNTClass::get_Abstract( THIS_ VARIANT_BOOL FAR *pfAbstract )
  757. {
  758. if ( !pfAbstract )
  759. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  760. *pfAbstract = _fAbstract? VARIANT_TRUE : VARIANT_FALSE;
  761. RRETURN(S_OK);
  762. }
  763. STDMETHODIMP
  764. CWinNTClass::put_Abstract( THIS_ VARIANT_BOOL fAbstract )
  765. {
  766. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  767. }
  768. STDMETHODIMP
  769. CWinNTClass::get_Auxiliary( THIS_ VARIANT_BOOL FAR *pfAuxiliary)
  770. {
  771. if ( !pfAuxiliary )
  772. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  773. *pfAuxiliary = VARIANT_FALSE;
  774. RRETURN(S_OK);
  775. }
  776. STDMETHODIMP
  777. CWinNTClass::put_Auxiliary( THIS_ VARIANT_BOOL fAuxiliary )
  778. {
  779. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  780. }
  781. STDMETHODIMP
  782. CWinNTClass::get_MandatoryProperties( THIS_ VARIANT FAR *pvMandatoryProperties )
  783. {
  784. HRESULT hr;
  785. VariantInit( pvMandatoryProperties );
  786. hr = VariantCopy( pvMandatoryProperties, &_vMandatoryProperties );
  787. RRETURN_EXP_IF_ERR(hr);
  788. }
  789. STDMETHODIMP
  790. CWinNTClass::put_MandatoryProperties( THIS_ VARIANT vMandatoryProperties )
  791. {
  792. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  793. }
  794. STDMETHODIMP
  795. CWinNTClass::get_DerivedFrom( THIS_ VARIANT FAR *pvDerivedFrom )
  796. {
  797. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  798. }
  799. STDMETHODIMP
  800. CWinNTClass::put_DerivedFrom( THIS_ VARIANT vDerivedFrom )
  801. {
  802. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  803. }
  804. STDMETHODIMP
  805. CWinNTClass::get_AuxDerivedFrom( THIS_ VARIANT FAR *pvAuxDerivedFrom )
  806. {
  807. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  808. }
  809. STDMETHODIMP
  810. CWinNTClass::put_AuxDerivedFrom( THIS_ VARIANT vAuxDerivedFrom )
  811. {
  812. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  813. }
  814. STDMETHODIMP
  815. CWinNTClass::get_PossibleSuperiors( THIS_ VARIANT FAR *pvPossSuperiors )
  816. {
  817. HRESULT hr;
  818. VariantInit( pvPossSuperiors );
  819. hr = VariantCopy( pvPossSuperiors, &_vPossSuperiors );
  820. RRETURN_EXP_IF_ERR(hr);
  821. }
  822. STDMETHODIMP
  823. CWinNTClass::put_PossibleSuperiors( THIS_ VARIANT vPossSuperiors )
  824. {
  825. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  826. }
  827. STDMETHODIMP
  828. CWinNTClass::get_Containment( THIS_ VARIANT FAR *pvContainment )
  829. {
  830. HRESULT hr;
  831. VariantInit( pvContainment );
  832. hr = VariantCopy( pvContainment, &_vContainment );
  833. RRETURN_EXP_IF_ERR(hr);
  834. }
  835. STDMETHODIMP
  836. CWinNTClass::put_Containment( THIS_ VARIANT vContainment )
  837. {
  838. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  839. }
  840. STDMETHODIMP
  841. CWinNTClass::get_Container( THIS_ VARIANT_BOOL FAR *pfContainer )
  842. {
  843. if ( !pfContainer )
  844. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  845. *pfContainer = _fContainer? VARIANT_TRUE : VARIANT_FALSE;
  846. RRETURN(S_OK);
  847. }
  848. STDMETHODIMP
  849. CWinNTClass::put_Container( THIS_ VARIANT_BOOL fContainer )
  850. {
  851. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  852. }
  853. STDMETHODIMP
  854. CWinNTClass::get_HelpFileName( THIS_ BSTR FAR *pbstrHelpFileName )
  855. {
  856. HRESULT hr;
  857. if ( !pbstrHelpFileName )
  858. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  859. hr = ADsAllocString( _bstrHelpFileName, pbstrHelpFileName );
  860. RRETURN_EXP_IF_ERR(hr);
  861. }
  862. STDMETHODIMP
  863. CWinNTClass::put_HelpFileName( THIS_ BSTR bstrHelpFile )
  864. {
  865. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  866. }
  867. STDMETHODIMP
  868. CWinNTClass::get_HelpFileContext( THIS_ long FAR *plHelpContext )
  869. {
  870. if ( !plHelpContext )
  871. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  872. *plHelpContext = _lHelpFileContext;
  873. RRETURN(S_OK);
  874. }
  875. STDMETHODIMP
  876. CWinNTClass::put_HelpFileContext( THIS_ long lHelpContext )
  877. {
  878. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  879. }
  880. STDMETHODIMP
  881. CWinNTClass::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers)
  882. {
  883. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  884. }
  885. HRESULT
  886. CWinNTClass::AllocateClassObject(CWinNTClass FAR * FAR * ppClass)
  887. {
  888. CWinNTClass FAR *pClass = NULL;
  889. CAggregatorDispMgr FAR *pDispMgr = NULL;
  890. HRESULT hr = S_OK;
  891. pClass = new CWinNTClass();
  892. if ( pClass == NULL )
  893. hr = E_OUTOFMEMORY;
  894. BAIL_ON_FAILURE(hr);
  895. pDispMgr = new CAggregatorDispMgr;
  896. if ( pDispMgr == NULL )
  897. hr = E_OUTOFMEMORY;
  898. BAIL_ON_FAILURE(hr);
  899. hr = LoadTypeInfoEntry( pDispMgr,
  900. LIBID_ADs,
  901. IID_IADs,
  902. (IADs *) pClass,
  903. DISPID_REGULAR );
  904. BAIL_ON_FAILURE(hr);
  905. hr = LoadTypeInfoEntry( pDispMgr,
  906. LIBID_ADs,
  907. IID_IADsClass,
  908. (IADsClass *) pClass,
  909. DISPID_REGULAR );
  910. BAIL_ON_FAILURE(hr);
  911. pClass->_pDispMgr = pDispMgr;
  912. *ppClass = pClass;
  913. RRETURN(hr);
  914. error:
  915. delete pDispMgr;
  916. delete pClass;
  917. RRETURN(hr);
  918. }
  919. /******************************************************************/
  920. /* Class CWinNTProperty
  921. /******************************************************************/
  922. DEFINE_IDispatch_Delegating_Implementation(CWinNTProperty)
  923. DEFINE_IADsExtension_Implementation(CWinNTProperty)
  924. DEFINE_IADs_Implementation(CWinNTProperty)
  925. CWinNTProperty::CWinNTProperty()
  926. : _pDispMgr( NULL ),
  927. _bstrOID( NULL ),
  928. _bstrSyntax( NULL ),
  929. _lMaxRange( 0 ),
  930. _lMinRange( 0 ),
  931. _fMultiValued( FALSE )
  932. {
  933. ENLIST_TRACKING(CWinNTProperty);
  934. }
  935. CWinNTProperty::~CWinNTProperty()
  936. {
  937. if ( _bstrOID ) {
  938. ADsFreeString( _bstrOID );
  939. }
  940. if ( _bstrSyntax ) {
  941. ADsFreeString( _bstrSyntax );
  942. }
  943. delete _pDispMgr;
  944. }
  945. HRESULT
  946. CWinNTProperty::CreateProperty(
  947. BSTR bstrParent,
  948. PROPERTYINFO *pPropertyInfo,
  949. DWORD dwObjectState,
  950. REFIID riid,
  951. CWinNTCredentials& Credentials,
  952. void **ppvObj
  953. )
  954. {
  955. CWinNTProperty FAR * pProperty = NULL;
  956. HRESULT hr = S_OK;
  957. hr = AllocatePropertyObject( &pProperty );
  958. BAIL_ON_FAILURE(hr);
  959. hr = ADsAllocString( pPropertyInfo->bstrOID, &pProperty->_bstrOID);
  960. BAIL_ON_FAILURE(hr);
  961. hr = ADsAllocString( pPropertyInfo->bstrSyntax, &pProperty->_bstrSyntax);
  962. BAIL_ON_FAILURE(hr);
  963. pProperty->_lMaxRange = pPropertyInfo->lMaxRange;
  964. pProperty->_lMinRange = pPropertyInfo->lMinRange;
  965. pProperty->_fMultiValued = (VARIANT_BOOL)pPropertyInfo->fMultiValued;
  966. hr = pProperty->InitializeCoreObject(
  967. bstrParent,
  968. pPropertyInfo->szPropertyName,
  969. PROPERTY_CLASS_NAME,
  970. NO_SCHEMA,
  971. CLSID_WinNTProperty,
  972. dwObjectState );
  973. BAIL_ON_FAILURE(hr);
  974. pProperty->_Credentials = Credentials;
  975. // check if the call is from UMI
  976. if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
  977. //
  978. // we do not pass riid to InitUmiObject below. This is because UMI object
  979. // does not support IDispatch. There are several places in ADSI code where
  980. // riid passed into this function is defaulted to IID_IDispatch -
  981. // IADsContainer::Create for example. To handle these cases, we always
  982. // request IID_IUnknown from the UMI object. Subsequent code within UMI
  983. // will QI for the appropriate interface.
  984. //
  985. if(3 == pProperty->_dwNumComponents) {
  986. pProperty->_CompClasses[0] = L"Computer";
  987. pProperty->_CompClasses[1] = L"Schema";
  988. pProperty->_CompClasses[2] = L"Property";
  989. }
  990. else
  991. BAIL_ON_FAILURE(hr = UMI_E_FAIL);
  992. hr = pProperty->InitUmiObject(
  993. pProperty->_Credentials,
  994. PropertyClass,
  995. g_dwPropertyClassTableSize,
  996. NULL,
  997. (IUnknown *)(INonDelegatingUnknown *) pProperty,
  998. NULL,
  999. IID_IUnknown,
  1000. ppvObj
  1001. );
  1002. BAIL_ON_FAILURE(hr);
  1003. //
  1004. // UMI object was created and the interface was obtained successfully.
  1005. // UMI object now has a reference to the inner unknown of IADs, since
  1006. // the call to Release() below is not going to be made in this case.
  1007. //
  1008. RRETURN(hr);
  1009. }
  1010. hr = pProperty->QueryInterface( riid, ppvObj );
  1011. BAIL_ON_FAILURE(hr);
  1012. pProperty->Release();
  1013. RRETURN(hr);
  1014. error:
  1015. delete pProperty;
  1016. RRETURN_EXP_IF_ERR(hr);
  1017. }
  1018. // called by implicit GetInfo from property cache
  1019. STDMETHODIMP
  1020. CWinNTProperty::GetInfo(
  1021. THIS_ DWORD dwApiLevel,
  1022. BOOL fExplicit
  1023. )
  1024. {
  1025. RRETURN(S_OK);
  1026. }
  1027. //----------------------------------------------------------------------------
  1028. // Function: QueryInterface
  1029. //
  1030. // Synopsis: If this object is aggregated within another object, then
  1031. // all calls will delegate to the outer object. Otherwise, the
  1032. // non-delegating QI is called
  1033. //
  1034. // Arguments:
  1035. //
  1036. // iid interface requested
  1037. // ppInterface Returns pointer to interface requested. NULL if interface
  1038. // is not supported.
  1039. //
  1040. // Returns: S_OK on success. Error code otherwise.
  1041. //
  1042. // Modifies: *ppInterface to return interface pointer
  1043. //
  1044. //----------------------------------------------------------------------------
  1045. STDMETHODIMP CWinNTProperty::QueryInterface(
  1046. REFIID iid,
  1047. LPVOID *ppInterface
  1048. )
  1049. {
  1050. if(_pUnkOuter != NULL)
  1051. RRETURN(_pUnkOuter->QueryInterface(
  1052. iid,
  1053. ppInterface
  1054. ));
  1055. RRETURN(NonDelegatingQueryInterface(
  1056. iid,
  1057. ppInterface
  1058. ));
  1059. }
  1060. //----------------------------------------------------------------------------
  1061. // Function: AddRef
  1062. //
  1063. // Synopsis: IUnknown::AddRef. If this object is aggregated within
  1064. // another, all calls will delegate to the outer object.
  1065. // Otherwise, the non-delegating AddRef is called
  1066. //
  1067. // Arguments:
  1068. //
  1069. // None
  1070. //
  1071. // Returns: New reference count
  1072. //
  1073. // Modifies: Nothing
  1074. //
  1075. //----------------------------------------------------------------------------
  1076. STDMETHODIMP_(ULONG) CWinNTProperty::AddRef(void)
  1077. {
  1078. if(_pUnkOuter != NULL)
  1079. RRETURN(_pUnkOuter->AddRef());
  1080. RRETURN(NonDelegatingAddRef());
  1081. }
  1082. //----------------------------------------------------------------------------
  1083. // Function: Release
  1084. //
  1085. // Synopsis: IUnknown::Release. If this object is aggregated within
  1086. // another, all calls will delegate to the outer object.
  1087. // Otherwise, the non-delegating Release is called
  1088. //
  1089. // Arguments:
  1090. //
  1091. // None
  1092. //
  1093. // Returns: New reference count
  1094. //
  1095. // Modifies: Nothing
  1096. //
  1097. //----------------------------------------------------------------------------
  1098. STDMETHODIMP_(ULONG) CWinNTProperty::Release(void)
  1099. {
  1100. if(_pUnkOuter != NULL)
  1101. RRETURN(_pUnkOuter->Release());
  1102. RRETURN(NonDelegatingRelease());
  1103. }
  1104. //----------------------------------------------------------------------------
  1105. STDMETHODIMP
  1106. CWinNTProperty::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
  1107. {
  1108. if (ppv == NULL) {
  1109. RRETURN(E_POINTER);
  1110. }
  1111. if (IsEqualIID(iid, IID_IUnknown))
  1112. {
  1113. *ppv = (IADsProperty FAR *) this;
  1114. }
  1115. else if (IsEqualIID(iid, IID_IDispatch))
  1116. {
  1117. *ppv = (IADs FAR *) this;
  1118. }
  1119. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  1120. {
  1121. *ppv = (ISupportErrorInfo FAR *)this;
  1122. }
  1123. else if (IsEqualIID(iid, IID_IADs))
  1124. {
  1125. *ppv = (IADs FAR *) this;
  1126. }
  1127. else if (IsEqualIID(iid, IID_IADsProperty))
  1128. {
  1129. *ppv = (IADsProperty FAR *) this;
  1130. }
  1131. else if( (_pDispatch != NULL) &&
  1132. IsEqualIID(iid, IID_IADsExtension) )
  1133. {
  1134. *ppv = (IADsExtension *) this;
  1135. }
  1136. else
  1137. {
  1138. *ppv = NULL;
  1139. return E_NOINTERFACE;
  1140. }
  1141. AddRef();
  1142. return NOERROR;
  1143. }
  1144. /* ISupportErrorInfo method */
  1145. STDMETHODIMP
  1146. CWinNTProperty::InterfaceSupportsErrorInfo(
  1147. THIS_ REFIID riid
  1148. )
  1149. {
  1150. if (IsEqualIID(riid, IID_IADs) ||
  1151. IsEqualIID(riid, IID_IADsProperty)) {
  1152. RRETURN(S_OK);
  1153. } else {
  1154. RRETURN(S_FALSE);
  1155. }
  1156. }
  1157. /* IADs methods */
  1158. STDMETHODIMP
  1159. CWinNTProperty::SetInfo(THIS)
  1160. {
  1161. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  1162. }
  1163. STDMETHODIMP
  1164. CWinNTProperty::GetInfo(THIS)
  1165. {
  1166. RRETURN(S_OK);
  1167. }
  1168. STDMETHODIMP
  1169. CWinNTProperty::ImplicitGetInfo(THIS)
  1170. {
  1171. RRETURN(S_OK);
  1172. }
  1173. /* IADsProperty methods */
  1174. STDMETHODIMP
  1175. CWinNTProperty::get_OID( THIS_ BSTR FAR *pbstrOID )
  1176. {
  1177. HRESULT hr;
  1178. if ( !pbstrOID )
  1179. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  1180. hr = ADsAllocString( _bstrOID, pbstrOID );
  1181. RRETURN_EXP_IF_ERR(hr);
  1182. }
  1183. STDMETHODIMP
  1184. CWinNTProperty::put_OID( THIS_ BSTR bstrOID )
  1185. {
  1186. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  1187. }
  1188. STDMETHODIMP
  1189. CWinNTProperty::get_Syntax( THIS_ BSTR FAR *pbstrSyntax )
  1190. {
  1191. HRESULT hr;
  1192. if ( !pbstrSyntax )
  1193. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  1194. hr = ADsAllocString( _bstrSyntax, pbstrSyntax );
  1195. RRETURN_EXP_IF_ERR(hr);
  1196. }
  1197. STDMETHODIMP
  1198. CWinNTProperty::put_Syntax( THIS_ BSTR bstrSyntax )
  1199. {
  1200. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  1201. }
  1202. STDMETHODIMP
  1203. CWinNTProperty::get_MaxRange( THIS_ long FAR *plMaxRange )
  1204. {
  1205. if ( !plMaxRange )
  1206. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  1207. *plMaxRange = _lMaxRange;
  1208. RRETURN(S_OK);
  1209. }
  1210. STDMETHODIMP
  1211. CWinNTProperty::put_MaxRange( THIS_ long lMaxRange )
  1212. {
  1213. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  1214. }
  1215. STDMETHODIMP
  1216. CWinNTProperty::get_MinRange( THIS_ long FAR *plMinRange )
  1217. {
  1218. if ( !plMinRange )
  1219. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  1220. *plMinRange = _lMinRange;
  1221. RRETURN(S_OK);
  1222. }
  1223. STDMETHODIMP
  1224. CWinNTProperty::put_MinRange( THIS_ long lMinRange )
  1225. {
  1226. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  1227. }
  1228. STDMETHODIMP
  1229. CWinNTProperty::get_MultiValued( THIS_ VARIANT_BOOL FAR *pfMultiValued )
  1230. {
  1231. if ( !pfMultiValued )
  1232. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  1233. *pfMultiValued = _fMultiValued? VARIANT_TRUE : VARIANT_FALSE;
  1234. RRETURN(S_OK);
  1235. }
  1236. STDMETHODIMP
  1237. CWinNTProperty::put_MultiValued( THIS_ VARIANT_BOOL fMultiValued )
  1238. {
  1239. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  1240. }
  1241. STDMETHODIMP
  1242. CWinNTProperty::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers)
  1243. {
  1244. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  1245. }
  1246. HRESULT
  1247. CWinNTProperty::AllocatePropertyObject(CWinNTProperty FAR * FAR * ppProperty)
  1248. {
  1249. CWinNTProperty FAR *pProperty = NULL;
  1250. CAggregatorDispMgr FAR *pDispMgr = NULL;
  1251. HRESULT hr = S_OK;
  1252. pProperty = new CWinNTProperty();
  1253. if ( pProperty == NULL )
  1254. hr = E_OUTOFMEMORY;
  1255. BAIL_ON_FAILURE(hr);
  1256. pDispMgr = new CAggregatorDispMgr;
  1257. if ( pDispMgr == NULL )
  1258. hr = E_OUTOFMEMORY;
  1259. BAIL_ON_FAILURE(hr);
  1260. hr = LoadTypeInfoEntry( pDispMgr,
  1261. LIBID_ADs,
  1262. IID_IADs,
  1263. (IADs *) pProperty,
  1264. DISPID_REGULAR );
  1265. BAIL_ON_FAILURE(hr);
  1266. hr = LoadTypeInfoEntry( pDispMgr,
  1267. LIBID_ADs,
  1268. IID_IADsProperty,
  1269. (IADsProperty *) pProperty,
  1270. DISPID_REGULAR );
  1271. BAIL_ON_FAILURE(hr);
  1272. pProperty->_pDispMgr = pDispMgr;
  1273. *ppProperty = pProperty;
  1274. RRETURN(hr);
  1275. error:
  1276. delete pDispMgr;
  1277. delete pProperty;
  1278. RRETURN(hr);
  1279. }
  1280. /******************************************************************/
  1281. /* Class CWinNTSyntax
  1282. /******************************************************************/
  1283. DEFINE_IDispatch_Delegating_Implementation(CWinNTSyntax)
  1284. DEFINE_IADsExtension_Implementation(CWinNTSyntax)
  1285. DEFINE_IADs_Implementation(CWinNTSyntax)
  1286. CWinNTSyntax::CWinNTSyntax()
  1287. {
  1288. ENLIST_TRACKING(CWinNTSyntax);
  1289. }
  1290. CWinNTSyntax::~CWinNTSyntax()
  1291. {
  1292. delete _pDispMgr;
  1293. }
  1294. HRESULT
  1295. CWinNTSyntax::CreateSyntax(
  1296. BSTR bstrParent,
  1297. SYNTAXINFO *pSyntaxInfo,
  1298. DWORD dwObjectState,
  1299. REFIID riid,
  1300. CWinNTCredentials& Credentials,
  1301. void **ppvObj
  1302. )
  1303. {
  1304. CWinNTSyntax FAR *pSyntax = NULL;
  1305. HRESULT hr = S_OK;
  1306. hr = AllocateSyntaxObject( &pSyntax );
  1307. BAIL_ON_FAILURE(hr);
  1308. hr = pSyntax->InitializeCoreObject(
  1309. bstrParent,
  1310. pSyntaxInfo->bstrName,
  1311. SYNTAX_CLASS_NAME,
  1312. NO_SCHEMA,
  1313. CLSID_WinNTSyntax,
  1314. dwObjectState );
  1315. BAIL_ON_FAILURE(hr);
  1316. pSyntax->_lOleAutoDataType = pSyntaxInfo->lOleAutoDataType;
  1317. pSyntax->_Credentials = Credentials;
  1318. // check if the call is from UMI
  1319. if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
  1320. //
  1321. // we do not pass riid to InitUmiObject below. This is because UMI object
  1322. // does not support IDispatch. There are several places in ADSI code where
  1323. // riid passed into this function is defaulted to IID_IDispatch -
  1324. // IADsContainer::Create for example. To handle these cases, we always
  1325. // request IID_IUnknown from the UMI object. Subsequent code within UMI
  1326. // will QI for the appropriate interface.
  1327. //
  1328. if(3 == pSyntax->_dwNumComponents) {
  1329. pSyntax->_CompClasses[0] = L"Computer";
  1330. pSyntax->_CompClasses[1] = L"Schema";
  1331. pSyntax->_CompClasses[2] = L"Syntax";
  1332. }
  1333. else
  1334. BAIL_ON_FAILURE(hr = UMI_E_FAIL);
  1335. hr = pSyntax->InitUmiObject(
  1336. pSyntax->_Credentials,
  1337. SyntaxClass,
  1338. g_dwSyntaxTableSize,
  1339. NULL,
  1340. (IUnknown *)(INonDelegatingUnknown *) pSyntax,
  1341. NULL,
  1342. IID_IUnknown,
  1343. ppvObj
  1344. );
  1345. BAIL_ON_FAILURE(hr);
  1346. //
  1347. // UMI object was created and the interface was obtained successfully.
  1348. // UMI object now has a reference to the inner unknown of IADs, since
  1349. // the call to Release() below is not going to be made in this case.
  1350. //
  1351. RRETURN(hr);
  1352. }
  1353. hr = pSyntax->QueryInterface( riid, ppvObj );
  1354. BAIL_ON_FAILURE(hr);
  1355. pSyntax->Release();
  1356. RRETURN(hr);
  1357. error:
  1358. delete pSyntax;
  1359. RRETURN_EXP_IF_ERR(hr);
  1360. }
  1361. // called by implicit GetInfo from property cache
  1362. STDMETHODIMP
  1363. CWinNTSyntax::GetInfo(
  1364. THIS_ DWORD dwApiLevel,
  1365. BOOL fExplicit
  1366. )
  1367. {
  1368. RRETURN(S_OK);
  1369. }
  1370. //----------------------------------------------------------------------------
  1371. // Function: QueryInterface
  1372. //
  1373. // Synopsis: If this object is aggregated within another object, then
  1374. // all calls will delegate to the outer object. Otherwise, the
  1375. // non-delegating QI is called
  1376. //
  1377. // Arguments:
  1378. //
  1379. // iid interface requested
  1380. // ppInterface Returns pointer to interface requested. NULL if interface
  1381. // is not supported.
  1382. //
  1383. // Returns: S_OK on success. Error code otherwise.
  1384. //
  1385. // Modifies: *ppInterface to return interface pointer
  1386. //
  1387. //----------------------------------------------------------------------------
  1388. STDMETHODIMP CWinNTSyntax::QueryInterface(
  1389. REFIID iid,
  1390. LPVOID *ppInterface
  1391. )
  1392. {
  1393. if(_pUnkOuter != NULL)
  1394. RRETURN(_pUnkOuter->QueryInterface(
  1395. iid,
  1396. ppInterface
  1397. ));
  1398. RRETURN(NonDelegatingQueryInterface(
  1399. iid,
  1400. ppInterface
  1401. ));
  1402. }
  1403. //----------------------------------------------------------------------------
  1404. // Function: AddRef
  1405. //
  1406. // Synopsis: IUnknown::AddRef. If this object is aggregated within
  1407. // another, all calls will delegate to the outer object.
  1408. // Otherwise, the non-delegating AddRef is called
  1409. //
  1410. // Arguments:
  1411. //
  1412. // None
  1413. //
  1414. // Returns: New reference count
  1415. //
  1416. // Modifies: Nothing
  1417. //
  1418. //----------------------------------------------------------------------------
  1419. STDMETHODIMP_(ULONG) CWinNTSyntax::AddRef(void)
  1420. {
  1421. if(_pUnkOuter != NULL)
  1422. RRETURN(_pUnkOuter->AddRef());
  1423. RRETURN(NonDelegatingAddRef());
  1424. }
  1425. //----------------------------------------------------------------------------
  1426. // Function: Release
  1427. //
  1428. // Synopsis: IUnknown::Release. If this object is aggregated within
  1429. // another, all calls will delegate to the outer object.
  1430. // Otherwise, the non-delegating Release is called
  1431. //
  1432. // Arguments:
  1433. //
  1434. // None
  1435. //
  1436. // Returns: New reference count
  1437. //
  1438. // Modifies: Nothing
  1439. //
  1440. //----------------------------------------------------------------------------
  1441. STDMETHODIMP_(ULONG) CWinNTSyntax::Release(void)
  1442. {
  1443. if(_pUnkOuter != NULL)
  1444. RRETURN(_pUnkOuter->Release());
  1445. RRETURN(NonDelegatingRelease());
  1446. }
  1447. //----------------------------------------------------------------------------
  1448. STDMETHODIMP
  1449. CWinNTSyntax::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
  1450. {
  1451. if (ppv == NULL) {
  1452. RRETURN(E_POINTER);
  1453. }
  1454. if (IsEqualIID(iid, IID_IUnknown))
  1455. {
  1456. *ppv = (IADs FAR *) this;
  1457. }
  1458. else if (IsEqualIID(iid, IID_IDispatch))
  1459. {
  1460. *ppv = (IADs FAR *) this;
  1461. }
  1462. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  1463. {
  1464. *ppv = (ISupportErrorInfo FAR *) this;
  1465. }
  1466. else if (IsEqualIID(iid, IID_IADs))
  1467. {
  1468. *ppv = (IADs FAR *) this;
  1469. }
  1470. else if (IsEqualIID(iid, IID_IADsSyntax))
  1471. {
  1472. *ppv = (IADsSyntax FAR *) this;
  1473. }
  1474. else if( (_pDispatch != NULL) &&
  1475. IsEqualIID(iid, IID_IADsExtension) )
  1476. {
  1477. *ppv = (IADsExtension *) this;
  1478. }
  1479. else
  1480. {
  1481. *ppv = NULL;
  1482. return E_NOINTERFACE;
  1483. }
  1484. AddRef();
  1485. return NOERROR;
  1486. }
  1487. /* ISupportErrorInfo method */
  1488. STDMETHODIMP
  1489. CWinNTSyntax::InterfaceSupportsErrorInfo(
  1490. THIS_ REFIID riid
  1491. )
  1492. {
  1493. if (IsEqualIID(riid, IID_IADs) ||
  1494. IsEqualIID(riid, IID_IADsSyntax)) {
  1495. RRETURN(S_OK);
  1496. } else {
  1497. RRETURN(S_FALSE);
  1498. }
  1499. }
  1500. /* IADs methods */
  1501. STDMETHODIMP
  1502. CWinNTSyntax::SetInfo(THIS)
  1503. {
  1504. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  1505. }
  1506. STDMETHODIMP
  1507. CWinNTSyntax::GetInfo(THIS)
  1508. {
  1509. RRETURN(S_OK);
  1510. }
  1511. STDMETHODIMP
  1512. CWinNTSyntax::ImplicitGetInfo(THIS)
  1513. {
  1514. RRETURN(S_OK);
  1515. }
  1516. HRESULT
  1517. CWinNTSyntax::AllocateSyntaxObject(CWinNTSyntax FAR * FAR * ppSyntax)
  1518. {
  1519. CWinNTSyntax FAR *pSyntax = NULL;
  1520. CAggregatorDispMgr FAR *pDispMgr = NULL;
  1521. HRESULT hr = S_OK;
  1522. pSyntax = new CWinNTSyntax();
  1523. if ( pSyntax == NULL )
  1524. hr = E_OUTOFMEMORY;
  1525. BAIL_ON_FAILURE(hr);
  1526. pDispMgr = new CAggregatorDispMgr;
  1527. if ( pDispMgr == NULL )
  1528. hr = E_OUTOFMEMORY;
  1529. BAIL_ON_FAILURE(hr);
  1530. hr = LoadTypeInfoEntry( pDispMgr,
  1531. LIBID_ADs,
  1532. IID_IADsSyntax,
  1533. (IADsSyntax *) pSyntax,
  1534. DISPID_REGULAR );
  1535. BAIL_ON_FAILURE(hr);
  1536. pSyntax->_pDispMgr = pDispMgr;
  1537. *ppSyntax = pSyntax;
  1538. RRETURN(hr);
  1539. error:
  1540. delete pDispMgr;
  1541. delete pSyntax;
  1542. RRETURN(hr);
  1543. }
  1544. STDMETHODIMP
  1545. CWinNTSyntax::get_OleAutoDataType( THIS_ long FAR *plOleAutoDataType )
  1546. {
  1547. if ( !plOleAutoDataType )
  1548. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  1549. *plOleAutoDataType = _lOleAutoDataType;
  1550. RRETURN(S_OK);
  1551. }
  1552. STDMETHODIMP
  1553. CWinNTSyntax::put_OleAutoDataType( THIS_ long lOleAutoDataType )
  1554. {
  1555. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  1556. }
  1557. /******************************************************************/
  1558. /* Misc Helpers
  1559. /******************************************************************/
  1560. HRESULT
  1561. MakeVariantFromStringList(
  1562. BSTR bstrList,
  1563. VARIANT *pvVariant
  1564. )
  1565. {
  1566. HRESULT hr = S_OK;
  1567. SAFEARRAY *aList = NULL;
  1568. SAFEARRAYBOUND aBound;
  1569. BSTR pszTempList = NULL;
  1570. if ( bstrList != NULL )
  1571. {
  1572. long i = 0;
  1573. long nCount = 1;
  1574. TCHAR c;
  1575. BSTR pszSrc;
  1576. hr = ADsAllocString( bstrList, &pszTempList );
  1577. BAIL_ON_FAILURE(hr);
  1578. while ( c = pszTempList[i] )
  1579. {
  1580. if ( c == TEXT(','))
  1581. {
  1582. pszTempList[i] = 0;
  1583. nCount++;
  1584. }
  1585. i++;
  1586. }
  1587. aBound.lLbound = 0;
  1588. aBound.cElements = nCount;
  1589. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  1590. if ( aList == NULL )
  1591. {
  1592. hr = E_OUTOFMEMORY;
  1593. BAIL_ON_FAILURE(hr);
  1594. }
  1595. pszSrc = pszTempList;
  1596. for ( i = 0; i < nCount; i++ )
  1597. {
  1598. VARIANT v;
  1599. VariantInit(&v);
  1600. V_VT(&v) = VT_BSTR;
  1601. hr = ADsAllocString( pszSrc, &(V_BSTR(&v)));
  1602. BAIL_ON_FAILURE(hr);
  1603. hr = SafeArrayPutElement( aList,
  1604. &i,
  1605. &v );
  1606. VariantClear(&v);
  1607. BAIL_ON_FAILURE(hr);
  1608. pszSrc += _tcslen( pszSrc ) + 1;
  1609. }
  1610. VariantInit( pvVariant );
  1611. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  1612. V_ARRAY(pvVariant) = aList;
  1613. ADsFreeString( pszTempList );
  1614. pszTempList = NULL;
  1615. }
  1616. else
  1617. {
  1618. aBound.lLbound = 0;
  1619. aBound.cElements = 0;
  1620. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  1621. if ( aList == NULL )
  1622. {
  1623. hr = E_OUTOFMEMORY;
  1624. BAIL_ON_FAILURE(hr);
  1625. }
  1626. VariantInit( pvVariant );
  1627. V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
  1628. V_ARRAY(pvVariant) = aList;
  1629. }
  1630. RRETURN(S_OK);
  1631. error:
  1632. if ( pszTempList )
  1633. ADsFreeString( pszTempList );
  1634. if ( aList )
  1635. SafeArrayDestroy( aList );
  1636. return hr;
  1637. }
  1638. STDMETHODIMP
  1639. CWinNTClass::get_OptionalProperties( THIS_ VARIANT FAR *retval )
  1640. {
  1641. HRESULT hr;
  1642. VariantInit( retval );
  1643. hr = VariantCopy( retval, &_vOptionalProperties );
  1644. RRETURN_EXP_IF_ERR(hr);
  1645. }
  1646. STDMETHODIMP
  1647. CWinNTClass::put_OptionalProperties( THIS_ VARIANT vOptionalProperties )
  1648. {
  1649. HRESULT hr = E_NOTIMPL;
  1650. RRETURN_EXP_IF_ERR(hr);
  1651. }
  1652. STDMETHODIMP
  1653. CWinNTClass::get_NamingProperties( THIS_ VARIANT FAR *retval )
  1654. {
  1655. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  1656. }
  1657. STDMETHODIMP
  1658. CWinNTClass::put_NamingProperties( THIS_ VARIANT vNamingProperties )
  1659. {
  1660. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  1661. }