Source code of Windows XP (NT5)
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.

4506 lines
128 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // ApplicationEntry.cpp
  4. //
  5. // Copyright (C) 1998, 1999 Microsoft Corporation. All rights reserved.
  6. //
  7. // Abstract :
  8. //
  9. // This is the implementation of IApplicationEntry
  10. //
  11. // History :
  12. //
  13. // 05/06/1999 luish Created
  14. //
  15. //////////////////////////////////////////////////////////////////////////////////////////////
  16. #include <windows.h>
  17. #include <string.h>
  18. #include "Resource.h"
  19. #include "AppMan.h"
  20. #include "Win32API.h"
  21. #include "ApplicationManager.h"
  22. #include "ExceptionHandler.h"
  23. #include "Lock.h"
  24. #include "AppManDebug.h"
  25. #include "StructIdentifiers.h"
  26. #include "Global.h"
  27. //To flag as DBG_APPENTRY
  28. #ifdef DBG_MODULE
  29. #undef DBG_MODULE
  30. #endif
  31. #define DBG_MODULE DBG_APPENTRY
  32. //
  33. // Macro definition used within this source file only
  34. //
  35. #define VALIDATE_PROPERTY(a) m_InformationManager.ValidateApplicationPropertyWithIndex((a), &m_sApplicationData)
  36. #define INVALIDATE_PROPERTY(a) m_InformationManager.InvalidateApplicationPropertyWithIndex((a), &m_sApplicationData)
  37. #define RESET_ACTIONSTATE(a) m_dwCurrentAction = (a)
  38. #define SET_ACTIONSTATE(a) m_dwCurrentAction = (a)
  39. #define CHECK_ACTIONSTATE(a) ((a) == m_dwCurrentAction)
  40. #define GET_ACTIONSTATE(a) (m_dwCurrentAction)
  41. #define CLEAR_ACTIONSTATE(a) m_dwCurrentAction = CURRENT_ACTION_NONE
  42. #define VALIDATE_STATE_FIELD() if (0 != m_sApplicationData.sBaseInfo.dwState) { VALIDATE_PROPERTY(IDX_PROPERTY_STATE); m_InformationManager.SetApplicationState(&m_sApplicationData, &m_sInstanceGuid); } else { INVALIDATE_PROPERTY(IDX_PROPERTY_STATE); }
  43. #define CHECK_APPLICATIONSTATE(a) (m_sApplicationData.sBaseInfo.dwState & (a))
  44. #define RESET_APPLICATIONSTATE(a) m_sApplicationData.sBaseInfo.dwState = (a); VALIDATE_STATE_FIELD()
  45. #define SET_APPLICATIONSTATE(a) m_sApplicationData.sBaseInfo.dwState = (a); VALIDATE_STATE_FIELD()
  46. #define GET_APPLICATIONSTATE() (m_sApplicationData.sBaseInfo.dwState)
  47. #define CLEAR_APPLICATIONSTATE() m_sApplicationData.sBaseInfo.dwState = 0; VALIDATE_STATE_FIELD()
  48. #define VALIDATE_CATEGORY_FIELD() if (APP_CATEGORY_NONE != m_sApplicationData.sBaseInfo.dwCategory) { VALIDATE_PROPERTY(IDX_PROPERTY_CATEGORY); } else { INVALIDATE_PROPERTY(IDX_PROPERTY_CATEGORY); }
  49. #define CHECK_APPLICATIONCATEGORY(a) ((a) == (m_sApplicationData.sBaseInfo.dwCategory & (a)))
  50. #define RESET_APPLICATIONCATEGORY(a) m_sApplicationData.sBaseInfo.dwCategory = (a); VALIDATE_CATEGORY_FIELD()
  51. #define SET_APPLICATIONCATEGORY(a) m_sApplicationData.sBaseInfo.dwCategory |= (a); VALIDATE_CATEGORY_FIELD()
  52. #define GET_APPLICATIONCATEGORY() (m_sApplicationData.sBaseInfo.dwCategory)
  53. #define CLEAR_APPLICATIONCATEGORY() m_sApplicationData.sBaseInfo.dwCategory = APP_CATEGORY_NONE; VALIDATE_CATEGORY_FIELD()
  54. //////////////////////////////////////////////////////////////////////////////////////////////
  55. //
  56. //////////////////////////////////////////////////////////////////////////////////////////////
  57. CApplicationEntry::CApplicationEntry(void)
  58. {
  59. FUNCTION("CApplicationEntry::CApplicationEntry (void)");
  60. m_dwLockCount = 0;
  61. m_fIsInitialized = FALSE;
  62. m_dwCurrentAction = CURRENT_ACTION_NONE;
  63. m_lReferenceCount = 1;
  64. m_hInstanceMutex = NULL;
  65. }
  66. //////////////////////////////////////////////////////////////////////////////////////////////
  67. //
  68. //////////////////////////////////////////////////////////////////////////////////////////////
  69. CApplicationEntry::~CApplicationEntry(void)
  70. {
  71. FUNCTION("CApplicationEntry::~CApplicationEntry (void)");
  72. if (CURRENT_ACTION_NONE != m_dwCurrentAction)
  73. {
  74. APPLICATION_DATA sApplicationData;
  75. ASSOCIATION_INFO sAssociationInfo;
  76. DWORD dwIndex;
  77. //
  78. // We need to force a leave event
  79. //
  80. switch(m_dwCurrentAction)
  81. {
  82. case CURRENT_ACTION_DOWNSIZING
  83. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE);
  84. break;
  85. case CURRENT_ACTION_REINSTALLING
  86. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL);
  87. break;
  88. case CURRENT_ACTION_UNINSTALLING
  89. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL);
  90. break;
  91. case CURRENT_ACTION_SELFTESTING
  92. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST);
  93. break;
  94. case (CURRENT_ACTION_SELFTESTING | CURRENT_ACTION_REINSTALLING)
  95. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL);
  96. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST);
  97. break;
  98. }
  99. //
  100. // Before we do anything, make sure to unlock the parent apps
  101. //
  102. ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo));
  103. dwIndex = 0;
  104. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  105. {
  106. if (0 == memcmp((LPVOID) &(sAssociationInfo.sChildGuid), (LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), sizeof(GUID)))
  107. {
  108. //
  109. // Get the associated application
  110. //
  111. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  112. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  113. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  114. if (SUCCEEDED(m_InformationManager.GetApplicationData(&sApplicationData)))
  115. {
  116. //
  117. // Unlock the parent applications
  118. //
  119. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  120. }
  121. }
  122. dwIndex++;
  123. }
  124. //
  125. // If the application was doing an initial install, abort will cause the application
  126. // entry to be removed from the system
  127. //
  128. UnLockApplication();
  129. }
  130. // 4/12/2000(RichGr): If we've got a mutex, release and close it. We were leaking handles
  131. // when swopping between AppManDiagTool tabs.
  132. if (NULL != m_hInstanceMutex)
  133. {
  134. ReleaseMutex(m_hInstanceMutex);
  135. CloseHandle(m_hInstanceMutex);
  136. m_hInstanceMutex = NULL;
  137. }
  138. if (TRUE == m_fIsInitialized)
  139. {
  140. m_InformationManager.ForceUnlockApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  141. }
  142. }
  143. //////////////////////////////////////////////////////////////////////////////////////////////
  144. //
  145. // TODO : the constructor requires that the incoming parameter
  146. // be a const, we cannot lock the source object by calling Lock() (which is not
  147. // a const method. So, when the copying occurs, the source object will not be locked
  148. //
  149. //////////////////////////////////////////////////////////////////////////////////////////////
  150. CApplicationEntry::CApplicationEntry(const CApplicationEntry & /*refSourceObject*/) // Get rid of /W4 warnings.
  151. {
  152. FUNCTION("CApplicationEntry::CApplicationEntry (const CApplicationEntry &refSourceObject)");
  153. }
  154. //////////////////////////////////////////////////////////////////////////////////////////////
  155. //
  156. //////////////////////////////////////////////////////////////////////////////////////////////
  157. CApplicationEntry & CApplicationEntry::operator = (const CApplicationEntry & /*refSourceObject*/)
  158. {
  159. return * this;
  160. }
  161. //////////////////////////////////////////////////////////////////////////////////////////////
  162. //
  163. // IUnknown interface implementation
  164. //
  165. //////////////////////////////////////////////////////////////////////////////////////////////
  166. STDMETHODIMP CApplicationEntry::QueryInterface(REFIID RefIID, LPVOID * ppVoidObject)
  167. {
  168. FUNCTION("CAppEntry::QueryInterface ()");
  169. HRESULT hResult = S_OK;
  170. ///////////////////////////////////////////////////////////////////////////////////////
  171. try
  172. {
  173. if (NULL == &RefIID)
  174. {
  175. THROW(E_UNEXPECTED);
  176. }
  177. if (NULL == ppVoidObject)
  178. {
  179. THROW(E_UNEXPECTED);
  180. }
  181. *ppVoidObject = NULL;
  182. if ((RefIID == IID_IUnknown)||(RefIID == IID_ApplicationEntry))
  183. {
  184. *ppVoidObject = (LPVOID) this;
  185. }
  186. if (*ppVoidObject)
  187. {
  188. ((LPUNKNOWN)*ppVoidObject)->AddRef();
  189. }
  190. else
  191. {
  192. hResult = E_NOINTERFACE;
  193. }
  194. }
  195. ///////////////////////////////////////////////////////////////////////////////////////
  196. catch(CAppManExceptionHandler * pException)
  197. {
  198. hResult = pException->GetResultCode();
  199. delete pException;
  200. }
  201. catch(...)
  202. {
  203. if ((NULL == &RefIID)||(NULL == ppVoidObject)||(IsBadWritePtr(ppVoidObject, sizeof(LPVOID))))
  204. {
  205. hResult = E_INVALIDARG;
  206. }
  207. else
  208. {
  209. hResult = E_UNEXPECTED;
  210. }
  211. }
  212. ///////////////////////////////////////////////////////////////////////////////////////
  213. return hResult;
  214. }
  215. //////////////////////////////////////////////////////////////////////////////////////////////
  216. //
  217. // IUnknown interface implementation
  218. //
  219. //////////////////////////////////////////////////////////////////////////////////////////////
  220. STDMETHODIMP_(ULONG) CApplicationEntry::AddRef(void)
  221. {
  222. FUNCTION("CAppEntry::AddRef ()");
  223. return InterlockedIncrement(&m_lReferenceCount);
  224. }
  225. //////////////////////////////////////////////////////////////////////////////////////////////
  226. //
  227. // IUnknown interface implementation
  228. //
  229. //////////////////////////////////////////////////////////////////////////////////////////////
  230. STDMETHODIMP_(ULONG) CApplicationEntry::Release(void)
  231. {
  232. FUNCTION("CAppEntry::Release ()");
  233. DWORD dwReferenceCount;
  234. dwReferenceCount = InterlockedDecrement(&m_lReferenceCount);
  235. if (0 == dwReferenceCount)
  236. {
  237. delete this;
  238. }
  239. return dwReferenceCount;
  240. }
  241. //////////////////////////////////////////////////////////////////////////////////////////////
  242. //
  243. //////////////////////////////////////////////////////////////////////////////////////////////
  244. STDMETHODIMP CApplicationEntry::Initialize(void)
  245. {
  246. FUNCTION("CAppEntry::Initialize ()");
  247. HRESULT hResult;
  248. hResult = m_sCriticalSection.Initialize();
  249. if (SUCCEEDED(hResult))
  250. {
  251. hResult = m_InformationManager.Initialize();
  252. if (SUCCEEDED(hResult))
  253. {
  254. hResult = Clear();
  255. if (SUCCEEDED(hResult))
  256. {
  257. m_fIsInitialized = TRUE;
  258. }
  259. }
  260. }
  261. return hResult;
  262. }
  263. //////////////////////////////////////////////////////////////////////////////////////////////
  264. //
  265. //////////////////////////////////////////////////////////////////////////////////////////////
  266. STDMETHODIMP CApplicationEntry::SetInitializationLevel(DWORD dwInitializationLevel)
  267. {
  268. FUNCTION("CAppEntry::SetInitializationLevel ()");
  269. m_dwInitializationLevel = dwInitializationLevel;
  270. return S_OK;
  271. }
  272. //////////////////////////////////////////////////////////////////////////////////////////////
  273. //
  274. //////////////////////////////////////////////////////////////////////////////////////////////
  275. STDMETHODIMP_(DWORD) CApplicationEntry::GetActionState(void)
  276. {
  277. FUNCTION("CAppEntry::GetActionState ()");
  278. return m_dwCurrentAction;
  279. }
  280. //////////////////////////////////////////////////////////////////////////////////////////////
  281. //
  282. //////////////////////////////////////////////////////////////////////////////////////////////
  283. STDMETHODIMP CApplicationEntry::LockApplication(void)
  284. {
  285. FUNCTION("CAppEntry::LockApplication ()");
  286. HRESULT hResult;
  287. hResult = m_InformationManager.LockApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  288. if (SUCCEEDED(hResult))
  289. {
  290. m_dwLockCount++;
  291. }
  292. else
  293. {
  294. THROW(APPMAN_E_APPLICATIONALREADYLOCKED);
  295. }
  296. return hResult;
  297. }
  298. //////////////////////////////////////////////////////////////////////////////////////////////
  299. //
  300. //////////////////////////////////////////////////////////////////////////////////////////////
  301. STDMETHODIMP CApplicationEntry::UnLockApplication(void)
  302. {
  303. FUNCTION("CAppEntry::UnLockApplication ()");
  304. HRESULT hResult;
  305. hResult = m_InformationManager.UnlockApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  306. if (SUCCEEDED(hResult))
  307. {
  308. if (0 < m_dwLockCount)
  309. {
  310. m_dwLockCount--;
  311. }
  312. }
  313. return hResult;
  314. }
  315. //////////////////////////////////////////////////////////////////////////////////////////////
  316. //
  317. //////////////////////////////////////////////////////////////////////////////////////////////
  318. STDMETHODIMP CApplicationEntry::Clear(void)
  319. {
  320. FUNCTION("CAppEntry::Clear ()");
  321. HRESULT hResult = S_OK;
  322. ///////////////////////////////////////////////////////////////////////////////////////
  323. try
  324. {
  325. CLock sLock(&m_sCriticalSection);
  326. DWORD dwIndex;
  327. CHAR szString[MAX_PATH];
  328. sLock.Lock();
  329. //
  330. // Make sure we are not in the middle of an action
  331. //
  332. if (CURRENT_ACTION_NONE != m_dwCurrentAction)
  333. {
  334. THROW(APPMAN_E_ACTIONINPROGRESS);
  335. }
  336. //
  337. // Make sure this application instance is not locked
  338. //
  339. if (0 != m_dwLockCount)
  340. {
  341. THROW(APPMAN_E_APPLICATIONALREADYLOCKED);
  342. }
  343. //
  344. // Ok, let's wipe the object
  345. //
  346. m_dwInitializationLevel = INIT_LEVEL_NONE;
  347. ZeroMemory(&m_sApplicationData, sizeof(m_sApplicationData));
  348. //
  349. // Initialize the structure headers
  350. //
  351. m_sApplicationData.sAgingInfo.dwSize = sizeof(m_sApplicationData.sAgingInfo);
  352. m_sApplicationData.sAgingInfo.dwStructId = AGING_STRUCT;
  353. m_sApplicationData.sBaseInfo.dwSize = sizeof(m_sApplicationData.sBaseInfo);
  354. m_sApplicationData.sBaseInfo.dwStructId = BASIC_APPINFO_STRUCT;
  355. m_sApplicationData.sAssociation.dwSize = sizeof(m_sApplicationData.sAssociation);
  356. m_sApplicationData.sAssociation.dwStructId = ASSOCIATION_STRUCT;
  357. //
  358. // Since this is a new object, let's initialize the crypto string
  359. //
  360. RandomInit();
  361. for (dwIndex = 0; dwIndex < MAX_PATH_CHARCOUNT + 1; dwIndex++)
  362. {
  363. m_sApplicationData.wszStringProperty[APP_STRING_CRYPTO][dwIndex] = RandomWORD();
  364. }
  365. //
  366. // If the object was assigned a mutex, kill the mutex
  367. //
  368. if (NULL != m_hInstanceMutex)
  369. {
  370. ReleaseMutex(m_hInstanceMutex);
  371. CloseHandle(m_hInstanceMutex);
  372. m_hInstanceMutex = NULL;
  373. }
  374. //
  375. // Create the instance info and constructs
  376. //
  377. if (FAILED(CoCreateGuid(&m_sInstanceGuid)))
  378. {
  379. THROW(E_UNEXPECTED);
  380. }
  381. sprintf(szString, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", m_sInstanceGuid.Data1, m_sInstanceGuid.Data2, m_sInstanceGuid.Data3, m_sInstanceGuid.Data4[0], m_sInstanceGuid.Data4[1], m_sInstanceGuid.Data4[2], m_sInstanceGuid.Data4[3], m_sInstanceGuid.Data4[4], m_sInstanceGuid.Data4[5], m_sInstanceGuid.Data4[6], m_sInstanceGuid.Data4[7]);
  382. m_hInstanceMutex = CreateMutex(NULL, TRUE, szString);
  383. sLock.UnLock();
  384. }
  385. ///////////////////////////////////////////////////////////////////////////////////////
  386. catch(CAppManExceptionHandler * pException)
  387. {
  388. hResult = pException->GetResultCode();
  389. delete pException;
  390. }
  391. catch(...)
  392. {
  393. hResult = E_UNEXPECTED;
  394. }
  395. ///////////////////////////////////////////////////////////////////////////////////////
  396. return hResult;
  397. }
  398. //////////////////////////////////////////////////////////////////////////////////////////////
  399. //
  400. //////////////////////////////////////////////////////////////////////////////////////////////
  401. STDMETHODIMP CApplicationEntry::ValidateGetPropertyParameters(const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPVOID lpData, const DWORD dwDataLen)
  402. {
  403. FUNCTION("CApplicationInfo::ValidateGetPropertyParameters (const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPVOID lpData, const DWORD dwDataLen)");
  404. //
  405. // Is the property currently initialized
  406. //
  407. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(dwPropertyIndex, &m_sApplicationData))
  408. {
  409. THROW(APPMAN_E_PROPERTYNOTSET);
  410. }
  411. //
  412. // Are we actually allowed to read this property
  413. //
  414. if (!(m_dwInitializationLevel & gPropertyInfo[dwPropertyIndex].dwReadMask))
  415. {
  416. THROW(APPMAN_E_PROPERTYNOTSET);
  417. }
  418. //
  419. // The property being passed in is either a GUID, a DWORD or a string
  420. //
  421. if (APP_STRING_NONE == gPropertyInfo[dwPropertyIndex].dwStringId)
  422. {
  423. //
  424. // dwPropertyModifers should be 0
  425. //
  426. if (0 != dwPropertyModifiers)
  427. {
  428. THROW(APPMAN_E_INVALIDPROPERTY);
  429. }
  430. //
  431. // Make sure dwDataLen is correct
  432. //
  433. if (gPropertyInfo[dwPropertyIndex].dwMaxLen != dwDataLen)
  434. {
  435. THROW(APPMAN_E_INVALIDPROPERTYSIZE);
  436. }
  437. //
  438. // Since the property is a GUID or a DWORD, the dwDatalen should be fixed
  439. //
  440. if ((NULL == lpData)||(IsBadWritePtr(lpData, dwDataLen)))
  441. {
  442. THROW(APPMAN_E_INVALIDPARAMETERS);
  443. }
  444. }
  445. else
  446. {
  447. //
  448. // Make sure dwDataLen is correct
  449. //
  450. if (0 == dwDataLen)
  451. {
  452. THROW(APPMAN_E_INVALIDPROPERTYSIZE);
  453. }
  454. //
  455. // Determine the character count in the incoming string
  456. //
  457. if ((APP_PROPERTY_STR_ANSI != dwPropertyModifiers)&&(APP_PROPERTY_STR_UNICODE != dwPropertyModifiers)&&(0 != dwPropertyModifiers))
  458. {
  459. THROW(APPMAN_E_INVALIDPROPERTYVALUE);
  460. }
  461. //
  462. // The property is a string
  463. //
  464. if ((NULL == lpData)||(IsBadWritePtr(lpData, dwDataLen)))
  465. {
  466. THROW(APPMAN_E_INVALIDPARAMETERS);
  467. }
  468. }
  469. return S_OK;
  470. }
  471. //////////////////////////////////////////////////////////////////////////////////////////////
  472. //
  473. //////////////////////////////////////////////////////////////////////////////////////////////
  474. STDMETHODIMP CApplicationEntry::ValidateStringProperty(const DWORD dwPropertyIndex, const DWORD /*dwPropertyModifiers*/, LPCWSTR wszStringProperty)
  475. {
  476. FUNCTION("CAppEntry::ValidateStringProperty ()");
  477. CWin32API sWin32API;
  478. if ((IDX_PROPERTY_COMPANYNAME == dwPropertyIndex)||(IDX_PROPERTY_SIGNATURE == dwPropertyIndex))
  479. {
  480. //
  481. // First we make sure that this is even a valid path
  482. //
  483. if (!sWin32API.IsValidFilename(wszStringProperty))
  484. {
  485. THROW(APPMAN_E_INVALIDPARAMETERS);
  486. }
  487. }
  488. return S_OK;
  489. }
  490. //////////////////////////////////////////////////////////////////////////////////////////////
  491. //
  492. //////////////////////////////////////////////////////////////////////////////////////////////
  493. STDMETHODIMP CApplicationEntry::ValidateSetPropertyParameters(const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPCVOID lpData, const DWORD dwDataLen)
  494. {
  495. FUNCTION("CApplicationInfo::ValidateSetPropertyParameters (const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPCVOID lpData, const DWORD dwDataLen)");
  496. DWORD dwCharCount = 0;
  497. //
  498. // Determine whether or not we are allowed to set this property at this time
  499. //
  500. if (!(m_dwCurrentAction & gPropertyInfo[dwPropertyIndex].dwWriteMask))
  501. {
  502. THROW(APPMAN_E_READONLYPROPERTY);
  503. }
  504. //
  505. // This is a special case when APP_PROPERTY_EXECUTECMDLINE is used. If the category has the
  506. // APP_CATEGORY_PATCH or APP_CATEGORY_DATA, then the APP_PROPERTY_EXECUTECMDLINE is
  507. // not setable
  508. //
  509. if (((APP_CATEGORY_PATCH | APP_CATEGORY_DATA) & m_sApplicationData.sBaseInfo.dwCategory)&&(IDX_PROPERTY_EXECUTECMDLINE == dwPropertyIndex))
  510. {
  511. THROW(APPMAN_E_READONLYPROPERTY);
  512. }
  513. //
  514. // The property being passed in is either a GUID/DWORD or a string
  515. //
  516. if (APP_STRING_NONE == gPropertyInfo[dwPropertyIndex].dwStringId)
  517. {
  518. //
  519. // dwPropertyModifers should be 0
  520. //
  521. if (0 != dwPropertyModifiers)
  522. {
  523. THROW(APPMAN_E_INVALIDPROPERTY);
  524. }
  525. //
  526. // Make sure dwDataLen is correct
  527. //
  528. if (gPropertyInfo[dwPropertyIndex].dwMaxLen != dwDataLen)
  529. {
  530. THROW(APPMAN_E_INVALIDPROPERTYSIZE);
  531. }
  532. //
  533. // Since the property is a GUID or a DWORD, the dwDatalen should be fixed
  534. //
  535. if ((NULL == lpData)||(IsBadReadPtr(lpData, dwDataLen)))
  536. {
  537. THROW(APPMAN_E_INVALIDPARAMETERS);
  538. }
  539. }
  540. else
  541. {
  542. //
  543. // The property is a string.
  544. //
  545. if (NULL != lpData)
  546. {
  547. if (0 == dwDataLen)
  548. {
  549. THROW(APPMAN_E_INVALIDPROPERTYSIZE);
  550. }
  551. //
  552. // First determine whether or not we can actual read the incoming string
  553. //
  554. if (IsBadReadPtr(lpData, dwDataLen))
  555. {
  556. THROW(APPMAN_E_INVALIDPARAMETERS);
  557. }
  558. //
  559. // Determine the character count in the incoming string
  560. //
  561. if (APP_PROPERTY_STR_ANSI == dwPropertyModifiers)
  562. {
  563. dwCharCount = StrLenA((LPSTR) lpData);
  564. }
  565. else
  566. {
  567. if ((APP_PROPERTY_STR_UNICODE == dwPropertyModifiers)||(0 == dwPropertyModifiers))
  568. {
  569. dwCharCount = StrLenW((LPWSTR) lpData);
  570. }
  571. else
  572. {
  573. THROW(APPMAN_E_INVALIDPROPERTYVALUE);
  574. }
  575. }
  576. //
  577. // Determine whether or not the storage buffer are big enough for the incoming string
  578. //
  579. if (gPropertyInfo[dwPropertyIndex].dwMaxLen < dwCharCount)
  580. {
  581. THROW(APPMAN_E_OVERFLOW);
  582. }
  583. }
  584. }
  585. return S_OK;
  586. }
  587. //////////////////////////////////////////////////////////////////////////////////////////////
  588. //
  589. //////////////////////////////////////////////////////////////////////////////////////////////
  590. STDMETHODIMP CApplicationEntry::ValidateCommandLine(LPCWSTR wszRootPath, LPCWSTR wszCommandLine)
  591. {
  592. FUNCTION("CAppEntry::ValidateCommandLine ()");
  593. CWin32API Win32API;
  594. BOOL fApplicationExists = FALSE;
  595. DWORD dwIndex, dwRootPathLen, dwCommandLineLen;
  596. WCHAR wszTempPath[MAX_PATH_CHARCOUNT+1];
  597. dwRootPathLen = wcslen(wszRootPath);
  598. dwCommandLineLen = wcslen(wszCommandLine);
  599. ZeroMemory(wszTempPath, sizeof(wszTempPath));
  600. wcscpy(wszTempPath, wszCommandLine);
  601. //
  602. // Make sure that wszRootPath is the subpath of wszCommandLine
  603. //
  604. if (0 != _wcsnicmp(wszRootPath, wszCommandLine, dwRootPathLen))
  605. {
  606. return E_FAIL;
  607. }
  608. //
  609. // At this point we go looking for .exe/.bat/.com and try to findfirstfile on the string
  610. //
  611. dwIndex = dwRootPathLen;
  612. while ((FALSE == fApplicationExists)&&(dwIndex <= dwCommandLineLen))
  613. {
  614. //
  615. // Slowly increment the wszTempPath string
  616. //
  617. wszTempPath[dwIndex] = wszCommandLine[dwIndex];
  618. dwIndex++;
  619. wszTempPath[dwIndex] = 0;
  620. if (4 < dwIndex)
  621. {
  622. //
  623. // Are the last 4 characters of wszTEmpPath ".EXE"
  624. //
  625. if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".EXE", 4))
  626. {
  627. if (Win32API.FileExists(wszTempPath))
  628. {
  629. if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath)))
  630. {
  631. fApplicationExists = TRUE;
  632. }
  633. }
  634. }
  635. //
  636. // Are the last 4 characters of wszTEmpPath ".BAT"
  637. //
  638. if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".BAT", 4))
  639. {
  640. if (Win32API.FileExists(wszTempPath))
  641. {
  642. if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath)))
  643. {
  644. fApplicationExists = TRUE;
  645. }
  646. }
  647. }
  648. //
  649. // Are the last 4 characters of wszTEmpPath ".COM"
  650. //
  651. if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".COM", 4))
  652. {
  653. if (Win32API.FileExists(wszTempPath))
  654. {
  655. if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath)))
  656. {
  657. fApplicationExists = TRUE;
  658. }
  659. }
  660. }
  661. //
  662. // Are the last 4 characters of wszTEmpPath ".CMD"
  663. //
  664. if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".CMD", 4))
  665. {
  666. if (Win32API.FileExists(wszTempPath))
  667. {
  668. if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath)))
  669. {
  670. fApplicationExists = TRUE;
  671. }
  672. }
  673. }
  674. }
  675. }
  676. if (FALSE == fApplicationExists)
  677. {
  678. return S_FALSE;
  679. }
  680. else
  681. {
  682. return S_OK;
  683. }
  684. }
  685. //////////////////////////////////////////////////////////////////////////////////////////////
  686. //
  687. // TODO : Insert checking to make sure properties are not set at a bad time
  688. //
  689. //////////////////////////////////////////////////////////////////////////////////////////////
  690. STDMETHODIMP CApplicationEntry::SetProperty(const DWORD dwProperty, LPCVOID lpData, const DWORD dwDataLen)
  691. {
  692. FUNCTION("CAppEntry::SetProperty ()");
  693. DPFMSG(MakeString("dwProperty = 0x%08x", dwProperty));
  694. HRESULT hResult = S_OK;
  695. ///////////////////////////////////////////////////////////////////////////////////////
  696. try
  697. {
  698. CLock sLock(&m_sCriticalSection);
  699. DWORD dwFilteredProperty, dwPropertyModifiers, dwPropertyIndex;
  700. DWORD dwStringIndex, dwCharCount;
  701. if (FALSE == m_fIsInitialized)
  702. {
  703. THROW(APPMAN_E_NOTINITIALIZED);
  704. }
  705. sLock.Lock();
  706. //
  707. // Extract the filtered property value and the property modifier value
  708. //
  709. dwFilteredProperty = dwProperty & 0x0000ffff;
  710. dwPropertyModifiers = dwProperty & 0xffff0000;
  711. //
  712. // Was the property passed in a valid property value
  713. //
  714. if (S_OK != m_InformationManager.IsValidApplicationProperty(dwFilteredProperty))
  715. {
  716. THROW(APPMAN_E_INVALIDPROPERTY);
  717. }
  718. //
  719. // Get the internal property index for dwProperty
  720. //
  721. dwPropertyIndex = m_InformationManager.GetPropertyIndex(dwFilteredProperty);
  722. //
  723. // Are the dwProperty/lpData/dwDataLen parameters valid and properly sized
  724. //
  725. ValidateSetPropertyParameters(dwPropertyIndex, dwPropertyModifiers, lpData, dwDataLen);
  726. //
  727. // Get the property
  728. //
  729. dwStringIndex = gPropertyInfo[dwPropertyIndex].dwStringId;
  730. if (APP_STRING_NONE == dwStringIndex)
  731. {
  732. switch(dwPropertyIndex)
  733. {
  734. case IDX_PROPERTY_GUID
  735. : memcpy(&m_sApplicationData.sBaseInfo.sApplicationGuid, lpData, sizeof(GUID));
  736. break;
  737. case IDX_PROPERTY_STATE
  738. : m_sApplicationData.sBaseInfo.dwState = *((LPDWORD) lpData);
  739. if (APP_STATE_DOWNSIZED != m_sApplicationData.sBaseInfo.dwState)
  740. {
  741. THROW(APPMAN_E_INVALIDPROPERTYVALUE);
  742. }
  743. break;
  744. case IDX_PROPERTY_CATEGORY
  745. : m_sApplicationData.sBaseInfo.dwCategory = *((LPDWORD) lpData);
  746. if (((~APP_CATEGORY_ALL) & m_sApplicationData.sBaseInfo.dwCategory)||(!(0x0000ffff & m_sApplicationData.sBaseInfo.dwCategory)))
  747. {
  748. THROW(APPMAN_E_INVALIDPROPERTYVALUE);
  749. }
  750. break;
  751. case IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES
  752. : m_sApplicationData.sBaseInfo.dwReservedKilobytes = *((LPDWORD) lpData);
  753. break;
  754. case IDX_PROPERTY_NONREMOVABLEKILOBYTES
  755. :
  756. break;
  757. case IDX_PROPERTY_REMOVABLEKILOBYTES
  758. :
  759. break;
  760. case IDX_PROPERTY_INSTALLDATE:
  761. case IDX_PROPERTY_LASTUSEDDATE
  762. : THROW(APPMAN_E_READONLYPROPERTY);
  763. break;
  764. default
  765. : THROW(E_UNEXPECTED);
  766. break;
  767. }
  768. }
  769. else
  770. {
  771. //
  772. // Are we dealing with the APP_PROPERTY_ROOTPATH
  773. //
  774. if (IDX_PROPERTY_ROOTPATH == dwPropertyIndex)
  775. {
  776. DWORD dwAdvancedMode = 0;
  777. m_InformationManager.GetAdvancedMode(&dwAdvancedMode);
  778. if (0 == dwAdvancedMode)
  779. {
  780. THROW(APPMAN_E_READONLYPROPERTY);
  781. }
  782. else
  783. {
  784. if (0 != m_sApplicationData.sAssociation.dwAssociationType)
  785. {
  786. THROW(APPMAN_E_READONLYPROPERTY);
  787. }
  788. }
  789. }
  790. //
  791. // Make ANSI into UNICODE string if required
  792. //
  793. if (APP_PROPERTY_STR_ANSI & dwProperty)
  794. {
  795. dwCharCount = StrLenA((LPSTR) lpData);
  796. CWin32API::MultiByteToWideChar((LPCSTR) lpData, dwDataLen, m_sApplicationData.wszStringProperty[dwStringIndex], MAX_PATH_CHARCOUNT);
  797. }
  798. else
  799. {
  800. dwCharCount = StrLenW((LPWSTR) lpData);
  801. memcpy((LPVOID) m_sApplicationData.wszStringProperty[dwStringIndex], (LPVOID) lpData, dwDataLen);
  802. }
  803. //
  804. // Make sure that the value we have just set is a valid string
  805. //
  806. ValidateStringProperty(dwPropertyIndex, dwPropertyModifiers, m_sApplicationData.wszStringProperty[dwStringIndex]);
  807. }
  808. //
  809. // Make sure the validate the newly set property
  810. //
  811. m_InformationManager.ValidateApplicationPropertyWithIndex(dwPropertyIndex, &m_sApplicationData);
  812. sLock.UnLock();
  813. }
  814. ///////////////////////////////////////////////////////////////////////////////////////
  815. catch(CAppManExceptionHandler * pException)
  816. {
  817. hResult = pException->GetResultCode();
  818. delete pException;
  819. }
  820. catch(...)
  821. {
  822. hResult = E_UNEXPECTED;
  823. }
  824. ///////////////////////////////////////////////////////////////////////////////////////
  825. return hResult;
  826. }
  827. //////////////////////////////////////////////////////////////////////////////////////////////
  828. //
  829. //////////////////////////////////////////////////////////////////////////////////////////////
  830. STDMETHODIMP CApplicationEntry::GetProperty(const DWORD dwProperty, LPVOID lpData, const DWORD dwDataLen)
  831. {
  832. FUNCTION("CAppEntry::GetProperty ()");
  833. DPFMSG(MakeString("dwProperty = 0x%08x", dwProperty));
  834. HRESULT hResult = S_OK;
  835. ///////////////////////////////////////////////////////////////////////////////////////
  836. try
  837. {
  838. CLock sLock(&m_sCriticalSection);
  839. DWORD dwFilteredProperty, dwPropertyModifiers, dwPropertyIndex, dwCharCount, dwStringIndex;
  840. if (FALSE == m_fIsInitialized)
  841. {
  842. THROW(APPMAN_E_NOTINITIALIZED);
  843. }
  844. sLock.Lock();
  845. //
  846. // Extract the filtered property value and the property modifier value
  847. //
  848. dwFilteredProperty = dwProperty & 0x0000ffff;
  849. dwPropertyModifiers = dwProperty & 0xffff0000;
  850. //
  851. // Was the property passed in a valid property value
  852. //
  853. if (S_OK != m_InformationManager.IsValidApplicationProperty(dwFilteredProperty))
  854. {
  855. THROW(APPMAN_E_INVALIDPROPERTY);
  856. }
  857. //
  858. // Get the internal property index for dwProperty
  859. //
  860. dwPropertyIndex = m_InformationManager.GetPropertyIndex(dwFilteredProperty);
  861. //
  862. // Are the dwProperty/lpData/dwDataLen parameters valid and properly sized
  863. //
  864. ValidateGetPropertyParameters(dwPropertyIndex, dwPropertyModifiers, lpData, dwDataLen);
  865. //
  866. // Get the property
  867. //
  868. dwStringIndex = gPropertyInfo[dwPropertyIndex].dwStringId;
  869. if (APP_STRING_NONE == dwStringIndex)
  870. {
  871. switch(dwPropertyIndex)
  872. {
  873. case IDX_PROPERTY_GUID
  874. : memcpy((LPVOID) lpData, (LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID));
  875. break;
  876. case IDX_PROPERTY_STATE
  877. : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwState;
  878. break;
  879. case IDX_PROPERTY_CATEGORY
  880. : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwCategory;
  881. break;
  882. case IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES
  883. : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwReservedKilobytes;
  884. break;
  885. case IDX_PROPERTY_NONREMOVABLEKILOBYTES
  886. : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes;
  887. break;
  888. case IDX_PROPERTY_REMOVABLEKILOBYTES
  889. : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwRemovableKilobytes;
  890. break;
  891. case IDX_PROPERTY_INSTALLDATE
  892. : memcpy((LPVOID) lpData, (LPVOID) &m_sApplicationData.sAgingInfo.stInstallDate, sizeof(SYSTEMTIME));
  893. break;
  894. case IDX_PROPERTY_LASTUSEDDATE
  895. : memcpy((LPVOID) lpData, (LPVOID) &m_sApplicationData.sAgingInfo.stLastUsedDate, sizeof(SYSTEMTIME));
  896. break;
  897. case IDX_PROPERTY_PIN
  898. : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwPinState;
  899. break;
  900. default
  901. : THROW(E_UNEXPECTED);
  902. break;
  903. }
  904. }
  905. else
  906. {
  907. if (APP_PROPERTY_STR_ANSI == dwPropertyModifiers)
  908. {
  909. dwCharCount = StrLenW((LPWSTR) m_sApplicationData.wszStringProperty[dwStringIndex]);
  910. if (dwDataLen < dwCharCount)
  911. {
  912. THROW(APPMAN_E_OVERFLOW);
  913. }
  914. CWin32API::WideCharToMultiByte((LPCWSTR) m_sApplicationData.wszStringProperty[dwStringIndex], MAX_PATH_CHARCOUNT, (LPSTR) lpData, dwDataLen);
  915. }
  916. else
  917. {
  918. dwCharCount = StrLenW((LPWSTR) m_sApplicationData.wszStringProperty[dwStringIndex]);
  919. if (dwDataLen < (dwCharCount*2))
  920. {
  921. THROW(APPMAN_E_OVERFLOW);
  922. }
  923. memcpy((LPVOID) lpData, (LPVOID) m_sApplicationData.wszStringProperty[dwStringIndex], dwCharCount*2);
  924. }
  925. }
  926. sLock.UnLock();
  927. }
  928. ///////////////////////////////////////////////////////////////////////////////////////
  929. catch(CAppManExceptionHandler * pException)
  930. {
  931. hResult = pException->GetResultCode();
  932. delete pException;
  933. }
  934. catch(...)
  935. {
  936. hResult = E_UNEXPECTED;
  937. }
  938. ///////////////////////////////////////////////////////////////////////////////////////
  939. return hResult;
  940. }
  941. //////////////////////////////////////////////////////////////////////////////////////////////
  942. //
  943. // The InitializeInstall() method will do the following actions before successfully returning.
  944. // If any of these steps fail, the method will return a failure.
  945. //
  946. // (1) Make sure the application object is not undergoing any other action
  947. // (2) Make sure that APP_PROPERTY_TYPE is set
  948. // (3) Make sure that APP_PROPERTY_SIGNATURE is set
  949. // (4) Make sure that APP_PROPERTY_ESTIMATED_INSTALL_SIZE is set
  950. // (5) Make sure that the application is not already installed
  951. // (6) Make sure to set the state of the application to APP_STATE_INSTALLING
  952. // (7) Explicitly call m_InformationManager.SetApplicationInfo() in order to prevent
  953. // step (8) from happening in case of a failure
  954. // (8) Make sure to set the state of the m_dwCurrentAction
  955. //
  956. //////////////////////////////////////////////////////////////////////////////////////////////
  957. STDMETHODIMP CApplicationEntry::InitializeInstall(void)
  958. {
  959. FUNCTION("CAppEntry::InitializeInstall ()");
  960. HRESULT hResult = S_OK;
  961. BOOL fParentLocked = FALSE;
  962. ///////////////////////////////////////////////////////////////////////////////////////
  963. try
  964. {
  965. CWin32API Win32API;
  966. DWORD dwIndex, dwReservedKilobytes, dwAdvancedMode;
  967. BOOL fApplicationRootExists;
  968. APPLICATION_DATA sApplicationData;
  969. DEVICE_RECORD sDeviceRecord;
  970. WCHAR wszRootPath[5];
  971. GUID sPathGuid;
  972. //
  973. // Make sure this object is not currently being used in another action
  974. //
  975. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  976. {
  977. THROW(APPMAN_E_ACTIONINPROGRESS);
  978. }
  979. //
  980. // Get the advanced mode
  981. //
  982. m_InformationManager.GetAdvancedMode(&dwAdvancedMode);
  983. //
  984. // Make sure the required fields are present
  985. //
  986. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_COMPANYNAME, &m_sApplicationData))
  987. {
  988. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  989. }
  990. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SIGNATURE, &m_sApplicationData))
  991. {
  992. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  993. }
  994. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_CATEGORY, &m_sApplicationData))
  995. {
  996. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  997. }
  998. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES, &m_sApplicationData))
  999. {
  1000. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1001. }
  1002. if ((0 < dwAdvancedMode)&&(0 == m_sApplicationData.sAssociation.dwAssociationType))
  1003. {
  1004. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData))
  1005. {
  1006. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1007. }
  1008. else
  1009. {
  1010. if (FALSE == Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]))
  1011. {
  1012. //
  1013. // We want to see if we can even create this directory. If we can, delete it right
  1014. // away in order to make sure that an empty directory is not created until we absolutely
  1015. // have to
  1016. //
  1017. if (!Win32API.CreateDirectory(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], TRUE))
  1018. {
  1019. THROW(APPMAN_E_INVALIDROOTPATH);
  1020. }
  1021. else
  1022. {
  1023. Win32API.RemoveDirectory(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]);
  1024. }
  1025. }
  1026. }
  1027. }
  1028. //
  1029. // Since this should be a new application
  1030. //
  1031. m_sApplicationData.sBaseInfo.dwPinState = FALSE;
  1032. VALIDATE_PROPERTY(IDX_PROPERTY_PIN);
  1033. //
  1034. // Is this is a brand new application entry
  1035. //
  1036. if (S_FALSE == m_InformationManager.CheckApplicationExistance(&m_sApplicationData))
  1037. {
  1038. DWORD dwDeviceIndex;
  1039. WCHAR wszAppManRoot[MAX_PATH_CHARCOUNT];
  1040. WCHAR wszAppManSetup[MAX_PATH_CHARCOUNT];
  1041. WCHAR wszCategory[MAX_PATH_CHARCOUNT];
  1042. //
  1043. // Initialize the path substrings
  1044. //
  1045. (OS_VERSION_9x & Win32API.GetOSVersion()) ? GetResourceStringW(IDS_APPMAN9x, wszAppManRoot, MAX_PATH_CHARCOUNT): GetResourceStringW(IDS_APPMANNT, wszAppManRoot, MAX_PATH_CHARCOUNT);
  1046. GetResourceStringW(IDS_APPMAN, wszAppManSetup, MAX_PATH_CHARCOUNT);
  1047. switch(GET_APPLICATIONCATEGORY())
  1048. {
  1049. case APP_CATEGORY_MISC:
  1050. case APP_CATEGORY_NONE
  1051. : ZeroMemory(wszCategory, sizeof(wszCategory));
  1052. break;
  1053. case APP_CATEGORY_ENTERTAINMENT
  1054. : GetResourceStringW(IDS_ENTERTAINMENT, wszCategory, MAX_PATH_CHARCOUNT);
  1055. break;
  1056. case APP_CATEGORY_PRODUCTIVITY
  1057. : GetResourceStringW(IDS_PRODUCTIVITY, wszCategory, MAX_PATH_CHARCOUNT);
  1058. break;
  1059. case APP_CATEGORY_PUBLISHING
  1060. : GetResourceStringW(IDS_PUBLISHING, wszCategory, MAX_PATH_CHARCOUNT);
  1061. break;
  1062. case APP_CATEGORY_SCIENTIFIC
  1063. : GetResourceStringW(IDS_SCIENTIFIC, wszCategory, MAX_PATH_CHARCOUNT);
  1064. break;
  1065. case APP_CATEGORY_AUTHORING
  1066. : GetResourceStringW(IDS_AUTHORING, wszCategory, MAX_PATH_CHARCOUNT);
  1067. break;
  1068. case APP_CATEGORY_MEDICAL
  1069. : GetResourceStringW(IDS_MEDICAL, wszCategory, MAX_PATH_CHARCOUNT);
  1070. break;
  1071. case APP_CATEGORY_BUSINESS
  1072. : GetResourceStringW(IDS_BUSINESS, wszCategory, MAX_PATH_CHARCOUNT);
  1073. break;
  1074. case APP_CATEGORY_FINANCIAL
  1075. : GetResourceStringW(IDS_FINANCIAL, wszCategory, MAX_PATH_CHARCOUNT);
  1076. break;
  1077. case APP_CATEGORY_EDUCATIONAL
  1078. : GetResourceStringW(IDS_EDUCATIONAL, wszCategory, MAX_PATH_CHARCOUNT);
  1079. break;
  1080. case APP_CATEGORY_REFERENCE
  1081. : GetResourceStringW(IDS_REFERENCE, wszCategory, MAX_PATH_CHARCOUNT);
  1082. break;
  1083. case APP_CATEGORY_WEB
  1084. : GetResourceStringW(IDS_WEB, wszCategory, MAX_PATH_CHARCOUNT);
  1085. break;
  1086. case APP_CATEGORY_DEVELOPMENTTOOL
  1087. : GetResourceStringW(IDS_DEVTOOL, wszCategory, MAX_PATH_CHARCOUNT);
  1088. break;
  1089. case APP_CATEGORY_MULTIMEDIA
  1090. : GetResourceStringW(IDS_MULTIMEDIA, wszCategory, MAX_PATH_CHARCOUNT);
  1091. break;
  1092. case APP_CATEGORY_VIRUSCLEANER
  1093. : GetResourceStringW(IDS_VIRUSCLEANER, wszCategory, MAX_PATH_CHARCOUNT);
  1094. break;
  1095. case APP_CATEGORY_CONNECTIVITY
  1096. : GetResourceStringW(IDS_CONNECTIVITY, wszCategory, MAX_PATH_CHARCOUNT);
  1097. break;
  1098. }
  1099. //
  1100. // Initialize the aging information
  1101. //
  1102. m_sApplicationData.sAgingInfo.dwInstallCost = 0;
  1103. m_sApplicationData.sAgingInfo.dwReInstallCount = 0;
  1104. m_sApplicationData.sAgingInfo.dwUsageCount = 0;
  1105. GetLocalTime(&(m_sApplicationData.sAgingInfo.stInstallDate));
  1106. VALIDATE_PROPERTY(IDX_PROPERTY_INSTALLDATE);
  1107. GetLocalTime(&(m_sApplicationData.sAgingInfo.stLastUsedDate));
  1108. VALIDATE_PROPERTY(IDX_PROPERTY_LASTUSEDDATE);
  1109. //
  1110. // Is this application associated with anything at all
  1111. //
  1112. if (0 != m_sApplicationData.sAssociation.dwAssociationType)
  1113. {
  1114. //
  1115. // Go get the application data of the associated application
  1116. //
  1117. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &m_sApplicationData.sAssociation.sParentGuid, sizeof(GUID));
  1118. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  1119. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  1120. if (FAILED(hResult))
  1121. {
  1122. THROW(APPMAN_E_INVALIDASSOCIATION);
  1123. }
  1124. //
  1125. // Make sure the parent is in a ready state
  1126. //
  1127. hResult = m_InformationManager.ReadyApplication(&sApplicationData);
  1128. if (FAILED(hResult))
  1129. {
  1130. THROW(APPMAN_E_APPLICATIONREQUIRED);
  1131. }
  1132. //
  1133. // Lock the parent applications
  1134. //
  1135. hResult = m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid);
  1136. if (FAILED(hResult))
  1137. {
  1138. THROW(hResult);
  1139. }
  1140. else
  1141. {
  1142. fParentLocked = TRUE;
  1143. }
  1144. //
  1145. // Go get the device index of the associated applications
  1146. //
  1147. memcpy((LPVOID) &sDeviceRecord.sDeviceGuid, (LPVOID) &sApplicationData.sBaseInfo.sDeviceGuid, sizeof(GUID));
  1148. hResult = m_InformationManager.GetDeviceInfo(&sDeviceRecord);
  1149. if (FAILED(hResult))
  1150. {
  1151. THROW(E_UNEXPECTED);
  1152. }
  1153. dwDeviceIndex = sDeviceRecord.sDeviceInfo.dwDeviceIndex;
  1154. //
  1155. // Go get the space required to install the application on the device
  1156. //
  1157. hResult = m_InformationManager.FreeSpaceOnDevice(&sDeviceRecord.sDeviceGuid, m_sApplicationData.sBaseInfo.dwReservedKilobytes);
  1158. if (FAILED(hResult))
  1159. {
  1160. THROW(APPMAN_E_NODISKSPACEAVAILABLE);
  1161. }
  1162. //
  1163. // Add the application to the database and then assign it a device. Note that we do
  1164. // not have to check for success code since these methods throw exceptions on error
  1165. //
  1166. m_InformationManager.AddApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1167. m_InformationManager.AssignDeviceToApplication(dwDeviceIndex, &m_sApplicationData);
  1168. //
  1169. // Lock the application
  1170. //
  1171. LockApplication();
  1172. //
  1173. // Setup the root paths and setup root paths depending on association type
  1174. //
  1175. switch(m_sApplicationData.sAssociation.dwAssociationType)
  1176. {
  1177. case APP_ASSOCIATION_INHERITBOTHPATHS // inherits both setup and application root paths
  1178. : memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], MAX_PATH_CHARCOUNT+1);
  1179. memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], MAX_PATH_CHARCOUNT+1);
  1180. VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH);
  1181. VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH);
  1182. break;
  1183. case APP_ASSOCIATION_INHERITAPPROOTPATH // inherits application root path
  1184. : memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], MAX_PATH_CHARCOUNT+1);
  1185. if (FAILED(CoCreateGuid(&sPathGuid)))
  1186. {
  1187. THROW(E_UNEXPECTED);
  1188. }
  1189. swprintf(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], L"%c:\\%s\\%s\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", dwDeviceIndex + 65, wszAppManRoot, wszAppManSetup, sPathGuid.Data1, sPathGuid.Data2, sPathGuid.Data3, sPathGuid.Data4[0], sPathGuid.Data4[1], sPathGuid.Data4[2], sPathGuid.Data4[3], sPathGuid.Data4[4], sPathGuid.Data4[5], sPathGuid.Data4[6], sPathGuid.Data4[7]);
  1190. VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH);
  1191. VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH);
  1192. break;
  1193. case APP_ASSOCIATION_INHERITSETUPROOTPATH // inherits setup root path and is rooted within application root path
  1194. : swprintf(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], L"%s\\%s", sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_SIGNATURE]);
  1195. VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH);
  1196. memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], MAX_PATH_CHARCOUNT+1);
  1197. VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH);
  1198. break;
  1199. default
  1200. : THROW(APPMAN_E_INVALIDASSOCIATION);
  1201. break;
  1202. }
  1203. //
  1204. // Record the application guid within the association
  1205. //
  1206. memcpy((LPVOID) &m_sApplicationData.sAssociation.sChildGuid, (LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID));
  1207. //
  1208. // Set the application data into the registry
  1209. //
  1210. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1211. //
  1212. // Add the association
  1213. //
  1214. m_InformationManager.AddAssociation(&m_sApplicationData.sAssociation);
  1215. }
  1216. else
  1217. {
  1218. //
  1219. // Are we in advanced mode
  1220. //
  1221. if (0 != dwAdvancedMode)
  1222. {
  1223. DWORD dwBaseIndex;
  1224. //
  1225. // Figure out where the first legal character is in the root path
  1226. //
  1227. dwBaseIndex = 0;
  1228. while ((dwBaseIndex < StrLenW(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]))&&(!((65 <= m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH][dwBaseIndex])&&(90 >= m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH][dwBaseIndex]))&&(!((97 <= m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH][dwBaseIndex])&&(122 >= m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH][dwBaseIndex])))))
  1229. {
  1230. dwBaseIndex++;
  1231. }
  1232. if (!(dwBaseIndex < StrLenW(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH])))
  1233. {
  1234. THROW(APPMAN_E_INVALIDROOTPATH);
  1235. }
  1236. //
  1237. // Figure out which drive it is supposed to be in
  1238. //
  1239. dwIndex = 0;
  1240. do
  1241. {
  1242. dwDeviceIndex = dwIndex;
  1243. swprintf(wszRootPath, L"%c:\\", dwDeviceIndex + 65);
  1244. dwIndex++;
  1245. } while ((26 > dwIndex)&&(0 != _wcsnicmp(wszRootPath, &(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH][dwBaseIndex]), 3)));
  1246. //
  1247. // Did we fail to find a matching device string
  1248. //
  1249. if (26 <= dwIndex)
  1250. {
  1251. THROW(APPMAN_E_INVALIDROOTPATH);
  1252. }
  1253. //
  1254. // Go get the device index of the associated applications
  1255. //
  1256. hResult = m_InformationManager.GetDeviceInfoWithIndex(dwDeviceIndex, &sDeviceRecord);
  1257. if (FAILED(hResult))
  1258. {
  1259. THROW(E_UNEXPECTED);
  1260. }
  1261. //
  1262. // Go get the space required to install the application on the device
  1263. //
  1264. hResult = m_InformationManager.FreeSpaceOnDevice(&sDeviceRecord.sDeviceGuid, m_sApplicationData.sBaseInfo.dwReservedKilobytes);
  1265. if (FAILED(hResult))
  1266. {
  1267. THROW(APPMAN_E_NODISKSPACEAVAILABLE);
  1268. }
  1269. //
  1270. // Add the application to the database and then assign it a device. Note that we do
  1271. // not have to check for success code since these methods throw exceptions on error
  1272. //
  1273. m_InformationManager.AddApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1274. m_InformationManager.AssignDeviceToApplication(dwDeviceIndex, &m_sApplicationData);
  1275. //
  1276. // Lock the application
  1277. //
  1278. LockApplication();
  1279. //
  1280. // Setup the setup root paths depending on association type
  1281. //
  1282. if (FAILED(CoCreateGuid(&sPathGuid)))
  1283. {
  1284. THROW(E_UNEXPECTED);
  1285. }
  1286. swprintf(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], L"%c:\\%s\\%s\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", dwDeviceIndex + 65, wszAppManRoot, wszAppManSetup, sPathGuid.Data1, sPathGuid.Data2, sPathGuid.Data3, sPathGuid.Data4[0], sPathGuid.Data4[1], sPathGuid.Data4[2], sPathGuid.Data4[3], sPathGuid.Data4[4], sPathGuid.Data4[5], sPathGuid.Data4[6], sPathGuid.Data4[7]);
  1287. VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH);
  1288. //
  1289. // Set the application data into the registry
  1290. //
  1291. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1292. }
  1293. else
  1294. {
  1295. //
  1296. // Check to see if the application root path already exists on a device and if so,
  1297. // attempt to install the application on that device
  1298. //
  1299. fApplicationRootExists = FALSE;
  1300. dwDeviceIndex = 0xffffffff;
  1301. dwIndex = 2;
  1302. do
  1303. {
  1304. //
  1305. // Build the application root path
  1306. //
  1307. if (1 == StrLenW(wszCategory))
  1308. {
  1309. swprintf(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], L"%c:\\%s\\%s\\%s", dwIndex + 65, wszAppManRoot, m_sApplicationData.wszStringProperty[APP_STRING_COMPANYNAME], m_sApplicationData.wszStringProperty[APP_STRING_SIGNATURE]);
  1310. }
  1311. else
  1312. {
  1313. swprintf(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], L"%c:\\%s\\%s\\%s\\%s", dwIndex + 65, wszAppManRoot, wszCategory, m_sApplicationData.wszStringProperty[APP_STRING_COMPANYNAME], m_sApplicationData.wszStringProperty[APP_STRING_SIGNATURE]);
  1314. }
  1315. //
  1316. // Check to see whether or not it exists
  1317. //
  1318. swprintf(wszRootPath, L"%c:\\", dwIndex + 65);
  1319. if (DRIVE_FIXED == Win32API.GetDriveType(wszRootPath))
  1320. {
  1321. fApplicationRootExists = Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]);
  1322. if (TRUE == fApplicationRootExists)
  1323. {
  1324. dwDeviceIndex = dwIndex;
  1325. }
  1326. }
  1327. dwIndex++;
  1328. }
  1329. while ((FALSE == fApplicationRootExists)&&(26 > dwIndex));
  1330. //
  1331. // Go get the space
  1332. //
  1333. hResult = APPMAN_E_NODISKSPACEAVAILABLE;
  1334. if (0xffffffff != dwDeviceIndex)
  1335. {
  1336. //
  1337. // The root path of the application was found on device dwDeviceIndex. Is this
  1338. // device excluded
  1339. //
  1340. m_InformationManager.GetDeviceInfoWithIndex(dwDeviceIndex, &sDeviceRecord);
  1341. if (0 == (m_sApplicationData.sBaseInfo.dwCategory & sDeviceRecord.sDeviceInfo.dwApplicationCategoryExclusionMask))
  1342. {
  1343. hResult = m_InformationManager.FreeSpaceOnDevice(&sDeviceRecord.sDeviceGuid, m_sApplicationData.sBaseInfo.dwReservedKilobytes);
  1344. }
  1345. }
  1346. if (FAILED(hResult))
  1347. {
  1348. //
  1349. // We failed to get space on the device that contained the legacy application
  1350. // root path. Therefore, we fall back
  1351. //
  1352. hResult = m_InformationManager.GetSpace(m_sApplicationData.sBaseInfo.dwCategory, m_sApplicationData.sBaseInfo.dwReservedKilobytes, &dwDeviceIndex);
  1353. }
  1354. //
  1355. // Go get the space
  1356. //
  1357. if (SUCCEEDED(hResult))
  1358. {
  1359. //
  1360. // Add the application to the database and then assign it a device. Note that we do
  1361. // not have to check for success code since these methods throw exceptions on error
  1362. //
  1363. m_InformationManager.AddApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1364. m_InformationManager.AssignDeviceToApplication(dwDeviceIndex, &m_sApplicationData);
  1365. //
  1366. // Lock the application
  1367. //
  1368. LockApplication();
  1369. //
  1370. // Create the root paths
  1371. //
  1372. if (1 == StrLenW(wszCategory))
  1373. {
  1374. swprintf(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], L"%c:\\%s\\%s\\%s", dwDeviceIndex + 65, wszAppManRoot, m_sApplicationData.wszStringProperty[APP_STRING_COMPANYNAME], m_sApplicationData.wszStringProperty[APP_STRING_SIGNATURE]);
  1375. }
  1376. else
  1377. {
  1378. swprintf(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], L"%c:\\%s\\%s\\%s\\%s", dwDeviceIndex + 65, wszAppManRoot, wszCategory, m_sApplicationData.wszStringProperty[APP_STRING_COMPANYNAME], m_sApplicationData.wszStringProperty[APP_STRING_SIGNATURE]);
  1379. }
  1380. if (FAILED(CoCreateGuid(&sPathGuid)))
  1381. {
  1382. THROW(E_UNEXPECTED);
  1383. }
  1384. swprintf(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], L"%c:\\%s\\%s\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", dwDeviceIndex + 65, wszAppManRoot, wszAppManSetup, sPathGuid.Data1, sPathGuid.Data2, sPathGuid.Data3, sPathGuid.Data4[0], sPathGuid.Data4[1], sPathGuid.Data4[2], sPathGuid.Data4[3], sPathGuid.Data4[4], sPathGuid.Data4[5], sPathGuid.Data4[6], sPathGuid.Data4[7]);
  1385. VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH);
  1386. VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH);
  1387. //
  1388. // Set the Appplication Info
  1389. //
  1390. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1391. }
  1392. else
  1393. {
  1394. THROW(APPMAN_E_NODISKSPACEAVAILABLE);
  1395. }
  1396. }
  1397. }
  1398. }
  1399. else
  1400. {
  1401. //
  1402. // Let's get the current information about this application
  1403. //
  1404. hResult = m_InformationManager.GetApplicationData(&m_sApplicationData);
  1405. if (FAILED(hResult))
  1406. {
  1407. THROW(E_UNEXPECTED);
  1408. }
  1409. //
  1410. // First we lock the application
  1411. //
  1412. LockApplication();
  1413. //
  1414. // Save the reserved space into dwReservedKilobytes temporarily
  1415. //
  1416. dwReservedKilobytes = m_sApplicationData.sBaseInfo.dwReservedKilobytes;
  1417. //
  1418. // Get the application information as registered within the database.
  1419. //
  1420. if (FAILED(m_InformationManager.GetApplicationData(&m_sApplicationData)))
  1421. {
  1422. SetInitializationLevel(INIT_LEVEL_BASIC);
  1423. THROW(E_UNEXPECTED);
  1424. }
  1425. //
  1426. // Restore the dwReservedKilobytes value
  1427. //
  1428. m_sApplicationData.sBaseInfo.dwReservedKilobytes = dwReservedKilobytes;
  1429. VALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
  1430. //
  1431. // Make sure the app is in an APP_STATE_INSTALLING state
  1432. //
  1433. if (!CHECK_APPLICATIONSTATE(APP_STATE_INSTALLING))
  1434. {
  1435. SetInitializationLevel(INIT_LEVEL_BASIC);
  1436. THROW(APPMAN_E_APPLICATIONALREADYEXISTS);
  1437. }
  1438. //
  1439. // Go get the space
  1440. //
  1441. if (FAILED(m_InformationManager.FreeSpaceOnDevice(&(m_sApplicationData.sBaseInfo.sDeviceGuid), m_sApplicationData.sBaseInfo.dwReservedKilobytes)))
  1442. {
  1443. THROW(APPMAN_E_NODISKSPACEAVAILABLE);
  1444. }
  1445. }
  1446. //
  1447. // Create the root paths if required
  1448. //
  1449. if (FALSE == Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]))
  1450. {
  1451. Win32API.CreateDirectory(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], TRUE);
  1452. }
  1453. if (FALSE == Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH]))
  1454. {
  1455. Win32API.CreateDirectory(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], TRUE);
  1456. }
  1457. //
  1458. // Record the original size of the root paths in order to compute the deltas during
  1459. // FinalizeInstall
  1460. //
  1461. ComputeOriginalApplicationSpaceInfo();
  1462. //
  1463. // Initialize some other properties
  1464. //
  1465. m_sApplicationData.sBaseInfo.dwRemovableKilobytes = 0;
  1466. m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes = 0;
  1467. VALIDATE_PROPERTY(IDX_PROPERTY_REMOVABLEKILOBYTES);
  1468. VALIDATE_PROPERTY(IDX_PROPERTY_NONREMOVABLEKILOBYTES);
  1469. //
  1470. // Get the application record ready for installation
  1471. //
  1472. SET_APPLICATIONSTATE(APP_STATE_INSTALLING);
  1473. SET_ACTIONSTATE(CURRENT_ACTION_INSTALLING);
  1474. m_dwInitializationLevel = INIT_LEVEL_TOTAL;
  1475. }
  1476. ///////////////////////////////////////////////////////////////////////////////////////
  1477. catch(CAppManExceptionHandler * pException)
  1478. {
  1479. //
  1480. // Make sure that if we have locked parents, we unlock them here
  1481. //
  1482. if (fParentLocked)
  1483. {
  1484. APPLICATION_DATA sApplicationData;
  1485. //
  1486. // Go get the application data of the associated application
  1487. //
  1488. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &m_sApplicationData.sAssociation.sParentGuid, sizeof(GUID));
  1489. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  1490. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  1491. if (SUCCEEDED(hResult))
  1492. {
  1493. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  1494. }
  1495. }
  1496. //
  1497. // Make sure to record the hResult that caused the error
  1498. //
  1499. hResult = pException->GetResultCode();
  1500. delete pException;
  1501. }
  1502. catch(...)
  1503. {
  1504. //
  1505. // Make sure that if we have locked parents, we unlock them here
  1506. //
  1507. if (fParentLocked)
  1508. {
  1509. APPLICATION_DATA sApplicationData;
  1510. //
  1511. // Go get the application data of the associated application
  1512. //
  1513. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &m_sApplicationData.sAssociation.sParentGuid, sizeof(GUID));
  1514. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  1515. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  1516. if (SUCCEEDED(hResult))
  1517. {
  1518. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  1519. }
  1520. }
  1521. hResult = E_UNEXPECTED;
  1522. }
  1523. ///////////////////////////////////////////////////////////////////////////////////////
  1524. return hResult;
  1525. }
  1526. //////////////////////////////////////////////////////////////////////////////////////////////
  1527. //
  1528. //////////////////////////////////////////////////////////////////////////////////////////////
  1529. STDMETHODIMP CApplicationEntry::FinalizeInstall(void)
  1530. {
  1531. FUNCTION("CAppEntry::FinalizeInstall ()");
  1532. HRESULT hResult = S_OK;
  1533. ///////////////////////////////////////////////////////////////////////////////////////
  1534. try
  1535. {
  1536. CWin32API sWin32API;
  1537. DWORD dwIndex;//, dwActualApplicationSize; // Get rid of /W4 warning.
  1538. APPLICATION_DATA sApplicationData;
  1539. ASSOCIATION_INFO sAssociationInfo;
  1540. //
  1541. // Make sure we are currently installing
  1542. //
  1543. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_INSTALLING))
  1544. {
  1545. THROW(APPMAN_E_ACTIONNOTINITIALIZED);
  1546. }
  1547. if (INIT_LEVEL_TOTAL != m_dwInitializationLevel)
  1548. {
  1549. THROW(APPMAN_E_ACTIONNOTINITIALIZED);
  1550. }
  1551. //
  1552. // Are the required properties set
  1553. //
  1554. if (((APP_CATEGORY_PATCH | APP_CATEGORY_DATA) & m_sApplicationData.sBaseInfo.dwCategory))
  1555. {
  1556. if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_EXECUTECMDLINE, &m_sApplicationData))
  1557. {
  1558. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1559. }
  1560. }
  1561. else
  1562. {
  1563. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_EXECUTECMDLINE, &m_sApplicationData))
  1564. {
  1565. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1566. }
  1567. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE]))
  1568. {
  1569. THROW(APPMAN_E_INVALIDEXECUTECMDLINE);
  1570. }
  1571. }
  1572. //
  1573. // Was a default setup command line given to us
  1574. //
  1575. if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_DEFAULTSETUPEXECMDLINE, &m_sApplicationData))
  1576. {
  1577. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_DEFAULTSETUPEXECMDLINE]))
  1578. {
  1579. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1580. }
  1581. if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_DOWNSIZECMDLINE, &m_sApplicationData))
  1582. {
  1583. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_DOWNSIZECMDLINE]))
  1584. {
  1585. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1586. }
  1587. }
  1588. if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_REINSTALLCMDLINE, &m_sApplicationData))
  1589. {
  1590. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_REINSTALLCMDLINE]))
  1591. {
  1592. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1593. }
  1594. }
  1595. if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_UNINSTALLCMDLINE, &m_sApplicationData))
  1596. {
  1597. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_UNINSTALLCMDLINE]))
  1598. {
  1599. THROW(APPMAN_E_INVALIDUNINSTALLCMDLINE);
  1600. }
  1601. }
  1602. if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SELFTESTCMDLINE, &m_sApplicationData))
  1603. {
  1604. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_SELFTESTCMDLINE]))
  1605. {
  1606. THROW(APPMAN_E_INVALIDSELFTESTCMDLINE);
  1607. }
  1608. }
  1609. }
  1610. else
  1611. {
  1612. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_DOWNSIZECMDLINE, &m_sApplicationData))
  1613. {
  1614. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1615. }
  1616. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_DOWNSIZECMDLINE]))
  1617. {
  1618. THROW(APPMAN_E_INVALIDDOWNSIZECMDLINE);
  1619. }
  1620. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_REINSTALLCMDLINE, &m_sApplicationData))
  1621. {
  1622. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1623. }
  1624. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_REINSTALLCMDLINE]))
  1625. {
  1626. THROW(APPMAN_E_INVALIDREINSTALLCMDLINE);
  1627. }
  1628. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_UNINSTALLCMDLINE, &m_sApplicationData))
  1629. {
  1630. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1631. }
  1632. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_UNINSTALLCMDLINE]))
  1633. {
  1634. THROW(APPMAN_E_INVALIDUNINSTALLCMDLINE);
  1635. }
  1636. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SELFTESTCMDLINE, &m_sApplicationData))
  1637. {
  1638. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1639. }
  1640. if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_SELFTESTCMDLINE]))
  1641. {
  1642. THROW(APPMAN_E_INVALIDSELFTESTCMDLINE);
  1643. }
  1644. }
  1645. //
  1646. // Do we need to do a cache fixup
  1647. //
  1648. ComputeApplicationSpaceInfo(m_sApplicationData.sBaseInfo.dwReservedKilobytes);
  1649. //
  1650. // Delete the reserved space field
  1651. //
  1652. m_sApplicationData.sBaseInfo.dwReservedKilobytes = 0;
  1653. INVALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
  1654. //
  1655. // Before we arbitrarily set the state of the application to APP_STATE_READY, check
  1656. // to see if the setup technology hasn't already changed
  1657. //
  1658. if (APP_STATE_INSTALLING == GET_APPLICATIONSTATE())
  1659. {
  1660. RESET_APPLICATIONSTATE(APP_STATE_READY);
  1661. }
  1662. else
  1663. {
  1664. if (APP_STATE_DOWNSIZED != GET_APPLICATIONSTATE())
  1665. {
  1666. THROW(APPMAN_E_INVALIDPROPERTYVALUE);
  1667. }
  1668. }
  1669. //
  1670. // Save the application info
  1671. //
  1672. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1673. //
  1674. // Make sure this IApplicationEntry instance is no longer in an action state
  1675. //
  1676. SET_ACTIONSTATE(CURRENT_ACTION_NONE);
  1677. //
  1678. // Unlock the parent apps
  1679. //
  1680. ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo));
  1681. dwIndex = 0;
  1682. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  1683. {
  1684. if (0 == memcmp((LPVOID) &(sAssociationInfo.sChildGuid), (LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), sizeof(GUID)))
  1685. {
  1686. //
  1687. // Get the associated application
  1688. //
  1689. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  1690. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  1691. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  1692. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  1693. if (SUCCEEDED(hResult))
  1694. {
  1695. //
  1696. // Unlock the parent applications
  1697. //
  1698. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  1699. }
  1700. }
  1701. dwIndex++;
  1702. }
  1703. //
  1704. // Unlock this app
  1705. //
  1706. UnLockApplication();
  1707. }
  1708. ///////////////////////////////////////////////////////////////////////////////////////
  1709. catch(CAppManExceptionHandler * pException)
  1710. {
  1711. hResult = pException->GetResultCode();
  1712. delete pException;
  1713. }
  1714. catch(...)
  1715. {
  1716. hResult = E_UNEXPECTED;
  1717. }
  1718. ///////////////////////////////////////////////////////////////////////////////////////
  1719. return hResult;
  1720. }
  1721. //////////////////////////////////////////////////////////////////////////////////////////////
  1722. //
  1723. //////////////////////////////////////////////////////////////////////////////////////////////
  1724. STDMETHODIMP CApplicationEntry::InitializeDownsize(void)
  1725. {
  1726. FUNCTION("CAppEntry::InitializeDownsize ()");
  1727. HRESULT hResult = S_OK;
  1728. HRESULT hLockResult = S_FALSE;
  1729. ///////////////////////////////////////////////////////////////////////////////////////
  1730. try
  1731. {
  1732. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  1733. {
  1734. THROW(APPMAN_E_ACTIONINPROGRESS);
  1735. }
  1736. //
  1737. // Are the required properties set
  1738. //
  1739. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  1740. {
  1741. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1742. }
  1743. //
  1744. // Lock the application
  1745. //
  1746. hResult = LockApplication();
  1747. if (S_OK == hResult)
  1748. {
  1749. hLockResult = S_OK;
  1750. hResult = m_InformationManager.GetApplicationData(&m_sApplicationData);
  1751. if (SUCCEEDED(hResult))
  1752. {
  1753. //
  1754. // Since GetApplicationInfo succeeded this means we have a totally initialized object
  1755. //
  1756. m_dwInitializationLevel = INIT_LEVEL_TOTAL;
  1757. //
  1758. // Record the original size of the root paths in order to compute the deltas during
  1759. // FinalizeInstall
  1760. //
  1761. ComputeOriginalApplicationSpaceInfo();
  1762. //
  1763. // Set the states
  1764. //
  1765. m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState;
  1766. RESET_APPLICATIONSTATE(APP_STATE_DOWNSIZING);
  1767. SET_ACTIONSTATE(CURRENT_ACTION_DOWNSIZING);
  1768. //
  1769. // Enter the wait event if any
  1770. //
  1771. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid);
  1772. }
  1773. }
  1774. else
  1775. {
  1776. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid);
  1777. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE);
  1778. }
  1779. }
  1780. ///////////////////////////////////////////////////////////////////////////////////////
  1781. catch(CAppManExceptionHandler * pException)
  1782. {
  1783. //
  1784. // Make sure to kill the wait event
  1785. //
  1786. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  1787. {
  1788. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid);
  1789. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE);
  1790. }
  1791. //
  1792. // Make sure to unlock the application if it was locked
  1793. //
  1794. if (S_OK == hLockResult)
  1795. {
  1796. UnLockApplication();
  1797. }
  1798. //
  1799. // Record the error code
  1800. //
  1801. hResult = pException->GetResultCode();
  1802. delete pException;
  1803. }
  1804. catch(...)
  1805. {
  1806. //
  1807. // Make sure to kill the wait event
  1808. //
  1809. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  1810. {
  1811. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid);
  1812. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE);
  1813. }
  1814. //
  1815. // Make sure to unlock the application if it was locked
  1816. //
  1817. if (S_OK == hLockResult)
  1818. {
  1819. UnLockApplication();
  1820. }
  1821. hResult = E_UNEXPECTED;
  1822. }
  1823. ///////////////////////////////////////////////////////////////////////////////////////
  1824. return hResult;
  1825. }
  1826. //////////////////////////////////////////////////////////////////////////////////////////////
  1827. //
  1828. //////////////////////////////////////////////////////////////////////////////////////////////
  1829. STDMETHODIMP CApplicationEntry::FinalizeDownsize(void)
  1830. {
  1831. FUNCTION("CAppEntry::FinalizeDownsize ()");
  1832. HRESULT hResult = S_OK;
  1833. ///////////////////////////////////////////////////////////////////////////////////////
  1834. try
  1835. {
  1836. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_DOWNSIZING))
  1837. {
  1838. THROW(APPMAN_E_ACTIONNOTINITIALIZED);
  1839. }
  1840. //
  1841. // Do we need to do a cache fixup
  1842. //
  1843. ComputeApplicationSpaceInfo(0);
  1844. //
  1845. // Set the application state to downsized
  1846. //
  1847. m_sApplicationData.sBaseInfo.dwState = APP_STATE_DOWNSIZED;
  1848. //
  1849. // Save the application info
  1850. //
  1851. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1852. //
  1853. // Unlock the application
  1854. //
  1855. UnLockApplication();
  1856. //
  1857. // Leave the wait event
  1858. //
  1859. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE);
  1860. SET_ACTIONSTATE(CURRENT_ACTION_NONE);
  1861. }
  1862. ///////////////////////////////////////////////////////////////////////////////////////
  1863. catch(CAppManExceptionHandler * pException)
  1864. {
  1865. hResult = pException->GetResultCode();
  1866. delete pException;
  1867. }
  1868. catch(...)
  1869. {
  1870. hResult = E_UNEXPECTED;
  1871. }
  1872. ///////////////////////////////////////////////////////////////////////////////////////
  1873. return hResult;
  1874. }
  1875. //////////////////////////////////////////////////////////////////////////////////////////////
  1876. //
  1877. //////////////////////////////////////////////////////////////////////////////////////////////
  1878. STDMETHODIMP CApplicationEntry::InitializeReInstall(void)
  1879. {
  1880. FUNCTION("CAppEntry::InitializeReInstall ()");
  1881. HRESULT hResult = S_OK;
  1882. HRESULT hLockResult = S_FALSE;
  1883. BOOL fParentLocked = FALSE;
  1884. ///////////////////////////////////////////////////////////////////////////////////////
  1885. try
  1886. {
  1887. APPLICATION_DATA sApplicationData;
  1888. ASSOCIATION_INFO sAssociationInfo;
  1889. DWORD dwIndex;
  1890. DWORD dwReservedKilobytes;
  1891. CWin32API sWin32API;
  1892. if ((!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))&&(!CHECK_ACTIONSTATE(CURRENT_ACTION_SELFTESTING)))
  1893. {
  1894. THROW(APPMAN_E_ACTIONINPROGRESS);
  1895. }
  1896. //
  1897. // Are the required properties set
  1898. //
  1899. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  1900. {
  1901. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1902. }
  1903. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES, &m_sApplicationData))
  1904. {
  1905. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  1906. }
  1907. //
  1908. // Save the dwReservedKilobytes property before calling GetApplicationData
  1909. //
  1910. dwReservedKilobytes = m_sApplicationData.sBaseInfo.dwReservedKilobytes;
  1911. //
  1912. // First we lock this application
  1913. //
  1914. hResult = LockApplication();
  1915. if (S_OK == hResult)
  1916. {
  1917. hLockResult = S_OK;
  1918. hResult = m_InformationManager.GetApplicationData(& m_sApplicationData);
  1919. if (SUCCEEDED(hResult))
  1920. {
  1921. //
  1922. // Since GetApplicationInfo succeeded this means we have a totally initialized object
  1923. //
  1924. m_dwInitializationLevel = INIT_LEVEL_TOTAL;
  1925. //
  1926. // Make sure to restore and validate the dwReservedKilobytes
  1927. //
  1928. m_sApplicationData.sBaseInfo.dwReservedKilobytes = dwReservedKilobytes;
  1929. VALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
  1930. //
  1931. // Make sure that the parent associated apps are associated
  1932. //
  1933. ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo));
  1934. dwIndex = 0;
  1935. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  1936. {
  1937. if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID)))
  1938. {
  1939. //
  1940. // Get the associated application
  1941. //
  1942. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  1943. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  1944. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  1945. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  1946. if (FAILED(hResult))
  1947. {
  1948. THROW(APPMAN_E_INVALIDASSOCIATION);
  1949. }
  1950. //
  1951. // Make sure the associated app is in a ready state
  1952. //
  1953. hResult = m_InformationManager.ReadyApplication(&sApplicationData);
  1954. if (FAILED(hResult))
  1955. {
  1956. THROW(APPMAN_E_APPLICATIONREQUIRED);
  1957. }
  1958. //
  1959. // Lock the parent applications
  1960. //
  1961. hResult = m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid);
  1962. if (FAILED(hResult))
  1963. {
  1964. THROW(hResult);
  1965. }
  1966. else
  1967. {
  1968. fParentLocked = TRUE;
  1969. }
  1970. }
  1971. dwIndex++;
  1972. }
  1973. //
  1974. // Go get the space
  1975. //
  1976. if (FAILED(m_InformationManager.FreeSpaceOnDevice(&(m_sApplicationData.sBaseInfo.sDeviceGuid), m_sApplicationData.sBaseInfo.dwReservedKilobytes)))
  1977. {
  1978. THROW(APPMAN_E_NODISKSPACEAVAILABLE);
  1979. }
  1980. //
  1981. // Record the original size of the root paths in order to computer the deltas during
  1982. // FinalizeInstall
  1983. //
  1984. ComputeOriginalApplicationSpaceInfo();
  1985. //
  1986. // Set the state of the application
  1987. //
  1988. m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState;
  1989. m_sApplicationData.sBaseInfo.dwState = APP_STATE_REINSTALLING;
  1990. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  1991. if (CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  1992. {
  1993. SET_ACTIONSTATE(CURRENT_ACTION_REINSTALLING);
  1994. }
  1995. else
  1996. {
  1997. SET_ACTIONSTATE(CURRENT_ACTION_REINSTALLING | CURRENT_ACTION_SELFTESTING);
  1998. }
  1999. //
  2000. // Enter the wait event if any
  2001. //
  2002. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL, &m_sInstanceGuid);
  2003. }
  2004. }
  2005. }
  2006. ///////////////////////////////////////////////////////////////////////////////////////
  2007. catch(CAppManExceptionHandler * pException)
  2008. {
  2009. APPLICATION_DATA sApplicationData;
  2010. ASSOCIATION_INFO sAssociationInfo;
  2011. DWORD dwIndex;
  2012. //
  2013. // Make sure to unlock the application if it was locked
  2014. //
  2015. if (S_OK == hLockResult)
  2016. {
  2017. UnLockApplication();
  2018. }
  2019. //
  2020. // Make sure that if we have locked parents, we unlock them here
  2021. //
  2022. if (fParentLocked)
  2023. {
  2024. ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo));
  2025. dwIndex = 0;
  2026. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  2027. {
  2028. if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID)))
  2029. {
  2030. //
  2031. // Get the associated application
  2032. //
  2033. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  2034. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  2035. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  2036. if (SUCCEEDED(m_InformationManager.GetApplicationData(&sApplicationData)))
  2037. {
  2038. //
  2039. // Unlock the parent applications
  2040. //
  2041. m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid);
  2042. }
  2043. }
  2044. dwIndex++;
  2045. }
  2046. }
  2047. //
  2048. // Make sure to kill the wait event
  2049. //
  2050. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  2051. {
  2052. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL, &m_sInstanceGuid);
  2053. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL);
  2054. }
  2055. hResult = pException->GetResultCode();
  2056. delete pException;
  2057. }
  2058. catch(...)
  2059. {
  2060. APPLICATION_DATA sApplicationData;
  2061. ASSOCIATION_INFO sAssociationInfo;
  2062. DWORD dwIndex;
  2063. //
  2064. // Make sure to unlock the application if it was locked
  2065. //
  2066. if (S_OK == hLockResult)
  2067. {
  2068. UnLockApplication();
  2069. }
  2070. //
  2071. // Make sure that if we have locked parents, we unlock them here
  2072. //
  2073. if (fParentLocked)
  2074. {
  2075. ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo));
  2076. dwIndex = 0;
  2077. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  2078. {
  2079. if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID)))
  2080. {
  2081. //
  2082. // Get the associated application
  2083. //
  2084. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  2085. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  2086. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  2087. if (SUCCEEDED(m_InformationManager.GetApplicationData(&sApplicationData)))
  2088. {
  2089. //
  2090. // Unlock the parent applications
  2091. //
  2092. m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid);
  2093. }
  2094. }
  2095. dwIndex++;
  2096. }
  2097. }
  2098. //
  2099. // Make sure to kill the wait event
  2100. //
  2101. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  2102. {
  2103. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL, &m_sInstanceGuid);
  2104. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL);
  2105. }
  2106. hResult = E_UNEXPECTED;
  2107. }
  2108. ///////////////////////////////////////////////////////////////////////////////////////
  2109. return hResult;
  2110. }
  2111. //////////////////////////////////////////////////////////////////////////////////////////////
  2112. //
  2113. //////////////////////////////////////////////////////////////////////////////////////////////
  2114. STDMETHODIMP CApplicationEntry::FinalizeReInstall(void)
  2115. {
  2116. FUNCTION("CAppEntry::FinalizeReInstall ()");
  2117. HRESULT hResult = S_OK;
  2118. ///////////////////////////////////////////////////////////////////////////////////////
  2119. try
  2120. {
  2121. CWin32API sWin32API;
  2122. DWORD dwIndex; //, dwActualApplicationSize; Get rid of /W4 warning.
  2123. APPLICATION_DATA sApplicationData;
  2124. ASSOCIATION_INFO sAssociationInfo;
  2125. //
  2126. // Make sure we are currently reinstalling
  2127. //
  2128. if ((!CHECK_ACTIONSTATE(CURRENT_ACTION_REINSTALLING))&&(!CHECK_ACTIONSTATE(CURRENT_ACTION_REINSTALLING | CURRENT_ACTION_SELFTESTING)))
  2129. {
  2130. THROW(APPMAN_E_ACTIONNOTINITIALIZED);
  2131. }
  2132. //
  2133. // Do we need to do a cache fixup
  2134. //
  2135. ComputeApplicationSpaceInfo(m_sApplicationData.sBaseInfo.dwReservedKilobytes);
  2136. //
  2137. // Clear the dwReservedKilobytes data member
  2138. //
  2139. m_sApplicationData.sBaseInfo.dwReservedKilobytes = 0;
  2140. INVALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
  2141. //
  2142. // Update the aging information
  2143. //
  2144. m_sApplicationData.sAgingInfo.dwReInstallCount++;
  2145. GetLocalTime(&(m_sApplicationData.sAgingInfo.stLastUsedDate));
  2146. VALIDATE_PROPERTY(IDX_PROPERTY_LASTUSEDDATE);
  2147. //
  2148. // Set the application state to ready
  2149. //
  2150. m_sApplicationData.sBaseInfo.dwState = APP_STATE_READY;
  2151. //
  2152. // Save the application info
  2153. //
  2154. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  2155. if (CHECK_ACTIONSTATE(CURRENT_ACTION_REINSTALLING))
  2156. {
  2157. RESET_ACTIONSTATE(CURRENT_ACTION_NONE);
  2158. }
  2159. else
  2160. {
  2161. RESET_ACTIONSTATE(CURRENT_ACTION_SELFTESTING);
  2162. }
  2163. //
  2164. // Before we do anything, make sure to unlock the parent apps
  2165. //
  2166. ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo));
  2167. dwIndex = 0;
  2168. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  2169. {
  2170. if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID)))
  2171. {
  2172. //
  2173. // Get the associated application
  2174. //
  2175. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  2176. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  2177. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  2178. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  2179. if (SUCCEEDED(hResult))
  2180. {
  2181. //
  2182. // Unlock the parent applications
  2183. //
  2184. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  2185. }
  2186. }
  2187. dwIndex++;
  2188. }
  2189. UnLockApplication();
  2190. //
  2191. // Leave the wait event
  2192. //
  2193. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL);
  2194. }
  2195. ///////////////////////////////////////////////////////////////////////////////////////
  2196. catch(CAppManExceptionHandler * pException)
  2197. {
  2198. hResult = pException->GetResultCode();
  2199. delete pException;
  2200. }
  2201. catch(...)
  2202. {
  2203. hResult = E_UNEXPECTED;
  2204. }
  2205. ///////////////////////////////////////////////////////////////////////////////////////
  2206. return hResult;
  2207. }
  2208. //////////////////////////////////////////////////////////////////////////////////////////////
  2209. //
  2210. //////////////////////////////////////////////////////////////////////////////////////////////
  2211. STDMETHODIMP CApplicationEntry::InitializeUnInstall(void)
  2212. {
  2213. FUNCTION("CAppEntry::InitializeUnInstall ()");
  2214. HRESULT hResult = S_OK;
  2215. HRESULT hLockResult = S_FALSE;
  2216. ///////////////////////////////////////////////////////////////////////////////////////
  2217. try
  2218. {
  2219. ASSOCIATION_INFO sAssociationInfo;
  2220. DWORD dwIndex;
  2221. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  2222. {
  2223. THROW(APPMAN_E_ACTIONINPROGRESS);
  2224. }
  2225. //
  2226. // Are the required properties set
  2227. //
  2228. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  2229. {
  2230. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  2231. }
  2232. hResult = m_InformationManager.GetApplicationData(&m_sApplicationData);
  2233. if (SUCCEEDED(hResult))
  2234. {
  2235. //
  2236. // Since GetApplicationInfo succeeded this means we have a totally initialized object
  2237. //
  2238. m_dwInitializationLevel = INIT_LEVEL_TOTAL;
  2239. //
  2240. // Check to make sure that this application is not required for another to run
  2241. //
  2242. dwIndex = 0;
  2243. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  2244. {
  2245. if (0 == memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)))
  2246. {
  2247. THROW(APPMAN_E_APPLICATIONREQUIRED);
  2248. }
  2249. dwIndex++;
  2250. }
  2251. //
  2252. // Lock the application
  2253. //
  2254. hResult = LockApplication();
  2255. if (S_OK == hResult)
  2256. {
  2257. hLockResult = S_OK;
  2258. m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState;
  2259. RESET_APPLICATIONSTATE(APP_STATE_UNINSTALLING);
  2260. SET_ACTIONSTATE(CURRENT_ACTION_UNINSTALLING);
  2261. //
  2262. // Enter the wait event if any
  2263. //
  2264. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL, &m_sInstanceGuid);
  2265. }
  2266. }
  2267. }
  2268. ///////////////////////////////////////////////////////////////////////////////////////
  2269. catch(CAppManExceptionHandler * pException)
  2270. {
  2271. //
  2272. // Make sure to unlock the application if it was locked
  2273. //
  2274. if (S_OK == hLockResult)
  2275. {
  2276. UnLockApplication();
  2277. }
  2278. //
  2279. // Make sure to kill the wait event
  2280. //
  2281. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  2282. {
  2283. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL, &m_sInstanceGuid);
  2284. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL);
  2285. }
  2286. hResult = pException->GetResultCode();
  2287. delete pException;
  2288. }
  2289. catch(...)
  2290. {
  2291. //
  2292. // Make sure to unlock the application if it was locked
  2293. //
  2294. if (S_OK == hLockResult)
  2295. {
  2296. UnLockApplication();
  2297. }
  2298. //
  2299. // Make sure to kill the wait event
  2300. //
  2301. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  2302. {
  2303. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL, &m_sInstanceGuid);
  2304. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL);
  2305. }
  2306. hResult = E_UNEXPECTED;
  2307. }
  2308. ///////////////////////////////////////////////////////////////////////////////////////
  2309. return hResult;
  2310. }
  2311. //////////////////////////////////////////////////////////////////////////////////////////////
  2312. //
  2313. //////////////////////////////////////////////////////////////////////////////////////////////
  2314. STDMETHODIMP CApplicationEntry::FinalizeUnInstall(void)
  2315. {
  2316. FUNCTION("CAppEntry::FinalizeUnInstall ()");
  2317. HRESULT hResult = S_OK;
  2318. ///////////////////////////////////////////////////////////////////////////////////////
  2319. try
  2320. {
  2321. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_UNINSTALLING))
  2322. {
  2323. THROW(APPMAN_E_ACTIONNOTINITIALIZED);
  2324. }
  2325. //
  2326. // Remove the application from the system
  2327. //
  2328. m_InformationManager.RemoveApplicationData(&m_sApplicationData);
  2329. UnLockApplication();
  2330. RESET_ACTIONSTATE(CURRENT_ACTION_NONE);
  2331. //
  2332. // Leave the wait event
  2333. //
  2334. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL);
  2335. }
  2336. ///////////////////////////////////////////////////////////////////////////////////////
  2337. catch(CAppManExceptionHandler * pException)
  2338. {
  2339. hResult = pException->GetResultCode();
  2340. delete pException;
  2341. }
  2342. catch(...)
  2343. {
  2344. hResult = E_UNEXPECTED;
  2345. }
  2346. ///////////////////////////////////////////////////////////////////////////////////////
  2347. return hResult;
  2348. }
  2349. //////////////////////////////////////////////////////////////////////////////////////////////
  2350. //
  2351. //////////////////////////////////////////////////////////////////////////////////////////////
  2352. STDMETHODIMP CApplicationEntry::InitializeSelfTest(void)
  2353. {
  2354. FUNCTION("CAppEntry::InitializeSelfTest ()");
  2355. HRESULT hResult = S_OK;
  2356. HRESULT hLockResult = S_OK;
  2357. ///////////////////////////////////////////////////////////////////////////////////////
  2358. try
  2359. {
  2360. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  2361. {
  2362. THROW(APPMAN_E_ACTIONINPROGRESS);
  2363. }
  2364. //
  2365. // Are the required properties set
  2366. //
  2367. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  2368. {
  2369. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  2370. }
  2371. hResult = LockApplication();
  2372. if (S_OK == hResult)
  2373. {
  2374. hLockResult = S_OK;
  2375. hResult = m_InformationManager.GetApplicationData(&m_sApplicationData);
  2376. if (SUCCEEDED(hResult))
  2377. {
  2378. //
  2379. // Since GetApplicationInfo succeeded this means we have a totally initialized object
  2380. //
  2381. m_dwInitializationLevel = INIT_LEVEL_TOTAL;
  2382. m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState;
  2383. m_sApplicationData.sBaseInfo.dwState |= APP_STATE_SELFTESTING;
  2384. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  2385. SET_ACTIONSTATE(CURRENT_ACTION_SELFTESTING);
  2386. //
  2387. // Enter the wait event if any
  2388. //
  2389. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST, &m_sInstanceGuid);
  2390. }
  2391. }
  2392. }
  2393. ///////////////////////////////////////////////////////////////////////////////////////
  2394. catch(CAppManExceptionHandler * pException)
  2395. {
  2396. //
  2397. // Make sure to unlock the application if it was locked
  2398. //
  2399. if (S_OK == hLockResult)
  2400. {
  2401. UnLockApplication();
  2402. }
  2403. //
  2404. // Make sure to kill the wait event
  2405. //
  2406. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  2407. {
  2408. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST, &m_sInstanceGuid);
  2409. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST);
  2410. }
  2411. hResult = pException->GetResultCode();
  2412. delete pException;
  2413. }
  2414. catch(...)
  2415. {
  2416. //
  2417. // Make sure to unlock the application if it was locked
  2418. //
  2419. if (S_OK == hLockResult)
  2420. {
  2421. UnLockApplication();
  2422. }
  2423. //
  2424. // Make sure to kill the wait event
  2425. //
  2426. if (INIT_LEVEL_TOTAL == m_dwInitializationLevel)
  2427. {
  2428. m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST, &m_sInstanceGuid);
  2429. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST);
  2430. }
  2431. hResult = E_UNEXPECTED;
  2432. }
  2433. ///////////////////////////////////////////////////////////////////////////////////////
  2434. return hResult;
  2435. }
  2436. //////////////////////////////////////////////////////////////////////////////////////////////
  2437. //
  2438. //////////////////////////////////////////////////////////////////////////////////////////////
  2439. STDMETHODIMP CApplicationEntry::FinalizeSelfTest(void)
  2440. {
  2441. FUNCTION("CAppEntry::FinalizeSelfTest ()");
  2442. HRESULT hResult = S_OK;
  2443. ///////////////////////////////////////////////////////////////////////////////////////
  2444. try
  2445. {
  2446. APPLICATION_DATA sApplicationData;
  2447. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_SELFTESTING))
  2448. {
  2449. THROW(APPMAN_E_ACTIONNOTINITIALIZED);
  2450. }
  2451. //
  2452. // Get the latest information from the database
  2453. //
  2454. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  2455. memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(sApplicationData));
  2456. m_InformationManager.SetApplicationData(&sApplicationData, &m_sInstanceGuid);
  2457. //
  2458. // Remove the selftest state flag from the application state
  2459. //
  2460. sApplicationData.sBaseInfo.dwState &= ~APP_STATE_SELFTESTING;
  2461. memcpy((LPVOID) &m_sApplicationData, (LPVOID) &sApplicationData, sizeof(sApplicationData));
  2462. //
  2463. // Save the application info
  2464. //
  2465. m_InformationManager.SetApplicationData(&sApplicationData, &m_sInstanceGuid);
  2466. UnLockApplication();
  2467. RESET_ACTIONSTATE(CURRENT_ACTION_NONE);
  2468. //
  2469. // Leave the wait event
  2470. //
  2471. m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST);
  2472. }
  2473. ///////////////////////////////////////////////////////////////////////////////////////
  2474. catch(CAppManExceptionHandler * pException)
  2475. {
  2476. hResult = pException->GetResultCode();
  2477. delete pException;
  2478. }
  2479. catch(...)
  2480. {
  2481. hResult = E_UNEXPECTED;
  2482. }
  2483. ///////////////////////////////////////////////////////////////////////////////////////
  2484. return hResult;
  2485. }
  2486. //////////////////////////////////////////////////////////////////////////////////////////////
  2487. //
  2488. //////////////////////////////////////////////////////////////////////////////////////////////
  2489. STDMETHODIMP CApplicationEntry::Abort(void)
  2490. {
  2491. FUNCTION("CAppEntry::Abort ()");
  2492. HRESULT hResult = S_OK;
  2493. ///////////////////////////////////////////////////////////////////////////////////////
  2494. try
  2495. {
  2496. APPLICATION_DATA sApplicationData;
  2497. ASSOCIATION_INFO sAssociationInfo;
  2498. DWORD dwIndex;
  2499. if (CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  2500. {
  2501. THROW(APPMAN_E_ACTIONNOTINITIALIZED);
  2502. }
  2503. //
  2504. // We need to force a leave event
  2505. //
  2506. switch(m_dwCurrentAction)
  2507. {
  2508. case CURRENT_ACTION_DOWNSIZING
  2509. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE);
  2510. break;
  2511. case CURRENT_ACTION_REINSTALLING
  2512. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL);
  2513. break;
  2514. case CURRENT_ACTION_UNINSTALLING
  2515. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL);
  2516. break;
  2517. case CURRENT_ACTION_SELFTESTING
  2518. : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST);
  2519. break;
  2520. }
  2521. //
  2522. // Before we do anything, make sure to unlock the parent apps
  2523. //
  2524. ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo));
  2525. dwIndex = 0;
  2526. while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo))
  2527. {
  2528. if (0 == memcmp((LPVOID) &(sAssociationInfo.sChildGuid), (LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), sizeof(GUID)))
  2529. {
  2530. //
  2531. // Get the associated application
  2532. //
  2533. ZeroMemory(&sApplicationData, sizeof(sApplicationData));
  2534. memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  2535. m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData);
  2536. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  2537. if (SUCCEEDED(hResult))
  2538. {
  2539. //
  2540. // Unlock the parent applications
  2541. //
  2542. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  2543. }
  2544. }
  2545. dwIndex++;
  2546. }
  2547. //
  2548. // If the application was doing an initial install, abort will cause the application
  2549. // entry to be removed from the system
  2550. //
  2551. if (CHECK_ACTIONSTATE(CURRENT_ACTION_INSTALLING))
  2552. {
  2553. UnLockApplication();
  2554. m_InformationManager.RemoveApplicationData(&m_sApplicationData);
  2555. }
  2556. else
  2557. {
  2558. //
  2559. // Simply restore the application info with the record currently saved in the
  2560. // registry
  2561. //
  2562. m_InformationManager.GetApplicationData(&m_sApplicationData);
  2563. m_sApplicationData.sBaseInfo.dwState = m_dwOriginalState;
  2564. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  2565. UnLockApplication();
  2566. }
  2567. SET_ACTIONSTATE(CURRENT_ACTION_NONE);
  2568. }
  2569. ///////////////////////////////////////////////////////////////////////////////////////
  2570. catch(CAppManExceptionHandler * pException)
  2571. {
  2572. hResult = pException->GetResultCode();
  2573. delete pException;
  2574. }
  2575. catch(...)
  2576. {
  2577. hResult = E_UNEXPECTED;
  2578. }
  2579. ///////////////////////////////////////////////////////////////////////////////////////
  2580. return hResult;
  2581. }
  2582. //////////////////////////////////////////////////////////////////////////////////////////////
  2583. //
  2584. //////////////////////////////////////////////////////////////////////////////////////////////
  2585. STDMETHODIMP CApplicationEntry::Run(const DWORD dwRunFlags, const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen)
  2586. {
  2587. FUNCTION("CAppEntry::Run ()");
  2588. HRESULT hResult = S_OK;
  2589. ///////////////////////////////////////////////////////////////////////////////////////
  2590. try
  2591. {
  2592. WCHAR wszParameters[MAX_PATH_CHARCOUNT];
  2593. WCHAR wszCommandLine[MAX_PATH_CHARCOUNT];
  2594. CWin32API sWin32API;
  2595. BOOL fRunning = FALSE;
  2596. PROCESS_INFORMATION sProcessInformation;
  2597. //
  2598. // We can only run if this object is not doing anything
  2599. //
  2600. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  2601. {
  2602. THROW(APPMAN_E_ACTIONINPROGRESS);
  2603. }
  2604. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  2605. {
  2606. if ((S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_COMPANYNAME, &m_sApplicationData))||(S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SIGNATURE, &m_sApplicationData)))
  2607. {
  2608. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  2609. }
  2610. }
  2611. //
  2612. // Make sure the application actually exists
  2613. //
  2614. if (INIT_LEVEL_NONE == m_dwInitializationLevel)
  2615. {
  2616. hResult = m_InformationManager.GetApplicationData(&m_sApplicationData);
  2617. if (FAILED(hResult))
  2618. {
  2619. THROW(hResult);
  2620. }
  2621. m_dwInitializationLevel = INIT_LEVEL_BASIC;
  2622. }
  2623. //
  2624. // This object cannot be run if it is APP_CATEGORY_PATCH or APP_CATEGORY_DAT
  2625. //
  2626. if ((APP_CATEGORY_PATCH | APP_CATEGORY_DATA) & m_sApplicationData.sBaseInfo.dwCategory)
  2627. {
  2628. THROW(APPMAN_E_APPNOTEXECUTABLE);
  2629. }
  2630. //
  2631. // Are the required properties set
  2632. //
  2633. //
  2634. // Ready the application
  2635. //
  2636. m_InformationManager.ReadyApplication(&m_sApplicationData);
  2637. //
  2638. // Build the command line parameters
  2639. //
  2640. ZeroMemory(wszParameters, sizeof(wszParameters));
  2641. if ((APP_PROPERTY_STR_ANSI == dwStringMask)||(APP_PROPERTY_STR_UNICODE == dwStringMask))
  2642. {
  2643. //
  2644. // Check to make sure the parameters are valid
  2645. //
  2646. if (NULL != lpData)
  2647. {
  2648. if (IsBadReadPtr(lpData, dwDataLen))
  2649. {
  2650. THROW(APPMAN_E_INVALIDPARAMETERS);
  2651. }
  2652. if (0 < dwDataLen)
  2653. {
  2654. //
  2655. // Make sure the command line parameters are converted to unicode
  2656. //
  2657. if (APP_PROPERTY_STR_ANSI == dwStringMask)
  2658. {
  2659. if (MAX_PATH_CHARCOUNT < StrLenA((LPCSTR) lpData))
  2660. {
  2661. THROW(APPMAN_E_INVALIDEXECUTECMDLINE);
  2662. }
  2663. else
  2664. {
  2665. sWin32API.MultiByteToWideChar((LPCSTR) lpData, dwDataLen, wszParameters, MAX_PATH_CHARCOUNT);
  2666. }
  2667. }
  2668. else
  2669. {
  2670. if (MAX_PATH_CHARCOUNT < StrLenW((LPCWSTR) lpData))
  2671. {
  2672. THROW(APPMAN_E_INVALIDEXECUTECMDLINE);
  2673. }
  2674. else
  2675. {
  2676. memcpy(wszParameters, lpData, StrLenW((LPCWSTR) lpData) * 2);
  2677. }
  2678. }
  2679. }
  2680. }
  2681. }
  2682. else
  2683. {
  2684. if (0 != dwStringMask)
  2685. {
  2686. THROW(APPMAN_E_INVALIDPARAMETERS);
  2687. }
  2688. }
  2689. //
  2690. // Construct the command line
  2691. //
  2692. if (1 < StrLenW(wszParameters))
  2693. {
  2694. //
  2695. // Make sure the total lenght does not exceed MAX_PATH_CHARCOUNT
  2696. //
  2697. if (MAX_PATH_CHARCOUNT < (StrLenW(m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE])+StrLenW(wszParameters)))
  2698. {
  2699. THROW(APPMAN_E_INVALIDEXECUTECMDLINE);
  2700. }
  2701. wcscpy(wszCommandLine, m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE]);
  2702. wcscat(wszCommandLine, L" /AppManStarted ");
  2703. wcscat(wszCommandLine, wszParameters);
  2704. }
  2705. else
  2706. {
  2707. wcscpy(wszCommandLine, m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE]);
  2708. wcscat(wszCommandLine, L" /AppManStarted");
  2709. }
  2710. //
  2711. // Run it
  2712. //
  2713. if (sWin32API.CreateProcess(wszCommandLine, &sProcessInformation))
  2714. {
  2715. fRunning = TRUE;
  2716. }
  2717. else
  2718. {
  2719. if (SUCCEEDED(m_InformationManager.SelfTestApplication(&m_sApplicationData)))
  2720. {
  2721. if (sWin32API.CreateProcess(wszCommandLine, &sProcessInformation))
  2722. {
  2723. fRunning = TRUE;
  2724. }
  2725. else
  2726. {
  2727. THROW(E_FAIL);
  2728. }
  2729. }
  2730. else
  2731. {
  2732. THROW(E_FAIL);
  2733. }
  2734. }
  2735. if (fRunning)
  2736. {
  2737. m_sApplicationData.sAgingInfo.dwUsageCount++;
  2738. GetLocalTime(&(m_sApplicationData.sAgingInfo.stLastUsedDate));
  2739. m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
  2740. if (APP_RUN_BLOCK & dwRunFlags)
  2741. {
  2742. WaitForSingleObject(sProcessInformation.hProcess, INFINITE);
  2743. }
  2744. CloseHandle(sProcessInformation.hThread);
  2745. CloseHandle(sProcessInformation.hProcess);
  2746. hResult = S_OK;
  2747. }
  2748. }
  2749. ///////////////////////////////////////////////////////////////////////////////////////
  2750. catch(CAppManExceptionHandler * pException)
  2751. {
  2752. hResult = pException->GetResultCode();
  2753. delete pException;
  2754. }
  2755. catch(...)
  2756. {
  2757. hResult = E_UNEXPECTED;
  2758. }
  2759. ///////////////////////////////////////////////////////////////////////////////////////
  2760. return hResult;
  2761. }
  2762. //////////////////////////////////////////////////////////////////////////////////////////////
  2763. //
  2764. // TODO
  2765. //
  2766. //////////////////////////////////////////////////////////////////////////////////////////////
  2767. STDMETHODIMP CApplicationEntry::AddAssociation(const DWORD dwAssociationType, const IApplicationEntry * lpApplicationEntry)
  2768. {
  2769. FUNCTION("CAppEntry::AddAssociation ()");
  2770. HRESULT hResult = S_OK;
  2771. ///////////////////////////////////////////////////////////////////////////////////////
  2772. try
  2773. {
  2774. ASSOCIATION_INFO sAssociationRecord;
  2775. APPLICATION_DATA sApplicationData;
  2776. //
  2777. // Make sure we are in a proper state
  2778. //
  2779. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  2780. {
  2781. THROW(APPMAN_E_CANNOTASSOCIATE);
  2782. }
  2783. //
  2784. // The initialization level should be INIT_LEVEL_NONE
  2785. //
  2786. if (INIT_LEVEL_NONE != m_dwInitializationLevel)
  2787. {
  2788. THROW(APPMAN_E_CANNOTASSOCIATE);
  2789. }
  2790. //
  2791. // Make sure an association does not already exist
  2792. //
  2793. if (0 != m_sApplicationData.sAssociation.dwAssociationType)
  2794. {
  2795. THROW(APPMAN_E_CANNOTASSOCIATE);
  2796. }
  2797. //
  2798. // Make sure the lpApplicationEntry parameter is valid
  2799. //
  2800. if (NULL == lpApplicationEntry)
  2801. {
  2802. THROW(APPMAN_E_INVALIDPARAMETERS);
  2803. }
  2804. if (IsBadReadPtr((LPVOID) lpApplicationEntry, sizeof(CApplicationEntry)))
  2805. {
  2806. THROW(APPMAN_E_INVALIDPARAMETERS);
  2807. }
  2808. //
  2809. // Make sure that dwAssociationType is valid
  2810. //
  2811. if ((APP_ASSOCIATION_INHERITBOTHPATHS != dwAssociationType)&&(APP_ASSOCIATION_INHERITAPPROOTPATH != dwAssociationType)&&(APP_ASSOCIATION_INHERITSETUPROOTPATH != dwAssociationType))
  2812. {
  2813. THROW(APPMAN_E_INVALIDASSOCIATION);
  2814. }
  2815. //
  2816. // Make sure the root path is not already set
  2817. //
  2818. if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData))
  2819. {
  2820. THROW(APPMAN_E_CANNOTASSOCIATE);
  2821. }
  2822. //
  2823. // Initialize the sAssociationRecord structure
  2824. //
  2825. sAssociationRecord.dwSize = sizeof(ASSOCIATION_INFO);
  2826. sAssociationRecord.dwStructId = ASSOCIATION_STRUCT;
  2827. sAssociationRecord.dwAssociationType = dwAssociationType;
  2828. //
  2829. // Does the application we want to association with even exist
  2830. //
  2831. memcpy((LPVOID) &sApplicationData, (LPVOID) ((CApplicationEntry *)lpApplicationEntry)->GetApplicationDataPtr(), sizeof(APPLICATION_DATA));
  2832. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  2833. if (FAILED(hResult))
  2834. {
  2835. THROW(APPMAN_E_UNKNOWNAPPLICATION);
  2836. }
  2837. //
  2838. // Fill in the rest of the information
  2839. //
  2840. memcpy((LPVOID)&sAssociationRecord.sParentGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID));
  2841. //
  2842. // Is there an association already ?
  2843. //
  2844. if (0 != m_sApplicationData.sAssociation.dwAssociationType)
  2845. {
  2846. THROW(APPMAN_E_ALREADYASSOCIATED);
  2847. }
  2848. //
  2849. // Ok make the association happen
  2850. //
  2851. memcpy((LPVOID) &m_sApplicationData.sAssociation, (LPVOID) &sAssociationRecord, sizeof(ASSOCIATION_INFO));
  2852. }
  2853. ///////////////////////////////////////////////////////////////////////////////////////
  2854. catch(CAppManExceptionHandler * pException)
  2855. {
  2856. hResult = pException->GetResultCode();
  2857. delete pException;
  2858. }
  2859. catch(...)
  2860. {
  2861. hResult = E_UNEXPECTED;
  2862. }
  2863. ///////////////////////////////////////////////////////////////////////////////////////
  2864. return hResult;
  2865. }
  2866. //////////////////////////////////////////////////////////////////////////////////////////////
  2867. //
  2868. // TODO
  2869. //
  2870. //////////////////////////////////////////////////////////////////////////////////////////////
  2871. STDMETHODIMP CApplicationEntry::RemoveAssociation(const DWORD dwAssociationType, const IApplicationEntry * lpApplicationEntry)
  2872. {
  2873. FUNCTION("CAppEntry::RemoveAssociation ()");
  2874. HRESULT hResult = S_OK;
  2875. ///////////////////////////////////////////////////////////////////////////////////////
  2876. try
  2877. {
  2878. //
  2879. // Make sure we are in a proper state
  2880. //
  2881. if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))
  2882. {
  2883. THROW(E_FAIL);
  2884. }
  2885. //
  2886. // The initialization level should be INIT_LEVEL_NONE
  2887. //
  2888. if (INIT_LEVEL_NONE != m_dwInitializationLevel)
  2889. {
  2890. THROW(E_FAIL);
  2891. }
  2892. //
  2893. // Make sure the lpApplicationEntry parameter is proper
  2894. //
  2895. if (NULL == lpApplicationEntry)
  2896. {
  2897. THROW(APPMAN_E_INVALIDPARAMETERS);
  2898. }
  2899. if (IsBadReadPtr((LPVOID) lpApplicationEntry, sizeof(CApplicationEntry)))
  2900. {
  2901. THROW(APPMAN_E_INVALIDPARAMETERS);
  2902. }
  2903. //
  2904. // Make sure that dwAssociationType is valid
  2905. //
  2906. if ((APP_ASSOCIATION_INHERITBOTHPATHS != dwAssociationType)&&(APP_ASSOCIATION_INHERITAPPROOTPATH != dwAssociationType)&&(APP_ASSOCIATION_INHERITSETUPROOTPATH != dwAssociationType))
  2907. {
  2908. THROW(APPMAN_E_INVALIDASSOCIATION);
  2909. }
  2910. //
  2911. // Make sure an association does exist
  2912. //
  2913. if (0 == m_sApplicationData.sAssociation.dwAssociationType)
  2914. {
  2915. THROW(E_FAIL);
  2916. }
  2917. ZeroMemory(&m_sApplicationData.sAssociation, sizeof(ASSOCIATION_INFO));
  2918. }
  2919. ///////////////////////////////////////////////////////////////////////////////////////
  2920. catch(CAppManExceptionHandler * pException)
  2921. {
  2922. hResult = pException->GetResultCode();
  2923. delete pException;
  2924. }
  2925. catch(...)
  2926. {
  2927. hResult = E_UNEXPECTED;
  2928. }
  2929. ///////////////////////////////////////////////////////////////////////////////////////
  2930. return hResult;
  2931. }
  2932. //////////////////////////////////////////////////////////////////////////////////////////////
  2933. //
  2934. // TODO
  2935. //
  2936. //////////////////////////////////////////////////////////////////////////////////////////////
  2937. STDMETHODIMP CApplicationEntry::EnumAssociations(const DWORD dwTargetIndex, LPDWORD lpdwAssociationType, IApplicationEntry * lpApplicationEntry)
  2938. {
  2939. FUNCTION("CAppEntry::EnumAssociations ()");
  2940. HRESULT hResult = S_OK;
  2941. ///////////////////////////////////////////////////////////////////////////////////////
  2942. try
  2943. {
  2944. ASSOCIATION_INFO sAssociationInfo;
  2945. DWORD dwIndex, dwActualIndex;
  2946. //
  2947. // Make sure the lpApplicationEntry pointer is good
  2948. //
  2949. if (NULL == lpApplicationEntry)
  2950. {
  2951. THROW(APPMAN_E_INVALIDPARAMETERS);
  2952. }
  2953. if (IsBadReadPtr((LPVOID) lpApplicationEntry, sizeof(CApplicationEntry)))
  2954. {
  2955. THROW(APPMAN_E_INVALIDPARAMETERS);
  2956. }
  2957. //
  2958. // Make sure that the lpdwAssociationType is valid
  2959. //
  2960. if (NULL == lpdwAssociationType)
  2961. {
  2962. THROW(APPMAN_E_INVALIDPARAMETERS);
  2963. }
  2964. if (IsBadWritePtr((LPVOID) lpdwAssociationType, sizeof(DWORD)))
  2965. {
  2966. THROW(APPMAN_E_INVALIDPARAMETERS);
  2967. }
  2968. //
  2969. // Get the nth association record. Ignore associations that belong to other applications
  2970. //
  2971. dwActualIndex = dwTargetIndex;
  2972. dwIndex = 0;
  2973. do
  2974. {
  2975. hResult = m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo);
  2976. if (S_OK == hResult)
  2977. {
  2978. if (memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sChildGuid, sizeof(GUID)))
  2979. {
  2980. if (memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)))
  2981. {
  2982. dwActualIndex++;
  2983. }
  2984. }
  2985. }
  2986. dwIndex++;
  2987. }
  2988. while ((dwIndex <= dwActualIndex)&&(S_OK == hResult));
  2989. //
  2990. // Did we find an association
  2991. //
  2992. if (S_OK == hResult)
  2993. {
  2994. if (0 == memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sChildGuid, sizeof(GUID)))
  2995. {
  2996. //
  2997. // The association is a child associations
  2998. //
  2999. *lpdwAssociationType = sAssociationInfo.dwAssociationType | APP_ASSOCIATION_CHILD;
  3000. hResult = lpApplicationEntry->Clear();
  3001. if (SUCCEEDED(hResult))
  3002. {
  3003. hResult = lpApplicationEntry->SetProperty(APP_PROPERTY_GUID, (LPCVOID) &sAssociationInfo.sParentGuid, sizeof(GUID));
  3004. if (SUCCEEDED(hResult))
  3005. {
  3006. hResult = m_InformationManager.GetApplicationData(((CApplicationEntry *) lpApplicationEntry)->GetApplicationDataPtr());
  3007. if (SUCCEEDED(hResult))
  3008. {
  3009. ((CApplicationEntry *) lpApplicationEntry)->SetInitializationLevel(INIT_LEVEL_BASIC);
  3010. }
  3011. }
  3012. }
  3013. }
  3014. else
  3015. {
  3016. if (0 == memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)))
  3017. {
  3018. //
  3019. // The association is a parent association
  3020. //
  3021. *lpdwAssociationType = sAssociationInfo.dwAssociationType | APP_ASSOCIATION_PARENT;
  3022. hResult = lpApplicationEntry->Clear();
  3023. if (SUCCEEDED(hResult))
  3024. {
  3025. hResult = lpApplicationEntry->SetProperty(APP_PROPERTY_GUID, (LPCVOID) &sAssociationInfo.sChildGuid, sizeof(GUID));
  3026. if (SUCCEEDED(hResult))
  3027. {
  3028. hResult = m_InformationManager.GetApplicationData(((CApplicationEntry *) lpApplicationEntry)->GetApplicationDataPtr());
  3029. if (SUCCEEDED(hResult))
  3030. {
  3031. ((CApplicationEntry *) lpApplicationEntry)->SetInitializationLevel(INIT_LEVEL_BASIC);
  3032. }
  3033. }
  3034. }
  3035. }
  3036. }
  3037. }
  3038. }
  3039. ///////////////////////////////////////////////////////////////////////////////////////
  3040. catch(CAppManExceptionHandler * pException)
  3041. {
  3042. hResult = pException->GetResultCode();
  3043. delete pException;
  3044. }
  3045. catch(...)
  3046. {
  3047. hResult = E_UNEXPECTED;
  3048. }
  3049. ///////////////////////////////////////////////////////////////////////////////////////
  3050. return hResult;
  3051. }
  3052. //////////////////////////////////////////////////////////////////////////////////////////////
  3053. //
  3054. // TODO
  3055. //
  3056. //////////////////////////////////////////////////////////////////////////////////////////////
  3057. STDMETHODIMP CApplicationEntry::GetTemporarySpace(const DWORD dwKilobytes, const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen)
  3058. {
  3059. FUNCTION("CAppEntry::GetTemporarySpace ()");
  3060. HRESULT hResult = E_FAIL;
  3061. BOOL fParentsLocked = FALSE;
  3062. BOOL fLocked = FALSE;
  3063. APPLICATION_DATA sApplicationData;
  3064. ///////////////////////////////////////////////////////////////////////////////////////
  3065. try
  3066. {
  3067. TEMP_SPACE_RECORD sTempSpaceRecord;
  3068. DWORD dwCharCount;
  3069. //
  3070. // Are the required properties set
  3071. //
  3072. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  3073. {
  3074. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3075. }
  3076. //
  3077. // Is the object a valid application object
  3078. //
  3079. memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(APPLICATION_DATA));
  3080. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  3081. if (FAILED(hResult))
  3082. {
  3083. THROW(APPMAN_E_UNKNOWNAPPLICATION);
  3084. }
  3085. //
  3086. // Make sure the string mask is good
  3087. //
  3088. if ((APP_PROPERTY_STR_ANSI != dwStringMask)&&(APP_PROPERTY_STR_UNICODE != dwStringMask))
  3089. {
  3090. THROW(APPMAN_E_INVALIDPARAMETERS);
  3091. }
  3092. //
  3093. // Check to make sure dwDataLen is greater than 0
  3094. //
  3095. if (0 == dwDataLen)
  3096. {
  3097. THROW(APPMAN_E_INVALIDPARAMETERS);
  3098. }
  3099. //
  3100. // Make sure that the lpData parameter is valid
  3101. //
  3102. if (NULL == lpData)
  3103. {
  3104. THROW(APPMAN_E_INVALIDPARAMETERS);
  3105. }
  3106. if (IsBadWritePtr(lpData, dwDataLen))
  3107. {
  3108. THROW(APPMAN_E_INVALIDPARAMETERS);
  3109. }
  3110. //
  3111. // Make sure the dwKilobytes is not 0
  3112. //
  3113. if (0 == dwKilobytes)
  3114. {
  3115. THROW(APPMAN_E_INVALIDPARAMETERS);
  3116. }
  3117. //
  3118. // Lock this application and all of it's parents
  3119. //
  3120. if (SUCCEEDED(m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid)))
  3121. {
  3122. //
  3123. // Make sure to record that fact that the applications got locked (in case of a THROW)
  3124. //
  3125. fParentsLocked = TRUE;
  3126. if (SUCCEEDED(m_InformationManager.LockApplicationData(&sApplicationData, &m_sInstanceGuid)))
  3127. {
  3128. //
  3129. // Make sure to record the fact that this application is locked (in case of a THROW)
  3130. //
  3131. fLocked = TRUE;
  3132. //
  3133. // Get the space
  3134. //
  3135. sTempSpaceRecord.dwSize = sizeof(TEMP_SPACE_RECORD);
  3136. sTempSpaceRecord.dwStructId = TEMP_SPACE_STRUCT;
  3137. sTempSpaceRecord.dwKilobytes = dwKilobytes;
  3138. memcpy((LPVOID) &sTempSpaceRecord.sApplicationGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID));
  3139. hResult = m_InformationManager.AddTempSpace(&sTempSpaceRecord);
  3140. if (FAILED(hResult))
  3141. {
  3142. THROW(hResult);
  3143. }
  3144. dwCharCount = StrLenW(sTempSpaceRecord.wszDirectory);
  3145. if (APP_PROPERTY_STR_ANSI == dwStringMask)
  3146. {
  3147. if (dwCharCount > dwDataLen)
  3148. {
  3149. m_InformationManager.RemoveTempSpace(&sTempSpaceRecord);
  3150. THROW(APPMAN_E_OVERFLOW);
  3151. }
  3152. CWin32API::WideCharToMultiByte((LPCWSTR) sTempSpaceRecord.wszDirectory, MAX_PATH_CHARCOUNT, (LPSTR) lpData, dwDataLen);
  3153. }
  3154. else
  3155. {
  3156. if (dwDataLen < (dwCharCount*2))
  3157. {
  3158. m_InformationManager.RemoveTempSpace(&sTempSpaceRecord);
  3159. THROW(APPMAN_E_OVERFLOW);
  3160. }
  3161. memcpy((LPVOID) lpData, (LPVOID) sTempSpaceRecord.wszDirectory, dwCharCount*2);
  3162. }
  3163. //
  3164. // Unlock this application
  3165. //
  3166. m_InformationManager.UnlockApplicationData(&sApplicationData, &m_sInstanceGuid);
  3167. }
  3168. //
  3169. // Unlock the parent applications
  3170. //
  3171. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  3172. }
  3173. }
  3174. ///////////////////////////////////////////////////////////////////////////////////////
  3175. catch(CAppManExceptionHandler * pException)
  3176. {
  3177. //
  3178. // Unlock the applications if required
  3179. //
  3180. if (fParentsLocked)
  3181. {
  3182. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  3183. }
  3184. //
  3185. // Is this application locked
  3186. //
  3187. if (fLocked)
  3188. {
  3189. m_InformationManager.UnlockApplicationData(&sApplicationData, &m_sInstanceGuid);
  3190. }
  3191. hResult = pException->GetResultCode();
  3192. delete pException;
  3193. }
  3194. catch(...)
  3195. {
  3196. //
  3197. // Unlock the applications if required
  3198. //
  3199. if (fParentsLocked)
  3200. {
  3201. m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid);
  3202. }
  3203. //
  3204. // Is this application locked
  3205. //
  3206. if (fLocked)
  3207. {
  3208. m_InformationManager.UnlockApplicationData(&sApplicationData, &m_sInstanceGuid);
  3209. }
  3210. hResult = E_UNEXPECTED;
  3211. }
  3212. ///////////////////////////////////////////////////////////////////////////////////////
  3213. return hResult;
  3214. }
  3215. //////////////////////////////////////////////////////////////////////////////////////////////
  3216. //
  3217. // TODO
  3218. //
  3219. //////////////////////////////////////////////////////////////////////////////////////////////
  3220. STDMETHODIMP CApplicationEntry::RemoveTemporarySpace(const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen)
  3221. {
  3222. FUNCTION("CAppEntry::RemoveTemporarySpace ()");
  3223. HRESULT hResult = S_OK;
  3224. APPLICATION_DATA sApplicationData;
  3225. ///////////////////////////////////////////////////////////////////////////////////////
  3226. try
  3227. {
  3228. TEMP_SPACE_RECORD sTempSpaceRecord;
  3229. DWORD dwCharCount;
  3230. //
  3231. // Are the required properties set
  3232. //
  3233. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  3234. {
  3235. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3236. }
  3237. //
  3238. // Is the object a valid application object
  3239. //
  3240. memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(APPLICATION_DATA));
  3241. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  3242. if (FAILED(hResult))
  3243. {
  3244. THROW(APPMAN_E_UNKNOWNAPPLICATION);
  3245. }
  3246. //
  3247. // Make sure the string mask is good
  3248. //
  3249. if ((APP_PROPERTY_STR_ANSI != dwStringMask)&&(APP_PROPERTY_STR_UNICODE != dwStringMask))
  3250. {
  3251. THROW(APPMAN_E_INVALIDPARAMETERS);
  3252. }
  3253. //
  3254. // Check to make sure dwDataLen is greater than 0
  3255. //
  3256. if (0 == dwDataLen)
  3257. {
  3258. THROW(APPMAN_E_INVALIDPARAMETERS);
  3259. }
  3260. //
  3261. // Make sure that the lpData parameter is valid
  3262. //
  3263. if (NULL == lpData)
  3264. {
  3265. THROW(APPMAN_E_INVALIDPARAMETERS);
  3266. }
  3267. if (IsBadReadPtr(lpData, dwDataLen))
  3268. {
  3269. THROW(APPMAN_E_INVALIDPARAMETERS);
  3270. }
  3271. //
  3272. // Initialize the sTempSpaceRecord structure
  3273. //
  3274. sTempSpaceRecord.dwSize = sizeof(TEMP_SPACE_RECORD);
  3275. sTempSpaceRecord.dwStructId = TEMP_SPACE_STRUCT;
  3276. memcpy((LPVOID) &sTempSpaceRecord.sApplicationGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID));
  3277. if (APP_PROPERTY_STR_ANSI == dwStringMask)
  3278. {
  3279. dwCharCount = StrLenA((LPSTR) lpData);
  3280. if (dwCharCount > MAX_PATH_CHARCOUNT)
  3281. {
  3282. THROW(APPMAN_E_OVERFLOW);
  3283. }
  3284. CWin32API::MultiByteToWideChar((LPCSTR) lpData, dwDataLen, sTempSpaceRecord.wszDirectory, MAX_PATH_CHARCOUNT);
  3285. }
  3286. else
  3287. {
  3288. dwCharCount = StrLenW((LPWSTR) lpData);
  3289. if (dwCharCount > MAX_PATH_CHARCOUNT)
  3290. {
  3291. THROW(APPMAN_E_OVERFLOW);
  3292. }
  3293. memcpy((LPVOID) sTempSpaceRecord.wszDirectory, (LPVOID) lpData, dwCharCount*2);
  3294. }
  3295. //
  3296. // Delete the temporary space
  3297. //
  3298. hResult = m_InformationManager.RemoveTempSpace(&sTempSpaceRecord);
  3299. }
  3300. ///////////////////////////////////////////////////////////////////////////////////////
  3301. catch(CAppManExceptionHandler * pException)
  3302. {
  3303. hResult = pException->GetResultCode();
  3304. delete pException;
  3305. }
  3306. catch(...)
  3307. {
  3308. hResult = E_UNEXPECTED;
  3309. }
  3310. ///////////////////////////////////////////////////////////////////////////////////////
  3311. return hResult;
  3312. }
  3313. //////////////////////////////////////////////////////////////////////////////////////////////
  3314. //
  3315. // TODO
  3316. //
  3317. //////////////////////////////////////////////////////////////////////////////////////////////
  3318. STDMETHODIMP CApplicationEntry::EnumTemporarySpaces(const DWORD dwTargetIndex, LPDWORD lpdwSpace, const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen)
  3319. {
  3320. FUNCTION("CAppEntry::EnumTemporarySpaces ()");
  3321. HRESULT hResult = S_OK;
  3322. APPLICATION_DATA sApplicationData;
  3323. ///////////////////////////////////////////////////////////////////////////////////////
  3324. try
  3325. {
  3326. TEMP_SPACE_RECORD sTempSpaceRecord;
  3327. DWORD dwIndex, dwActualIndex;
  3328. DWORD dwCharCount;
  3329. //
  3330. // Are the required properties set
  3331. //
  3332. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData))
  3333. {
  3334. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3335. }
  3336. //
  3337. // Is the object a valid application object
  3338. //
  3339. memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(APPLICATION_DATA));
  3340. hResult = m_InformationManager.GetApplicationData(&sApplicationData);
  3341. if (FAILED(hResult))
  3342. {
  3343. THROW(APPMAN_E_UNKNOWNAPPLICATION);
  3344. }
  3345. //
  3346. // Make sure the string mask is good
  3347. //
  3348. if ((APP_PROPERTY_STR_ANSI != dwStringMask)&&(APP_PROPERTY_STR_UNICODE != dwStringMask))
  3349. {
  3350. THROW(APPMAN_E_INVALIDPARAMETERS);
  3351. }
  3352. //
  3353. // Check to make sure dwDataLen is greater than 0
  3354. //
  3355. if (0 == dwDataLen)
  3356. {
  3357. THROW(APPMAN_E_INVALIDPARAMETERS);
  3358. }
  3359. //
  3360. // Make sure that the lpData parameter is valid
  3361. //
  3362. if (NULL == lpData)
  3363. {
  3364. THROW(APPMAN_E_INVALIDPARAMETERS);
  3365. }
  3366. if (IsBadWritePtr(lpData, dwDataLen))
  3367. {
  3368. THROW(APPMAN_E_INVALIDPARAMETERS);
  3369. }
  3370. //
  3371. // Check to make sure lpdwSpace is valid
  3372. //
  3373. if (NULL == lpdwSpace)
  3374. {
  3375. THROW(APPMAN_E_INVALIDPARAMETERS);
  3376. }
  3377. if (IsBadWritePtr(lpdwSpace, sizeof(DWORD)))
  3378. {
  3379. THROW(APPMAN_E_INVALIDPARAMETERS);
  3380. }
  3381. //
  3382. // Get the nth temp space. Ignore temp spaces that are not owned by this application
  3383. //
  3384. dwActualIndex = dwTargetIndex;
  3385. dwIndex = 0;
  3386. do
  3387. {
  3388. hResult = m_InformationManager.EnumTempSpace(dwIndex, &sTempSpaceRecord);
  3389. if (S_OK == hResult)
  3390. {
  3391. if (memcmp((LPVOID) &sTempSpaceRecord.sApplicationGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID)))
  3392. {
  3393. dwActualIndex++;
  3394. }
  3395. }
  3396. dwIndex++;
  3397. }
  3398. while ((dwIndex <= dwActualIndex)&&(S_OK == hResult));
  3399. //
  3400. // Did we find a target temp space
  3401. //
  3402. if (S_OK == hResult)
  3403. {
  3404. //
  3405. // Record the size
  3406. //
  3407. *lpdwSpace = sTempSpaceRecord.dwKilobytes;
  3408. //
  3409. // Record the string
  3410. //
  3411. dwCharCount = StrLenW(sTempSpaceRecord.wszDirectory);
  3412. if (APP_PROPERTY_STR_ANSI == dwStringMask)
  3413. {
  3414. if (dwCharCount > dwDataLen)
  3415. {
  3416. THROW(APPMAN_E_OVERFLOW);
  3417. }
  3418. CWin32API::WideCharToMultiByte((LPCWSTR) sTempSpaceRecord.wszDirectory, MAX_PATH_CHARCOUNT, (LPSTR) lpData, dwDataLen);
  3419. }
  3420. else
  3421. {
  3422. if (dwDataLen < (dwCharCount*2))
  3423. {
  3424. THROW(APPMAN_E_OVERFLOW);
  3425. }
  3426. memcpy((LPVOID) lpData, (LPVOID) sTempSpaceRecord.wszDirectory, dwCharCount*2);
  3427. }
  3428. }
  3429. }
  3430. ///////////////////////////////////////////////////////////////////////////////////////
  3431. catch(CAppManExceptionHandler * pException)
  3432. {
  3433. hResult = pException->GetResultCode();
  3434. delete pException;
  3435. }
  3436. catch(...)
  3437. {
  3438. hResult = E_UNEXPECTED;
  3439. }
  3440. ///////////////////////////////////////////////////////////////////////////////////////
  3441. return hResult;
  3442. }
  3443. //////////////////////////////////////////////////////////////////////////////////////////////
  3444. //
  3445. //////////////////////////////////////////////////////////////////////////////////////////////
  3446. STDMETHODIMP CApplicationEntry::ComputeOriginalApplicationSpaceInfo(void)
  3447. {
  3448. FUNCTION("CAppEntry::ComputeOriginalApplicationSpaceInfo ()");
  3449. CWin32API Win32API;
  3450. //
  3451. // Make sure the root paths are set
  3452. //
  3453. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SETUPROOTPATH, &m_sApplicationData))
  3454. {
  3455. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3456. }
  3457. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData))
  3458. {
  3459. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3460. }
  3461. //
  3462. // How much space is currently take by the application
  3463. //
  3464. m_dwOriginalSetupRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH]);
  3465. m_dwOriginalApplicationRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]);
  3466. return S_OK;
  3467. }
  3468. //////////////////////////////////////////////////////////////////////////////////////////////
  3469. //
  3470. //////////////////////////////////////////////////////////////////////////////////////////////
  3471. STDMETHODIMP CApplicationEntry::ComputeApplicationSpaceInfo(const DWORD dwInstalledKilobytesExpected)
  3472. {
  3473. FUNCTION("CAppEntry::ComputeApplicationSpaceInfo ()");
  3474. HRESULT hResult = S_OK;
  3475. DWORD dwSetupInstalledKilobytes, dwSetupUnInstalledKilobytes;
  3476. DWORD dwApplicationInstalledKilobytes, dwApplicationUnInstalledKilobytes;
  3477. DWORD dwInstalledKilobytes, dwUnInstalledKilobytes;
  3478. DWORD dwSetupRootPathSizeKilobytes, dwApplicationRootPathSizeKilobytes;
  3479. CWin32API Win32API;
  3480. //
  3481. // Make sure the root paths and estimated install kilobytes are set
  3482. //
  3483. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SETUPROOTPATH, &m_sApplicationData))
  3484. {
  3485. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3486. }
  3487. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData))
  3488. {
  3489. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3490. }
  3491. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_REMOVABLEKILOBYTES, &m_sApplicationData))
  3492. {
  3493. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3494. }
  3495. if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_NONREMOVABLEKILOBYTES, &m_sApplicationData))
  3496. {
  3497. THROW(APPMAN_E_REQUIREDPROPERTIESMISSING);
  3498. }
  3499. //
  3500. // What is the actual amount of kilobytes taken up by the application paths
  3501. //
  3502. dwSetupRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH]);
  3503. dwApplicationRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]);
  3504. //
  3505. // Did we add or remove kilobytes from the setup root path
  3506. //
  3507. if (dwSetupRootPathSizeKilobytes > m_dwOriginalSetupRootPathSizeKilobytes)
  3508. {
  3509. dwSetupInstalledKilobytes = dwSetupRootPathSizeKilobytes - m_dwOriginalSetupRootPathSizeKilobytes;
  3510. dwSetupUnInstalledKilobytes = 0;
  3511. }
  3512. else
  3513. {
  3514. dwSetupInstalledKilobytes = 0;
  3515. dwSetupUnInstalledKilobytes = m_dwOriginalSetupRootPathSizeKilobytes - dwSetupRootPathSizeKilobytes;
  3516. }
  3517. //
  3518. // Did we add or remove kilobytes from the application root path
  3519. //
  3520. if (dwApplicationRootPathSizeKilobytes > m_dwOriginalApplicationRootPathSizeKilobytes)
  3521. {
  3522. dwApplicationInstalledKilobytes = dwApplicationRootPathSizeKilobytes - m_dwOriginalApplicationRootPathSizeKilobytes;
  3523. dwApplicationUnInstalledKilobytes = 0;
  3524. }
  3525. else
  3526. {
  3527. dwApplicationInstalledKilobytes = 0;
  3528. dwApplicationUnInstalledKilobytes = m_dwOriginalApplicationRootPathSizeKilobytes - dwApplicationRootPathSizeKilobytes;
  3529. }
  3530. //
  3531. // The total is
  3532. //
  3533. dwInstalledKilobytes = dwSetupInstalledKilobytes + dwApplicationInstalledKilobytes;
  3534. dwUnInstalledKilobytes = dwSetupUnInstalledKilobytes + dwApplicationUnInstalledKilobytes;
  3535. //
  3536. // Did we use up more kilobytes than expected
  3537. //
  3538. if (dwInstalledKilobytes > dwUnInstalledKilobytes)
  3539. {
  3540. if ((dwInstalledKilobytes - dwUnInstalledKilobytes) > dwInstalledKilobytesExpected)
  3541. {
  3542. DWORD dwExtraKilobytes;
  3543. //
  3544. // How many extra kilobytes were used up by the installation
  3545. //
  3546. dwExtraKilobytes = (dwInstalledKilobytes - dwUnInstalledKilobytes) - dwInstalledKilobytesExpected;
  3547. //
  3548. // Go get the space required to install the application on the device
  3549. //
  3550. hResult = m_InformationManager.FixCacheOverrun(&m_sApplicationData.sBaseInfo.sDeviceGuid, dwExtraKilobytes);
  3551. if (FAILED(hResult))
  3552. {
  3553. THROW(APPMAN_E_CACHEOVERRUN);
  3554. }
  3555. }
  3556. }
  3557. //
  3558. // Update the removable and non-removable space and validate the properties
  3559. //
  3560. m_sApplicationData.sBaseInfo.dwRemovableKilobytes += dwApplicationInstalledKilobytes;
  3561. if (m_sApplicationData.sBaseInfo.dwRemovableKilobytes > dwApplicationUnInstalledKilobytes)
  3562. {
  3563. m_sApplicationData.sBaseInfo.dwRemovableKilobytes -= dwApplicationUnInstalledKilobytes;
  3564. }
  3565. else
  3566. {
  3567. m_sApplicationData.sBaseInfo.dwRemovableKilobytes = 0;
  3568. }
  3569. m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes += dwSetupInstalledKilobytes;
  3570. if (m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes > dwSetupUnInstalledKilobytes)
  3571. {
  3572. m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes -= dwSetupUnInstalledKilobytes;
  3573. }
  3574. else
  3575. {
  3576. m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes = 0;
  3577. }
  3578. //
  3579. // Make sure dwRemovableKilobytes and dwNonRemovableKilobytes are not recursively adding
  3580. //
  3581. if (m_sApplicationData.sBaseInfo.dwRemovableKilobytes > dwApplicationRootPathSizeKilobytes)
  3582. {
  3583. m_sApplicationData.sBaseInfo.dwRemovableKilobytes = dwApplicationRootPathSizeKilobytes;
  3584. }
  3585. if (m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes > dwSetupRootPathSizeKilobytes)
  3586. {
  3587. m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes = dwSetupRootPathSizeKilobytes;
  3588. }
  3589. VALIDATE_PROPERTY(IDX_PROPERTY_REMOVABLEKILOBYTES);
  3590. VALIDATE_PROPERTY(IDX_PROPERTY_NONREMOVABLEKILOBYTES);
  3591. return hResult;
  3592. }
  3593. //////////////////////////////////////////////////////////////////////////////////////////////
  3594. //
  3595. //////////////////////////////////////////////////////////////////////////////////////////////
  3596. LPAPPLICATION_DATA CApplicationEntry::GetApplicationDataPtr(void)
  3597. {
  3598. FUNCTION("CAppEntry::GetApplicationDataPtr()");
  3599. return &m_sApplicationData;
  3600. }