diff options
Diffstat (limited to 'src/vm/hosting.cpp')
-rw-r--r-- | src/vm/hosting.cpp | 1027 |
1 files changed, 0 insertions, 1027 deletions
diff --git a/src/vm/hosting.cpp b/src/vm/hosting.cpp index 4dd6a59729..620b9d6800 100644 --- a/src/vm/hosting.cpp +++ b/src/vm/hosting.cpp @@ -14,10 +14,6 @@ #include "corhost.h" #include "threads.h" -#if defined(FEATURE_CLICKONCE) -#include "isolationpriv.h" -#include "shlwapi.h" -#endif #define countof(x) (sizeof(x) / sizeof(x[0])) @@ -197,15 +193,6 @@ BOOL GlobalAllocStore::m_Disabled = FALSE; #endif -#if defined(_DEBUG) && !defined(FEATURE_CORECLR) -// The helper thread can't call regular new / delete b/c of interop-debugging deadlocks. -// It must use the (InteropSafe) heap from debugger.h, you also can't allocate normally -// when we have any other thread hard-suspended. - -// Telesto doesn't support interop-debugging, so this won't be an issue. - -void AssertAllocationAllowed(); -#endif HANDLE g_ExecutableHeapHandle = NULL; @@ -225,9 +212,6 @@ LPVOID EEVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, D return NULL; #endif -#if defined(_DEBUG) && !defined(FEATURE_CORECLR) - AssertAllocationAllowed(); -#endif #ifdef _DEBUG if (g_fEEStarted) { @@ -236,44 +220,6 @@ LPVOID EEVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, D _ASSERTE (lpAddress || (dwSize % g_SystemInfo.dwAllocationGranularity) == 0); #endif -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager(); - if (pMM) { - LPVOID pMem; - EMemoryCriticalLevel eLevel = eTaskCritical; - if (!g_fEEStarted) - { - eLevel = eProcessCritical; - } - else - { - Thread *pThread = GetThread(); - if (pThread && pThread->HasLockInCurrentDomain()) - { - if (GetAppDomain()->IsDefaultDomain()) - { - eLevel = eProcessCritical; - } - else - { - eLevel = eAppDomainCritical; - } - } - } - HRESULT hr = S_OK; - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = pMM->VirtualAlloc (lpAddress, dwSize, flAllocationType, flProtect, eLevel, &pMem); - END_SO_TOLERANT_CODE_CALLING_HOST; - - if(hr != S_OK) - { - STRESS_LOG_OOM_STACK(dwSize); - } - - return (hr == S_OK) ? pMem : NULL; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { LPVOID p = NULL; @@ -337,19 +283,6 @@ BOOL EEVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) { BOOL retVal = FALSE; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager(); - if (pMM) { -#ifdef _DEBUG - GlobalAllocStore::ValidateFree(lpAddress); -#endif - - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - retVal = pMM->VirtualFree (lpAddress, dwSize, dwFreeType) == S_OK; - END_SO_TOLERANT_CODE_CALLING_HOST; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { #ifdef _DEBUG GlobalAllocStore::RemoveAlloc (lpAddress); @@ -373,20 +306,6 @@ SIZE_T EEVirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZ } CONTRACTL_END; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager(); - if (pMM) { - SIZE_T result; - HRESULT hr = S_OK; - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = pMM->VirtualQuery((void*)lpAddress, lpBuffer, dwLength, &result); - END_SO_TOLERANT_CODE_CALLING_HOST; - if (FAILED(hr)) - return 0; - return result; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { return ::VirtualQuery(lpAddress, lpBuffer, dwLength); } @@ -404,17 +323,6 @@ BOOL EEVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWOR } CONTRACTL_END; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager(); - if (pMM) { - BOOL result = FALSE; - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - result = pMM->VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect) == S_OK; - END_SO_TOLERANT_CODE_CALLING_HOST; - return result; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { return ::VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect); } @@ -429,13 +337,6 @@ HANDLE EEGetProcessHeap() STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_SO_TOLERANT; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager(); - if (pMM) { - return (HANDLE)1; // pretending we return an handle is ok because handles are ignored by the hosting api - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { return GetProcessHeap(); } @@ -455,14 +356,6 @@ HANDLE EEHeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize) #ifndef FEATURE_PAL -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMalloc *pHM = CorHost2::GetHostMalloc(); - if (pHM) - { - return NULL; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { return ::HeapCreate(flOptions, dwInitialSize, dwMaximumSize); } @@ -485,14 +378,6 @@ BOOL EEHeapDestroy(HANDLE hHeap) #ifndef FEATURE_PAL -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMalloc *pHM = CorHost2::GetHostMalloc(); - if (pHM) - { - return TRUE; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { return ::HeapDestroy(hHeap); } @@ -510,54 +395,6 @@ BOOL EEHeapDestroy(HANDLE hHeap) #endif #endif -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -LPVOID EEHeapAllocHosted(IHostMalloc * pHM, SIZE_T dwBytes) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_SO_INTOLERANT; - - Thread * pThread = GetThreadNULLOk(); - EMemoryCriticalLevel eLevel = eTaskCritical; - if (!g_fEEStarted) - { - eLevel = eProcessCritical; - } - else - { - if (pThread && pThread->HasLockInCurrentDomain()) - { - if (GetAppDomain()->IsDefaultDomain()) - { - eLevel = eProcessCritical; - } - else - { - eLevel = eAppDomainCritical; - } - } - } - LPVOID pMem = NULL; - HRESULT hr = S_OK; - { - CantAllocHolder caHolder; - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(pThread); - hr = pHM->Alloc(dwBytes, eLevel, &pMem); - END_SO_TOLERANT_CODE_CALLING_HOST; - } - - if(hr != S_OK - //under OOM, we might not be able to get Execution Engine and can't access stress log - && GetExecutionEngine () - // If we have not created StressLog ring buffer, we should not try to use it. - // StressLog is going to do a memory allocation. We may enter an endless loop. - && ClrFlsGetValue(TlsIdx_StressLog) != NULL ) - { - STRESS_LOG_OOM_STACK(dwBytes); - } - - return (hr == S_OK) ? pMem : NULL; -} -#endif // FEATURE_INCLUDE_ALL_INTERFACES #undef HeapAlloc LPVOID EEHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) @@ -570,20 +407,7 @@ LPVOID EEHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) return NULL; #endif -#if defined(_DEBUG) && !defined(FEATURE_CORECLR) - AssertAllocationAllowed(); -#endif -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMalloc *pHM = CorHost2::GetHostMalloc(); - - // TODO: implement hosted executable heap - if (pHM && hHeap != g_ExecutableHeapHandle) - { - return EEHeapAllocHosted(pHM, dwBytes); - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { LPVOID p = NULL; @@ -644,30 +468,9 @@ BOOL EEHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) // @todo - Need a backout validation here. CONTRACT_VIOLATION(SOToleranceViolation); -#if defined(_DEBUG) && !defined(FEATURE_CORECLR) - AssertAllocationAllowed(); -#endif BOOL retVal = FALSE; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMalloc *pHM = CorHost2::GetHostMalloc(); - - // TODO: implement hosted executable heap - if (pHM && hHeap != g_ExecutableHeapHandle) - { - if (lpMem == NULL) { - retVal = TRUE; - } -#ifdef _DEBUG - GlobalAllocStore::ValidateFree(lpMem); -#endif - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - retVal = pHM->Free(lpMem) == S_OK; - END_SO_TOLERANT_CODE_CALLING_HOST; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { #ifdef _DEBUG GlobalAllocStore::RemoveAlloc (lpMem); @@ -723,14 +526,6 @@ BOOL EEHeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) { #ifndef FEATURE_PAL -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostMalloc *pHM = CorHost2::GetHostMalloc(); - if (pHM) - { - return TRUE; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { return ::HeapValidate(hHeap, dwFlags, lpMem); } @@ -745,7 +540,6 @@ HANDLE EEGetProcessExecutableHeap() { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; -#ifdef FEATURE_CORECLR #ifndef FEATURE_PAL @@ -780,18 +574,6 @@ HANDLE EEGetProcessExecutableHeap() { UNREACHABLE(); #endif // !FEATURE_PAL -#else // FEATURE_CORECLR - - // - // Use process executable heap created by the shim - // - if (g_ExecutableHeapHandle == NULL) - { - extern HANDLE GetProcessExecutableHeap(); - g_ExecutableHeapHandle = GetProcessExecutableHeap(); - } - -#endif // FEATURE_CORECLR // TODO: implement hosted executable heap return g_ExecutableHeapHandle; @@ -813,42 +595,6 @@ DWORD EESleepEx(DWORD dwMilliseconds, BOOL bAlertable) DWORD res; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostTaskManager *provider = CorHost2::GetHostTaskManager(); - if ((provider != NULL)){ - DWORD option = 0; - if (bAlertable) - { - option = WAIT_ALERTABLE; - } - - - HRESULT hr; - - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = provider->Sleep(dwMilliseconds, option); - END_SO_TOLERANT_CODE_CALLING_HOST; - - if (hr == S_OK) { - res = WAIT_OBJECT_0; - } - else if (hr == HOST_E_INTERRUPTED) { - _ASSERTE(bAlertable); - Thread *pThread = GetThread(); - if (pThread) - { - pThread->UserInterruptAPC(APC_Code); - } - res = WAIT_IO_COMPLETION; - } - else - { - _ASSERTE (!"Unknown return from host Sleep\n"); - res = WAIT_OBJECT_0; - } - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { res = ::SleepEx(dwMilliseconds, bAlertable); } @@ -889,15 +635,6 @@ BOOL __DangerousSwitchToThread (DWORD dwSleepMSec, DWORD dwSwitchCount, BOOL goT } CONTRACTL_END; - if (CLRTaskHosted()) - { - Thread *pThread = GetThread(); - if (pThread && pThread->HasThreadState(Thread::TS_YieldRequested)) - { - pThread->ResetThreadState(Thread::TS_YieldRequested); - } - } - if (dwSleepMSec > 0) { // when called with goThroughOS make sure to not call into the host. This function @@ -940,22 +677,6 @@ BOOL __DangerousSwitchToThread (DWORD dwSleepMSec, DWORD dwSwitchCount, BOOL goT ClrSleepEx(1, FALSE); } -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostTaskManager *provider = CorHost2::GetHostTaskManager(); - if ((provider != NULL) && (goThroughOS == FALSE)) - { - DWORD option = 0; - - HRESULT hr; - - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = provider->SwitchToTask(option); - END_SO_TOLERANT_CODE_CALLING_HOST; - - return hr == S_OK; - } - else -#endif // FEATURE_INCLUDE_ALL_INTERFACES { return SwitchToThread(); } @@ -1155,751 +876,3 @@ BOOL EEAllocationDisallowed() #endif } -#ifdef FEATURE_CLICKONCE - -HRESULT GetApplicationManifest (LPCWSTR pwzAppFullName, - DWORD dwManifestPaths, - LPCWSTR *ppwzManifestPaths, - __out_z __deref_out_opt LPWSTR *ppwzApplicationFolderPath, - __out_z __deref_out_opt LPWSTR *ppszKeyForm, - ICMS **ppApplicationManifest) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pwzAppFullName)); - PRECONDITION(CheckPointer(ppwzManifestPaths, NULL_OK)); - PRECONDITION(CheckPointer(ppApplicationManifest)); - } CONTRACTL_END; - - ReleaseHolder<IStore> pStore(NULL); - ReleaseHolder<IAppIdAuthority> pAppIdAuth(NULL); - ReleaseHolder<IDefinitionAppId> pDefinitionIdentity(NULL); - ReleaseHolder<IEnumDefinitionIdentity> pEnumDefinitionIdentity(NULL); - ReleaseHolder<IDefinitionIdentity> pDeploymentDefinitionIdentity(NULL); - ReleaseHolder<IDefinitionIdentity> pApplicationDefinitionIdentity(NULL); - ReleaseHolder<IDefinitionIdentity> pSubscriptionIdentity(NULL); - ReleaseHolder<IDefinitionAppId> pSubscriptionAppId(NULL); - - ReleaseHolder<IUnknown> TempFetched(NULL); - HRESULT hr = S_OK; - - // Maybe this is not an installed application. Grab the manifest path if specified and parse the manifest. - if (dwManifestPaths > 0) { - if (dwManifestPaths < 2) - goto ErrExit; - - hr = ParseManifest(ppwzManifestPaths[1], NULL, __uuidof(ICMS), &TempFetched); - if (TempFetched == NULL) - { - goto ErrExit; - } - - IfFailGo(TempFetched->QueryInterface(__uuidof(ICMS), (void**) ppApplicationManifest)); - TempFetched.Release(); - - // Set the application directory to be the location of the application manifest. - if (ppwzApplicationFolderPath) { - LPCWSTR pszSlash; - if (((pszSlash = wcsrchr(ppwzManifestPaths[1], W('\\'))) != NULL) || ((pszSlash = wcsrchr(ppwzManifestPaths[1], W('/'))) != NULL)) { - DWORD cchDirectory = (DWORD) (pszSlash - ppwzManifestPaths[1] + 1); - *ppwzApplicationFolderPath = (LPWSTR) CoTaskMemAlloc(2 * (cchDirectory + 1)); - - if (*ppwzApplicationFolderPath == NULL) - { - hr = E_OUTOFMEMORY; - goto ErrExit; - } - - memcpy(*ppwzApplicationFolderPath, ppwzManifestPaths[1], 2 * cchDirectory); - (*ppwzApplicationFolderPath)[cchDirectory] = W('\0'); - } - } - goto ErrExit; - } - - // Get the user store. - IfFailGo(GetUserStore(0, NULL, __uuidof(IStore), &pStore)); - - // Get the AppId authority - IfFailGo(GetAppIdAuthority(&pAppIdAuth)); - - // Get the IDefintionIdentity of the application full name passed in as an argument. - IfFailGo(pAppIdAuth->TextToDefinition(0, pwzAppFullName, &pDefinitionIdentity)); - - // Get the ICMS object representing the application manifest. - IfFailGo(pDefinitionIdentity->EnumAppPath(&pEnumDefinitionIdentity)); - IfFailGo(pEnumDefinitionIdentity->Reset()); - ULONG numItems = 0; - IfFailGo(pEnumDefinitionIdentity->Next(1, &pDeploymentDefinitionIdentity, &numItems)); - if (numItems < 1) { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - goto ErrExit; - } - IfFailGo(pEnumDefinitionIdentity->Next(1, &pApplicationDefinitionIdentity, &numItems)); - if (numItems < 1) { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - goto ErrExit; - } - - if (ppszKeyForm){ - // Create subscription identity from deployment identity. - IfFailGo(pDeploymentDefinitionIdentity->Clone(0,NULL,&pSubscriptionIdentity)); - IfFailGo(pSubscriptionIdentity->SetAttribute(NULL,W("version"),NULL)); - - // Create the subscription app id. - IfFailGo(pAppIdAuth->CreateDefinition(&pSubscriptionAppId)); - - IDefinitionIdentity *defIdentityArray[1]; - defIdentityArray[0] = pSubscriptionIdentity; - - IfFailGo(pSubscriptionAppId->SetAppPath(1,defIdentityArray)); - IfFailGo(pAppIdAuth->GenerateDefinitionKey(0,pSubscriptionAppId,ppszKeyForm)); - } - - hr = pStore->GetAssemblyInformation(0, pApplicationDefinitionIdentity, __uuidof(ICMS), &TempFetched); - if (SUCCEEDED(hr)) { - if (ppwzApplicationFolderPath) { - // Get the application folder path. - LPVOID cookie = NULL; - IfFailGo(pStore->LockApplicationPath(0, pDefinitionIdentity, &cookie, ppwzApplicationFolderPath)); - IfFailGo(pStore->ReleaseApplicationPath(cookie)); - } - } - IfFailGo(TempFetched->QueryInterface(__uuidof(ICMS), (void**) ppApplicationManifest)); - TempFetched.Release(); - -ErrExit: - pStore.Release(); - pAppIdAuth.Release(); - pDefinitionIdentity.Release(); - pEnumDefinitionIdentity.Release(); - pDeploymentDefinitionIdentity.Release(); - pApplicationDefinitionIdentity.Release(); - pSubscriptionIdentity.Release(); - pSubscriptionAppId.Release(); - - return hr; -} - -BOOL DoesMarkOfTheWebExist (LPCWSTR pwzAppFullName) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pwzAppFullName)); - } CONTRACTL_END; - - HANDLE alternateStreamHandle = INVALID_HANDLE_VALUE; - - StackSString alternateStreamPath(pwzAppFullName); - alternateStreamPath.Append(W(":Zone.Identifier")); - - // Try to open alternate file stream - alternateStreamHandle = WszCreateFile( - alternateStreamPath.GetUnicode(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - 0, - NULL); - - if (INVALID_HANDLE_VALUE != alternateStreamHandle) - { - CloseHandle(alternateStreamHandle); - - // We only check if MOTW (alternate stream) is present, - // no matter what the zone is. - return TRUE; - } - - return FALSE; -} - -HRESULT GetApplicationEntryPointInfo (LPCWSTR pwzAppFullName, - DWORD dwManifestPaths, - LPCWSTR *ppwzManifestPaths, - __out_z __deref_out_opt LPWSTR *ppwzApplicationFolderPath, - LPCWSTR *ppwzCodeBase, - LPCWSTR *ppwzParameters, - __out_z __deref_out_opt LPWSTR *ppwzProcessorArch, - __out_z __deref_out_opt LPWSTR *ppwzAppIdKeyForm) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pwzAppFullName)); - PRECONDITION(CheckPointer(ppwzManifestPaths, NULL_OK)); - PRECONDITION(CheckPointer(ppwzCodeBase, NULL_OK)); - PRECONDITION(CheckPointer(ppwzParameters, NULL_OK)); - PRECONDITION(CheckPointer(ppwzProcessorArch, NULL_OK)); - } CONTRACTL_END; - - ReleaseHolder<ICMS> pApplicationManifest(NULL); - ReleaseHolder<ISection> pEntrySection(NULL); - ReleaseHolder<IEnumUnknown> pEntryEnum(NULL); - ReleaseHolder<IEntryPointEntry> pEntry(NULL); - ReleaseHolder<IReferenceIdentity> pReferenceId(NULL); - ReleaseHolder<ISectionWithStringKey> pNamedRefSection(NULL); - ReleaseHolder<ISectionWithReferenceIdentityKey> pRefSection(NULL); - ReleaseHolder<IAssemblyReferenceEntry> pRefEntry(NULL); - ReleaseHolder<IAssemblyReferenceDependentAssemblyEntry> pDependentAssemblyEntry(NULL); - CoTaskMemHolder<WCHAR> pwszDependencyName = NULL; - - ReleaseHolder<IUnknown> TempFetched(NULL); - ReleaseHolder<ISection> TempFetchedSection(NULL); - HRESULT hr = S_OK; - - // Get the ICMS object representing the application manifest. - IfFailGo(GetApplicationManifest(pwzAppFullName, dwManifestPaths, ppwzManifestPaths, ppwzApplicationFolderPath, ppwzAppIdKeyForm,&pApplicationManifest)); - - // Get the app entry point section. - IfFailGo(pApplicationManifest->get_EntryPointSection(&pEntrySection)); - if (pEntrySection == NULL) { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - goto ErrExit; - } - - // Get the entry point enum. - IfFailGo(pEntrySection->get__NewEnum(&TempFetched)); - IfFailGo(TempFetched->QueryInterface(__uuidof(IEnumUnknown), &pEntryEnum)); - TempFetched.Release(); - - // Get the first entry point. - ULONG numItems = 0; - IfFailGo(pEntryEnum->Next(1, &TempFetched, &numItems)); - if (numItems < 1) { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - goto ErrExit; - } - IfFailGo(TempFetched->QueryInterface(__uuidof(IEntryPointEntry), &pEntry)); - TempFetched.Release(); - - // We support both name and identity based entry points. - IfFailGo(pEntry->get_Identity(&pReferenceId)); - if (pReferenceId == NULL) { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - goto ErrExit; - } - - // Get the assembly reference section. - IfFailGo(pApplicationManifest->get_AssemblyReferenceSection(&TempFetchedSection)); - IfFailGo(TempFetchedSection->QueryInterface(__uuidof(ISectionWithReferenceIdentityKey), &pRefSection)); - TempFetchedSection.Release(); - -#ifdef CLICKONCE_LONGHORN_RELATED - // - // If a reference assembly matching entry point does not exist, use the codebase - // of command line file. - // - if (FAILED(pRefSection->Lookup(pReferenceId, &TempFetched))) - { - if (ppwzCodeBase) { - IfFailGo(pEntry->get_CommandLine_File(ppwzCodeBase)); - } - } - else -#endif - { - // Lookup the assembly reference entry. - IfFailGo(pRefSection->Lookup(pReferenceId, &TempFetched)); - IfFailGo(TempFetched->QueryInterface(__uuidof(IAssemblyReferenceEntry), &pRefEntry)); - TempFetched.Release(); - - // Get the assembly codebase. Codebase may either come from <dependentAssembly> or <installFrom>. - // In a valid reference there should always be a <dependentAssembly> section. - IfFailGo(pRefEntry->get_DependentAssembly(&pDependentAssemblyEntry)); - - if (ppwzCodeBase) { - IfFailGo(pDependentAssemblyEntry->get_Codebase(ppwzCodeBase)); - } - } - - // Get the parameters - if (ppwzParameters) - IfFailGo(pEntry->get_CommandLine_Parameters(ppwzParameters)); - - // Get the processor architecture requested in the app manifest - if (ppwzProcessorArch) - IfFailGo(pReferenceId->GetAttribute(NULL, W("processorArchitecture"), ppwzProcessorArch)); - -ErrExit: - pApplicationManifest.Release(); - pEntrySection.Release(); - pEntryEnum.Release(); - pEntry.Release(); - pReferenceId.Release(); - pNamedRefSection.Release(); - pRefSection.Release(); - pRefEntry.Release(); - pDependentAssemblyEntry.Release(); - pwszDependencyName.Release(); - - return hr; -} - -// -// Export used in the ClickOnce installer for launching manifest-based applications. -// - -typedef struct _tagNameMap { - LPWSTR pwszProcessorArch; - DWORD dwRuntimeInfoFlag; -} NAME_MAP; - -DWORD g_DfSvcSpinLock = 0; -void EnterDfSvcSpinLock () { - WRAPPER_NO_CONTRACT; - while (1) { - if (InterlockedExchange ((LPLONG)&g_DfSvcSpinLock, 1) == 1) - ClrSleepEx (5, FALSE); - else - return; - } -} - -void LeaveDfSvcSpinLock () { - InterlockedExchange ((LPLONG)&g_DfSvcSpinLock, 0); -} - -// -// ThreadProc used by SHCreateProcess call - to activate ClickOnce app with ShellExecuteEx -// ShellExecuteEx can only be used from STA threads - we are creating our own STA thread -// -DWORD CorLaunchApplication_ThreadProc(void*) -{ - return 0; -} - -// -// This callback is executed as the sync-callback on SHCreateThread. -// SHCreateThread does not return till this callback returns. -// -DWORD CorLaunchApplication_Callback(void* pv) -{ - SHELLEXECUTEINFO *pSei = static_cast<SHELLEXECUTEINFO *>(pv); - IUnknown* pDummyUnknown; - CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*) &pDummyUnknown); - - if (RunningOnWin8()) - { - // When SEE_MASK_FLAG_HINST_IS_SITE is specified SHELLEXECUTEINFO.hInstApp is used as an - // _In_ parameter and specifies a IUnknown* to be used as a site pointer. The site pointer - // is used to provide services to shell execute, the handler binding process and the verb handlers - // once they are invoked. - // - // SEE_MASK_HINST_IS_SITE is available on Win8+ - // Defining it locally in Win8-conditioned code - // - const ULONG SEE_MASK_HINST_IS_SITE = 0x08000000; - - pSei->fMask = SEE_MASK_HINST_IS_SITE; - pSei->hInstApp = reinterpret_cast<HINSTANCE>(pDummyUnknown); - } - - WszShellExecuteEx(pSei); - // We ignore all errors from ShellExecute. - // - // This may change with Win8:783168 - - if (pDummyUnknown) - { - pDummyUnknown->Release(); - } - - return 0; -} - -//----------------------------------------------------------------------------- -// WszSHCreateThread -// -// @func calls SHCreateThread with the provided parameters -// -// @rdesc Result -//----------------------------------------------------------------------------------- -HRESULT WszSHCreateThread( - LPTHREAD_START_ROUTINE pfnThreadProc, - void *pData, - SHCT_FLAGS dwFlags, - LPTHREAD_START_ROUTINE pfnCallback -) -{ - CONTRACTL - { - NOTHROW; - MODE_PREEMPTIVE; - INJECT_FAULT(return E_OUTOFMEMORY;); - } - CONTRACTL_END; - - HRESULT hr = S_OK; - HMODULE _hmodShlwapi = 0; - - typedef BOOL (*PFNSHCREATETHREAD) ( - __in LPTHREAD_START_ROUTINE pfnThreadProc, - __in_opt void *pData, - __in SHCT_FLAGS dwFlags, - __in_opt LPTHREAD_START_ROUTINE pfnCallback - ); - - static PFNSHCREATETHREAD pfnW = NULL; - if (NULL == pfnW) - { - _hmodShlwapi = CLRLoadLibrary(W("shlwapi.dll")); - - if (_hmodShlwapi) - { - pfnW = (PFNSHCREATETHREAD)GetProcAddress(_hmodShlwapi, "SHCreateThread"); - } - } - - if (pfnW) - { - BOOL bRet = pfnW(pfnThreadProc, pData, dwFlags, pfnCallback); - - if (!bRet) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - } - } - else - { - hr = HRESULT_FROM_WIN32(GetLastError()); - } - - // NOTE: We leak the module handles and let the OS gather them at process shutdown. - - return hr; -} - -STDAPI CorLaunchApplication (HOST_TYPE dwClickOnceHost, - LPCWSTR pwzAppFullName, - DWORD dwManifestPaths, - LPCWSTR *ppwzManifestPaths, - DWORD dwActivationData, - LPCWSTR *ppwzActivationData, - LPPROCESS_INFORMATION lpProcessInformation) -{ - // HostType is encoded in the lowest 2 bits. - unsigned hostType = dwClickOnceHost & MASK_HOSTTYPE; - - // NoPinnableBit is the highest bit. - unsigned notPinnableBit = dwClickOnceHost & MASK_NOTPINNABLE; - - // DontShowInstallDialog bit - unsigned dontShowInstallDialog = dwClickOnceHost & MASK_DONT_SHOW_INSTALL_DIALOG; - - bool bUseShellExecute = false; - - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - PRECONDITION(CheckPointer(pwzAppFullName, NULL_OK)); - PRECONDITION(CheckPointer(ppwzManifestPaths, NULL_OK)); - PRECONDITION(CheckPointer(ppwzActivationData, NULL_OK)); - PRECONDITION(hostType == HOST_TYPE_DEFAULT || hostType == HOST_TYPE_APPLAUNCH || hostType == HOST_TYPE_CORFLAG); - PRECONDITION(CheckPointer(lpProcessInformation)); - } CONTRACTL_END; - - - if (pwzAppFullName == NULL) - return E_POINTER; - - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - - LPVOID lpEnvironment = NULL; - EX_TRY - { - StackSString commandLine(StackSString::Ascii, "\""); // put quotes around path to the command line. - StackSString appEntryPath(W("")); // the path to the entry point(the exe to run) of the application, initialized to empty string - NewArrayHolder<WCHAR> wszDirectory(NULL); - NewArrayHolder<WCHAR> wszVersion(NULL); - CoTaskMemHolder<WCHAR> pwszApplicationFolderPath(NULL); - CoTaskMemHolder<WCHAR> pwszAppIdKeyForm(NULL); - CoTaskMemHolder<WCHAR> pwszCodebase(NULL); - CoTaskMemHolder<WCHAR> pwszParameters(NULL); - CoTaskMemHolder<WCHAR> pwszProcessorArch(NULL); - - hr = GetApplicationEntryPointInfo(pwzAppFullName, dwManifestPaths, ppwzManifestPaths, (LPWSTR*) (void*) &pwszApplicationFolderPath, (LPCWSTR*) (void*) &pwszCodebase, (LPCWSTR*) (void*) &pwszParameters, (LPWSTR*) (void*) &pwszProcessorArch,(LPWSTR*) (void*) &pwszAppIdKeyForm); - - if (SUCCEEDED(hr)) { - // construct the application Entry Path - if (pwszApplicationFolderPath != NULL) { - appEntryPath.Append(pwszApplicationFolderPath); - SString::CIterator i = appEntryPath.End()-1; - if (i[0] != '\\') - appEntryPath.Append(W("\\")); - } - appEntryPath.Append(pwszCodebase); - - if (hostType == HOST_TYPE_CORFLAG) { - // construct the command line - commandLine.Append(appEntryPath); - commandLine.Append(W("\"")); - - if (RunningOnWin8() && - DoesMarkOfTheWebExist(appEntryPath.GetUnicode())) - { - // We will use ShellExecute for any zone set in MOTW stream. - // ShellExecute would call Application Reputation API if the zone is the one - // that requires AppRep validation. At the moment, they would do this for Internet Zone only, - // but there are talks about changing the behavior to include some of the other zones. - // By not checking the zone here we leave to AppRep/ShellExecute to decide, - // which is exactly what we want. - bUseShellExecute = true; - } - else - { - if (pwszParameters != NULL) { - commandLine.Append(W(" ")); - commandLine.Append(pwszParameters); - } - } - - // now construct the environment variables - EnterDfSvcSpinLock(); - WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, pwzAppFullName); - - if (dwManifestPaths > 0 && ppwzManifestPaths) { - for (DWORD i=0; i<dwManifestPaths; i++) { - StackSString manifestFile(g_pwzClickOnceEnv_Manifest); - StackSString buf; - COUNT_T size = buf.GetUnicodeAllocation(); - _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10); - buf.CloseBuffer(); - manifestFile.Append(buf); - WszSetEnvironmentVariable(manifestFile.GetUnicode(), *ppwzManifestPaths++); - } - } - - if (dwActivationData > 0 && ppwzActivationData) { - for (DWORD i=0; i<dwActivationData; i++) { - StackSString activationData(g_pwzClickOnceEnv_Parameter); - StackSString buf; - COUNT_T size = buf.GetUnicodeAllocation(); - _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10); - buf.CloseBuffer(); - activationData.Append(buf); - WszSetEnvironmentVariable(activationData.GetUnicode(), *ppwzActivationData++); - } - } - -#undef GetEnvironmentStrings -#undef GetEnvironmentStringsW - lpEnvironment = (LPVOID) GetEnvironmentStringsW(); -#define GetEnvironmentStringsW() Use_WszGetEnvironmentStrings() -#define GetEnvironmentStrings() Use_WszGetEnvironmentStrings() - } else { - // application folder is required to determine appEntryPath for framework version selection, - // but should not be used as working directory for partial trust apps - pwszApplicationFolderPath.Clear(); - - // find the architecture from manifest and required version from the application itself - static const NAME_MAP g_NameMapArray[] = { - {W("x86"), RUNTIME_INFO_REQUEST_X86}, - {W("ia64"), RUNTIME_INFO_REQUEST_IA64}, - {W("amd64"), RUNTIME_INFO_REQUEST_AMD64}, - }; - - DWORD dwRuntimeInfoFlags = RUNTIME_INFO_UPGRADE_VERSION | - RUNTIME_INFO_CONSIDER_POST_2_0 | - RUNTIME_INFO_EMULATE_EXE_LAUNCH; - - // We want to control whether shim should show install dialog or not, - // and not leave this decision to the Shim. - if (dontShowInstallDialog > 0) - { - dwRuntimeInfoFlags |= RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG; - } - else - { - // show even if SEM_CRITICAL is set - dwRuntimeInfoFlags |= METAHOST_POLICY_IGNORE_ERROR_MODE; - } - - if (pwszProcessorArch) { - for (DWORD index = 0; index < sizeof(g_NameMapArray) / sizeof(NAME_MAP); index++) { - if (SString::_wcsicmp(g_NameMapArray[index].pwszProcessorArch, pwszProcessorArch) == 0) { - dwRuntimeInfoFlags |= g_NameMapArray[index].dwRuntimeInfoFlag; - break; - } - } - } - wszDirectory = new WCHAR[MAX_LONGPATH + 1]; - wszVersion = new WCHAR[MAX_PATH_FNAME + 1]; - wszVersion[0] = 0; // we don't prefer any version - DWORD cchBuffer = MAX_LONGPATH; - - // Use GetRequestedRuntimeInfo because MetaHost APIs do not yet support architecture arguments. - // Calls to GetRequestedRuntimeInfo() will goes to a local copy inside clr.dll, - // have to call mscoree::GetRequestedRuntimeInfo. - typedef HRESULT (*PFNGetRequestedRuntimeInfo)(LPCWSTR pExe, - LPCWSTR pwszVersion, - LPCWSTR pConfigurationFile, - DWORD startupFlags, - DWORD runtimeInfoFlags, - LPWSTR pDirectory, - DWORD dwDirectory, - DWORD *dwDirectoryLength, - LPWSTR pVersion, - DWORD cchBuffer, - DWORD* dwlength); - PFNGetRequestedRuntimeInfo pfnGetRequestedRuntimeInfo = NULL; - HMODULE hMscoree = GetModuleHandleW( W("mscoree.dll") ); // mscoree.dll should have already been loaded - if( hMscoree != NULL ) - pfnGetRequestedRuntimeInfo = (PFNGetRequestedRuntimeInfo)GetProcAddress( hMscoree, "GetRequestedRuntimeInfo" ); - if( pfnGetRequestedRuntimeInfo == NULL ) - pfnGetRequestedRuntimeInfo = GetRequestedRuntimeInfoInternal; // in case mscoree has not been loaded, use the built in function - hr = pfnGetRequestedRuntimeInfo(appEntryPath.GetUnicode(), // Use the image path to guide all version binding - NULL, // Do not prime with any preferred version - NULL, // No explicit config file - pick up on one next to image if there. - 0, // startupFlags - dwRuntimeInfoFlags, // Will bind to post-v2 runtimes if EXE PE runtime version is post-v2 - // or EXE has config file binding to post-v2 runtime. - wszDirectory, MAX_LONGPATH, NULL, // Retrieve bound directory - wszVersion, MAX_PATH_FNAME, NULL); // Retrieve bound version - - if (SUCCEEDED(hr)) { - commandLine.Append(wszDirectory); - commandLine.Append(wszVersion); - commandLine.Append(W("\\applaunch.exe")); - commandLine.Append(W("\" /activate \"")); - commandLine.Append(pwzAppFullName); - commandLine.Append(W("\" ")); - - if (dwManifestPaths > 0 && ppwzManifestPaths) { - commandLine.Append(W("/manifests ")); - for (DWORD i=0; i<dwManifestPaths; i++) { - commandLine.Append(W("\"")); - commandLine.Append(*ppwzManifestPaths++); - commandLine.Append(W("\" ")); - } - } - - if (dwActivationData > 0 && ppwzActivationData) { - commandLine.Append(W("/parameters ")); - for (DWORD i=0; i<dwActivationData; i++) { - commandLine.Append(W("\"")); - commandLine.Append(*ppwzActivationData++); - commandLine.Append(W("\" ")); - } - } - } - } - } - - if (SUCCEEDED(hr)) { - // CreateProcess won't let this parameter be const - // (it writes a NULL in the middle), so we create a writable version - LPCWSTR wszCommandLineNonWritable = commandLine.GetUnicode(); - size_t len = wcslen(wszCommandLineNonWritable); - NewArrayHolder<WCHAR> wszCommandLine(new WCHAR[len + 1]); - memcpy(wszCommandLine, wszCommandLineNonWritable, len * sizeof(WCHAR)); - wszCommandLine[len] = W('\0'); - - STARTUPINFO sui; - memset(&sui, 0, sizeof(STARTUPINFO)); - sui.cb = sizeof(STARTUPINFO); - sui.lpTitle = pwszAppIdKeyForm; - sui.dwFlags = STARTF_TITLEISAPPID; - - if (notPinnableBit>0) - sui.dwFlags |= STARTF_PREVENTPINNING; - - // ClickOnce uses ShellExecute to utilize Win8+ Application Reputation service. - // Application Reputation validates applications coming from the Internet. - // ClickOnce will use ShellExecute only if there is a Mark-of-the-Web file-stream for the executable. - // In all other cases we continue to use CreateProcess. CreateProcess does not use AppRep service. - if (bUseShellExecute) - { - SHELLEXECUTEINFO sei; - memset(&sei, 0, sizeof(SHELLEXECUTEINFO)); - sei.cbSize = sizeof(SHELLEXECUTEINFO); - sei.hwnd = NULL; - sei.lpVerb = NULL; - sei.lpFile = wszCommandLine; - sei.lpParameters = pwszParameters; - sei.lpDirectory = pwszApplicationFolderPath; - sei.nShow = SW_SHOWDEFAULT; - sei.hInstApp = NULL; - - // Application Reputation is a COM Shell Extension that requires a calling thread to be an STA - // CorLaunchApplication_Callback calls ShellExecuteEx. - hr = WszSHCreateThread((LPTHREAD_START_ROUTINE) CorLaunchApplication_ThreadProc, &sei, CTF_COINIT_STA, - (LPTHREAD_START_ROUTINE) CorLaunchApplication_Callback); - } - else - { - // Launch the child process - BOOL result = WszCreateProcess(NULL, - wszCommandLine, - NULL, NULL, FALSE, - (lpEnvironment) ? NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_DEFAULT_ERROR_MODE : NORMAL_PRIORITY_CLASS | CREATE_DEFAULT_ERROR_MODE, - lpEnvironment, pwszApplicationFolderPath, - &sui, lpProcessInformation); - if (!result) - hr = HRESULT_FROM_GetLastError(); - } - } - } - EX_CATCH_HRESULT(hr); - - // cleanup - if (hostType == HOST_TYPE_CORFLAG) { - // free the environment block -#undef FreeEnvironmentStringsA -#undef FreeEnvironmentStringsW - if (NULL != lpEnvironment) { - FreeEnvironmentStringsW((LPWSTR) lpEnvironment); - } -#define FreeEnvironmentStringsW(lpEnvironment) Use_WszFreeEnvironmentStrings(lpEnvironment) -#define FreeEnvironmentStringsA(lpEnvironment) Use_WszFreeEnvironmentStrings(lpEnvironment) - // reset the environment variables - WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, NULL); - EX_TRY - { - if (dwManifestPaths > 0 && ppwzManifestPaths) { - for (DWORD i=0; i<dwManifestPaths; i++) { - StackSString manifestFile(g_pwzClickOnceEnv_Manifest); - StackSString buf; - COUNT_T size = buf.GetUnicodeAllocation(); - _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10); - buf.CloseBuffer(); - manifestFile.Append(buf); - WszSetEnvironmentVariable(manifestFile.GetUnicode(), NULL); - } - } - if (dwActivationData > 0 && ppwzActivationData) { - for (DWORD i=0; i<dwActivationData; i++) { - StackSString activationData(g_pwzClickOnceEnv_Parameter); - StackSString buf; - COUNT_T size = buf.GetUnicodeAllocation(); - _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10); - buf.CloseBuffer(); - activationData.Append(buf); - WszSetEnvironmentVariable(activationData.GetUnicode(), NULL); - } - } - } - EX_CATCH_HRESULT(hr); - // leave the spin lock so other requests can be served. - LeaveDfSvcSpinLock(); - } - - END_ENTRYPOINT_NOTHROW; - - return hr; -} -#endif // FEATURE_CLICKONCE |