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.

1076 lines
24 KiB

  1. // DirectorySpecification.cpp: implementation of the CDirectorySpecification class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "DirectorySpecification.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CDirectorySpecification::CDirectorySpecification(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CDirectorySpecification::~CDirectorySpecification()
  18. {
  19. }
  20. HRESULT CDirectorySpecification::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. MSIHANDLE hView = NULL;
  24. MSIHANDLE hRecord = NULL;
  25. MSIHANDLE hDView = NULL;
  26. MSIHANDLE hDRecord = NULL;
  27. int i = -1;
  28. WCHAR * wcBuf = NULL;
  29. WCHAR * wcDir = NULL;
  30. WCHAR * wcPath = NULL;
  31. WCHAR * wcProductCode = NULL;
  32. WCHAR * wcCompID = NULL;
  33. WCHAR * wcDirectory = NULL;
  34. WCHAR * wcTestCode = NULL;
  35. DWORD dwBufSize;
  36. bool bMatch = false;
  37. UINT uiStatus;
  38. bool bGotID = false;
  39. bool bDoneFirst = false;
  40. try
  41. {
  42. if ( ( wcBuf = new WCHAR [ BUFF_SIZE ] ) == NULL )
  43. {
  44. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  45. }
  46. if ( ( wcDir = new WCHAR [ BUFF_SIZE ] ) == NULL )
  47. {
  48. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  49. }
  50. if ( ( wcPath = new WCHAR [ BUFF_SIZE * 4 ] ) == NULL )
  51. {
  52. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  53. }
  54. if ( ( wcProductCode = new WCHAR [ 39 ] ) == NULL )
  55. {
  56. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  57. }
  58. if ( ( wcCompID = new WCHAR [ 39 ] ) == NULL )
  59. {
  60. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  61. }
  62. if ( ( wcDirectory = new WCHAR [ BUFF_SIZE ] ) == NULL )
  63. {
  64. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  65. }
  66. if ( ( wcTestCode = new WCHAR [ 39 ] ) == NULL )
  67. {
  68. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  69. }
  70. DWORD dwBufSizeDir = BUFF_SIZE;
  71. DWORD dwBufSizeBuf = BUFF_SIZE;
  72. //These will change from class to class
  73. bool bCheck, bValidated;
  74. INSTALLSTATE piInstalled;
  75. int iState;
  76. SetSinglePropertyPath(L"CheckID");
  77. //improve getobject performance by optimizing the query
  78. if(atAction != ACTIONTYPE_ENUM)
  79. {
  80. // we are doing GetObject so we need to be reinitialized
  81. hr = WBEM_E_NOT_FOUND;
  82. BSTR bstrCompare;
  83. int iPos = -1;
  84. bstrCompare = SysAllocString ( L"CheckID" );
  85. if ( bstrCompare )
  86. {
  87. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  88. {
  89. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) < BUFF_SIZE )
  90. {
  91. //Get the action we're looking for
  92. wcscpy(wcBuf, m_pRequest->m_Value[iPos]);
  93. // safe operation if wcslen ( wcBuf ) > 38
  94. if ( wcslen ( wcBuf ) > 38 )
  95. {
  96. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  97. }
  98. else
  99. {
  100. // we are not good to go, they have sent us longer string
  101. SysFreeString ( bstrCompare );
  102. throw hr;
  103. }
  104. // safe because lenght has been tested already in condition
  105. RemoveFinalGUID(m_pRequest->m_Value[iPos], wcDirectory);
  106. // safe because lenght is going to be at least 39
  107. //we have a componentized directory... do a little more work
  108. if ( (wcDirectory[wcslen(wcDirectory) - 1] == L'}') &&
  109. (wcDirectory[wcslen(wcDirectory) - 38] == L'{')
  110. )
  111. {
  112. RemoveFinalGUID(wcDirectory, wcDirectory);
  113. }
  114. bGotID = true;
  115. }
  116. else
  117. {
  118. // we are not good to go, they have sent us longer string
  119. SysFreeString ( bstrCompare );
  120. throw hr;
  121. }
  122. }
  123. SysFreeString ( bstrCompare );
  124. }
  125. else
  126. {
  127. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  128. }
  129. }
  130. CStringExt wcID;
  131. Query wcQuery;
  132. wcQuery.Append ( 1, L"select distinct `Directory`, `DefaultDir` from Directory" );
  133. //optimize for GetObject
  134. if ( bGotID )
  135. {
  136. wcQuery.Append ( 3, L" where `Directory`=\'", wcDirectory, L"\'" );
  137. }
  138. QueryExt wcQuery1 ( L"select distinct `ComponentId`, `Component` from Component where `Directory_`=\'" );
  139. LPWSTR Buffer = NULL;
  140. LPWSTR dynBuffer = NULL;
  141. DWORD dwDynBuffer = 0L;
  142. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  143. {
  144. // safe operation:
  145. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  146. wcscpy(wcProductCode, m_pRequest->Package(i));
  147. if((atAction == ACTIONTYPE_ENUM) || (bGotID && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  148. //Open our database
  149. try
  150. {
  151. if ( GetView ( &hView, wcProductCode, wcQuery, L"Directory", FALSE, FALSE ) )
  152. {
  153. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  154. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  155. CheckMSI(uiStatus);
  156. bDoneFirst = false;
  157. UINT uiStatusTemp = ERROR_SUCCESS;
  158. //create different instances for each software element
  159. dwBufSize = dwBufSizeDir;;
  160. if ( ( uiStatusTemp = g_fpMsiRecordGetStringW(hRecord, 1, wcDir, &dwBufSize) )== ERROR_MORE_DATA )
  161. {
  162. delete [] wcDir;
  163. wcDir = NULL;
  164. if ( ( wcDir = new WCHAR [ dwBufSize + 1 ] ) != NULL )
  165. {
  166. CheckMSI ( g_fpMsiRecordGetStringW(hRecord, 1, wcDir, &dwBufSize) );
  167. dwBufSizeDir = dwBufSize;
  168. }
  169. else
  170. {
  171. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  172. }
  173. }
  174. else
  175. {
  176. if ( uiStatusTemp != ERROR_SUCCESS )
  177. {
  178. CheckMSI ( uiStatusTemp );
  179. }
  180. }
  181. // make query on fly
  182. wcQuery1.Append ( 2, wcDir, L"\'" );
  183. if ( ( ( uiStatus = g_fpMsiDatabaseOpenViewW ( msidata.GetDatabase (),
  184. wcQuery1,
  185. &hDView
  186. )
  187. ) == ERROR_SUCCESS
  188. )
  189. || !bDoneFirst
  190. )
  191. {
  192. if((g_fpMsiViewExecute(hDView, 0) == ERROR_SUCCESS) || !bDoneFirst){
  193. try{
  194. uiStatus = g_fpMsiViewFetch(hDView, &hDRecord);
  195. while(!bMatch && (!bDoneFirst || (uiStatus == ERROR_SUCCESS)) && (hr != WBEM_E_CALL_CANCELLED)){
  196. bValidated = false;
  197. if(uiStatus == ERROR_SUCCESS){
  198. dwBufSize = 39;
  199. CheckMSI(g_fpMsiRecordGetStringW(hDRecord, 1, wcCompID, &dwBufSize));
  200. bValidated = ValidateComponentID(wcCompID, wcProductCode);
  201. }
  202. if(((uiStatus != ERROR_SUCCESS) && !bDoneFirst) || (bValidated && (uiStatus != ERROR_NO_MORE_ITEMS))){
  203. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  204. //----------------------------------------------------
  205. PutProperty(m_pObj, pDirectory, wcDir);
  206. wcID.Copy ( wcDir );
  207. DWORD dwCompID = 0L;
  208. LPWSTR wszTemp = NULL;
  209. if(uiStatus == ERROR_SUCCESS)
  210. {
  211. dwCompID = wcslen ( wcCompID );
  212. try
  213. {
  214. if ( ( wszTemp = new WCHAR [ dwCompID + 1 ] ) == NULL )
  215. {
  216. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  217. }
  218. }
  219. catch ( ... )
  220. {
  221. if ( wszTemp )
  222. {
  223. delete [] wszTemp;
  224. wszTemp = NULL;
  225. }
  226. throw;
  227. }
  228. wcscpy(wszTemp, wcCompID);
  229. PutProperty(m_pObj, pSoftwareElementID, wcCompID);
  230. }
  231. if ( dwCompID )
  232. {
  233. wcID.Append ( 1, wszTemp );
  234. if ( wszTemp )
  235. {
  236. delete [] wszTemp;
  237. wszTemp = NULL;
  238. }
  239. }
  240. wcID.Append ( 1, wcProductCode );
  241. PutKeyProperty(m_pObj, pCheckID, wcID, &bCheck, m_pRequest);
  242. //====================================================
  243. dwBufSize = BUFF_SIZE * 4;
  244. BOOL bContinue = TRUE;
  245. DWORD dwContinue= 2;
  246. DWORD dwStatus = ERROR_SUCCESS;
  247. do
  248. {
  249. if ( ( dwStatus = CreateDirectoryPath ( msidata.GetProduct (),
  250. msidata.GetDatabase (),
  251. wcDir,
  252. wcPath,
  253. &dwBufSize
  254. )
  255. ) == ERROR_MORE_DATA
  256. )
  257. {
  258. delete [] wcPath;
  259. wcPath = NULL;
  260. if ( ( wcPath = new WCHAR [ dwBufSize + 1 ] ) == NULL )
  261. {
  262. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  263. }
  264. }
  265. else
  266. {
  267. bContinue = FALSE;
  268. }
  269. }
  270. while ( bContinue && dwContinue-- );
  271. if ( dwStatus == ERROR_SUCCESS )
  272. {
  273. PutProperty(m_pObj, pDirectoryPath, wcPath);
  274. }
  275. dwBufSize = dwBufSizeBuf;
  276. PutPropertySpecial ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, FALSE, 3, pDefaultDir, pCaption, pDescription );
  277. if(uiStatus == ERROR_SUCCESS){
  278. dwBufSize = dwBufSizeBuf;
  279. if ( ( uiStatusTemp = g_fpMsiRecordGetStringW(hDRecord, 2, wcBuf, &dwBufSize) ) == ERROR_MORE_DATA )
  280. {
  281. delete [] wcBuf;
  282. wcBuf = NULL;
  283. if ( ( wcBuf = new WCHAR [ dwBufSize + 1 ] ) != NULL )
  284. {
  285. CheckMSI(g_fpMsiRecordGetStringW(hDRecord, 2, wcBuf, &dwBufSize));
  286. dwBufSizeBuf = dwBufSize;
  287. }
  288. else
  289. {
  290. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  291. }
  292. }
  293. else
  294. {
  295. if ( uiStatusTemp != ERROR_SUCCESS )
  296. {
  297. CheckMSI ( uiStatusTemp );
  298. }
  299. }
  300. PutProperty(m_pObj, pName, wcBuf);
  301. dwBufSize = dwBufSizeBuf;
  302. piInstalled = g_fpMsiGetComponentPathW(wcProductCode, wcCompID, wcBuf, &dwBufSize);
  303. SoftwareElementState(piInstalled, &iState);
  304. PutProperty(m_pObj, pSoftwareElementState, iState);
  305. PutProperty(m_pObj, pTargetOperatingSystem, GetOS());
  306. dwBufSize = dwBufSizeBuf;
  307. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"ProductVersion", wcBuf, &dwBufSize));
  308. PutProperty(m_pObj, pVersion, wcBuf);
  309. }
  310. //----------------------------------------------------
  311. if(bCheck) bMatch = true;
  312. if((atAction != ACTIONTYPE_GET) || bMatch){
  313. hr = pHandler->Indicate(1, &m_pObj);
  314. }
  315. m_pObj->Release();
  316. m_pObj = NULL;
  317. if(!bDoneFirst) bDoneFirst = true;
  318. }
  319. g_fpMsiCloseHandle(hDRecord);
  320. uiStatus = g_fpMsiViewFetch(hDView, &hDRecord);
  321. }
  322. }catch(...){
  323. g_fpMsiCloseHandle(hDRecord);
  324. g_fpMsiViewClose(hDView);
  325. g_fpMsiCloseHandle(hDView);
  326. throw;
  327. }
  328. g_fpMsiCloseHandle(hDRecord);
  329. g_fpMsiViewClose(hDView);
  330. g_fpMsiCloseHandle(hDView);
  331. }
  332. }
  333. g_fpMsiCloseHandle(hRecord);
  334. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  335. }
  336. }
  337. }
  338. catch(...)
  339. {
  340. if ( dynBuffer )
  341. {
  342. delete [] dynBuffer;
  343. dynBuffer = NULL;
  344. }
  345. g_fpMsiCloseHandle(hRecord);
  346. g_fpMsiViewClose(hView);
  347. g_fpMsiCloseHandle(hView);
  348. msidata.CloseDatabase ();
  349. msidata.CloseProduct ();
  350. if(m_pObj)
  351. {
  352. m_pObj->Release();
  353. m_pObj = NULL;
  354. }
  355. throw;
  356. }
  357. g_fpMsiCloseHandle(hRecord);
  358. g_fpMsiViewClose(hView);
  359. g_fpMsiCloseHandle(hView);
  360. msidata.CloseDatabase ();
  361. msidata.CloseProduct ();
  362. }
  363. }
  364. if ( dynBuffer )
  365. {
  366. delete [] dynBuffer;
  367. dynBuffer = NULL;
  368. }
  369. }
  370. catch ( ... )
  371. {
  372. if (wcBuf)
  373. {
  374. delete [] wcBuf;
  375. wcBuf = NULL;
  376. }
  377. if (wcDir)
  378. {
  379. delete [] wcDir;
  380. wcDir = NULL;
  381. }
  382. if (wcPath)
  383. {
  384. delete [] wcPath;
  385. wcPath = NULL;
  386. }
  387. if (wcProductCode)
  388. {
  389. delete [] wcProductCode;
  390. wcProductCode = NULL;
  391. }
  392. if (wcCompID)
  393. {
  394. delete [] wcCompID;
  395. wcCompID = NULL;
  396. }
  397. if (wcDirectory)
  398. {
  399. delete [] wcDirectory;
  400. wcDirectory = NULL;
  401. }
  402. if (wcTestCode)
  403. {
  404. delete [] wcTestCode;
  405. wcTestCode = NULL;
  406. }
  407. throw;
  408. }
  409. if (wcBuf)
  410. {
  411. delete [] wcBuf;
  412. wcBuf = NULL;
  413. }
  414. if (wcDir)
  415. {
  416. delete [] wcDir;
  417. wcDir = NULL;
  418. }
  419. if (wcPath)
  420. {
  421. delete [] wcPath;
  422. wcPath = NULL;
  423. }
  424. if (wcProductCode)
  425. {
  426. delete [] wcProductCode;
  427. wcProductCode = NULL;
  428. }
  429. if (wcCompID)
  430. {
  431. delete [] wcCompID;
  432. wcCompID = NULL;
  433. }
  434. if (wcDirectory)
  435. {
  436. delete [] wcDirectory;
  437. wcDirectory = NULL;
  438. }
  439. if (wcTestCode)
  440. {
  441. delete [] wcTestCode;
  442. wcTestCode = NULL;
  443. }
  444. return hr;
  445. }
  446. DWORD CDirectorySpecification::CreateDirectoryPath ( MSIHANDLE hProduct,
  447. MSIHANDLE hDatabase,
  448. WCHAR *wcDir,
  449. WCHAR *wcPath,
  450. DWORD *dwPath
  451. )
  452. {
  453. DWORD dwResult = static_cast < DWORD > ( E_INVALIDARG );
  454. MSIHANDLE hView = NULL;
  455. MSIHANDLE hRecord = NULL;
  456. LPWSTR wcQuery = NULL;
  457. LPWSTR wcBuf = NULL;
  458. if ( wcDir )
  459. {
  460. DWORD dwQuery = 0L;
  461. LPWSTR wszQuery= L"select distinct `Directory_Parent`, `DefaultDir` from Directory where `Directory`=\'";
  462. dwQuery = lstrlenW ( wszQuery ) + lstrlenW ( wcDir ) + 1 + 1;
  463. try
  464. {
  465. if ( ( wcQuery = new WCHAR [ dwQuery ] ) == NULL )
  466. {
  467. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  468. }
  469. wcscpy(wcQuery, wszQuery);
  470. wcscat(wcQuery, wcDir);
  471. wcscat(wcQuery, L"\'");
  472. }
  473. catch ( ... )
  474. {
  475. if ( wcQuery )
  476. {
  477. delete [] wcQuery;
  478. wcQuery = NULL;
  479. }
  480. throw;
  481. }
  482. try
  483. {
  484. if ( ( wcBuf = new WCHAR [ BUFF_SIZE ] ) == NULL )
  485. {
  486. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  487. }
  488. }
  489. catch ( ... )
  490. {
  491. if ( wcQuery )
  492. {
  493. delete [] wcQuery;
  494. wcQuery = NULL;
  495. }
  496. if ( wcBuf )
  497. {
  498. delete [] wcBuf;
  499. wcBuf = NULL;
  500. }
  501. throw;
  502. }
  503. DWORD dwPathSize = 0;
  504. dwPathSize = * dwPath;
  505. DWORD dwUsed = 1; // last null
  506. DWORD dwBufSize = BUFF_SIZE;
  507. //Do all this to open a view on the directory we want
  508. if ( ( dwResult = g_fpMsiDatabaseOpenViewW ( hDatabase, wcQuery, &hView ) ) == ERROR_SUCCESS )
  509. {
  510. delete [] wcQuery;
  511. wcQuery = NULL;
  512. if(g_fpMsiViewExecute(hView, 0) == ERROR_SUCCESS)
  513. {
  514. if ( ( dwResult = g_fpMsiViewFetch ( hView, &hRecord ) ) == ERROR_SUCCESS )
  515. {
  516. BOOL bContinue = TRUE;
  517. DWORD dwContinue= 2;
  518. dwBufSize = BUFF_SIZE;
  519. do
  520. {
  521. if ( ( dwResult = g_fpMsiRecordGetStringW ( hRecord, 1, wcBuf, &dwBufSize ) ) == ERROR_MORE_DATA )
  522. {
  523. delete [] wcBuf;
  524. wcBuf = NULL;
  525. try
  526. {
  527. if ( ( wcBuf = new WCHAR [ dwBufSize + 1 ] ) == NULL )
  528. {
  529. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  530. }
  531. }
  532. catch ( ... )
  533. {
  534. if ( wcBuf )
  535. {
  536. delete [] wcBuf;
  537. wcBuf = NULL;
  538. }
  539. throw;
  540. }
  541. dwBufSize++;
  542. }
  543. else
  544. {
  545. if ( dwContinue == 2 )
  546. {
  547. dwBufSize = BUFF_SIZE;
  548. }
  549. bContinue = FALSE;
  550. }
  551. }
  552. while ( bContinue && dwContinue-- );
  553. if( dwResult == ERROR_SUCCESS )
  554. {
  555. //For TARGETDIR
  556. if(wcscmp(L"TARGETDIR", wcBuf) == 0)
  557. {
  558. bContinue = TRUE;
  559. dwContinue= 2;
  560. DWORD dwBufSizeOld = dwBufSize;
  561. do
  562. {
  563. if ( ( dwResult = g_fpMsiGetProductPropertyW (
  564. hProduct,
  565. L"TARGETDIR",
  566. wcBuf,
  567. &dwBufSize
  568. )
  569. ) == ERROR_MORE_DATA
  570. )
  571. {
  572. delete [] wcBuf;
  573. wcBuf = NULL;
  574. try
  575. {
  576. if ( ( wcBuf = new WCHAR [ dwBufSize + 1 ] ) == NULL )
  577. {
  578. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  579. }
  580. dwBufSize ++;
  581. }
  582. catch ( ... )
  583. {
  584. if ( wcBuf )
  585. {
  586. delete [] wcBuf;
  587. wcBuf = NULL;
  588. }
  589. throw;
  590. }
  591. }
  592. else
  593. {
  594. if ( dwContinue == 2 )
  595. {
  596. dwBufSize = dwBufSizeOld;
  597. }
  598. bContinue = FALSE;
  599. }
  600. }
  601. while ( bContinue && dwContinue-- );
  602. if ( dwResult == ERROR_SUCCESS )
  603. {
  604. dwUsed = dwUsed +
  605. lstrlenW ( wcBuf );
  606. if ( dwUsed > dwPathSize )
  607. {
  608. ( *dwPath ) = ( *dwPath ) + ( dwUsed - dwPathSize );
  609. dwResult = ERROR_MORE_DATA;
  610. }
  611. else
  612. {
  613. wcscpy(wcPath, wcBuf);
  614. }
  615. }
  616. }
  617. //For WindowsFolder
  618. else if(wcscmp(L"WindowsFolder", wcBuf) == 0)
  619. {
  620. DWORD dwSize = 0;
  621. bContinue = TRUE;
  622. dwContinue= 2;
  623. do
  624. {
  625. dwSize = GetEnvironmentVariableW ( L"WINDIR", wcBuf, dwBufSize );
  626. if ( dwSize == 0 )
  627. {
  628. dwResult = static_cast < DWORD > ( E_FAIL );
  629. bContinue = FALSE;
  630. }
  631. else if ( dwSize > dwBufSize )
  632. {
  633. delete [] wcBuf;
  634. wcBuf = NULL;
  635. try
  636. {
  637. if ( ( wcBuf = new WCHAR [ dwSize + 1 ] ) == NULL )
  638. {
  639. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  640. }
  641. dwBufSize = dwSize + 1;
  642. }
  643. catch ( ... )
  644. {
  645. if ( wcBuf )
  646. {
  647. delete [] wcBuf;
  648. wcBuf = NULL;
  649. }
  650. throw;
  651. }
  652. }
  653. else
  654. {
  655. bContinue = FALSE;
  656. dwResult = ERROR_SUCCESS;
  657. }
  658. }
  659. while ( bContinue && dwContinue-- );
  660. if ( dwResult == ERROR_SUCCESS )
  661. {
  662. dwUsed = dwUsed +
  663. lstrlenW ( wcBuf );
  664. if ( dwUsed > dwPathSize )
  665. {
  666. ( *dwPath ) = ( *dwPath ) + ( dwUsed - dwPathSize );
  667. dwResult = ERROR_MORE_DATA;
  668. }
  669. else
  670. {
  671. wcscpy(wcPath, wcBuf);
  672. }
  673. }
  674. }
  675. //For DesktopFolder
  676. else if(wcscmp(L"DesktopFolder", wcBuf) == 0)
  677. {
  678. WCHAR wcVar[15];
  679. if(AreWeOnNT())
  680. {
  681. wcscpy(wcVar, L"USERPROFILE");
  682. }
  683. else
  684. {
  685. wcscpy(wcVar, L"WINDIR");
  686. }
  687. DWORD dwSize = 0;
  688. bContinue = TRUE;
  689. dwContinue= 2;
  690. do
  691. {
  692. dwSize = GetEnvironmentVariableW ( wcVar, wcBuf, dwBufSize );
  693. if ( dwSize == 0 )
  694. {
  695. dwResult = static_cast < DWORD > ( E_FAIL );
  696. bContinue = FALSE;
  697. }
  698. else if ( dwSize > dwBufSize )
  699. {
  700. delete [] wcBuf;
  701. wcBuf = NULL;
  702. try
  703. {
  704. if ( ( wcBuf = new WCHAR [ dwSize + 1 ] ) == NULL )
  705. {
  706. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  707. }
  708. dwBufSize = dwSize + 1;
  709. }
  710. catch ( ... )
  711. {
  712. if ( wcBuf )
  713. {
  714. delete [] wcBuf;
  715. wcBuf = NULL;
  716. }
  717. throw;
  718. }
  719. }
  720. else
  721. {
  722. bContinue = FALSE;
  723. dwResult = ERROR_SUCCESS;
  724. }
  725. }
  726. while ( bContinue && dwContinue-- );
  727. if ( dwResult == ERROR_SUCCESS )
  728. {
  729. dwUsed = dwUsed +
  730. lstrlenW ( wcBuf ) +
  731. lstrlenW ( L"\\Desktop" );
  732. if ( dwUsed > dwPathSize )
  733. {
  734. ( *dwPath ) = ( *dwPath ) + ( dwUsed - dwPathSize );
  735. dwResult = ERROR_MORE_DATA;
  736. }
  737. else
  738. {
  739. wcscpy(wcPath, wcBuf);
  740. wcscat(wcPath, L"\\Desktop");
  741. }
  742. }
  743. }
  744. //For same parent/directory
  745. else if(wcscmp(wcDir, wcBuf) == 0)
  746. {
  747. dwResult = ERROR_SUCCESS;
  748. }
  749. //Continue recursion
  750. else
  751. {
  752. dwResult = CreateDirectoryPath ( hProduct, hDatabase, wcBuf, wcPath, dwPath );
  753. if ( dwResult == ERROR_MORE_DATA )
  754. {
  755. dwUsed = dwUsed + ( * dwPath );
  756. }
  757. }
  758. }
  759. if ( dwResult == ERROR_SUCCESS || dwResult == ERROR_MORE_DATA )
  760. {
  761. bContinue = TRUE;
  762. dwContinue= 2;
  763. DWORD dwResultHelp = ERROR_SUCCESS;
  764. do
  765. {
  766. if ( ( dwResultHelp = g_fpMsiRecordGetStringW ( hRecord,
  767. 2,
  768. wcBuf,
  769. &dwBufSize
  770. )
  771. ) == ERROR_MORE_DATA
  772. )
  773. {
  774. delete [] wcBuf;
  775. wcBuf = NULL;
  776. try
  777. {
  778. if ( ( wcBuf = new WCHAR [ dwBufSize ] ) == NULL )
  779. {
  780. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  781. }
  782. }
  783. catch ( ... )
  784. {
  785. if ( wcBuf )
  786. {
  787. delete [] wcBuf;
  788. wcBuf = NULL;
  789. }
  790. throw;
  791. }
  792. }
  793. else
  794. {
  795. bContinue = FALSE;
  796. }
  797. }
  798. while ( bContinue && dwContinue-- );
  799. if ( dwResultHelp == ERROR_MORE_DATA )
  800. {
  801. dwResult = static_cast < DWORD > ( E_FAIL );
  802. }
  803. if ( dwResult == ERROR_SUCCESS || dwResult == ERROR_MORE_DATA )
  804. {
  805. LPWSTR wcBufHelp = NULL;
  806. try
  807. {
  808. wcBufHelp = ParseDefDir ( wcBuf );
  809. }
  810. catch ( ... )
  811. {
  812. delete [] wcBuf;
  813. wcBuf = NULL;
  814. throw;
  815. }
  816. dwUsed = dwUsed +
  817. lstrlenW ( wcBufHelp );
  818. if ( dwUsed > dwPathSize )
  819. {
  820. ( *dwPath ) = ( *dwPath ) + ( dwUsed - dwPathSize );
  821. dwResult = ERROR_MORE_DATA;
  822. }
  823. else
  824. {
  825. wcscat(wcPath, wcBufHelp);
  826. }
  827. }
  828. }
  829. g_fpMsiCloseHandle(hRecord);
  830. }
  831. else if ( dwResult == E_OUTOFMEMORY )
  832. {
  833. g_fpMsiViewClose(hView);
  834. g_fpMsiCloseHandle(hView);
  835. delete [] wcBuf;
  836. wcBuf = NULL;
  837. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  838. }
  839. }
  840. g_fpMsiViewClose(hView);
  841. g_fpMsiCloseHandle(hView);
  842. delete [] wcBuf;
  843. wcBuf = NULL;
  844. }
  845. else
  846. {
  847. delete [] wcBuf;
  848. wcBuf = NULL;
  849. delete [] wcQuery;
  850. wcQuery = NULL;
  851. if(dwResult == E_OUTOFMEMORY)
  852. {
  853. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  854. }
  855. }
  856. }
  857. if ( dwResult == ERROR_MORE_DATA )
  858. {
  859. wcPath [ 0 ] = 0;
  860. }
  861. return dwResult;
  862. }
  863. WCHAR * CDirectorySpecification::ParseDefDir(WCHAR *wcDefaultDir)
  864. {
  865. WCHAR * wcTmp;
  866. WCHAR * wcBuf = NULL;
  867. if ( ( wcBuf = (WCHAR *)malloc( ( wcslen ( wcDefaultDir ) + 1 + 1 ) * sizeof(WCHAR)) ) != NULL )
  868. {
  869. wcscpy(wcBuf, L"\\");
  870. wcscat(wcBuf, wcDefaultDir);
  871. for(wcTmp = wcBuf; *wcTmp; wcTmp++) if(*wcTmp == L':') *wcTmp = NULL;
  872. for(wcTmp = wcBuf; *wcTmp; wcTmp++) if(*wcTmp == L'.') wcscpy(wcBuf, L"");
  873. wcscpy(wcDefaultDir, wcBuf);
  874. free((void *)wcBuf);
  875. }
  876. else
  877. {
  878. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  879. }
  880. return wcDefaultDir;
  881. }