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.

2886 lines
78 KiB

  1. // SoftwareElementAction.cpp: implementation of the CSoftwareElementAction class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "SoftwareElementAction.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CSoftwareElementAction::CSoftwareElementAction(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CSoftwareElementAction::~CSoftwareElementAction()
  18. {
  19. }
  20. HRESULT CSoftwareElementAction::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_E_FAILED;
  23. CRequestObject *pActionRObj = 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"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. 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. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_ClassInfoAction") == 0)))
  49. if(FAILED(hr = SoftwareElementClass(pHandler, atAction, pActionRObj, pElementRObj))){
  50. if(pActionRObj){
  51. pActionRObj->Cleanup();
  52. delete pActionRObj;
  53. pActionRObj = 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. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_CreateFolderAction") == 0)))
  64. if(FAILED(hr = SoftwareElementCreateFolder(pHandler, atAction, pActionRObj, pElementRObj))){
  65. if(pActionRObj){
  66. pActionRObj->Cleanup();
  67. delete pActionRObj;
  68. pActionRObj = 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. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_DuplicateFileAction") == 0)))
  79. if(FAILED(hr = SoftwareElementDuplicateFile(pHandler, atAction, pActionRObj, pElementRObj))){
  80. if(pActionRObj){
  81. pActionRObj->Cleanup();
  82. delete pActionRObj;
  83. pActionRObj = 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. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_ExtensionInfoAction") == 0)))
  94. if(FAILED(hr = SoftwareElementExtension(pHandler, atAction, pActionRObj, pElementRObj))){
  95. if(pActionRObj){
  96. pActionRObj->Cleanup();
  97. delete pActionRObj;
  98. pActionRObj = 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. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_MoveFileAction") == 0)))
  109. if(FAILED(hr = SoftwareElementMoveFile(pHandler, atAction, pActionRObj, pElementRObj))){
  110. if(pActionRObj){
  111. pActionRObj->Cleanup();
  112. delete pActionRObj;
  113. pActionRObj = 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. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_RemoveFileAction") == 0)))
  124. if(FAILED(hr = SoftwareElementRemoveFile(pHandler, atAction, pActionRObj, pElementRObj))){
  125. if(pActionRObj){
  126. pActionRObj->Cleanup();
  127. delete pActionRObj;
  128. pActionRObj = NULL;
  129. }
  130. if(pElementRObj){
  131. pElementRObj->Cleanup();
  132. delete pElementRObj;
  133. pElementRObj = NULL;
  134. }
  135. return hr;
  136. }
  137. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  138. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_RegistryAction") == 0)))
  139. if(FAILED(hr = SoftwareElementRegistry(pHandler, atAction, pActionRObj, pElementRObj))){
  140. if(pActionRObj){
  141. pActionRObj->Cleanup();
  142. delete pActionRObj;
  143. pActionRObj = NULL;
  144. }
  145. if(pElementRObj){
  146. pElementRObj->Cleanup();
  147. delete pElementRObj;
  148. pElementRObj = NULL;
  149. }
  150. return hr;
  151. }
  152. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  153. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_PublishComponentAction") == 0)))
  154. if(FAILED(hr = SoftwareElementPublish(pHandler, atAction, pActionRObj, pElementRObj))){
  155. if(pActionRObj){
  156. pActionRObj->Cleanup();
  157. delete pActionRObj;
  158. pActionRObj = NULL;
  159. }
  160. if(pElementRObj){
  161. pElementRObj->Cleanup();
  162. delete pElementRObj;
  163. pElementRObj = NULL;
  164. }
  165. return hr;
  166. }
  167. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  168. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_RemoveIniAction") == 0)))
  169. if(FAILED(hr = SoftwareElementRemoveIniValue(pHandler, atAction, pActionRObj, pElementRObj))){
  170. if(pActionRObj){
  171. pActionRObj->Cleanup();
  172. delete pActionRObj;
  173. pActionRObj = NULL;
  174. }
  175. if(pElementRObj){
  176. pElementRObj->Cleanup();
  177. delete pElementRObj;
  178. pElementRObj = NULL;
  179. }
  180. return hr;
  181. }
  182. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  183. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_ShortcutAction") == 0)))
  184. if(FAILED(hr = SoftwareElementShortcut(pHandler, atAction, pActionRObj, pElementRObj))){
  185. if(pActionRObj){
  186. pActionRObj->Cleanup();
  187. delete pActionRObj;
  188. pActionRObj = NULL;
  189. }
  190. if(pElementRObj){
  191. pElementRObj->Cleanup();
  192. delete pElementRObj;
  193. pElementRObj = NULL;
  194. }
  195. return hr;
  196. }
  197. if((atAction == ACTIONTYPE_ENUM) || pElementRObj ||
  198. (pActionRObj && pActionRObj->m_bstrClass && (_wcsicmp(pActionRObj->m_bstrClass, L"Win32_TypeLibraryAction") == 0)))
  199. if(FAILED(hr = SoftwareElementTypeLibrary(pHandler, atAction, pActionRObj, pElementRObj))){
  200. if(pActionRObj){
  201. pActionRObj->Cleanup();
  202. delete pActionRObj;
  203. pActionRObj = NULL;
  204. }
  205. if(pElementRObj){
  206. pElementRObj->Cleanup();
  207. delete pElementRObj;
  208. pElementRObj = NULL;
  209. }
  210. return hr;
  211. }
  212. if(pActionRObj){
  213. pActionRObj->Cleanup();
  214. delete pActionRObj;
  215. pActionRObj = NULL;
  216. }
  217. if(pElementRObj){
  218. pElementRObj->Cleanup();
  219. delete pElementRObj;
  220. pElementRObj = NULL;
  221. }
  222. }catch(...){
  223. if(pActionRObj){
  224. pActionRObj->Cleanup();
  225. delete pActionRObj;
  226. pActionRObj = NULL;
  227. }
  228. if(pElementRObj){
  229. pElementRObj->Cleanup();
  230. delete pElementRObj;
  231. pElementRObj = NULL;
  232. }
  233. }
  234. return hr;
  235. }
  236. HRESULT CSoftwareElementAction::SoftwareElementTypeLibrary(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  237. , CRequestObject *pActionData, CRequestObject *pElementData)
  238. {
  239. HRESULT hr = WBEM_S_NO_ERROR;
  240. MSIHANDLE hView = NULL;
  241. MSIHANDLE hRecord = NULL;
  242. int i = -1;
  243. WCHAR wcBuf[BUFF_SIZE];
  244. WCHAR wcProductCode[39];
  245. WCHAR wcTestCode[39];
  246. WCHAR wcLibID[BUFF_SIZE];
  247. DWORD dwBufSize;
  248. bool bMatch = false;
  249. bool bTestCode = false;
  250. UINT uiStatus;
  251. WCHAR wcElement[BUFF_SIZE];
  252. bool bGotAction = false;
  253. bool bGotElement = false;
  254. CStringExt wcProp;
  255. if(atAction != ACTIONTYPE_ENUM){
  256. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  257. if(pActionData){
  258. for(int i = 0; i < pActionData->m_iPropCount; i++){
  259. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  260. {
  261. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  262. {
  263. //Get the action we're looking for
  264. wcscpy(wcBuf, pActionData->m_Value[i]);
  265. // safe operation if wcslen ( wcBuf ) > 38
  266. if ( wcslen ( wcBuf ) > 38 )
  267. {
  268. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  269. }
  270. else
  271. {
  272. // we are not good to go, they have sent us longer string
  273. throw hr;
  274. }
  275. // safe because lenght has been tested already in condition
  276. GetFirstGUID(pActionData->m_Value[i], wcLibID);
  277. bGotAction = true;
  278. bTestCode = true;
  279. break;
  280. }
  281. else
  282. {
  283. // we are not good to go, they have sent us longer string
  284. throw hr;
  285. }
  286. }
  287. }
  288. }
  289. if(pElementData)
  290. {
  291. for(int j = 0; j < pElementData->m_iPropCount; j++){
  292. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  293. //Get the product code we're looking for
  294. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  295. {
  296. wcscpy(wcElement, pElementData->m_Value[j]);
  297. bGotElement = true;
  298. break;
  299. }
  300. }
  301. }
  302. }
  303. }
  304. //These will change from class to class
  305. bool bEnvironment, bElement;
  306. Query wcQuery;
  307. wcQuery.Append ( 1, L"select distinct `Component_`, `LibID`, `Language` from TypeLib" );
  308. //optimize for GetObject
  309. if ( bGotElement || bGotAction )
  310. {
  311. if ( bGotAction )
  312. {
  313. wcQuery.Append ( 3, L" where `LibID`=\'", wcLibID, L"\'" );
  314. }
  315. if ( bGotElement )
  316. {
  317. if ( bGotAction )
  318. {
  319. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  320. }
  321. else
  322. {
  323. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  324. }
  325. }
  326. }
  327. LPWSTR Buffer = NULL;
  328. LPWSTR dynBuffer = NULL;
  329. DWORD dwDynBuffer = 0L;
  330. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  331. {
  332. // safe operation:
  333. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  334. wcscpy(wcProductCode, m_pRequest->Package(i));
  335. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  336. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  337. //Open our database
  338. try
  339. {
  340. if ( GetView ( &hView, wcProductCode, wcQuery, L"TypeLib", TRUE, FALSE ) )
  341. {
  342. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  343. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  344. CheckMSI(uiStatus);
  345. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  346. //----------------------------------------------------
  347. dwBufSize = BUFF_SIZE;
  348. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  349. dwBufSize = BUFF_SIZE;
  350. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  351. Buffer,
  352. wcProductCode,
  353. wcElement,
  354. &dwBufSize
  355. );
  356. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  357. {
  358. dynBuffer [ 0 ] = 0;
  359. }
  360. if( uiStatus == ERROR_SUCCESS )
  361. {
  362. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  363. dwBufSize = 39;
  364. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  365. if(wcscmp(wcBuf, L"") != 0)
  366. {
  367. // safe operation
  368. wcProp.Copy(L"Win32_TypeLibraryAction.ActionID=\"");
  369. wcProp.Append ( 1, wcBuf );
  370. dwBufSize = BUFF_SIZE;
  371. GetBufferToPut ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  372. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  373. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  374. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  375. {
  376. dynBuffer [ 0 ] = 0;
  377. }
  378. if(bEnvironment && bElement) bMatch = true;
  379. if((atAction != ACTIONTYPE_GET) || bMatch){
  380. hr = pHandler->Indicate(1, &m_pObj);
  381. }
  382. }
  383. }
  384. m_pObj->Release();
  385. m_pObj = NULL;
  386. g_fpMsiCloseHandle(hRecord);
  387. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  388. }
  389. }
  390. }
  391. catch(...)
  392. {
  393. if ( dynBuffer )
  394. {
  395. delete [] dynBuffer;
  396. dynBuffer = NULL;
  397. }
  398. g_fpMsiCloseHandle(hRecord);
  399. g_fpMsiViewClose(hView);
  400. g_fpMsiCloseHandle(hView);
  401. msidata.CloseDatabase ();
  402. if(m_pObj)
  403. {
  404. m_pObj->Release();
  405. m_pObj = NULL;
  406. }
  407. throw;
  408. }
  409. g_fpMsiCloseHandle(hRecord);
  410. g_fpMsiViewClose(hView);
  411. g_fpMsiCloseHandle(hView);
  412. msidata.CloseDatabase ();
  413. }
  414. }
  415. if ( dynBuffer )
  416. {
  417. delete [] dynBuffer;
  418. dynBuffer = NULL;
  419. }
  420. return hr;
  421. }
  422. HRESULT CSoftwareElementAction::SoftwareElementShortcut(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  423. , CRequestObject *pActionData, CRequestObject *pElementData)
  424. {
  425. HRESULT hr = WBEM_S_NO_ERROR;
  426. MSIHANDLE hView = NULL;
  427. MSIHANDLE hRecord = NULL;
  428. int i = -1;
  429. WCHAR wcBuf[BUFF_SIZE];
  430. WCHAR wcProductCode[39];
  431. WCHAR wcTestCode[39];
  432. WCHAR wcShortcut[BUFF_SIZE];
  433. DWORD dwBufSize;
  434. bool bMatch = false;
  435. bool bTestCode = false;
  436. UINT uiStatus;
  437. WCHAR wcElement[BUFF_SIZE];
  438. bool bGotAction = false;
  439. bool bGotElement = false;
  440. CStringExt wcProp;
  441. if(atAction != ACTIONTYPE_ENUM){
  442. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  443. if(pActionData){
  444. for(int i = 0; i < pActionData->m_iPropCount; i++){
  445. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  446. {
  447. if ( ::SysStringLen (pActionData->m_Value[i] ) < BUFF_SIZE )
  448. {
  449. //Get the action we're looking for
  450. wcscpy(wcBuf, pActionData->m_Value[i]);
  451. // safe operation if wcslen ( wcBuf ) > 38
  452. if ( wcslen ( wcBuf ) > 38 )
  453. {
  454. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  455. }
  456. else
  457. {
  458. // we are not good to go, they have sent us longer string
  459. throw hr;
  460. }
  461. // safe because lenght has been tested already in condition
  462. RemoveFinalGUID(pActionData->m_Value[i], wcShortcut);
  463. bGotAction = true;
  464. bTestCode = true;
  465. break;
  466. }
  467. else
  468. {
  469. // we are not good to go, they have sent us longer string
  470. throw hr;
  471. }
  472. }
  473. }
  474. }
  475. if(pElementData){
  476. for(int j = 0; j < pElementData->m_iPropCount; j++){
  477. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  478. //Get the product code we're looking for
  479. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  480. {
  481. wcscpy(wcElement, pElementData->m_Value[j]);
  482. bGotElement = true;
  483. break;
  484. }
  485. }
  486. }
  487. }
  488. }
  489. //These will change from class to class
  490. bool bEnvironment, bElement;
  491. Query wcQuery;
  492. wcQuery.Append ( 1, L"select distinct `Component_`, `Shortcut` from Shortcut" );
  493. //optimize for GetObject
  494. if ( bGotElement || bGotAction )
  495. {
  496. if ( bGotAction )
  497. {
  498. wcQuery.Append ( 3, L" where `Shortcut`=\'", wcShortcut, L"\'" );
  499. }
  500. if ( bGotElement )
  501. {
  502. if ( bGotAction )
  503. {
  504. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  505. }
  506. else
  507. {
  508. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  509. }
  510. }
  511. }
  512. LPWSTR Buffer = NULL;
  513. LPWSTR dynBuffer = NULL;
  514. DWORD dwDynBuffer = 0L;
  515. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  516. {
  517. // safe operation:
  518. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  519. wcscpy(wcProductCode, m_pRequest->Package(i));
  520. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  521. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  522. //Open our database
  523. try
  524. {
  525. if ( GetView ( &hView, wcProductCode, wcQuery, L"Shortcut", TRUE, FALSE ) )
  526. {
  527. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  528. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  529. CheckMSI(uiStatus);
  530. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  531. //----------------------------------------------------
  532. dwBufSize = BUFF_SIZE;
  533. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  534. dwBufSize = BUFF_SIZE;
  535. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  536. Buffer,
  537. wcProductCode,
  538. wcElement,
  539. &dwBufSize
  540. );
  541. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  542. {
  543. dynBuffer [ 0 ] = 0;
  544. }
  545. if( uiStatus == ERROR_SUCCESS )
  546. {
  547. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  548. dwBufSize = BUFF_SIZE;
  549. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  550. if ( Buffer && Buffer [ 0 ] != 0 )
  551. {
  552. // safe operation
  553. wcProp.Copy(L"Win32_ShortcutAction.ActionID=\"");
  554. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  555. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  556. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  557. {
  558. dynBuffer [ 0 ] = 0;
  559. }
  560. if(bEnvironment && bElement) bMatch = true;
  561. if((atAction != ACTIONTYPE_GET) || bMatch){
  562. hr = pHandler->Indicate(1, &m_pObj);
  563. }
  564. }
  565. }
  566. m_pObj->Release();
  567. m_pObj = NULL;
  568. g_fpMsiCloseHandle(hRecord);
  569. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  570. }
  571. }
  572. }
  573. catch(...)
  574. {
  575. if ( dynBuffer )
  576. {
  577. delete [] dynBuffer;
  578. dynBuffer = NULL;
  579. }
  580. g_fpMsiCloseHandle(hRecord);
  581. g_fpMsiViewClose(hView);
  582. g_fpMsiCloseHandle(hView);
  583. msidata.CloseDatabase ();
  584. if(m_pObj)
  585. {
  586. m_pObj->Release();
  587. m_pObj = NULL;
  588. }
  589. throw;
  590. }
  591. g_fpMsiCloseHandle(hRecord);
  592. g_fpMsiViewClose(hView);
  593. g_fpMsiCloseHandle(hView);
  594. msidata.CloseDatabase ();
  595. }
  596. }
  597. if ( dynBuffer )
  598. {
  599. delete [] dynBuffer;
  600. dynBuffer = NULL;
  601. }
  602. return hr;
  603. }
  604. HRESULT CSoftwareElementAction::SoftwareElementRemoveIniValue(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  605. , CRequestObject *pActionData, CRequestObject *pElementData)
  606. {
  607. HRESULT hr = WBEM_S_NO_ERROR;
  608. MSIHANDLE hView = NULL;
  609. MSIHANDLE hRecord = NULL;
  610. int i = -1;
  611. WCHAR wcBuf[BUFF_SIZE];
  612. WCHAR wcProductCode[39];
  613. WCHAR wcTestCode[39];
  614. WCHAR wcIniFile[BUFF_SIZE];
  615. DWORD dwBufSize;
  616. bool bMatch = false;
  617. bool bTestCode = false;
  618. UINT uiStatus;
  619. WCHAR wcElement[BUFF_SIZE];
  620. bool bGotAction = false;
  621. bool bGotElement = false;
  622. CStringExt wcProp;
  623. if(atAction != ACTIONTYPE_ENUM){
  624. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  625. if(pActionData){
  626. for(int i = 0; i < pActionData->m_iPropCount; i++){
  627. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  628. {
  629. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  630. {
  631. //Get the action we're looking for
  632. wcscpy(wcBuf, pActionData->m_Value[i]);
  633. // safe operation if wcslen ( wcBuf ) > 38
  634. if ( wcslen ( wcBuf ) > 38 )
  635. {
  636. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  637. }
  638. else
  639. {
  640. // we are not good to go, they have sent us longer string
  641. throw hr;
  642. }
  643. // safe because lenght has been tested already in condition
  644. RemoveFinalGUID(pActionData->m_Value[i], wcIniFile);
  645. bGotAction = true;
  646. bTestCode = true;
  647. break;
  648. }
  649. else
  650. {
  651. // we are not good to go, they have sent us longer string
  652. throw hr;
  653. }
  654. }
  655. }
  656. }
  657. if(pElementData){
  658. for(int j = 0; j < pElementData->m_iPropCount; j++){
  659. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  660. //Get the product code we're looking for
  661. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  662. {
  663. wcscpy(wcElement, pElementData->m_Value[j]);
  664. bGotElement = true;
  665. break;
  666. }
  667. }
  668. }
  669. }
  670. }
  671. //These will change from class to class
  672. bool bEnvironment, bElement;
  673. Query wcQuery;
  674. wcQuery.Append ( 1, L"select distinct `Component_`, `RemoveIniFile` from RemoveIniFile" );
  675. //optimize for GetObject
  676. if ( bGotElement || bGotAction )
  677. {
  678. if ( bGotAction )
  679. {
  680. wcQuery.Append ( 3, L" where `RemoveIniFile`=\'", wcIniFile, L"\'" );
  681. }
  682. if ( bGotElement )
  683. {
  684. if ( bGotAction )
  685. {
  686. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  687. }
  688. else
  689. {
  690. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  691. }
  692. }
  693. }
  694. LPWSTR Buffer = NULL;
  695. LPWSTR dynBuffer = NULL;
  696. DWORD dwDynBuffer = 0L;
  697. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  698. {
  699. // safe operation:
  700. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  701. wcscpy(wcProductCode, m_pRequest->Package(i));
  702. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  703. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  704. //Open our database
  705. try
  706. {
  707. if ( GetView ( &hView, wcProductCode, wcQuery, L"RemoveIniFile", TRUE, FALSE ) )
  708. {
  709. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  710. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  711. CheckMSI(uiStatus);
  712. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  713. //----------------------------------------------------
  714. dwBufSize = BUFF_SIZE;
  715. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  716. dwBufSize = BUFF_SIZE;
  717. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  718. Buffer,
  719. wcProductCode,
  720. wcElement,
  721. &dwBufSize
  722. );
  723. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  724. {
  725. dynBuffer [ 0 ] = 0;
  726. }
  727. if( uiStatus == ERROR_SUCCESS )
  728. {
  729. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  730. dwBufSize = BUFF_SIZE;
  731. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  732. if ( Buffer && Buffer [ 0 ] != 0 )
  733. {
  734. // safe operation
  735. wcProp.Copy(L"Win32_RemoveIniAction.ActionID=\"");
  736. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  737. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  738. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  739. {
  740. dynBuffer [ 0 ] = 0;
  741. }
  742. if(bEnvironment && bElement) bMatch = true;
  743. if((atAction != ACTIONTYPE_GET) || bMatch){
  744. hr = pHandler->Indicate(1, &m_pObj);
  745. }
  746. }
  747. }
  748. m_pObj->Release();
  749. m_pObj = NULL;
  750. g_fpMsiCloseHandle(hRecord);
  751. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  752. }
  753. }
  754. }
  755. catch(...)
  756. {
  757. if ( dynBuffer )
  758. {
  759. delete [] dynBuffer;
  760. dynBuffer = NULL;
  761. }
  762. g_fpMsiCloseHandle(hRecord);
  763. g_fpMsiViewClose(hView);
  764. g_fpMsiCloseHandle(hView);
  765. msidata.CloseDatabase ();
  766. if(m_pObj)
  767. {
  768. m_pObj->Release();
  769. m_pObj = NULL;
  770. }
  771. throw;
  772. }
  773. g_fpMsiCloseHandle(hRecord);
  774. g_fpMsiViewClose(hView);
  775. g_fpMsiCloseHandle(hView);
  776. msidata.CloseDatabase ();
  777. }
  778. }
  779. if ( dynBuffer )
  780. {
  781. delete [] dynBuffer;
  782. dynBuffer = NULL;
  783. }
  784. return hr;
  785. }
  786. HRESULT CSoftwareElementAction::SoftwareElementPublish(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  787. , CRequestObject *pActionData, CRequestObject *pElementData)
  788. {
  789. HRESULT hr = WBEM_S_NO_ERROR;
  790. MSIHANDLE hView = NULL;
  791. MSIHANDLE hRecord = NULL;
  792. int i = -1;
  793. WCHAR wcBuf[BUFF_SIZE];
  794. WCHAR wcProductCode[39];
  795. WCHAR wcTestCode[39];
  796. WCHAR wcCompID[BUFF_SIZE];
  797. DWORD dwBufSize;
  798. bool bMatch = false;
  799. bool bTestCode = false;
  800. UINT uiStatus;
  801. WCHAR wcElement[BUFF_SIZE];
  802. bool bGotAction = false;
  803. bool bGotElement = false;
  804. CStringExt wcProp;
  805. if(atAction != ACTIONTYPE_ENUM){
  806. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  807. if(pActionData){
  808. for(int i = 0; i < pActionData->m_iPropCount; i++){
  809. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  810. {
  811. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  812. {
  813. //Get the action we're looking for
  814. wcscpy(wcBuf, pActionData->m_Value[i]);
  815. // safe operation if wcslen ( wcBuf ) > 38
  816. if ( wcslen ( wcBuf ) > 38 )
  817. {
  818. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  819. }
  820. else
  821. {
  822. // we are not good to go, they have sent us longer string
  823. throw hr;
  824. }
  825. // safe because lenght has been tested already in condition
  826. GetFirstGUID(pActionData->m_Value[i], wcCompID);
  827. bGotAction = true;
  828. bTestCode = true;
  829. break;
  830. }
  831. else
  832. {
  833. // we are not good to go, they have sent us longer string
  834. throw hr;
  835. }
  836. }
  837. }
  838. }
  839. if(pElementData){
  840. for(int j = 0; j < pElementData->m_iPropCount; j++){
  841. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  842. //Get the product code we're looking for
  843. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  844. {
  845. wcscpy(wcElement, pElementData->m_Value[j]);
  846. bGotElement = true;
  847. break;
  848. }
  849. }
  850. }
  851. }
  852. }
  853. //These will change from class to class
  854. bool bEnvironment, bElement;
  855. Query wcQuery;
  856. wcQuery.Append ( 1, L"select distinct `Component_`, `ComponentId`, `Qualifier` from PublishComponent" );
  857. //optimize for GetObject
  858. if ( bGotElement || bGotAction )
  859. {
  860. if ( bGotAction )
  861. {
  862. wcQuery.Append ( 3, L" where `ComponentId`=\'", wcCompID, L"\'" );
  863. }
  864. if ( bGotElement )
  865. {
  866. if ( bGotAction )
  867. {
  868. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  869. }
  870. else
  871. {
  872. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  873. }
  874. }
  875. }
  876. LPWSTR Buffer = NULL;
  877. LPWSTR dynBuffer = NULL;
  878. DWORD dwDynBuffer = 0L;
  879. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  880. {
  881. // safe operation:
  882. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  883. wcscpy(wcProductCode, m_pRequest->Package(i));
  884. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  885. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  886. //Open our database
  887. try
  888. {
  889. if ( GetView ( &hView, wcProductCode, wcQuery, L"PublishComponent", TRUE, FALSE ) )
  890. {
  891. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  892. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  893. CheckMSI(uiStatus);
  894. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  895. //----------------------------------------------------
  896. dwBufSize = BUFF_SIZE;
  897. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  898. dwBufSize = BUFF_SIZE;
  899. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  900. Buffer,
  901. wcProductCode,
  902. wcElement,
  903. &dwBufSize
  904. );
  905. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  906. {
  907. dynBuffer [ 0 ] = 0;
  908. }
  909. if( uiStatus == ERROR_SUCCESS )
  910. {
  911. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  912. dwBufSize = BUFF_SIZE;
  913. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  914. if(wcscmp(wcBuf, L"") != 0)
  915. {
  916. // safe operation
  917. wcProp.Copy(L"Win32_PublishComponentAction.ActionID=\"");
  918. wcProp.Append ( 1, wcBuf );
  919. dwBufSize = BUFF_SIZE;
  920. GetBufferToPut ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  921. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  922. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  923. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  924. {
  925. dynBuffer [ 0 ] = 0;
  926. }
  927. if(bEnvironment && bElement) bMatch = true;
  928. if((atAction != ACTIONTYPE_GET) || bMatch){
  929. hr = pHandler->Indicate(1, &m_pObj);
  930. }
  931. }
  932. }
  933. m_pObj->Release();
  934. m_pObj = NULL;
  935. g_fpMsiCloseHandle(hRecord);
  936. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  937. }
  938. }
  939. }
  940. catch(...)
  941. {
  942. if ( dynBuffer )
  943. {
  944. delete [] dynBuffer;
  945. dynBuffer = NULL;
  946. }
  947. g_fpMsiCloseHandle(hRecord);
  948. g_fpMsiViewClose(hView);
  949. g_fpMsiCloseHandle(hView);
  950. msidata.CloseDatabase ();
  951. if(m_pObj)
  952. {
  953. m_pObj->Release();
  954. m_pObj = NULL;
  955. }
  956. throw;
  957. }
  958. g_fpMsiCloseHandle(hRecord);
  959. g_fpMsiViewClose(hView);
  960. g_fpMsiCloseHandle(hView);
  961. msidata.CloseDatabase ();
  962. }
  963. }
  964. if ( dynBuffer )
  965. {
  966. delete [] dynBuffer;
  967. dynBuffer = NULL;
  968. }
  969. return hr;
  970. }
  971. HRESULT CSoftwareElementAction::SoftwareElementRegistry(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  972. , CRequestObject *pActionData, CRequestObject *pElementData)
  973. {
  974. HRESULT hr = WBEM_S_NO_ERROR;
  975. MSIHANDLE hView = NULL;
  976. MSIHANDLE hRecord = NULL;
  977. int i = -1;
  978. WCHAR wcBuf[BUFF_SIZE];
  979. WCHAR wcProductCode[39];
  980. WCHAR wcTestCode[39];
  981. WCHAR wcRegistry[BUFF_SIZE];
  982. DWORD dwBufSize;
  983. bool bMatch = false;
  984. bool bTestCode = false;
  985. UINT uiStatus;
  986. WCHAR wcElement[BUFF_SIZE];
  987. bool bGotAction = false;
  988. bool bGotElement = false;
  989. CStringExt wcProp;
  990. if(atAction != ACTIONTYPE_ENUM){
  991. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  992. if(pActionData){
  993. for(int i = 0; i < pActionData->m_iPropCount; i++){
  994. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  995. {
  996. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  997. {
  998. //Get the action we're looking for
  999. wcscpy(wcBuf, pActionData->m_Value[i]);
  1000. // safe operation if wcslen ( wcBuf ) > 38
  1001. if ( wcslen ( wcBuf ) > 38 )
  1002. {
  1003. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  1004. }
  1005. else
  1006. {
  1007. // we are not good to go, they have sent us longer string
  1008. throw hr;
  1009. }
  1010. // safe because lenght has been tested already in condition
  1011. RemoveFinalGUID(pActionData->m_Value[i], wcRegistry);
  1012. bGotAction = true;
  1013. bTestCode = true;
  1014. break;
  1015. }
  1016. else
  1017. {
  1018. // we are not good to go, they have sent us longer string
  1019. throw hr;
  1020. }
  1021. }
  1022. }
  1023. }
  1024. if(pElementData){
  1025. for(int j = 0; j < pElementData->m_iPropCount; j++){
  1026. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  1027. //Get the product code we're looking for
  1028. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  1029. {
  1030. wcscpy(wcElement, pElementData->m_Value[j]);
  1031. bGotElement = true;
  1032. break;
  1033. }
  1034. }
  1035. }
  1036. }
  1037. }
  1038. //These will change from class to class
  1039. bool bEnvironment, bElement;
  1040. Query wcQuery;
  1041. wcQuery.Append ( 1, L"select distinct `Component_`, `Registry` from Registry" );
  1042. //optimize for GetObject
  1043. if ( bGotElement || bGotAction )
  1044. {
  1045. if ( bGotAction )
  1046. {
  1047. wcQuery.Append ( 3, L" where `Registry`=\'", wcRegistry, L"\'" );
  1048. }
  1049. if ( bGotElement )
  1050. {
  1051. if ( bGotAction )
  1052. {
  1053. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1054. }
  1055. else
  1056. {
  1057. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1058. }
  1059. }
  1060. }
  1061. LPWSTR Buffer = NULL;
  1062. LPWSTR dynBuffer = NULL;
  1063. DWORD dwDynBuffer = 0L;
  1064. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1065. {
  1066. // safe operation:
  1067. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1068. wcscpy(wcProductCode, m_pRequest->Package(i));
  1069. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1070. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1071. //Open our database
  1072. try
  1073. {
  1074. if ( GetView ( &hView, wcProductCode, wcQuery, L"Registry", TRUE, FALSE ) )
  1075. {
  1076. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1077. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1078. CheckMSI(uiStatus);
  1079. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1080. //----------------------------------------------------
  1081. dwBufSize = BUFF_SIZE;
  1082. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1083. dwBufSize = BUFF_SIZE;
  1084. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1085. Buffer,
  1086. wcProductCode,
  1087. wcElement,
  1088. &dwBufSize
  1089. );
  1090. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1091. {
  1092. dynBuffer [ 0 ] = 0;
  1093. }
  1094. if( uiStatus == ERROR_SUCCESS )
  1095. {
  1096. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  1097. dwBufSize = BUFF_SIZE;
  1098. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1099. if ( Buffer && Buffer [ 0 ] != 0 )
  1100. {
  1101. // safe operation
  1102. wcProp.Copy(L"Win32_RegistryAction.ActionID=\"");
  1103. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  1104. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  1105. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1106. {
  1107. dynBuffer [ 0 ] = 0;
  1108. }
  1109. if(bEnvironment && bElement) bMatch = true;
  1110. if((atAction != ACTIONTYPE_GET) || bMatch){
  1111. hr = pHandler->Indicate(1, &m_pObj);
  1112. }
  1113. }
  1114. }
  1115. m_pObj->Release();
  1116. m_pObj = NULL;
  1117. g_fpMsiCloseHandle(hRecord);
  1118. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1119. }
  1120. }
  1121. }
  1122. catch(...)
  1123. {
  1124. if ( dynBuffer )
  1125. {
  1126. delete [] dynBuffer;
  1127. dynBuffer = NULL;
  1128. }
  1129. g_fpMsiCloseHandle(hRecord);
  1130. g_fpMsiViewClose(hView);
  1131. g_fpMsiCloseHandle(hView);
  1132. msidata.CloseDatabase ();
  1133. if(m_pObj)
  1134. {
  1135. m_pObj->Release();
  1136. m_pObj = NULL;
  1137. }
  1138. throw;
  1139. }
  1140. g_fpMsiCloseHandle(hRecord);
  1141. g_fpMsiViewClose(hView);
  1142. g_fpMsiCloseHandle(hView);
  1143. msidata.CloseDatabase ();
  1144. }
  1145. }
  1146. if ( dynBuffer )
  1147. {
  1148. delete [] dynBuffer;
  1149. dynBuffer = NULL;
  1150. }
  1151. return hr;
  1152. }
  1153. HRESULT CSoftwareElementAction::SoftwareElementRemoveFile(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  1154. , CRequestObject *pActionData, CRequestObject *pElementData)
  1155. {
  1156. HRESULT hr = WBEM_S_NO_ERROR;
  1157. MSIHANDLE hView = NULL;
  1158. MSIHANDLE hRecord = NULL;
  1159. int i = -1;
  1160. WCHAR wcBuf[BUFF_SIZE];
  1161. WCHAR wcProductCode[39];
  1162. WCHAR wcTestCode[39];
  1163. WCHAR wcFile[BUFF_SIZE];
  1164. DWORD dwBufSize;
  1165. bool bMatch = false;
  1166. bool bTestCode = false;
  1167. UINT uiStatus;
  1168. WCHAR wcElement[BUFF_SIZE];
  1169. bool bGotAction = false;
  1170. bool bGotElement = false;
  1171. CStringExt wcProp;
  1172. if(atAction != ACTIONTYPE_ENUM){
  1173. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  1174. if(pActionData){
  1175. for(int i = 0; i < pActionData->m_iPropCount; i++){
  1176. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  1177. {
  1178. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  1179. {
  1180. //Get the action we're looking for
  1181. wcscpy(wcBuf, pActionData->m_Value[i]);
  1182. // safe operation if wcslen ( wcBuf ) > 38
  1183. if ( wcslen ( wcBuf ) > 38 )
  1184. {
  1185. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  1186. }
  1187. else
  1188. {
  1189. // we are not good to go, they have sent us longer string
  1190. throw hr;
  1191. }
  1192. // safe because lenght has been tested already in condition
  1193. RemoveFinalGUID(pActionData->m_Value[i], wcFile);
  1194. bGotAction = true;
  1195. bTestCode = true;
  1196. break;
  1197. }
  1198. else
  1199. {
  1200. // we are not good to go, they have sent us longer string
  1201. throw hr;
  1202. }
  1203. }
  1204. }
  1205. }
  1206. if(pElementData){
  1207. for(int j = 0; j < pElementData->m_iPropCount; j++){
  1208. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  1209. //Get the product code we're looking for
  1210. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  1211. {
  1212. wcscpy(wcElement, pElementData->m_Value[j]);
  1213. bGotElement = true;
  1214. break;
  1215. }
  1216. }
  1217. }
  1218. }
  1219. }
  1220. //These will change from class to class
  1221. bool bEnvironment, bElement;
  1222. Query wcQuery;
  1223. wcQuery.Append ( 1, L"select distinct `Component_`, `FileKey` from RemoveFile" );
  1224. //optimize for GetObject
  1225. if ( bGotElement || bGotAction )
  1226. {
  1227. if ( bGotAction )
  1228. {
  1229. wcQuery.Append ( 3, L" where `FileKey`=\'", wcFile, L"\'" );
  1230. }
  1231. if ( bGotElement )
  1232. {
  1233. if ( bGotAction )
  1234. {
  1235. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1236. }
  1237. else
  1238. {
  1239. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1240. }
  1241. }
  1242. }
  1243. LPWSTR Buffer = NULL;
  1244. LPWSTR dynBuffer = NULL;
  1245. DWORD dwDynBuffer = 0L;
  1246. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1247. {
  1248. // safe operation:
  1249. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1250. wcscpy(wcProductCode, m_pRequest->Package(i));
  1251. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1252. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1253. //Open our database
  1254. try
  1255. {
  1256. if ( GetView ( &hView, wcProductCode, wcQuery, L"RemoveFile", TRUE, FALSE ) )
  1257. {
  1258. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1259. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1260. CheckMSI(uiStatus);
  1261. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1262. //----------------------------------------------------
  1263. dwBufSize = BUFF_SIZE;
  1264. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1265. dwBufSize = BUFF_SIZE;
  1266. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1267. Buffer,
  1268. wcProductCode,
  1269. wcElement,
  1270. &dwBufSize
  1271. );
  1272. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1273. {
  1274. dynBuffer [ 0 ] = 0;
  1275. }
  1276. if( uiStatus == ERROR_SUCCESS )
  1277. {
  1278. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  1279. dwBufSize = BUFF_SIZE;
  1280. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1281. if ( Buffer && Buffer [ 0 ] != 0 )
  1282. {
  1283. // safe operation
  1284. wcProp.Copy(L"Win32_RemoveFileAction.ActionID=\"");
  1285. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  1286. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  1287. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1288. {
  1289. dynBuffer [ 0 ] = 0;
  1290. }
  1291. if(bEnvironment && bElement) bMatch = true;
  1292. if((atAction != ACTIONTYPE_GET) || bMatch){
  1293. hr = pHandler->Indicate(1, &m_pObj);
  1294. }
  1295. }
  1296. }
  1297. m_pObj->Release();
  1298. m_pObj = NULL;
  1299. g_fpMsiCloseHandle(hRecord);
  1300. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1301. }
  1302. }
  1303. }
  1304. catch(...)
  1305. {
  1306. if ( dynBuffer )
  1307. {
  1308. delete [] dynBuffer;
  1309. dynBuffer = NULL;
  1310. }
  1311. g_fpMsiCloseHandle(hRecord);
  1312. g_fpMsiViewClose(hView);
  1313. g_fpMsiCloseHandle(hView);
  1314. msidata.CloseDatabase ();
  1315. if(m_pObj)
  1316. {
  1317. m_pObj->Release();
  1318. m_pObj = NULL;
  1319. }
  1320. throw;
  1321. }
  1322. g_fpMsiCloseHandle(hRecord);
  1323. g_fpMsiViewClose(hView);
  1324. g_fpMsiCloseHandle(hView);
  1325. msidata.CloseDatabase ();
  1326. }
  1327. }
  1328. if ( dynBuffer )
  1329. {
  1330. delete [] dynBuffer;
  1331. dynBuffer = NULL;
  1332. }
  1333. return hr;
  1334. }
  1335. HRESULT CSoftwareElementAction::SoftwareElementMoveFile(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  1336. , CRequestObject *pActionData, CRequestObject *pElementData)
  1337. {
  1338. HRESULT hr = WBEM_S_NO_ERROR;
  1339. MSIHANDLE hView = NULL;
  1340. MSIHANDLE hRecord = NULL;
  1341. int i = -1;
  1342. WCHAR wcBuf[BUFF_SIZE];
  1343. WCHAR wcProductCode[39];
  1344. WCHAR wcTestCode[39];
  1345. WCHAR wcFile[BUFF_SIZE];
  1346. DWORD dwBufSize;
  1347. bool bMatch = false;
  1348. bool bTestCode = false;
  1349. UINT uiStatus;
  1350. WCHAR wcElement[BUFF_SIZE];
  1351. bool bGotAction = false;
  1352. bool bGotElement = false;
  1353. CStringExt wcProp;
  1354. if(atAction != ACTIONTYPE_ENUM){
  1355. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  1356. if(pActionData){
  1357. for(int i = 0; i < pActionData->m_iPropCount; i++){
  1358. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  1359. {
  1360. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  1361. {
  1362. //Get the action we're looking for
  1363. wcscpy(wcBuf, pActionData->m_Value[i]);
  1364. // safe operation if wcslen ( wcBuf ) > 38
  1365. if ( wcslen ( wcBuf ) > 38 )
  1366. {
  1367. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  1368. }
  1369. else
  1370. {
  1371. // we are not good to go, they have sent us longer string
  1372. throw hr;
  1373. }
  1374. // safe because lenght has been tested already in condition
  1375. RemoveFinalGUID(pActionData->m_Value[i], wcFile);
  1376. bGotAction = true;
  1377. bTestCode = true;
  1378. break;
  1379. }
  1380. else
  1381. {
  1382. // we are not good to go, they have sent us longer string
  1383. throw hr;
  1384. }
  1385. }
  1386. }
  1387. }
  1388. if(pElementData){
  1389. for(int j = 0; j < pElementData->m_iPropCount; j++){
  1390. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  1391. //Get the product code we're looking for
  1392. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  1393. {
  1394. wcscpy(wcElement, pElementData->m_Value[j]);
  1395. bGotElement = true;
  1396. break;
  1397. }
  1398. }
  1399. }
  1400. }
  1401. }
  1402. //These will change from class to class
  1403. bool bEnvironment, bElement;
  1404. Query wcQuery;
  1405. wcQuery.Append ( 1, L"select distinct `Component_`, `FileKey` from MoveFile" );
  1406. //optimize for GetObject
  1407. if ( bGotElement || bGotAction )
  1408. {
  1409. if ( bGotAction )
  1410. {
  1411. wcQuery.Append ( 3, L" where `FileKey`=\'", wcFile, L"\'" );
  1412. }
  1413. if ( bGotElement )
  1414. {
  1415. if ( bGotAction )
  1416. {
  1417. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1418. }
  1419. else
  1420. {
  1421. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1422. }
  1423. }
  1424. }
  1425. LPWSTR Buffer = NULL;
  1426. LPWSTR dynBuffer = NULL;
  1427. DWORD dwDynBuffer = 0L;
  1428. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1429. {
  1430. // safe operation:
  1431. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1432. wcscpy(wcProductCode, m_pRequest->Package(i));
  1433. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1434. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1435. //Open our database
  1436. try
  1437. {
  1438. if ( GetView ( &hView, wcProductCode, wcQuery, L"MoveFile", TRUE, FALSE ) )
  1439. {
  1440. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1441. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1442. CheckMSI(uiStatus);
  1443. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1444. //----------------------------------------------------
  1445. dwBufSize = BUFF_SIZE;
  1446. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1447. dwBufSize = BUFF_SIZE;
  1448. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1449. Buffer,
  1450. wcProductCode,
  1451. wcElement,
  1452. &dwBufSize
  1453. );
  1454. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1455. {
  1456. dynBuffer [ 0 ] = 0;
  1457. }
  1458. if( uiStatus == ERROR_SUCCESS )
  1459. {
  1460. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  1461. dwBufSize = BUFF_SIZE;
  1462. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1463. if ( Buffer && Buffer [ 0 ] != 0 )
  1464. {
  1465. // safe operation
  1466. wcProp.Copy(L"Win32_MoveFileAction.ActionID=\"");
  1467. wcProp.Append ( 1, Buffer );
  1468. dwBufSize = BUFF_SIZE;
  1469. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  1470. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1471. {
  1472. dynBuffer [ 0 ] = 0;
  1473. }
  1474. if(bEnvironment && bElement) bMatch = true;
  1475. if((atAction != ACTIONTYPE_GET) || bMatch){
  1476. hr = pHandler->Indicate(1, &m_pObj);
  1477. }
  1478. }
  1479. }
  1480. m_pObj->Release();
  1481. m_pObj = NULL;
  1482. g_fpMsiCloseHandle(hRecord);
  1483. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1484. }
  1485. }
  1486. }
  1487. catch(...)
  1488. {
  1489. if ( dynBuffer )
  1490. {
  1491. delete [] dynBuffer;
  1492. dynBuffer = NULL;
  1493. }
  1494. g_fpMsiCloseHandle(hRecord);
  1495. g_fpMsiViewClose(hView);
  1496. g_fpMsiCloseHandle(hView);
  1497. msidata.CloseDatabase ();
  1498. if(m_pObj)
  1499. {
  1500. m_pObj->Release();
  1501. m_pObj = NULL;
  1502. }
  1503. throw;
  1504. }
  1505. g_fpMsiCloseHandle(hRecord);
  1506. g_fpMsiViewClose(hView);
  1507. g_fpMsiCloseHandle(hView);
  1508. msidata.CloseDatabase ();
  1509. }
  1510. }
  1511. if ( dynBuffer )
  1512. {
  1513. delete [] dynBuffer;
  1514. dynBuffer = NULL;
  1515. }
  1516. return hr;
  1517. }
  1518. HRESULT CSoftwareElementAction::SoftwareElementExtension(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  1519. , CRequestObject *pActionData, CRequestObject *pElementData)
  1520. {
  1521. HRESULT hr = WBEM_S_NO_ERROR;
  1522. MSIHANDLE hView = NULL;
  1523. MSIHANDLE hRecord = NULL;
  1524. int i = -1;
  1525. WCHAR wcBuf[BUFF_SIZE];
  1526. WCHAR wcProductCode[39];
  1527. WCHAR wcTestCode[39];
  1528. WCHAR wcExtension[BUFF_SIZE];
  1529. DWORD dwBufSize;
  1530. bool bMatch = false;
  1531. bool bTestCode = false;
  1532. UINT uiStatus;
  1533. WCHAR wcElement[BUFF_SIZE];
  1534. bool bGotAction = false;
  1535. bool bGotElement = false;
  1536. CStringExt wcProp;
  1537. if(atAction != ACTIONTYPE_ENUM){
  1538. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  1539. if(pActionData){
  1540. for(int i = 0; i < pActionData->m_iPropCount; i++){
  1541. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  1542. {
  1543. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  1544. {
  1545. //Get the action we're looking for
  1546. wcscpy(wcBuf, pActionData->m_Value[i]);
  1547. // safe operation if wcslen ( wcBuf ) > 38
  1548. if ( wcslen ( wcBuf ) > 38 )
  1549. {
  1550. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  1551. }
  1552. else
  1553. {
  1554. // we are not good to go, they have sent us longer string
  1555. throw hr;
  1556. }
  1557. // safe because lenght has been tested already in condition
  1558. RemoveFinalGUID(pActionData->m_Value[i], wcExtension);
  1559. bGotAction = true;
  1560. bTestCode = true;
  1561. break;
  1562. }
  1563. else
  1564. {
  1565. // we are not good to go, they have sent us longer string
  1566. throw hr;
  1567. }
  1568. }
  1569. }
  1570. }
  1571. if(pElementData){
  1572. for(int j = 0; j < pElementData->m_iPropCount; j++){
  1573. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  1574. //Get the product code we're looking for
  1575. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  1576. {
  1577. wcscpy(wcElement, pElementData->m_Value[j]);
  1578. bGotElement = true;
  1579. break;
  1580. }
  1581. }
  1582. }
  1583. }
  1584. }
  1585. //These will change from class to class
  1586. bool bEnvironment, bElement;
  1587. Query wcQuery;
  1588. wcQuery.Append ( 1, L"select distinct `Component_`, `Extension` from Extension" );
  1589. //optimize for GetObject
  1590. if ( bGotElement || bGotAction )
  1591. {
  1592. if ( bGotAction )
  1593. {
  1594. wcQuery.Append ( 3, L" where `Extension`=\'", wcExtension, L"\'" );
  1595. }
  1596. if ( bGotElement )
  1597. {
  1598. if ( bGotAction )
  1599. {
  1600. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1601. }
  1602. else
  1603. {
  1604. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1605. }
  1606. }
  1607. }
  1608. LPWSTR Buffer = NULL;
  1609. LPWSTR dynBuffer = NULL;
  1610. DWORD dwDynBuffer = 0L;
  1611. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1612. {
  1613. // safe operation:
  1614. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1615. wcscpy(wcProductCode, m_pRequest->Package(i));
  1616. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1617. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1618. //Open our database
  1619. try
  1620. {
  1621. if ( GetView ( &hView, wcProductCode, wcQuery, L"Extension", TRUE, FALSE ) )
  1622. {
  1623. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1624. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1625. CheckMSI(uiStatus);
  1626. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1627. //----------------------------------------------------
  1628. dwBufSize = BUFF_SIZE;
  1629. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1630. dwBufSize = BUFF_SIZE;
  1631. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1632. wcBuf,
  1633. wcProductCode,
  1634. wcElement,
  1635. &dwBufSize
  1636. );
  1637. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1638. {
  1639. dynBuffer [ 0 ] = 0;
  1640. }
  1641. if( uiStatus == ERROR_SUCCESS )
  1642. {
  1643. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  1644. dwBufSize = BUFF_SIZE;
  1645. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1646. if ( Buffer && Buffer [ 0 ] != 0 )
  1647. {
  1648. // safe operation
  1649. wcProp.Copy(L"Win32_ExtensionInfoAction.ActionID=\"");
  1650. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  1651. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  1652. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1653. {
  1654. dynBuffer [ 0 ] = 0;
  1655. }
  1656. if(bEnvironment && bElement) bMatch = true;
  1657. if((atAction != ACTIONTYPE_GET) || bMatch){
  1658. hr = pHandler->Indicate(1, &m_pObj);
  1659. }
  1660. }
  1661. }
  1662. m_pObj->Release();
  1663. m_pObj = NULL;
  1664. g_fpMsiCloseHandle(hRecord);
  1665. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1666. }
  1667. }
  1668. }
  1669. catch(...)
  1670. {
  1671. if ( dynBuffer )
  1672. {
  1673. delete [] dynBuffer;
  1674. dynBuffer = NULL;
  1675. }
  1676. g_fpMsiCloseHandle(hRecord);
  1677. g_fpMsiViewClose(hView);
  1678. g_fpMsiCloseHandle(hView);
  1679. msidata.CloseDatabase ();
  1680. if(m_pObj)
  1681. {
  1682. m_pObj->Release();
  1683. m_pObj = NULL;
  1684. }
  1685. throw;
  1686. }
  1687. g_fpMsiCloseHandle(hRecord);
  1688. g_fpMsiViewClose(hView);
  1689. g_fpMsiCloseHandle(hView);
  1690. msidata.CloseDatabase ();
  1691. }
  1692. }
  1693. if ( dynBuffer )
  1694. {
  1695. delete [] dynBuffer;
  1696. dynBuffer = NULL;
  1697. }
  1698. return hr;
  1699. }
  1700. HRESULT CSoftwareElementAction::SoftwareElementDuplicateFile(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  1701. , CRequestObject *pActionData, CRequestObject *pElementData)
  1702. {
  1703. HRESULT hr = WBEM_S_NO_ERROR;
  1704. MSIHANDLE hView = NULL;
  1705. MSIHANDLE hRecord = NULL;
  1706. int i = -1;
  1707. WCHAR wcBuf[BUFF_SIZE];
  1708. WCHAR wcProductCode[39];
  1709. WCHAR wcTestCode[39];
  1710. WCHAR wcFile[BUFF_SIZE];
  1711. DWORD dwBufSize;
  1712. bool bMatch = false;
  1713. bool bTestCode = false;
  1714. UINT uiStatus;
  1715. WCHAR wcElement[BUFF_SIZE];
  1716. bool bGotAction = false;
  1717. bool bGotElement = false;
  1718. CStringExt wcProp;
  1719. if(atAction != ACTIONTYPE_ENUM){
  1720. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  1721. if(pActionData){
  1722. for(int i = 0; i < pActionData->m_iPropCount; i++){
  1723. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  1724. {
  1725. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  1726. {
  1727. //Get the action we're looking for
  1728. wcscpy(wcBuf, pActionData->m_Value[i]);
  1729. // safe operation if wcslen ( wcBuf ) > 38
  1730. if ( wcslen ( wcBuf ) > 38 )
  1731. {
  1732. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  1733. }
  1734. else
  1735. {
  1736. // we are not good to go, they have sent us longer string
  1737. throw hr;
  1738. }
  1739. // safe because lenght has been tested already in condition
  1740. RemoveFinalGUID(pActionData->m_Value[i], wcFile);
  1741. bGotAction = true;
  1742. bTestCode = true;
  1743. break;
  1744. }
  1745. else
  1746. {
  1747. // we are not good to go, they have sent us longer string
  1748. throw hr;
  1749. }
  1750. }
  1751. }
  1752. }
  1753. if(pElementData){
  1754. for(int j = 0; j < pElementData->m_iPropCount; j++){
  1755. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  1756. //Get the product code we're looking for
  1757. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  1758. {
  1759. wcscpy(wcElement, pElementData->m_Value[j]);
  1760. bGotElement = true;
  1761. break;
  1762. }
  1763. }
  1764. }
  1765. }
  1766. }
  1767. //These will change from class to class
  1768. bool bEnvironment, bElement;
  1769. Query wcQuery;
  1770. wcQuery.Append ( 1, L"select distinct `Component_`, `FileKey` from DuplicateFile" );
  1771. //optimize for GetObject
  1772. if ( bGotElement || bGotAction )
  1773. {
  1774. if ( bGotAction )
  1775. {
  1776. wcQuery.Append ( 3, L" where `FileKey`=\'", wcFile, L"\'" );
  1777. }
  1778. if ( bGotElement )
  1779. {
  1780. if ( bGotAction )
  1781. {
  1782. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1783. }
  1784. else
  1785. {
  1786. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1787. }
  1788. }
  1789. }
  1790. LPWSTR Buffer = NULL;
  1791. LPWSTR dynBuffer = NULL;
  1792. DWORD dwDynBuffer = 0L;
  1793. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1794. {
  1795. // safe operation:
  1796. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1797. wcscpy(wcProductCode, m_pRequest->Package(i));
  1798. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1799. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1800. //Open our database
  1801. try
  1802. {
  1803. if ( GetView ( &hView, wcProductCode, wcQuery, L"DuplicateFile", TRUE, FALSE ) )
  1804. {
  1805. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1806. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1807. CheckMSI(uiStatus);
  1808. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1809. //----------------------------------------------------
  1810. dwBufSize = BUFF_SIZE;
  1811. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1812. dwBufSize = BUFF_SIZE;
  1813. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1814. Buffer,
  1815. wcProductCode,
  1816. wcElement,
  1817. &dwBufSize
  1818. );
  1819. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1820. {
  1821. dynBuffer [ 0 ] = 0;
  1822. }
  1823. if( uiStatus == ERROR_SUCCESS )
  1824. {
  1825. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  1826. dwBufSize = BUFF_SIZE;
  1827. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1828. if ( Buffer && Buffer [ 0 ] != 0 )
  1829. {
  1830. // safe operation
  1831. wcProp.Copy(L"Win32_DuplicateFileAction.ActionID=\"");
  1832. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  1833. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  1834. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  1835. {
  1836. dynBuffer [ 0 ] = 0;
  1837. }
  1838. if(bEnvironment && bElement) bMatch = true;
  1839. if((atAction != ACTIONTYPE_GET) || bMatch){
  1840. hr = pHandler->Indicate(1, &m_pObj);
  1841. }
  1842. }
  1843. }
  1844. m_pObj->Release();
  1845. m_pObj = NULL;
  1846. g_fpMsiCloseHandle(hRecord);
  1847. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1848. }
  1849. }
  1850. }
  1851. catch(...)
  1852. {
  1853. if ( dynBuffer )
  1854. {
  1855. delete [] dynBuffer;
  1856. dynBuffer = NULL;
  1857. }
  1858. g_fpMsiCloseHandle(hRecord);
  1859. g_fpMsiViewClose(hView);
  1860. g_fpMsiCloseHandle(hView);
  1861. msidata.CloseDatabase ();
  1862. if(m_pObj)
  1863. {
  1864. m_pObj->Release();
  1865. m_pObj = NULL;
  1866. }
  1867. throw;
  1868. }
  1869. g_fpMsiCloseHandle(hRecord);
  1870. g_fpMsiViewClose(hView);
  1871. g_fpMsiCloseHandle(hView);
  1872. msidata.CloseDatabase ();
  1873. }
  1874. }
  1875. if ( dynBuffer )
  1876. {
  1877. delete [] dynBuffer;
  1878. dynBuffer = NULL;
  1879. }
  1880. return hr;
  1881. }
  1882. HRESULT CSoftwareElementAction::SoftwareElementCreateFolder(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  1883. , CRequestObject *pActionData, CRequestObject *pElementData)
  1884. {
  1885. HRESULT hr = WBEM_S_NO_ERROR;
  1886. MSIHANDLE hView = NULL;
  1887. MSIHANDLE hRecord = NULL;
  1888. int i = -1;
  1889. WCHAR wcBuf[BUFF_SIZE];
  1890. WCHAR wcProductCode[39];
  1891. WCHAR wcTestCode[39];
  1892. WCHAR wcFolder[BUFF_SIZE];
  1893. DWORD dwBufSize;
  1894. bool bMatch = false;
  1895. bool bTestCode = false;
  1896. UINT uiStatus;
  1897. WCHAR wcElement[BUFF_SIZE];
  1898. bool bGotAction = false;
  1899. bool bGotElement = false;
  1900. CStringExt wcProp;
  1901. if(atAction != ACTIONTYPE_ENUM){
  1902. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  1903. if(pActionData){
  1904. for(int i = 0; i < pActionData->m_iPropCount; i++){
  1905. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  1906. {
  1907. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  1908. {
  1909. //Get the action we're looking for
  1910. wcscpy(wcBuf, pActionData->m_Value[i]);
  1911. // safe operation if wcslen ( wcBuf ) > 38
  1912. if ( wcslen ( wcBuf ) > 38 )
  1913. {
  1914. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  1915. }
  1916. else
  1917. {
  1918. // we are not good to go, they have sent us longer string
  1919. throw hr;
  1920. }
  1921. // safe because lenght has been tested already in condition
  1922. RemoveFinalGUID(pActionData->m_Value[i], wcFolder);
  1923. bGotAction = true;
  1924. bTestCode = true;
  1925. break;
  1926. }
  1927. else
  1928. {
  1929. // we are not good to go, they have sent us longer string
  1930. throw hr;
  1931. }
  1932. }
  1933. }
  1934. }
  1935. if(pElementData){
  1936. for(int j = 0; j < pElementData->m_iPropCount; j++){
  1937. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  1938. //Get the product code we're looking for
  1939. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  1940. {
  1941. wcscpy(wcElement, pElementData->m_Value[j]);
  1942. bGotElement = true;
  1943. break;
  1944. }
  1945. }
  1946. }
  1947. }
  1948. }
  1949. //These will change from class to class
  1950. bool bEnvironment, bElement;
  1951. Query wcQuery;
  1952. wcQuery.Append ( 1, L"select distinct `Component_`, `Directory_` from CreateFolder" );
  1953. //optimize for GetObject
  1954. if ( bGotElement || bGotAction )
  1955. {
  1956. if ( bGotAction )
  1957. {
  1958. wcQuery.Append ( 3, L" where `Directory_`=\'", wcFolder, L"\'" );
  1959. }
  1960. if ( bGotElement )
  1961. {
  1962. if ( bGotAction )
  1963. {
  1964. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  1965. }
  1966. else
  1967. {
  1968. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  1969. }
  1970. }
  1971. }
  1972. LPWSTR Buffer = NULL;
  1973. LPWSTR dynBuffer = NULL;
  1974. DWORD dwDynBuffer = 0L;
  1975. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  1976. {
  1977. // safe operation:
  1978. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  1979. wcscpy(wcProductCode, m_pRequest->Package(i));
  1980. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  1981. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  1982. bMatch = false;
  1983. //Open our database
  1984. try
  1985. {
  1986. if ( GetView ( &hView, wcProductCode, wcQuery, L"CreateFolder", TRUE, FALSE ) )
  1987. {
  1988. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  1989. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  1990. CheckMSI(uiStatus);
  1991. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  1992. //----------------------------------------------------
  1993. dwBufSize = BUFF_SIZE;
  1994. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  1995. dwBufSize = BUFF_SIZE;
  1996. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  1997. Buffer,
  1998. wcProductCode,
  1999. wcElement,
  2000. &dwBufSize
  2001. );
  2002. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  2003. {
  2004. dynBuffer [ 0 ] = 0;
  2005. }
  2006. if( uiStatus == ERROR_SUCCESS )
  2007. {
  2008. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  2009. dwBufSize = BUFF_SIZE;
  2010. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  2011. if ( Buffer && Buffer [ 0 ] != 0 )
  2012. {
  2013. // safe operation
  2014. wcProp.Copy(L"Win32_CreateFolderAction.ActionID=\"");
  2015. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  2016. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  2017. //====================================================
  2018. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  2019. {
  2020. dynBuffer [ 0 ] = 0;
  2021. }
  2022. //----------------------------------------------------
  2023. if(bEnvironment && bElement) bMatch = true;
  2024. if((atAction != ACTIONTYPE_GET) || bMatch){
  2025. hr = pHandler->Indicate(1, &m_pObj);
  2026. }
  2027. }
  2028. }
  2029. m_pObj->Release();
  2030. m_pObj = NULL;
  2031. g_fpMsiCloseHandle(hRecord);
  2032. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  2033. }
  2034. }
  2035. }
  2036. catch(...)
  2037. {
  2038. if ( dynBuffer )
  2039. {
  2040. delete [] dynBuffer;
  2041. dynBuffer = NULL;
  2042. }
  2043. g_fpMsiCloseHandle(hRecord);
  2044. g_fpMsiViewClose(hView);
  2045. g_fpMsiCloseHandle(hView);
  2046. msidata.CloseDatabase ();
  2047. if(m_pObj)
  2048. {
  2049. m_pObj->Release();
  2050. m_pObj = NULL;
  2051. }
  2052. throw;
  2053. }
  2054. g_fpMsiCloseHandle(hRecord);
  2055. g_fpMsiViewClose(hView);
  2056. g_fpMsiCloseHandle(hView);
  2057. msidata.CloseDatabase ();
  2058. }
  2059. }
  2060. if ( dynBuffer )
  2061. {
  2062. delete [] dynBuffer;
  2063. dynBuffer = NULL;
  2064. }
  2065. return hr;
  2066. }
  2067. HRESULT CSoftwareElementAction::SoftwareElementClass(IWbemObjectSink *pHandler, ACTIONTYPE atAction
  2068. , CRequestObject *pActionData, CRequestObject *pElementData)
  2069. {
  2070. HRESULT hr = WBEM_S_NO_ERROR;
  2071. MSIHANDLE hView = NULL;
  2072. MSIHANDLE hRecord = NULL;
  2073. int i = -1;
  2074. WCHAR wcBuf[BUFF_SIZE];
  2075. WCHAR wcProductCode[39];
  2076. WCHAR wcTestCode[39];
  2077. WCHAR wcCLSID[BUFF_SIZE];
  2078. DWORD dwBufSize;
  2079. bool bMatch = false;
  2080. bool bTestCode = false;
  2081. UINT uiStatus;
  2082. WCHAR wcElement[BUFF_SIZE];
  2083. bool bGotAction = false;
  2084. bool bGotElement = false;
  2085. CStringExt wcProp;
  2086. if(atAction != ACTIONTYPE_ENUM){
  2087. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  2088. if(pActionData){
  2089. for(int i = 0; i < pActionData->m_iPropCount; i++){
  2090. if(_wcsicmp(pActionData->m_Property[i], L"ActionID") == 0)
  2091. {
  2092. if ( ::SysStringLen ( pActionData->m_Value[i] ) < BUFF_SIZE )
  2093. {
  2094. //Get the action we're looking for
  2095. wcscpy(wcBuf, pActionData->m_Value[i]);
  2096. // safe operation if wcslen ( wcBuf ) > 38
  2097. if ( wcslen ( wcBuf ) > 38 )
  2098. {
  2099. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  2100. }
  2101. else
  2102. {
  2103. // we are not good to go, they have sent us longer string
  2104. throw hr;
  2105. }
  2106. // safe because lenght has been tested already in condition
  2107. GetFirstGUID(pActionData->m_Value[i], wcCLSID);
  2108. bGotAction = true;
  2109. bTestCode = true;
  2110. break;
  2111. }
  2112. else
  2113. {
  2114. // we are not good to go, they have sent us longer string
  2115. throw hr;
  2116. }
  2117. }
  2118. }
  2119. }
  2120. if(pElementData){
  2121. for(int j = 0; j < pElementData->m_iPropCount; j++){
  2122. if(_wcsicmp(pElementData->m_Property[j], L"Name") == 0){
  2123. //Get the product code we're looking for
  2124. if ( ::SysStringLen (pElementData->m_Value[j]) < BUFF_SIZE )
  2125. {
  2126. wcscpy(wcElement, pElementData->m_Value[j]);
  2127. bGotElement = true;
  2128. break;
  2129. }
  2130. }
  2131. }
  2132. }
  2133. }
  2134. //These will change from class to class
  2135. bool bEnvironment, bElement;
  2136. Query wcQuery;
  2137. wcQuery.Append ( 1, L"select distinct `Component_`, `CLSID`, `Context` from Class" );
  2138. //optimize for GetObject
  2139. if ( bGotElement || bGotAction )
  2140. {
  2141. if ( bGotAction )
  2142. {
  2143. wcQuery.Append ( 3, L" where `CLSID`=\'", wcCLSID, L"\'" );
  2144. }
  2145. if ( bGotElement )
  2146. {
  2147. if ( bGotAction )
  2148. {
  2149. wcQuery.Append ( 3, L" or `Component_`=\'", wcElement, L"\'" );
  2150. }
  2151. else
  2152. {
  2153. wcQuery.Append ( 3, L" where `Component_`=\'", wcElement, L"\'" );
  2154. }
  2155. }
  2156. }
  2157. LPWSTR Buffer = NULL;
  2158. LPWSTR dynBuffer = NULL;
  2159. DWORD dwDynBuffer = 0L;
  2160. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  2161. {
  2162. // safe operation:
  2163. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  2164. wcscpy(wcProductCode, m_pRequest->Package(i));
  2165. if((atAction == ACTIONTYPE_ENUM) || bGotElement ||
  2166. (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  2167. //Open our database
  2168. try
  2169. {
  2170. if ( GetView ( &hView, wcProductCode, wcQuery, L"Class", TRUE, FALSE ) )
  2171. {
  2172. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  2173. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  2174. CheckMSI(uiStatus);
  2175. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  2176. //----------------------------------------------------
  2177. dwBufSize = BUFF_SIZE;
  2178. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  2179. dwBufSize = BUFF_SIZE;
  2180. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  2181. Buffer,
  2182. wcProductCode,
  2183. wcElement,
  2184. &dwBufSize
  2185. );
  2186. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  2187. {
  2188. dynBuffer [ 0 ] = 0;
  2189. }
  2190. if( uiStatus == ERROR_SUCCESS )
  2191. {
  2192. PutKeyProperty(m_pObj, pElement, wcElement, &bElement, m_pRequest);
  2193. dwBufSize = BUFF_SIZE;
  2194. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  2195. if(wcscmp(wcBuf, L"") != 0)
  2196. {
  2197. // safe operation
  2198. wcProp.Copy(L"Win32_ClassInfoAction.ActionID=\"");
  2199. wcProp.Append ( 1, wcBuf );
  2200. dwBufSize = BUFF_SIZE;
  2201. GetBufferToPut ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  2202. wcProp.Append ( 3, wcBuf, wcProductCode, L"\"" );
  2203. PutKeyProperty(m_pObj, pAction, wcProp, &bEnvironment, m_pRequest);
  2204. //====================================================
  2205. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  2206. {
  2207. dynBuffer [ 0 ] = 0;
  2208. }
  2209. //----------------------------------------------------
  2210. if(bEnvironment && bElement) bMatch = true;
  2211. if((atAction != ACTIONTYPE_GET) || bMatch){
  2212. hr = pHandler->Indicate(1, &m_pObj);
  2213. }
  2214. }
  2215. }
  2216. m_pObj->Release();
  2217. m_pObj = NULL;
  2218. g_fpMsiCloseHandle(hRecord);
  2219. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  2220. }
  2221. }
  2222. }
  2223. catch(...)
  2224. {
  2225. if ( dynBuffer )
  2226. {
  2227. delete [] dynBuffer;
  2228. dynBuffer = NULL;
  2229. }
  2230. g_fpMsiCloseHandle(hRecord);
  2231. g_fpMsiViewClose(hView);
  2232. g_fpMsiCloseHandle(hView);
  2233. msidata.CloseDatabase ();
  2234. if(m_pObj)
  2235. {
  2236. m_pObj->Release();
  2237. m_pObj = NULL;
  2238. }
  2239. throw;
  2240. }
  2241. g_fpMsiCloseHandle(hRecord);
  2242. g_fpMsiViewClose(hView);
  2243. g_fpMsiCloseHandle(hView);
  2244. msidata.CloseDatabase ();
  2245. }
  2246. }
  2247. if ( dynBuffer )
  2248. {
  2249. delete [] dynBuffer;
  2250. dynBuffer = NULL;
  2251. }
  2252. return hr;
  2253. }