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.

1677 lines
44 KiB

  1. // SoftwareElementCheck.cpp: implementation of the CSoftwareElementCheck class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "SoftwareElementCheck.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CSoftwareElementCheck::CSoftwareElementCheck(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CSoftwareElementCheck::~CSoftwareElementCheck()
  18. {
  19. }
  20. HRESULT CSoftwareElementCheck::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_E_FAILED;
  23. CRequestObject *pCheckRObj = NULL;
  24. CRequestObject *pElementRObj = 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. for(int i = 0; i < m_pRequest->m_iPropCount; i++){
  32. if(_wcsicmp(m_pRequest->m_Property[i], L"CHECK") == 0){
  33. pCheckRObj = new CRequestObject();
  34. if(!pCheckRObj) throw he;
  35. pCheckRObj->Initialize(m_pNamespace);
  36. pCheckRObj->ParsePath(m_pRequest->m_Value[i]);
  37. break;
  38. }
  39. if(_wcsicmp(m_pRequest->m_Property[i], L"Element") == 0){
  40. pElementRObj = new CRequestObject();
  41. if(!pElementRObj) throw he;
  42. pElementRObj->Initialize(m_pNamespace);
  43. pElementRObj->ParsePath(m_pRequest->m_Value[i]);
  44. }
  45. }
  46. }
  47. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  48. (pCheckRObj && pCheckRObj->m_bstrClass && (_wcsicmp(pCheckRObj->m_bstrClass, L"Win32_FileSpecification") == 0)))
  49. if(FAILED(hr = SoftwareElementFile(pHandler, atAction, pCheckRObj, pElementRObj))){
  50. if(pCheckRObj){
  51. pCheckRObj->Cleanup();
  52. delete pCheckRObj;
  53. pCheckRObj = NULL;
  54. }
  55. if(pElementRObj){
  56. pElementRObj->Cleanup();
  57. delete pElementRObj;
  58. pElementRObj = NULL;
  59. }
  60. return hr;
  61. }
  62. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  63. (pCheckRObj && pCheckRObj->m_bstrClass && (_wcsicmp(pCheckRObj->m_bstrClass, L"Win32_IniFileSpecification") == 0)))
  64. if(FAILED(hr = SoftwareElementIniFile(pHandler, atAction, pCheckRObj, pElementRObj))){
  65. if(pCheckRObj){
  66. pCheckRObj->Cleanup();
  67. delete pCheckRObj;
  68. pCheckRObj = NULL;
  69. }
  70. if(pElementRObj){
  71. pElementRObj->Cleanup();
  72. delete pElementRObj;
  73. pElementRObj = NULL;
  74. }
  75. return hr;
  76. }
  77. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  78. (pCheckRObj && pCheckRObj->m_bstrClass && (_wcsicmp(pCheckRObj->m_bstrClass, L"Win32_ReserveCost") == 0)))
  79. if(FAILED(hr = SoftwareElementReserveCost(pHandler, atAction, pCheckRObj, pElementRObj))){
  80. if(pCheckRObj){
  81. pCheckRObj->Cleanup();
  82. delete pCheckRObj;
  83. pCheckRObj = NULL;
  84. }
  85. if(pElementRObj){
  86. pElementRObj->Cleanup();
  87. delete pElementRObj;
  88. pElementRObj = NULL;
  89. }
  90. return hr;
  91. }
  92. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  93. (pCheckRObj && pCheckRObj->m_bstrClass && (_wcsicmp(pCheckRObj->m_bstrClass, L"Win32_EnvironmentSpecification") == 0)))
  94. if(FAILED(hr = SoftwareElementEnvironment(pHandler, atAction, pCheckRObj, pElementRObj))){
  95. if(pCheckRObj){
  96. pCheckRObj->Cleanup();
  97. delete pCheckRObj;
  98. pCheckRObj = NULL;
  99. }
  100. if(pElementRObj){
  101. pElementRObj->Cleanup();
  102. delete pElementRObj;
  103. pElementRObj = NULL;
  104. }
  105. return hr;
  106. }
  107. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  108. (pCheckRObj && pCheckRObj->m_bstrClass && (_wcsicmp(pCheckRObj->m_bstrClass, L"Win32_ODBCTranslatorSpecification") == 0)))
  109. if(FAILED(hr = ODBCTranslatorSoftwareElement(pHandler, atAction, pCheckRObj, pElementRObj))){
  110. if(pCheckRObj){
  111. pCheckRObj->Cleanup();
  112. delete pCheckRObj;
  113. pCheckRObj = NULL;
  114. }
  115. if(pElementRObj){
  116. pElementRObj->Cleanup();
  117. delete pElementRObj;
  118. pElementRObj = NULL;
  119. }
  120. return hr;
  121. }
  122. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  123. (pCheckRObj && pCheckRObj->m_bstrClass && (_wcsicmp(pCheckRObj->m_bstrClass, L"Win32_ODBCDataSourceSpecification") == 0)))
  124. if(FAILED(hr = ODBCDataSourceSoftwareElement(pHandler, atAction, pCheckRObj, pElementRObj))){
  125. if(pCheckRObj){
  126. pCheckRObj->Cleanup();
  127. delete pCheckRObj;
  128. pCheckRObj = NULL;
  129. }
  130. if(pElementRObj){
  131. pElementRObj->Cleanup();
  132. delete pElementRObj;
  133. pElementRObj = NULL;
  134. }
  135. return hr;
  136. }
  137. if(pCheckRObj){
  138. pCheckRObj->Cleanup();
  139. delete pCheckRObj;
  140. pCheckRObj = NULL;
  141. }
  142. if(pElementRObj){
  143. pElementRObj->Cleanup();
  144. delete pElementRObj;
  145. pElementRObj = NULL;
  146. }
  147. }catch(...){
  148. if(pCheckRObj){
  149. pCheckRObj->Cleanup();
  150. delete pCheckRObj;
  151. pCheckRObj = NULL;
  152. }
  153. if(pElementRObj){
  154. pElementRObj->Cleanup();
  155. delete pElementRObj;
  156. pElementRObj = NULL;
  157. }
  158. }
  159. return hr;
  160. }
  161. HRESULT CSoftwareElementCheck::ODBCDataSourceSoftwareElement(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  162. CRequestObject *pCheckData, CRequestObject *pElementData)
  163. {
  164. HRESULT hr = WBEM_S_NO_ERROR;
  165. MSIHANDLE hView = NULL;
  166. MSIHANDLE hRecord = NULL;
  167. int i = -1;
  168. WCHAR wcBuf[BUFF_SIZE];
  169. WCHAR wcProductCode[39];
  170. WCHAR wcTestCode[39];
  171. WCHAR wcDataSource[BUFF_SIZE];
  172. DWORD dwBufSize;
  173. bool bMatch = false;
  174. bool bTestCode = false;
  175. UINT uiStatus;
  176. WCHAR wcElement[BUFF_SIZE];
  177. bool bCheck = false;
  178. bool bGotElement = false;
  179. CStringExt wcProp;
  180. if(atAction != ACTIONTYPE_ENUM){
  181. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  182. if(pCheckData){
  183. for(int i = 0; i < pCheckData->m_iPropCount; i++){
  184. if(_wcsicmp(pCheckData->m_Property[i], L"CheckID") == 0)
  185. {
  186. if ( ::SysStringLen ( pCheckData->m_Value[i] ) < BUFF_SIZE )
  187. {
  188. //Get the action we're looking for
  189. wcscpy(wcBuf, pCheckData->m_Value[i]);
  190. // safe operation if wcslen ( wcBuf ) > 38
  191. if ( wcslen ( wcBuf ) > 38 )
  192. {
  193. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  194. }
  195. else
  196. {
  197. // we are not good to go, they have sent us longer string
  198. throw hr;
  199. }
  200. // safe because lenght has been tested already in condition
  201. RemoveFinalGUID(pCheckData->m_Value[i], wcDataSource);
  202. bCheck = true;
  203. bTestCode = true;
  204. break;
  205. }
  206. else
  207. {
  208. // we are not good to go, they have sent us longer string
  209. throw hr;
  210. }
  211. }
  212. }
  213. }
  214. if(pElementData){
  215. for(int j = 0; j < pElementData->m_iPropCount; j++){
  216. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  217. //Get the product code we're looking for
  218. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  219. {
  220. wcscpy(wcElement, pElementData->m_Value[j]);
  221. bGotElement = true;
  222. break;
  223. }
  224. }
  225. }
  226. }
  227. }
  228. //These will change from class to class
  229. bool bFeature, bElement;
  230. Query wcQuery;
  231. wcQuery.Append ( 1, L"select distinct `Component_`, `DataSource` from ODBCDataSource" );
  232. //optimize for GetObject
  233. if ( bGotElement || bCheck )
  234. {
  235. if ( bCheck )
  236. {
  237. wcQuery.Append ( 3, L" where `DataSource`=\'", wcDataSource, L"\'" );
  238. }
  239. if ( bGotElement )
  240. {
  241. if ( bCheck )
  242. {
  243. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  244. }
  245. else
  246. {
  247. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  248. }
  249. }
  250. }
  251. LPWSTR Buffer = NULL;
  252. LPWSTR dynBuffer = NULL;
  253. DWORD dwDynBuffer = 0L;
  254. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  255. {
  256. // safe operation:
  257. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  258. wcscpy(wcProductCode, m_pRequest->Package(i));
  259. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  260. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  261. //Open our database
  262. try
  263. {
  264. if ( GetView ( &hView, wcProductCode, wcQuery, L"ODBCDataSource", TRUE, FALSE ) )
  265. {
  266. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  267. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  268. CheckMSI(uiStatus);
  269. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  270. //----------------------------------------------------
  271. dwBufSize = BUFF_SIZE;
  272. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  273. if ( ValidateComponentName ( msidata.GetDatabase(), wcProductCode, Buffer ) )
  274. {
  275. dwBufSize = BUFF_SIZE;
  276. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  277. wcBuf,
  278. wcProductCode,
  279. wcElement,
  280. &dwBufSize
  281. );
  282. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  283. {
  284. dynBuffer [ 0 ] = 0;
  285. }
  286. if( uiStatus == ERROR_SUCCESS )
  287. {
  288. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  289. dwBufSize = BUFF_SIZE;
  290. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  291. if ( Buffer && Buffer [ 0 ] != 0 )
  292. {
  293. // safe operation
  294. wcProp.Copy(L"Win32_ODBCDataSourceSpecification.CheckID=\"");
  295. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  296. PutKeyProperty(m_pObj, pCheck, wcProp, &bFeature, m_pRequest);
  297. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  298. {
  299. dynBuffer [ 0 ] = 0;
  300. }
  301. if(bFeature && bElement) bMatch = true;
  302. if((atAction != ACTIONTYPE_GET) || bMatch){
  303. hr = pHandler->Indicate(1, &m_pObj);
  304. }
  305. }
  306. }
  307. }
  308. else
  309. {
  310. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  311. {
  312. dynBuffer [ 0 ] = 0;
  313. }
  314. }
  315. m_pObj->Release();
  316. m_pObj = NULL;
  317. g_fpMsiCloseHandle(hRecord);
  318. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  319. }
  320. }
  321. }
  322. catch(...)
  323. {
  324. if ( dynBuffer )
  325. {
  326. delete [] dynBuffer;
  327. dynBuffer = NULL;
  328. }
  329. g_fpMsiCloseHandle(hRecord);
  330. g_fpMsiViewClose(hView);
  331. g_fpMsiCloseHandle(hView);
  332. msidata.CloseDatabase ();
  333. if(m_pObj)
  334. {
  335. m_pObj->Release();
  336. m_pObj = NULL;
  337. }
  338. throw;
  339. }
  340. g_fpMsiCloseHandle(hRecord);
  341. g_fpMsiViewClose(hView);
  342. g_fpMsiCloseHandle(hView);
  343. msidata.CloseDatabase ();
  344. }
  345. }
  346. if ( dynBuffer )
  347. {
  348. delete [] dynBuffer;
  349. dynBuffer = NULL;
  350. }
  351. return hr;
  352. }
  353. HRESULT CSoftwareElementCheck::ODBCTranslatorSoftwareElement(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  354. CRequestObject *pCheckData,CRequestObject *pElementData)
  355. {
  356. HRESULT hr = WBEM_S_NO_ERROR;
  357. MSIHANDLE hView = NULL;
  358. MSIHANDLE hRecord = NULL;
  359. int i = -1;
  360. WCHAR wcBuf[BUFF_SIZE];
  361. WCHAR wcTestCode[39];
  362. WCHAR wcProductCode[39];
  363. WCHAR wcTranslator[BUFF_SIZE];
  364. DWORD dwBufSize;
  365. bool bMatch = false;
  366. bool bTestCode = false;
  367. UINT uiStatus;
  368. WCHAR wcElement[BUFF_SIZE];
  369. bool bCheck = false;
  370. bool bGotElement = false;
  371. CStringExt wcProp;
  372. if(atAction != ACTIONTYPE_ENUM){
  373. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  374. if(pCheckData){
  375. for(int i = 0; i < pCheckData->m_iPropCount; i++){
  376. if(_wcsicmp(pCheckData->m_Property[i], L"CheckID") == 0)
  377. {
  378. if ( ::SysStringLen ( pCheckData->m_Value[i] ) < BUFF_SIZE )
  379. {
  380. //Get the action we're looking for
  381. wcscpy(wcBuf, pCheckData->m_Value[i]);
  382. // safe operation if wcslen ( wcBuf ) > 38
  383. if ( wcslen ( wcBuf ) > 38 )
  384. {
  385. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  386. }
  387. else
  388. {
  389. // we are not good to go, they have sent us longer string
  390. throw hr;
  391. }
  392. // safe because lenght has been tested already in condition
  393. RemoveFinalGUID(pCheckData->m_Value[i], wcTranslator);
  394. bCheck = true;
  395. bTestCode = true;
  396. break;
  397. }
  398. else
  399. {
  400. // we are not good to go, they have sent us longer string
  401. throw hr;
  402. }
  403. }
  404. }
  405. }
  406. if(pElementData){
  407. for(int j = 0; j < pElementData->m_iPropCount; j++){
  408. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  409. //Get the product code we're looking for
  410. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  411. {
  412. wcscpy(wcElement, pElementData->m_Value[j]);
  413. bGotElement = true;
  414. break;
  415. }
  416. }
  417. }
  418. }
  419. }
  420. //These will change from class to class
  421. bool bFeature, bElement;
  422. Query wcQuery;
  423. wcQuery.Append ( 1, L"select distinct `Component_`, `Translator` from ODBCTranslator" );
  424. //optimize for GetObject
  425. if ( bGotElement || bCheck )
  426. {
  427. if ( bCheck )
  428. {
  429. wcQuery.Append ( 3, L" where `Translator`=\'", wcTranslator, L"\'" );
  430. }
  431. if ( bGotElement )
  432. {
  433. if ( bCheck )
  434. {
  435. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  436. }
  437. else
  438. {
  439. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  440. }
  441. }
  442. }
  443. LPWSTR Buffer = NULL;
  444. LPWSTR dynBuffer = NULL;
  445. DWORD dwDynBuffer = 0L;
  446. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  447. {
  448. // safe operation:
  449. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  450. wcscpy(wcProductCode, m_pRequest->Package(i));
  451. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  452. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  453. //Open our database
  454. try
  455. {
  456. if ( GetView ( &hView, wcProductCode, wcQuery, L"ODBCTranslator", TRUE, FALSE ) )
  457. {
  458. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  459. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  460. CheckMSI(uiStatus);
  461. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  462. //----------------------------------------------------
  463. dwBufSize = BUFF_SIZE;
  464. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  465. if ( ValidateComponentName ( msidata.GetDatabase(), wcProductCode, Buffer ) )
  466. {
  467. dwBufSize = BUFF_SIZE;
  468. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  469. wcBuf,
  470. wcProductCode,
  471. wcElement,
  472. &dwBufSize
  473. );
  474. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  475. {
  476. dynBuffer [ 0 ] = 0;
  477. }
  478. if( uiStatus == ERROR_SUCCESS )
  479. {
  480. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  481. dwBufSize = BUFF_SIZE;
  482. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  483. if ( Buffer && Buffer [ 0 ] != 0 )
  484. {
  485. // safe operation
  486. wcProp.Copy(L"Win32_ODBCTranslatorSpecification.CheckID=\"");
  487. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  488. PutKeyProperty(m_pObj, pCheck, wcProp, &bFeature, m_pRequest);
  489. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  490. {
  491. dynBuffer [ 0 ] = 0;
  492. }
  493. if(bFeature && bElement) bMatch = true;
  494. if((atAction != ACTIONTYPE_GET) || bMatch){
  495. hr = pHandler->Indicate(1, &m_pObj);
  496. }
  497. }
  498. }
  499. }
  500. else
  501. {
  502. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  503. {
  504. dynBuffer [ 0 ] = 0;
  505. }
  506. }
  507. m_pObj->Release();
  508. m_pObj = NULL;
  509. g_fpMsiCloseHandle(hRecord);
  510. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  511. }
  512. }
  513. }
  514. catch(...)
  515. {
  516. if ( dynBuffer )
  517. {
  518. delete [] dynBuffer;
  519. dynBuffer = NULL;
  520. }
  521. g_fpMsiCloseHandle(hRecord);
  522. g_fpMsiViewClose(hView);
  523. g_fpMsiCloseHandle(hView);
  524. msidata.CloseDatabase ();
  525. if(m_pObj)
  526. {
  527. m_pObj->Release();
  528. m_pObj = NULL;
  529. }
  530. throw;
  531. }
  532. g_fpMsiCloseHandle(hRecord);
  533. g_fpMsiViewClose(hView);
  534. g_fpMsiCloseHandle(hView);
  535. msidata.CloseDatabase ();
  536. }
  537. }
  538. if ( dynBuffer )
  539. {
  540. delete [] dynBuffer;
  541. dynBuffer = NULL;
  542. }
  543. return hr;
  544. }
  545. HRESULT CSoftwareElementCheck::SoftwareElementEnvironment(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  546. CRequestObject *pCheckData,CRequestObject *pElementData)
  547. {
  548. HRESULT hr = WBEM_S_NO_ERROR;
  549. MSIHANDLE hView = NULL;
  550. MSIHANDLE hRecord = NULL;
  551. int i = -1;
  552. WCHAR wcBuf[BUFF_SIZE];
  553. WCHAR wcProductCode[39];
  554. WCHAR wcTestCode[39];
  555. WCHAR wcEnvironment[BUFF_SIZE];
  556. DWORD dwBufSize;
  557. bool bMatch = false;
  558. bool bTestCode = false;
  559. UINT uiStatus;
  560. WCHAR wcElement[BUFF_SIZE];
  561. bool bCheck = false;
  562. bool bGotElement = false;
  563. CStringExt wcProp;
  564. if(atAction != ACTIONTYPE_ENUM){
  565. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  566. if(pCheckData){
  567. for(int i = 0; i < pCheckData->m_iPropCount; i++){
  568. if(_wcsicmp(pCheckData->m_Property[i], L"CheckID") == 0)
  569. {
  570. if ( ::SysStringLen ( pCheckData->m_Value[i] ) < BUFF_SIZE )
  571. {
  572. //Get the action we're looking for
  573. wcscpy(wcBuf, pCheckData->m_Value[i]);
  574. // safe operation if wcslen ( wcBuf ) > 38
  575. if ( wcslen ( wcBuf ) > 38 )
  576. {
  577. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  578. }
  579. else
  580. {
  581. // we are not good to go, they have sent us longer string
  582. throw hr;
  583. }
  584. // safe because lenght has been tested already in condition
  585. RemoveFinalGUID(pCheckData->m_Value[i], wcEnvironment);
  586. bCheck = true;
  587. bTestCode = true;
  588. break;
  589. }
  590. else
  591. {
  592. // we are not good to go, they have sent us longer string
  593. throw hr;
  594. }
  595. }
  596. }
  597. }
  598. if(pElementData){
  599. for(int j = 0; j < pElementData->m_iPropCount; j++){
  600. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  601. //Get the product code we're looking for
  602. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  603. {
  604. wcscpy(wcElement, pElementData->m_Value[j]);
  605. bGotElement = true;
  606. break;
  607. }
  608. }
  609. }
  610. }
  611. }
  612. //These will change from class to class
  613. bool bEnvironment, bElement;
  614. Query wcQuery;
  615. wcQuery.Append ( 1, L"select distinct `Component_`, `Environment` from Environment" );
  616. //optimize for GetObject
  617. if ( bGotElement || bCheck )
  618. {
  619. if ( bCheck )
  620. {
  621. wcQuery.Append ( 3, L" where `Environment`=\'", wcEnvironment, L"\'" );
  622. }
  623. if ( bGotElement )
  624. {
  625. if ( bCheck )
  626. {
  627. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  628. }
  629. else
  630. {
  631. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  632. }
  633. }
  634. }
  635. LPWSTR Buffer = NULL;
  636. LPWSTR dynBuffer = NULL;
  637. DWORD dwDynBuffer = 0L;
  638. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  639. {
  640. // safe operation:
  641. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  642. wcscpy(wcProductCode, m_pRequest->Package(i));
  643. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  644. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  645. //Open our database
  646. try
  647. {
  648. if ( GetView ( &hView, wcProductCode, wcQuery, L"Environment", TRUE, FALSE ) )
  649. {
  650. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  651. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  652. CheckMSI(uiStatus);
  653. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  654. //----------------------------------------------------
  655. dwBufSize = BUFF_SIZE;
  656. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  657. if ( ValidateComponentName ( msidata.GetDatabase(), wcProductCode, Buffer ) )
  658. {
  659. dwBufSize = BUFF_SIZE;
  660. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  661. wcBuf,
  662. wcProductCode,
  663. wcElement,
  664. &dwBufSize
  665. );
  666. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  667. {
  668. dynBuffer [ 0 ] = 0;
  669. }
  670. if( uiStatus == ERROR_SUCCESS )
  671. {
  672. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  673. dwBufSize = BUFF_SIZE;
  674. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  675. if ( Buffer && Buffer [ 0 ] != 0 )
  676. {
  677. // safe operation
  678. wcProp.Copy(L"Win32_EnvironmentSpecification.CheckID=\"");
  679. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  680. PutKeyProperty(m_pObj, pCheck, wcProp, &bEnvironment, m_pRequest);
  681. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  682. {
  683. dynBuffer [ 0 ] = 0;
  684. }
  685. //====================================================
  686. /*
  687. dwBufSize = BUFF_SIZE;
  688. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  689. PutProperty(m_pObj, pName, wcBuf);
  690. dwBufSize = BUFF_SIZE;
  691. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  692. PutProperty(m_pObj, pValue, wcBuf);
  693. */
  694. //----------------------------------------------------
  695. if(bEnvironment && bElement) bMatch = true;
  696. if((atAction != ACTIONTYPE_GET) || bMatch){
  697. hr = pHandler->Indicate(1, &m_pObj);
  698. }
  699. }
  700. }
  701. }
  702. else
  703. {
  704. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  705. {
  706. dynBuffer [ 0 ] = 0;
  707. }
  708. }
  709. m_pObj->Release();
  710. m_pObj = NULL;
  711. g_fpMsiCloseHandle(hRecord);
  712. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  713. }
  714. }
  715. }
  716. catch(...)
  717. {
  718. if ( dynBuffer )
  719. {
  720. delete [] dynBuffer;
  721. dynBuffer = NULL;
  722. }
  723. g_fpMsiCloseHandle(hRecord);
  724. g_fpMsiViewClose(hView);
  725. g_fpMsiCloseHandle(hView);
  726. msidata.CloseDatabase ();
  727. if(m_pObj)
  728. {
  729. m_pObj->Release();
  730. m_pObj = NULL;
  731. }
  732. throw;
  733. }
  734. g_fpMsiCloseHandle(hRecord);
  735. g_fpMsiViewClose(hView);
  736. g_fpMsiCloseHandle(hView);
  737. msidata.CloseDatabase ();
  738. }
  739. }
  740. if ( dynBuffer )
  741. {
  742. delete [] dynBuffer;
  743. dynBuffer = NULL;
  744. }
  745. return hr;
  746. }
  747. HRESULT CSoftwareElementCheck::SoftwareElementReserveCost(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  748. CRequestObject *pCheckData,CRequestObject *pElementData)
  749. {
  750. HRESULT hr = WBEM_S_NO_ERROR;
  751. MSIHANDLE hView = NULL;
  752. MSIHANDLE hRecord = NULL;
  753. int i = -1;
  754. WCHAR wcBuf[BUFF_SIZE];
  755. WCHAR wcProductCode[39];
  756. WCHAR wcTestCode[39];
  757. WCHAR wcReserve[BUFF_SIZE];
  758. DWORD dwBufSize;
  759. bool bMatch = false;
  760. bool bTestCode = false;
  761. UINT uiStatus;
  762. WCHAR wcElement[BUFF_SIZE];
  763. bool bCheck = false;
  764. bool bGotElement = false;
  765. CStringExt wcProp;
  766. if(atAction != ACTIONTYPE_ENUM){
  767. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  768. if(pCheckData){
  769. for(int i = 0; i < pCheckData->m_iPropCount; i++){
  770. if(_wcsicmp(pCheckData->m_Property[i], L"CheckID") == 0)
  771. {
  772. if ( ::SysStringLen ( pCheckData->m_Value[i] ) < BUFF_SIZE )
  773. {
  774. //Get the action we're looking for
  775. wcscpy(wcBuf, pCheckData->m_Value[i]);
  776. // safe operation if wcslen ( wcBuf ) > 38
  777. if ( wcslen ( wcBuf ) > 38 )
  778. {
  779. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  780. }
  781. else
  782. {
  783. // we are not good to go, they have sent us longer string
  784. throw hr;
  785. }
  786. // safe because lenght has been tested already in condition
  787. RemoveFinalGUID(pCheckData->m_Value[i], wcReserve);
  788. bCheck = true;
  789. bTestCode = true;
  790. break;
  791. }
  792. else
  793. {
  794. // we are not good to go, they have sent us longer string
  795. throw hr;
  796. }
  797. }
  798. }
  799. }
  800. if(pElementData){
  801. for(int j = 0; j < pElementData->m_iPropCount; j++){
  802. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  803. //Get the product code we're looking for
  804. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  805. {
  806. wcscpy(wcElement, pElementData->m_Value[j]);
  807. bGotElement = true;
  808. break;
  809. }
  810. }
  811. }
  812. }
  813. }
  814. //These will change from class to class
  815. bool bEnvironment, bElement;
  816. Query wcQuery;
  817. wcQuery.Append ( 1, L"select distinct `Component_`, `ReserveKey` from ReserveCost" );
  818. //optimize for GetObject
  819. if ( bGotElement || bCheck )
  820. {
  821. if ( bCheck )
  822. {
  823. wcQuery.Append ( 3, L" where `ReserveKey`=\'", wcReserve, L"\'" );
  824. }
  825. if ( bGotElement )
  826. {
  827. if ( bCheck )
  828. {
  829. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  830. }
  831. else
  832. {
  833. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  834. }
  835. }
  836. }
  837. LPWSTR Buffer = NULL;
  838. LPWSTR dynBuffer = NULL;
  839. DWORD dwDynBuffer = 0L;
  840. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  841. {
  842. // safe operation:
  843. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  844. wcscpy(wcProductCode, m_pRequest->Package(i));
  845. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  846. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  847. //Open our database
  848. try
  849. {
  850. if ( GetView ( &hView, wcProductCode, wcQuery, L"ReserveCost", TRUE, FALSE ) )
  851. {
  852. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  853. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  854. CheckMSI(uiStatus);
  855. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  856. //----------------------------------------------------
  857. dwBufSize = BUFF_SIZE;
  858. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  859. if ( ValidateComponentName ( msidata.GetDatabase(), wcProductCode, Buffer ) )
  860. {
  861. dwBufSize = BUFF_SIZE;
  862. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  863. wcBuf,
  864. wcProductCode,
  865. wcElement,
  866. &dwBufSize
  867. );
  868. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  869. {
  870. dynBuffer [ 0 ] = 0;
  871. }
  872. if( uiStatus == ERROR_SUCCESS )
  873. {
  874. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  875. dwBufSize = BUFF_SIZE;
  876. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  877. if ( Buffer && Buffer [ 0 ] != 0 )
  878. {
  879. // safe operation
  880. wcProp.Copy(L"Win32_ReserveCost.CheckID=\"");
  881. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  882. PutKeyProperty(m_pObj, pCheck, wcProp, &bEnvironment, m_pRequest);
  883. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  884. {
  885. dynBuffer [ 0 ] = 0;
  886. }
  887. if(bEnvironment && bElement) bMatch = true;
  888. if((atAction != ACTIONTYPE_GET) || bMatch){
  889. hr = pHandler->Indicate(1, &m_pObj);
  890. }
  891. }
  892. }
  893. }
  894. else
  895. {
  896. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  897. {
  898. dynBuffer [ 0 ] = 0;
  899. }
  900. }
  901. m_pObj->Release();
  902. m_pObj = NULL;
  903. g_fpMsiCloseHandle(hRecord);
  904. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  905. }
  906. }
  907. }
  908. catch(...)
  909. {
  910. if ( dynBuffer )
  911. {
  912. delete [] dynBuffer;
  913. dynBuffer = NULL;
  914. }
  915. g_fpMsiCloseHandle(hRecord);
  916. g_fpMsiViewClose(hView);
  917. g_fpMsiCloseHandle(hView);
  918. msidata.CloseDatabase ();
  919. if(m_pObj)
  920. {
  921. m_pObj->Release();
  922. m_pObj = NULL;
  923. }
  924. throw;
  925. }
  926. g_fpMsiCloseHandle(hRecord);
  927. g_fpMsiViewClose(hView);
  928. g_fpMsiCloseHandle(hView);
  929. msidata.CloseDatabase ();
  930. }
  931. }
  932. if ( dynBuffer )
  933. {
  934. delete [] dynBuffer;
  935. dynBuffer = NULL;
  936. }
  937. return hr;
  938. }
  939. HRESULT CSoftwareElementCheck::SoftwareElementIniFile(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  940. CRequestObject *pCheckData,CRequestObject *pElementData)
  941. {
  942. HRESULT hr = WBEM_S_NO_ERROR;
  943. MSIHANDLE hView = NULL;
  944. MSIHANDLE hRecord = NULL;
  945. int i = -1;
  946. WCHAR wcBuf[BUFF_SIZE];
  947. WCHAR wcProductCode[39];
  948. WCHAR wcTestCode[39];
  949. WCHAR wcIniFile[BUFF_SIZE];
  950. DWORD dwBufSize;
  951. bool bMatch = false;
  952. bool bTestCode = false;
  953. UINT uiStatus;
  954. WCHAR wcElement[BUFF_SIZE];
  955. bool bCheck = false;
  956. bool bGotElement = false;
  957. CStringExt wcProp;
  958. if(atAction != ACTIONTYPE_ENUM){
  959. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  960. if(pCheckData){
  961. for(int i = 0; i < pCheckData->m_iPropCount; i++){
  962. if(_wcsicmp(pCheckData->m_Property[i], L"CheckID") == 0)
  963. {
  964. if ( ::SysStringLen ( pCheckData->m_Value[i] ) < BUFF_SIZE )
  965. {
  966. //Get the action we're looking for
  967. wcscpy(wcBuf, pCheckData->m_Value[i]);
  968. // safe operation if wcslen ( wcBuf ) > 38
  969. if ( wcslen ( wcBuf ) > 38 )
  970. {
  971. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  972. }
  973. else
  974. {
  975. // we are not good to go, they have sent us longer string
  976. throw hr;
  977. }
  978. // safe because lenght has been tested already in condition
  979. RemoveFinalGUID(pCheckData->m_Value[i], wcIniFile);
  980. bCheck = true;
  981. bTestCode = true;
  982. break;
  983. }
  984. else
  985. {
  986. // we are not good to go, they have sent us longer string
  987. throw hr;
  988. }
  989. }
  990. }
  991. }
  992. if(pElementData){
  993. for(int j = 0; j < pElementData->m_iPropCount; j++){
  994. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  995. //Get the product code we're looking for
  996. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  997. {
  998. wcscpy(wcElement, pElementData->m_Value[j]);
  999. bGotElement = true;
  1000. break;
  1001. }
  1002. }
  1003. }
  1004. }
  1005. }
  1006. //These will change from class to class
  1007. bool bEnvironment, bElement;
  1008. Query wcQuery;
  1009. wcQuery.Append ( 1, L"select distinct `Component_`, `IniFile` from IniFile" );
  1010. //optimize for GetObject
  1011. if ( bGotElement || bCheck )
  1012. {
  1013. if ( bCheck )
  1014. {
  1015. wcQuery.Append ( 3, L" where `IniFile`=\'", wcIniFile, L"\'" );
  1016. }
  1017. if ( bGotElement )
  1018. {
  1019. if ( bCheck )
  1020. {
  1021. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1022. }
  1023. else
  1024. {
  1025. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1026. }
  1027. }
  1028. }
  1029. LPWSTR Buffer = NULL;
  1030. LPWSTR dynBuffer = NULL;
  1031. DWORD dwDynBuffer = 0L;
  1032. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1033. {
  1034. // safe operation:
  1035. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1036. wcscpy(wcProductCode, m_pRequest->Package(i));
  1037. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1038. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1039. //Open our database
  1040. try
  1041. {
  1042. if ( GetView ( &hView, wcProductCode, wcQuery, L"IniFile", TRUE, FALSE ) )
  1043. {
  1044. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1045. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1046. CheckMSI(uiStatus);
  1047. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1048. //----------------------------------------------------
  1049. dwBufSize = BUFF_SIZE;
  1050. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1051. if ( ValidateComponentName ( msidata.GetDatabase(), wcProductCode, Buffer ) )
  1052. {
  1053. dwBufSize = BUFF_SIZE;
  1054. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1055. wcBuf,
  1056. wcProductCode,
  1057. wcElement,
  1058. &dwBufSize
  1059. );
  1060. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1061. {
  1062. dynBuffer [ 0 ] = 0;
  1063. }
  1064. if( uiStatus == ERROR_SUCCESS )
  1065. {
  1066. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  1067. dwBufSize = BUFF_SIZE;
  1068. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1069. if ( Buffer && Buffer [ 0 ] != 0 )
  1070. {
  1071. // safe operation
  1072. wcProp.Copy(L"Win32_IniFileSpecification.CheckID=\"");
  1073. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  1074. PutKeyProperty(m_pObj, pCheck, wcProp, &bEnvironment, m_pRequest);
  1075. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1076. {
  1077. dynBuffer [ 0 ] = 0;
  1078. }
  1079. if(bEnvironment && bElement) bMatch = true;
  1080. if((atAction != ACTIONTYPE_GET) || bMatch){
  1081. hr = pHandler->Indicate(1, &m_pObj);
  1082. }
  1083. }
  1084. }
  1085. }
  1086. else
  1087. {
  1088. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1089. {
  1090. dynBuffer [ 0 ] = 0;
  1091. }
  1092. }
  1093. m_pObj->Release();
  1094. m_pObj = NULL;
  1095. g_fpMsiCloseHandle(hRecord);
  1096. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1097. }
  1098. }
  1099. }
  1100. catch(...)
  1101. {
  1102. if ( dynBuffer )
  1103. {
  1104. delete [] dynBuffer;
  1105. dynBuffer = NULL;
  1106. }
  1107. g_fpMsiCloseHandle(hRecord);
  1108. g_fpMsiViewClose(hView);
  1109. g_fpMsiCloseHandle(hView);
  1110. msidata.CloseDatabase ();
  1111. if(m_pObj)
  1112. {
  1113. m_pObj->Release();
  1114. m_pObj = NULL;
  1115. }
  1116. throw;
  1117. }
  1118. g_fpMsiCloseHandle(hRecord);
  1119. g_fpMsiViewClose(hView);
  1120. g_fpMsiCloseHandle(hView);
  1121. msidata.CloseDatabase ();
  1122. }
  1123. }
  1124. if ( dynBuffer )
  1125. {
  1126. delete [] dynBuffer;
  1127. dynBuffer = NULL;
  1128. }
  1129. return hr;
  1130. }
  1131. HRESULT CSoftwareElementCheck::SoftwareElementFile(IWbemObjectSink *pHandler, ACTIONTYPE atAction,
  1132. CRequestObject *pCheckData,CRequestObject *pElementData)
  1133. {
  1134. HRESULT hr = WBEM_S_NO_ERROR;
  1135. MSIHANDLE hView = NULL;
  1136. MSIHANDLE hRecord = NULL;
  1137. int i = -1;
  1138. WCHAR wcBuf[BUFF_SIZE];
  1139. WCHAR wcProductCode[39];
  1140. WCHAR wcTestCode[39];
  1141. WCHAR wcFile[BUFF_SIZE];
  1142. DWORD dwBufSize;
  1143. bool bMatch = false;
  1144. bool bTestCode = false;
  1145. UINT uiStatus;
  1146. WCHAR wcElement[BUFF_SIZE];
  1147. bool bCheck = false;
  1148. bool bGotElement = false;
  1149. CStringExt wcProp;
  1150. if(atAction != ACTIONTYPE_ENUM){
  1151. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  1152. if(pCheckData){
  1153. for(int i = 0; i < pCheckData->m_iPropCount; i++){
  1154. if(_wcsicmp(pCheckData->m_Property[i], L"CheckID") == 0)
  1155. {
  1156. if ( ::SysStringLen ( pCheckData->m_Value[i] ) < BUFF_SIZE )
  1157. {
  1158. //Get the action we're looking for
  1159. wcscpy(wcBuf, pCheckData->m_Value[i]);
  1160. // safe operation if wcslen ( wcBuf ) > 38
  1161. if ( wcslen ( wcBuf ) > 38 )
  1162. {
  1163. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  1164. }
  1165. else
  1166. {
  1167. // we are not good to go, they have sent us longer string
  1168. throw hr;
  1169. }
  1170. // safe because lenght has been tested already in condition
  1171. RemoveFinalGUID(pCheckData->m_Value[i], wcFile);
  1172. bCheck = true;
  1173. bTestCode = true;
  1174. break;
  1175. }
  1176. else
  1177. {
  1178. // we are not good to go, they have sent us longer string
  1179. throw hr;
  1180. }
  1181. }
  1182. }
  1183. }
  1184. if(pElementData){
  1185. for(int j = 0; j < pElementData->m_iPropCount; j++){
  1186. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  1187. //Get the product code we're looking for
  1188. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  1189. {
  1190. wcscpy(wcElement, pElementData->m_Value[j]);
  1191. bGotElement = true;
  1192. break;
  1193. }
  1194. }
  1195. }
  1196. }
  1197. }
  1198. //These will change from class to class
  1199. bool bEnvironment, bElement;
  1200. Query wcQuery;
  1201. wcQuery.Append ( 1, L"select distinct `Component_`, `File` from File" );
  1202. //optimize for GetObject
  1203. if ( bGotElement || bCheck )
  1204. {
  1205. if ( bCheck )
  1206. {
  1207. wcQuery.Append ( 3, L" where `File`=\'", wcFile, L"\'" );
  1208. }
  1209. if ( bGotElement )
  1210. {
  1211. if ( bCheck )
  1212. {
  1213. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1214. }
  1215. else
  1216. {
  1217. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1218. }
  1219. }
  1220. }
  1221. LPWSTR Buffer = NULL;
  1222. LPWSTR dynBuffer = NULL;
  1223. DWORD dwDynBuffer = 0L;
  1224. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1225. {
  1226. // safe operation:
  1227. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1228. wcscpy(wcProductCode, m_pRequest->Package(i));
  1229. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1230. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1231. //Open our database
  1232. try
  1233. {
  1234. if ( GetView ( &hView, wcProductCode, wcQuery, L"File", TRUE, FALSE ) )
  1235. {
  1236. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1237. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1238. CheckMSI(uiStatus);
  1239. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1240. //----------------------------------------------------
  1241. dwBufSize = BUFF_SIZE;
  1242. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1243. if ( ValidateComponentName ( msidata.GetDatabase(), wcProductCode, Buffer ) )
  1244. {
  1245. dwBufSize = BUFF_SIZE;
  1246. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1247. wcBuf,
  1248. wcProductCode,
  1249. wcElement,
  1250. &dwBufSize
  1251. );
  1252. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1253. {
  1254. dynBuffer [ 0 ] = 0;
  1255. }
  1256. if( uiStatus == ERROR_SUCCESS )
  1257. {
  1258. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  1259. dwBufSize = BUFF_SIZE;
  1260. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1261. if ( Buffer && Buffer [ 0 ] != 0 )
  1262. {
  1263. // safe operation
  1264. wcProp.Copy(L"Win32_FileSpecification.CheckID=\"");
  1265. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  1266. PutKeyProperty(m_pObj, pCheck, wcProp, &bEnvironment, m_pRequest);
  1267. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1268. {
  1269. dynBuffer [ 0 ] = 0;
  1270. }
  1271. if(bEnvironment && bElement) bMatch = true;
  1272. if((atAction != ACTIONTYPE_GET) || bMatch){
  1273. hr = pHandler->Indicate(1, &m_pObj);
  1274. }
  1275. }
  1276. }
  1277. }
  1278. else
  1279. {
  1280. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1281. {
  1282. dynBuffer [ 0 ] = 0;
  1283. }
  1284. }
  1285. m_pObj->Release();
  1286. m_pObj = NULL;
  1287. g_fpMsiCloseHandle(hRecord);
  1288. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1289. }
  1290. }
  1291. }
  1292. catch(...)
  1293. {
  1294. if ( dynBuffer )
  1295. {
  1296. delete [] dynBuffer;
  1297. dynBuffer = NULL;
  1298. }
  1299. g_fpMsiCloseHandle(hRecord);
  1300. g_fpMsiViewClose(hView);
  1301. g_fpMsiCloseHandle(hView);
  1302. msidata.CloseDatabase ();
  1303. if(m_pObj)
  1304. {
  1305. m_pObj->Release();
  1306. m_pObj = NULL;
  1307. }
  1308. throw;
  1309. }
  1310. g_fpMsiCloseHandle(hRecord);
  1311. g_fpMsiViewClose(hView);
  1312. g_fpMsiCloseHandle(hView);
  1313. msidata.CloseDatabase ();
  1314. }
  1315. }
  1316. if ( dynBuffer )
  1317. {
  1318. delete [] dynBuffer;
  1319. dynBuffer = NULL;
  1320. }
  1321. return hr;
  1322. }