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.

1846 lines
42 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Microsoft WMIOLE DB Provider
  3. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // dataconvert.cpp
  6. //
  7. ////////////////////////////////////////////////////////////////////////////
  8. #include "headers.h"
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. //
  11. // This function returns the default OLE DB representation for a data type
  12. //
  13. // To be used only to create tables or any other things
  14. // But should not be used for setting properties of type ARRAYS
  15. //
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. HRESULT CDataMap::MapOLEDBTypeToCIMType(WORD wDataType, long & lCIMType)
  18. {
  19. HRESULT hr = S_OK;
  20. BOOL bArray = FALSE;
  21. if( wDataType & DBTYPE_ARRAY)
  22. {
  23. bArray = TRUE;
  24. wDataType = wDataType & ~DBTYPE_ARRAY;
  25. }
  26. switch( wDataType ){
  27. case DBTYPE_I1:
  28. lCIMType = CIM_SINT8;
  29. break;
  30. case DBTYPE_UI1:
  31. lCIMType = CIM_UINT8;
  32. break;
  33. case DBTYPE_I2:
  34. lCIMType = CIM_SINT16;
  35. break;
  36. case DBTYPE_UI2:
  37. lCIMType = CIM_UINT16;
  38. break;
  39. case DBTYPE_I4:
  40. lCIMType = CIM_SINT32;
  41. break;
  42. case DBTYPE_UI4:
  43. lCIMType = CIM_UINT32;
  44. break;
  45. case DBTYPE_I8:
  46. lCIMType = CIM_SINT64;
  47. break;
  48. case DBTYPE_UI8:
  49. lCIMType = CIM_UINT64;
  50. break;
  51. case DBTYPE_R4:
  52. lCIMType = CIM_REAL32;
  53. break;
  54. case DBTYPE_R8:
  55. lCIMType = CIM_REAL64;
  56. break;
  57. case DBTYPE_BOOL:
  58. lCIMType = CIM_BOOLEAN;
  59. break;
  60. case DBTYPE_WSTR:
  61. case DBTYPE_BSTR:
  62. case DBTYPE_STR:
  63. lCIMType = CIM_STRING;
  64. break;
  65. case DBTYPE_DATE :
  66. case DBTYPE_DBTIME :
  67. case DBTYPE_DBTIMESTAMP:
  68. lCIMType = CIM_DATETIME;
  69. break;
  70. case DBTYPE_IDISPATCH :
  71. case DBTYPE_IUNKNOWN :
  72. lCIMType = CIM_IUNKNOWN;
  73. break;
  74. case DBTYPE_VARIANT:
  75. hr = E_FAIL;
  76. break;
  77. default:
  78. assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
  79. }
  80. if( bArray == TRUE)
  81. {
  82. lCIMType |= CIM_FLAG_ARRAY;
  83. }
  84. return hr;
  85. }
  86. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. // Function to Map CIMType to OLEDB type and allocate memory for the data
  88. // NTRaid:111819 - 111822
  89. // 06/07/00
  90. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  91. HRESULT CDataMap::AllocateAndMapCIMTypeToOLEDBType(CVARIANT & vValue,BYTE *& pData,DBTYPE & dwColType,DBLENGTH & dwSize, DWORD &dwFlags)
  92. {
  93. HRESULT hr = S_OK;
  94. SAFEARRAY *pArray = NULL;
  95. LONG lType= 0;
  96. VARIANT *pVar = NULL,*pvar2 = NULL;
  97. pData = NULL;
  98. lType = vValue.GetType();
  99. if(lType != VT_NULL && lType != VT_NULL)
  100. {
  101. lType = dwColType;
  102. // If the type is of some array
  103. if (dwColType & CIM_FLAG_ARRAY)
  104. {
  105. lType = CIM_FLAG_ARRAY;
  106. }
  107. }
  108. try
  109. {
  110. switch( lType ){
  111. case VT_NULL:
  112. pData = NULL;
  113. hr = DBSTATUS_S_ISNULL;
  114. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  115. break;
  116. case VT_EMPTY:
  117. pData = NULL;
  118. hr = DBSTATUS_S_ISNULL;
  119. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  120. break;
  121. // Arrays are always shown as ARRAY of VARIANTS to make it easily accessible with scripting
  122. case CIM_FLAG_ARRAY:
  123. lType = vValue.GetType();
  124. // since date is given out as string from WMI
  125. if(IsDateType((DBTYPE)dwColType))
  126. {
  127. lType = dwColType;
  128. }
  129. hr = ConvertToVariantArray(((VARIANT *)&vValue)->parray,(DBTYPE)lType,(SAFEARRAY **)&pData);
  130. dwSize = sizeof(SAFEARRAY);
  131. dwColType = VT_ARRAY | VT_VARIANT;
  132. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  133. break;
  134. case CIM_SINT8:
  135. case CIM_UINT8:
  136. pData = new BYTE[1];
  137. if(pData)
  138. {
  139. *pData = (BYTE)vValue.GetByte();
  140. dwSize = sizeof(BYTE);
  141. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  142. }
  143. else
  144. {
  145. hr = E_OUTOFMEMORY;
  146. }
  147. break;
  148. case CIM_CHAR16:
  149. case CIM_SINT16:
  150. case CIM_UINT16:
  151. case CIM_BOOLEAN:
  152. {
  153. dwSize = sizeof(short);
  154. pData = new BYTE[dwSize];
  155. short tmp = vValue.GetShort();
  156. if(pData)
  157. {
  158. memcpy(pData,(BYTE*)&tmp,dwSize);
  159. }
  160. else
  161. {
  162. hr = E_OUTOFMEMORY;
  163. }
  164. }
  165. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  166. break;
  167. case CIM_SINT32:
  168. case CIM_UINT32:
  169. case CIM_REAL32:
  170. {
  171. dwSize = sizeof(long);
  172. long tmp = vValue.GetLONG();
  173. pData = new BYTE[dwSize];
  174. if(pData)
  175. {
  176. memset(pData,0,dwSize);
  177. memcpy(pData,(BYTE*)&tmp,dwSize);
  178. }
  179. else
  180. {
  181. hr = E_OUTOFMEMORY;
  182. }
  183. }
  184. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  185. break;
  186. case CIM_SINT64:
  187. case CIM_UINT64:
  188. case CIM_REAL64:
  189. {
  190. dwSize = 8;
  191. double dblVal = vValue.GetDouble();
  192. pData = new BYTE[dwSize];
  193. if(pData)
  194. {
  195. memcpy(pData,&dblVal,dwSize);
  196. }
  197. else
  198. {
  199. hr = E_OUTOFMEMORY;
  200. }
  201. }
  202. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  203. break;
  204. case CIM_DATETIME:
  205. case DBTYPE_DBTIMESTAMP:
  206. dwSize = sizeof(DBTIMESTAMP);
  207. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  208. if( vValue.GetStr() != NULL)
  209. {
  210. pData = new BYTE[dwSize];
  211. if(pData)
  212. {
  213. hr = ConvertDateToOledbType(vValue.GetStr(),(DBTIMESTAMP *)pData);
  214. dwColType = DBTYPE_DBTIMESTAMP;
  215. }
  216. else
  217. {
  218. hr = E_OUTOFMEMORY;
  219. }
  220. }
  221. else
  222. {
  223. hr = DBSTATUS_S_ISNULL;
  224. pData = NULL;
  225. dwSize = 0;
  226. }
  227. break;
  228. case VT_DATE:
  229. dwSize = sizeof(DBTIMESTAMP);
  230. pData = new BYTE[dwSize];
  231. if(pData)
  232. {
  233. ConvertVariantDateOledbDate(&((VARIANT *)&vValue)->date,(DBTIMESTAMP *)pData);
  234. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  235. dwColType = DBTYPE_DBTIMESTAMP;
  236. }
  237. else
  238. {
  239. hr = E_OUTOFMEMORY;
  240. }
  241. break;
  242. case CIM_STRING:
  243. pData = (BYTE *)Wmioledb_SysAllocString(vValue.GetStr());
  244. dwSize = SysStringLen(vValue.GetStr());
  245. break;
  246. case CIM_REFERENCE:
  247. break;
  248. case CIM_OBJECT:
  249. break;
  250. case CIM_IUNKNOWN:
  251. pData = new BYTE[sizeof(IUnknown *)];
  252. if(pData)
  253. {
  254. memset(pData,0,sizeof(IUnknown *));
  255. hr = vValue.GetUnknown()->QueryInterface(IID_IUnknown,(void **)pData);
  256. }
  257. else
  258. {
  259. hr = E_OUTOFMEMORY;
  260. }
  261. break;
  262. case VT_VARIANT:
  263. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  264. dwSize = sizeof(VARIANT);
  265. pVar = new VARIANT;
  266. if(pVar)
  267. {
  268. VariantInit(pVar);
  269. hr = VariantCopy(pVar,vValue);
  270. dwColType = DBTYPE_VARIANT;
  271. pData = (BYTE *) pVar;
  272. pvar2 = (VARIANT *)pData;
  273. }
  274. else
  275. {
  276. hr = E_OUTOFMEMORY;
  277. }
  278. break;
  279. default:
  280. assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
  281. }
  282. } // try
  283. catch(...)
  284. {
  285. switch( lType )
  286. {
  287. case CIM_FLAG_ARRAY:
  288. {
  289. if(pData)
  290. {
  291. SafeArrayDestroy((SAFEARRAY *)pData);
  292. }
  293. }
  294. break;
  295. case CIM_STRING:
  296. {
  297. if(pData)
  298. {
  299. SysFreeString((BSTR)pData);
  300. }
  301. }
  302. break;
  303. case VT_VARIANT:
  304. {
  305. SAFE_DELETE_PTR((VARIANT *&)pData);
  306. }
  307. break;
  308. case CIM_IUNKNOWN:
  309. if(pData)
  310. {
  311. (*(IUnknown **)pData)->Release();
  312. SAFE_DELETE_ARRAY(pData);
  313. }
  314. break;
  315. default:
  316. {
  317. SAFE_DELETE_ARRAY(pData);
  318. }
  319. break;
  320. throw;
  321. }
  322. }
  323. return hr;
  324. }
  325. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  326. // Free the data allocated to store data
  327. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  328. HRESULT CDataMap::FreeData(DBTYPE lType, BYTE *& pData)
  329. {
  330. HRESULT hr = S_OK;
  331. VARIANT *pVar = NULL;
  332. //=======================================================================
  333. // See if it is an array
  334. //=======================================================================
  335. /* if( lType & CIM_FLAG_ARRAY ){
  336. lType = lType &~ CIM_FLAG_ARRAY;
  337. fArray = TRUE;
  338. }
  339. */
  340. // If the pointer sent is not NULL
  341. if( lType & CIM_FLAG_ARRAY )
  342. {
  343. lType = CIM_FLAG_ARRAY;
  344. }
  345. if(pData)
  346. {
  347. switch( lType ){
  348. case VT_EMPTY:
  349. break;
  350. case VT_NULL:
  351. break;
  352. case CIM_FLAG_ARRAY:
  353. pVar = (VARIANT *)pData;
  354. hr = SafeArrayDestroy((SAFEARRAY *)pData);
  355. break;
  356. case CIM_UINT8:
  357. case CIM_SINT8:
  358. SAFE_DELETE_PTR((BYTE*)pData);
  359. break;
  360. case CIM_BOOLEAN:
  361. case CIM_CHAR16:
  362. case CIM_SINT16:
  363. case CIM_UINT16:
  364. SAFE_DELETE_PTR((short*&)pData);
  365. break;
  366. case CIM_REAL32:
  367. case CIM_SINT32:
  368. case CIM_UINT32:
  369. SAFE_DELETE_PTR((DWORD*&)pData);
  370. break;
  371. case CIM_SINT64:
  372. case CIM_UINT64:
  373. case CIM_REAL64:
  374. SAFE_DELETE_ARRAY((BYTE*)pData);
  375. break;
  376. case CIM_DATETIME:
  377. case DBTYPE_DBTIMESTAMP:
  378. SAFE_DELETE_PTR((DBTIMESTAMP *&)pData);
  379. break;
  380. case CIM_STRING:
  381. SysFreeString((BSTR)pData);
  382. break;
  383. case CIM_REFERENCE:
  384. break;
  385. case CIM_OBJECT:
  386. case CIM_IUNKNOWN:
  387. // case DBTYPE_IUNKNOWN:
  388. if(pData)
  389. {
  390. SAFE_RELEASE_PTR((*(IUnknown **)pData));
  391. SAFE_DELETE_ARRAY(pData);
  392. }
  393. break;
  394. case VT_VARIANT:
  395. hr = VariantClear((VARIANT *)pData);
  396. SAFE_DELETE_PTR((VARIANT *&)pData);
  397. break;
  398. case DBTYPE_DATE:
  399. SAFE_DELETE_PTR((DATE *&)pData);
  400. break;
  401. default:
  402. assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
  403. }
  404. }
  405. if(hr == S_OK)
  406. pData = NULL;
  407. return hr;
  408. }
  409. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  410. //
  411. // This function returns the default OLE DB representation for a data type
  412. //
  413. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  414. HRESULT CDataMap::MapCIMTypeToOLEDBType(long lType, WORD & wdbOLEDBType, DBLENGTH & uColumnSize , DWORD &dwFlags) // OUT OLE DB type for DBColumnInfo
  415. {
  416. HRESULT hr = S_OK;
  417. LONG lCimType = lType;
  418. if ( lType & CIM_FLAG_ARRAY)
  419. {
  420. lCimType = CIM_FLAG_ARRAY;
  421. }
  422. switch( lCimType ){
  423. case VT_EMPTY:
  424. wdbOLEDBType = DBTYPE_EMPTY;
  425. uColumnSize = 0;
  426. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  427. break;
  428. case VT_NULL:
  429. wdbOLEDBType = DBTYPE_NULL;
  430. uColumnSize = 0;
  431. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  432. break;
  433. case CIM_SINT8:
  434. wdbOLEDBType = DBTYPE_I1;
  435. uColumnSize = 1;
  436. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  437. break;
  438. case CIM_UINT8:
  439. wdbOLEDBType = DBTYPE_UI1;
  440. uColumnSize = 1;
  441. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  442. break;
  443. case CIM_SINT16:
  444. wdbOLEDBType = DBTYPE_I2;
  445. uColumnSize = 2;
  446. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  447. break;
  448. case CIM_UINT16:
  449. wdbOLEDBType = DBTYPE_UI2;
  450. uColumnSize = 2;
  451. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  452. break;
  453. case CIM_SINT32:
  454. wdbOLEDBType = DBTYPE_I4;
  455. uColumnSize = 4;
  456. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  457. break;
  458. case CIM_UINT32:
  459. wdbOLEDBType = DBTYPE_UI4;
  460. uColumnSize = 4;
  461. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  462. break;
  463. case CIM_SINT64:
  464. wdbOLEDBType = DBTYPE_I8 ; //DBTYPE_R8; //DBTYPE_I8;
  465. uColumnSize = 8;
  466. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  467. break;
  468. case CIM_UINT64:
  469. wdbOLEDBType = DBTYPE_UI8 ; //DBTYPE_R8; //DBTYPE_UI8;
  470. uColumnSize = 8;
  471. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  472. break;
  473. case CIM_REAL32:
  474. wdbOLEDBType = DBTYPE_R4;
  475. uColumnSize = 4;
  476. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  477. break;
  478. case CIM_REAL64:
  479. wdbOLEDBType = DBTYPE_R8;
  480. uColumnSize = 8;
  481. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  482. break;
  483. case CIM_BOOLEAN:
  484. wdbOLEDBType = DBTYPE_BOOL;
  485. uColumnSize = 2;
  486. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  487. break;
  488. case CIM_STRING:
  489. wdbOLEDBType = DBTYPE_BSTR;
  490. uColumnSize = ~0 ;//MAX_CIM_STRING_SIZE; //sizeof(BSTR); // set the size to -1 ( a variable length string)
  491. break;
  492. case CIM_DATETIME:
  493. case DBTYPE_DBTIMESTAMP:
  494. case VT_DATE :
  495. wdbOLEDBType = DBTYPE_DBTIMESTAMP;
  496. uColumnSize = sizeof(DBTIMESTAMP);
  497. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  498. break;
  499. case CIM_REFERENCE:
  500. wdbOLEDBType = DBTYPE_BSTR;
  501. uColumnSize = sizeof(BSTR);
  502. break;
  503. case CIM_CHAR16:
  504. wdbOLEDBType = DBTYPE_STR;
  505. uColumnSize = 2;
  506. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  507. break;
  508. case CIM_OBJECT:
  509. wdbOLEDBType = DBTYPE_BSTR;
  510. uColumnSize = sizeof(BSTR);
  511. break;
  512. case CIM_FLAG_ARRAY:
  513. wdbOLEDBType = VT_ARRAY | VT_VARIANT;
  514. uColumnSize = sizeof(SAFEARRAY);
  515. hr = S_OK;
  516. break;
  517. case DBTYPE_GUID:
  518. wdbOLEDBType = DBTYPE_GUID;
  519. uColumnSize = sizeof(GUID);
  520. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  521. break;
  522. case CIM_IUNKNOWN:
  523. wdbOLEDBType = DBTYPE_IUNKNOWN;
  524. uColumnSize = sizeof(IUnknown *);
  525. dwFlags |= DBCOLUMNFLAGS_ISFIXEDLENGTH;
  526. break;
  527. default:
  528. assert( !"Unmatched CIMTYPE to OLEDB Data Type." );
  529. }
  530. return hr;
  531. }
  532. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  533. // This function translates text strings to OLEDB types
  534. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  535. HRESULT CDataMap::TranslateParameterStringToOLEDBType( DBTYPE & wDataType, WCHAR * str)
  536. {
  537. HRESULT hr = S_OK;
  538. // Arrays ????
  539. wDataType = 999;
  540. if( 0 == _wcsicmp(L"DBTYPE_CHAR",str )){
  541. wDataType = DBTYPE_STR;
  542. }
  543. else if( 0 == _wcsicmp(L"DBTYPE_VARCHAR",str )){
  544. wDataType = DBTYPE_STR;
  545. }
  546. else if( 0 == _wcsicmp(L"DBTYPE_LONGVARCHAR",str )){
  547. wDataType = DBTYPE_STR;
  548. }
  549. else if( 0 == _wcsicmp(L"DBTYPE_WCHAR",str )){
  550. wDataType = DBTYPE_WSTR;
  551. }
  552. else if( 0 == _wcsicmp(L"DBTYPE_WVARCHAR",str )){
  553. wDataType = DBTYPE_WSTR;
  554. }
  555. else if( 0 == _wcsicmp(L"DBTYPE_WLONGVARCHAR",str )){
  556. wDataType = DBTYPE_WSTR;
  557. }
  558. else if( 0 == _wcsicmp(L"DBTYPE_UI1",str )){
  559. wDataType = DBTYPE_UI1;
  560. }
  561. else if( 0 == _wcsicmp(L"DBTYPE_I1",str )){
  562. wDataType = DBTYPE_I1;
  563. }
  564. else if( 0 == _wcsicmp(L"DBTYPE_I2",str )){
  565. wDataType = DBTYPE_I2;
  566. }
  567. else if( 0 == _wcsicmp(L"DBTYPE_UI2",str )){
  568. wDataType = DBTYPE_UI2;
  569. }
  570. else if( 0 == _wcsicmp(L"DBTYPE_I4",str )){
  571. wDataType = DBTYPE_I4;
  572. }
  573. else if( 0 == _wcsicmp(L"DBTYPE_UI4",str )){
  574. wDataType = DBTYPE_UI4;
  575. }
  576. else if( 0 == _wcsicmp(L"DBTYPE_I8",str )){
  577. wDataType = DBTYPE_I8;
  578. }
  579. else if( 0 == _wcsicmp(L"DBTYPE_UI8",str )){
  580. wDataType = DBTYPE_UI8;
  581. }
  582. else if( 0 == _wcsicmp(L"DBTYPE_R4",str )){
  583. wDataType = DBTYPE_R4;
  584. }
  585. else if( 0 == _wcsicmp(L"DBTYPE_R8",str )){
  586. wDataType = DBTYPE_R8;
  587. }
  588. else if( 0 == _wcsicmp(L"DBTYPE_BOOL",str )){
  589. wDataType = DBTYPE_BOOL;
  590. }
  591. else if( 0 == _wcsicmp(L"DBTYPE_WSTR",str )){
  592. wDataType = DBTYPE_WSTR;
  593. }
  594. else if( 0 == _wcsicmp(L"DBTYPE_BSTR",str )){
  595. wDataType = DBTYPE_BSTR;
  596. }
  597. else if( 0 == _wcsicmp(L"DBTYPE_STR",str )){
  598. wDataType = DBTYPE_STR;
  599. }
  600. else if( 0 == _wcsicmp(L"DBTYPE_DATE ",str )){
  601. wDataType = DBTYPE_DATE ;
  602. }
  603. else if( 0 == _wcsicmp(L"DBTYPE_DBTIME ",str )){
  604. wDataType = DBTYPE_DBTIME ;
  605. }
  606. else if( 0 == _wcsicmp(L"DBTYPE_DBTIMESTAMP",str )){
  607. wDataType = DBTYPE_DBTIMESTAMP;
  608. }
  609. else if( 0 == _wcsicmp(L"DBTYPE_IDISPATCH",str )){
  610. wDataType = DBTYPE_IDISPATCH;
  611. }
  612. else if( 0 == _wcsicmp(L"DBTYPE_IUNKNOWN",str )){
  613. wDataType = DBTYPE_IUNKNOWN;
  614. }
  615. return hr;
  616. }
  617. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  618. // This function maps and converts OLEDBTYPE to CIMTYPE
  619. //
  620. // Note:
  621. // dwArrayCIMType = -1 - If data passed is not array
  622. // dwArrayCIMType = actual CIMTYPE - If the passed data is array
  623. //
  624. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  625. HRESULT CDataMap::MapAndConvertOLEDBTypeToCIMType(DBTYPE wDataType, void *pData ,DBLENGTH dwSrcLength, VARIANT &varData,LONG_PTR lArrayCIMType)
  626. {
  627. HRESULT hr = S_OK;
  628. DWORD dwDstStatus = 0 , cbDstMaxLength = 0;
  629. void *pSrc = NULL;
  630. BSTR strDate=Wmioledb_SysAllocString(NULL);
  631. SAFEARRAY * pArrayTemp = NULL;
  632. DBLENGTH dbDstLen = 0;
  633. if(lArrayCIMType == -1)
  634. {
  635. if(wDataType == VT_BSTR)
  636. pSrc = &pData;
  637. else
  638. pSrc = pData;
  639. switch( wDataType )
  640. {
  641. case DBTYPE_UI1:
  642. case DBTYPE_I1:
  643. wDataType = DBTYPE_I2;
  644. break;
  645. case DBTYPE_UI2:
  646. wDataType = DBTYPE_I2;
  647. break;
  648. case DBTYPE_UI4:
  649. wDataType = DBTYPE_I4;
  650. break;
  651. case DBTYPE_DBTIMESTAMP:
  652. if(IsValidDBTimeStamp((DBTIMESTAMP *)pData))
  653. {
  654. // Converts OLEDB DBTIMESTAMP to DMTF date format
  655. ConvertOledbDateToCIMType((DBTIMESTAMP *)pData,strDate);
  656. pSrc = &strDate;
  657. wDataType = VT_BSTR;
  658. }
  659. else
  660. hr = DBSTATUS_E_CANTCONVERTVALUE;
  661. }
  662. }
  663. else
  664. // if the type is array then convert it into the appropriate type
  665. if( (wDataType & DBTYPE_ARRAY) && (lArrayCIMType & DBTYPE_ARRAY))
  666. {
  667. hr = ConvertAndCopyArray((SAFEARRAY *)pData, &pArrayTemp, wDataType,(DBTYPE)lArrayCIMType,&dwDstStatus);
  668. wDataType = (DBTYPE)lArrayCIMType;
  669. pSrc = pArrayTemp;
  670. }
  671. if( hr == S_OK)
  672. {
  673. hr = g_pIDataConvert->DataConvert( wDataType, VT_VARIANT, dwSrcLength, &dbDstLen, pSrc,
  674. &varData, sizeof(VARIANT), 0, &dwDstStatus,
  675. 0, // bPrecision for conversion to DBNUMERIC
  676. 0, // bScale for conversion to DBNUMERIC
  677. DBDATACONVERT_DEFAULT);
  678. }
  679. // Release memory
  680. if( pArrayTemp)
  681. {
  682. SafeArrayDestroy(pArrayTemp);
  683. pArrayTemp = NULL;
  684. }
  685. SysFreeString(strDate);
  686. return hr;
  687. }
  688. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  689. // This function maps and converts OLEDBTYPE to CIMTYPE
  690. //
  691. // Note:
  692. // dwArrayCIMType = -1 - If data passed is not array
  693. // dwArrayCIMType = actual CIMTYPE - If the passed data is array
  694. //
  695. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  696. HRESULT CDataMap::ConvertToCIMType(BYTE *pData, DBTYPE lType ,DBLENGTH lDataLength,LONG lCIMType ,VARIANT &varData)
  697. {
  698. HRESULT hr = DBSTATUS_E_CANTCONVERTVALUE;
  699. DWORD dwDstStatus = 0;
  700. DWORD cbDstMaxLength = 0;
  701. void * pDst = NULL;
  702. void * pSrc = NULL;
  703. void * pTemp = NULL;
  704. BYTE * pbTemp = NULL;
  705. BSTR strDate = Wmioledb_SysAllocString(NULL);
  706. SAFEARRAY * pArrayTemp = NULL;
  707. BOOL bAlloc = FALSE;
  708. DBLENGTH dbDstLen = 0;
  709. DBTYPE wDataType = 0;
  710. BOOL bConverted = FALSE;
  711. wDataType = (DBTYPE)lCIMType;
  712. if(! pData)
  713. {
  714. VariantClear(&varData);
  715. hr = S_OK;
  716. }
  717. else
  718. {
  719. switch(lCIMType)
  720. {
  721. case CIM_UINT8:
  722. wDataType = VT_I2;
  723. break;
  724. case CIM_UINT16:
  725. wDataType = VT_I2;
  726. break;
  727. case CIM_UINT32:
  728. wDataType = VT_I4;
  729. break;
  730. case CIM_DATETIME:
  731. BSTR strDate;
  732. pTemp = new BYTE[sizeof(DBTIMESTAMP)];
  733. if( lType == VT_BSTR)
  734. pSrc = *(BSTR **)pData;
  735. else
  736. pSrc = pData;
  737. //NTRaid:111795
  738. // 06/07/00
  739. if(pTemp == NULL)
  740. {
  741. hr = E_OUTOFMEMORY;
  742. }
  743. else
  744. // Convert the given date to DBTIMESTAMP
  745. if( S_OK == (hr = g_pIDataConvert->DataConvert( (DBTYPE)lType,DBTYPE_DBTIMESTAMP, lDataLength,&dbDstLen, pSrc,
  746. pTemp, sizeof(DBTIMESTAMP), 0, &dwDstStatus,
  747. 0, // bPrecision for conversion to DBNUMERIC
  748. 0, // bScale for conversion to DBNUMERIC
  749. DBDATACONVERT_DEFAULT)) && dwDstStatus != DBSTATUS_S_ISNULL)
  750. {
  751. // Call this function to convert DBTIMESTAMP date to CIM date format
  752. if(S_OK == (hr = ConvertOledbDateToCIMType((DBTIMESTAMP*)pTemp,strDate)))
  753. {
  754. varData.vt = VT_BSTR;
  755. varData.bstrVal = Wmioledb_SysAllocString(strDate);
  756. SysFreeString(strDate);
  757. }
  758. }
  759. SAFE_DELETE_ARRAY(pTemp);
  760. bConverted = TRUE;
  761. break;
  762. }
  763. if(bConverted == FALSE)
  764. {
  765. pTemp = pData;
  766. hr = S_OK;
  767. // if the required type and the type of the data passed is different then convert the data to appropriate
  768. // type
  769. if( lType != (LONG)wDataType && (hr = g_pIDataConvert->CanConvert((DBTYPE)lType,(DBTYPE)wDataType)) == S_OK)
  770. {
  771. pTemp = NULL;
  772. if(SUCCEEDED(hr = AllocateData(wDataType,pTemp,dbDstLen)))
  773. {
  774. bAlloc = TRUE;
  775. if( lType == VT_BSTR)
  776. pSrc = (BYTE *)*((BSTR **)pData);
  777. else
  778. pSrc = pData;
  779. hr = g_pIDataConvert->DataConvert( (DBTYPE)lType,(DBTYPE)wDataType, lDataLength,&dbDstLen, pSrc,
  780. pTemp, dbDstLen, 0, &dwDstStatus,
  781. 0, // bPrecision for conversion to DBNUMERIC
  782. 0, // bScale for conversion to DBNUMERIC
  783. DBDATACONVERT_DEFAULT);
  784. }
  785. }
  786. if( hr == S_OK)
  787. {
  788. if( wDataType == VT_BSTR)
  789. pSrc = *(BSTR **)pTemp;
  790. else
  791. pSrc = pTemp;
  792. hr = g_pIDataConvert->DataConvert((DBTYPE)wDataType, VT_VARIANT, dbDstLen, &dbDstLen, pSrc,
  793. &varData, sizeof(VARIANT), 0, &dwDstStatus,
  794. 0, // bPrecision for conversion to DBNUMERIC
  795. 0, // bScale for conversion to DBNUMERIC
  796. DBDATACONVERT_DEFAULT);
  797. }
  798. if( bAlloc == TRUE)
  799. {
  800. pbTemp = (BYTE *)pTemp;
  801. FreeData(wDataType,pbTemp);
  802. }
  803. }
  804. }
  805. SysFreeString(strDate);
  806. return hr;
  807. }
  808. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  809. // This function convert data to the OLEDBTYPE required. It also allocates memory for the data
  810. //
  811. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  812. HRESULT CDataMap::AllocateAndConvertToOLEDBType(VARIANT &varData,LONG lCimType , DBTYPE lOledbType,BYTE *&pData, DBLENGTH &lDataLength, DBSTATUS &dwStatus)
  813. {
  814. HRESULT hr = DBSTATUS_E_CANTCONVERTVALUE;
  815. DBTYPE wDataType = 0;
  816. DBLENGTH dwDstLength = 0;
  817. BYTE *pSrc = NULL;
  818. void *pTemp = NULL;
  819. void *pDst = NULL;
  820. BOOL bConvert = FALSE;
  821. BOOL bAlloc = FALSE;
  822. DBLENGTH dbDstLen = 0;
  823. wDataType = (DBTYPE)lCimType;
  824. if(wDataType & CIM_FLAG_ARRAY)
  825. {
  826. wDataType = CIM_FLAG_ARRAY;
  827. }
  828. if(varData.vt == VT_NULL || varData.vt == VT_EMPTY)
  829. {
  830. pData = NULL;
  831. lDataLength = NULL;
  832. dwStatus = DBSTATUS_S_ISNULL;
  833. return S_OK;
  834. }
  835. switch(wDataType)
  836. {
  837. // Arrays are always shown as ARRAY of VARIANTS to make it easily accessible with scripting
  838. case CIM_FLAG_ARRAY:
  839. // if(lOledbType != VT_ARRAY || VT_VARIANT)
  840. // Bug number 103751 in Windows bugs
  841. hr = DBSTATUS_E_CANTCONVERTVALUE;
  842. if(lOledbType == (VT_ARRAY | VT_VARIANT))
  843. {
  844. hr = ConvertToVariantArray(((VARIANT *)&varData)->parray,varData.vt,(SAFEARRAY **)&pData);
  845. }
  846. bConvert = TRUE;
  847. break;
  848. case CIM_DATETIME:
  849. case DBTYPE_DBTIMESTAMP:
  850. lDataLength = sizeof(DBTIMESTAMP);
  851. if( varData.bstrVal != NULL)
  852. {
  853. // NTRaid:111818
  854. // 06/13/00
  855. pSrc = new BYTE[lDataLength];
  856. if(pSrc)
  857. {
  858. bAlloc = TRUE;
  859. hr = ConvertDateToOledbType(varData.bstrVal,(DBTIMESTAMP *)pSrc);
  860. wDataType = DBTYPE_DBTIMESTAMP;
  861. }
  862. else
  863. {
  864. hr = E_OUTOFMEMORY;
  865. }
  866. }
  867. else
  868. {
  869. hr = S_OK;
  870. pSrc = NULL;
  871. lDataLength = 0;
  872. bConvert = TRUE;
  873. }
  874. break;
  875. default:
  876. wDataType = VT_VARIANT;
  877. lDataLength = sizeof(VARIANT);
  878. pSrc = (BYTE *)&varData;
  879. // NTRaid:111818
  880. // 06/13/00
  881. hr = S_OK;
  882. }
  883. // NTRaid:111818
  884. // 06/13/00
  885. if(SUCCEEDED(hr) && bConvert == FALSE && pSrc != NULL && g_pIDataConvert->CanConvert((DBTYPE)wDataType,(DBTYPE)lOledbType) == S_OK)
  886. {
  887. //AllocateData(lOledbType,pDst,dwDstLength);
  888. if(wDataType == VT_BSTR)
  889. pDst = *(BSTR **)pData;
  890. else
  891. pDst = (void *)pData;
  892. hr = g_pIDataConvert->DataConvert( (DBTYPE)wDataType,(DBTYPE)lOledbType, lDataLength,&dbDstLen, pSrc,
  893. pDst, dbDstLen, 0, &dwStatus,
  894. 0, // bPrecision for conversion to DBNUMERIC
  895. 0, // bScale for conversion to DBNUMERIC
  896. DBDATACONVERT_DEFAULT);
  897. if( hr == S_OK)
  898. {
  899. pData = (BYTE *)pDst;
  900. }
  901. }
  902. if(bAlloc == TRUE)
  903. {
  904. delete [] pSrc;
  905. }
  906. lDataLength = (LONG)dbDstLen;
  907. return hr;
  908. }
  909. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  910. // Function to convert the data to variant type
  911. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  912. HRESULT CDataMap::ConvertVariantType(VARIANT &varSrc, VARIANT varDst ,CIMTYPE lDstType)
  913. {
  914. HRESULT hr = E_FAIL;
  915. switch(lDstType)
  916. {
  917. case CIM_DATETIME:
  918. case DBTYPE_DBTIMESTAMP:
  919. case DBTYPE_DATE:
  920. case DBTYPE_DBTIME:
  921. lDstType = DBTYPE_BSTR;
  922. break;
  923. case CIM_REFERENCE :
  924. case CIM_CHAR16:
  925. case CIM_OBJECT:
  926. case CIM_FLAG_ARRAY:
  927. break;
  928. case CIM_UINT64:
  929. case CIM_SINT64:
  930. lDstType = VT_R8;
  931. };
  932. hr = VariantChangeType(&varSrc,&varDst,0,(SHORT)lDstType);
  933. return hr;
  934. }
  935. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  936. // Function to compare data of same types and check if both are same
  937. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  938. BOOL CDataMap::CompareData(DWORD dwType,void * pData1 , void *pData2)
  939. {
  940. BOOL bRet = FALSE;
  941. long lType = VT_NULL;
  942. if(pData1 == NULL || pData2 == NULL)
  943. {
  944. if(pData1 == pData2)
  945. bRet = TRUE;
  946. return bRet;
  947. }
  948. // If the type is of some array
  949. if (dwType & VT_ARRAY)
  950. {
  951. lType = CIM_FLAG_ARRAY;
  952. }
  953. else
  954. lType = dwType;
  955. switch( lType ){
  956. case VT_NULL:
  957. case VT_EMPTY:
  958. bRet = TRUE;
  959. break;
  960. case CIM_FLAG_ARRAY:
  961. bRet = FALSE;
  962. break;
  963. case CIM_SINT8:
  964. case CIM_UINT8:
  965. if(!memcmp(pData1,pData2,1))
  966. bRet = TRUE;
  967. break;
  968. case CIM_CHAR16:
  969. case CIM_SINT16:
  970. case CIM_UINT16:
  971. case CIM_BOOLEAN:
  972. if(!memcmp(pData1,pData2,2))
  973. bRet = TRUE;
  974. break;
  975. case CIM_SINT32:
  976. case CIM_UINT32:
  977. case CIM_REAL32:
  978. if(!memcmp(pData1,pData2,4))
  979. bRet = TRUE;
  980. break;
  981. case CIM_SINT64:
  982. case CIM_UINT64:
  983. case CIM_REAL64:
  984. if(!memcmp(pData1,pData2,8))
  985. bRet = TRUE;
  986. break;
  987. case CIM_DATETIME:
  988. case DBTYPE_DBTIMESTAMP:
  989. if(!memcmp(pData1,pData2,sizeof(DBTIMESTAMP)))
  990. bRet = TRUE;
  991. break;
  992. case CIM_STRING:
  993. if( pData1 != NULL && pData2 != NULL)
  994. {
  995. if(!_wcsicmp((WCHAR *)pData1,(WCHAR *)pData2))
  996. bRet = TRUE;
  997. }
  998. break;
  999. case CIM_REFERENCE:
  1000. case CIM_OBJECT:
  1001. case VT_VARIANT:
  1002. case CIM_IUNKNOWN:
  1003. break;
  1004. case DBTYPE_DATE:
  1005. if(!memcmp(pData1,pData2,sizeof(DATE)))
  1006. bRet = TRUE;
  1007. break;
  1008. default:
  1009. assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
  1010. }
  1011. return bRet;
  1012. }
  1013. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1014. // Function to check if a Safearray is Empty or not
  1015. // NOTE :Works on Single dimensional array
  1016. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1017. BOOL CDataMap::IsSafeArrayEmpty(SAFEARRAY *psa)
  1018. {
  1019. BOOL bRet = TRUE;
  1020. long lUBound = 0,lLBound = 0;
  1021. HRESULT hr = 0;
  1022. hr = SafeArrayGetUBound(psa,1,&lUBound);
  1023. hr = SafeArrayGetLBound(psa,1,&lLBound);
  1024. if( hr == S_OK && lLBound <= lUBound)
  1025. {
  1026. bRet = FALSE;
  1027. }
  1028. return bRet;
  1029. }
  1030. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1031. // Function to convert a safearray of one type to safearray of another type if,
  1032. // the source and destination arrays are of different type
  1033. // and this will just copy the safearray to the destination if the arraytypes are of same type
  1034. // NOTE: Works on Single dimensional array
  1035. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1036. HRESULT CDataMap::ConvertAndCopyArray(SAFEARRAY *psaSrc, SAFEARRAY **ppsaDst, DBTYPE dwSrcType,DBTYPE dwDstType,DBSTATUS *pdwStatus)
  1037. {
  1038. HRESULT hr = S_OK;
  1039. SAFEARRAYBOUND sabound;
  1040. LONG lUBound = 0;
  1041. LONG lLBound = 0;
  1042. int nArrayIndex = 0;
  1043. void * pSrc = NULL;
  1044. void * pDst = NULL;
  1045. void * pTemp = NULL;
  1046. DBLENGTH dbSrcLen = 0;
  1047. DBLENGTH dbDstLen = 0;
  1048. BSTR * pTempStr;
  1049. BYTE * pbTemp = NULL;
  1050. short dwSrcElemType = (SHORT) dwSrcType & ~DBTYPE_ARRAY;
  1051. short dwDstElemType = (SHORT)dwDstType & ~DBTYPE_ARRAY;
  1052. *pdwStatus = DBSTATUS_S_OK;
  1053. // If the array is not a single dimenstion array , then there is an error
  1054. if(SafeArrayGetDim(psaSrc) != 1)
  1055. return E_FAIL; // Bad array, or too many dimensions
  1056. // If the source safearray is not empty
  1057. if(!IsSafeArrayEmpty(psaSrc))
  1058. {
  1059. // if source and destination safe array is same then we can
  1060. // copy the safearray using SafeArrayCopy
  1061. if( dwSrcType != dwDstType)
  1062. {
  1063. // if the destination type is array of DBDATETIME then
  1064. // set error and status
  1065. if( IsDateType(dwDstType) && dwDstElemType == DBTYPE_DBTIMESTAMP)
  1066. {
  1067. hr = E_FAIL;
  1068. *pdwStatus = DBSTATUS_E_BADSTATUS;
  1069. }
  1070. else
  1071. // If the data type of the elements of the array can be converted
  1072. // if the source type is date then conversion will be from the string in CIMDATE formate
  1073. // which will be done by a utility function and not from the OLEDB conversion routine
  1074. if( SUCCEEDED (hr = g_pIDataConvert->CanConvert(dwSrcElemType, dwDstElemType)) || IsDateType(dwSrcElemType))
  1075. {
  1076. dbSrcLen = SafeArrayGetElemsize(psaSrc);
  1077. memset(&sabound,0,sizeof(SAFEARRAYBOUND));
  1078. hr = SafeArrayGetUBound(psaSrc,1,&lUBound);
  1079. hr = SafeArrayGetLBound(psaSrc,1,&lLBound);
  1080. if( lUBound > lLBound)
  1081. {
  1082. sabound.lLbound = lLBound;
  1083. sabound.cElements = lUBound - lLBound +1;
  1084. // Create the safearray
  1085. *ppsaDst = SafeArrayCreate(dwDstElemType, 1, &sabound);
  1086. pSrc = new BYTE[dbSrcLen];
  1087. if(SUCCEEDED(hr = AllocateData(dwDstElemType,pDst,dbDstLen)))
  1088. {
  1089. if(dwDstElemType == VT_BSTR)
  1090. pTemp = *(BSTR **)pDst;
  1091. else
  1092. pTemp = pDst;
  1093. // Navigate thru each element in the dimension of the array
  1094. for(nArrayIndex = lLBound ; nArrayIndex <= lUBound ; nArrayIndex++)
  1095. {
  1096. hr = SafeArrayGetElement(psaSrc,(long *)&nArrayIndex,pSrc);
  1097. if(hr == S_OK && dbDstLen > 0)
  1098. {
  1099. if( IsDateType(dwSrcType) || IsDateType(dwDstType))
  1100. {
  1101. // Convert the element data
  1102. hr = ConvertDateTypes(
  1103. dwSrcElemType,
  1104. dwDstElemType,
  1105. dbSrcLen,
  1106. &dbDstLen,
  1107. &(((VARIANT *)pSrc)->bstrVal),
  1108. pTemp,
  1109. dbDstLen,
  1110. pdwStatus);
  1111. }
  1112. else
  1113. {
  1114. // Free the previous string allocated from previous
  1115. // conversion
  1116. if( dwDstElemType == VT_BSTR && pDst != NULL)
  1117. {
  1118. pTempStr = *(BSTR **)pDst;
  1119. SysFreeString(*pTempStr);
  1120. }
  1121. // Convert the element data
  1122. hr = g_pIDataConvert->DataConvert(
  1123. dwSrcElemType,
  1124. dwDstElemType,
  1125. dbSrcLen,
  1126. &dbDstLen,
  1127. pSrc,
  1128. pTemp,
  1129. dbDstLen,
  1130. 0,
  1131. pdwStatus,
  1132. 0,
  1133. 0,
  1134. DBDATACONVERT_DEFAULT);
  1135. if(hr == DB_E_UNSUPPORTEDCONVERSION && pdwStatus != NULL)
  1136. *pdwStatus = DBSTATUS_E_CANTCONVERTVALUE;
  1137. }
  1138. // Put the data to the destination array
  1139. hr = SafeArrayPutElement(*ppsaDst,(long *)&nArrayIndex,pTemp);
  1140. }
  1141. else
  1142. {
  1143. hr = E_FAIL;
  1144. *pdwStatus = DBSTATUS_E_BADSTATUS;
  1145. break;
  1146. }
  1147. }// for
  1148. }
  1149. }
  1150. SAFE_DELETE_ARRAY(pSrc);
  1151. pbTemp = (BYTE *)pDst;
  1152. FreeData(dwDstElemType,pbTemp);
  1153. pDst = pbTemp;
  1154. }
  1155. else // Else if the data types of src and dst is not convertible then set the status
  1156. {
  1157. *pdwStatus = DBSTATUS_E_CANTCONVERTVALUE;
  1158. }
  1159. }
  1160. else // if the src and dst or of same type then just copy the arrays
  1161. {
  1162. hr = SafeArrayCopy(psaSrc,ppsaDst);
  1163. }
  1164. }
  1165. else
  1166. {
  1167. ppsaDst = NULL;
  1168. *pdwStatus = DBSTATUS_S_ISNULL;
  1169. }
  1170. return hr;
  1171. }
  1172. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1173. // Function to allocate memory
  1174. // Used by ConvertAndCopyArray function to allocate data for elements for converting
  1175. // the data type and putting it to the array
  1176. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1177. HRESULT CDataMap::AllocateData(DBTYPE dwType,void *& pData,DBLENGTH &dwLength)
  1178. {
  1179. HRESULT hr = S_OK;
  1180. long lType = dwType;
  1181. SAFEARRAY *pArray = NULL;
  1182. dwLength = 0;
  1183. // If the type is of some array
  1184. if (lType & CIM_FLAG_ARRAY)
  1185. {
  1186. lType = CIM_FLAG_ARRAY;
  1187. }
  1188. try
  1189. {
  1190. switch( lType ){
  1191. case VT_NULL:
  1192. pData = NULL;
  1193. hr = DBSTATUS_S_ISNULL;
  1194. break;
  1195. case VT_EMPTY:
  1196. pData = NULL;
  1197. hr = DBSTATUS_S_ISNULL;
  1198. break;
  1199. case CIM_FLAG_ARRAY:
  1200. break;
  1201. case CIM_SINT8:
  1202. case CIM_UINT8:
  1203. pData = new BYTE[1];
  1204. dwLength = sizeof(BYTE);
  1205. if(!pData)
  1206. {
  1207. hr = E_OUTOFMEMORY;
  1208. }
  1209. break;
  1210. case CIM_CHAR16:
  1211. case CIM_SINT16:
  1212. case CIM_UINT16:
  1213. case CIM_BOOLEAN:
  1214. dwLength = sizeof(short);
  1215. pData = new BYTE[dwLength];
  1216. if(!pData)
  1217. {
  1218. hr = E_OUTOFMEMORY;
  1219. }
  1220. break;
  1221. case CIM_SINT32:
  1222. case CIM_UINT32:
  1223. case CIM_REAL32:
  1224. dwLength = sizeof(long);
  1225. pData = new BYTE[dwLength];
  1226. if(!pData)
  1227. {
  1228. hr = E_OUTOFMEMORY;
  1229. }
  1230. break;
  1231. case CIM_SINT64:
  1232. case CIM_UINT64:
  1233. case CIM_REAL64:
  1234. dwLength = 8;
  1235. pData = new BYTE[8];
  1236. if(!pData)
  1237. {
  1238. hr = E_OUTOFMEMORY;
  1239. }
  1240. break;
  1241. case CIM_DATETIME:
  1242. case DBTYPE_DBTIMESTAMP:
  1243. dwLength = sizeof(DBTIMESTAMP);
  1244. pData = new BYTE[dwLength];
  1245. if(!pData)
  1246. {
  1247. hr = E_OUTOFMEMORY;
  1248. }
  1249. break;
  1250. case DBTYPE_DATE:
  1251. dwLength = sizeof(DATE);
  1252. pData = new BYTE[dwLength];
  1253. if(!pData)
  1254. {
  1255. hr = E_OUTOFMEMORY;
  1256. }
  1257. break;
  1258. case CIM_STRING:
  1259. pData = new BYTE[sizeof(BSTR)];
  1260. dwLength = sizeof(BSTR);
  1261. if(!pData)
  1262. {
  1263. hr = E_OUTOFMEMORY;
  1264. }
  1265. break;
  1266. case CIM_REFERENCE:
  1267. break;
  1268. case CIM_OBJECT:
  1269. break;
  1270. case VT_VARIANT:
  1271. dwLength = sizeof(VARIANT);
  1272. pData = new BYTE[sizeof(VARIANT)];
  1273. if(!pData)
  1274. {
  1275. hr = E_OUTOFMEMORY;
  1276. }
  1277. else
  1278. {
  1279. VariantInit((VARIANT *)pData);
  1280. }
  1281. break;
  1282. default:
  1283. hr = E_FAIL;
  1284. // assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
  1285. }
  1286. } // try
  1287. catch(...)
  1288. {
  1289. SAFE_DELETE_ARRAY(pData);
  1290. throw;
  1291. }
  1292. return hr;
  1293. }
  1294. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1295. // Function to convert WMI (DMTF) formate date to OLEDB format
  1296. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1297. HRESULT CDataMap::ConvertDateToOledbType(BSTR strDate,DBTIMESTAMP *pTimeStamp)
  1298. {
  1299. WBEMTime wbemTime(strDate);
  1300. if(wbemTime.IsOk())
  1301. {
  1302. SYSTEMTIME sysTime;
  1303. memset(&sysTime,0,sizeof(SYSTEMTIME));
  1304. wbemTime.GetSYSTEMTIME(&sysTime);
  1305. pTimeStamp->year = (SHORT) sysTime.wYear;
  1306. pTimeStamp->month = (USHORT)sysTime.wMonth;
  1307. pTimeStamp->day = (USHORT)sysTime.wDay;
  1308. pTimeStamp->hour = (USHORT)sysTime.wHour;
  1309. pTimeStamp->minute = (USHORT)sysTime.wMinute;
  1310. pTimeStamp->second = (USHORT)sysTime.wSecond;
  1311. pTimeStamp->fraction= (ULONG)sysTime.wMilliseconds * 1000000; // converting into billionth of second
  1312. return S_OK;
  1313. }
  1314. return DBSTATUS_E_CANTCONVERTVALUE;
  1315. }
  1316. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1317. // Function to convert VARIANT date format to OLEDB format
  1318. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1319. HRESULT CDataMap::ConvertVariantDateOledbDate(DATE *pDate,DBTIMESTAMP *pTimeStamp)
  1320. {
  1321. HRESULT hr = S_OK;
  1322. DWORD dwDstStatus = 0 ,cbDstMaxLength = 0;
  1323. DBLENGTH dbDstLen = 0;
  1324. hr = g_pIDataConvert->DataConvert( VT_DATE, DBTYPE_DBTIMESTAMP, sizeof(DATE), &dbDstLen, pDate,
  1325. pTimeStamp, sizeof(DBTIMESTAMP), 0, &dwDstStatus,
  1326. 0, // bPrecision for conversion to DBNUMERIC
  1327. 0, // bScale for conversion to DBNUMERIC
  1328. DBDATACONVERT_DEFAULT);
  1329. return hr;
  1330. }
  1331. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1332. // Function to convert OLEDB format to WMI (DMTF) format
  1333. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1334. HRESULT CDataMap::ConvertOledbDateToCIMType(DBTIMESTAMP *pTimeStamp,BSTR &strDate)
  1335. {
  1336. WBEMTime wbemTime;
  1337. SYSTEMTIME sysTime;
  1338. memset(&sysTime,0,sizeof(SYSTEMTIME));
  1339. sysTime.wYear = pTimeStamp->year;
  1340. sysTime.wMonth = pTimeStamp->month;
  1341. sysTime.wDay = pTimeStamp->day;
  1342. sysTime.wHour = pTimeStamp->hour;
  1343. sysTime.wMinute = pTimeStamp->minute;
  1344. sysTime.wSecond = pTimeStamp->second;
  1345. sysTime.wMilliseconds = (WORD)pTimeStamp->fraction/ 1000000; // converting into micosecond
  1346. wbemTime = sysTime;
  1347. strDate = wbemTime.GetDMTF();
  1348. return S_OK;
  1349. }
  1350. HRESULT CDataMap::ConvertOledbDateToCIMType(VARIANT *vTimeStamp,BSTR &strDate)
  1351. {
  1352. WBEMTime wbemTime;
  1353. SYSTEMTIME sysTime;
  1354. memset(&sysTime,0,sizeof(SYSTEMTIME));
  1355. DBTIMESTAMP *pTimeStamp;
  1356. assert(vTimeStamp->vt == (VT_ARRAY | VT_UI1) || vTimeStamp->vt == (VT_ARRAY | VT_I1));
  1357. SafeArrayAccessData(vTimeStamp->parray,(void **)&pTimeStamp);
  1358. ConvertOledbDateToCIMType(pTimeStamp,strDate);
  1359. SafeArrayUnaccessData(vTimeStamp->parray);
  1360. return S_OK;
  1361. }
  1362. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1363. // Function to convert OLEDB format to WMI (DMTF) format
  1364. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1365. HRESULT CDataMap::ConvertVariantDateToCIMType(DATE *pDate,BSTR &strDate)
  1366. {
  1367. DBTIMESTAMP dbTimeStamp;
  1368. memset(&dbTimeStamp,0,sizeof(DBTIMESTAMP));
  1369. ConvertVariantDateOledbDate(pDate,&dbTimeStamp);
  1370. ConvertOledbDateToCIMType(&dbTimeStamp,strDate);
  1371. return S_OK;
  1372. }
  1373. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1374. // Check if the DTIMESTAMP passed is valid or not
  1375. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1376. BOOL CDataMap::IsValidDBTimeStamp(DBTIMESTAMP *pTimeStamp)
  1377. {
  1378. HRESULT hr = S_OK;
  1379. DWORD dwDstStatus = 0 , cbDstMaxLength = 0;
  1380. void *pSrc = NULL;
  1381. CVARIANT varDate;
  1382. DBLENGTH dbDstLen = 0;
  1383. hr = g_pIDataConvert->DataConvert( DBTYPE_DBTIMESTAMP, VT_VARIANT, sizeof(DBTIMESTAMP), &dbDstLen, pTimeStamp,
  1384. &varDate, sizeof(VARIANT), 0, &dwDstStatus,
  1385. 0, // bPrecision for conversion to DBNUMERIC
  1386. 0, // bScale for conversion to DBNUMERIC
  1387. DBDATACONVERT_DEFAULT);
  1388. if( hr != S_OK)
  1389. return FALSE;
  1390. return TRUE;
  1391. }
  1392. BOOL CDataMap::IsDateType(DWORD dwType)
  1393. {
  1394. BOOL bRet = FALSE;
  1395. if(dwType & VT_ARRAY)
  1396. dwType = dwType & ~(VT_ARRAY);
  1397. switch(dwType)
  1398. {
  1399. case DBTYPE_DATE:
  1400. case DBTYPE_DBTIMESTAMP:
  1401. case DBTYPE_DBTIME:
  1402. case CIM_DATETIME:
  1403. bRet = TRUE;
  1404. break;
  1405. }
  1406. return bRet;
  1407. }
  1408. HRESULT CDataMap::ConvertDateTypes( DWORD dwSrcType,
  1409. DWORD dwDstType,
  1410. DBLENGTH dwSrcLen,
  1411. DBLENGTH* pdwDstLen,
  1412. void * pSrc,
  1413. void * & pDst,
  1414. DBLENGTH dbDstLen,
  1415. DWORD * pdwStatus)
  1416. {
  1417. HRESULT hr = S_OK;
  1418. DBTIMESTAMP *pSrcTimeStamp = NULL;
  1419. pSrcTimeStamp = new DBTIMESTAMP;
  1420. // NTRaid:111817
  1421. // 06/07/00
  1422. if(!pSrcTimeStamp)
  1423. {
  1424. hr = E_OUTOFMEMORY;
  1425. }
  1426. else
  1427. {
  1428. memset(pSrcTimeStamp,0,sizeof(DBTIMESTAMP));
  1429. switch(dwSrcType)
  1430. {
  1431. case CIM_DATETIME:
  1432. hr = ConvertDateToOledbType(*(BSTR*)pSrc ,pSrcTimeStamp);
  1433. break;
  1434. default :
  1435. hr = g_pIDataConvert->DataConvert( (USHORT)dwSrcType , DBTYPE_DBTIMESTAMP, dwSrcLen, &dbDstLen, pSrc, pSrcTimeStamp,
  1436. sizeof(DBTIMESTAMP), 0, pdwStatus,
  1437. 0, // bPrecision for conversion to DBNUMERIC
  1438. 0, // bScale for conversion to DBNUMERIC
  1439. DBDATACONVERT_DEFAULT);
  1440. }
  1441. if( hr == S_OK)
  1442. {
  1443. switch(dwDstType)
  1444. {
  1445. case CIM_DATETIME:
  1446. hr = ConvertOledbDateToCIMType(pSrcTimeStamp,(BSTR)*(BSTR *)pDst);
  1447. default:
  1448. hr = g_pIDataConvert->DataConvert( DBTYPE_DBTIMESTAMP, (USHORT)dwDstType, sizeof(DBTIMESTAMP), &dbDstLen, pSrcTimeStamp,
  1449. pDst, dbDstLen, 0, pdwStatus,
  1450. 0, // bPrecision for conversion to DBNUMERIC
  1451. 0, // bScale for conversion to DBNUMERIC
  1452. DBDATACONVERT_DEFAULT);
  1453. }
  1454. }
  1455. SAFE_DELETE_PTR(pSrcTimeStamp);
  1456. }
  1457. return hr;
  1458. }
  1459. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1460. // Clear data for a particular DBTYPE
  1461. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1462. HRESULT CDataMap::ClearData(DBTYPE lType, void * pData)
  1463. {
  1464. HRESULT hr = S_OK;
  1465. VARIANT *pVar = NULL;
  1466. BSTR * pStr;;
  1467. //=======================================================================
  1468. // See if it is an array
  1469. //=======================================================================
  1470. // If the pointer sent is not NULL
  1471. if( lType & CIM_FLAG_ARRAY )
  1472. {
  1473. lType = CIM_FLAG_ARRAY;
  1474. }
  1475. if(pData)
  1476. {
  1477. switch( lType ){
  1478. case DBTYPE_EMPTY:
  1479. break;
  1480. case DBTYPE_NULL:
  1481. break;
  1482. case DBTYPE_ARRAY:
  1483. pVar = (VARIANT *)pData;
  1484. hr = SafeArrayDestroy((SAFEARRAY *)pData);
  1485. break;
  1486. case DBTYPE_I1:
  1487. case DBTYPE_UI1:
  1488. memset(pData,0,sizeof(BYTE));
  1489. break;
  1490. case DBTYPE_BOOL:
  1491. case DBTYPE_I2:
  1492. case DBTYPE_UI2:
  1493. memset(pData,0,sizeof(short));
  1494. break;
  1495. case DBTYPE_R4:
  1496. case DBTYPE_UI4:
  1497. case DBTYPE_I4:
  1498. memset(pData,0,sizeof(long));
  1499. break;
  1500. case DBTYPE_R8:
  1501. case DBTYPE_I8:
  1502. case DBTYPE_UI8:
  1503. memset(pData,0,8);
  1504. break;
  1505. case DBTYPE_DBTIMESTAMP:
  1506. memset(pData,0,sizeof(DBTIMESTAMP));
  1507. break;
  1508. case DBTYPE_BSTR:
  1509. pStr = (BSTR *)pData;
  1510. SysFreeString(*pStr);
  1511. break;
  1512. case DBTYPE_STR:
  1513. wcscpy((WCHAR *)pData,L"");
  1514. case DBTYPE_VARIANT:
  1515. hr = VariantClear((VARIANT *)pData);
  1516. break;
  1517. case DBTYPE_DATE:
  1518. memset(pData,0,sizeof(DATE));
  1519. break;
  1520. case DBTYPE_WSTR:
  1521. memset(pData,0,sizeof(WCHAR));
  1522. break;
  1523. case DBTYPE_IUNKNOWN:
  1524. pData = NULL;
  1525. break;
  1526. default:
  1527. assert( !"Unmatched OLEDB Data Type to CIMTYPE." );
  1528. }
  1529. }
  1530. if(hr == S_OK)
  1531. pData = NULL;
  1532. return hr;
  1533. }
  1534. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1535. // Convert a SAFEARRAY or any type to SAFEARRAY of VARIANT
  1536. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1537. HRESULT CDataMap::ConvertToVariantArray(SAFEARRAY *pArray,DBTYPE dwSrcType,SAFEARRAY ** ppArrayOut)
  1538. {
  1539. DWORD dwStatus = 0;
  1540. return ConvertAndCopyArray(pArray, ppArrayOut, dwSrcType,VT_ARRAY|VT_VARIANT,&dwStatus);
  1541. }