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.

673 lines
20 KiB

  1. // SoftwareFeature.cpp: implementation of the CSoftwareFeature class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. ////////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "SoftwareFeature.h"
  8. //////////////////////////////////////////////////////////////////////
  9. // Construction/Destruction
  10. //////////////////////////////////////////////////////////////////////
  11. CSoftwareFeature::CSoftwareFeature(CRequestObject *pObj, IWbemServices *pNamespace,
  12. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  13. {
  14. }
  15. CSoftwareFeature::~CSoftwareFeature()
  16. {
  17. }
  18. HRESULT CSoftwareFeature::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  19. {
  20. HRESULT hr = WBEM_S_NO_ERROR;
  21. int i = -1;
  22. int iEnum;
  23. long lDate;
  24. WCHAR wcBuf[BUFF_SIZE];
  25. WCHAR wcName[BUFF_SIZE];
  26. WCHAR wcParent[BUFF_SIZE];
  27. WCHAR wcDesc[BUFF_SIZE];
  28. #if !defined(_UNICODE)
  29. WCHAR wcTmp[BUFF_SIZE];
  30. #endif
  31. WCHAR wcProductCode[39];
  32. DWORD dwBufSize;
  33. DWORD dwBufSize2;
  34. DWORD dwCount;
  35. DWORD dwAttrib;
  36. WORD wDate;
  37. bool bMatch = false;
  38. UINT uiStatus;
  39. //These will change from class to class
  40. bool bFeature, bName, bVersion = false , bIDNum, bProductHandle;
  41. INSTALLSTATE piInstalled;
  42. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED)){
  43. wcscpy(wcProductCode, m_pRequest->Package(i));
  44. //Open our database
  45. try
  46. {
  47. if ( GetView ( NULL, wcProductCode, NULL, NULL, FALSE, TRUE ) )
  48. {
  49. bProductHandle = true;
  50. }
  51. else
  52. {
  53. bProductHandle = false;
  54. }
  55. iEnum = 0;
  56. // try to get available feature
  57. do
  58. {
  59. uiStatus = g_fpMsiEnumFeaturesW(wcProductCode, iEnum++, wcName, wcParent);
  60. }
  61. while ( uiStatus == ERROR_MORE_DATA );
  62. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  63. CheckMSI(uiStatus);
  64. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  65. //----------------------------------------------------
  66. dwBufSize = BUFF_SIZE;
  67. CheckMSI(g_fpMsiGetProductInfoW(wcProductCode,
  68. #if defined(_UNICODE)
  69. INSTALLPROPERTY_PRODUCTNAME
  70. #else
  71. TcharToWchar(INSTALLPROPERTY_PRODUCTNAME, wcTmp)
  72. #endif
  73. , wcBuf, &dwBufSize));
  74. PutKeyProperty(m_pObj, pProductName, wcBuf, &bName, m_pRequest);
  75. dwBufSize = BUFF_SIZE;
  76. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,
  77. #if defined(_UNICODE)
  78. INSTALLPROPERTY_VERSIONSTRING
  79. #else
  80. TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp)
  81. #endif
  82. , wcBuf, &dwBufSize))
  83. PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
  84. else{
  85. dwBufSize = BUFF_SIZE;
  86. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,
  87. #if defined(_UNICODE)
  88. INSTALLPROPERTY_VERSION
  89. #else
  90. TcharToWchar(INSTALLPROPERTY_VERSION, wcTmp)
  91. #endif
  92. , wcBuf, &dwBufSize))
  93. PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
  94. }
  95. if ( bProductHandle )
  96. {
  97. dwBufSize = BUFF_SIZE;
  98. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"Manufacturer", wcBuf, &dwBufSize));
  99. PutProperty(m_pObj, pVendor, wcBuf);
  100. dwBufSize = BUFF_SIZE;
  101. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"ProductVersion", wcBuf, &dwBufSize));
  102. PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
  103. }
  104. PutKeyProperty(m_pObj, pIdentifyingNumber, wcProductCode, &bIDNum, m_pRequest);
  105. dwBufSize = BUFF_SIZE;
  106. PutKeyProperty(m_pObj, pName, wcName, &bFeature, m_pRequest);
  107. //====================================================
  108. piInstalled = g_fpMsiQueryFeatureStateW(m_pRequest->Package(i), wcName);
  109. PutProperty(m_pObj, pInstallState, (int)piInstalled);
  110. if(ERROR_SUCCESS == g_fpMsiGetFeatureUsageW(wcProductCode, wcName, &dwCount, &wDate)){
  111. PutProperty(m_pObj, pAccesses, (int)dwCount);
  112. lDate = (1980 + ((wDate & 65024) >> 9)) * 10000;
  113. lDate += ((wDate & 480) >> 5) * 100;
  114. lDate += (wDate & 31 );
  115. //safe operation
  116. _ltow(lDate, wcBuf, 10);
  117. wcscat(wcBuf, L"******.000000+***");
  118. PutProperty(m_pObj, pLastUse, wcBuf);
  119. }
  120. if ( bProductHandle )
  121. {
  122. dwBufSize = dwBufSize2 = BUFF_SIZE;
  123. if ( ERROR_SUCCESS == g_fpMsiGetFeatureInfoW ( msidata.GetProduct (),
  124. wcName,
  125. &dwAttrib,
  126. wcBuf,
  127. &dwBufSize,
  128. wcDesc,
  129. &dwBufSize2
  130. )
  131. )
  132. {
  133. PutProperty(m_pObj, pDescription, wcDesc);
  134. PutProperty(m_pObj, pCaption, wcBuf);
  135. PutProperty(m_pObj, pAttributes, (int)dwAttrib);
  136. }
  137. else
  138. {
  139. PutProperty(m_pObj, pDescription, wcName);
  140. PutProperty(m_pObj, pCaption, wcName);
  141. }
  142. }
  143. else
  144. {
  145. PutProperty(m_pObj, pDescription, wcName);
  146. PutProperty(m_pObj, pCaption, wcName);
  147. }
  148. //----------------------------------------------------
  149. if(bFeature && bName && bVersion && bIDNum) bMatch = true;
  150. if((atAction != ACTIONTYPE_GET) || bMatch){
  151. hr = pHandler->Indicate(1, &m_pObj);
  152. }
  153. m_pObj->Release();
  154. m_pObj = NULL;
  155. // try to get available feature
  156. do
  157. {
  158. uiStatus = g_fpMsiEnumFeaturesW(wcProductCode, iEnum++, wcName, wcParent);
  159. }
  160. while ( uiStatus == ERROR_MORE_DATA );
  161. }
  162. }
  163. catch(...)
  164. {
  165. msidata.CloseProduct ();
  166. if(m_pObj)
  167. {
  168. m_pObj->Release();
  169. m_pObj = NULL;
  170. }
  171. throw;
  172. }
  173. msidata.CloseProduct ();
  174. }
  175. return hr;
  176. }
  177. bool CSoftwareFeature::CheckUsage(UINT uiStatus)
  178. {
  179. switch(uiStatus){
  180. case ERROR_BAD_CONFIGURATION:
  181. throw WBEM_E_FAILED;
  182. case ERROR_INSTALL_FAILURE:
  183. return false;
  184. case ERROR_SUCCESS:
  185. return true;
  186. default:
  187. return false;
  188. }
  189. return false;
  190. }
  191. HRESULT CSoftwareFeature::Configure(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  192. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  193. {
  194. HRESULT hr = WBEM_S_NO_ERROR;
  195. HRESULT hrReturn = WBEM_S_NO_ERROR;
  196. int iState;
  197. UINT uiStatus = 1603;
  198. WCHAR wcCode[BUFF_SIZE];
  199. WCHAR wcFeature[BUFF_SIZE];
  200. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  201. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  202. BSTR bstrConfigure = SysAllocString(L"Configure");
  203. if(!bstrConfigure)
  204. {
  205. ::SysFreeString (bstrReturnValue);
  206. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  207. }
  208. IWbemClassObject *pClass = NULL;
  209. IWbemClassObject *pOutClass = NULL;
  210. IWbemClassObject *pOutParams = NULL;
  211. VARIANT v;
  212. INSTALLSTATE isState;
  213. int i = -1;
  214. bool bFoundCode = false;
  215. bool bFoundFeature = false;
  216. if(SUCCEEDED(hr = pReqObj->m_pNamespace->GetObject(pReqObj->m_bstrClass, 0, pCtx, &pClass, NULL)))
  217. {
  218. if(SUCCEEDED(hr = pClass->GetMethod(bstrConfigure, 0, NULL, &pOutClass)))
  219. {
  220. if(SUCCEEDED(hr = pOutClass->SpawnInstance(0, &pOutParams)))
  221. {
  222. //Get PackageLocation
  223. if(!SUCCEEDED(GetProperty(pInParams, "InstallState", &iState)))
  224. hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  225. //Get the Product Code
  226. while(pReqObj->m_Property[++i])
  227. {
  228. if(wcscmp(pReqObj->m_Property[i], L"IdentifyingNumber") == 0)
  229. {
  230. if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
  231. {
  232. wcscpy(wcCode, pReqObj->m_Value[i]);
  233. bFoundCode = true;
  234. break;
  235. }
  236. }
  237. }
  238. //Get the Feature Name
  239. i = -1;
  240. while(pReqObj->m_Property[++i])
  241. {
  242. if(wcscmp(pReqObj->m_Property[i], L"Name") == 0)
  243. {
  244. if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
  245. {
  246. wcscpy(wcFeature, pReqObj->m_Value[i]);
  247. bFoundFeature = true;
  248. break;
  249. }
  250. }
  251. }
  252. if(bFoundCode && bFoundFeature){
  253. //Get the appropriate State
  254. switch(iState){
  255. case 1:
  256. isState = INSTALLSTATE_DEFAULT;
  257. break;
  258. case 2:
  259. isState = INSTALLSTATE_ADVERTISED;
  260. break;
  261. case 3:
  262. isState = INSTALLSTATE_LOCAL;
  263. break;
  264. case 4:
  265. isState = INSTALLSTATE_ABSENT;
  266. break;
  267. case 5:
  268. isState = INSTALLSTATE_SOURCE;
  269. break;
  270. default:
  271. isState = INSTALLSTATE_NOTUSED;
  272. break;
  273. }
  274. //If everything is valid, proceed
  275. if((isState != INSTALLSTATE_NOTUSED) && (hrReturn == WBEM_S_NO_ERROR)){
  276. if(!IsNT4()){
  277. if ( msidata.Lock () )
  278. {
  279. INSTALLUI_HANDLER ui = NULL;
  280. //Set UI Level w/ event callback
  281. ui = SetupExternalUI ( );
  282. try
  283. {
  284. //Call Installer
  285. uiStatus = g_fpMsiConfigureFeatureW(wcCode, wcFeature, isState);
  286. }
  287. catch(...)
  288. {
  289. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  290. }
  291. //Restore UI Level w/ event callback
  292. RestoreExternalUI ( ui );
  293. msidata. Unlock();
  294. }
  295. }else{
  296. /////////////////
  297. // NT4 fix code....
  298. try{
  299. WCHAR wcAction[20];
  300. wcscpy(wcAction, L"/sfconfigure");
  301. WCHAR wcTmp[100];
  302. _itow((int)isState, wcTmp, 10);
  303. LPWSTR wcCommandLine = NULL;
  304. try
  305. {
  306. if ( ( wcCommandLine = new WCHAR [ wcslen ( wcCode ) + wcslen ( wcFeature ) + 3 + wcslen ( wcTmp ) ] ) != NULL )
  307. {
  308. wcscpy(wcCommandLine, wcCode);
  309. wcscat(wcCommandLine, L" ");
  310. wcscat(wcCommandLine, wcFeature);
  311. wcscat(wcCommandLine, L" ");
  312. wcscat(wcCommandLine, wcTmp);
  313. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  314. delete [] wcCommandLine;
  315. }
  316. else
  317. {
  318. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  319. }
  320. }
  321. catch ( ... )
  322. {
  323. if ( wcCommandLine )
  324. {
  325. delete [] wcCommandLine;
  326. wcCommandLine = NULL;
  327. }
  328. hrReturn = E_OUTOFMEMORY;
  329. }
  330. }catch(...){
  331. hrReturn = WBEM_E_FAILED;
  332. }
  333. ////////////////////
  334. }
  335. if(SUCCEEDED(hrReturn)){
  336. //Set up ReturnValue
  337. VariantInit(&v);
  338. V_VT(&v) = VT_I4;
  339. V_I4(&v) = uiStatus;
  340. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  341. if(!bstrReturnValue)
  342. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  343. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  344. &v, NULL)))
  345. pHandler->Indicate(1, &pOutParams);
  346. SysFreeString(bstrReturnValue);
  347. }
  348. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  349. }else hr = WBEM_E_FAILED;
  350. pOutParams->Release();
  351. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  352. pOutClass->Release();
  353. }
  354. pClass->Release();
  355. }
  356. SysFreeString(bstrReturnValue);
  357. SysFreeString(bstrConfigure);
  358. return hrReturn;
  359. }
  360. HRESULT CSoftwareFeature::Reinstall(CRequestObject *pReqObj, IWbemClassObject *pInParams,
  361. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  362. {
  363. HRESULT hr = WBEM_S_NO_ERROR;
  364. HRESULT hrReturn = WBEM_S_NO_ERROR;
  365. int iMode;
  366. UINT uiStatus = 1603;
  367. WCHAR wcCode[BUFF_SIZE];
  368. WCHAR wcFeature[BUFF_SIZE];
  369. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  370. if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  371. BSTR bstrReinstall = SysAllocString(L"Reinstall");
  372. if(!bstrReinstall)
  373. {
  374. ::SysFreeString (bstrReturnValue);
  375. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  376. }
  377. IWbemClassObject *pClass = NULL;
  378. IWbemClassObject *pOutClass = NULL;
  379. IWbemClassObject *pOutParams = NULL;
  380. VARIANT v;
  381. DWORD dwMode;
  382. int i = -1;
  383. bool bFoundCode = false;
  384. bool bFoundFeature = false;
  385. if(SUCCEEDED(hr = pReqObj->m_pNamespace->GetObject(pReqObj->m_bstrClass, 0, pCtx, &pClass, NULL))){
  386. if(SUCCEEDED(hr = pClass->GetMethod(bstrReinstall, 0, NULL, &pOutClass))){
  387. if(SUCCEEDED(hr = pOutClass->SpawnInstance(0, &pOutParams))){
  388. //Get Reinstall Mode
  389. if(!SUCCEEDED(GetProperty(pInParams, "ReinstallMode", &iMode)))
  390. hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  391. //Get the Product Code
  392. while(pReqObj->m_Property[++i])
  393. {
  394. if(wcscmp(pReqObj->m_Property[i], L"IdentifyingNumber") == 0)
  395. {
  396. if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
  397. {
  398. wcscpy(wcCode, pReqObj->m_Value[i]);
  399. bFoundCode = true;
  400. break;
  401. }
  402. }
  403. }
  404. //Get the Feature Name
  405. i = -1;
  406. while(pReqObj->m_Property[++i])
  407. {
  408. if(wcscmp(pReqObj->m_Property[i], L"Name") == 0)
  409. {
  410. if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
  411. {
  412. wcscpy(wcFeature, pReqObj->m_Value[i]);
  413. bFoundFeature = true;
  414. break;
  415. }
  416. }
  417. }
  418. if(bFoundCode && bFoundFeature){
  419. //Get the appropriate ReinstallMode
  420. switch(iMode){
  421. case 1:
  422. dwMode = REINSTALLMODE_FILEMISSING;
  423. break;
  424. case 2:
  425. dwMode = REINSTALLMODE_FILEOLDERVERSION;
  426. break;
  427. case 3:
  428. dwMode = REINSTALLMODE_FILEEQUALVERSION;
  429. break;
  430. case 4:
  431. dwMode = REINSTALLMODE_FILEEXACT;
  432. break;
  433. case 5:
  434. dwMode = REINSTALLMODE_FILEVERIFY;
  435. break;
  436. case 6:
  437. dwMode = REINSTALLMODE_FILEREPLACE;
  438. break;
  439. case 7:
  440. dwMode = REINSTALLMODE_USERDATA;
  441. break;
  442. case 8:
  443. dwMode = REINSTALLMODE_MACHINEDATA;
  444. break;
  445. case 9:
  446. dwMode = REINSTALLMODE_SHORTCUT;
  447. break;
  448. case 10:
  449. dwMode = REINSTALLMODE_PACKAGE;
  450. break;
  451. default:
  452. dwMode = NULL;
  453. break;
  454. }
  455. //If everything is valid, proceed
  456. if ( dwMode && hrReturn == WBEM_S_NO_ERROR )
  457. {
  458. if(!IsNT4()){
  459. if ( msidata.Lock () )
  460. {
  461. INSTALLUI_HANDLER ui = NULL;
  462. //Set UI Level w/ event callback
  463. ui = SetupExternalUI ( );
  464. try
  465. {
  466. //Call Installer
  467. uiStatus = g_fpMsiReinstallFeatureW(wcCode, wcFeature, dwMode);
  468. }
  469. catch(...)
  470. {
  471. uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
  472. }
  473. //Restore UI Level w/ event callback
  474. RestoreExternalUI ( ui );
  475. msidata. Unlock();
  476. }
  477. }else{
  478. /////////////////
  479. // NT4 fix code....
  480. try{
  481. WCHAR wcAction[20];
  482. wcscpy(wcAction, L"/sfreinstall");
  483. WCHAR wcTmp[100];
  484. _itow((int)dwMode, wcTmp, 10);
  485. LPWSTR wcCommandLine = NULL;
  486. try
  487. {
  488. if ( ( wcCommandLine = new WCHAR [ wcslen ( wcCode ) + wcslen ( wcFeature ) + 3 + wcslen ( wcTmp ) ] ) != NULL )
  489. {
  490. wcscpy(wcCommandLine, wcCode);
  491. wcscat(wcCommandLine, L" ");
  492. wcscat(wcCommandLine, wcFeature);
  493. wcscat(wcCommandLine, L" ");
  494. wcscat(wcCommandLine, wcTmp);
  495. hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
  496. delete [] wcCommandLine;
  497. }
  498. else
  499. {
  500. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  501. }
  502. }
  503. catch ( ... )
  504. {
  505. if ( wcCommandLine )
  506. {
  507. delete [] wcCommandLine;
  508. wcCommandLine = NULL;
  509. }
  510. hrReturn = E_OUTOFMEMORY;
  511. }
  512. }catch(...){
  513. hrReturn = WBEM_E_FAILED;
  514. }
  515. ////////////////////
  516. }
  517. if(SUCCEEDED(hrReturn)){
  518. //Set up ReturnValue
  519. VariantInit(&v);
  520. V_VT(&v) = VT_I4;
  521. V_I4(&v) = uiStatus;
  522. BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
  523. if(!bstrReturnValue)
  524. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  525. if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
  526. &v, NULL)))
  527. pHandler->Indicate(1, &pOutParams);
  528. SysFreeString(bstrReturnValue);
  529. }
  530. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  531. }else hr = WBEM_E_FAILED;
  532. pOutParams->Release();
  533. }else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
  534. pOutClass->Release();
  535. }
  536. pClass->Release();
  537. }
  538. SysFreeString(bstrReturnValue);
  539. SysFreeString(bstrReinstall);
  540. return hrReturn;
  541. }