|
|
//////////////////////////////////////////////////////////////////////////////////////////////
//
// ApplicationEntry.cpp
//
// Copyright (C) 1998, 1999 Microsoft Corporation. All rights reserved.
//
// Abstract :
//
// This is the implementation of IApplicationEntry
//
// History :
//
// 05/06/1999 luish Created
//
//////////////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <string.h>
#include "Resource.h"
#include "AppMan.h"
#include "Win32API.h"
#include "ApplicationManager.h"
#include "ExceptionHandler.h"
#include "Lock.h"
#include "AppManDebug.h"
#include "StructIdentifiers.h"
#include "Global.h"
//To flag as DBG_APPENTRY
#ifdef DBG_MODULE
#undef DBG_MODULE
#endif
#define DBG_MODULE DBG_APPENTRY
//
// Macro definition used within this source file only
//
#define VALIDATE_PROPERTY(a) m_InformationManager.ValidateApplicationPropertyWithIndex((a), &m_sApplicationData)
#define INVALIDATE_PROPERTY(a) m_InformationManager.InvalidateApplicationPropertyWithIndex((a), &m_sApplicationData)
#define RESET_ACTIONSTATE(a) m_dwCurrentAction = (a)
#define SET_ACTIONSTATE(a) m_dwCurrentAction = (a)
#define CHECK_ACTIONSTATE(a) ((a) == m_dwCurrentAction)
#define GET_ACTIONSTATE(a) (m_dwCurrentAction)
#define CLEAR_ACTIONSTATE(a) m_dwCurrentAction = CURRENT_ACTION_NONE
#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); }
#define CHECK_APPLICATIONSTATE(a) (m_sApplicationData.sBaseInfo.dwState & (a))
#define RESET_APPLICATIONSTATE(a) m_sApplicationData.sBaseInfo.dwState = (a); VALIDATE_STATE_FIELD()
#define SET_APPLICATIONSTATE(a) m_sApplicationData.sBaseInfo.dwState = (a); VALIDATE_STATE_FIELD()
#define GET_APPLICATIONSTATE() (m_sApplicationData.sBaseInfo.dwState)
#define CLEAR_APPLICATIONSTATE() m_sApplicationData.sBaseInfo.dwState = 0; VALIDATE_STATE_FIELD()
#define VALIDATE_CATEGORY_FIELD() if (APP_CATEGORY_NONE != m_sApplicationData.sBaseInfo.dwCategory) { VALIDATE_PROPERTY(IDX_PROPERTY_CATEGORY); } else { INVALIDATE_PROPERTY(IDX_PROPERTY_CATEGORY); }
#define CHECK_APPLICATIONCATEGORY(a) ((a) == (m_sApplicationData.sBaseInfo.dwCategory & (a)))
#define RESET_APPLICATIONCATEGORY(a) m_sApplicationData.sBaseInfo.dwCategory = (a); VALIDATE_CATEGORY_FIELD()
#define SET_APPLICATIONCATEGORY(a) m_sApplicationData.sBaseInfo.dwCategory |= (a); VALIDATE_CATEGORY_FIELD()
#define GET_APPLICATIONCATEGORY() (m_sApplicationData.sBaseInfo.dwCategory)
#define CLEAR_APPLICATIONCATEGORY() m_sApplicationData.sBaseInfo.dwCategory = APP_CATEGORY_NONE; VALIDATE_CATEGORY_FIELD()
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
CApplicationEntry::CApplicationEntry(void) { FUNCTION("CApplicationEntry::CApplicationEntry (void)");
m_dwLockCount = 0; m_fIsInitialized = FALSE; m_dwCurrentAction = CURRENT_ACTION_NONE; m_lReferenceCount = 1; m_hInstanceMutex = NULL; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
CApplicationEntry::~CApplicationEntry(void) { FUNCTION("CApplicationEntry::~CApplicationEntry (void)");
if (CURRENT_ACTION_NONE != m_dwCurrentAction) { APPLICATION_DATA sApplicationData; ASSOCIATION_INFO sAssociationInfo; DWORD dwIndex;
//
// We need to force a leave event
//
switch(m_dwCurrentAction) { case CURRENT_ACTION_DOWNSIZING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE); break;
case CURRENT_ACTION_REINSTALLING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL); break;
case CURRENT_ACTION_UNINSTALLING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL); break;
case CURRENT_ACTION_SELFTESTING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST); break;
case (CURRENT_ACTION_SELFTESTING | CURRENT_ACTION_REINSTALLING) : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST); break; }
//
// Before we do anything, make sure to unlock the parent apps
//
ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo)); dwIndex = 0; while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &(sAssociationInfo.sChildGuid), (LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), sizeof(GUID))) { //
// Get the associated application
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); if (SUCCEEDED(m_InformationManager.GetApplicationData(&sApplicationData))) { //
// Unlock the parent applications
//
m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); } } dwIndex++; }
//
// If the application was doing an initial install, abort will cause the application
// entry to be removed from the system
//
UnLockApplication(); }
// 4/12/2000(RichGr): If we've got a mutex, release and close it. We were leaking handles
// when swopping between AppManDiagTool tabs.
if (NULL != m_hInstanceMutex) { ReleaseMutex(m_hInstanceMutex); CloseHandle(m_hInstanceMutex); m_hInstanceMutex = NULL; }
if (TRUE == m_fIsInitialized) { m_InformationManager.ForceUnlockApplicationData(&m_sApplicationData, &m_sInstanceGuid); }
}
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO : the constructor requires that the incoming parameter
// be a const, we cannot lock the source object by calling Lock() (which is not
// a const method. So, when the copying occurs, the source object will not be locked
//
//////////////////////////////////////////////////////////////////////////////////////////////
CApplicationEntry::CApplicationEntry(const CApplicationEntry & /*refSourceObject*/) // Get rid of /W4 warnings.
{ FUNCTION("CApplicationEntry::CApplicationEntry (const CApplicationEntry &refSourceObject)"); }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
CApplicationEntry & CApplicationEntry::operator = (const CApplicationEntry & /*refSourceObject*/) { return * this; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// IUnknown interface implementation
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::QueryInterface(REFIID RefIID, LPVOID * ppVoidObject) { FUNCTION("CAppEntry::QueryInterface ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { if (NULL == &RefIID) { THROW(E_UNEXPECTED); }
if (NULL == ppVoidObject) { THROW(E_UNEXPECTED); }
*ppVoidObject = NULL;
if ((RefIID == IID_IUnknown)||(RefIID == IID_ApplicationEntry)) { *ppVoidObject = (LPVOID) this; }
if (*ppVoidObject) { ((LPUNKNOWN)*ppVoidObject)->AddRef(); } else { hResult = E_NOINTERFACE; } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { if ((NULL == &RefIID)||(NULL == ppVoidObject)||(IsBadWritePtr(ppVoidObject, sizeof(LPVOID)))) { hResult = E_INVALIDARG; } else { hResult = E_UNEXPECTED; } }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// IUnknown interface implementation
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CApplicationEntry::AddRef(void) { FUNCTION("CAppEntry::AddRef ()");
return InterlockedIncrement(&m_lReferenceCount); }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// IUnknown interface implementation
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CApplicationEntry::Release(void) { FUNCTION("CAppEntry::Release ()");
DWORD dwReferenceCount;
dwReferenceCount = InterlockedDecrement(&m_lReferenceCount); if (0 == dwReferenceCount) { delete this; }
return dwReferenceCount; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::Initialize(void) { FUNCTION("CAppEntry::Initialize ()");
HRESULT hResult;
hResult = m_sCriticalSection.Initialize(); if (SUCCEEDED(hResult)) { hResult = m_InformationManager.Initialize(); if (SUCCEEDED(hResult)) { hResult = Clear(); if (SUCCEEDED(hResult)) { m_fIsInitialized = TRUE; } } }
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::SetInitializationLevel(DWORD dwInitializationLevel) { FUNCTION("CAppEntry::SetInitializationLevel ()");
m_dwInitializationLevel = dwInitializationLevel;
return S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(DWORD) CApplicationEntry::GetActionState(void) { FUNCTION("CAppEntry::GetActionState ()");
return m_dwCurrentAction; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::LockApplication(void) { FUNCTION("CAppEntry::LockApplication ()");
HRESULT hResult;
hResult = m_InformationManager.LockApplicationData(&m_sApplicationData, &m_sInstanceGuid); if (SUCCEEDED(hResult)) { m_dwLockCount++; } else { THROW(APPMAN_E_APPLICATIONALREADYLOCKED); }
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::UnLockApplication(void) { FUNCTION("CAppEntry::UnLockApplication ()");
HRESULT hResult;
hResult = m_InformationManager.UnlockApplicationData(&m_sApplicationData, &m_sInstanceGuid); if (SUCCEEDED(hResult)) { if (0 < m_dwLockCount) { m_dwLockCount--; } }
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::Clear(void) { FUNCTION("CAppEntry::Clear ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { CLock sLock(&m_sCriticalSection); DWORD dwIndex; CHAR szString[MAX_PATH];
sLock.Lock();
//
// Make sure we are not in the middle of an action
//
if (CURRENT_ACTION_NONE != m_dwCurrentAction) { THROW(APPMAN_E_ACTIONINPROGRESS); }
//
// Make sure this application instance is not locked
//
if (0 != m_dwLockCount) { THROW(APPMAN_E_APPLICATIONALREADYLOCKED); }
//
// Ok, let's wipe the object
//
m_dwInitializationLevel = INIT_LEVEL_NONE; ZeroMemory(&m_sApplicationData, sizeof(m_sApplicationData));
//
// Initialize the structure headers
//
m_sApplicationData.sAgingInfo.dwSize = sizeof(m_sApplicationData.sAgingInfo); m_sApplicationData.sAgingInfo.dwStructId = AGING_STRUCT;
m_sApplicationData.sBaseInfo.dwSize = sizeof(m_sApplicationData.sBaseInfo); m_sApplicationData.sBaseInfo.dwStructId = BASIC_APPINFO_STRUCT;
m_sApplicationData.sAssociation.dwSize = sizeof(m_sApplicationData.sAssociation); m_sApplicationData.sAssociation.dwStructId = ASSOCIATION_STRUCT;
//
// Since this is a new object, let's initialize the crypto string
//
RandomInit();
for (dwIndex = 0; dwIndex < MAX_PATH_CHARCOUNT + 1; dwIndex++) { m_sApplicationData.wszStringProperty[APP_STRING_CRYPTO][dwIndex] = RandomWORD(); }
//
// If the object was assigned a mutex, kill the mutex
//
if (NULL != m_hInstanceMutex) { ReleaseMutex(m_hInstanceMutex); CloseHandle(m_hInstanceMutex); m_hInstanceMutex = NULL; }
//
// Create the instance info and constructs
//
if (FAILED(CoCreateGuid(&m_sInstanceGuid))) { THROW(E_UNEXPECTED); } 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]); m_hInstanceMutex = CreateMutex(NULL, TRUE, szString);
sLock.UnLock(); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::ValidateGetPropertyParameters(const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPVOID lpData, const DWORD dwDataLen) { FUNCTION("CApplicationInfo::ValidateGetPropertyParameters (const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPVOID lpData, const DWORD dwDataLen)");
//
// Is the property currently initialized
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(dwPropertyIndex, &m_sApplicationData)) { THROW(APPMAN_E_PROPERTYNOTSET); }
//
// Are we actually allowed to read this property
//
if (!(m_dwInitializationLevel & gPropertyInfo[dwPropertyIndex].dwReadMask)) { THROW(APPMAN_E_PROPERTYNOTSET); }
//
// The property being passed in is either a GUID, a DWORD or a string
//
if (APP_STRING_NONE == gPropertyInfo[dwPropertyIndex].dwStringId) {
//
// dwPropertyModifers should be 0
//
if (0 != dwPropertyModifiers) { THROW(APPMAN_E_INVALIDPROPERTY); }
//
// Make sure dwDataLen is correct
//
if (gPropertyInfo[dwPropertyIndex].dwMaxLen != dwDataLen) { THROW(APPMAN_E_INVALIDPROPERTYSIZE); }
//
// Since the property is a GUID or a DWORD, the dwDatalen should be fixed
//
if ((NULL == lpData)||(IsBadWritePtr(lpData, dwDataLen))) { THROW(APPMAN_E_INVALIDPARAMETERS); } } else { //
// Make sure dwDataLen is correct
//
if (0 == dwDataLen) { THROW(APPMAN_E_INVALIDPROPERTYSIZE); }
//
// Determine the character count in the incoming string
//
if ((APP_PROPERTY_STR_ANSI != dwPropertyModifiers)&&(APP_PROPERTY_STR_UNICODE != dwPropertyModifiers)&&(0 != dwPropertyModifiers)) { THROW(APPMAN_E_INVALIDPROPERTYVALUE); }
//
// The property is a string
//
if ((NULL == lpData)||(IsBadWritePtr(lpData, dwDataLen))) { THROW(APPMAN_E_INVALIDPARAMETERS); } } return S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::ValidateStringProperty(const DWORD dwPropertyIndex, const DWORD /*dwPropertyModifiers*/, LPCWSTR wszStringProperty) { FUNCTION("CAppEntry::ValidateStringProperty ()");
CWin32API sWin32API;
if ((IDX_PROPERTY_COMPANYNAME == dwPropertyIndex)||(IDX_PROPERTY_SIGNATURE == dwPropertyIndex)) { //
// First we make sure that this is even a valid path
//
if (!sWin32API.IsValidFilename(wszStringProperty)) { THROW(APPMAN_E_INVALIDPARAMETERS); } }
return S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::ValidateSetPropertyParameters(const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPCVOID lpData, const DWORD dwDataLen) { FUNCTION("CApplicationInfo::ValidateSetPropertyParameters (const DWORD dwPropertyIndex, const DWORD dwPropertyModifiers, LPCVOID lpData, const DWORD dwDataLen)");
DWORD dwCharCount = 0;
//
// Determine whether or not we are allowed to set this property at this time
//
if (!(m_dwCurrentAction & gPropertyInfo[dwPropertyIndex].dwWriteMask)) { THROW(APPMAN_E_READONLYPROPERTY); }
//
// This is a special case when APP_PROPERTY_EXECUTECMDLINE is used. If the category has the
// APP_CATEGORY_PATCH or APP_CATEGORY_DATA, then the APP_PROPERTY_EXECUTECMDLINE is
// not setable
//
if (((APP_CATEGORY_PATCH | APP_CATEGORY_DATA) & m_sApplicationData.sBaseInfo.dwCategory)&&(IDX_PROPERTY_EXECUTECMDLINE == dwPropertyIndex)) { THROW(APPMAN_E_READONLYPROPERTY); } //
// The property being passed in is either a GUID/DWORD or a string
//
if (APP_STRING_NONE == gPropertyInfo[dwPropertyIndex].dwStringId) { //
// dwPropertyModifers should be 0
//
if (0 != dwPropertyModifiers) { THROW(APPMAN_E_INVALIDPROPERTY); }
//
// Make sure dwDataLen is correct
//
if (gPropertyInfo[dwPropertyIndex].dwMaxLen != dwDataLen) { THROW(APPMAN_E_INVALIDPROPERTYSIZE); } //
// Since the property is a GUID or a DWORD, the dwDatalen should be fixed
//
if ((NULL == lpData)||(IsBadReadPtr(lpData, dwDataLen))) { THROW(APPMAN_E_INVALIDPARAMETERS); } } else { //
// The property is a string.
//
if (NULL != lpData) { if (0 == dwDataLen) { THROW(APPMAN_E_INVALIDPROPERTYSIZE); }
//
// First determine whether or not we can actual read the incoming string
//
if (IsBadReadPtr(lpData, dwDataLen)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Determine the character count in the incoming string
//
if (APP_PROPERTY_STR_ANSI == dwPropertyModifiers) { dwCharCount = StrLenA((LPSTR) lpData); } else { if ((APP_PROPERTY_STR_UNICODE == dwPropertyModifiers)||(0 == dwPropertyModifiers)) { dwCharCount = StrLenW((LPWSTR) lpData); } else { THROW(APPMAN_E_INVALIDPROPERTYVALUE); } }
//
// Determine whether or not the storage buffer are big enough for the incoming string
//
if (gPropertyInfo[dwPropertyIndex].dwMaxLen < dwCharCount) { THROW(APPMAN_E_OVERFLOW); } } } return S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::ValidateCommandLine(LPCWSTR wszRootPath, LPCWSTR wszCommandLine) { FUNCTION("CAppEntry::ValidateCommandLine ()"); CWin32API Win32API; BOOL fApplicationExists = FALSE; DWORD dwIndex, dwRootPathLen, dwCommandLineLen; WCHAR wszTempPath[MAX_PATH_CHARCOUNT+1];
dwRootPathLen = wcslen(wszRootPath); dwCommandLineLen = wcslen(wszCommandLine); ZeroMemory(wszTempPath, sizeof(wszTempPath)); wcscpy(wszTempPath, wszCommandLine);
//
// Make sure that wszRootPath is the subpath of wszCommandLine
//
if (0 != _wcsnicmp(wszRootPath, wszCommandLine, dwRootPathLen)) { return E_FAIL; }
//
// At this point we go looking for .exe/.bat/.com and try to findfirstfile on the string
//
dwIndex = dwRootPathLen; while ((FALSE == fApplicationExists)&&(dwIndex <= dwCommandLineLen)) { //
// Slowly increment the wszTempPath string
//
wszTempPath[dwIndex] = wszCommandLine[dwIndex]; dwIndex++; wszTempPath[dwIndex] = 0;
if (4 < dwIndex) { //
// Are the last 4 characters of wszTEmpPath ".EXE"
//
if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".EXE", 4)) { if (Win32API.FileExists(wszTempPath)) { if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath))) { fApplicationExists = TRUE; } } }
//
// Are the last 4 characters of wszTEmpPath ".BAT"
//
if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".BAT", 4)) { if (Win32API.FileExists(wszTempPath)) { if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath))) { fApplicationExists = TRUE; } } }
//
// Are the last 4 characters of wszTEmpPath ".COM"
//
if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".COM", 4)) { if (Win32API.FileExists(wszTempPath)) { if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath))) { fApplicationExists = TRUE; } } }
//
// Are the last 4 characters of wszTEmpPath ".CMD"
//
if (!_wcsnicmp(&wszTempPath[dwIndex-4], L".CMD", 4)) { if (Win32API.FileExists(wszTempPath)) { if (!(FILE_ATTRIBUTE_DIRECTORY & Win32API.FileAttributes(wszTempPath))) { fApplicationExists = TRUE; } } } } }
if (FALSE == fApplicationExists) { return S_FALSE; } else { return S_OK; } }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO : Insert checking to make sure properties are not set at a bad time
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::SetProperty(const DWORD dwProperty, LPCVOID lpData, const DWORD dwDataLen) { FUNCTION("CAppEntry::SetProperty ()"); DPFMSG(MakeString("dwProperty = 0x%08x", dwProperty));
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { CLock sLock(&m_sCriticalSection); DWORD dwFilteredProperty, dwPropertyModifiers, dwPropertyIndex; DWORD dwStringIndex, dwCharCount;
if (FALSE == m_fIsInitialized) { THROW(APPMAN_E_NOTINITIALIZED); }
sLock.Lock();
//
// Extract the filtered property value and the property modifier value
//
dwFilteredProperty = dwProperty & 0x0000ffff; dwPropertyModifiers = dwProperty & 0xffff0000;
//
// Was the property passed in a valid property value
//
if (S_OK != m_InformationManager.IsValidApplicationProperty(dwFilteredProperty)) { THROW(APPMAN_E_INVALIDPROPERTY); }
//
// Get the internal property index for dwProperty
//
dwPropertyIndex = m_InformationManager.GetPropertyIndex(dwFilteredProperty);
//
// Are the dwProperty/lpData/dwDataLen parameters valid and properly sized
//
ValidateSetPropertyParameters(dwPropertyIndex, dwPropertyModifiers, lpData, dwDataLen);
//
// Get the property
//
dwStringIndex = gPropertyInfo[dwPropertyIndex].dwStringId;
if (APP_STRING_NONE == dwStringIndex) { switch(dwPropertyIndex) { case IDX_PROPERTY_GUID : memcpy(&m_sApplicationData.sBaseInfo.sApplicationGuid, lpData, sizeof(GUID)); break; case IDX_PROPERTY_STATE : m_sApplicationData.sBaseInfo.dwState = *((LPDWORD) lpData); if (APP_STATE_DOWNSIZED != m_sApplicationData.sBaseInfo.dwState) { THROW(APPMAN_E_INVALIDPROPERTYVALUE); } break; case IDX_PROPERTY_CATEGORY : m_sApplicationData.sBaseInfo.dwCategory = *((LPDWORD) lpData); if (((~APP_CATEGORY_ALL) & m_sApplicationData.sBaseInfo.dwCategory)||(!(0x0000ffff & m_sApplicationData.sBaseInfo.dwCategory))) { THROW(APPMAN_E_INVALIDPROPERTYVALUE); } break; case IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES : m_sApplicationData.sBaseInfo.dwReservedKilobytes = *((LPDWORD) lpData); break; case IDX_PROPERTY_NONREMOVABLEKILOBYTES : break; case IDX_PROPERTY_REMOVABLEKILOBYTES : break; case IDX_PROPERTY_INSTALLDATE: case IDX_PROPERTY_LASTUSEDDATE : THROW(APPMAN_E_READONLYPROPERTY); break; default : THROW(E_UNEXPECTED); break; } } else { //
// Are we dealing with the APP_PROPERTY_ROOTPATH
//
if (IDX_PROPERTY_ROOTPATH == dwPropertyIndex) { DWORD dwAdvancedMode = 0;
m_InformationManager.GetAdvancedMode(&dwAdvancedMode); if (0 == dwAdvancedMode) { THROW(APPMAN_E_READONLYPROPERTY); } else { if (0 != m_sApplicationData.sAssociation.dwAssociationType) { THROW(APPMAN_E_READONLYPROPERTY); } } }
//
// Make ANSI into UNICODE string if required
//
if (APP_PROPERTY_STR_ANSI & dwProperty) { dwCharCount = StrLenA((LPSTR) lpData); CWin32API::MultiByteToWideChar((LPCSTR) lpData, dwDataLen, m_sApplicationData.wszStringProperty[dwStringIndex], MAX_PATH_CHARCOUNT); } else { dwCharCount = StrLenW((LPWSTR) lpData); memcpy((LPVOID) m_sApplicationData.wszStringProperty[dwStringIndex], (LPVOID) lpData, dwDataLen); }
//
// Make sure that the value we have just set is a valid string
//
ValidateStringProperty(dwPropertyIndex, dwPropertyModifiers, m_sApplicationData.wszStringProperty[dwStringIndex]); }
//
// Make sure the validate the newly set property
//
m_InformationManager.ValidateApplicationPropertyWithIndex(dwPropertyIndex, &m_sApplicationData);
sLock.UnLock(); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::GetProperty(const DWORD dwProperty, LPVOID lpData, const DWORD dwDataLen) { FUNCTION("CAppEntry::GetProperty ()"); DPFMSG(MakeString("dwProperty = 0x%08x", dwProperty));
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { CLock sLock(&m_sCriticalSection); DWORD dwFilteredProperty, dwPropertyModifiers, dwPropertyIndex, dwCharCount, dwStringIndex;
if (FALSE == m_fIsInitialized) { THROW(APPMAN_E_NOTINITIALIZED); }
sLock.Lock();
//
// Extract the filtered property value and the property modifier value
//
dwFilteredProperty = dwProperty & 0x0000ffff; dwPropertyModifiers = dwProperty & 0xffff0000;
//
// Was the property passed in a valid property value
//
if (S_OK != m_InformationManager.IsValidApplicationProperty(dwFilteredProperty)) { THROW(APPMAN_E_INVALIDPROPERTY); }
//
// Get the internal property index for dwProperty
//
dwPropertyIndex = m_InformationManager.GetPropertyIndex(dwFilteredProperty);
//
// Are the dwProperty/lpData/dwDataLen parameters valid and properly sized
//
ValidateGetPropertyParameters(dwPropertyIndex, dwPropertyModifiers, lpData, dwDataLen);
//
// Get the property
//
dwStringIndex = gPropertyInfo[dwPropertyIndex].dwStringId; if (APP_STRING_NONE == dwStringIndex) { switch(dwPropertyIndex) { case IDX_PROPERTY_GUID : memcpy((LPVOID) lpData, (LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID)); break; case IDX_PROPERTY_STATE : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwState; break; case IDX_PROPERTY_CATEGORY : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwCategory; break; case IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwReservedKilobytes; break; case IDX_PROPERTY_NONREMOVABLEKILOBYTES : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes; break; case IDX_PROPERTY_REMOVABLEKILOBYTES : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwRemovableKilobytes; break; case IDX_PROPERTY_INSTALLDATE : memcpy((LPVOID) lpData, (LPVOID) &m_sApplicationData.sAgingInfo.stInstallDate, sizeof(SYSTEMTIME)); break; case IDX_PROPERTY_LASTUSEDDATE : memcpy((LPVOID) lpData, (LPVOID) &m_sApplicationData.sAgingInfo.stLastUsedDate, sizeof(SYSTEMTIME)); break; case IDX_PROPERTY_PIN : *(LPDWORD)lpData = m_sApplicationData.sBaseInfo.dwPinState; break; default : THROW(E_UNEXPECTED); break; } } else { if (APP_PROPERTY_STR_ANSI == dwPropertyModifiers) { dwCharCount = StrLenW((LPWSTR) m_sApplicationData.wszStringProperty[dwStringIndex]); if (dwDataLen < dwCharCount) { THROW(APPMAN_E_OVERFLOW); } CWin32API::WideCharToMultiByte((LPCWSTR) m_sApplicationData.wszStringProperty[dwStringIndex], MAX_PATH_CHARCOUNT, (LPSTR) lpData, dwDataLen); } else { dwCharCount = StrLenW((LPWSTR) m_sApplicationData.wszStringProperty[dwStringIndex]); if (dwDataLen < (dwCharCount*2)) { THROW(APPMAN_E_OVERFLOW); } memcpy((LPVOID) lpData, (LPVOID) m_sApplicationData.wszStringProperty[dwStringIndex], dwCharCount*2); } }
sLock.UnLock(); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// The InitializeInstall() method will do the following actions before successfully returning.
// If any of these steps fail, the method will return a failure.
//
// (1) Make sure the application object is not undergoing any other action
// (2) Make sure that APP_PROPERTY_TYPE is set
// (3) Make sure that APP_PROPERTY_SIGNATURE is set
// (4) Make sure that APP_PROPERTY_ESTIMATED_INSTALL_SIZE is set
// (5) Make sure that the application is not already installed
// (6) Make sure to set the state of the application to APP_STATE_INSTALLING
// (7) Explicitly call m_InformationManager.SetApplicationInfo() in order to prevent
// step (8) from happening in case of a failure
// (8) Make sure to set the state of the m_dwCurrentAction
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::InitializeInstall(void) { FUNCTION("CAppEntry::InitializeInstall ()");
HRESULT hResult = S_OK; BOOL fParentLocked = FALSE;
///////////////////////////////////////////////////////////////////////////////////////
try { CWin32API Win32API; DWORD dwIndex, dwReservedKilobytes, dwAdvancedMode; BOOL fApplicationRootExists; APPLICATION_DATA sApplicationData; DEVICE_RECORD sDeviceRecord; WCHAR wszRootPath[5]; GUID sPathGuid;
//
// Make sure this object is not currently being used in another action
//
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(APPMAN_E_ACTIONINPROGRESS); }
//
// Get the advanced mode
//
m_InformationManager.GetAdvancedMode(&dwAdvancedMode);
//
// Make sure the required fields are present
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_COMPANYNAME, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SIGNATURE, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_CATEGORY, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if ((0 < dwAdvancedMode)&&(0 == m_sApplicationData.sAssociation.dwAssociationType)) { if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } else { if (FALSE == Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH])) { //
// We want to see if we can even create this directory. If we can, delete it right
// away in order to make sure that an empty directory is not created until we absolutely
// have to
//
if (!Win32API.CreateDirectory(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], TRUE)) { THROW(APPMAN_E_INVALIDROOTPATH); } else { Win32API.RemoveDirectory(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]); } } } }
//
// Since this should be a new application
//
m_sApplicationData.sBaseInfo.dwPinState = FALSE; VALIDATE_PROPERTY(IDX_PROPERTY_PIN);
//
// Is this is a brand new application entry
//
if (S_FALSE == m_InformationManager.CheckApplicationExistance(&m_sApplicationData)) { DWORD dwDeviceIndex; WCHAR wszAppManRoot[MAX_PATH_CHARCOUNT]; WCHAR wszAppManSetup[MAX_PATH_CHARCOUNT]; WCHAR wszCategory[MAX_PATH_CHARCOUNT];
//
// Initialize the path substrings
//
(OS_VERSION_9x & Win32API.GetOSVersion()) ? GetResourceStringW(IDS_APPMAN9x, wszAppManRoot, MAX_PATH_CHARCOUNT): GetResourceStringW(IDS_APPMANNT, wszAppManRoot, MAX_PATH_CHARCOUNT); GetResourceStringW(IDS_APPMAN, wszAppManSetup, MAX_PATH_CHARCOUNT);
switch(GET_APPLICATIONCATEGORY()) { case APP_CATEGORY_MISC: case APP_CATEGORY_NONE : ZeroMemory(wszCategory, sizeof(wszCategory)); break; case APP_CATEGORY_ENTERTAINMENT : GetResourceStringW(IDS_ENTERTAINMENT, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_PRODUCTIVITY : GetResourceStringW(IDS_PRODUCTIVITY, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_PUBLISHING : GetResourceStringW(IDS_PUBLISHING, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_SCIENTIFIC : GetResourceStringW(IDS_SCIENTIFIC, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_AUTHORING : GetResourceStringW(IDS_AUTHORING, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_MEDICAL : GetResourceStringW(IDS_MEDICAL, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_BUSINESS : GetResourceStringW(IDS_BUSINESS, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_FINANCIAL : GetResourceStringW(IDS_FINANCIAL, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_EDUCATIONAL : GetResourceStringW(IDS_EDUCATIONAL, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_REFERENCE : GetResourceStringW(IDS_REFERENCE, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_WEB : GetResourceStringW(IDS_WEB, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_DEVELOPMENTTOOL : GetResourceStringW(IDS_DEVTOOL, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_MULTIMEDIA : GetResourceStringW(IDS_MULTIMEDIA, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_VIRUSCLEANER : GetResourceStringW(IDS_VIRUSCLEANER, wszCategory, MAX_PATH_CHARCOUNT); break; case APP_CATEGORY_CONNECTIVITY : GetResourceStringW(IDS_CONNECTIVITY, wszCategory, MAX_PATH_CHARCOUNT); break; }
//
// Initialize the aging information
//
m_sApplicationData.sAgingInfo.dwInstallCost = 0; m_sApplicationData.sAgingInfo.dwReInstallCount = 0; m_sApplicationData.sAgingInfo.dwUsageCount = 0; GetLocalTime(&(m_sApplicationData.sAgingInfo.stInstallDate)); VALIDATE_PROPERTY(IDX_PROPERTY_INSTALLDATE); GetLocalTime(&(m_sApplicationData.sAgingInfo.stLastUsedDate)); VALIDATE_PROPERTY(IDX_PROPERTY_LASTUSEDDATE);
//
// Is this application associated with anything at all
//
if (0 != m_sApplicationData.sAssociation.dwAssociationType) { //
// Go get the application data of the associated application
//
memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &m_sApplicationData.sAssociation.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_INVALIDASSOCIATION); }
//
// Make sure the parent is in a ready state
//
hResult = m_InformationManager.ReadyApplication(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_APPLICATIONREQUIRED); }
//
// Lock the parent applications
//
hResult = m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid); if (FAILED(hResult)) { THROW(hResult); } else { fParentLocked = TRUE; }
//
// Go get the device index of the associated applications
//
memcpy((LPVOID) &sDeviceRecord.sDeviceGuid, (LPVOID) &sApplicationData.sBaseInfo.sDeviceGuid, sizeof(GUID)); hResult = m_InformationManager.GetDeviceInfo(&sDeviceRecord); if (FAILED(hResult)) { THROW(E_UNEXPECTED); }
dwDeviceIndex = sDeviceRecord.sDeviceInfo.dwDeviceIndex;
//
// Go get the space required to install the application on the device
//
hResult = m_InformationManager.FreeSpaceOnDevice(&sDeviceRecord.sDeviceGuid, m_sApplicationData.sBaseInfo.dwReservedKilobytes); if (FAILED(hResult)) { THROW(APPMAN_E_NODISKSPACEAVAILABLE); }
//
// Add the application to the database and then assign it a device. Note that we do
// not have to check for success code since these methods throw exceptions on error
//
m_InformationManager.AddApplicationData(&m_sApplicationData, &m_sInstanceGuid); m_InformationManager.AssignDeviceToApplication(dwDeviceIndex, &m_sApplicationData);
//
// Lock the application
//
LockApplication();
//
// Setup the root paths and setup root paths depending on association type
//
switch(m_sApplicationData.sAssociation.dwAssociationType) { case APP_ASSOCIATION_INHERITBOTHPATHS // inherits both setup and application root paths
: memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], MAX_PATH_CHARCOUNT+1); memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], MAX_PATH_CHARCOUNT+1); VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH); VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH); break; case APP_ASSOCIATION_INHERITAPPROOTPATH // inherits application root path
: memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], MAX_PATH_CHARCOUNT+1); if (FAILED(CoCreateGuid(&sPathGuid))) { THROW(E_UNEXPECTED); } 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]); VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH); VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH); break; case APP_ASSOCIATION_INHERITSETUPROOTPATH // inherits setup root path and is rooted within application root path
: swprintf(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], L"%s\\%s", sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_SIGNATURE]); VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH); memcpy((LPVOID) m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], MAX_PATH_CHARCOUNT+1); VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH); break; default : THROW(APPMAN_E_INVALIDASSOCIATION); break; }
//
// Record the application guid within the association
//
memcpy((LPVOID) &m_sApplicationData.sAssociation.sChildGuid, (LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID));
//
// Set the application data into the registry
//
m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
//
// Add the association
//
m_InformationManager.AddAssociation(&m_sApplicationData.sAssociation); } else { //
// Are we in advanced mode
//
if (0 != dwAdvancedMode) { DWORD dwBaseIndex;
//
// Figure out where the first legal character is in the root path
//
dwBaseIndex = 0; 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]))))) { dwBaseIndex++; }
if (!(dwBaseIndex < StrLenW(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]))) { THROW(APPMAN_E_INVALIDROOTPATH); }
//
// Figure out which drive it is supposed to be in
//
dwIndex = 0; do { dwDeviceIndex = dwIndex; swprintf(wszRootPath, L"%c:\\", dwDeviceIndex + 65); dwIndex++;
} while ((26 > dwIndex)&&(0 != _wcsnicmp(wszRootPath, &(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH][dwBaseIndex]), 3)));
//
// Did we fail to find a matching device string
//
if (26 <= dwIndex) { THROW(APPMAN_E_INVALIDROOTPATH); }
//
// Go get the device index of the associated applications
//
hResult = m_InformationManager.GetDeviceInfoWithIndex(dwDeviceIndex, &sDeviceRecord); if (FAILED(hResult)) { THROW(E_UNEXPECTED); }
//
// Go get the space required to install the application on the device
//
hResult = m_InformationManager.FreeSpaceOnDevice(&sDeviceRecord.sDeviceGuid, m_sApplicationData.sBaseInfo.dwReservedKilobytes); if (FAILED(hResult)) { THROW(APPMAN_E_NODISKSPACEAVAILABLE); }
//
// Add the application to the database and then assign it a device. Note that we do
// not have to check for success code since these methods throw exceptions on error
//
m_InformationManager.AddApplicationData(&m_sApplicationData, &m_sInstanceGuid); m_InformationManager.AssignDeviceToApplication(dwDeviceIndex, &m_sApplicationData);
//
// Lock the application
//
LockApplication();
//
// Setup the setup root paths depending on association type
//
if (FAILED(CoCreateGuid(&sPathGuid))) { THROW(E_UNEXPECTED); } 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]); VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH);
//
// Set the application data into the registry
//
m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid); } else { //
// Check to see if the application root path already exists on a device and if so,
// attempt to install the application on that device
//
fApplicationRootExists = FALSE; dwDeviceIndex = 0xffffffff; dwIndex = 2; do { //
// Build the application root path
//
if (1 == StrLenW(wszCategory)) { 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]); } else { 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]); }
//
// Check to see whether or not it exists
//
swprintf(wszRootPath, L"%c:\\", dwIndex + 65); if (DRIVE_FIXED == Win32API.GetDriveType(wszRootPath)) { fApplicationRootExists = Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]); if (TRUE == fApplicationRootExists) { dwDeviceIndex = dwIndex; } }
dwIndex++; } while ((FALSE == fApplicationRootExists)&&(26 > dwIndex));
//
// Go get the space
//
hResult = APPMAN_E_NODISKSPACEAVAILABLE; if (0xffffffff != dwDeviceIndex) { //
// The root path of the application was found on device dwDeviceIndex. Is this
// device excluded
//
m_InformationManager.GetDeviceInfoWithIndex(dwDeviceIndex, &sDeviceRecord); if (0 == (m_sApplicationData.sBaseInfo.dwCategory & sDeviceRecord.sDeviceInfo.dwApplicationCategoryExclusionMask)) { hResult = m_InformationManager.FreeSpaceOnDevice(&sDeviceRecord.sDeviceGuid, m_sApplicationData.sBaseInfo.dwReservedKilobytes); } }
if (FAILED(hResult)) { //
// We failed to get space on the device that contained the legacy application
// root path. Therefore, we fall back
//
hResult = m_InformationManager.GetSpace(m_sApplicationData.sBaseInfo.dwCategory, m_sApplicationData.sBaseInfo.dwReservedKilobytes, &dwDeviceIndex); }
//
// Go get the space
//
if (SUCCEEDED(hResult)) { //
// Add the application to the database and then assign it a device. Note that we do
// not have to check for success code since these methods throw exceptions on error
//
m_InformationManager.AddApplicationData(&m_sApplicationData, &m_sInstanceGuid); m_InformationManager.AssignDeviceToApplication(dwDeviceIndex, &m_sApplicationData); //
// Lock the application
//
LockApplication();
//
// Create the root paths
//
if (1 == StrLenW(wszCategory)) { 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]); } else { 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]); }
if (FAILED(CoCreateGuid(&sPathGuid))) { THROW(E_UNEXPECTED); } 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]);
VALIDATE_PROPERTY(IDX_PROPERTY_ROOTPATH); VALIDATE_PROPERTY(IDX_PROPERTY_SETUPROOTPATH);
//
// Set the Appplication Info
//
m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid); } else { THROW(APPMAN_E_NODISKSPACEAVAILABLE); } } } } else { //
// Let's get the current information about this application
//
hResult = m_InformationManager.GetApplicationData(&m_sApplicationData); if (FAILED(hResult)) { THROW(E_UNEXPECTED); }
//
// First we lock the application
//
LockApplication();
//
// Save the reserved space into dwReservedKilobytes temporarily
//
dwReservedKilobytes = m_sApplicationData.sBaseInfo.dwReservedKilobytes;
//
// Get the application information as registered within the database.
//
if (FAILED(m_InformationManager.GetApplicationData(&m_sApplicationData))) { SetInitializationLevel(INIT_LEVEL_BASIC); THROW(E_UNEXPECTED); }
//
// Restore the dwReservedKilobytes value
//
m_sApplicationData.sBaseInfo.dwReservedKilobytes = dwReservedKilobytes; VALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
//
// Make sure the app is in an APP_STATE_INSTALLING state
//
if (!CHECK_APPLICATIONSTATE(APP_STATE_INSTALLING)) { SetInitializationLevel(INIT_LEVEL_BASIC); THROW(APPMAN_E_APPLICATIONALREADYEXISTS); }
//
// Go get the space
//
if (FAILED(m_InformationManager.FreeSpaceOnDevice(&(m_sApplicationData.sBaseInfo.sDeviceGuid), m_sApplicationData.sBaseInfo.dwReservedKilobytes))) { THROW(APPMAN_E_NODISKSPACEAVAILABLE); } }
//
// Create the root paths if required
//
if (FALSE == Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH])) { Win32API.CreateDirectory(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], TRUE); }
if (FALSE == Win32API.FileExists(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH])) { Win32API.CreateDirectory(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], TRUE); }
//
// Record the original size of the root paths in order to compute the deltas during
// FinalizeInstall
//
ComputeOriginalApplicationSpaceInfo();
//
// Initialize some other properties
//
m_sApplicationData.sBaseInfo.dwRemovableKilobytes = 0; m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes = 0; VALIDATE_PROPERTY(IDX_PROPERTY_REMOVABLEKILOBYTES); VALIDATE_PROPERTY(IDX_PROPERTY_NONREMOVABLEKILOBYTES);
//
// Get the application record ready for installation
//
SET_APPLICATIONSTATE(APP_STATE_INSTALLING); SET_ACTIONSTATE(CURRENT_ACTION_INSTALLING); m_dwInitializationLevel = INIT_LEVEL_TOTAL; }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { //
// Make sure that if we have locked parents, we unlock them here
//
if (fParentLocked) { APPLICATION_DATA sApplicationData;
//
// Go get the application data of the associated application
//
memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &m_sApplicationData.sAssociation.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (SUCCEEDED(hResult)) { m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); } }
//
// Make sure to record the hResult that caused the error
//
hResult = pException->GetResultCode();
delete pException; }
catch(...) { //
// Make sure that if we have locked parents, we unlock them here
//
if (fParentLocked) { APPLICATION_DATA sApplicationData;
//
// Go get the application data of the associated application
//
memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &m_sApplicationData.sAssociation.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (SUCCEEDED(hResult)) { m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); } }
hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::FinalizeInstall(void) { FUNCTION("CAppEntry::FinalizeInstall ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { CWin32API sWin32API; DWORD dwIndex;//, dwActualApplicationSize; // Get rid of /W4 warning.
APPLICATION_DATA sApplicationData; ASSOCIATION_INFO sAssociationInfo;
//
// Make sure we are currently installing
//
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_INSTALLING)) { THROW(APPMAN_E_ACTIONNOTINITIALIZED); }
if (INIT_LEVEL_TOTAL != m_dwInitializationLevel) { THROW(APPMAN_E_ACTIONNOTINITIALIZED); }
//
// Are the required properties set
//
if (((APP_CATEGORY_PATCH | APP_CATEGORY_DATA) & m_sApplicationData.sBaseInfo.dwCategory)) { if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_EXECUTECMDLINE, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } } else { if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_EXECUTECMDLINE, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE])) { THROW(APPMAN_E_INVALIDEXECUTECMDLINE); } }
//
// Was a default setup command line given to us
//
if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_DEFAULTSETUPEXECMDLINE, &m_sApplicationData)) { if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_DEFAULTSETUPEXECMDLINE])) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_DOWNSIZECMDLINE, &m_sApplicationData)) { if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_DOWNSIZECMDLINE])) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } } if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_REINSTALLCMDLINE, &m_sApplicationData)) { if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_REINSTALLCMDLINE])) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } } if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_UNINSTALLCMDLINE, &m_sApplicationData)) { if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_UNINSTALLCMDLINE])) { THROW(APPMAN_E_INVALIDUNINSTALLCMDLINE); } } if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SELFTESTCMDLINE, &m_sApplicationData)) { if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_SELFTESTCMDLINE])) { THROW(APPMAN_E_INVALIDSELFTESTCMDLINE); } } } else { if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_DOWNSIZECMDLINE, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_DOWNSIZECMDLINE])) { THROW(APPMAN_E_INVALIDDOWNSIZECMDLINE); } if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_REINSTALLCMDLINE, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_REINSTALLCMDLINE])) { THROW(APPMAN_E_INVALIDREINSTALLCMDLINE); } if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_UNINSTALLCMDLINE, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_UNINSTALLCMDLINE])) { THROW(APPMAN_E_INVALIDUNINSTALLCMDLINE); } if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SELFTESTCMDLINE, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } if (S_OK != ValidateCommandLine(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH], m_sApplicationData.wszStringProperty[APP_STRING_SELFTESTCMDLINE])) { THROW(APPMAN_E_INVALIDSELFTESTCMDLINE); } }
//
// Do we need to do a cache fixup
//
ComputeApplicationSpaceInfo(m_sApplicationData.sBaseInfo.dwReservedKilobytes);
//
// Delete the reserved space field
//
m_sApplicationData.sBaseInfo.dwReservedKilobytes = 0; INVALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
//
// Before we arbitrarily set the state of the application to APP_STATE_READY, check
// to see if the setup technology hasn't already changed
//
if (APP_STATE_INSTALLING == GET_APPLICATIONSTATE()) { RESET_APPLICATIONSTATE(APP_STATE_READY); } else { if (APP_STATE_DOWNSIZED != GET_APPLICATIONSTATE()) { THROW(APPMAN_E_INVALIDPROPERTYVALUE); } }
//
// Save the application info
//
m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
//
// Make sure this IApplicationEntry instance is no longer in an action state
//
SET_ACTIONSTATE(CURRENT_ACTION_NONE);
//
// Unlock the parent apps
//
ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo)); dwIndex = 0; while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &(sAssociationInfo.sChildGuid), (LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), sizeof(GUID))) { //
// Get the associated application
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (SUCCEEDED(hResult)) { //
// Unlock the parent applications
//
m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); } } dwIndex++; }
//
// Unlock this app
//
UnLockApplication(); } ///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::InitializeDownsize(void) { FUNCTION("CAppEntry::InitializeDownsize ()");
HRESULT hResult = S_OK; HRESULT hLockResult = S_FALSE;
///////////////////////////////////////////////////////////////////////////////////////
try { if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(APPMAN_E_ACTIONINPROGRESS); }
//
// Are the required properties set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
//
// Lock the application
//
hResult = LockApplication(); if (S_OK == hResult) { hLockResult = S_OK;
hResult = m_InformationManager.GetApplicationData(&m_sApplicationData); if (SUCCEEDED(hResult)) { //
// Since GetApplicationInfo succeeded this means we have a totally initialized object
//
m_dwInitializationLevel = INIT_LEVEL_TOTAL;
//
// Record the original size of the root paths in order to compute the deltas during
// FinalizeInstall
//
ComputeOriginalApplicationSpaceInfo();
//
// Set the states
//
m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState; RESET_APPLICATIONSTATE(APP_STATE_DOWNSIZING); SET_ACTIONSTATE(CURRENT_ACTION_DOWNSIZING);
//
// Enter the wait event if any
//
m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid); } } else { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE); } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { //
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE); }
//
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
//
// Record the error code
//
hResult = pException->GetResultCode();
delete pException; }
catch(...) { //
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE); }
//
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::FinalizeDownsize(void) { FUNCTION("CAppEntry::FinalizeDownsize ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { if (!CHECK_ACTIONSTATE(CURRENT_ACTION_DOWNSIZING)) { THROW(APPMAN_E_ACTIONNOTINITIALIZED); }
//
// Do we need to do a cache fixup
//
ComputeApplicationSpaceInfo(0);
//
// Set the application state to downsized
//
m_sApplicationData.sBaseInfo.dwState = APP_STATE_DOWNSIZED;
//
// Save the application info
//
m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
//
// Unlock the application
//
UnLockApplication();
//
// Leave the wait event
//
m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE);
SET_ACTIONSTATE(CURRENT_ACTION_NONE); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::InitializeReInstall(void) { FUNCTION("CAppEntry::InitializeReInstall ()");
HRESULT hResult = S_OK; HRESULT hLockResult = S_FALSE; BOOL fParentLocked = FALSE;
///////////////////////////////////////////////////////////////////////////////////////
try { APPLICATION_DATA sApplicationData; ASSOCIATION_INFO sAssociationInfo; DWORD dwIndex; DWORD dwReservedKilobytes; CWin32API sWin32API;
if ((!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE))&&(!CHECK_ACTIONSTATE(CURRENT_ACTION_SELFTESTING))) { THROW(APPMAN_E_ACTIONINPROGRESS); }
//
// Are the required properties set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } //
// Save the dwReservedKilobytes property before calling GetApplicationData
//
dwReservedKilobytes = m_sApplicationData.sBaseInfo.dwReservedKilobytes;
//
// First we lock this application
//
hResult = LockApplication(); if (S_OK == hResult) { hLockResult = S_OK;
hResult = m_InformationManager.GetApplicationData(& m_sApplicationData); if (SUCCEEDED(hResult)) { //
// Since GetApplicationInfo succeeded this means we have a totally initialized object
//
m_dwInitializationLevel = INIT_LEVEL_TOTAL;
//
// Make sure to restore and validate the dwReservedKilobytes
//
m_sApplicationData.sBaseInfo.dwReservedKilobytes = dwReservedKilobytes; VALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
//
// Make sure that the parent associated apps are associated
//
ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo)); dwIndex = 0; while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID))) { //
// Get the associated application
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_INVALIDASSOCIATION); }
//
// Make sure the associated app is in a ready state
//
hResult = m_InformationManager.ReadyApplication(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_APPLICATIONREQUIRED); }
//
// Lock the parent applications
//
hResult = m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid); if (FAILED(hResult)) { THROW(hResult); } else { fParentLocked = TRUE; } } dwIndex++; }
//
// Go get the space
//
if (FAILED(m_InformationManager.FreeSpaceOnDevice(&(m_sApplicationData.sBaseInfo.sDeviceGuid), m_sApplicationData.sBaseInfo.dwReservedKilobytes))) { THROW(APPMAN_E_NODISKSPACEAVAILABLE); }
//
// Record the original size of the root paths in order to computer the deltas during
// FinalizeInstall
//
ComputeOriginalApplicationSpaceInfo();
//
// Set the state of the application
//
m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState; m_sApplicationData.sBaseInfo.dwState = APP_STATE_REINSTALLING; m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
if (CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { SET_ACTIONSTATE(CURRENT_ACTION_REINSTALLING); } else { SET_ACTIONSTATE(CURRENT_ACTION_REINSTALLING | CURRENT_ACTION_SELFTESTING); }
//
// Enter the wait event if any
//
m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL, &m_sInstanceGuid); } } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { APPLICATION_DATA sApplicationData; ASSOCIATION_INFO sAssociationInfo; DWORD dwIndex;
//
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
//
// Make sure that if we have locked parents, we unlock them here
//
if (fParentLocked) { ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo)); dwIndex = 0; while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID))) { //
// Get the associated application
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); if (SUCCEEDED(m_InformationManager.GetApplicationData(&sApplicationData))) { //
// Unlock the parent applications
//
m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid); } } dwIndex++; } }
//
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL); } hResult = pException->GetResultCode(); delete pException; }
catch(...) { APPLICATION_DATA sApplicationData; ASSOCIATION_INFO sAssociationInfo; DWORD dwIndex;
//
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
//
// Make sure that if we have locked parents, we unlock them here
//
if (fParentLocked) { ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo)); dwIndex = 0; while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID))) { //
// Get the associated application
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); if (SUCCEEDED(m_InformationManager.GetApplicationData(&sApplicationData))) { //
// Unlock the parent applications
//
m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid); } } dwIndex++; } }
//
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL); }
hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::FinalizeReInstall(void) { FUNCTION("CAppEntry::FinalizeReInstall ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { CWin32API sWin32API; DWORD dwIndex; //, dwActualApplicationSize; Get rid of /W4 warning.
APPLICATION_DATA sApplicationData; ASSOCIATION_INFO sAssociationInfo;
//
// Make sure we are currently reinstalling
//
if ((!CHECK_ACTIONSTATE(CURRENT_ACTION_REINSTALLING))&&(!CHECK_ACTIONSTATE(CURRENT_ACTION_REINSTALLING | CURRENT_ACTION_SELFTESTING))) { THROW(APPMAN_E_ACTIONNOTINITIALIZED); } //
// Do we need to do a cache fixup
//
ComputeApplicationSpaceInfo(m_sApplicationData.sBaseInfo.dwReservedKilobytes);
//
// Clear the dwReservedKilobytes data member
//
m_sApplicationData.sBaseInfo.dwReservedKilobytes = 0; INVALIDATE_PROPERTY(IDX_PROPERTY_ESTIMATEDINSTALLKILOBYTES);
//
// Update the aging information
//
m_sApplicationData.sAgingInfo.dwReInstallCount++; GetLocalTime(&(m_sApplicationData.sAgingInfo.stLastUsedDate)); VALIDATE_PROPERTY(IDX_PROPERTY_LASTUSEDDATE);
//
// Set the application state to ready
//
m_sApplicationData.sBaseInfo.dwState = APP_STATE_READY;
//
// Save the application info
//
m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid); if (CHECK_ACTIONSTATE(CURRENT_ACTION_REINSTALLING)) { RESET_ACTIONSTATE(CURRENT_ACTION_NONE); } else { RESET_ACTIONSTATE(CURRENT_ACTION_SELFTESTING); }
//
// Before we do anything, make sure to unlock the parent apps
//
ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo)); dwIndex = 0; while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), (LPVOID) &(sAssociationInfo.sChildGuid), sizeof(GUID))) { //
// Get the associated application
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (SUCCEEDED(hResult)) { //
// Unlock the parent applications
//
m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); } } dwIndex++; }
UnLockApplication();
//
// Leave the wait event
//
m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::InitializeUnInstall(void) { FUNCTION("CAppEntry::InitializeUnInstall ()");
HRESULT hResult = S_OK; HRESULT hLockResult = S_FALSE;
///////////////////////////////////////////////////////////////////////////////////////
try { ASSOCIATION_INFO sAssociationInfo; DWORD dwIndex;
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(APPMAN_E_ACTIONINPROGRESS); }
//
// Are the required properties set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
hResult = m_InformationManager.GetApplicationData(&m_sApplicationData); if (SUCCEEDED(hResult)) { //
// Since GetApplicationInfo succeeded this means we have a totally initialized object
//
m_dwInitializationLevel = INIT_LEVEL_TOTAL;
//
// Check to make sure that this application is not required for another to run
//
dwIndex = 0;
while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID))) { THROW(APPMAN_E_APPLICATIONREQUIRED); }
dwIndex++; }
//
// Lock the application
//
hResult = LockApplication(); if (S_OK == hResult) { hLockResult = S_OK; m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState; RESET_APPLICATIONSTATE(APP_STATE_UNINSTALLING); SET_ACTIONSTATE(CURRENT_ACTION_UNINSTALLING);
//
// Enter the wait event if any
//
m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL, &m_sInstanceGuid); } } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { //
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
//
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL); }
hResult = pException->GetResultCode(); delete pException; }
catch(...) { //
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
//
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL); }
hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::FinalizeUnInstall(void) { FUNCTION("CAppEntry::FinalizeUnInstall ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try {
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_UNINSTALLING)) { THROW(APPMAN_E_ACTIONNOTINITIALIZED); }
//
// Remove the application from the system
//
m_InformationManager.RemoveApplicationData(&m_sApplicationData); UnLockApplication(); RESET_ACTIONSTATE(CURRENT_ACTION_NONE);
//
// Leave the wait event
//
m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::InitializeSelfTest(void) { FUNCTION("CAppEntry::InitializeSelfTest ()");
HRESULT hResult = S_OK; HRESULT hLockResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(APPMAN_E_ACTIONINPROGRESS); }
//
// Are the required properties set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
hResult = LockApplication(); if (S_OK == hResult) { hLockResult = S_OK; hResult = m_InformationManager.GetApplicationData(&m_sApplicationData); if (SUCCEEDED(hResult)) { //
// Since GetApplicationInfo succeeded this means we have a totally initialized object
//
m_dwInitializationLevel = INIT_LEVEL_TOTAL;
m_dwOriginalState = m_sApplicationData.sBaseInfo.dwState; m_sApplicationData.sBaseInfo.dwState |= APP_STATE_SELFTESTING; m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid); SET_ACTIONSTATE(CURRENT_ACTION_SELFTESTING);
//
// Enter the wait event if any
//
m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST, &m_sInstanceGuid); } } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { //
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
//
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST); }
hResult = pException->GetResultCode(); delete pException; }
catch(...) { //
// Make sure to unlock the application if it was locked
//
if (S_OK == hLockResult) { UnLockApplication(); }
//
// Make sure to kill the wait event
//
if (INIT_LEVEL_TOTAL == m_dwInitializationLevel) { m_InformationManager.EnterWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST, &m_sInstanceGuid); m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST); }
hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::FinalizeSelfTest(void) { FUNCTION("CAppEntry::FinalizeSelfTest ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { APPLICATION_DATA sApplicationData;
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_SELFTESTING)) { THROW(APPMAN_E_ACTIONNOTINITIALIZED); }
//
// Get the latest information from the database
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(sApplicationData)); m_InformationManager.SetApplicationData(&sApplicationData, &m_sInstanceGuid);
//
// Remove the selftest state flag from the application state
//
sApplicationData.sBaseInfo.dwState &= ~APP_STATE_SELFTESTING; memcpy((LPVOID) &m_sApplicationData, (LPVOID) &sApplicationData, sizeof(sApplicationData));
//
// Save the application info
//
m_InformationManager.SetApplicationData(&sApplicationData, &m_sInstanceGuid); UnLockApplication(); RESET_ACTIONSTATE(CURRENT_ACTION_NONE);
//
// Leave the wait event
//
m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::Abort(void) { FUNCTION("CAppEntry::Abort ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { APPLICATION_DATA sApplicationData; ASSOCIATION_INFO sAssociationInfo; DWORD dwIndex;
if (CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(APPMAN_E_ACTIONNOTINITIALIZED); }
//
// We need to force a leave event
//
switch(m_dwCurrentAction) { case CURRENT_ACTION_DOWNSIZING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_DOWNSIZE); break;
case CURRENT_ACTION_REINSTALLING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_REINSTALL); break;
case CURRENT_ACTION_UNINSTALLING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_UNINSTALL); break;
case CURRENT_ACTION_SELFTESTING : m_InformationManager.LeaveWaitEvent(&m_sApplicationData, WAIT_FINALIZE_SELFTEST); break; }
//
// Before we do anything, make sure to unlock the parent apps
//
ZeroMemory(&sAssociationInfo, sizeof(sAssociationInfo)); dwIndex = 0; while (S_OK == m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo)) { if (0 == memcmp((LPVOID) &(sAssociationInfo.sChildGuid), (LPVOID) &(m_sApplicationData.sBaseInfo.sApplicationGuid), sizeof(GUID))) { //
// Get the associated application
//
ZeroMemory(&sApplicationData, sizeof(sApplicationData)); memcpy((LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); m_InformationManager.ValidateApplicationPropertyWithIndex(IDX_PROPERTY_GUID, &sApplicationData); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (SUCCEEDED(hResult)) { //
// Unlock the parent applications
//
m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); } } dwIndex++; }
//
// If the application was doing an initial install, abort will cause the application
// entry to be removed from the system
//
if (CHECK_ACTIONSTATE(CURRENT_ACTION_INSTALLING)) { UnLockApplication(); m_InformationManager.RemoveApplicationData(&m_sApplicationData); } else { //
// Simply restore the application info with the record currently saved in the
// registry
//
m_InformationManager.GetApplicationData(&m_sApplicationData); m_sApplicationData.sBaseInfo.dwState = m_dwOriginalState; m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid); UnLockApplication(); }
SET_ACTIONSTATE(CURRENT_ACTION_NONE); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::Run(const DWORD dwRunFlags, const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen) { FUNCTION("CAppEntry::Run ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { WCHAR wszParameters[MAX_PATH_CHARCOUNT]; WCHAR wszCommandLine[MAX_PATH_CHARCOUNT]; CWin32API sWin32API; BOOL fRunning = FALSE; PROCESS_INFORMATION sProcessInformation;
//
// We can only run if this object is not doing anything
//
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(APPMAN_E_ACTIONINPROGRESS); }
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { if ((S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_COMPANYNAME, &m_sApplicationData))||(S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SIGNATURE, &m_sApplicationData))) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); } }
//
// Make sure the application actually exists
//
if (INIT_LEVEL_NONE == m_dwInitializationLevel) { hResult = m_InformationManager.GetApplicationData(&m_sApplicationData); if (FAILED(hResult)) { THROW(hResult); } m_dwInitializationLevel = INIT_LEVEL_BASIC; }
//
// This object cannot be run if it is APP_CATEGORY_PATCH or APP_CATEGORY_DAT
//
if ((APP_CATEGORY_PATCH | APP_CATEGORY_DATA) & m_sApplicationData.sBaseInfo.dwCategory) { THROW(APPMAN_E_APPNOTEXECUTABLE); }
//
// Are the required properties set
//
//
// Ready the application
//
m_InformationManager.ReadyApplication(&m_sApplicationData);
//
// Build the command line parameters
//
ZeroMemory(wszParameters, sizeof(wszParameters)); if ((APP_PROPERTY_STR_ANSI == dwStringMask)||(APP_PROPERTY_STR_UNICODE == dwStringMask)) { //
// Check to make sure the parameters are valid
//
if (NULL != lpData) { if (IsBadReadPtr(lpData, dwDataLen)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (0 < dwDataLen) { //
// Make sure the command line parameters are converted to unicode
//
if (APP_PROPERTY_STR_ANSI == dwStringMask) { if (MAX_PATH_CHARCOUNT < StrLenA((LPCSTR) lpData)) { THROW(APPMAN_E_INVALIDEXECUTECMDLINE); } else { sWin32API.MultiByteToWideChar((LPCSTR) lpData, dwDataLen, wszParameters, MAX_PATH_CHARCOUNT); } } else { if (MAX_PATH_CHARCOUNT < StrLenW((LPCWSTR) lpData)) { THROW(APPMAN_E_INVALIDEXECUTECMDLINE); } else { memcpy(wszParameters, lpData, StrLenW((LPCWSTR) lpData) * 2); } } } } } else { if (0 != dwStringMask) { THROW(APPMAN_E_INVALIDPARAMETERS); } }
//
// Construct the command line
//
if (1 < StrLenW(wszParameters)) { //
// Make sure the total lenght does not exceed MAX_PATH_CHARCOUNT
//
if (MAX_PATH_CHARCOUNT < (StrLenW(m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE])+StrLenW(wszParameters))) { THROW(APPMAN_E_INVALIDEXECUTECMDLINE); }
wcscpy(wszCommandLine, m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE]); wcscat(wszCommandLine, L" /AppManStarted "); wcscat(wszCommandLine, wszParameters); } else { wcscpy(wszCommandLine, m_sApplicationData.wszStringProperty[APP_STRING_EXECUTECMDLINE]); wcscat(wszCommandLine, L" /AppManStarted"); }
//
// Run it
//
if (sWin32API.CreateProcess(wszCommandLine, &sProcessInformation)) { fRunning = TRUE; } else { if (SUCCEEDED(m_InformationManager.SelfTestApplication(&m_sApplicationData))) { if (sWin32API.CreateProcess(wszCommandLine, &sProcessInformation)) { fRunning = TRUE; } else { THROW(E_FAIL); } } else { THROW(E_FAIL); } }
if (fRunning) { m_sApplicationData.sAgingInfo.dwUsageCount++; GetLocalTime(&(m_sApplicationData.sAgingInfo.stLastUsedDate)); m_InformationManager.SetApplicationData(&m_sApplicationData, &m_sInstanceGuid);
if (APP_RUN_BLOCK & dwRunFlags) { WaitForSingleObject(sProcessInformation.hProcess, INFINITE); }
CloseHandle(sProcessInformation.hThread); CloseHandle(sProcessInformation.hProcess);
hResult = S_OK; } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::AddAssociation(const DWORD dwAssociationType, const IApplicationEntry * lpApplicationEntry) { FUNCTION("CAppEntry::AddAssociation ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { ASSOCIATION_INFO sAssociationRecord; APPLICATION_DATA sApplicationData;
//
// Make sure we are in a proper state
//
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(APPMAN_E_CANNOTASSOCIATE); }
//
// The initialization level should be INIT_LEVEL_NONE
//
if (INIT_LEVEL_NONE != m_dwInitializationLevel) { THROW(APPMAN_E_CANNOTASSOCIATE); }
//
// Make sure an association does not already exist
//
if (0 != m_sApplicationData.sAssociation.dwAssociationType) { THROW(APPMAN_E_CANNOTASSOCIATE); }
//
// Make sure the lpApplicationEntry parameter is valid
//
if (NULL == lpApplicationEntry) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadReadPtr((LPVOID) lpApplicationEntry, sizeof(CApplicationEntry))) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Make sure that dwAssociationType is valid
//
if ((APP_ASSOCIATION_INHERITBOTHPATHS != dwAssociationType)&&(APP_ASSOCIATION_INHERITAPPROOTPATH != dwAssociationType)&&(APP_ASSOCIATION_INHERITSETUPROOTPATH != dwAssociationType)) { THROW(APPMAN_E_INVALIDASSOCIATION); }
//
// Make sure the root path is not already set
//
if (S_OK == m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData)) { THROW(APPMAN_E_CANNOTASSOCIATE); }
//
// Initialize the sAssociationRecord structure
//
sAssociationRecord.dwSize = sizeof(ASSOCIATION_INFO); sAssociationRecord.dwStructId = ASSOCIATION_STRUCT; sAssociationRecord.dwAssociationType = dwAssociationType;
//
// Does the application we want to association with even exist
//
memcpy((LPVOID) &sApplicationData, (LPVOID) ((CApplicationEntry *)lpApplicationEntry)->GetApplicationDataPtr(), sizeof(APPLICATION_DATA)); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_UNKNOWNAPPLICATION); }
//
// Fill in the rest of the information
//
memcpy((LPVOID)&sAssociationRecord.sParentGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID));
//
// Is there an association already ?
//
if (0 != m_sApplicationData.sAssociation.dwAssociationType) { THROW(APPMAN_E_ALREADYASSOCIATED); }
//
// Ok make the association happen
//
memcpy((LPVOID) &m_sApplicationData.sAssociation, (LPVOID) &sAssociationRecord, sizeof(ASSOCIATION_INFO));
}
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::RemoveAssociation(const DWORD dwAssociationType, const IApplicationEntry * lpApplicationEntry) { FUNCTION("CAppEntry::RemoveAssociation ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { //
// Make sure we are in a proper state
//
if (!CHECK_ACTIONSTATE(CURRENT_ACTION_NONE)) { THROW(E_FAIL); }
//
// The initialization level should be INIT_LEVEL_NONE
//
if (INIT_LEVEL_NONE != m_dwInitializationLevel) { THROW(E_FAIL); }
//
// Make sure the lpApplicationEntry parameter is proper
//
if (NULL == lpApplicationEntry) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadReadPtr((LPVOID) lpApplicationEntry, sizeof(CApplicationEntry))) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Make sure that dwAssociationType is valid
//
if ((APP_ASSOCIATION_INHERITBOTHPATHS != dwAssociationType)&&(APP_ASSOCIATION_INHERITAPPROOTPATH != dwAssociationType)&&(APP_ASSOCIATION_INHERITSETUPROOTPATH != dwAssociationType)) { THROW(APPMAN_E_INVALIDASSOCIATION); }
//
// Make sure an association does exist
//
if (0 == m_sApplicationData.sAssociation.dwAssociationType) { THROW(E_FAIL); }
ZeroMemory(&m_sApplicationData.sAssociation, sizeof(ASSOCIATION_INFO)); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::EnumAssociations(const DWORD dwTargetIndex, LPDWORD lpdwAssociationType, IApplicationEntry * lpApplicationEntry) { FUNCTION("CAppEntry::EnumAssociations ()");
HRESULT hResult = S_OK;
///////////////////////////////////////////////////////////////////////////////////////
try { ASSOCIATION_INFO sAssociationInfo; DWORD dwIndex, dwActualIndex;
//
// Make sure the lpApplicationEntry pointer is good
//
if (NULL == lpApplicationEntry) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadReadPtr((LPVOID) lpApplicationEntry, sizeof(CApplicationEntry))) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Make sure that the lpdwAssociationType is valid
//
if (NULL == lpdwAssociationType) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadWritePtr((LPVOID) lpdwAssociationType, sizeof(DWORD))) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Get the nth association record. Ignore associations that belong to other applications
//
dwActualIndex = dwTargetIndex; dwIndex = 0; do { hResult = m_InformationManager.EnumAssociations(dwIndex, &sAssociationInfo); if (S_OK == hResult) { if (memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sChildGuid, sizeof(GUID))) { if (memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID))) { dwActualIndex++; } } } dwIndex++; } while ((dwIndex <= dwActualIndex)&&(S_OK == hResult));
//
// Did we find an association
//
if (S_OK == hResult) { if (0 == memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sChildGuid, sizeof(GUID))) { //
// The association is a child associations
//
*lpdwAssociationType = sAssociationInfo.dwAssociationType | APP_ASSOCIATION_CHILD; hResult = lpApplicationEntry->Clear(); if (SUCCEEDED(hResult)) { hResult = lpApplicationEntry->SetProperty(APP_PROPERTY_GUID, (LPCVOID) &sAssociationInfo.sParentGuid, sizeof(GUID)); if (SUCCEEDED(hResult)) { hResult = m_InformationManager.GetApplicationData(((CApplicationEntry *) lpApplicationEntry)->GetApplicationDataPtr()); if (SUCCEEDED(hResult)) { ((CApplicationEntry *) lpApplicationEntry)->SetInitializationLevel(INIT_LEVEL_BASIC); } } } } else { if (0 == memcmp((LPVOID) &m_sApplicationData.sBaseInfo.sApplicationGuid, (LPVOID) &sAssociationInfo.sParentGuid, sizeof(GUID))) { //
// The association is a parent association
//
*lpdwAssociationType = sAssociationInfo.dwAssociationType | APP_ASSOCIATION_PARENT; hResult = lpApplicationEntry->Clear(); if (SUCCEEDED(hResult)) { hResult = lpApplicationEntry->SetProperty(APP_PROPERTY_GUID, (LPCVOID) &sAssociationInfo.sChildGuid, sizeof(GUID)); if (SUCCEEDED(hResult)) { hResult = m_InformationManager.GetApplicationData(((CApplicationEntry *) lpApplicationEntry)->GetApplicationDataPtr()); if (SUCCEEDED(hResult)) { ((CApplicationEntry *) lpApplicationEntry)->SetInitializationLevel(INIT_LEVEL_BASIC); } } } } } } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::GetTemporarySpace(const DWORD dwKilobytes, const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen) { FUNCTION("CAppEntry::GetTemporarySpace ()");
HRESULT hResult = E_FAIL; BOOL fParentsLocked = FALSE; BOOL fLocked = FALSE; APPLICATION_DATA sApplicationData;
///////////////////////////////////////////////////////////////////////////////////////
try { TEMP_SPACE_RECORD sTempSpaceRecord; DWORD dwCharCount;
//
// Are the required properties set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
//
// Is the object a valid application object
//
memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(APPLICATION_DATA)); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_UNKNOWNAPPLICATION); }
//
// Make sure the string mask is good
//
if ((APP_PROPERTY_STR_ANSI != dwStringMask)&&(APP_PROPERTY_STR_UNICODE != dwStringMask)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Check to make sure dwDataLen is greater than 0
//
if (0 == dwDataLen) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Make sure that the lpData parameter is valid
//
if (NULL == lpData) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadWritePtr(lpData, dwDataLen)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Make sure the dwKilobytes is not 0
//
if (0 == dwKilobytes) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Lock this application and all of it's parents
//
if (SUCCEEDED(m_InformationManager.LockParentApplications(&sApplicationData, &m_sInstanceGuid))) { //
// Make sure to record that fact that the applications got locked (in case of a THROW)
//
fParentsLocked = TRUE;
if (SUCCEEDED(m_InformationManager.LockApplicationData(&sApplicationData, &m_sInstanceGuid))) {
//
// Make sure to record the fact that this application is locked (in case of a THROW)
//
fLocked = TRUE;
//
// Get the space
//
sTempSpaceRecord.dwSize = sizeof(TEMP_SPACE_RECORD); sTempSpaceRecord.dwStructId = TEMP_SPACE_STRUCT; sTempSpaceRecord.dwKilobytes = dwKilobytes; memcpy((LPVOID) &sTempSpaceRecord.sApplicationGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID)); hResult = m_InformationManager.AddTempSpace(&sTempSpaceRecord); if (FAILED(hResult)) { THROW(hResult); }
dwCharCount = StrLenW(sTempSpaceRecord.wszDirectory); if (APP_PROPERTY_STR_ANSI == dwStringMask) { if (dwCharCount > dwDataLen) { m_InformationManager.RemoveTempSpace(&sTempSpaceRecord); THROW(APPMAN_E_OVERFLOW); } CWin32API::WideCharToMultiByte((LPCWSTR) sTempSpaceRecord.wszDirectory, MAX_PATH_CHARCOUNT, (LPSTR) lpData, dwDataLen); } else { if (dwDataLen < (dwCharCount*2)) { m_InformationManager.RemoveTempSpace(&sTempSpaceRecord); THROW(APPMAN_E_OVERFLOW); } memcpy((LPVOID) lpData, (LPVOID) sTempSpaceRecord.wszDirectory, dwCharCount*2); }
//
// Unlock this application
//
m_InformationManager.UnlockApplicationData(&sApplicationData, &m_sInstanceGuid); }
//
// Unlock the parent applications
//
m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { //
// Unlock the applications if required
//
if (fParentsLocked) { m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); }
//
// Is this application locked
//
if (fLocked) { m_InformationManager.UnlockApplicationData(&sApplicationData, &m_sInstanceGuid); }
hResult = pException->GetResultCode(); delete pException; }
catch(...) { //
// Unlock the applications if required
//
if (fParentsLocked) { m_InformationManager.UnlockParentApplications(&sApplicationData, &m_sInstanceGuid); }
//
// Is this application locked
//
if (fLocked) { m_InformationManager.UnlockApplicationData(&sApplicationData, &m_sInstanceGuid); }
hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::RemoveTemporarySpace(const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen) { FUNCTION("CAppEntry::RemoveTemporarySpace ()");
HRESULT hResult = S_OK; APPLICATION_DATA sApplicationData;
///////////////////////////////////////////////////////////////////////////////////////
try { TEMP_SPACE_RECORD sTempSpaceRecord; DWORD dwCharCount;
//
// Are the required properties set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
//
// Is the object a valid application object
//
memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(APPLICATION_DATA)); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_UNKNOWNAPPLICATION); }
//
// Make sure the string mask is good
//
if ((APP_PROPERTY_STR_ANSI != dwStringMask)&&(APP_PROPERTY_STR_UNICODE != dwStringMask)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Check to make sure dwDataLen is greater than 0
//
if (0 == dwDataLen) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Make sure that the lpData parameter is valid
//
if (NULL == lpData) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadReadPtr(lpData, dwDataLen)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Initialize the sTempSpaceRecord structure
//
sTempSpaceRecord.dwSize = sizeof(TEMP_SPACE_RECORD); sTempSpaceRecord.dwStructId = TEMP_SPACE_STRUCT; memcpy((LPVOID) &sTempSpaceRecord.sApplicationGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID)); if (APP_PROPERTY_STR_ANSI == dwStringMask) { dwCharCount = StrLenA((LPSTR) lpData); if (dwCharCount > MAX_PATH_CHARCOUNT) { THROW(APPMAN_E_OVERFLOW); } CWin32API::MultiByteToWideChar((LPCSTR) lpData, dwDataLen, sTempSpaceRecord.wszDirectory, MAX_PATH_CHARCOUNT); } else { dwCharCount = StrLenW((LPWSTR) lpData); if (dwCharCount > MAX_PATH_CHARCOUNT) { THROW(APPMAN_E_OVERFLOW); } memcpy((LPVOID) sTempSpaceRecord.wszDirectory, (LPVOID) lpData, dwCharCount*2); }
//
// Delete the temporary space
//
hResult = m_InformationManager.RemoveTempSpace(&sTempSpaceRecord); }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::EnumTemporarySpaces(const DWORD dwTargetIndex, LPDWORD lpdwSpace, const DWORD dwStringMask, LPVOID lpData, const DWORD dwDataLen) { FUNCTION("CAppEntry::EnumTemporarySpaces ()");
HRESULT hResult = S_OK; APPLICATION_DATA sApplicationData;
///////////////////////////////////////////////////////////////////////////////////////
try { TEMP_SPACE_RECORD sTempSpaceRecord; DWORD dwIndex, dwActualIndex; DWORD dwCharCount;
//
// Are the required properties set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_GUID, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
//
// Is the object a valid application object
//
memcpy((LPVOID) &sApplicationData, (LPVOID) &m_sApplicationData, sizeof(APPLICATION_DATA)); hResult = m_InformationManager.GetApplicationData(&sApplicationData); if (FAILED(hResult)) { THROW(APPMAN_E_UNKNOWNAPPLICATION); }
//
// Make sure the string mask is good
//
if ((APP_PROPERTY_STR_ANSI != dwStringMask)&&(APP_PROPERTY_STR_UNICODE != dwStringMask)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Check to make sure dwDataLen is greater than 0
//
if (0 == dwDataLen) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Make sure that the lpData parameter is valid
//
if (NULL == lpData) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadWritePtr(lpData, dwDataLen)) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Check to make sure lpdwSpace is valid
//
if (NULL == lpdwSpace) { THROW(APPMAN_E_INVALIDPARAMETERS); }
if (IsBadWritePtr(lpdwSpace, sizeof(DWORD))) { THROW(APPMAN_E_INVALIDPARAMETERS); }
//
// Get the nth temp space. Ignore temp spaces that are not owned by this application
//
dwActualIndex = dwTargetIndex; dwIndex = 0; do { hResult = m_InformationManager.EnumTempSpace(dwIndex, &sTempSpaceRecord); if (S_OK == hResult) { if (memcmp((LPVOID) &sTempSpaceRecord.sApplicationGuid, (LPVOID) &sApplicationData.sBaseInfo.sApplicationGuid, sizeof(GUID))) { dwActualIndex++; } } dwIndex++; } while ((dwIndex <= dwActualIndex)&&(S_OK == hResult));
//
// Did we find a target temp space
//
if (S_OK == hResult) { //
// Record the size
//
*lpdwSpace = sTempSpaceRecord.dwKilobytes;
//
// Record the string
//
dwCharCount = StrLenW(sTempSpaceRecord.wszDirectory); if (APP_PROPERTY_STR_ANSI == dwStringMask) { if (dwCharCount > dwDataLen) { THROW(APPMAN_E_OVERFLOW); } CWin32API::WideCharToMultiByte((LPCWSTR) sTempSpaceRecord.wszDirectory, MAX_PATH_CHARCOUNT, (LPSTR) lpData, dwDataLen); } else { if (dwDataLen < (dwCharCount*2)) { THROW(APPMAN_E_OVERFLOW); } memcpy((LPVOID) lpData, (LPVOID) sTempSpaceRecord.wszDirectory, dwCharCount*2); } } }
///////////////////////////////////////////////////////////////////////////////////////
catch(CAppManExceptionHandler * pException) { hResult = pException->GetResultCode(); delete pException; }
catch(...) { hResult = E_UNEXPECTED; }
///////////////////////////////////////////////////////////////////////////////////////
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::ComputeOriginalApplicationSpaceInfo(void) { FUNCTION("CAppEntry::ComputeOriginalApplicationSpaceInfo ()"); CWin32API Win32API;
//
// Make sure the root paths are set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SETUPROOTPATH, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
//
// How much space is currently take by the application
//
m_dwOriginalSetupRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH]); m_dwOriginalApplicationRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]);
return S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CApplicationEntry::ComputeApplicationSpaceInfo(const DWORD dwInstalledKilobytesExpected) { FUNCTION("CAppEntry::ComputeApplicationSpaceInfo ()");
HRESULT hResult = S_OK; DWORD dwSetupInstalledKilobytes, dwSetupUnInstalledKilobytes; DWORD dwApplicationInstalledKilobytes, dwApplicationUnInstalledKilobytes; DWORD dwInstalledKilobytes, dwUnInstalledKilobytes; DWORD dwSetupRootPathSizeKilobytes, dwApplicationRootPathSizeKilobytes; CWin32API Win32API;
//
// Make sure the root paths and estimated install kilobytes are set
//
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_SETUPROOTPATH, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_ROOTPATH, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_REMOVABLEKILOBYTES, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
if (S_OK != m_InformationManager.IsApplicationPropertyInitializedWithIndex(IDX_PROPERTY_NONREMOVABLEKILOBYTES, &m_sApplicationData)) { THROW(APPMAN_E_REQUIREDPROPERTIESMISSING); }
//
// What is the actual amount of kilobytes taken up by the application paths
//
dwSetupRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_SETUPROOTPATH]); dwApplicationRootPathSizeKilobytes = Win32API.GetDirectorySize(m_sApplicationData.wszStringProperty[APP_STRING_APPROOTPATH]);
//
// Did we add or remove kilobytes from the setup root path
//
if (dwSetupRootPathSizeKilobytes > m_dwOriginalSetupRootPathSizeKilobytes) { dwSetupInstalledKilobytes = dwSetupRootPathSizeKilobytes - m_dwOriginalSetupRootPathSizeKilobytes; dwSetupUnInstalledKilobytes = 0; } else { dwSetupInstalledKilobytes = 0; dwSetupUnInstalledKilobytes = m_dwOriginalSetupRootPathSizeKilobytes - dwSetupRootPathSizeKilobytes; }
//
// Did we add or remove kilobytes from the application root path
//
if (dwApplicationRootPathSizeKilobytes > m_dwOriginalApplicationRootPathSizeKilobytes) { dwApplicationInstalledKilobytes = dwApplicationRootPathSizeKilobytes - m_dwOriginalApplicationRootPathSizeKilobytes; dwApplicationUnInstalledKilobytes = 0; } else { dwApplicationInstalledKilobytes = 0; dwApplicationUnInstalledKilobytes = m_dwOriginalApplicationRootPathSizeKilobytes - dwApplicationRootPathSizeKilobytes; } //
// The total is
//
dwInstalledKilobytes = dwSetupInstalledKilobytes + dwApplicationInstalledKilobytes; dwUnInstalledKilobytes = dwSetupUnInstalledKilobytes + dwApplicationUnInstalledKilobytes;
//
// Did we use up more kilobytes than expected
//
if (dwInstalledKilobytes > dwUnInstalledKilobytes) { if ((dwInstalledKilobytes - dwUnInstalledKilobytes) > dwInstalledKilobytesExpected) { DWORD dwExtraKilobytes;
//
// How many extra kilobytes were used up by the installation
//
dwExtraKilobytes = (dwInstalledKilobytes - dwUnInstalledKilobytes) - dwInstalledKilobytesExpected;
//
// Go get the space required to install the application on the device
//
hResult = m_InformationManager.FixCacheOverrun(&m_sApplicationData.sBaseInfo.sDeviceGuid, dwExtraKilobytes); if (FAILED(hResult)) { THROW(APPMAN_E_CACHEOVERRUN); } } }
//
// Update the removable and non-removable space and validate the properties
//
m_sApplicationData.sBaseInfo.dwRemovableKilobytes += dwApplicationInstalledKilobytes; if (m_sApplicationData.sBaseInfo.dwRemovableKilobytes > dwApplicationUnInstalledKilobytes) { m_sApplicationData.sBaseInfo.dwRemovableKilobytes -= dwApplicationUnInstalledKilobytes; } else { m_sApplicationData.sBaseInfo.dwRemovableKilobytes = 0; }
m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes += dwSetupInstalledKilobytes; if (m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes > dwSetupUnInstalledKilobytes) { m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes -= dwSetupUnInstalledKilobytes; } else { m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes = 0; }
//
// Make sure dwRemovableKilobytes and dwNonRemovableKilobytes are not recursively adding
//
if (m_sApplicationData.sBaseInfo.dwRemovableKilobytes > dwApplicationRootPathSizeKilobytes) { m_sApplicationData.sBaseInfo.dwRemovableKilobytes = dwApplicationRootPathSizeKilobytes; }
if (m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes > dwSetupRootPathSizeKilobytes) { m_sApplicationData.sBaseInfo.dwNonRemovableKilobytes = dwSetupRootPathSizeKilobytes; }
VALIDATE_PROPERTY(IDX_PROPERTY_REMOVABLEKILOBYTES); VALIDATE_PROPERTY(IDX_PROPERTY_NONREMOVABLEKILOBYTES);
return hResult; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
LPAPPLICATION_DATA CApplicationEntry::GetApplicationDataPtr(void) { FUNCTION("CAppEntry::GetApplicationDataPtr()");
return &m_sApplicationData; }
|