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.

921 lines
26 KiB

  1. // ProductResource1.cpp: implementation of the CProductResource class.
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "ProductResource1.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CProductResource::CProductResource(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CProductResource::~CProductResource()
  18. {
  19. }
  20. HRESULT CProductResource::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. CRequestObject *pProductRObj = NULL;
  24. CRequestObject *pResRObj = NULL;
  25. try{
  26. if(atAction != ACTIONTYPE_ENUM)
  27. {
  28. // we are doing GetObject so we need to be reinitialized
  29. hr = WBEM_E_NOT_FOUND;
  30. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  31. int i;
  32. for(i = 0; i < m_pRequest->m_iPropCount; i++){
  33. if(_wcsicmp(m_pRequest->m_Property[i], L"Resource") == 0){
  34. pResRObj = new CRequestObject();
  35. if(!pResRObj) throw he;
  36. pResRObj->Initialize(m_pNamespace);
  37. pResRObj->ParsePath(m_pRequest->m_Value[i]);
  38. break;
  39. }
  40. if(_wcsicmp(m_pRequest->m_Property[i], L"Product") == 0){
  41. pProductRObj = new CRequestObject();
  42. if(!pProductRObj) throw he;
  43. pProductRObj->Initialize(m_pNamespace);
  44. pProductRObj->ParsePath(m_pRequest->m_Value[i]);
  45. break;
  46. }
  47. }
  48. }
  49. if((atAction == ACTIONTYPE_ENUM) || pProductRObj ||
  50. (pResRObj && pResRObj->m_bstrClass && (_wcsicmp(pResRObj->m_bstrClass, L"Win32_Patch") == 0)))
  51. if(FAILED(hr = ProductPatch(pHandler, atAction, pResRObj, pProductRObj))){
  52. if(pResRObj){
  53. pResRObj->Cleanup();
  54. delete pResRObj;
  55. pResRObj = NULL;
  56. }
  57. if(pProductRObj){
  58. pProductRObj->Cleanup();
  59. delete pProductRObj;
  60. pProductRObj = NULL;
  61. }
  62. return hr;
  63. }
  64. if((atAction == ACTIONTYPE_ENUM) || pProductRObj ||
  65. (pResRObj && pResRObj->m_bstrClass && (_wcsicmp(pResRObj->m_bstrClass, L"Win32_Property") == 0)))
  66. if(FAILED(hr = ProductProperty(pHandler, atAction, pResRObj, pProductRObj))){
  67. if(pResRObj){
  68. pResRObj->Cleanup();
  69. delete pResRObj;
  70. pResRObj = NULL;
  71. }
  72. if(pProductRObj){
  73. pProductRObj->Cleanup();
  74. delete pProductRObj;
  75. pProductRObj = NULL;
  76. }
  77. return hr;
  78. }
  79. if((atAction == ACTIONTYPE_ENUM) || pProductRObj ||
  80. (pResRObj && pResRObj->m_bstrClass && (_wcsicmp(pResRObj->m_bstrClass, L"Win32_PatchPackage") == 0)))
  81. if(FAILED(hr = ProductPatchPackage(pHandler, atAction, pResRObj, pProductRObj))){
  82. if(pResRObj){
  83. pResRObj->Cleanup();
  84. delete pResRObj;
  85. pResRObj = NULL;
  86. }
  87. if(pProductRObj){
  88. pProductRObj->Cleanup();
  89. delete pProductRObj;
  90. pProductRObj = NULL;
  91. }
  92. return hr;
  93. }
  94. if((atAction == ACTIONTYPE_ENUM) || pProductRObj ||
  95. (pResRObj && pResRObj->m_bstrClass && (_wcsicmp(pResRObj->m_bstrClass, L"Win32_Upgrade") == 0)))
  96. if(FAILED(hr = ProductUpgradeInformation(pHandler, atAction, pResRObj, pProductRObj))){
  97. if(pResRObj){
  98. pResRObj->Cleanup();
  99. delete pResRObj;
  100. pResRObj = NULL;
  101. }
  102. if(pProductRObj){
  103. pProductRObj->Cleanup();
  104. delete pProductRObj;
  105. pProductRObj = NULL;
  106. }
  107. return hr;
  108. }
  109. if(pResRObj){
  110. pResRObj->Cleanup();
  111. delete pResRObj;
  112. pResRObj = NULL;
  113. }
  114. if(pProductRObj){
  115. pProductRObj->Cleanup();
  116. delete pProductRObj;
  117. pProductRObj = NULL;
  118. }
  119. }catch(...){
  120. if(pResRObj){
  121. pResRObj->Cleanup();
  122. delete pResRObj;
  123. pResRObj = NULL;
  124. }
  125. if(pProductRObj){
  126. pProductRObj->Cleanup();
  127. delete pProductRObj;
  128. pProductRObj = NULL;
  129. }
  130. }
  131. return hr;
  132. }
  133. HRESULT CProductResource::ProductUpgradeInformation(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  134. CRequestObject *pResRObj, CRequestObject *pProductRObj)
  135. {
  136. HRESULT hr = WBEM_S_NO_ERROR;
  137. MSIHANDLE hView = NULL, hRecord = NULL;
  138. int i = -1;
  139. WCHAR wcBuf[BUFF_SIZE];
  140. WCHAR wcProduct[BUFF_SIZE];
  141. WCHAR wcUpgradeCode[BUFF_SIZE];
  142. WCHAR wcProductCode[39];
  143. WCHAR wcTestCode[39];
  144. DWORD dwBufSize;
  145. UINT uiStatus;
  146. bool bMatch = false;
  147. bool bTestCode = false;
  148. bool bUpgradeCode = false;
  149. if(atAction != ACTIONTYPE_ENUM){
  150. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  151. int j;
  152. if(pProductRObj){
  153. for(j = 0; j < pProductRObj->m_iPropCount; j++){
  154. if(_wcsicmp(pProductRObj->m_Property[j], L"IdentifyingNumber") == 0){
  155. //Get the product code we're looking for
  156. if ( ::SysStringLen (pProductRObj->m_Value[j]) < BUFF_SIZE )
  157. {
  158. wcscpy(wcTestCode, pProductRObj->m_Value[j]);
  159. bTestCode = true;
  160. break;
  161. }
  162. }
  163. }
  164. }
  165. if(pResRObj){
  166. for(j = 0; j < pResRObj->m_iPropCount; j++){
  167. if(_wcsicmp(pResRObj->m_Property[j], L"UpgradeCode") == 0){
  168. //Get the product code we're looking for
  169. if ( ::SysStringLen (pResRObj->m_Value[j]) < BUFF_SIZE )
  170. {
  171. wcscpy(wcUpgradeCode, pResRObj->m_Value[j]);
  172. bUpgradeCode = true;
  173. break;
  174. }
  175. }
  176. }
  177. }
  178. }
  179. bool bResource, bProduct;
  180. CStringExt wcResource;
  181. Query wcQuery;
  182. wcQuery.Append ( 1, L"select distinct `UpgradeCode`, `ProductVersion`, `Operator` from Upgrade" );
  183. //optimize for GetObject
  184. if ( bUpgradeCode && (atAction != ACTIONTYPE_ENUM) )
  185. {
  186. wcQuery.Append ( 3, L" where `UpgradeCode`=\'", wcUpgradeCode, L"\'" );
  187. }
  188. LPWSTR Buffer = NULL;
  189. LPWSTR dynBuffer = NULL;
  190. DWORD dwDynBuffer = 0L;
  191. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  192. {
  193. // safe operation:
  194. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  195. wcscpy(wcProductCode, m_pRequest->Package(i));
  196. if((atAction == ACTIONTYPE_ENUM) ||
  197. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  198. if(CreateProductString(wcProductCode, wcProduct)){
  199. //Open our database
  200. try
  201. {
  202. if ( GetView ( &hView, wcProductCode, wcQuery, L"Upgrade", TRUE, FALSE ) )
  203. {
  204. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  205. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  206. CheckMSI(uiStatus);
  207. wcResource.Copy ( L"Win32_Upgrade.UpgradeCode=\"" );
  208. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  209. //----------------------------------------------------
  210. dwBufSize = BUFF_SIZE;
  211. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 1, wcBuf, &dwBufSize));
  212. if(wcscmp(wcBuf, L"") != 0)
  213. {
  214. wcResource.Append ( 2, wcBuf, L"\",ProductVersion=\"" );
  215. dwBufSize = BUFF_SIZE;
  216. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  217. wcResource.Append ( 2, wcBuf, L"\",Operator=\"" );
  218. dwBufSize = BUFF_SIZE;
  219. GetBufferToPut ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  220. wcResource.Append ( 4, Buffer, L"\",ProductCode=\"", wcProductCode, L"\"" );
  221. PutKeyProperty(m_pObj, pResource, wcResource, &bResource, m_pRequest);
  222. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  223. {
  224. dynBuffer [ 0 ] = 0;
  225. }
  226. PutKeyProperty(m_pObj, pProduct, wcProduct, &bProduct, m_pRequest);
  227. //----------------------------------------------------
  228. if(bResource && bProduct) bMatch = true;
  229. if((atAction != ACTIONTYPE_GET) || bMatch){
  230. hr = pHandler->Indicate(1, &m_pObj);
  231. }
  232. }
  233. m_pObj->Release();
  234. m_pObj = NULL;
  235. g_fpMsiCloseHandle(hRecord);
  236. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  237. }
  238. }
  239. }
  240. catch(...)
  241. {
  242. if ( dynBuffer )
  243. {
  244. delete [] dynBuffer;
  245. dynBuffer = NULL;
  246. }
  247. if (hRecord)
  248. g_fpMsiCloseHandle(hRecord);
  249. if (hView)
  250. {
  251. g_fpMsiViewClose(hView);
  252. g_fpMsiCloseHandle(hView);
  253. }
  254. msidata.CloseDatabase ();
  255. if(m_pObj)
  256. {
  257. m_pObj->Release();
  258. m_pObj = NULL;
  259. }
  260. throw;
  261. }
  262. if (hRecord)
  263. g_fpMsiCloseHandle(hRecord);
  264. if (hView)
  265. {
  266. g_fpMsiViewClose(hView);
  267. g_fpMsiCloseHandle(hView);
  268. }
  269. msidata.CloseDatabase ();
  270. }
  271. }
  272. }
  273. if ( dynBuffer )
  274. {
  275. delete [] dynBuffer;
  276. dynBuffer = NULL;
  277. }
  278. return hr;
  279. }
  280. HRESULT CProductResource::ProductPatchPackage(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  281. CRequestObject *pResRObj, CRequestObject *pProductRObj)
  282. {
  283. HRESULT hr = WBEM_S_NO_ERROR;
  284. MSIHANDLE hView = NULL, hRecord = NULL;
  285. int i = -1;
  286. WCHAR wcBuf[39];
  287. WCHAR wcProduct[BUFF_SIZE];
  288. WCHAR wcPatchID[BUFF_SIZE];
  289. WCHAR wcProductCode[39];
  290. WCHAR wcTestCode[39];
  291. DWORD dwBufSize;
  292. UINT uiStatus;
  293. bool bMatch = false;
  294. bool bTestCode = false;
  295. bool bPatchID = false;
  296. if(atAction != ACTIONTYPE_ENUM){
  297. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  298. int j;
  299. if(pProductRObj){
  300. for(j = 0; j < pProductRObj->m_iPropCount; j++){
  301. if(_wcsicmp(pProductRObj->m_Property[j], L"IdentifyingNumber") == 0){
  302. //Get the product code we're looking for
  303. if ( ::SysStringLen (pProductRObj->m_Value[j]) < BUFF_SIZE )
  304. {
  305. wcscpy(wcTestCode, pProductRObj->m_Value[j]);
  306. bTestCode = true;
  307. break;
  308. }
  309. }
  310. }
  311. }
  312. if(pResRObj){
  313. for(j = 0; j < pResRObj->m_iPropCount; j++){
  314. if(_wcsicmp(pResRObj->m_Property[j], L"PatchID") == 0){
  315. //Get the product code we're looking for
  316. if ( ::SysStringLen (pResRObj->m_Value[j]) < BUFF_SIZE )
  317. {
  318. wcscpy(wcPatchID, pResRObj->m_Value[j]);
  319. bPatchID = true;
  320. break;
  321. }
  322. }
  323. }
  324. }
  325. }
  326. bool bResource, bProduct;
  327. CStringExt wcResource;
  328. Query wcQuery;
  329. wcQuery.Append ( 1, L"select distinct `PatchId` from PatchPackage" );
  330. //optimize for GetObject
  331. if ( bPatchID && (atAction != ACTIONTYPE_ENUM) )
  332. {
  333. wcQuery.Append ( 3, L" where `PatchId`=\'", wcPatchID, L"\'" );
  334. }
  335. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  336. {
  337. // safe operation:
  338. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  339. wcscpy(wcProductCode, m_pRequest->Package(i));
  340. if((atAction == ACTIONTYPE_ENUM) ||
  341. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  342. if(CreateProductString(wcProductCode, wcProduct)){
  343. //Open our database
  344. try
  345. {
  346. if ( GetView ( &hView, wcProductCode, wcQuery, L"PatchPackage", TRUE, FALSE ) )
  347. {
  348. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  349. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  350. CheckMSI(uiStatus);
  351. wcResource.Copy ( L"Win32_PatchPackage.PatchID=\"" );
  352. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  353. //----------------------------------------------------
  354. dwBufSize = 39;
  355. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 1, wcBuf, &dwBufSize));
  356. if(wcscmp(wcBuf, L"") != 0)
  357. {
  358. wcResource.Append ( 4, wcBuf, L"\",ProductCode=\"", wcProductCode, L"\"" );
  359. PutKeyProperty(m_pObj, pResource, wcResource, &bResource, m_pRequest);
  360. PutKeyProperty(m_pObj, pProduct, wcProduct, &bProduct, m_pRequest);
  361. //====================================================
  362. //----------------------------------------------------
  363. if(bResource && bProduct) bMatch = true;
  364. if((atAction != ACTIONTYPE_GET) || bMatch){
  365. hr = pHandler->Indicate(1, &m_pObj);
  366. }
  367. }
  368. m_pObj->Release();
  369. m_pObj = NULL;
  370. g_fpMsiCloseHandle(hRecord);
  371. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  372. }
  373. }
  374. }
  375. catch(...)
  376. {
  377. if (hRecord)
  378. g_fpMsiCloseHandle(hRecord);
  379. if (hView)
  380. {
  381. g_fpMsiViewClose(hView);
  382. g_fpMsiCloseHandle(hView);
  383. }
  384. msidata.CloseDatabase ();
  385. if(m_pObj)
  386. {
  387. m_pObj->Release();
  388. m_pObj = NULL;
  389. }
  390. throw;
  391. }
  392. if (hRecord)
  393. g_fpMsiCloseHandle(hRecord);
  394. if (hView)
  395. {
  396. g_fpMsiViewClose(hView);
  397. g_fpMsiCloseHandle(hView);
  398. }
  399. msidata.CloseDatabase ();
  400. }
  401. }
  402. }
  403. return hr;
  404. }
  405. HRESULT CProductResource::ProductProperty(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  406. CRequestObject *pResRObj, CRequestObject *pProductRObj)
  407. {
  408. HRESULT hr = WBEM_S_NO_ERROR;
  409. MSIHANDLE hView = NULL, hRecord = NULL;
  410. int i = -1;
  411. WCHAR wcBuf[BUFF_SIZE];
  412. WCHAR wcProduct[BUFF_SIZE];
  413. WCHAR wcProperty[BUFF_SIZE];
  414. WCHAR wcProductCode[39];
  415. WCHAR wcTestCode[39];
  416. DWORD dwBufSize;
  417. UINT uiStatus;
  418. bool bMatch = false;
  419. bool bTestCode = false;
  420. bool bProperty = false;
  421. if(atAction != ACTIONTYPE_ENUM){
  422. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  423. int j;
  424. if(pProductRObj){
  425. for(j = 0; j < pProductRObj->m_iPropCount; j++){
  426. if(_wcsicmp(pProductRObj->m_Property[j], L"IdentifyingNumber") == 0){
  427. //Get the product code we're looking for
  428. if ( ::SysStringLen (pProductRObj->m_Value[j]) < BUFF_SIZE )
  429. {
  430. wcscpy(wcTestCode, pProductRObj->m_Value[j]);
  431. bTestCode = true;
  432. break;
  433. }
  434. }
  435. }
  436. }
  437. if(pResRObj){
  438. for(j = 0; j < pResRObj->m_iPropCount; j++){
  439. if(_wcsicmp(pResRObj->m_Property[j], L"PatchID") == 0){
  440. //Get the product code we're looking for
  441. if ( ::SysStringLen (pResRObj->m_Value[j]) < BUFF_SIZE )
  442. {
  443. wcscpy(wcProperty, pResRObj->m_Value[j]);
  444. bProperty = true;
  445. break;
  446. }
  447. }
  448. }
  449. }
  450. }
  451. bool bResource, bProduct;
  452. CStringExt wcResource;
  453. Query wcQuery;
  454. wcQuery.Append ( 1, L"select distinct `Property` from Property" );
  455. //optimize for GetObject
  456. if ( bProperty && (atAction != ACTIONTYPE_ENUM) )
  457. {
  458. wcQuery.Append ( 3, L" where `Property`=\'", wcProperty, L"\'" );
  459. }
  460. LPWSTR Buffer = NULL;
  461. LPWSTR dynBuffer = NULL;
  462. DWORD dwDynBuffer = 0L;
  463. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  464. {
  465. // safe operation:
  466. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  467. wcscpy(wcProductCode, m_pRequest->Package(i));
  468. if((atAction == ACTIONTYPE_ENUM) ||
  469. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  470. if(CreateProductString(wcProductCode, wcProduct))
  471. {
  472. //Open our database
  473. try
  474. {
  475. if ( GetView ( &hView, wcProductCode, wcQuery, L"Property", TRUE, FALSE ) )
  476. {
  477. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  478. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  479. CheckMSI(uiStatus);
  480. wcResource.Copy ( L"Win32_Property.Property=\"" );
  481. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  482. //----------------------------------------------------
  483. dwBufSize = BUFF_SIZE;
  484. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  485. if ( Buffer && Buffer [ 0 ] != 0 )
  486. {
  487. wcResource.Append ( 4, Buffer, L"\",ProductCode=\"", wcProductCode, L"\"" );
  488. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  489. {
  490. dynBuffer [ 0 ] = 0;
  491. }
  492. PutKeyProperty(m_pObj, pResource, wcResource, &bResource, m_pRequest);
  493. PutKeyProperty(m_pObj, pProduct, wcProduct, &bProduct, m_pRequest);
  494. //====================================================
  495. //----------------------------------------------------
  496. if(bResource && bProduct) bMatch = true;
  497. if((atAction != ACTIONTYPE_GET) || bMatch){
  498. hr = pHandler->Indicate(1, &m_pObj);
  499. }
  500. }
  501. m_pObj->Release();
  502. m_pObj = NULL;
  503. g_fpMsiCloseHandle(hRecord);
  504. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  505. }
  506. }
  507. }
  508. catch(...)
  509. {
  510. if ( dynBuffer )
  511. {
  512. delete [] dynBuffer;
  513. dynBuffer = NULL;
  514. }
  515. if (hRecord)
  516. g_fpMsiCloseHandle(hRecord);
  517. if (hView)
  518. {
  519. g_fpMsiViewClose(hView);
  520. g_fpMsiCloseHandle(hView);
  521. }
  522. msidata.CloseDatabase ();
  523. if(m_pObj)
  524. {
  525. m_pObj->Release();
  526. m_pObj = NULL;
  527. }
  528. throw;
  529. }
  530. if (hRecord)
  531. g_fpMsiCloseHandle(hRecord);
  532. if (hView)
  533. {
  534. g_fpMsiViewClose(hView);
  535. g_fpMsiCloseHandle(hView);
  536. }
  537. msidata.CloseDatabase ();
  538. }
  539. }
  540. }
  541. if ( dynBuffer )
  542. {
  543. delete [] dynBuffer;
  544. dynBuffer = NULL;
  545. }
  546. return hr;
  547. }
  548. HRESULT CProductResource::ProductPatch(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  549. CRequestObject *pResRObj, CRequestObject *pProductRObj)
  550. {
  551. HRESULT hr = WBEM_S_NO_ERROR;
  552. MSIHANDLE hView = NULL, hRecord = NULL;
  553. int i = -1;
  554. WCHAR wcBuf[BUFF_SIZE];
  555. WCHAR wcProduct[BUFF_SIZE];
  556. WCHAR wcPatch[BUFF_SIZE];
  557. WCHAR wcProductCode[39];
  558. WCHAR wcTestCode[39];
  559. DWORD dwBufSize;
  560. UINT uiStatus;
  561. bool bMatch = false;
  562. bool bTestCode = false;
  563. bool bPatch = false;
  564. if(atAction != ACTIONTYPE_ENUM){
  565. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  566. int j;
  567. if(pProductRObj){
  568. for(j = 0; j < pProductRObj->m_iPropCount; j++){
  569. if(_wcsicmp(pProductRObj->m_Property[j], L"IdentifyingNumber") == 0){
  570. //Get the product code we're looking for
  571. if ( ::SysStringLen (pProductRObj->m_Value[j]) < BUFF_SIZE )
  572. {
  573. wcscpy(wcTestCode, pProductRObj->m_Value[j]);
  574. bTestCode = true;
  575. break;
  576. }
  577. }
  578. }
  579. }
  580. if(pResRObj){
  581. for(j = 0; j < pResRObj->m_iPropCount; j++){
  582. if(_wcsicmp(pResRObj->m_Property[j], L"File") == 0){
  583. //Get the product code we're looking for
  584. if ( ::SysStringLen (pResRObj->m_Value[j]) < BUFF_SIZE )
  585. {
  586. wcscpy(wcPatch, pResRObj->m_Value[j]);
  587. bPatch = true;
  588. break;
  589. }
  590. }
  591. }
  592. }
  593. }
  594. bool bResource, bProduct;
  595. CStringExt wcResource;
  596. Query wcQuery;
  597. wcQuery.Append ( 1, L"select distinct `File_`, `Sequence` from Patch" );
  598. //optimize for GetObject
  599. if ( bPatch && (atAction != ACTIONTYPE_ENUM) )
  600. {
  601. wcQuery.Append ( 3, L" where `File_`=\'", wcPatch, L"\'" );
  602. }
  603. LPWSTR Buffer = NULL;
  604. LPWSTR dynBuffer = NULL;
  605. DWORD dwDynBuffer = 0L;
  606. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  607. {
  608. // safe operation:
  609. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  610. wcscpy(wcProductCode, m_pRequest->Package(i));
  611. if((atAction == ACTIONTYPE_ENUM) ||
  612. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  613. if(CreateProductString(wcProductCode, wcProduct)){
  614. //Open our database
  615. try
  616. {
  617. if ( GetView ( &hView, wcProductCode, wcQuery, L"Patch", TRUE, FALSE ) )
  618. {
  619. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  620. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  621. CheckMSI(uiStatus);
  622. wcResource.Copy ( L"Win32_Patch.File=\"" );
  623. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  624. //----------------------------------------------------
  625. dwBufSize = BUFF_SIZE;
  626. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  627. if( Buffer && Buffer[ 0 ] != 0 )
  628. {
  629. wcResource.Append ( 2, Buffer, L"\",Sequence=\"" );
  630. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  631. {
  632. dynBuffer [ 0 ] = 0;
  633. }
  634. dwBufSize = BUFF_SIZE;
  635. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  636. if(wcscmp(wcBuf, L"") != 0)
  637. {
  638. wcResource.Append ( 4, wcBuf, L"\",ProductCode=\"", wcProductCode, L"\"" );
  639. PutKeyProperty(m_pObj, pResource, wcResource, &bResource, m_pRequest);
  640. PutKeyProperty(m_pObj, pProduct, wcProduct, &bProduct, m_pRequest);
  641. //====================================================
  642. //----------------------------------------------------
  643. if(bResource && bProduct) bMatch = true;
  644. if((atAction != ACTIONTYPE_GET) || bMatch){
  645. hr = pHandler->Indicate(1, &m_pObj);
  646. }
  647. }
  648. }
  649. m_pObj->Release();
  650. m_pObj = NULL;
  651. g_fpMsiCloseHandle(hRecord);
  652. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  653. }
  654. }
  655. }
  656. catch(...)
  657. {
  658. if ( dynBuffer )
  659. {
  660. delete [] dynBuffer;
  661. dynBuffer = NULL;
  662. }
  663. if (hRecord)
  664. g_fpMsiCloseHandle(hRecord);
  665. if (hView)
  666. {
  667. g_fpMsiViewClose(hView);
  668. g_fpMsiCloseHandle(hView);
  669. }
  670. msidata.CloseDatabase ();
  671. if(m_pObj)
  672. {
  673. m_pObj->Release();
  674. m_pObj = NULL;
  675. }
  676. throw;
  677. }
  678. if (hRecord)
  679. g_fpMsiCloseHandle(hRecord);
  680. if (hView)
  681. {
  682. g_fpMsiViewClose(hView);
  683. g_fpMsiCloseHandle(hView);
  684. }
  685. msidata.CloseDatabase ();
  686. }
  687. }
  688. }
  689. if ( dynBuffer )
  690. {
  691. delete [] dynBuffer;
  692. dynBuffer = NULL;
  693. }
  694. return hr;
  695. }