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.

660 lines
20 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 1997-1998 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: sdohelperfuncs.cpp
  6. //
  7. // Project: Everest
  8. //
  9. // Description: Helper Functions
  10. //
  11. // Log:
  12. //
  13. // When Who What
  14. // ---- --- ----
  15. // 6/08/98 TLP Initial Version
  16. // 9/06/98 TLP Added data store helpers
  17. // 9/09/98 TLP Added misc helpers
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include <iascomp.h>
  22. #include <iasutil.h>
  23. #include "sdohelperfuncs.h"
  24. #include "sdoproperty.h"
  25. #include "sdo.h"
  26. ///////////////////////////////////////////////////////////////////
  27. HRESULT SDOGetCollectionEnumerator(
  28. /*[in]*/ ISdo* pSdo,
  29. /*[in]*/ LONG lPropertyId,
  30. /*[out]*/ IEnumVARIANT** ppEnum
  31. )
  32. {
  33. HRESULT hr;
  34. CComPtr<IUnknown> pUnknown;
  35. CComPtr<ISdoCollection> pSdoCollection;
  36. _variant_t vtDispatch;
  37. _ASSERT( NULL != pSdo && NULL == *ppEnum );
  38. hr = pSdo->GetProperty(lPropertyId, &vtDispatch);
  39. _ASSERT( VT_DISPATCH == V_VT(&vtDispatch) );
  40. if ( SUCCEEDED(hr) )
  41. {
  42. hr = vtDispatch.pdispVal->QueryInterface(IID_ISdoCollection, (void**)&pSdoCollection);
  43. if ( SUCCEEDED(hr) )
  44. {
  45. hr = pSdoCollection->get__NewEnum(&pUnknown);
  46. if ( SUCCEEDED(hr) )
  47. {
  48. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)ppEnum);
  49. }
  50. }
  51. }
  52. if ( FAILED(hr) )
  53. IASTracePrintf("Error in SDO Helper - SDOGetCollectionEnumerator() failed...");
  54. return hr;
  55. }
  56. ///////////////////////////////////////////////////////////////////
  57. HRESULT SDONextObjectFromCollection(
  58. /*[in]*/ IEnumVARIANT* pEnum,
  59. /*[out]*/ ISdo** ppSdo
  60. )
  61. {
  62. HRESULT hr;
  63. DWORD dwRetrieved = 1;
  64. _variant_t vtDispatch;
  65. _ASSERT( NULL != pEnum && NULL == *ppSdo );
  66. hr = pEnum->Next(1, &vtDispatch, &dwRetrieved);
  67. _ASSERT( S_OK == hr || S_FALSE == hr );
  68. if ( S_OK == hr )
  69. {
  70. hr = vtDispatch.pdispVal->QueryInterface(IID_ISdo, (void**)ppSdo);
  71. if ( FAILED(hr) )
  72. IASTracePrintf("Error in SDO Helper - SDOGetNextObjectFromCollection() failed...");
  73. }
  74. return hr;
  75. }
  76. ///////////////////////////////////////////////////////////////////
  77. HRESULT SDOGetComponentFromCollection(
  78. /*[in]*/ ISdo* pSdoServer,
  79. /*[in]*/ LONG lCollectionPropertyId,
  80. /*[in]*/ LONG lComponentId,
  81. /*[out]*/ ISdo** ppSdo
  82. )
  83. {
  84. HRESULT hr;
  85. CComPtr<IEnumVARIANT> pEnum;
  86. CComPtr<ISdo> pSdo;
  87. LONG ComponentId;
  88. do
  89. {
  90. hr = SDOGetCollectionEnumerator(
  91. pSdoServer,
  92. lCollectionPropertyId,
  93. &pEnum
  94. );
  95. if ( FAILED(hr) )
  96. break;
  97. hr = SDONextObjectFromCollection(pEnum,&pSdo);
  98. while( S_OK == hr )
  99. {
  100. hr = SDOGetComponentIdFromObject(
  101. pSdo,
  102. &ComponentId
  103. );
  104. if ( FAILED(hr) )
  105. break;
  106. if ( ComponentId == lComponentId )
  107. {
  108. pSdo.p->AddRef();
  109. *ppSdo = pSdo;
  110. break;
  111. }
  112. pSdo.Release();
  113. hr = SDONextObjectFromCollection(pEnum,&pSdo);
  114. }
  115. if ( S_OK != hr )
  116. hr = E_FAIL;
  117. } while ( FALSE );
  118. return hr;
  119. }
  120. ///////////////////////////////////////////////////////////////////
  121. HRESULT SDOConfigureComponentFromObject(
  122. /*[in]*/ ISdo* pSdo,
  123. /*[in]*/ IIasComponent* pComponent
  124. )
  125. {
  126. HRESULT hr = E_FAIL;
  127. do
  128. {
  129. _ASSERT( NULL != pSdo && NULL != pComponent );
  130. CComPtr<IUnknown> pUnknown;
  131. hr = pSdo->get__NewEnum(&pUnknown);
  132. if ( FAILED(hr) )
  133. {
  134. IASTracePrintf("Error in SDO - SDOConfigureComponentFromObject() - get__NewEnum() failed... %x", hr);
  135. break;
  136. }
  137. CComPtr<IEnumVARIANT> pEnumProperties;
  138. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)&pEnumProperties);
  139. if ( FAILED(hr) )
  140. {
  141. IASTracePrintf("Error in SDO - SDOConfigureComponentFromObject() - QueryInterface(IID_IEnumVARIANT) failed... %x", hr);
  142. break;
  143. }
  144. LONG flags;
  145. LONG alias;
  146. _variant_t vtProperty;
  147. CComPtr<ISdoPropertyInfo> pSdoPropertyInfo;
  148. hr = SDONextPropertyFromClass(pEnumProperties, &pSdoPropertyInfo);
  149. while ( S_OK == hr )
  150. {
  151. hr = pSdoPropertyInfo->get_Flags(&flags);
  152. if ( FAILED(hr) )
  153. {
  154. IASTracePrintf("Error in SDO - SDOConfigureComponentFromObject() - ISdoPropertyInfo::get_Flags() failed... %x", hr);
  155. break;
  156. }
  157. if ( SDO_PROPERTY_COMPONENT & flags )
  158. {
  159. hr = pSdoPropertyInfo->get_Alias(&alias);
  160. if ( FAILED(hr) )
  161. {
  162. IASTracePrintf("Error in SDO - SDOConfigureComponentFromObject() - ISdoPropertyInfo::get_Alias() failed... %x", hr);
  163. break;
  164. }
  165. hr = pSdo->GetProperty(alias, &vtProperty);
  166. if ( FAILED(hr) )
  167. {
  168. IASTracePrintf("Error in SDO - SDOConfigureComponentFromObject() - ISdo::GetProperty() failed... %x", hr);
  169. break;
  170. }
  171. hr = pComponent->PutProperty(alias, &vtProperty);
  172. if ( FAILED(hr) )
  173. {
  174. IASTracePrintf("Error in SDO - SDOConfigureComponentFromObject() - ISdo::PutProperty() failed... %x", hr);
  175. break;
  176. }
  177. vtProperty.Clear();
  178. }
  179. pSdoPropertyInfo.Release();
  180. hr = SDONextPropertyFromClass(pEnumProperties, &pSdoPropertyInfo);
  181. }
  182. if ( S_FALSE == hr )
  183. hr = S_OK;
  184. } while (FALSE);
  185. return hr;
  186. }
  187. ///////////////////////////////////////////////////////////////////
  188. HRESULT SDOGetComponentIdFromObject(
  189. /*[in]*/ ISdo* pSdo,
  190. /*[out]*/ PLONG pComponentId
  191. )
  192. {
  193. _ASSERT( NULL != pSdo && NULL != pComponentId );
  194. HRESULT hr;
  195. _variant_t vtProperty;
  196. hr = pSdo->GetProperty(PROPERTY_COMPONENT_ID, &vtProperty);
  197. if ( SUCCEEDED(hr) )
  198. {
  199. _ASSERT( VT_I4 == V_VT(&vtProperty) );
  200. *pComponentId = V_I4(&vtProperty);
  201. }
  202. else
  203. {
  204. IASTracePrintf("Error in SDO Helper - SDOGetComponentIdFromObject() failed...");
  205. }
  206. return hr;
  207. }
  208. ///////////////////////////////////////////////////////////////////
  209. HRESULT SDOCreateComponentFromObject(
  210. /*[in]*/ ISdo* pSdo,
  211. /*[out]*/ IIasComponent** ppComponent
  212. )
  213. {
  214. HRESULT hr;
  215. _variant_t vtProgId;
  216. CLSID clsId;
  217. _ASSERT( NULL != pSdo && NULL == *ppComponent );
  218. hr = pSdo->GetProperty(PROPERTY_COMPONENT_PROG_ID, &vtProgId);
  219. if ( SUCCEEDED(hr) )
  220. {
  221. _ASSERT( VT_BSTR == V_VT(&vtProgId) );
  222. hr = CLSIDFromProgID(V_BSTR(&vtProgId), &clsId);
  223. if ( SUCCEEDED(hr) )
  224. {
  225. hr = CoCreateInstance(
  226. clsId,
  227. NULL,
  228. CLSCTX_INPROC_SERVER,
  229. IID_IIasComponent,
  230. (void**)ppComponent
  231. );
  232. }
  233. }
  234. if ( FAILED(hr) )
  235. IASTracePrintf("Error in SDO Helper - SDOCreateComponentFromObject() failed...");
  236. return hr;
  237. }
  238. //////////////////////////////////////////////////////////////////////////////
  239. HRESULT SDOGetContainedObject(
  240. /*[in]*/ BSTR bstrObjectName,
  241. /*[in]*/ IDataStoreObject* pDSObject,
  242. /*[out]*/ IDataStoreObject** ppDSObject
  243. )
  244. {
  245. CComPtr<IDataStoreContainer> pDSContainer;
  246. HRESULT hr = pDSObject->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
  247. if ( FAILED(hr) )
  248. {
  249. IASTracePrintf("Error in SDO Schema - BuildClasses() - QueryInterface(1) failed...");
  250. return hr;
  251. }
  252. hr = pDSContainer->Item(bstrObjectName, ppDSObject);
  253. if ( FAILED(hr) )
  254. IASTracePrintf("Error in SDO Schema - BuildClasses() - Item('%ls') failed...", bstrObjectName);
  255. return hr;
  256. }
  257. //////////////////////////////////////////////////////////////////////////////
  258. HRESULT SDOGetContainerEnumerator(
  259. /*[in]*/ IDataStoreObject* pDSObject,
  260. /*[out]*/ IEnumVARIANT** ppObjectEnumerator
  261. )
  262. {
  263. CComPtr<IDataStoreContainer> pDSContainer;
  264. HRESULT hr = pDSObject->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
  265. if ( FAILED(hr) )
  266. {
  267. IASTracePrintf("Error in SDO - GetContainerEnumerator() - QueryInterface(IDataStoreContainer) returned %lx...", hr);
  268. return hr;
  269. }
  270. CComPtr<IUnknown> pUnknown;
  271. hr = pDSContainer->get__NewEnum(&pUnknown);
  272. if ( FAILED(hr) )
  273. {
  274. IASTracePrintf("Error in SDO - GetContainerEnumerator - get__NewEnum() returned %lx...", hr);
  275. return hr;
  276. }
  277. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)ppObjectEnumerator);
  278. if ( FAILED(hr) )
  279. {
  280. IASTracePrintf("Error in SDO - GetContainerEnumerator() - QueryInterface(IID_IEnumVARIANT) returned %lx...",hr);
  281. return hr;
  282. }
  283. return hr;
  284. }
  285. //////////////////////////////////////////////////////////////////////////////
  286. HRESULT SDONextObjectFromContainer(
  287. /*[in]*/ IEnumVARIANT* pEnumVariant,
  288. /*[out]*/ IDataStoreObject** ppDSObject
  289. )
  290. {
  291. _variant_t vt;
  292. DWORD dwRetrieved = 1;
  293. HRESULT hr = pEnumVariant->Next(1, &vt, &dwRetrieved);
  294. if ( S_OK == hr )
  295. {
  296. hr = vt.pdispVal->QueryInterface(IID_IDataStoreObject,(void**)ppDSObject);
  297. if ( FAILED(hr) )
  298. IASTracePrintf("Error in SDO - GetNextObjectFromContainer() - QueryInterface(IDataStoreObject) failed...");
  299. }
  300. return hr;
  301. }
  302. //////////////////////////////////////////////////////////////////////////////
  303. HRESULT SDOGetObjectPropertyEnumerator(
  304. /*[in]*/ IDataStoreObject* pDSObject,
  305. /*[out]*/ IEnumVARIANT** ppPropertyEnumerator
  306. )
  307. {
  308. CComPtr<IUnknown> pUnknown;
  309. HRESULT hr = pDSObject->get__NewEnum(&pUnknown);
  310. if ( FAILED(hr) )
  311. {
  312. IASTracePrintf("Error in SDO Schema - GetObjectPropertyEnumerator() - get__NewEnum() failed...");
  313. return hr;
  314. }
  315. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)ppPropertyEnumerator);
  316. if ( FAILED(hr) )
  317. IASTracePrintf("Error in SDO Schema - GetObjectPropertyEnumerator() - QueryInterface(IID_IEnumVARIANT) failed...");
  318. return hr;
  319. }
  320. //////////////////////////////////////////////////////////////////////////////
  321. HRESULT SDONextPropertyFromObject(
  322. /*[in]*/ IEnumVARIANT* pEnumVariant,
  323. /*[out]*/ IDataStoreProperty** ppDSProperty
  324. )
  325. {
  326. _variant_t vt;
  327. DWORD dwRetrieved = 1;
  328. HRESULT hr = pEnumVariant->Next(1, &vt, &dwRetrieved);
  329. if ( S_OK == hr )
  330. {
  331. hr = vt.pdispVal->QueryInterface(IID_IDataStoreObject,(void**)ppDSProperty);
  332. if ( FAILED(hr) )
  333. IASTracePrintf("Error in SDO - GetNextPropertyFromObject() - QueryInterface(IDataStoreProperty) failed...");
  334. }
  335. return hr;
  336. }
  337. //////////////////////////////////////////////////////////////////////////////
  338. HRESULT SDOGetClassPropertyEnumerator(
  339. /*[in]*/ CLASSPROPERTYSET ePropertySet,
  340. /*[in]*/ ISdoClassInfo* pSdoClassInfo,
  341. /*[out]*/ IEnumVARIANT** ppPropertyEnumerator
  342. )
  343. {
  344. CComPtr<IUnknown> pUnknown;
  345. HRESULT hr;
  346. if ( PROPERTY_SET_REQUIRED == ePropertySet )
  347. {
  348. hr = pSdoClassInfo->get_RequiredProperties(&pUnknown);
  349. }
  350. else
  351. {
  352. _ASSERT( PROPERTY_SET_OPTIONAL == ePropertySet );
  353. hr = pSdoClassInfo->get_OptionalProperties(&pUnknown);
  354. }
  355. if ( FAILED(hr) )
  356. {
  357. IASTracePrintf("Error in SDO Schema - GetClassPropertyEnumerator() - get__NewEnum() failed...");
  358. return hr;
  359. }
  360. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)ppPropertyEnumerator);
  361. if ( FAILED(hr) )
  362. {
  363. IASTracePrintf("Error in SDO Schema - GetClassPropertyEnumerator() - QueryInterface(IID_IEnumVARIANT) failed...");
  364. return hr;
  365. }
  366. return S_OK;
  367. }
  368. //////////////////////////////////////////////////////////////////////////////
  369. HRESULT SDONextPropertyFromClass(
  370. /*[in]*/ IEnumVARIANT* pEnumVariant,
  371. /*[out]*/ ISdoPropertyInfo** ppSdoPropertyInfo
  372. )
  373. {
  374. _variant_t vt;
  375. DWORD dwRetrieved = 1;
  376. HRESULT hr = pEnumVariant->Next(1, &vt, &dwRetrieved);
  377. if ( S_OK == hr )
  378. {
  379. hr = vt.punkVal->QueryInterface(IID_ISdoPropertyInfo,(void**)ppSdoPropertyInfo);
  380. if ( FAILED(hr) )
  381. IASTracePrintf("Error in SDO - GetNextPropertyFromClass() - QueryInterface(ISdoPropertyInfo) failed...");
  382. }
  383. return hr;
  384. }
  385. //////////////////////////////////////////////////////////////////////////////
  386. BOOL SDOIsNameUnique(
  387. /*[in]*/ ISdoCollection* pSdoCollection,
  388. /*[in]*/ VARIANT* pName
  389. )
  390. {
  391. // Get the data store containers enumerator
  392. //
  393. CComPtr<IUnknown> pUnknown;
  394. HRESULT hr = pSdoCollection->get__NewEnum(&pUnknown);
  395. if ( FAILED(hr) )
  396. return FALSE;
  397. CComPtr<IEnumVARIANT> pEnumVariant;
  398. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)&pEnumVariant);
  399. if ( FAILED(hr) )
  400. {
  401. IASTracePrintf("Error in SDO - IsNameUnique() - QueryInterface(IID_IEnumVARIANT) failed...");
  402. return FALSE;
  403. }
  404. CComPtr<ISdo> pSdo;
  405. _variant_t vtName;
  406. hr = ::SDONextObjectFromCollection(pEnumVariant, &pSdo);
  407. while ( S_OK == hr )
  408. {
  409. hr = pSdo->GetProperty(PROPERTY_SDO_NAME, &vtName);
  410. if ( FAILED(hr) )
  411. break;
  412. if ( 0 == lstrcmpi(V_BSTR(pName), V_BSTR(&vtName) ) )
  413. break;
  414. vtName.Clear();
  415. pSdo.Release();
  416. hr = ::SDONextObjectFromCollection(pEnumVariant, &pSdo);
  417. }
  418. if ( S_FALSE == hr )
  419. return TRUE;
  420. else
  421. return FALSE;
  422. }
  423. //////////////////////////////////////////////////////////////////////////
  424. HRESULT ValidateDNSName(
  425. /*[in]*/ VARIANT* pValue
  426. )
  427. {
  428. // Is it a BSTR?
  429. if (V_VT(pValue) != VT_BSTR) { return E_INVALIDARG; }
  430. // Is it dotted decimal?
  431. if (wcsspn(V_BSTR(pValue), L"0123456789.") == wcslen(V_BSTR(pValue)))
  432. {
  433. // If so, then make sure it can be converted.
  434. if (ias_inet_wtoh(V_BSTR(pValue)) == 0xffffffff)
  435. {
  436. return E_INVALIDARG;
  437. }
  438. }
  439. return S_OK;
  440. }
  441. #define SYSTEM_ROOT_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
  442. #define SYSTEM_ROOT_VALUE L"SystemRoot"
  443. #define LOG_FILE_DIR L"\\system32\\LogFiles"
  444. //////////////////////////////////////////////////////////////////////////////
  445. HRESULT SDOGetLogFileDirectory(
  446. /*[in]*/ LPCWSTR lpszComputerName,
  447. /*[in]*/ DWORD dwLogFileDirectorySize,
  448. /*[out*/ PWCHAR pLogFileDirectory
  449. )
  450. {
  451. _ASSERT( pLogFileDirectory != NULL && dwLogFileDirectorySize > 0 );
  452. HRESULT hr = E_FAIL;
  453. do
  454. {
  455. LONG lResult = ERROR_SUCCESS;
  456. HKEY hKeyRemote = HKEY_LOCAL_MACHINE;
  457. DWORD dwSize = MAX_PATH;
  458. wchar_t szBuffer[MAX_PATH + 1];
  459. if ( lpszComputerName )
  460. {
  461. // Is lpszComputerName the name of the local machine?
  462. //
  463. GetComputerName(szBuffer, &dwSize);
  464. if ( lstrcmpi(szBuffer, lpszComputerName ) )
  465. {
  466. // Nope... we're attached to a remote computer so connect to the
  467. // remote machine's registry.
  468. //
  469. lResult = RegConnectRegistry(
  470. lpszComputerName,
  471. HKEY_LOCAL_MACHINE,
  472. &hKeyRemote
  473. );
  474. }
  475. }
  476. if ( ERROR_SUCCESS != lResult )
  477. {
  478. IASTracePrintf("Error in GetLogFileDirectory() - Could not attach to the remote registry..");
  479. hr = HRESULT_FROM_WIN32(GetLastError());
  480. break;
  481. }
  482. // Open the "CurrentVersion" key
  483. //
  484. CRegKey CurVerKey;
  485. lResult = CurVerKey.Open(
  486. hKeyRemote,
  487. SYSTEM_ROOT_REG_KEY,
  488. KEY_READ
  489. );
  490. if ( ERROR_SUCCESS != lResult )
  491. {
  492. IASTracePrintf("Error in GetLogFileDirectory() - Could not open the 'system root' registry key..");
  493. hr = HRESULT_FROM_WIN32(GetLastError());
  494. break;
  495. }
  496. // Get the value of the "SystemRoot" Registry entry
  497. //
  498. dwSize = MAX_PATH;
  499. lResult = CurVerKey.QueryValue(
  500. szBuffer,
  501. (LPCTSTR)SYSTEM_ROOT_VALUE,
  502. &dwSize
  503. );
  504. if ( ERROR_SUCCESS != lResult )
  505. {
  506. IASTracePrintf("Error in SDO Schema - SetDefaults() - Could not get the 'system root' registry value..");
  507. hr = HRESULT_FROM_WIN32(GetLastError());
  508. break;
  509. }
  510. // Now build the default log file directory path
  511. //
  512. if ( lstrlen(szBuffer) + lstrlen(LOG_FILE_DIR) >= dwLogFileDirectorySize )
  513. {
  514. IASTracePrintf("Error in GetLogFileDirectory() - system root directory path is too long..");
  515. hr = E_UNEXPECTED;
  516. break;
  517. }
  518. wsprintf(
  519. pLogFileDirectory,
  520. L"%s%s",
  521. szBuffer,
  522. LOG_FILE_DIR
  523. );
  524. hr = S_OK;
  525. } while ( FALSE );
  526. return hr;
  527. }
  528. //////////////////////////////////////////////////////////////////////////////
  529. BEGIN_CLASSTOPROGID_MAP(SdoClassNameToProgID)
  530. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_ATTRIBUTE, SDO_PROG_ID_ATTRIBUTE)
  531. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_CLIENT, SDO_PROG_ID_CLIENT)
  532. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_CONDITION, SDO_PROG_ID_CONDITION)
  533. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_DICTIONARY, SDO_PROG_ID_DICTIONARY)
  534. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_PROFILE, SDO_PROG_ID_PROFILE)
  535. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_POLICY, SDO_PROG_ID_POLICY)
  536. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_SERVICE, SDO_PROG_ID_SERVICE)
  537. // DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_USER, SDO_PROG_ID_USER)
  538. DEFINE_CLASSTOPROGID_ENTRY(SDO_CLASS_NAME_VENDOR, SDO_PROG_ID_VENDOR)
  539. END_CLASSTOPROGID_MAP()
  540. //////////////////////////////////////////////////////////////////////////////
  541. LPWSTR GetDataStoreClass(
  542. /*[in]*/ LPCWSTR lpszSdoProgId
  543. )
  544. {
  545. PCLASSTOPROGID pClassToProgId = SdoClassNameToProgID;
  546. while ( pClassToProgId->pDatastoreClass )
  547. {
  548. if ( 0 == lstrcmp(pClassToProgId->pSdoProgId, lpszSdoProgId) )
  549. return pClassToProgId->pDatastoreClass;
  550. pClassToProgId++;
  551. }
  552. return SDO_CLASS_NAME_COMPONENT;
  553. }
  554. HRESULT SDOGetProductLimits(
  555. IUnknown* source,
  556. IAS_PRODUCT_LIMITS* result
  557. ) throw ()
  558. {
  559. if ((source == 0) || (result == 0))
  560. {
  561. return E_POINTER;
  562. }
  563. CComPtr<IASProductLimits> limits;
  564. HRESULT hr = source->QueryInterface(
  565. __uuidof(IASProductLimits),
  566. reinterpret_cast<void**>(&limits)
  567. );
  568. if (SUCCEEDED(hr))
  569. {
  570. hr = limits->get_Limits(result);
  571. }
  572. return hr;
  573. }