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.

1881 lines
54 KiB

  1. // Product.cpp: implementation of the CProduct class.
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "Product.h"
  8. #include <wininet.h>
  9. #include <ocidl.h>
  10. #include "CRegCls.h"
  11. #include <WbemTime.h>
  12. #include <helper.h>
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. CProduct::CProduct(CRequestObject *pObj, IWbemServices *pNamespace,
  17. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  18. {
  19. }
  20. CProduct::~CProduct()
  21. {
  22. }
  23. HRESULT CProduct::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  24. {
  25. HRESULT hr = WBEM_S_NO_ERROR;
  26. int i = -1;
  27. WCHAR wcBuf[BUFF_SIZE];
  28. WCHAR wcProductCode[39];
  29. WCHAR wcTestCode[39];
  30. DWORD dwBufsize;
  31. bool bMatch = false;
  32. bool bTestCode = false;
  33. if(atAction != ACTIONTYPE_ENUM)
  34. {
  35. // we are doing GetObject so we need to be reinitialized
  36. hr = WBEM_E_NOT_FOUND;
  37. int iPos = -1;
  38. BSTR bstrIdentifyingNumber = SysAllocString(L"IdentifyingNumber");
  39. if ( bstrIdentifyingNumber )
  40. {
  41. if(FindIn(m_pRequest->m_Property, bstrIdentifyingNumber, &iPos))
  42. {
  43. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) == 38 )
  44. {
  45. wcscpy(wcTestCode, m_pRequest->m_Value[iPos]);
  46. bTestCode = true;
  47. }
  48. else
  49. {
  50. // we are not good to go, they have sent us longer string
  51. SysFreeString ( bstrIdentifyingNumber );
  52. throw hr;
  53. }
  54. }
  55. SysFreeString(bstrIdentifyingNumber);
  56. }
  57. else
  58. {
  59. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  60. }
  61. }
  62. bool bName, bVersion = false, bIDNum, bProductHandle;
  63. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  64. {
  65. // safe operation:
  66. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  67. wcscpy(wcProductCode, m_pRequest->Package(i));
  68. if((atAction == ACTIONTYPE_ENUM) || (bTestCode && (_wcsicmp(wcTestCode, wcProductCode) == 0)))
  69. {
  70. //Open our database
  71. try
  72. {
  73. if ( GetView ( NULL, wcProductCode, NULL, NULL, FALSE, TRUE ) )
  74. {
  75. bProductHandle = true;
  76. }
  77. else
  78. {
  79. bProductHandle = false;
  80. }
  81. if(FAILED(hr = SpawnAnInstance(&m_pObj)))
  82. {
  83. throw hr;
  84. }
  85. dwBufsize = BUFF_SIZE;
  86. CheckMSI(g_fpMsiGetProductInfoW(wcProductCode, INSTALLPROPERTY_PRODUCTNAME, wcBuf, &dwBufsize));
  87. PutKeyProperty(m_pObj, pName, wcBuf, &bName, m_pRequest);
  88. PutProperty(m_pObj, pCaption, wcBuf);
  89. PutProperty(m_pObj, pDescription, wcBuf);
  90. if(bProductHandle)
  91. {
  92. dwBufsize = BUFF_SIZE;
  93. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"Manufacturer", wcBuf, &dwBufsize));
  94. PutProperty(m_pObj, pVendor, wcBuf);
  95. dwBufsize = BUFF_SIZE;
  96. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"ProductVersion", wcBuf, &dwBufsize));
  97. PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
  98. }
  99. PutKeyProperty(m_pObj, pIdentifyingNumber, wcProductCode, &bIDNum, m_pRequest);
  100. INSTALLSTATE isState = g_fpMsiQueryProductStateW(wcProductCode);
  101. switch(isState)
  102. {
  103. case INSTALLSTATE_ABSENT:
  104. break;
  105. case INSTALLSTATE_ADVERTISED:
  106. dwBufsize = BUFF_SIZE;
  107. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,INSTALLPROPERTY_VERSIONSTRING, wcBuf, &dwBufsize))
  108. {
  109. PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
  110. dwBufsize = BUFF_SIZE;
  111. }
  112. break;
  113. case INSTALLSTATE_BADCONFIG:
  114. break;
  115. case INSTALLSTATE_DEFAULT:
  116. dwBufsize = BUFF_SIZE;
  117. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,INSTALLPROPERTY_VERSIONSTRING, wcBuf, &dwBufsize))
  118. {
  119. PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
  120. }
  121. dwBufsize = BUFF_SIZE;
  122. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,INSTALLPROPERTY_LOCALPACKAGE, wcBuf, &dwBufsize))
  123. {
  124. PutProperty(m_pObj, pPackageCache, wcBuf);
  125. }
  126. dwBufsize = BUFF_SIZE;
  127. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,INSTALLPROPERTY_INSTALLDATE, wcBuf, &dwBufsize))
  128. {
  129. PutProperty(m_pObj, pInstallDate, wcBuf);
  130. if ( ( lstrlenW ( wcBuf ) + lstrlenW ( L"000000.000000+000" ) + 1 ) < BUFF_SIZE )
  131. {
  132. lstrcatW ( wcBuf, L"000000.000000+000" );
  133. BSTR bstrWbemTime;
  134. if ( ( bstrWbemTime = ::SysAllocString ( wcBuf ) ) != NULL )
  135. {
  136. WBEMTime time ( bstrWbemTime );
  137. ::SysFreeString ( bstrWbemTime );
  138. if ( time.IsOk () )
  139. {
  140. bstrWbemTime= time.GetDMTF ( );
  141. try
  142. {
  143. PutProperty( m_pObj, pInstallDate2, bstrWbemTime );
  144. }
  145. catch ( ... )
  146. {
  147. ::SysFreeString ( bstrWbemTime );
  148. throw;
  149. }
  150. ::SysFreeString ( bstrWbemTime );
  151. }
  152. else
  153. {
  154. hr = E_INVALIDARG;
  155. }
  156. }
  157. else
  158. {
  159. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  160. }
  161. }
  162. else
  163. {
  164. hr = E_FAIL;
  165. }
  166. }
  167. dwBufsize = BUFF_SIZE;
  168. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,INSTALLPROPERTY_INSTALLLOCATION, wcBuf, &dwBufsize))
  169. {
  170. PutProperty(m_pObj, pInstallLocation, wcBuf);
  171. }
  172. break;
  173. case INSTALLSTATE_INVALIDARG:
  174. break;
  175. case INSTALLSTATE_UNKNOWN:
  176. break;
  177. default:
  178. break;
  179. }
  180. PutProperty(m_pObj, pInstallState, (int)isState);
  181. if(bName && bVersion && bIDNum)
  182. {
  183. bMatch = true;
  184. }
  185. if((atAction != ACTIONTYPE_GET) || bMatch)
  186. {
  187. hr = pHandler->Indicate(1, &m_pObj);
  188. }
  189. m_pObj->Release();
  190. m_pObj = NULL;
  191. }
  192. catch(...)
  193. {
  194. msidata.CloseProduct ();
  195. if(m_pObj)
  196. {
  197. m_pObj->Release();
  198. m_pObj = NULL;
  199. }
  200. throw;
  201. }
  202. msidata.CloseProduct ();
  203. }
  204. }
  205. return hr;
  206. }
  207. HRESULT CProduct::Admin(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  208. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  209. {
  210. HRESULT hrReturn = WBEM_S_NO_ERROR;
  211. BSTR bstrPackage = NULL;
  212. BSTR bstrTarget = NULL;
  213. BSTR bstrOptions = NULL;
  214. UINT uiStatus = 1603;
  215. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  216. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  217. BSTR bstrInstall = SysAllocString(L"Install");
  218. if(!bstrInstall)
  219. {
  220. ::SysFreeString (bstrReturnValue);
  221. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  222. }
  223. IWbemClassObject *pClass = NULL;
  224. IWbemClassObject *pOutClass = NULL;
  225. IWbemClassObject *pOutParams = NULL;
  226. VARIANT v;
  227. m_pRequest = pReqObj;
  228. LPWSTR wcOptions = NULL;
  229. DWORD dwOptions = BUFF_SIZE;
  230. try
  231. {
  232. if ( ( wcOptions = new WCHAR [ dwOptions ] ) == NULL )
  233. {
  234. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  235. }
  236. }
  237. catch ( ... )
  238. {
  239. if ( wcOptions )
  240. {
  241. delete [] wcOptions;
  242. wcOptions = NULL;
  243. }
  244. throw;
  245. }
  246. if(SUCCEEDED(hrReturn = m_pRequest->m_pNamespace->GetObject(m_pRequest->m_bstrClass,
  247. 0, pCtx, &pClass, NULL))){
  248. if(SUCCEEDED(hrReturn = pClass->GetMethod(bstrInstall, 0, NULL, &pOutClass))){
  249. if(SUCCEEDED(hrReturn = pOutClass->SpawnInstance(0, &pOutParams))){
  250. //Get PackageLocation
  251. if(SUCCEEDED(GetProperty(pInParams, "PackageLocation", &bstrPackage))){
  252. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_bstrPackage ( bstrPackage ) ;
  253. if((wcscmp(bstrPackage, L"") != 0) && (wcslen(bstrPackage) <= INTERNET_MAX_PATH_LENGTH)){
  254. //Get Options
  255. if(SUCCEEDED(GetProperty(pInParams, "TargetLocation", &bstrTarget))){
  256. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_bstrTarget ( bstrTarget ) ;
  257. //Get Options
  258. if(SUCCEEDED(GetProperty(pInParams, "Options", &bstrOptions)))
  259. {
  260. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_bstrOptions ( bstrOptions ) ;
  261. // safe operation
  262. wcscpy(wcOptions, L"ACTION=ADMIN");
  263. if((wcscmp(bstrTarget, L"") != 0))
  264. {
  265. if ( wcslen ( wcOptions ) + wcslen ( L" TARGETDIR=") + wcslen ( bstrTarget ) + 1 < dwOptions )
  266. {
  267. wcscat(wcOptions, L" TARGETDIR=");
  268. wcscat(wcOptions, bstrTarget);
  269. }
  270. else
  271. {
  272. LPWSTR wsz = NULL;
  273. try
  274. {
  275. if ( ( wsz = new WCHAR [ wcslen ( wcOptions ) + wcslen ( L" TARGETDIR=") + wcslen ( bstrTarget ) + 1 ] ) != NULL )
  276. {
  277. wcscpy(wsz, wcOptions);
  278. wcscat(wsz, L" TARGETDIR=");
  279. wcscat(wsz, bstrTarget);
  280. if ( wcOptions )
  281. {
  282. delete [] wcOptions;
  283. wcOptions = NULL;
  284. }
  285. wcOptions = wsz;
  286. }
  287. else
  288. {
  289. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  290. }
  291. }
  292. catch ( ... )
  293. {
  294. if ( wsz )
  295. {
  296. delete [] wsz;
  297. wsz = NULL;
  298. }
  299. if ( wcOptions )
  300. {
  301. delete [] wcOptions;
  302. wcOptions = NULL;
  303. }
  304. hrReturn = E_OUTOFMEMORY;
  305. }
  306. }
  307. }
  308. if((wcscmp(bstrOptions, L"") != 0))
  309. {
  310. if ( wcslen ( wcOptions ) + wcslen ( L" ") + wcslen ( bstrOptions ) + 1 < dwOptions )
  311. {
  312. wcscat(wcOptions, L" ");
  313. wcscat(wcOptions, bstrOptions);
  314. }
  315. else
  316. {
  317. LPWSTR wsz = NULL;
  318. try
  319. {
  320. if ( ( wsz = new WCHAR [ wcslen ( wcOptions ) + wcslen ( L" ") + wcslen ( bstrOptions ) + 1 ] ) != NULL )
  321. {
  322. wcscpy(wsz, wcOptions);
  323. wcscat(wsz, L" ");
  324. wcscat(wsz, bstrOptions);
  325. if ( wcOptions )
  326. {
  327. delete [] wcOptions;
  328. wcOptions = NULL;
  329. }
  330. wcOptions = wsz;
  331. }
  332. else
  333. {
  334. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  335. }
  336. }
  337. catch ( ... )
  338. {
  339. if ( wsz )
  340. {
  341. delete [] wsz;
  342. wsz = NULL;
  343. }
  344. if ( wcOptions )
  345. {
  346. delete [] wcOptions;
  347. wcOptions = NULL;
  348. }
  349. hrReturn = E_OUTOFMEMORY;
  350. }
  351. }
  352. }
  353. if(hrReturn == WBEM_S_NO_ERROR){
  354. if(!IsNT4()){
  355. if ( msidata.Lock () )
  356. {
  357. INSTALLUI_HANDLER ui = NULL;
  358. //Set UI Level w/ event callback
  359. ui = SetupExternalUI ( );
  360. try
  361. {
  362. //Call Installer
  363. uiStatus = g_fpMsiInstallProductW(bstrPackage, wcOptions);
  364. }
  365. catch(...)
  366. {
  367. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  368. }
  369. //Restore UI Level w/ event callback
  370. RestoreExternalUI ( ui );
  371. msidata. Unlock();
  372. }
  373. }else{
  374. /////////////////
  375. // NT4 fix code....
  376. try{
  377. WCHAR wcAction[20];
  378. wcscpy(wcAction, L"/admin");
  379. LPWSTR wcCommandLine = NULL;
  380. try
  381. {
  382. if ( ( wcCommandLine = new WCHAR [ wcslen ( bstrPackage ) + 1 + wcslen ( wcOptions ) + 1 ] ) != NULL )
  383. {
  384. wcscpy(wcCommandLine, bstrPackage);
  385. wcscat(wcCommandLine, L" ");
  386. wcscat(wcCommandLine, wcOptions);
  387. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  388. delete [] wcCommandLine;
  389. }
  390. else
  391. {
  392. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  393. }
  394. }
  395. catch ( ... )
  396. {
  397. if ( wcCommandLine )
  398. {
  399. delete [] wcCommandLine;
  400. wcCommandLine = NULL;
  401. }
  402. hrReturn = E_OUTOFMEMORY;
  403. }
  404. }catch(...){
  405. hrReturn = WBEM_E_FAILED;
  406. }
  407. ////////////////////
  408. }
  409. if(SUCCEEDED(hrReturn)){
  410. //Set up ReturnValue
  411. VariantInit(&v);
  412. V_VT(&v) = VT_I4;
  413. V_I4(&v) = uiStatus;
  414. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  415. if(!bstrReturnValue)
  416. {
  417. delete [] wcOptions;
  418. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  419. }
  420. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  421. &v, NULL)))
  422. pHandler->Indicate(1, &pOutParams);
  423. SysFreeString(bstrReturnValue);
  424. }
  425. }
  426. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  427. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  428. }else hrReturn = WBEM_E_INVALID_PARAMETER;
  429. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  430. pOutParams->Release();
  431. }
  432. pOutClass->Release();
  433. }
  434. pClass->Release();
  435. }
  436. if ( wcOptions )
  437. {
  438. delete [] wcOptions;
  439. wcOptions = NULL;
  440. }
  441. SysFreeString(bstrReturnValue);
  442. SysFreeString(bstrInstall);
  443. return hrReturn;
  444. }
  445. HRESULT CProduct::Advertise(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  446. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  447. {
  448. HRESULT hrReturn = WBEM_S_NO_ERROR;
  449. BSTR bstrPackage = NULL;
  450. BSTR wcBuf = NULL;
  451. UINT uiStatus = 1603;
  452. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  453. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  454. BSTR bstrAdvertise = SysAllocString(L"Advertise");
  455. if(!bstrAdvertise)
  456. {
  457. ::SysFreeString (bstrReturnValue);
  458. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  459. }
  460. IWbemClassObject *pClass = NULL;
  461. IWbemClassObject *pOutClass = NULL;
  462. IWbemClassObject *pOutParams = NULL;
  463. VARIANT v;
  464. m_pRequest = pReqObj;
  465. LPWSTR wcOptions = NULL;
  466. DWORD dwOptions = BUFF_SIZE;
  467. try
  468. {
  469. if ( ( wcOptions = new WCHAR [ dwOptions ] ) == NULL )
  470. {
  471. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  472. }
  473. }
  474. catch ( ... )
  475. {
  476. if ( wcOptions )
  477. {
  478. delete [] wcOptions;
  479. wcOptions = NULL;
  480. }
  481. throw;
  482. }
  483. if(SUCCEEDED(hrReturn = m_pRequest->m_pNamespace->GetObject(m_pRequest->m_bstrClass,
  484. 0, pCtx, &pClass, NULL))){
  485. if(SUCCEEDED(hrReturn = pClass->GetMethod(bstrAdvertise, 0, NULL, &pOutClass))){
  486. if(SUCCEEDED(hrReturn = pOutClass->SpawnInstance(0, &pOutParams))){
  487. //Get PackageLocation
  488. if(SUCCEEDED(GetProperty(pInParams, "PackageLocation", &bstrPackage))){
  489. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_bstrPackage ( bstrPackage ) ;
  490. if((wcscmp(bstrPackage, L"") != 0) && (wcslen(bstrPackage) <= INTERNET_MAX_PATH_LENGTH)){
  491. //Get Options
  492. if ( SUCCEEDED ( GetProperty ( pInParams, "Options", &wcBuf ) ) )
  493. {
  494. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_wcBuf ( wcBuf ) ;
  495. //Make sure we perform an advertisement
  496. wcscpy(wcOptions, L"ACTION=ADVERTISE ALLUSERS=1");
  497. if( wcBuf && wcscmp ( wcBuf, L"" ) != 0 )
  498. {
  499. if ( wcslen ( wcOptions ) + wcslen ( L" ") + SysStringLen ( wcBuf ) + 1 < dwOptions )
  500. {
  501. wcscat(wcOptions, L" ");
  502. wcscat(wcOptions, wcBuf);
  503. }
  504. else
  505. {
  506. LPWSTR wsz = NULL;
  507. try
  508. {
  509. if ( ( wsz = new WCHAR [ wcslen ( wcOptions ) + wcslen ( L" ") + SysStringLen ( wcBuf ) + 1 ] ) != NULL )
  510. {
  511. wcscpy(wsz, wcOptions);
  512. wcscat(wsz, L" ");
  513. wcscat(wsz, wcBuf);
  514. if ( wcOptions )
  515. {
  516. delete [] wcOptions;
  517. wcOptions = NULL;
  518. }
  519. wcOptions = wsz;
  520. }
  521. else
  522. {
  523. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  524. }
  525. }
  526. catch ( ... )
  527. {
  528. if ( wsz )
  529. {
  530. delete [] wsz;
  531. wsz = NULL;
  532. }
  533. if ( wcOptions )
  534. {
  535. delete [] wcOptions;
  536. wcOptions = NULL;
  537. }
  538. hrReturn = E_OUTOFMEMORY;
  539. }
  540. }
  541. }
  542. if(hrReturn == WBEM_S_NO_ERROR){
  543. if(!IsNT4()){
  544. if ( msidata.Lock () )
  545. {
  546. INSTALLUI_HANDLER ui = NULL;
  547. //Set UI Level w/ event callback
  548. ui = SetupExternalUI ( );
  549. try
  550. {
  551. //Call Installer
  552. uiStatus = g_fpMsiInstallProductW(bstrPackage, wcOptions);
  553. }
  554. catch(...)
  555. {
  556. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  557. }
  558. //Restore UI Level w/ event callback
  559. RestoreExternalUI ( ui );
  560. msidata. Unlock();
  561. }
  562. }else{
  563. /////////////////
  564. // NT4 fix code....
  565. try{
  566. WCHAR wcAction[20];
  567. wcscpy(wcAction, L"/advertise");
  568. LPWSTR wcCommandLine = NULL;
  569. try
  570. {
  571. if ( ( wcCommandLine = new WCHAR [ wcslen ( bstrPackage ) + 1 + wcslen ( wcOptions ) + 1 ] ) != NULL )
  572. {
  573. wcscpy(wcCommandLine, bstrPackage);
  574. wcscat(wcCommandLine, L" ");
  575. wcscat(wcCommandLine, wcOptions);
  576. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  577. delete [] wcCommandLine;
  578. }
  579. else
  580. {
  581. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  582. }
  583. }
  584. catch ( ... )
  585. {
  586. if ( wcCommandLine )
  587. {
  588. delete [] wcCommandLine;
  589. wcCommandLine = NULL;
  590. }
  591. hrReturn = E_OUTOFMEMORY;
  592. }
  593. }catch(...){
  594. hrReturn = WBEM_E_FAILED;
  595. }
  596. ////////////////////
  597. }
  598. if(SUCCEEDED(hrReturn)){
  599. //Set up ReturnValue
  600. VariantInit(&v);
  601. V_VT(&v) = VT_I4;
  602. V_I4(&v) = uiStatus;
  603. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  604. if(!bstrReturnValue)
  605. {
  606. delete [] wcOptions;
  607. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  608. }
  609. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  610. &v, NULL)))
  611. pHandler->Indicate(1, &pOutParams);
  612. SysFreeString(bstrReturnValue);
  613. }
  614. }
  615. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  616. }else hrReturn = WBEM_E_INVALID_PARAMETER;
  617. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  618. pOutParams->Release();
  619. }
  620. pOutClass->Release();
  621. }
  622. pClass->Release();
  623. }
  624. if ( wcOptions )
  625. {
  626. delete [] wcOptions;
  627. wcOptions = NULL;
  628. }
  629. SysFreeString(bstrReturnValue);
  630. SysFreeString(bstrAdvertise);
  631. return hrReturn;
  632. }
  633. HRESULT CProduct::Configure(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  634. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  635. {
  636. HRESULT hrReturn = WBEM_S_NO_ERROR;
  637. int iState, iLevel;
  638. UINT uiStatus = 1603;
  639. WCHAR wcCode[BUFF_SIZE];
  640. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  641. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  642. BSTR bstrConfigure = SysAllocString(L"Configure");
  643. if(!bstrConfigure)
  644. {
  645. ::SysFreeString (bstrReturnValue);
  646. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  647. }
  648. IWbemClassObject *pClass = NULL;
  649. IWbemClassObject *pOutClass = NULL;
  650. IWbemClassObject *pOutParams = NULL;
  651. VARIANT v;
  652. INSTALLSTATE isState;
  653. int i = -1;
  654. bool bFoundCode = false;
  655. m_pRequest = pReqObj;
  656. LPWSTR wcOptions = NULL;
  657. DWORD dwOptions = BUFF_SIZE;
  658. try
  659. {
  660. if ( ( wcOptions = new WCHAR [ dwOptions ] ) == NULL )
  661. {
  662. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  663. }
  664. }
  665. catch ( ... )
  666. {
  667. if ( wcOptions )
  668. {
  669. delete [] wcOptions;
  670. wcOptions = NULL;
  671. }
  672. throw;
  673. }
  674. if(SUCCEEDED(hrReturn = m_pRequest->m_pNamespace->GetObject(m_pRequest->m_bstrClass,
  675. 0, pCtx, &pClass, NULL))){
  676. if(SUCCEEDED(hrReturn = pClass->GetMethod(bstrConfigure, 0, NULL, &pOutClass))){
  677. if(SUCCEEDED(hrReturn = pOutClass->SpawnInstance(0, &pOutParams))){
  678. //Get PackageLocation
  679. if(SUCCEEDED(GetProperty(pInParams, "InstallState", &iState))){
  680. //Get Options
  681. if(SUCCEEDED(GetProperty(pInParams, "InstallLevel", &iLevel))){
  682. //Get the Product Code
  683. while(pReqObj->m_Property[++i]){
  684. if(wcscmp(pReqObj->m_Property[i], L"IdentifyingNumber") == 0)
  685. {
  686. if ( wcslen ( pReqObj->m_Value[i] ) < BUFF_SIZE )
  687. {
  688. wcscpy(wcCode, pReqObj->m_Value[i]);
  689. bFoundCode = true;
  690. }
  691. }
  692. }
  693. if(bFoundCode){
  694. //Get the appropriate State
  695. switch(iState){
  696. case 1:
  697. isState = INSTALLSTATE_DEFAULT;
  698. break;
  699. case 2:
  700. isState = INSTALLSTATE_LOCAL;
  701. break;
  702. case 3:
  703. isState = INSTALLSTATE_SOURCE;
  704. break;
  705. default:
  706. isState = INSTALLSTATE_NOTUSED;
  707. break;
  708. }
  709. //Get the appropriate Level
  710. switch(iLevel){
  711. case 1:
  712. iLevel = INSTALLLEVEL_DEFAULT;
  713. break;
  714. case 2:
  715. iLevel = INSTALLLEVEL_MINIMUM;
  716. break;
  717. case 3:
  718. iLevel = INSTALLLEVEL_MAXIMUM;
  719. break;
  720. default:
  721. iLevel = -123;
  722. break;
  723. }
  724. //If everything is valid, proceed
  725. if((isState != INSTALLSTATE_NOTUSED) && (iLevel != -123) &&
  726. (hrReturn == WBEM_S_NO_ERROR)){
  727. if(!IsNT4()){
  728. if ( msidata.Lock () )
  729. {
  730. INSTALLUI_HANDLER ui = NULL;
  731. //Set UI Level w/ event callback
  732. ui = SetupExternalUI ( );
  733. try
  734. {
  735. //Call Installer
  736. uiStatus = g_fpMsiConfigureProductW(wcCode, iLevel, isState);
  737. }
  738. catch(...)
  739. {
  740. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  741. }
  742. //Restore UI Level w/ event callback
  743. RestoreExternalUI ( ui );
  744. msidata. Unlock();
  745. }
  746. }else{
  747. /////////////////
  748. // NT4 fix code....
  749. try{
  750. WCHAR wcAction[20];
  751. wcscpy(wcAction, L"/configure");
  752. LPWSTR wcCommandLine = NULL;
  753. WCHAR wcTmp1[100];
  754. WCHAR wcTmp2[100];
  755. _itow((int)iLevel, wcTmp1, 10);
  756. _itow((int)isState, wcTmp2, 10);
  757. try
  758. {
  759. if ( ( wcCommandLine = new WCHAR [ wcslen ( wcCode ) + wcslen ( wcTmp1 ) + wcslen ( wcTmp2 ) + 3 ] ) != NULL )
  760. {
  761. wcscpy(wcCommandLine, wcCode);
  762. wcscat(wcCommandLine, L" ");
  763. wcscpy(wcCommandLine, wcTmp1);
  764. wcscat(wcCommandLine, L" ");
  765. wcscat(wcCommandLine, wcTmp2);
  766. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  767. delete [] wcCommandLine;
  768. }
  769. else
  770. {
  771. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  772. }
  773. }
  774. catch ( ... )
  775. {
  776. if ( wcCommandLine )
  777. {
  778. delete [] wcCommandLine;
  779. wcCommandLine = NULL;
  780. }
  781. hrReturn = E_OUTOFMEMORY;
  782. }
  783. }catch(...){
  784. hrReturn = WBEM_E_FAILED;
  785. }
  786. ////////////////////
  787. }
  788. if(SUCCEEDED(hrReturn)){
  789. //Set up ReturnValue
  790. VariantInit(&v);
  791. V_VT(&v) = VT_I4;
  792. V_I4(&v) = uiStatus;
  793. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  794. if(!bstrReturnValue)
  795. {
  796. delete [] wcOptions;
  797. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  798. }
  799. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  800. &v, NULL)))
  801. pHandler->Indicate(1, &pOutParams);
  802. SysFreeString(bstrReturnValue);
  803. }
  804. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  805. }else hrReturn = WBEM_E_FAILED;
  806. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  807. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  808. pOutParams->Release();
  809. }else return WBEM_E_INVALID_METHOD_PARAMETERS;
  810. pOutClass->Release();
  811. }
  812. pClass->Release();
  813. }
  814. if ( wcOptions )
  815. {
  816. delete [] wcOptions;
  817. wcOptions = NULL;
  818. }
  819. SysFreeString(bstrReturnValue);
  820. SysFreeString(bstrConfigure);
  821. return hrReturn;
  822. }
  823. HRESULT CProduct::Install(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  824. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  825. {
  826. HRESULT hrReturn = WBEM_S_NO_ERROR;
  827. BSTR bstrPackage = NULL;
  828. BSTR wcBuf = NULL;
  829. UINT uiStatus = 1603;
  830. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  831. IWbemClassObject *pClass = NULL;
  832. IWbemClassObject *pOutClass = NULL;
  833. IWbemClassObject *pOutParams = NULL;
  834. VARIANT v;
  835. m_pRequest = pReqObj;
  836. LPWSTR wcOptions = NULL;
  837. DWORD dwOptions = BUFF_SIZE;
  838. try
  839. {
  840. if ( ( wcOptions = new WCHAR [ dwOptions ] ) == NULL )
  841. {
  842. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  843. }
  844. }
  845. catch ( ... )
  846. {
  847. if ( wcOptions )
  848. {
  849. delete [] wcOptions;
  850. wcOptions = NULL;
  851. }
  852. throw;
  853. }
  854. if(SUCCEEDED(hrReturn = m_pRequest->m_pNamespace->GetObject(m_pRequest->m_bstrClass,
  855. 0, pCtx, &pClass, NULL))){
  856. BSTR bstrInstall = SysAllocString(L"Install");
  857. if(!bstrInstall)
  858. {
  859. if ( wcOptions )
  860. {
  861. delete [] wcOptions;
  862. wcOptions = NULL;
  863. }
  864. throw he;
  865. }
  866. if(SUCCEEDED(hrReturn = pClass->GetMethod(bstrInstall, 0, NULL, &pOutClass))){
  867. pClass->Release();
  868. SysFreeString(bstrInstall);
  869. if(SUCCEEDED(hrReturn = pOutClass->SpawnInstance(0, &pOutParams))){
  870. pOutClass->Release();
  871. //Get PackageLocation
  872. if(SUCCEEDED(hrReturn = GetProperty(pInParams, "PackageLocation", &bstrPackage))){
  873. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_bstrPackage ( bstrPackage ) ;
  874. if((wcscmp(bstrPackage, L"") != 0) &&
  875. (wcslen(bstrPackage) <= INTERNET_MAX_PATH_LENGTH)){
  876. //Get Options
  877. if ( SUCCEEDED ( hrReturn = GetProperty ( pInParams, "Options", &wcBuf ) ) )
  878. {
  879. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_wcBuf ( wcBuf ) ;
  880. //Make sure we perform an advertisement
  881. wcscpy(wcOptions, L"ACTION=INSTALL ALLUSERS=1");
  882. if( wcBuf && wcscmp ( wcBuf, L"" ) != 0 )
  883. {
  884. if ( wcslen ( wcOptions ) + wcslen ( L" ") + SysStringLen ( wcBuf ) + 1 < dwOptions )
  885. {
  886. wcscat(wcOptions, L" ");
  887. wcscat(wcOptions, wcBuf);
  888. }
  889. else
  890. {
  891. LPWSTR wsz = NULL;
  892. try
  893. {
  894. if ( ( wsz = new WCHAR [ wcslen ( wcOptions ) + wcslen ( L" ") + SysStringLen ( wcBuf ) + 1 ] ) != NULL )
  895. {
  896. wcscpy(wsz, wcOptions);
  897. wcscat(wsz, L" ");
  898. wcscat(wsz, wcBuf);
  899. if ( wcOptions )
  900. {
  901. delete [] wcOptions;
  902. wcOptions = NULL;
  903. }
  904. wcOptions = wsz;
  905. }
  906. else
  907. {
  908. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  909. }
  910. }
  911. catch ( ... )
  912. {
  913. if ( wsz )
  914. {
  915. delete [] wsz;
  916. wsz = NULL;
  917. }
  918. if ( wcOptions )
  919. {
  920. delete [] wcOptions;
  921. wcOptions = NULL;
  922. }
  923. hrReturn = E_OUTOFMEMORY;
  924. }
  925. }
  926. }
  927. if(hrReturn == WBEM_S_NO_ERROR){
  928. //We want to call MSI ourselves unless we are on NT4
  929. // and dealing with a user install.
  930. if(!IsNT4()){
  931. if ( msidata.Lock () )
  932. {
  933. INSTALLUI_HANDLER ui = NULL;
  934. //Set UI Level w/ event callback
  935. ui = SetupExternalUI ( );
  936. try
  937. {
  938. //Call Installer
  939. uiStatus = g_fpMsiInstallProductW(bstrPackage, wcOptions);
  940. }
  941. catch(...)
  942. {
  943. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  944. }
  945. //Restore UI Level w/ event callback
  946. RestoreExternalUI ( ui );
  947. msidata. Unlock();
  948. }
  949. }else{
  950. /////////////////
  951. // NT4 fix code....
  952. try{
  953. WCHAR wcAction[20];
  954. wcscpy(wcAction, L"/install");
  955. LPWSTR wcCommandLine = NULL;
  956. try
  957. {
  958. if ( ( wcCommandLine = new WCHAR [ wcslen ( bstrPackage ) + 1 + wcslen ( wcOptions ) + 1 ] ) != NULL )
  959. {
  960. wcscpy(wcCommandLine, bstrPackage);
  961. wcscat(wcCommandLine, L" ");
  962. wcscat(wcCommandLine, wcOptions);
  963. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  964. delete [] wcCommandLine;
  965. }
  966. else
  967. {
  968. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  969. }
  970. }
  971. catch ( ... )
  972. {
  973. if ( wcCommandLine )
  974. {
  975. delete [] wcCommandLine;
  976. wcCommandLine = NULL;
  977. }
  978. hrReturn = E_OUTOFMEMORY;
  979. }
  980. }catch(...){
  981. hrReturn = WBEM_E_FAILED;
  982. }
  983. ////////////////////
  984. }
  985. if(SUCCEEDED(hrReturn)){
  986. //Set up ReturnValue
  987. VariantInit(&v);
  988. V_VT(&v) = VT_I4;
  989. V_I4(&v) = uiStatus;
  990. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  991. if(!bstrReturnValue)
  992. {
  993. delete [] wcOptions;
  994. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  995. }
  996. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  997. &v, NULL)))
  998. pHandler->Indicate(1, &pOutParams);
  999. SysFreeString(bstrReturnValue);
  1000. }
  1001. }
  1002. }
  1003. }else
  1004. hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1005. }
  1006. pOutParams->Release();
  1007. }else
  1008. pOutClass->Release();
  1009. }else{
  1010. pClass->Release();
  1011. SysFreeString(bstrInstall);
  1012. }
  1013. }
  1014. if ( wcOptions )
  1015. {
  1016. delete [] wcOptions;
  1017. wcOptions = NULL;
  1018. }
  1019. return hrReturn;
  1020. }
  1021. HRESULT CProduct::Reinstall(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  1022. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  1023. {
  1024. HRESULT hrReturn = WBEM_S_NO_ERROR;
  1025. int iMode;
  1026. UINT uiStatus = 1603;
  1027. WCHAR wcCode[BUFF_SIZE];
  1028. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  1029. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1030. BSTR bstrReinstall = SysAllocString(L"Reinstall");
  1031. if(!bstrReinstall)
  1032. {
  1033. ::SysFreeString (bstrReturnValue);
  1034. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1035. }
  1036. IWbemClassObject *pClass = NULL;
  1037. IWbemClassObject *pOutClass = NULL;
  1038. IWbemClassObject *pOutParams = NULL;
  1039. VARIANT v;
  1040. DWORD dwMode;
  1041. int i = -1;
  1042. bool bFoundCode = false;
  1043. m_pRequest = pReqObj;
  1044. LPWSTR wcOptions = NULL;
  1045. DWORD dwOptions = BUFF_SIZE;
  1046. try
  1047. {
  1048. if ( ( wcOptions = new WCHAR [ dwOptions ] ) == NULL )
  1049. {
  1050. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1051. }
  1052. }
  1053. catch ( ... )
  1054. {
  1055. if ( wcOptions )
  1056. {
  1057. delete [] wcOptions;
  1058. wcOptions = NULL;
  1059. }
  1060. throw;
  1061. }
  1062. if(SUCCEEDED(hrReturn = m_pRequest->m_pNamespace->GetObject(m_pRequest->m_bstrClass,
  1063. 0, pCtx, &pClass, NULL))){
  1064. if(SUCCEEDED(hrReturn = pClass->GetMethod(bstrReinstall, 0, NULL, &pOutClass))){
  1065. if(SUCCEEDED(hrReturn = pOutClass->SpawnInstance(0, &pOutParams))){
  1066. //Get Reinstall Mode
  1067. if(SUCCEEDED(GetProperty(pInParams, "ReinstallMode", &iMode))){
  1068. //Get the Product Code
  1069. while(pReqObj->m_Property[++i])
  1070. {
  1071. if(wcscmp(pReqObj->m_Property[i], L"IdentifyingNumber") == 0)
  1072. {
  1073. if ( wcslen ( pReqObj->m_Value[i] ) < BUFF_SIZE )
  1074. {
  1075. wcscpy(wcCode, pReqObj->m_Value[i]);
  1076. bFoundCode = true;
  1077. }
  1078. }
  1079. }
  1080. if(bFoundCode){
  1081. //Get the appropriate ReinstallMode
  1082. switch(iMode){
  1083. case 1:
  1084. dwMode = REINSTALLMODE_FILEMISSING;
  1085. break;
  1086. case 2:
  1087. dwMode = REINSTALLMODE_FILEOLDERVERSION;
  1088. break;
  1089. case 3:
  1090. dwMode = REINSTALLMODE_FILEEQUALVERSION;
  1091. break;
  1092. case 4:
  1093. dwMode = REINSTALLMODE_FILEEXACT;
  1094. break;
  1095. case 5:
  1096. dwMode = REINSTALLMODE_FILEVERIFY;
  1097. break;
  1098. case 6:
  1099. dwMode = REINSTALLMODE_FILEREPLACE;
  1100. break;
  1101. case 7:
  1102. dwMode = REINSTALLMODE_USERDATA;
  1103. break;
  1104. case 8:
  1105. dwMode = REINSTALLMODE_MACHINEDATA;
  1106. break;
  1107. case 9:
  1108. dwMode = REINSTALLMODE_SHORTCUT;
  1109. break;
  1110. case 10:
  1111. dwMode = REINSTALLMODE_PACKAGE;
  1112. break;
  1113. default:
  1114. dwMode = NULL;
  1115. break;
  1116. }
  1117. //If everything is valid, proceed
  1118. if ( dwMode && hrReturn == WBEM_S_NO_ERROR )
  1119. {
  1120. if(!IsNT4()){
  1121. if ( msidata.Lock () )
  1122. {
  1123. INSTALLUI_HANDLER ui = NULL;
  1124. //Set UI Level w/ event callback
  1125. ui = SetupExternalUI ( );
  1126. try
  1127. {
  1128. //Call Installer
  1129. uiStatus = g_fpMsiReinstallProductW(wcCode, dwMode);
  1130. }
  1131. catch(...)
  1132. {
  1133. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  1134. }
  1135. //Restore UI Level w/ event callback
  1136. RestoreExternalUI ( ui );
  1137. msidata. Unlock();
  1138. }
  1139. }else{
  1140. /////////////////
  1141. // NT4 fix code....
  1142. try{
  1143. WCHAR wcAction[20];
  1144. wcscpy(wcAction, L"/reinstall");
  1145. WCHAR wcTmp[100];
  1146. _itow((int)dwMode, wcTmp, 10);
  1147. LPWSTR wcCommandLine = NULL;
  1148. try
  1149. {
  1150. if ( ( wcCommandLine = new WCHAR [ wcslen ( wcCode ) + 1 + wcslen ( wcTmp ) + 1 ] ) != NULL )
  1151. {
  1152. wcscpy(wcCommandLine, wcCode);
  1153. wcscat(wcCommandLine, L" ");
  1154. wcscat(wcCommandLine, wcTmp);
  1155. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  1156. delete [] wcCommandLine;
  1157. }
  1158. else
  1159. {
  1160. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1161. }
  1162. }
  1163. catch ( ... )
  1164. {
  1165. if ( wcCommandLine )
  1166. {
  1167. delete [] wcCommandLine;
  1168. wcCommandLine = NULL;
  1169. }
  1170. hrReturn = E_OUTOFMEMORY;
  1171. }
  1172. }catch(...){
  1173. hrReturn = WBEM_E_FAILED;
  1174. }
  1175. ////////////////////
  1176. }
  1177. if(SUCCEEDED(hrReturn)){
  1178. //Set up ReturnValue
  1179. VariantInit(&v);
  1180. V_VT(&v) = VT_I4;
  1181. V_I4(&v) = uiStatus;
  1182. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  1183. if(!bstrReturnValue)
  1184. {
  1185. delete [] wcOptions;
  1186. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1187. }
  1188. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  1189. &v, NULL)))
  1190. pHandler->Indicate(1, &pOutParams);
  1191. SysFreeString(bstrReturnValue);
  1192. }
  1193. }else return WBEM_E_INVALID_METHOD_PARAMETERS;
  1194. }else hrReturn = WBEM_E_FAILED;
  1195. pOutParams->Release();
  1196. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1197. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1198. pOutClass->Release();
  1199. }
  1200. pClass->Release();
  1201. }
  1202. if ( wcOptions )
  1203. {
  1204. delete [] wcOptions;
  1205. wcOptions = NULL;
  1206. }
  1207. SysFreeString(bstrReinstall);
  1208. return hrReturn;
  1209. }
  1210. HRESULT CProduct::Uninstall(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  1211. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  1212. {
  1213. HRESULT hrReturn = WBEM_S_NO_ERROR;
  1214. UINT uiStatus = 1603;
  1215. WCHAR wcCode[BUFF_SIZE];
  1216. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  1217. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1218. BSTR bstrConfigure = SysAllocString(L"Configure");
  1219. if(!bstrConfigure)
  1220. {
  1221. ::SysFreeString (bstrReturnValue);
  1222. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1223. }
  1224. IWbemClassObject *pClass = NULL;
  1225. IWbemClassObject *pOutClass = NULL;
  1226. IWbemClassObject *pOutParams = NULL;
  1227. VARIANT v;
  1228. int i = -1;
  1229. bool bFoundCode = false;
  1230. m_pRequest = pReqObj;
  1231. LPWSTR wcOptions = NULL;
  1232. DWORD dwOptions = BUFF_SIZE;
  1233. try
  1234. {
  1235. if ( ( wcOptions = new WCHAR [ dwOptions ] ) == NULL )
  1236. {
  1237. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1238. }
  1239. }
  1240. catch ( ... )
  1241. {
  1242. if ( wcOptions )
  1243. {
  1244. delete [] wcOptions;
  1245. wcOptions = NULL;
  1246. }
  1247. throw;
  1248. }
  1249. if(SUCCEEDED(hrReturn = m_pRequest->m_pNamespace->GetObject(m_pRequest->m_bstrClass,
  1250. 0, pCtx, &pClass, NULL))){
  1251. if(SUCCEEDED(hrReturn = pClass->GetMethod(bstrConfigure, 0, NULL, &pOutClass))){
  1252. if(SUCCEEDED(hrReturn = pOutClass->SpawnInstance(0, &pOutParams))){
  1253. //Get the Product Code
  1254. while(pReqObj->m_Property[++i])
  1255. {
  1256. if(wcscmp(pReqObj->m_Property[i], L"IdentifyingNumber") == 0)
  1257. {
  1258. if ( wcslen ( pReqObj->m_Value[i] ) < BUFF_SIZE )
  1259. {
  1260. wcscpy(wcCode, pReqObj->m_Value[i]);
  1261. bFoundCode = true;
  1262. }
  1263. }
  1264. }
  1265. if(bFoundCode){
  1266. //If everything is valid, proceed
  1267. if(hrReturn == WBEM_S_NO_ERROR){
  1268. if(!IsNT4()){
  1269. if ( msidata.Lock () )
  1270. {
  1271. INSTALLUI_HANDLER ui = NULL;
  1272. //Set UI Level w/ event callback
  1273. ui = SetupExternalUI ( );
  1274. try
  1275. {
  1276. //Call Installer
  1277. uiStatus = g_fpMsiConfigureProductW(wcCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT);
  1278. }
  1279. catch(...)
  1280. {
  1281. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  1282. }
  1283. //Restore UI Level w/ event callback
  1284. RestoreExternalUI ( ui );
  1285. msidata. Unlock();
  1286. }
  1287. }else{
  1288. /////////////////
  1289. // NT4 fix code....
  1290. try{
  1291. WCHAR wcAction[20];
  1292. wcscpy(wcAction, L"/uninstall");
  1293. LPWSTR wcCommandLine = NULL;
  1294. try
  1295. {
  1296. if ( ( wcCommandLine = new WCHAR [ wcslen ( wcCode ) + 1 ] ) != NULL )
  1297. {
  1298. wcscpy(wcCommandLine, wcCode);
  1299. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  1300. delete [] wcCommandLine;
  1301. }
  1302. else
  1303. {
  1304. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1305. }
  1306. }
  1307. catch ( ... )
  1308. {
  1309. if ( wcCommandLine )
  1310. {
  1311. delete [] wcCommandLine;
  1312. wcCommandLine = NULL;
  1313. }
  1314. hrReturn = E_OUTOFMEMORY;
  1315. }
  1316. }catch(...){
  1317. hrReturn = WBEM_E_FAILED;
  1318. }
  1319. ////////////////////
  1320. }
  1321. if(SUCCEEDED(hrReturn)){
  1322. //Set up ReturnValue
  1323. VariantInit(&v);
  1324. V_VT(&v) = VT_I4;
  1325. V_I4(&v) = uiStatus;
  1326. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  1327. if(!bstrReturnValue)
  1328. {
  1329. delete [] wcOptions;
  1330. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1331. }
  1332. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  1333. &v, NULL)))
  1334. pHandler->Indicate(1, &pOutParams);
  1335. SysFreeString(bstrReturnValue);
  1336. }
  1337. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1338. }else hrReturn = WBEM_E_FAILED;
  1339. pOutParams->Release();
  1340. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1341. pOutClass->Release();
  1342. }
  1343. pClass->Release();
  1344. }
  1345. if ( wcOptions )
  1346. {
  1347. delete [] wcOptions;
  1348. wcOptions = NULL;
  1349. }
  1350. SysFreeString(bstrConfigure);
  1351. return hrReturn;
  1352. }
  1353. HRESULT CProduct::Upgrade(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  1354. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  1355. {
  1356. HRESULT hrReturn = WBEM_S_NO_ERROR;
  1357. BSTR bstrPackage = NULL;
  1358. BSTR wcOptions = NULL;
  1359. UINT uiStatus = 1603;
  1360. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  1361. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1362. BSTR bstrUpgrade = SysAllocString(L"Upgrade");
  1363. if(!bstrUpgrade)
  1364. {
  1365. ::SysFreeString (bstrReturnValue);
  1366. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1367. }
  1368. IWbemClassObject *pClass = NULL;
  1369. IWbemClassObject *pOutClass = NULL;
  1370. IWbemClassObject *pOutParams = NULL;
  1371. VARIANT v;
  1372. m_pRequest = pReqObj;
  1373. if(SUCCEEDED(hrReturn = m_pRequest->m_pNamespace->GetObject(m_pRequest->m_bstrClass,
  1374. 0, pCtx, &pClass, NULL))){
  1375. if(SUCCEEDED(hrReturn = pClass->GetMethod(bstrUpgrade, 0, NULL, &pOutClass))){
  1376. if(SUCCEEDED(hrReturn = pOutClass->SpawnInstance(0, &pOutParams))){
  1377. //Get PackageLocation
  1378. if(SUCCEEDED(GetProperty(pInParams, "PackageLocation", &bstrPackage))){
  1379. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_bstrPackage ( bstrPackage ) ;
  1380. if((wcscmp(bstrPackage, L"") != 0) && (wcslen(bstrPackage) <= INTERNET_MAX_PATH_LENGTH)){
  1381. //Get Options
  1382. if ( SUCCEEDED ( GetProperty ( pInParams, "Options", &wcOptions ) ) )
  1383. {
  1384. OnDelete < BSTR, void ( * ) ( BSTR ), SysFreeString > del_wcOptions ( wcOptions ) ;
  1385. if(hrReturn == WBEM_S_NO_ERROR){
  1386. if(!IsNT4()){
  1387. if ( msidata.Lock () )
  1388. {
  1389. INSTALLUI_HANDLER ui = NULL;
  1390. //Set UI Level w/ event callback
  1391. ui = SetupExternalUI ( );
  1392. try
  1393. {
  1394. //Call Installer
  1395. if ( wcOptions && wcscmp ( wcOptions, L"" ) != 0 )
  1396. {
  1397. uiStatus = g_fpMsiApplyPatchW(bstrPackage, NULL, INSTALLTYPE_DEFAULT, wcOptions);
  1398. }
  1399. else
  1400. {
  1401. uiStatus = g_fpMsiApplyPatchW(bstrPackage, NULL, INSTALLTYPE_DEFAULT, NULL);
  1402. }
  1403. }
  1404. catch(...)
  1405. {
  1406. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  1407. }
  1408. //Restore UI Level w/ event callback
  1409. RestoreExternalUI ( ui );
  1410. msidata. Unlock();
  1411. }
  1412. }else{
  1413. /////////////////
  1414. // NT4 fix code....
  1415. try{
  1416. WCHAR wcAction[20];
  1417. wcscpy(wcAction, L"/upgrade");
  1418. LPWSTR wcCommandLine = NULL;
  1419. try
  1420. {
  1421. if ( ( wcCommandLine = new WCHAR [ wcslen ( bstrPackage ) + 1 + wcslen ( wcOptions ) + 1 ] ) != NULL )
  1422. {
  1423. wcscpy(wcCommandLine, bstrPackage);
  1424. wcscat(wcCommandLine, L" ");
  1425. wcscat(wcCommandLine, wcOptions);
  1426. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  1427. delete [] wcCommandLine;
  1428. }
  1429. else
  1430. {
  1431. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1432. }
  1433. }
  1434. catch ( ... )
  1435. {
  1436. if ( wcCommandLine )
  1437. {
  1438. delete [] wcCommandLine;
  1439. wcCommandLine = NULL;
  1440. }
  1441. hrReturn = E_OUTOFMEMORY;
  1442. }
  1443. }catch(...){
  1444. hrReturn = WBEM_E_FAILED;
  1445. }
  1446. ////////////////////
  1447. }
  1448. if(SUCCEEDED(hrReturn)){
  1449. //Set up ReturnValue
  1450. VariantInit(&v);
  1451. V_VT(&v) = VT_I4;
  1452. V_I4(&v) = uiStatus;
  1453. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  1454. if(!bstrReturnValue)
  1455. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1456. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  1457. &v, NULL)))
  1458. pHandler->Indicate(1, &pOutParams);
  1459. SysFreeString(bstrReturnValue);
  1460. }
  1461. }
  1462. }else
  1463. hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1464. }else
  1465. hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1466. }else
  1467. hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  1468. pOutParams->Release();
  1469. }
  1470. pOutClass->Release();
  1471. }
  1472. pClass->Release();
  1473. }
  1474. SysFreeString(bstrUpgrade);
  1475. return hrReturn;
  1476. }