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.

1015 lines
31 KiB

  1. //***************************************************************************
  2. //
  3. // (c) 1999-2001 by Microsoft Corp. All Rights Reserved.
  4. //
  5. // sqlexec.cpp
  6. //
  7. // cvadai 6-May-1999 created.
  8. //
  9. //***************************************************************************
  10. #define _SQLEXEC_CPP_
  11. #pragma warning( disable : 4786 ) // identifier was truncated to 'number' characters in the
  12. #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
  13. #include "precomp.h"
  14. #include <std.h>
  15. #include <sqlutils.h>
  16. #include <sqlexec.h>
  17. #include <arena.h>
  18. #include <reputils.h>
  19. #include <smrtptr.h>
  20. #if defined _WIN64
  21. #define ULONG unsigned __int64
  22. #define LONG __int64
  23. #endif
  24. typedef struct tagDBObject
  25. {
  26. HACCESSOR hAcc;
  27. IUnknown *pUnk;
  28. } DBObject;
  29. struct BLOBDATA
  30. {
  31. DBSTATUS dwStatus;
  32. DWORD dwLength;
  33. ISequentialStream* pISeqStream;
  34. };
  35. __int64 CSQLExecute::GetInt64 (DB_NUMERIC *pId)
  36. {
  37. BYTE buff;
  38. __int64 dTemp = 0;
  39. __int64 *pTemp = &dTemp;
  40. int i = 0, iPos = 15;
  41. while (iPos >= 0)
  42. {
  43. buff = pId->val[iPos];
  44. dTemp |= buff;
  45. iPos--;
  46. if (iPos >= 0)
  47. dTemp <<= 8;
  48. }
  49. if (!pId->sign)
  50. dTemp *= -1;
  51. return dTemp;
  52. }
  53. void CSQLExecute::GetInt64 (DB_NUMERIC *pId, wchar_t **ppBuffer)
  54. {
  55. __int64 dTemp;
  56. dTemp = GetInt64 (pId);
  57. wchar_t *pBuff = new wchar_t[21];
  58. if (pBuff)
  59. swprintf(pBuff, L"%I64d", dTemp);
  60. *ppBuffer = pBuff;
  61. }
  62. struct OLEDBDATA
  63. {
  64. DBSTATUS dwStatus;
  65. DWORD dwLen;
  66. BYTE data[8192];
  67. };
  68. //***************************************************************************
  69. void CSQLExecute::SetDBNumeric (DB_NUMERIC &Id, SQL_ID ObjId)
  70. {
  71. Id.precision = 20;
  72. Id.scale = 0;
  73. Id.sign = 1;
  74. __int64 dTemp = ObjId;
  75. short i = 0, iPos = 0;
  76. if (dTemp < 0)
  77. {
  78. Id.sign = 0;
  79. dTemp *= -1;
  80. }
  81. while (iPos < 16)
  82. {
  83. if (!dTemp)
  84. {
  85. Id.val[iPos] = 0;
  86. }
  87. else
  88. {
  89. i = dTemp & 0xFF;
  90. Id.val[iPos] = i;
  91. dTemp >>= 8;
  92. }
  93. iPos++;
  94. }
  95. }
  96. void CSQLExecute::ClearBindingInfo(DBBINDING *binding)
  97. {
  98. binding->obLength = 0;
  99. binding->obStatus = 0;
  100. binding->pTypeInfo = NULL;
  101. binding->pObject = NULL;
  102. binding->pBindExt = NULL;
  103. binding->dwPart = DBPART_VALUE;
  104. binding->dwMemOwner = DBMEMOWNER_CLIENTOWNED;
  105. binding->dwFlags = 0;
  106. binding->bScale = 0;
  107. }
  108. void CSQLExecute::SetBindingInfo(DBBINDING *binding, unsigned long iOrdinal, unsigned long uSize, DBPARAMIO io,
  109. unsigned long maxlen, DBTYPE type, BYTE bPrecision)
  110. {
  111. binding->iOrdinal = iOrdinal;
  112. binding->obValue = uSize;
  113. binding->eParamIO = io;
  114. binding->cbMaxLen = maxlen;
  115. binding->wType = type;
  116. binding->bPrecision = bPrecision;
  117. }
  118. void CSQLExecute::SetParamBindInfo (DBPARAMBINDINFO &BindInfo, LPWSTR pszType, LPWSTR lpName, unsigned long uSize, DWORD dwFlags, BYTE bPrecision)
  119. {
  120. BindInfo.pwszDataSourceType = pszType;
  121. BindInfo.pwszName = lpName;
  122. BindInfo.ulParamSize = uSize;
  123. BindInfo.dwFlags = dwFlags;
  124. BindInfo.bPrecision = bPrecision;
  125. BindInfo.bScale = 0;
  126. }
  127. //***************************************************************************
  128. //
  129. // CSQLExecute::ExecuteQuery
  130. //
  131. //***************************************************************************
  132. HRESULT CSQLExecute::ExecuteQuery(IDBCreateCommand *pCmd, LPCWSTR lpSQL, IRowset **ppIRowset, DWORD *dwNumRows, ...)
  133. {
  134. HRESULT hr = WBEM_S_NO_ERROR;
  135. ICommandText *pICommandText = NULL;
  136. IRowset *pIRowset = NULL;
  137. LONG lRows;
  138. va_list argptr;
  139. int iSize = wcslen(lpSQL)+4096;
  140. wchar_t *pSQL = new wchar_t[iSize];
  141. CDeleteMe <wchar_t> r (pSQL);
  142. if (pSQL)
  143. {
  144. va_start(argptr, dwNumRows);
  145. vswprintf(pSQL, lpSQL, argptr);
  146. va_end(argptr);
  147. hr = pCmd->CreateCommand(NULL, IID_ICommandText,
  148. (IUnknown**) &pICommandText);
  149. CReleaseMe r (pICommandText);
  150. if (SUCCEEDED(hr))
  151. {
  152. pICommandText->SetCommandText(DBGUID_DBSQL, pSQL);
  153. ICommand *pICommand = NULL;
  154. pICommandText->QueryInterface(IID_ICommand,
  155. (void **) & pICommand);
  156. CReleaseMe r1 (pICommand);
  157. hr = pICommand->Execute(NULL, IID_IRowset, NULL,
  158. &lRows, (IUnknown**) &pIRowset);
  159. if (FAILED(hr))
  160. {
  161. int i = 0;
  162. hr = GetWMIError(pICommand);
  163. }
  164. else
  165. {
  166. if (ppIRowset)
  167. *ppIRowset = pIRowset;
  168. else if (pIRowset)
  169. pIRowset->Release();
  170. }
  171. }
  172. }
  173. else
  174. hr = WBEM_E_OUT_OF_MEMORY;
  175. if (dwNumRows)
  176. *dwNumRows = lRows;
  177. return hr;
  178. }
  179. //***************************************************************************
  180. //
  181. // CSQLExecute::ExecuteQuery
  182. //
  183. //***************************************************************************
  184. HRESULT CSQLExecute::ExecuteQuery(IDBInitialize *pDBInit, LPCWSTR lpSQL, IRowset **ppIRowset, DWORD *dwNumRows)
  185. {
  186. HRESULT hr = WBEM_S_NO_ERROR;
  187. IDBCreateSession *pIDBCreate = NULL;
  188. IDBCreateCommand *pIDBCreateCommand = NULL;
  189. hr = pDBInit->QueryInterface(IID_IDBCreateSession,
  190. (void**) &pIDBCreate);
  191. CReleaseMe r (pIDBCreate);
  192. if (SUCCEEDED(hr))
  193. {
  194. hr = pIDBCreate->CreateSession(NULL, IID_IDBCreateCommand,
  195. (IUnknown**) &pIDBCreateCommand);
  196. CReleaseMe r2 (pIDBCreateCommand);
  197. if (SUCCEEDED(hr))
  198. {
  199. hr = ExecuteQuery(pIDBCreateCommand, lpSQL, ppIRowset, dwNumRows);
  200. }
  201. }
  202. return hr;
  203. }
  204. //***************************************************************************
  205. //
  206. // CSQLExecute::ExecuteQueryAsync
  207. //
  208. //***************************************************************************
  209. HRESULT CSQLExecute::ExecuteQueryAsync(IDBInitialize *pDBInit, LPCWSTR lpSQL, IDBAsynchStatus **ppIAsync, DWORD *dwNumRows)
  210. {
  211. HRESULT hr = WBEM_S_NO_ERROR;
  212. IDBCreateSession *pIDBCreate = NULL;
  213. IDBCreateCommand *pIDBCreateCommand = NULL;
  214. ICommandText *pICommandText = NULL;
  215. LONG lRows = 0;
  216. hr = pDBInit->QueryInterface(IID_IDBCreateSession,
  217. (void**) &pIDBCreate);
  218. CReleaseMe r (pIDBCreate);
  219. if (SUCCEEDED(hr))
  220. {
  221. hr = pIDBCreate->CreateSession(NULL, IID_IDBCreateCommand,
  222. (IUnknown**) &pIDBCreateCommand);
  223. CReleaseMe r1 (pIDBCreateCommand);
  224. if (SUCCEEDED(hr))
  225. {
  226. hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
  227. (IUnknown**) &pICommandText);
  228. CReleaseMe r2 (pICommandText);
  229. if (SUCCEEDED(hr))
  230. {
  231. // Admittedly, this won't work unless we have
  232. // set the IDBProperties DBPROP_ROWSET_ASYNCH
  233. // property to DBPROPVAL_ASYNCH_INITIALIZE
  234. pICommandText->SetCommandText(DBGUID_DBSQL, lpSQL);
  235. ICommand *pICommand = NULL;
  236. pICommandText->QueryInterface(IID_ICommand,
  237. (void **) & pICommand);
  238. CReleaseMe r3 (pICommand);
  239. hr = pICommand->Execute(NULL, IID_IDBAsynchStatus, NULL,
  240. &lRows, (IUnknown**) ppIAsync);
  241. }
  242. }
  243. }
  244. if (dwNumRows)
  245. *dwNumRows = lRows;
  246. return hr;
  247. }
  248. //***************************************************************************
  249. //
  250. // CSQLExecute::IsDataReady
  251. //
  252. //***************************************************************************
  253. HRESULT CSQLExecute::IsDataReady(IDBAsynchStatus *pIAsync)
  254. {
  255. HRESULT hr = WBEM_S_NO_ERROR;
  256. unsigned long uAsyncPhase = 0;
  257. ULONG uProgress, uProgressMax;
  258. if (pIAsync)
  259. hr = pIAsync->GetStatus(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN,
  260. &uProgress, &uProgressMax, &uAsyncPhase, NULL);
  261. if (SUCCEEDED(hr))
  262. hr = WBEM_S_NO_ERROR;
  263. else if (hr == DB_E_CANCELED)
  264. hr = WBEM_S_OPERATION_CANCELLED;
  265. else
  266. {
  267. hr = WBEM_E_FAILED;
  268. // SetWMIOLEDBError(pIAsync);
  269. }
  270. if (uAsyncPhase == DBASYNCHPHASE_COMPLETE)
  271. hr = WBEM_S_NO_ERROR;
  272. else if (uAsyncPhase == DBASYNCHPHASE_INITIALIZATION ||
  273. uAsyncPhase == DBASYNCHPHASE_POPULATION)
  274. hr = WBEM_S_PENDING;
  275. return hr;
  276. }
  277. //***************************************************************************
  278. //
  279. // CSQLExecute::CancelQuery
  280. //
  281. //***************************************************************************
  282. HRESULT CSQLExecute::CancelQuery(IDBAsynchStatus *pIAsync)
  283. {
  284. HRESULT hr = WBEM_S_NO_ERROR;
  285. if (pIAsync)
  286. {
  287. hr = pIAsync->Abort(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN);
  288. }
  289. return hr;
  290. }
  291. //***************************************************************************
  292. //
  293. // CSQLExecute::GetNumColumns
  294. //
  295. //***************************************************************************
  296. HRESULT CSQLExecute::GetNumColumns(IRowset *pIRowset, IMalloc *pMalloc, int &iNumCols)
  297. {
  298. HRESULT hr = WBEM_S_NO_ERROR;
  299. DBCOLUMNINFO* pColumnsInfo = NULL;
  300. IColumnsInfo* pIColumnsInfo = NULL;
  301. OLECHAR* pColumnStrings = NULL;
  302. ULONG uNum;
  303. pIRowset->QueryInterface(IID_IColumnsInfo, (void**) &pIColumnsInfo);
  304. CReleaseMe r (pIColumnsInfo);
  305. hr = pIColumnsInfo->GetColumnInfo(&uNum, &pColumnsInfo, &pColumnStrings);
  306. pMalloc->Free( pColumnsInfo );
  307. pMalloc->Free( pColumnStrings );
  308. if (SUCCEEDED(hr))
  309. iNumCols = (int)uNum;
  310. return hr;
  311. }
  312. //***************************************************************************
  313. //
  314. // CSQLExecute::GetDataType
  315. //
  316. //***************************************************************************
  317. HRESULT CSQLExecute::GetDataType(IRowset *pIRowset, int iPos, IMalloc *pMalloc, DWORD &dwType,
  318. DWORD &dwSize, DWORD &dwPrec, DWORD &dwScale, LPWSTR *lpColName)
  319. {
  320. HRESULT hr = WBEM_S_NO_ERROR;
  321. DBCOLUMNINFO* pColumnsInfo = NULL;
  322. IColumnsInfo* pIColumnsInfo = NULL;
  323. OLECHAR* pColumnStrings = NULL;
  324. ULONG uNum;
  325. BYTE* pRowValues = NULL;
  326. pIRowset->QueryInterface(IID_IColumnsInfo, (void**) &pIColumnsInfo);
  327. CReleaseMe r (pIColumnsInfo);
  328. hr = pIColumnsInfo->GetColumnInfo(&uNum, &pColumnsInfo, &pColumnStrings);
  329. if (SUCCEEDED(hr) && uNum >= iPos)
  330. {
  331. dwSize = pColumnsInfo[iPos-1].ulColumnSize;
  332. dwPrec = pColumnsInfo[iPos-1].bPrecision;
  333. dwScale = pColumnsInfo[iPos-1].bScale;
  334. dwType = pColumnsInfo[iPos-1].wType;
  335. if (lpColName)
  336. *lpColName = Macro_CloneLPWSTR(pColumnsInfo[iPos-1].pwszName);
  337. }
  338. else
  339. {
  340. dwType = 0;
  341. dwSize = 0;
  342. dwPrec = 0;
  343. dwScale = 0;
  344. }
  345. pMalloc->Free( pColumnsInfo );
  346. pMalloc->Free( pColumnStrings );
  347. return hr;
  348. }
  349. //***************************************************************************
  350. //
  351. // CSQLExecute::GetColumnValue
  352. //
  353. //***************************************************************************
  354. HRESULT CSQLExecute::GetColumnValue(IRowset *pIRowset, int iPos, IMalloc *pMalloc, HROW **ppRow,
  355. VARIANT &vValue, LPWSTR * lpColName)
  356. {
  357. HRESULT hr = WBEM_S_NO_ERROR;
  358. DWORD dwType;
  359. DWORD dwOrigType ;
  360. IAccessor* pIAccessor=NULL; // Pointer to the
  361. // accessor
  362. HACCESSOR hAccessor; // Accessor handle
  363. HROW *pRows = NULL;
  364. ULONG cRowsObtained; // Count of rows
  365. // obtained
  366. DBBINDSTATUS* pDBBindStatus = NULL;
  367. DBBINDING* pDBBindings = NULL;
  368. OLEDBDATA data;
  369. VariantClear(&vValue);
  370. if (!ppRow)
  371. {
  372. hr = WBEM_E_INVALID_PARAMETER;
  373. }
  374. else
  375. {
  376. if (*ppRow)
  377. {
  378. pRows = *ppRow;
  379. }
  380. else
  381. {
  382. HROW *hRow = new HROW[1];
  383. if (!hRow)
  384. return WBEM_E_OUT_OF_MEMORY;
  385. pRows = &hRow[0];
  386. hr = pIRowset->GetNextRows( 0, // Reserved
  387. 0, // cRowsToSkip
  388. 1, // cRowsDesired
  389. &cRowsObtained, // cRowsObtained
  390. &pRows ); // Filled in w/ row handles.
  391. if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
  392. {
  393. *ppRow = pRows;
  394. }
  395. }
  396. if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
  397. {
  398. DWORD dwSize = 0, dwPrec = 0, dwScale = 0;
  399. hr = GetDataType(pIRowset, iPos, pMalloc, dwType, dwSize, dwPrec, dwScale, lpColName);
  400. if (SUCCEEDED(hr))
  401. {
  402. dwOrigType = dwType;
  403. if (dwType == DBTYPE_DATE || dwType == DBTYPE_DBDATE)
  404. {
  405. dwType = DBTYPE_DBTIMESTAMP;
  406. dwSize = sizeof(DBTIMESTAMP)+1;
  407. }
  408. else if (dwType == DBTYPE_CY ||
  409. (dwType == DBTYPE_NUMERIC && dwScale > 0) ||
  410. dwType == DBTYPE_GUID)
  411. {
  412. dwType = DBTYPE_WSTR;
  413. dwSize = 100;
  414. }
  415. pDBBindings = new DBBINDING[1];
  416. CDeleteMe <DBBINDING> r5 (pDBBindings);
  417. if (!pDBBindings)
  418. return WBEM_E_OUT_OF_MEMORY;
  419. pDBBindings[0].iOrdinal = iPos;
  420. pDBBindings[0].obValue = offsetof(OLEDBDATA, data);
  421. pDBBindings[0].obLength = offsetof(OLEDBDATA, dwLen);
  422. pDBBindings[0].obStatus = offsetof(OLEDBDATA, dwStatus);
  423. pDBBindings[0].pTypeInfo = NULL;
  424. pDBBindings[0].pObject = NULL;
  425. pDBBindings[0].pBindExt = NULL;
  426. pDBBindings[0].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
  427. pDBBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
  428. pDBBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
  429. pDBBindings[0].wType = dwType;
  430. if (dwSize > 65535)
  431. dwSize = 65535;
  432. if (dwType == DBTYPE_WSTR ||
  433. dwType == DBTYPE_STR ||
  434. dwType == DBTYPE_BSTR)
  435. pDBBindings[0].cbMaxLen = dwSize+1;
  436. else
  437. pDBBindings[0].cbMaxLen = dwSize;
  438. pDBBindings[0].dwFlags = 0;
  439. pDBBindings[0].bPrecision = dwPrec;
  440. pDBBindings[0].bScale = dwScale;
  441. pDBBindStatus = new DBBINDSTATUS[1];
  442. CDeleteMe <DBBINDSTATUS> r6 (pDBBindStatus);
  443. if (!pDBBindStatus)
  444. return WBEM_E_OUT_OF_MEMORY;
  445. pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
  446. CReleaseMe r7 (pIAccessor);
  447. hr = pIAccessor->CreateAccessor(
  448. DBACCESSOR_ROWDATA,// Accessor will be used to retrieve row
  449. // data
  450. 1, // Number of columns being bound
  451. pDBBindings, // Structure containing bind info
  452. 0,
  453. &hAccessor, // Returned accessor handle
  454. pDBBindStatus // Information about binding validity
  455. );
  456. if (SUCCEEDED(hr))
  457. {
  458. hr = pIRowset->GetData(*pRows, hAccessor, &data);
  459. VariantClear(&vValue);
  460. if (data.dwStatus != DBSTATUS_S_ISNULL)
  461. SetVariant(dwType, &vValue, data.data, dwOrigType);
  462. else
  463. vValue.vt = VT_NULL;
  464. hr = WBEM_S_NO_ERROR;
  465. }
  466. }
  467. pIAccessor->ReleaseAccessor(hAccessor, NULL);
  468. }
  469. }
  470. if (hr == DB_S_ENDOFROWSET)
  471. hr = WBEM_S_NO_MORE_DATA;
  472. return hr;
  473. }
  474. //***************************************************************************
  475. //
  476. // CSQLExecute::ReadImageValue
  477. //
  478. //***************************************************************************
  479. HRESULT CSQLExecute::ReadImageValue (IRowset *pIRowset, int iPos, HROW **ppRow, BYTE **ppBuffer, DWORD &dwLen)
  480. {
  481. HRESULT hr = WBEM_S_NO_ERROR;
  482. IAccessor* pIAccessor; // Pointer to the
  483. DBOBJECT ObjectStruct;
  484. HACCESSOR hAccessor; // Accessor handle
  485. ULONG cRowsObtained; // Count of rows
  486. // obtained
  487. DBBINDSTATUS* pDBBindStatus = NULL;
  488. DBBINDING *pDBBindings = NULL;
  489. ObjectStruct.dwFlags = STGM_READ;
  490. ObjectStruct.iid = IID_ISequentialStream;
  491. HROW* pRows = NULL;
  492. unsigned long cbRead; // Count of bytes read
  493. BLOBDATA BLOBGetData;
  494. if (!ppRow)
  495. {
  496. hr = WBEM_E_INVALID_PARAMETER;
  497. }
  498. else
  499. {
  500. if (*ppRow)
  501. {
  502. pRows = *ppRow;
  503. }
  504. else
  505. {
  506. HROW *hRow = new HROW[1];
  507. if (!hRow)
  508. return WBEM_E_OUT_OF_MEMORY;
  509. pRows = &hRow[0];
  510. hr = pIRowset->GetNextRows( 0, // Reserved
  511. 0, // cRowsToSkip
  512. 1, // cRowsDesired
  513. &cRowsObtained, // cRowsObtained
  514. &pRows ); // Filled in w/ row handles.
  515. if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
  516. {
  517. *ppRow = pRows;
  518. }
  519. }
  520. }
  521. dwLen = 0;
  522. if (hr != DB_S_ENDOFROWSET && SUCCEEDED(hr))
  523. {
  524. pDBBindings = new DBBINDING[1];
  525. if (!pDBBindings)
  526. return WBEM_E_OUT_OF_MEMORY;
  527. CDeleteMe <DBBINDING> d (pDBBindings);
  528. pDBBindings[0].iOrdinal = iPos;
  529. pDBBindings[0].obValue = offsetof(BLOBDATA, pISeqStream);
  530. pDBBindings[0].obLength = offsetof(BLOBDATA, dwLength);
  531. pDBBindings[0].obStatus = offsetof(BLOBDATA, dwStatus);
  532. pDBBindings[0].pTypeInfo = NULL;
  533. pDBBindings[0].pObject = &ObjectStruct;
  534. pDBBindings[0].pBindExt = NULL;
  535. pDBBindings[0].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
  536. pDBBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
  537. pDBBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
  538. pDBBindings[0].wType = DBTYPE_IUNKNOWN;
  539. pDBBindings[0].cbMaxLen = 0;
  540. pDBBindings[0].dwFlags = 0;
  541. pDBBindings[0].bPrecision = 0;
  542. pDBBindings[0].bScale = 0;
  543. pDBBindStatus = new DBBINDSTATUS[1];
  544. if (!pDBBindStatus)
  545. return WBEM_E_OUT_OF_MEMORY;
  546. CDeleteMe <DBBINDSTATUS> d1 (pDBBindStatus);
  547. pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
  548. CReleaseMe r1 (pIAccessor);
  549. hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1,
  550. pDBBindings, 0, &hAccessor, pDBBindStatus);
  551. if (FAILED(hr))
  552. hr = WBEM_E_OUT_OF_MEMORY;
  553. else
  554. {
  555. DWORD dwTotal = 0;
  556. // Get the row data, the pointer to an ISequentialStream*.
  557. hr = pIRowset->GetData(*pRows, hAccessor, &BLOBGetData);
  558. if (SUCCEEDED(hr) && BLOBGetData.dwStatus == DBSTATUS_S_OK)
  559. {
  560. ISequentialStream *pStream = BLOBGetData.pISeqStream;
  561. CReleaseMe r (pStream);
  562. DWORD dwSize = BLOBGetData.dwLength;
  563. BYTE *pbTemp = NULL;
  564. pbTemp = (BYTE *)CWin32DefaultArena::WbemMemAlloc(dwSize);
  565. if (!pbTemp)
  566. {
  567. hr = WBEM_E_OUT_OF_MEMORY;
  568. }
  569. else
  570. {
  571. ZeroMemory(pbTemp, dwSize);
  572. *ppBuffer = pbTemp;
  573. hr = pStream->Read(pbTemp, dwSize, &cbRead);
  574. if (hr == S_OK)
  575. dwLen = cbRead;
  576. else
  577. hr = WBEM_E_FAILED;
  578. }
  579. }
  580. pIAccessor->ReleaseAccessor(hAccessor, NULL);
  581. }
  582. }
  583. return hr;
  584. }
  585. //***************************************************************************
  586. //
  587. // CSQLExecute::WriteImageValue
  588. //
  589. //***************************************************************************
  590. HRESULT CSQLExecute::WriteImageValue(IDBCreateCommand *pIDBCreateCommand, LPCWSTR lpSQL, int iPos, BYTE *pValue, DWORD dwLen)
  591. {
  592. HRESULT hr = WBEM_S_NO_ERROR;
  593. IAccessor* pIAccessor; // Pointer to the
  594. DBOBJECT ObjectStruct;
  595. HACCESSOR hAccessor; // Accessor handle
  596. ULONG cRowsObtained; // Count of rows
  597. // obtained
  598. DBBINDSTATUS* pDBBindStatus = NULL;
  599. DBBINDING *pDBBindings = NULL;
  600. HROW* pRows = NULL;
  601. LONG lRows;
  602. ICommandText* pICommandText = NULL;
  603. ICommandProperties* pICommandProperties = NULL;
  604. IRowset *pIRowset = NULL;
  605. IRowsetChange *pRowsetChg = NULL;
  606. ObjectStruct.dwFlags = STGM_READ;
  607. ObjectStruct.iid = IID_ISequentialStream;
  608. BLOBDATA BLOBSetData;
  609. DBPROPSET rgPropSets[1];
  610. DBPROP rgProperties[1];
  611. const ULONG cProperties = 1;
  612. rgPropSets[0].guidPropertySet = DBPROPSET_ROWSET;
  613. rgPropSets[0].cProperties = cProperties;
  614. rgPropSets[0].rgProperties = rgProperties;
  615. //Now set properties in the property group (DBPROPSET_ROWSET)
  616. rgPropSets[0].rgProperties[0].dwPropertyID = DBPROP_UPDATABILITY;
  617. rgPropSets[0].rgProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
  618. rgPropSets[0].rgProperties[0].dwStatus = DBPROPSTATUS_OK;
  619. rgPropSets[0].rgProperties[0].colid = DB_NULLID;
  620. rgPropSets[0].rgProperties[0].vValue.vt = VT_I4;
  621. V_I4(&rgPropSets[0].rgProperties[0].vValue) = DBPROPVAL_UP_CHANGE;
  622. hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
  623. (IUnknown**) &pICommandText);
  624. CReleaseMe r1 (pICommandText);
  625. if (SUCCEEDED(hr))
  626. {
  627. //Set the rowset properties
  628. hr = pICommandText->QueryInterface(IID_ICommandProperties,
  629. (void **)&pICommandProperties);
  630. CReleaseMe r (pICommandProperties);
  631. if (SUCCEEDED(hr))
  632. {
  633. hr = pICommandProperties->SetProperties(1, rgPropSets);
  634. pICommandText->SetCommandText(DBGUID_DBSQL, lpSQL);
  635. ICommand *pICommand = NULL;
  636. pICommandText->QueryInterface(IID_ICommand,
  637. (void **) & pICommand);
  638. CReleaseMe r2 (pICommand);
  639. hr = pICommand->Execute(NULL, IID_IRowsetChange, NULL,
  640. &lRows, (IUnknown**) &pRowsetChg);
  641. CReleaseMe r3 (pRowsetChg);
  642. if (FAILED(hr))
  643. {
  644. int i = 0;
  645. hr = GetWMIError(pICommand);
  646. }
  647. else
  648. {
  649. hr = pRowsetChg->QueryInterface(IID_IRowset,
  650. (void **)&pIRowset);
  651. CReleaseMe r4 (pIRowset);
  652. if (SUCCEEDED(hr))
  653. {
  654. HROW *hRow = new HROW[1];
  655. if (!hRow)
  656. return WBEM_E_OUT_OF_MEMORY;
  657. pRows = &hRow[0];
  658. hr = pIRowset->GetNextRows( 0, // Reserved
  659. 0, // cRowsToSkip
  660. 1, // cRowsDesired
  661. &cRowsObtained, // cRowsObtained
  662. &pRows ); // Filled in w/ row handles.
  663. CDeleteMe <HROW> d0 (hRow);
  664. if (SUCCEEDED(hr))
  665. {
  666. pDBBindings = new DBBINDING[1];
  667. if (!pDBBindings)
  668. return WBEM_E_OUT_OF_MEMORY;
  669. CDeleteMe <DBBINDING> d1 (pDBBindings);
  670. pDBBindings[0].iOrdinal = iPos;
  671. pDBBindings[0].obValue = offsetof(BLOBDATA, pISeqStream);
  672. pDBBindings[0].obLength = offsetof(BLOBDATA, dwLength);
  673. pDBBindings[0].obStatus = offsetof(BLOBDATA, dwStatus);
  674. pDBBindings[0].pTypeInfo = NULL;
  675. pDBBindings[0].pObject = &ObjectStruct;
  676. pDBBindings[0].pBindExt = NULL;
  677. pDBBindings[0].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
  678. pDBBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
  679. pDBBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
  680. pDBBindings[0].wType = DBTYPE_IUNKNOWN;
  681. pDBBindings[0].cbMaxLen = 0;
  682. pDBBindings[0].dwFlags = 0;
  683. pDBBindings[0].bPrecision = 0;
  684. pDBBindings[0].bScale = 0;
  685. pDBBindStatus = new DBBINDSTATUS[1];
  686. if (!pDBBindStatus)
  687. return WBEM_E_OUT_OF_MEMORY;
  688. CDeleteMe <DBBINDSTATUS> d2 (pDBBindStatus);
  689. hr = pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
  690. CReleaseMe r5 (pIAccessor);
  691. if (SUCCEEDED(hr))
  692. {
  693. hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1,
  694. pDBBindings, 0, &hAccessor, pDBBindStatus);
  695. CSeqStream *pSeqStream = new CSeqStream;
  696. if (!pSeqStream)
  697. return WBEM_E_OUT_OF_MEMORY;
  698. pSeqStream->Write(pValue, dwLen, NULL);
  699. BLOBSetData.pISeqStream = pSeqStream;
  700. BLOBSetData.dwStatus = DBSTATUS_S_OK;
  701. BLOBSetData.dwLength = pSeqStream->Length();
  702. hr = pRowsetChg->SetData(pRows[0], hAccessor, &BLOBSetData);
  703. if (FAILED(hr))
  704. hr = GetWMIError(pICommand);
  705. pIAccessor->ReleaseAccessor(hAccessor, NULL);
  706. }
  707. pIRowset->ReleaseRows(1, pRows, NULL, NULL, NULL);
  708. }
  709. }
  710. }
  711. }
  712. }
  713. return hr;
  714. }
  715. //***************************************************************************
  716. //
  717. // CSQLExecute::SetVariant
  718. //
  719. //***************************************************************************
  720. void CSQLExecute::SetVariant(DWORD dwType, VARIANT *vValue, BYTE *pData, DWORD dwTargetType)
  721. {
  722. vValue->vt = VT_NULL;
  723. BYTE *pBuffer = NULL;
  724. wchar_t *wTemp = NULL;
  725. switch(dwType)
  726. {
  727. case DBTYPE_DBTIMESTAMP:
  728. if (*pData)
  729. {
  730. DBTIMESTAMP *pTime = ((DBTIMESTAMP *)pData);
  731. wchar_t szTmp[100];
  732. swprintf(szTmp, L"%04d%02d%02d%02d%02d%02d.%06d+000",
  733. pTime->year, pTime->month, pTime->day, pTime->hour,
  734. pTime->minute, pTime->second, pTime->fraction);
  735. V_BSTR(vValue) = SysAllocString((LPWSTR)szTmp);
  736. vValue->vt = VT_BSTR;
  737. }
  738. break;
  739. case DBTYPE_STR:
  740. wTemp = new wchar_t[(strlen((const char *)pData)*2)];
  741. if (wTemp)
  742. {
  743. swprintf(wTemp, L"%S", (const char *)pData);
  744. V_BSTR(vValue) = SysAllocString(wTemp);
  745. vValue->vt = VT_BSTR;
  746. delete wTemp;
  747. }
  748. break;
  749. case DBTYPE_WSTR:
  750. case DBTYPE_BSTR:
  751. V_BSTR(vValue) = SysAllocString((LPWSTR)pData);
  752. vValue->vt = VT_BSTR;
  753. break;
  754. case DBTYPE_I4:
  755. case DBTYPE_UI4:
  756. if (*((long *)pData) != NULL)
  757. V_I4(vValue) = *((long *)pData);
  758. else
  759. V_I4(vValue) = 0;
  760. vValue->vt = VT_I4;
  761. break;
  762. case DBTYPE_I2:
  763. case DBTYPE_UI2:
  764. if (*((short *)pData) != NULL)
  765. V_I4(vValue) = *((short *)pData);
  766. else
  767. V_I4(vValue) = 0;
  768. vValue->vt = VT_I4; // We are expecting the short ints to come out as long...
  769. break;
  770. case DBTYPE_I1:
  771. case DBTYPE_UI1:
  772. V_UI1(vValue) = *((BYTE *)pData);
  773. vValue->vt = VT_UI1;
  774. break;
  775. case DBTYPE_BOOL:
  776. V_BOOL(vValue) = (*((BOOL *)pData) ? TRUE: FALSE);
  777. vValue->vt = VT_BOOL;
  778. break;
  779. case DBTYPE_R4:
  780. if (*((float *)pData) != NULL)
  781. {
  782. vValue->fltVal = (*((float *)pData));
  783. }
  784. else
  785. vValue->fltVal = 0;
  786. vValue->vt = VT_R4;
  787. break;
  788. case DBTYPE_R8:
  789. if (*((double *)pData) != NULL)
  790. {
  791. vValue->dblVal = (*((double *)pData));
  792. }
  793. else
  794. vValue->dblVal = 0;
  795. vValue->vt = VT_R8;
  796. break;
  797. case DBTYPE_I8:
  798. case DBTYPE_UI8:
  799. case DBTYPE_NUMERIC:
  800. if (*pData != NULL)
  801. {
  802. wchar_t *pwTemp = NULL;
  803. long lRet;
  804. short sRet;
  805. BYTE bRet;
  806. DB_NUMERIC *pTemp = ((DB_NUMERIC *)pData);
  807. switch(dwTargetType)
  808. {
  809. case DBTYPE_I8:
  810. case DBTYPE_UI8:
  811. case DBTYPE_NUMERIC:
  812. GetInt64(pTemp, &pwTemp);
  813. vValue->bstrVal = SysAllocString(pwTemp);
  814. vValue->vt = VT_BSTR;
  815. delete pwTemp;
  816. break;
  817. case DBTYPE_I4:
  818. case DBTYPE_UI2:
  819. case DBTYPE_UI4:
  820. lRet = (*((long *)pTemp->val));
  821. vValue->lVal = lRet;
  822. if (!pTemp->sign) vValue->lVal *= -1;
  823. vValue->vt = VT_I4;
  824. break;
  825. case DBTYPE_I2:
  826. sRet = *((short *)pTemp->val);
  827. V_I2(vValue) = sRet;
  828. vValue->vt = VT_I2;
  829. if (!pTemp->sign) V_I2(vValue) *= -1;
  830. break;
  831. case CIM_BOOLEAN:
  832. V_BOOL(vValue) = *((BOOL *)pTemp->val)?true:false;
  833. vValue->vt = VT_BOOL;
  834. break;
  835. case DBTYPE_UI1:
  836. case DBTYPE_I1:
  837. case CIM_CHAR16:
  838. bRet = *((BYTE *)pTemp->val);
  839. V_UI1(vValue) = bRet;
  840. vValue->vt = VT_UI1;
  841. break;
  842. }
  843. }
  844. break;
  845. case DBTYPE_BYTES:
  846. // UINT8|ARRAY
  847. // We have to set this as an array of bytes.
  848. // vValue->pbVal = (BYTE *)pData;
  849. // vValue->vt = VT_UI1|VT_ARRAY; // ?? Is this right? TBD
  850. break;
  851. }
  852. }