Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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