////////////////////////////////////////////////////////////////////////////////////////////// // // 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 #include #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; }