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.

915 lines
21 KiB

  1. // Utils.cpp: implementation of the CGenericClass class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. char * WcharToTchar(WCHAR * wcPtr, char * tcTmp)
  8. {
  9. WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcPtr, (-1), tcTmp, BUFF_SIZE, NULL, NULL);
  10. return tcTmp;
  11. }
  12. WCHAR * TcharToWchar(char * tcPtr, WCHAR * wcTmp)
  13. {
  14. MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, tcPtr, (-1), wcTmp, BUFF_SIZE);
  15. return wcTmp;
  16. }
  17. WCHAR * TcharToWchar(const char * tcPtr, WCHAR * wcTmp)
  18. {
  19. MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, tcPtr, (-1), wcTmp, BUFF_SIZE);
  20. return wcTmp;
  21. }
  22. HRESULT ConvertError(UINT uiStatus)
  23. {
  24. switch(uiStatus){
  25. case ERROR_INSTALL_ALREADY_RUNNING:
  26. return WBEM_E_ACCESS_DENIED;
  27. case ERROR_ACCESS_DENIED:
  28. return WBEM_E_PRIVILEGE_NOT_HELD;
  29. case E_OUTOFMEMORY:
  30. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  31. return WBEM_E_OUT_OF_MEMORY;
  32. default:
  33. return WBEM_E_FAILED;
  34. }
  35. }
  36. WCHAR * EscapeStringW(WCHAR * wcIn, WCHAR * wcOut)
  37. {
  38. wcOut [ 0 ] = 0;
  39. DWORD dwLenghtIn = 0L;
  40. dwLenghtIn = lstrlenW ( wcIn );
  41. WCHAR wcTmp[BUFF_SIZE] = { L'\0' };
  42. wcscpy(wcTmp, wcIn);
  43. WCHAR * wcp = wcTmp;
  44. DWORD dwNumber = 0L;
  45. while ( *wcp )
  46. {
  47. if ( *wcp == L'\\' || *wcp == L'\"' )
  48. {
  49. dwNumber++;
  50. }
  51. wcp++;
  52. }
  53. if ( BUFF_SIZE > ( dwLenghtIn + dwNumber * 2 ) )
  54. {
  55. wcp = wcTmp;
  56. while ( *wcp )
  57. {
  58. switch ( *wcp )
  59. {
  60. case L'\\':
  61. *wcp = NULL;
  62. wcscpy(wcOut, wcTmp);
  63. wcscat(wcOut, L"\\\\");
  64. wcscat(wcOut, (wcp + 1));
  65. wcscpy(wcTmp, wcOut);
  66. wcp++;
  67. break;
  68. case L'\"':
  69. *wcp = NULL;
  70. wcscpy(wcOut, wcTmp);
  71. wcscat(wcOut, L"\\\"");
  72. wcscat(wcOut, (wcp + 1));
  73. wcscpy(wcTmp, wcOut);
  74. wcp++;
  75. break;
  76. default:
  77. break;
  78. }
  79. wcp++;
  80. }
  81. }
  82. return wcOut;
  83. }
  84. void SoftwareElementState(INSTALLSTATE piInstalled, int *iState)
  85. {
  86. switch(piInstalled){
  87. case INSTALLSTATE_ABSENT:
  88. *iState = 0;
  89. break;
  90. case INSTALLSTATE_BADCONFIG:
  91. *iState = 0;
  92. break;
  93. case INSTALLSTATE_INVALIDARG:
  94. *iState = 0;
  95. break;
  96. case INSTALLSTATE_LOCAL:
  97. *iState = 2;
  98. break;
  99. case INSTALLSTATE_SOURCE:
  100. *iState = 1;
  101. break;
  102. case INSTALLSTATE_SOURCEABSENT:
  103. *iState = 0;
  104. break;
  105. case INSTALLSTATE_UNKNOWN:
  106. *iState = 0;
  107. break;
  108. default:
  109. *iState = 0;
  110. }
  111. }
  112. // string am getting is BUF_SIZE ( statically allocated )
  113. bool CreateProductString(WCHAR *wcProductCode, WCHAR *wcProductPath)
  114. {
  115. DWORD dwBufSize;
  116. WCHAR wcBuf[BUFF_SIZE];
  117. #if !defined(_UNICODE)
  118. WCHAR wcTmp[BUFF_SIZE];
  119. #endif
  120. bool bResult = false;
  121. // safe operation
  122. wcscpy(wcProductPath, L"Win32_Product.IdentifyingNumber=\"");
  123. if ( wcslen ( wcProductPath ) +
  124. wcslen ( L"\",Name=\"" )
  125. < BUFF_SIZE
  126. )
  127. {
  128. wcscat(wcProductPath, wcProductCode);
  129. wcscat(wcProductPath, L"\",Name=\"");
  130. dwBufSize = BUFF_SIZE;
  131. #if defined(_UNICODE)
  132. if(g_fpMsiGetProductInfoW(wcProductCode, INSTALLPROPERTY_PRODUCTNAME,
  133. #else
  134. if(g_fpMsiGetProductInfoW(wcProductCode, TcharToWchar(INSTALLPROPERTY_PRODUCTNAME, wcTmp),
  135. #endif
  136. wcBuf, &dwBufSize) == ERROR_SUCCESS)
  137. {
  138. if ( wcslen (wcProductPath) +
  139. wcslen (wcBuf) +
  140. wcslen (L"\",Version=\"")
  141. < BUFF_SIZE
  142. )
  143. {
  144. wcscat(wcProductPath, wcBuf);
  145. wcscat(wcProductPath, L"\",Version=\"");
  146. dwBufSize = BUFF_SIZE;
  147. #if defined(_UNICODE)
  148. if(g_fpMsiGetProductInfoW(wcProductCode, INSTALLPROPERTY_VERSIONSTRING,
  149. #else
  150. if(g_fpMsiGetProductInfoW(wcProductCode, TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp),
  151. #endif
  152. wcBuf, &dwBufSize) == ERROR_SUCCESS)
  153. {
  154. if ( wcslen (wcProductPath) +
  155. wcslen (wcBuf) +
  156. 1
  157. < BUFF_SIZE
  158. )
  159. {
  160. wcscat(wcProductPath, wcBuf);
  161. wcscat(wcProductPath, L"\"");
  162. bResult = true;
  163. }
  164. }
  165. else
  166. {
  167. dwBufSize = BUFF_SIZE;
  168. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,
  169. #if defined(_UNICODE)
  170. INSTALLPROPERTY_VERSION, wcBuf, &dwBufSize))
  171. {
  172. #else
  173. TcharToWchar(INSTALLPROPERTY_VERSION, wcTmp), wcBuf, &dwBufSize))
  174. {
  175. #endif
  176. if ( wcslen (wcProductPath) +
  177. wcslen (wcBuf) +
  178. 1
  179. < BUFF_SIZE
  180. )
  181. {
  182. wcscat(wcProductPath, wcBuf);
  183. wcscat(wcProductPath, L"\"");
  184. bResult = true;
  185. }
  186. }
  187. }
  188. }
  189. }
  190. }
  191. return bResult;
  192. }
  193. DWORD CreateSoftwareElementString ( MSIHANDLE hDatabase, WCHAR *wcComponent, WCHAR *wcProductCode, WCHAR *wcPath, DWORD * dwPath )
  194. {
  195. DWORD dwResult = static_cast < DWORD > ( E_INVALIDARG );
  196. DWORD dwResultHelp = static_cast < DWORD > ( S_FALSE );
  197. #if !defined(_UNICODE)
  198. WCHAR wcTmp[BUFF_SIZE];
  199. #endif
  200. if ( wcComponent != NULL && wcComponent [ 0 ] != 0 )
  201. {
  202. MSIHANDLE hView = NULL;
  203. MSIHANDLE hRecord = NULL;
  204. DWORD dwBufSize = BUFF_SIZE;
  205. LPWSTR wcBuf = NULL;
  206. LPWSTR wcID = NULL;
  207. LPWSTR wcQuery = NULL;
  208. int iState = 0L;
  209. DWORD dwPathSize = 0;
  210. dwPathSize = * dwPath;
  211. DWORD dwUsed = 1; // last null
  212. try
  213. {
  214. if ( ( wcBuf = new WCHAR [ dwBufSize ] ) == NULL )
  215. {
  216. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  217. }
  218. if ( ( wcID = new WCHAR [ dwBufSize ] ) == NULL )
  219. {
  220. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  221. }
  222. LPCWSTR wszQuery = L"select distinct `ComponentId` from Component where `Component`=\'";
  223. DWORD dwQuery = 0L;
  224. dwQuery = lstrlenW ( wszQuery ) + lstrlenW ( wcComponent ) + 1 + 1;
  225. if ( ( wcQuery = new WCHAR [ dwQuery ] ) == NULL )
  226. {
  227. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  228. }
  229. wcscpy ( wcQuery, wszQuery );
  230. wcscat ( wcQuery, wcComponent );
  231. wcscat ( wcQuery, L"\'" );
  232. if ( ( dwResult = g_fpMsiDatabaseOpenViewW ( hDatabase, wcQuery, &hView ) ) == ERROR_SUCCESS )
  233. {
  234. if ( g_fpMsiViewExecute ( hView, 0 ) == ERROR_SUCCESS )
  235. {
  236. if ( g_fpMsiViewFetch ( hView, &hRecord ) != ERROR_NO_MORE_ITEMS )
  237. {
  238. dwBufSize = BUFF_SIZE;
  239. BOOL bContinue = TRUE;
  240. DWORD dwContinue= 2;
  241. do
  242. {
  243. if ( ( dwResult = g_fpMsiRecordGetStringW ( hRecord, 1, wcID, &dwBufSize ) ) == ERROR_MORE_DATA )
  244. {
  245. delete [] wcID;
  246. wcID = NULL;
  247. if ( ( wcID = new WCHAR [ dwBufSize ] ) == NULL )
  248. {
  249. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  250. }
  251. }
  252. else
  253. {
  254. bContinue = FALSE;
  255. }
  256. }
  257. while ( bContinue && dwContinue-- );
  258. if ( dwResult == ERROR_MORE_DATA )
  259. {
  260. dwResult = static_cast < DWORD > ( E_FAIL );
  261. }
  262. if ( dwResult == ERROR_SUCCESS && wcProductCode != NULL && wcProductCode [ 0 ] != 0 )
  263. {
  264. //Check to make sure it's on the system
  265. if ( ValidateComponentID ( wcID, wcProductCode ) )
  266. {
  267. dwUsed = dwUsed +
  268. lstrlenW ( L"Win32_SoftwareElement.Name=\"" ) +
  269. lstrlenW ( wcComponent ) +
  270. lstrlenW ( L"\",SoftwareElementID=\"" ) +
  271. lstrlenW ( wcID ) +
  272. lstrlenW ( L"\",SoftwareElementState=" );
  273. if ( dwUsed > dwPathSize )
  274. {
  275. dwResultHelp = ERROR_MORE_DATA;
  276. }
  277. else
  278. {
  279. wcscpy(wcPath, L"Win32_SoftwareElement.Name=\"");
  280. wcscat(wcPath, wcComponent);
  281. wcscat(wcPath, L"\",SoftwareElementID=\"");
  282. wcscat(wcPath, wcID);
  283. wcscat(wcPath, L"\",SoftwareElementState=");
  284. }
  285. SoftwareElementState ( g_fpMsiGetComponentPathW (
  286. wcProductCode,
  287. wcID,
  288. NULL,
  289. NULL
  290. ),
  291. &iState
  292. );
  293. _itow(iState, wcBuf, 10);
  294. dwUsed = dwUsed +
  295. lstrlenW ( wcBuf ) +
  296. lstrlenW ( L"\",SoftwareElementState=\"" );
  297. if ( dwUsed > dwPathSize )
  298. {
  299. dwResultHelp = ERROR_MORE_DATA;
  300. }
  301. else
  302. {
  303. wcscat(wcPath, wcBuf);
  304. wcscat(wcPath, L",TargetOperatingSystem=");
  305. }
  306. _itow(GetOS(), wcBuf, 10);
  307. dwUsed = dwUsed +
  308. lstrlenW ( wcBuf ) +
  309. lstrlenW ( L"\",SoftwareElementState=\"" );
  310. if ( dwUsed > dwPathSize )
  311. {
  312. dwResultHelp = ERROR_MORE_DATA;
  313. }
  314. else
  315. {
  316. wcscat(wcPath, wcBuf);
  317. wcscat(wcPath, L",Version=\"");
  318. }
  319. dwBufSize = BUFF_SIZE;
  320. wcBuf [0] = 0;
  321. bContinue = TRUE;
  322. dwContinue = 2;
  323. do
  324. {
  325. if ( ( dwResult = g_fpMsiGetProductInfoW ( wcProductCode,
  326. #ifdef _UNICODE
  327. INSTALLPROPERTY_VERSIONSTRING,
  328. #else _UNICODE
  329. TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp),
  330. #endif _UNICODE
  331. wcBuf,
  332. &dwBufSize
  333. )
  334. ) == ERROR_MORE_DATA
  335. )
  336. {
  337. delete [] wcBuf;
  338. wcBuf = NULL;
  339. if ( ( wcBuf = new WCHAR [ dwBufSize + 1 ] ) == NULL )
  340. {
  341. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  342. }
  343. dwBufSize = dwBufSize + 1;
  344. }
  345. else
  346. {
  347. bContinue = FALSE;
  348. }
  349. }
  350. while ( bContinue && dwContinue-- );
  351. if ( dwResult == ERROR_MORE_DATA )
  352. {
  353. dwResult = static_cast < DWORD > ( E_FAIL );
  354. }
  355. if ( dwResult == ERROR_SUCCESS )
  356. {
  357. dwUsed = dwUsed +
  358. lstrlenW ( wcBuf ) +
  359. lstrlenW ( L"\"" );
  360. if ( dwUsed > dwPathSize )
  361. {
  362. dwResultHelp = ERROR_MORE_DATA;
  363. }
  364. else
  365. {
  366. wcscat(wcPath, wcBuf);
  367. wcscat(wcPath, L"\"");
  368. dwResult = ERROR_SUCCESS;
  369. }
  370. }
  371. }
  372. else
  373. {
  374. dwResult = static_cast < DWORD > ( E_FAIL );
  375. }
  376. }
  377. }
  378. }
  379. }
  380. else
  381. {
  382. if ( dwResult == E_OUTOFMEMORY )
  383. {
  384. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  385. }
  386. }
  387. }
  388. catch ( ... )
  389. {
  390. if ( wcBuf )
  391. {
  392. delete [] wcBuf;
  393. wcBuf = NULL;
  394. }
  395. if ( wcID )
  396. {
  397. delete [] wcID;
  398. wcID = NULL;
  399. }
  400. if ( wcQuery )
  401. {
  402. delete [] wcQuery;
  403. wcQuery = NULL;
  404. }
  405. throw;
  406. }
  407. if ( wcBuf )
  408. {
  409. delete [] wcBuf;
  410. wcBuf = NULL;
  411. }
  412. if ( wcID )
  413. {
  414. delete [] wcID;
  415. wcID = NULL;
  416. }
  417. if ( wcQuery )
  418. {
  419. delete [] wcQuery;
  420. wcQuery = NULL;
  421. }
  422. g_fpMsiCloseHandle(hRecord);
  423. g_fpMsiViewClose(hView);
  424. g_fpMsiCloseHandle(hView);
  425. if ( dwResult == ERROR_SUCCESS && dwResultHelp == ERROR_MORE_DATA )
  426. {
  427. ( * dwPath ) = ( * dwPath ) + ( dwUsed - dwPathSize );
  428. wcPath [ 0 ] = 0;
  429. dwResult = dwResultHelp;
  430. }
  431. }
  432. return dwResult;
  433. }
  434. // string am getting is BUF_SIZE ( statically allocated )
  435. bool CreateSoftwareFeatureString(WCHAR *wcName, WCHAR *wcProductCode, WCHAR * wcString, bool bValidate)
  436. {
  437. bool bResult = false;
  438. DWORD dwBufSize;
  439. WCHAR wcBuf[BUFF_SIZE];
  440. #if !defined(_UNICODE)
  441. WCHAR wcTmp[BUFF_SIZE];
  442. #endif
  443. if((bValidate) && (!ValidateFeatureName(wcName, wcProductCode))) return bResult;
  444. // safe operation
  445. wcscpy(wcString, L"Win32_SoftwareFeature.IdentifyingNumber=\"");
  446. if ( wcslen ( wcString ) +
  447. wcslen ( L"\",Name=\"" ) +
  448. wcslen ( wcName ) +
  449. wcslen ( L"\",ProductName=\"" )
  450. < BUFF_SIZE
  451. )
  452. {
  453. wcscat(wcString, wcProductCode);
  454. wcscat(wcString, L"\",Name=\"");
  455. wcscat(wcString, wcName);
  456. wcscat(wcString, L"\",ProductName=\"");
  457. dwBufSize = BUFF_SIZE;
  458. if(g_fpMsiGetProductInfoW(wcProductCode,
  459. #if defined(_UNICODE)
  460. INSTALLPROPERTY_PRODUCTNAME,
  461. #else
  462. TcharToWchar(INSTALLPROPERTY_PRODUCTNAME, wcTmp),
  463. #endif
  464. wcBuf, &dwBufSize) == ERROR_SUCCESS)
  465. {
  466. if ( wcslen (wcString) +
  467. wcslen (wcBuf) +
  468. wcslen (L"\",Version=\"")
  469. < BUFF_SIZE
  470. )
  471. {
  472. wcscat(wcString, wcBuf);
  473. wcscat(wcString, L"\",Version=\"");
  474. dwBufSize = BUFF_SIZE;
  475. if(g_fpMsiGetProductInfoW(wcProductCode,
  476. #if defined(_UNICODE)
  477. INSTALLPROPERTY_VERSIONSTRING,
  478. #else
  479. TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp),
  480. #endif
  481. wcBuf, &dwBufSize) == ERROR_SUCCESS)
  482. {
  483. if ( wcslen (wcString) +
  484. wcslen (wcBuf) +
  485. 1
  486. < BUFF_SIZE
  487. )
  488. {
  489. wcscat(wcString, wcBuf);
  490. wcscat(wcString, L"\"");
  491. bResult = true;
  492. }
  493. }
  494. else
  495. {
  496. dwBufSize = BUFF_SIZE;
  497. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,
  498. #if defined(_UNICODE)
  499. INSTALLPROPERTY_VERSION
  500. #else
  501. TcharToWchar(INSTALLPROPERTY_VERSION, wcTmp)
  502. #endif
  503. , wcBuf, &dwBufSize))
  504. {
  505. if ( wcslen (wcString) +
  506. wcslen (wcBuf) +
  507. 1
  508. < BUFF_SIZE
  509. )
  510. {
  511. wcscat(wcString, wcBuf);
  512. wcscat(wcString, L"\"");
  513. bResult = true;
  514. }
  515. }
  516. }
  517. }
  518. }
  519. }
  520. return bResult;
  521. }
  522. // simple helper to ask the age old question
  523. // of what OS are we running on, anyway?
  524. bool AreWeOnNT()
  525. {
  526. OSVERSIONINFO osversion;
  527. osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  528. GetVersionEx(&osversion);
  529. return (osversion.dwPlatformId == VER_PLATFORM_WIN32_NT);
  530. }
  531. int GetOS()
  532. {
  533. OSVERSIONINFO osversion;
  534. int iOS = 19;
  535. osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  536. GetVersionEx(&osversion);
  537. if(osversion.dwPlatformId == VER_PLATFORM_WIN32s) iOS = 16;
  538. else if(osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS){
  539. if(osversion.dwMinorVersion == 0) iOS = 17;
  540. else iOS = 18;
  541. }
  542. return iOS;
  543. }
  544. bool IsNT4()
  545. {
  546. OSVERSIONINFO osversion;
  547. int iOS = 19;
  548. osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  549. GetVersionEx(&osversion);
  550. return osversion.dwMajorVersion == 4;
  551. }
  552. bool IsNT5()
  553. {
  554. OSVERSIONINFO osversion;
  555. int iOS = 19;
  556. osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  557. GetVersionEx(&osversion);
  558. return osversion.dwMajorVersion == 5;
  559. }
  560. // checks impersonation level
  561. // impersonates client if allowed
  562. HRESULT CheckImpersonationLevel()
  563. {
  564. HRESULT hr = WBEM_E_ACCESS_DENIED;
  565. if(AreWeOnNT()){
  566. if(SUCCEEDED(CoImpersonateClient())){
  567. // Now, let's check the impersonation level. First, get the thread token
  568. HANDLE hThreadTok;
  569. DWORD dwImp, dwBytesReturned;
  570. if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hThreadTok )){
  571. DWORD dwLastError = GetLastError();
  572. if (dwLastError == ERROR_NO_TOKEN){
  573. // If the CoImpersonate works, but the OpenThreadToken fails due to ERROR_NO_TOKEN, we
  574. // are running under the process token (either local system, or if we are running
  575. // with /exe, the rights of the logged in user). In either case, impersonation rights
  576. // don't apply. We have the full rights of that user.
  577. hr = WBEM_S_NO_ERROR;
  578. }else{
  579. // If we failed to get the thread token for any other reason, an error.
  580. hr = WBEM_E_ACCESS_DENIED;
  581. }
  582. }else{
  583. if(GetTokenInformation(hThreadTok, TokenImpersonationLevel, &dwImp,
  584. sizeof(DWORD), &dwBytesReturned)){
  585. // Is the impersonation level Impersonate?
  586. if (dwImp >= SecurityImpersonation) hr = WBEM_S_NO_ERROR;
  587. else hr = WBEM_E_ACCESS_DENIED;
  588. }else hr = WBEM_E_FAILED;
  589. CloseHandle(hThreadTok);
  590. }
  591. if (FAILED(hr))
  592. {
  593. CoRevertToSelf();
  594. }
  595. }
  596. }else
  597. // let win9X in...
  598. hr = WBEM_S_NO_ERROR;
  599. return hr;
  600. }
  601. bool ValidateComponentID(WCHAR *wcID, WCHAR *wcProductCode)
  602. {
  603. int i = 0;
  604. WCHAR * wcBuf = (WCHAR *)malloc(BUFF_SIZE * sizeof(WCHAR));
  605. if(!wcBuf)
  606. {
  607. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  608. }
  609. DWORD dwBufSize;
  610. UINT uiStatus;
  611. INSTALLSTATE isInstalled;
  612. bool bRetVal = false;
  613. dwBufSize = BUFF_SIZE;
  614. isInstalled = g_fpMsiGetComponentPathW(wcProductCode, wcID, wcBuf, &dwBufSize);
  615. // this lines are added for backward compatability ( ! INSTALLSTATE_NOTUSED )
  616. if( isInstalled == INSTALLSTATE_LOCAL ||
  617. isInstalled == INSTALLSTATE_SOURCE ||
  618. isInstalled == INSTALLSTATE_SOURCEABSENT ||
  619. isInstalled == INSTALLSTATE_UNKNOWN ||
  620. isInstalled == INSTALLSTATE_ABSENT
  621. )
  622. {
  623. bRetVal = true;
  624. }
  625. free((void *)wcBuf);
  626. return bRetVal;
  627. }
  628. bool ValidateComponentName ( MSIHANDLE hDatabase, WCHAR *wcProductCode, WCHAR *wcName )
  629. {
  630. bool bResult = false;
  631. if ( wcName != NULL )
  632. {
  633. MSIHANDLE hView = NULL;
  634. MSIHANDLE hRecord = NULL;
  635. LPWSTR wcQuery = NULL;
  636. LPWSTR wcBuf = NULL;
  637. LPCWSTR wszQuery = L"select distinct `ComponentId` from Component where `Component`=\'";
  638. DWORD dwBuf = BUFF_SIZE;
  639. DWORD dwQuery = 0L;
  640. dwQuery = wcslen ( wszQuery ) + wcslen ( wcName ) + 1 + 1;
  641. if ( ( wcQuery = new WCHAR [ dwQuery ] ) == NULL )
  642. {
  643. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  644. }
  645. try
  646. {
  647. wcscpy ( wcQuery, wszQuery );
  648. wcscat ( wcQuery, wcName );
  649. wcscat ( wcQuery, L"\'" );
  650. }
  651. catch ( ... )
  652. {
  653. delete [] wcQuery;
  654. wcQuery = NULL;
  655. throw;
  656. }
  657. try
  658. {
  659. if ( ( wcBuf = new WCHAR [ dwBuf ] ) == NULL )
  660. {
  661. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  662. }
  663. }
  664. catch ( ... )
  665. {
  666. delete [] wcQuery;
  667. wcQuery = NULL;
  668. throw;
  669. }
  670. HRESULT hRes = S_OK;
  671. if ( ERROR_SUCCESS == ( hRes = g_fpMsiDatabaseOpenViewW ( hDatabase, wcQuery, &hView ) ) )
  672. {
  673. if ( ERROR_SUCCESS == g_fpMsiViewExecute ( hView, 0 ) )
  674. {
  675. if ( ERROR_NO_MORE_ITEMS != ( hRes = g_fpMsiViewFetch ( hView, &hRecord ) ) )
  676. {
  677. if ( E_OUTOFMEMORY == hRes )
  678. {
  679. g_fpMsiCloseHandle(hRecord);
  680. g_fpMsiViewClose(hView);
  681. g_fpMsiCloseHandle(hView);
  682. delete [] wcBuf;
  683. delete [] wcQuery;
  684. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  685. }
  686. if ( ERROR_SUCCESS == g_fpMsiRecordGetStringW ( hRecord, 1, wcBuf, &dwBuf ) )
  687. {
  688. //Check to make sure it's on the system
  689. bResult = ValidateComponentID ( wcBuf, wcProductCode );
  690. }
  691. g_fpMsiCloseHandle(hRecord);
  692. }
  693. }
  694. g_fpMsiViewClose(hView);
  695. g_fpMsiCloseHandle(hView);
  696. }
  697. else
  698. {
  699. if ( E_OUTOFMEMORY == hRes )
  700. {
  701. delete [] wcBuf;
  702. delete [] wcQuery;
  703. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  704. }
  705. }
  706. delete [] wcBuf;
  707. delete [] wcQuery;
  708. }
  709. return bResult;
  710. }
  711. bool ValidateFeatureName(WCHAR *wcName, WCHAR *wcProduct)
  712. {
  713. int i = 0;
  714. bool bRetVal = false;
  715. WCHAR * wcBuf = (WCHAR *)malloc(BUFF_SIZE * sizeof(WCHAR));
  716. if(!wcBuf)
  717. {
  718. wcBuf = NULL;
  719. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  720. }
  721. WCHAR * wcParent = (WCHAR *)malloc(BUFF_SIZE * sizeof(WCHAR));
  722. if(!wcParent)
  723. {
  724. free ( wcBuf );
  725. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  726. }
  727. UINT uiStatus;
  728. while((uiStatus = g_fpMsiEnumFeaturesW(wcProduct, i++, wcBuf, wcParent)) != ERROR_NO_MORE_ITEMS){
  729. if(uiStatus != S_OK){
  730. bRetVal = false;
  731. break;
  732. }
  733. if(wcscmp(wcName, wcBuf) == 0){
  734. bRetVal = true;
  735. break;
  736. }
  737. }
  738. free((void *)wcBuf);
  739. free((void *)wcParent);
  740. return bRetVal;
  741. }
  742. bool SafeLeaveCriticalSection(CRITICAL_SECTION *pcs)
  743. {
  744. void * vpOwner = pcs->OwningThread;
  745. DWORD dwOwner = PtrToUlong(vpOwner);
  746. if((pcs->LockCount > -1) && (dwOwner == GetCurrentThreadId()))
  747. LeaveCriticalSection(pcs);
  748. return true;
  749. }