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.

1213 lines
27 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997
  5. //
  6. // File: getobj.cxx
  7. //
  8. // Contents: ADSI GetObject functionality
  9. //
  10. // History: 25-Feb-97 SophiaC Created.
  11. // 25-Jun-97 MagnusH Added private extension mechanism
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "iis.hxx"
  15. #pragma hdrstop
  16. extern LPWSTR szProviderName;
  17. //+---------------------------------------------------------------------------
  18. // Function: RelativeGetObject
  19. //
  20. // Synopsis: Gets object relative to given Active Directory path.
  21. //
  22. // Arguments: [BSTR ADsPath]
  23. // [BSTR ClassName]
  24. // [BSTR RelativeName]
  25. // [IUnknown** ppObject]
  26. // [BOOL bNamespaceRelative]
  27. //
  28. // Returns: HRESULT
  29. //
  30. // Modifies: *ppObject
  31. //
  32. //----------------------------------------------------------------------------
  33. HRESULT
  34. RelativeGetObject(
  35. BSTR ADsPath,
  36. BSTR ClassName,
  37. BSTR RelativeName,
  38. CCredentials& Credentials,
  39. IDispatch * FAR* ppObject,
  40. BOOL bNamespaceRelative
  41. )
  42. {
  43. HRESULT hr = S_OK;
  44. LPWSTR pszBuffer = NULL;
  45. DWORD dwLen;
  46. *ppObject = NULL;
  47. if (!RelativeName || !*RelativeName) {
  48. RRETURN(E_ADS_UNKNOWN_OBJECT);
  49. }
  50. dwLen = wcslen(ADsPath) + wcslen(RelativeName) + wcslen(ClassName) + 4;
  51. pszBuffer = (LPWSTR)AllocADsMem(dwLen*sizeof(WCHAR));
  52. if (!pszBuffer) {
  53. hr = E_OUTOFMEMORY;
  54. BAIL_ON_FAILURE(hr);
  55. }
  56. wcscpy(pszBuffer, ADsPath);
  57. if (bNamespaceRelative)
  58. wcscat(pszBuffer, L"//");
  59. else
  60. wcscat(pszBuffer, L"/");
  61. wcscat(pszBuffer, RelativeName);
  62. if (ClassName && *ClassName) {
  63. wcscat(pszBuffer,L",");
  64. wcscat(pszBuffer, ClassName);
  65. }
  66. hr = ::GetObject(
  67. pszBuffer,
  68. Credentials,
  69. (LPVOID *)ppObject
  70. );
  71. BAIL_ON_FAILURE(hr);
  72. error:
  73. if (pszBuffer) {
  74. FreeADsMem(pszBuffer);
  75. }
  76. RRETURN(hr);
  77. }
  78. //+---------------------------------------------------------------------------
  79. // Function: GetObject
  80. //
  81. // Synopsis: Called by ResolvePathName to return an object
  82. //
  83. // Arguments: [LPWSTR szBuffer]
  84. // [LPVOID *ppObject]
  85. //
  86. // Returns: HRESULT
  87. //
  88. // Modifies: -
  89. //
  90. //----------------------------------------------------------------------------
  91. HRESULT
  92. GetObject(
  93. LPWSTR szBuffer,
  94. CCredentials& Credentials,
  95. LPVOID * ppObject
  96. )
  97. {
  98. HRESULT hr;
  99. DWORD dwStatus = NO_ERROR;
  100. WCHAR szCommonName[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
  101. LPWSTR pszParent = NULL;
  102. IMSAdminBase * pAdminBase = NULL;
  103. METADATA_HANDLE hObjHandle = NULL;
  104. METADATA_RECORD mdrData;
  105. LPWSTR pszIISPathName = NULL;
  106. WCHAR DataBuf[MAX_PATH];
  107. DWORD dwReqdBufferLen;
  108. OBJECTINFO ObjectInfo;
  109. POBJECTINFO pObjectInfo = &ObjectInfo;
  110. CLexer Lexer(szBuffer);
  111. IIsSchema *pSchema = NULL;
  112. IADs * pADs = NULL;
  113. //
  114. // Parse the pathname
  115. //
  116. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  117. hr = ADsObject(&Lexer, pObjectInfo);
  118. BAIL_ON_FAILURE(hr);
  119. //
  120. // Validate that this ADs pathname is to be processed by
  121. // us - as in the provider name is @IIS!
  122. //
  123. hr = InitServerInfo(pObjectInfo->TreeName, &pAdminBase, &pSchema);
  124. BAIL_ON_FAILURE(hr);
  125. hr = ValidateProvider(pObjectInfo);
  126. BAIL_ON_FAILURE(hr);
  127. hr = ValidateObjectType(pObjectInfo);
  128. switch (pObjectInfo->ObjectType) {
  129. case TOKEN_NAMESPACE:
  130. //
  131. // This means that this is a namespace object;
  132. // instantiate the namespace object
  133. //
  134. hr = GetNamespaceObject(
  135. pObjectInfo,
  136. Credentials,
  137. ppObject
  138. );
  139. BAIL_ON_FAILURE(hr);
  140. break;
  141. case TOKEN_SCHEMA:
  142. hr = GetSchemaObject(
  143. pObjectInfo,
  144. pSchema,
  145. ppObject
  146. );
  147. BAIL_ON_FAILURE(hr);
  148. break;
  149. case TOKEN_CLASS:
  150. hr = GetClassObject(
  151. pObjectInfo,
  152. pSchema,
  153. ppObject
  154. );
  155. BAIL_ON_FAILURE(hr);
  156. break;
  157. case TOKEN_PROPERTY:
  158. hr = GetPropertyObject(
  159. pObjectInfo,
  160. pSchema,
  161. ppObject
  162. );
  163. BAIL_ON_FAILURE(hr);
  164. break;
  165. case TOKEN_SYNTAX:
  166. hr = GetSyntaxObject(
  167. pObjectInfo,
  168. ppObject
  169. );
  170. BAIL_ON_FAILURE(hr);
  171. break;
  172. default:
  173. pszIISPathName = AllocADsStr(szBuffer);
  174. if (!pszIISPathName) {
  175. hr = E_OUTOFMEMORY;
  176. BAIL_ON_FAILURE(hr);
  177. }
  178. *pszIISPathName = L'\0';
  179. hr = BuildIISPathFromADsPath(
  180. pObjectInfo,
  181. pszIISPathName
  182. );
  183. BAIL_ON_FAILURE(hr);
  184. hr = OpenAdminBaseKey(
  185. pObjectInfo->TreeName,
  186. (LPWSTR)pszIISPathName,
  187. METADATA_PERMISSION_READ,
  188. &pAdminBase,
  189. &hObjHandle
  190. );
  191. BAIL_ON_FAILURE(hr);
  192. //
  193. // Find out Class Name
  194. //
  195. mdrData.dwMDIdentifier = MD_KEY_TYPE;
  196. mdrData.dwMDDataType = STRING_METADATA;
  197. mdrData.dwMDUserType = ALL_METADATA;
  198. mdrData.dwMDAttributes = METADATA_INHERIT;
  199. mdrData.dwMDDataLen = MAX_PATH;
  200. mdrData.pbMDData = (PBYTE)DataBuf;
  201. hr = pAdminBase->GetData(
  202. hObjHandle,
  203. L"",
  204. &mdrData,
  205. &dwReqdBufferLen
  206. );
  207. if (FAILED(hr)) {
  208. if (hr == MD_ERROR_DATA_NOT_FOUND) {
  209. memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
  210. SIZEOF_DEFAULT_CLASS_W);
  211. if (pObjectInfo->ClassName[0] != L'\0' &&
  212. _wcsicmp((LPWSTR)pObjectInfo->ClassName, DataBuf)) {
  213. hr = E_ADS_BAD_PARAMETER;
  214. BAIL_ON_FAILURE(hr);
  215. }
  216. }
  217. else {
  218. BAIL_ON_FAILURE(hr);
  219. }
  220. }
  221. else {
  222. if (pObjectInfo->ClassName[0] != L'\0' &&
  223. _wcsicmp((LPWSTR)pObjectInfo->ClassName, DataBuf)) {
  224. hr = E_ADS_BAD_PARAMETER;
  225. BAIL_ON_FAILURE(hr);
  226. }
  227. hr = pSchema->ValidateClassName((LPWSTR)DataBuf);
  228. if (hr == E_ADS_SCHEMA_VIOLATION) {
  229. memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
  230. SIZEOF_DEFAULT_CLASS_W);
  231. }
  232. }
  233. //
  234. // Close the handle now
  235. //
  236. if (hObjHandle) {
  237. CloseAdminBaseKey(pAdminBase, hObjHandle);
  238. hObjHandle = NULL;
  239. }
  240. pszParent = AllocADsStr(szBuffer);
  241. if (!pszParent) {
  242. hr = E_OUTOFMEMORY;
  243. BAIL_ON_FAILURE(hr);
  244. }
  245. *pszParent = L'\0';
  246. hr = BuildADsParentPath(
  247. szBuffer,
  248. pszParent,
  249. szCommonName
  250. );
  251. BAIL_ON_FAILURE(hr);
  252. hr = CIISGenObject::CreateGenericObject(
  253. pszParent,
  254. szCommonName,
  255. (LPWSTR)DataBuf,
  256. Credentials,
  257. ADS_OBJECT_BOUND,
  258. IID_IDispatch,
  259. (void **)&pADs
  260. );
  261. BAIL_ON_FAILURE(hr);
  262. hr = pADs->QueryInterface(
  263. IID_IDispatch,
  264. ppObject
  265. );
  266. BAIL_ON_FAILURE(hr);
  267. }
  268. error:
  269. if (pAdminBase && hObjHandle) {
  270. CloseAdminBaseKey(pAdminBase, hObjHandle);
  271. }
  272. if (pADs) {
  273. pADs->Release();
  274. }
  275. if (pszIISPathName) {
  276. FreeADsStr(pszIISPathName);
  277. }
  278. if (pszParent) {
  279. FreeADsStr(pszParent);
  280. }
  281. FreeObjectInfo( &ObjectInfo );
  282. RRETURN(hr);
  283. }
  284. HRESULT
  285. BuildIISPathFromADsPath(
  286. LPWSTR szADsPathName,
  287. LPWSTR * pszIISPathName
  288. )
  289. {
  290. OBJECTINFO ObjectInfo;
  291. POBJECTINFO pObjectInfo = &ObjectInfo;
  292. CLexer Lexer(szADsPathName);
  293. DWORD i = 0;
  294. HRESULT hr;
  295. LPWSTR szIISPathName = NULL;
  296. *pszIISPathName = NULL;
  297. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  298. hr = ADsObject(&Lexer, pObjectInfo);
  299. BAIL_ON_FAILURE(hr);
  300. szIISPathName = AllocADsStr(szADsPathName);
  301. if (!szIISPathName) {
  302. hr = E_OUTOFMEMORY;
  303. BAIL_ON_FAILURE(hr);
  304. }
  305. *szIISPathName = L'\0';
  306. hr = BuildIISPathFromADsPath(pObjectInfo, szIISPathName);
  307. BAIL_ON_FAILURE(hr);
  308. *pszIISPathName = szIISPathName;
  309. error:
  310. FreeObjectInfo( &ObjectInfo );
  311. RRETURN(hr);
  312. }
  313. HRESULT
  314. BuildIISPathFromADsPath(
  315. POBJECTINFO pObjectInfo,
  316. LPWSTR pszIISPathName
  317. )
  318. {
  319. DWORD dwNumComponents = 0;
  320. DWORD i = 0;
  321. dwNumComponents = pObjectInfo->NumComponents;
  322. //
  323. // wcscat "LM" to IIS Metabase path
  324. //
  325. wcscat(pszIISPathName, L"/LM/");
  326. if (dwNumComponents) {
  327. for (i = 0; i < dwNumComponents; i++) {
  328. wcscat(pszIISPathName, pObjectInfo->ComponentArray[i].szComponent);
  329. if( i < dwNumComponents -1 ) {
  330. wcscat(pszIISPathName,L"/");
  331. }
  332. }
  333. }
  334. RRETURN(S_OK);
  335. }
  336. HRESULT
  337. BuildADsParentPath(
  338. LPWSTR szBuffer,
  339. LPWSTR szParent,
  340. LPWSTR szCommonName
  341. )
  342. {
  343. OBJECTINFO ObjectInfo;
  344. POBJECTINFO pObjectInfo = &ObjectInfo;
  345. CLexer Lexer(szBuffer);
  346. DWORD i = 0;
  347. DWORD dwNumComponents = 0;
  348. HRESULT hr;
  349. LPWSTR pszComponent = NULL, pszValue = NULL;
  350. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  351. hr = ADsObject(&Lexer, pObjectInfo);
  352. BAIL_ON_FAILURE(hr);
  353. dwNumComponents = pObjectInfo->NumComponents;
  354. if (!dwNumComponents && !pObjectInfo->TreeName) {
  355. //
  356. // There are no CNs in this pathname and
  357. // no tree name specified. This is the
  358. // namespace object - its parent is the
  359. // @ADs! object
  360. //
  361. wsprintf(szParent,L"ADs:");
  362. hr = S_OK;
  363. } else if (!dwNumComponents && pObjectInfo->TreeName) {
  364. //
  365. // There are no CNs in this pathname and a tree
  366. // name has been specified. This is the root
  367. // object - its parent is the @IIS! object
  368. wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
  369. //
  370. // And the common name is the TreeName
  371. //
  372. wsprintf(szCommonName,L"%s", pObjectInfo->TreeName);
  373. hr = S_OK;
  374. }else {
  375. //
  376. // There are one or more CNs, a tree name has been
  377. // specified. In the worst case the parent is the
  378. // root object. In the best case a long CN.
  379. //
  380. wsprintf(
  381. szParent, L"%s://%s",
  382. pObjectInfo->ProviderName,
  383. pObjectInfo->TreeName
  384. );
  385. for (i = 0; i < dwNumComponents - 1; i++) {
  386. wcscat(szParent, L"/");
  387. pszComponent = pObjectInfo->ComponentArray[i].szComponent;
  388. pszValue = pObjectInfo->ComponentArray[i].szValue;
  389. if (pszComponent && pszValue) {
  390. wcscat(
  391. szParent,
  392. pObjectInfo->ComponentArray[i].szComponent
  393. );
  394. wcscat(szParent,L"=");
  395. wcscat(
  396. szParent,
  397. pObjectInfo->ComponentArray[i].szValue
  398. );
  399. }else if (pszComponent){
  400. wcscat(
  401. szParent,
  402. pObjectInfo->ComponentArray[i].szComponent
  403. );
  404. }else {
  405. //
  406. // Error - we should never hit this case!!
  407. //
  408. }
  409. }
  410. //
  411. // And the common name is the last component
  412. //
  413. pszComponent = pObjectInfo->ComponentArray[dwNumComponents - 1].szComponent;
  414. pszValue = pObjectInfo->ComponentArray[dwNumComponents - 1].szValue;
  415. if (pszComponent && pszValue) {
  416. wsprintf(szCommonName, L"%s=%s",pszComponent, pszValue);
  417. }else if (pszComponent){
  418. wsprintf(szCommonName, L"%s", pszComponent);
  419. }else {
  420. //
  421. // Error - we should never hit this case!!
  422. //
  423. }
  424. }
  425. error:
  426. FreeObjectInfo( &ObjectInfo );
  427. RRETURN(hr);
  428. }
  429. HRESULT
  430. BuildADsParentPath(
  431. POBJECTINFO pObjectInfo,
  432. LPWSTR szParent,
  433. LPWSTR szCommonName
  434. )
  435. {
  436. DWORD i = 0;
  437. DWORD dwNumComponents = 0;
  438. HRESULT hr;
  439. LPWSTR pszComponent = NULL, pszValue = NULL;
  440. dwNumComponents = pObjectInfo->NumComponents;
  441. if (!dwNumComponents && !pObjectInfo->TreeName) {
  442. //
  443. // There are no CNs in this pathname and
  444. // no tree name specified. This is the
  445. // namespace object - its parent is the
  446. // @ADs! object
  447. //
  448. wsprintf(szParent,L"ADs:");
  449. RRETURN(S_OK);
  450. } else if (!dwNumComponents && pObjectInfo->TreeName) {
  451. //
  452. // There are no CNs in this pathname and a tree
  453. // name has been specified. This is the root
  454. // object - its parent is the @IIS! object
  455. wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
  456. //
  457. // And the common name is the TreeName. Remember the
  458. // "//" will be added on when we reconstruct the full
  459. // pathname
  460. //
  461. wsprintf(szCommonName,L"%s", pObjectInfo->TreeName);
  462. RRETURN(S_OK);
  463. }else {
  464. //
  465. // There are one or more CNs, a tree name has been
  466. // specified. In the worst case the parent is the
  467. // root object. In the best case a long CN.
  468. //
  469. wsprintf(
  470. szParent, L"%s://%s",
  471. pObjectInfo->ProviderName,
  472. pObjectInfo->TreeName
  473. );
  474. for (i = 0; i < dwNumComponents - 1; i++) {
  475. wcscat(szParent, L"/");
  476. pszComponent = pObjectInfo->ComponentArray[i].szComponent;
  477. pszValue = pObjectInfo->ComponentArray[i].szValue;
  478. if (pszComponent && pszValue) {
  479. wcscat(
  480. szParent,
  481. pObjectInfo->ComponentArray[i].szComponent
  482. );
  483. wcscat(szParent,L"=");
  484. wcscat(
  485. szParent,
  486. pObjectInfo->ComponentArray[i].szValue
  487. );
  488. }else if (pszComponent){
  489. wcscat(
  490. szParent,
  491. pObjectInfo->ComponentArray[i].szComponent
  492. );
  493. }else {
  494. //
  495. // Error - we should never hit this case!!
  496. //
  497. }
  498. }
  499. //
  500. // And the common name is the last component
  501. //
  502. pszComponent = pObjectInfo->ComponentArray[dwNumComponents - 1].szComponent;
  503. pszValue = pObjectInfo->ComponentArray[dwNumComponents - 1].szValue;
  504. if (pszComponent && pszValue) {
  505. wsprintf(szCommonName, L"%s=%s",pszComponent, pszValue);
  506. }else if (pszComponent){
  507. wsprintf(szCommonName, L"%s", pszComponent);
  508. }else {
  509. //
  510. // Error - we should never hit this case!!
  511. //
  512. }
  513. }
  514. RRETURN(S_OK);
  515. }
  516. VOID
  517. FreeObjectInfo(
  518. POBJECTINFO pObjectInfo
  519. )
  520. {
  521. if ( !pObjectInfo )
  522. return;
  523. FreeADsStr( pObjectInfo->ProviderName );
  524. FreeADsStr( pObjectInfo->TreeName );
  525. for ( DWORD i = 0; i < pObjectInfo->NumComponents; i++ ) {
  526. if (pObjectInfo->ComponentArray[i].szComponent) {
  527. FreeADsStr( pObjectInfo->ComponentArray[i].szComponent );
  528. }
  529. if (pObjectInfo->ComponentArray[i].szValue) {
  530. FreeADsStr( pObjectInfo->ComponentArray[i].szValue );
  531. }
  532. }
  533. if (pObjectInfo->ComponentArray) {
  534. FreeADsMem(pObjectInfo->ComponentArray);
  535. }
  536. // We don't need to free pObjectInfo since the object is always a static
  537. // variable on the stack.
  538. }
  539. //+---------------------------------------------------------------------------
  540. // Function: GetNamespaceObject
  541. //
  542. // Synopsis: called by GetObject
  543. //
  544. // Arguments: [POBJECTINFO pObjectInfo]
  545. // [LPVOID * ppObject]
  546. //
  547. // Returns: HRESULT
  548. //
  549. // Modifies: -
  550. //
  551. //----------------------------------------------------------------------------
  552. HRESULT
  553. GetNamespaceObject(
  554. POBJECTINFO pObjectInfo,
  555. CCredentials& Credentials,
  556. LPVOID * ppObject
  557. )
  558. {
  559. HRESULT hr;
  560. hr = ValidateNamespaceObject(
  561. pObjectInfo
  562. );
  563. BAIL_ON_FAILURE(hr);
  564. hr = CIISNamespace::CreateNamespace(
  565. L"ADs:",
  566. L"IIS:",
  567. Credentials,
  568. ADS_OBJECT_BOUND,
  569. IID_IUnknown,
  570. ppObject
  571. );
  572. error:
  573. RRETURN(hr);
  574. }
  575. //+---------------------------------------------------------------------------
  576. // Function: GetSchemaObject
  577. //
  578. // Synopsis: called by GetObject
  579. //
  580. // Arguments: [POBJECTINFO pObjectInfo]
  581. // [LPVOID * ppObject]
  582. //
  583. // Returns: HRESULT
  584. //
  585. // Modifies: -
  586. //
  587. //----------------------------------------------------------------------------
  588. HRESULT
  589. GetSchemaObject(
  590. POBJECTINFO pObjectInfo,
  591. IIsSchema *pSchemaCache,
  592. LPVOID * ppObject
  593. )
  594. {
  595. HRESULT hr = S_OK;
  596. DWORD dwObjectType = 0;
  597. hr = ValidateSchemaObject(
  598. pObjectInfo,
  599. &dwObjectType
  600. );
  601. BAIL_ON_FAILURE(hr);
  602. //
  603. // Note: The "error:" tag is at the end of the switch statement,
  604. // so we can simply break out.
  605. //
  606. switch (dwObjectType) {
  607. case IIS_SCHEMA_ID:
  608. hr = GetIntSchemaObject(
  609. pObjectInfo,
  610. ppObject
  611. );
  612. break;
  613. case IIS_CLASSPROP_ID:
  614. hr = GetClassObject(
  615. pObjectInfo,
  616. pSchemaCache,
  617. ppObject
  618. );
  619. if (FAILED(hr)) {
  620. hr = GetPropertyObject(
  621. pObjectInfo,
  622. pSchemaCache,
  623. ppObject
  624. );
  625. if (FAILED(hr)) {
  626. hr = GetSyntaxObject(
  627. pObjectInfo,
  628. ppObject
  629. );
  630. }
  631. if (FAILED(hr)) {
  632. hr = E_ADS_UNKNOWN_OBJECT;
  633. }
  634. }
  635. break;
  636. default:
  637. hr = E_ADS_UNKNOWN_OBJECT;
  638. break;
  639. }
  640. error:
  641. RRETURN(hr);
  642. }
  643. //+---------------------------------------------------------------------------
  644. // Function: GetSchemaObject
  645. //
  646. // Synopsis:
  647. //
  648. // Arguments:
  649. //
  650. // Returns:
  651. //
  652. // Modifies:
  653. //
  654. //----------------------------------------------------------------------------
  655. HRESULT
  656. GetIntSchemaObject(
  657. POBJECTINFO pObjInfo,
  658. LPVOID * ppObject
  659. )
  660. {
  661. LPUNKNOWN pUnknown = NULL;
  662. WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
  663. WCHAR ADsName[MAX_PATH];
  664. HRESULT hr = S_OK;
  665. if (pObjInfo->NumComponents != 1)
  666. RRETURN(E_ADS_BAD_PATHNAME);
  667. if ( _wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 )
  668. {
  669. hr = E_ADS_BAD_PATHNAME;
  670. BAIL_ON_FAILURE(hr);
  671. }
  672. hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
  673. BAIL_ON_FAILURE(hr);
  674. hr = CIISSchema::CreateSchema( pObjInfo->TreeName,
  675. ADsParent,
  676. pObjInfo->ComponentArray[0].szComponent,
  677. ADS_OBJECT_BOUND,
  678. IID_IUnknown,
  679. (void **)&pUnknown );
  680. BAIL_ON_FAILURE(hr);
  681. *ppObject = pUnknown;
  682. RRETURN(hr);
  683. error:
  684. if (pUnknown)
  685. pUnknown->Release();
  686. *ppObject = NULL;
  687. RRETURN(hr);
  688. }
  689. //+---------------------------------------------------------------------------
  690. // Function: GetClassObject
  691. //
  692. // Synopsis:
  693. //
  694. // Arguments:
  695. //
  696. // Returns:
  697. //
  698. // Modifies:
  699. //
  700. //----------------------------------------------------------------------------
  701. HRESULT
  702. GetClassObject(
  703. POBJECTINFO pObjInfo,
  704. IIsSchema *pSchemaCache,
  705. LPVOID * ppObject
  706. )
  707. {
  708. LPUNKNOWN pUnknown = NULL;
  709. WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
  710. WCHAR ADsName[MAX_PATH];
  711. HRESULT hr = S_OK;
  712. DWORD i;
  713. DWORD dwNumComponents = pObjInfo->NumComponents;
  714. if ( dwNumComponents != 2 && dwNumComponents != 3)
  715. RRETURN(E_ADS_BAD_PATHNAME);
  716. if ( (dwNumComponents == 2 &&
  717. _wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 ) ||
  718. (dwNumComponents == 3 &&
  719. _wcsicmp( pObjInfo->ComponentArray[0].szComponent, CLASS_CLASS_NAME ) != 0 ))
  720. {
  721. hr = E_ADS_BAD_PATHNAME;
  722. BAIL_ON_FAILURE(hr);
  723. }
  724. //
  725. // Validate the given class name
  726. //
  727. hr = pSchemaCache->ValidateClassName(
  728. pObjInfo->ComponentArray[dwNumComponents-1].szComponent);
  729. BAIL_ON_FAILURE(hr);
  730. //
  731. // Class name found, create and return the object
  732. //
  733. hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
  734. BAIL_ON_FAILURE(hr);
  735. hr = CIISClass::CreateClass( ADsParent,
  736. pObjInfo->ComponentArray[dwNumComponents-1].szComponent,
  737. ADS_OBJECT_BOUND,
  738. IID_IUnknown,
  739. (void **)&pUnknown );
  740. BAIL_ON_FAILURE(hr);
  741. *ppObject = pUnknown;
  742. RRETURN(hr);
  743. error:
  744. if (pUnknown)
  745. pUnknown->Release();
  746. *ppObject = NULL;
  747. RRETURN(hr);
  748. }
  749. //+---------------------------------------------------------------------------
  750. // Function: GetSyntaxObject
  751. //
  752. // Synopsis:
  753. //
  754. // Arguments:
  755. //
  756. // Returns:
  757. //
  758. // Modifies:
  759. //
  760. //----------------------------------------------------------------------------
  761. HRESULT
  762. GetSyntaxObject(
  763. POBJECTINFO pObjInfo,
  764. LPVOID * ppObject
  765. )
  766. {
  767. LPUNKNOWN pUnknown = NULL;
  768. WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
  769. WCHAR ADsName[MAX_PATH];
  770. HRESULT hr = S_OK;
  771. DWORD i;
  772. DWORD dwNumComponents = pObjInfo->NumComponents;
  773. if (dwNumComponents != 2 && dwNumComponents != 3)
  774. RRETURN(E_ADS_BAD_PATHNAME);
  775. if ( (dwNumComponents == 2 &&
  776. _wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 ) ||
  777. (dwNumComponents == 3 &&
  778. _wcsicmp( pObjInfo->ComponentArray[0].szComponent, SYNTAX_CLASS_NAME ) != 0 ))
  779. {
  780. hr = E_ADS_BAD_PATHNAME;
  781. BAIL_ON_FAILURE(hr);
  782. }
  783. //
  784. // Look for the given syntax name
  785. //
  786. for ( i = 0; i < g_cIISSyntax; i++ )
  787. {
  788. if ( _wcsicmp( g_aIISSyntax[i].bstrName,
  789. pObjInfo->ComponentArray[dwNumComponents-1].szComponent ) == 0 )
  790. break;
  791. }
  792. if ( i == g_cIISSyntax )
  793. {
  794. // Syntax name not found, return error
  795. hr = E_ADS_BAD_PATHNAME;
  796. BAIL_ON_FAILURE(hr);
  797. }
  798. //
  799. // Syntax name found, create and return the object
  800. //
  801. hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
  802. BAIL_ON_FAILURE(hr);
  803. hr = CIISSyntax::CreateSyntax( ADsParent,
  804. &(g_aIISSyntax[i]),
  805. ADS_OBJECT_BOUND,
  806. IID_IUnknown,
  807. (void **)&pUnknown );
  808. BAIL_ON_FAILURE(hr);
  809. *ppObject = pUnknown;
  810. RRETURN(hr);
  811. error:
  812. if (pUnknown)
  813. pUnknown->Release();
  814. *ppObject = NULL;
  815. RRETURN(hr);
  816. }
  817. //+---------------------------------------------------------------------------
  818. // Function: GetPropertyObject
  819. //
  820. // Synopsis:
  821. //
  822. // Arguments:
  823. //
  824. // Returns:
  825. //
  826. // Modifies:
  827. //
  828. //----------------------------------------------------------------------------
  829. HRESULT
  830. GetPropertyObject(
  831. POBJECTINFO pObjInfo,
  832. IIsSchema *pSchemaCache,
  833. LPVOID * ppObject
  834. )
  835. {
  836. LPUNKNOWN pUnknown = NULL;
  837. WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
  838. WCHAR ADsName[MAX_PATH];
  839. HRESULT hr = S_OK;
  840. DWORD i;
  841. DWORD dwNumComponents = pObjInfo->NumComponents;
  842. if (dwNumComponents != 2 && dwNumComponents != 3)
  843. RRETURN(E_ADS_BAD_PATHNAME);
  844. if ( (dwNumComponents == 2 &&
  845. _wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 ) ||
  846. (dwNumComponents == 3 &&
  847. _wcsicmp( pObjInfo->ComponentArray[0].szComponent, PROPERTY_CLASS_NAME ) != 0 ))
  848. {
  849. hr = E_ADS_BAD_PATHNAME;
  850. BAIL_ON_FAILURE(hr);
  851. }
  852. //
  853. // Validate the given property name
  854. //
  855. hr = pSchemaCache->ValidatePropertyName(
  856. pObjInfo->ComponentArray[dwNumComponents-1].szComponent);
  857. BAIL_ON_FAILURE(hr);
  858. //
  859. // Property name is found, so create and return the object
  860. //
  861. hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
  862. BAIL_ON_FAILURE(hr);
  863. hr = CIISProperty::CreateProperty(
  864. ADsParent,
  865. pObjInfo->ComponentArray[dwNumComponents-1].szComponent,
  866. ADS_OBJECT_BOUND,
  867. IID_IUnknown,
  868. (void **)&pUnknown );
  869. BAIL_ON_FAILURE(hr);
  870. *ppObject = pUnknown;
  871. RRETURN(hr);
  872. error:
  873. if (pUnknown)
  874. pUnknown->Release();
  875. *ppObject = NULL;
  876. RRETURN(hr);
  877. }
  878. HRESULT
  879. ValidateNamespaceObject(
  880. POBJECTINFO pObjectInfo
  881. )
  882. {
  883. if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) {
  884. RRETURN(S_OK);
  885. }
  886. RRETURN(E_FAIL);
  887. }
  888. HRESULT
  889. ValidateProvider(
  890. POBJECTINFO pObjectInfo
  891. )
  892. {
  893. //
  894. // The provider name is case-sensitive. This is a restriction that OLE
  895. // has put on us.
  896. //
  897. if (!(wcscmp(pObjectInfo->ProviderName, szProviderName))) {
  898. RRETURN(S_OK);
  899. }
  900. RRETURN(E_FAIL);
  901. }
  902. HRESULT
  903. ValidateObjectType(
  904. POBJECTINFO pObjectInfo
  905. )
  906. {
  907. if (pObjectInfo->ProviderName && !pObjectInfo->TreeName
  908. && !pObjectInfo->NumComponents) {
  909. pObjectInfo->ObjectType = TOKEN_NAMESPACE;
  910. }else if (pObjectInfo->ProviderName && pObjectInfo->TreeName
  911. && pObjectInfo->NumComponents) {
  912. if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"schema")) {
  913. pObjectInfo->ObjectType = TOKEN_SCHEMA;
  914. }
  915. else if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"class")) {
  916. pObjectInfo->ObjectType = TOKEN_CLASS;
  917. }
  918. else if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"property")) {
  919. pObjectInfo->ObjectType = TOKEN_PROPERTY;
  920. }
  921. else if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"syntax")) {
  922. pObjectInfo->ObjectType = TOKEN_SYNTAX;
  923. }
  924. }
  925. RRETURN(S_OK);
  926. }
  927. HRESULT
  928. ValidateSchemaObject(
  929. POBJECTINFO pObjectInfo,
  930. PDWORD pdwObjectType
  931. )
  932. {
  933. DWORD dwNumComponents = 0;
  934. dwNumComponents = pObjectInfo->NumComponents;
  935. switch (dwNumComponents) {
  936. case 1:
  937. if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent, L"schema")) {
  938. *pdwObjectType = IIS_SCHEMA_ID;
  939. RRETURN(S_OK);
  940. }
  941. break;
  942. case 2:
  943. *pdwObjectType = IIS_CLASSPROP_ID;
  944. RRETURN(S_OK);
  945. default:
  946. break;
  947. }
  948. RRETURN(E_FAIL);
  949. }