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.

1528 lines
42 KiB

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