From c3073a96d072daeccaa48549a50e4b88d9a9a4f4 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 31 Jul 2018 14:46:29 -0700 Subject: [PATCH] Delete FEATURE_IPCMAN (dotnet/coreclr#19212) Commit migrated from https://github.com/dotnet/coreclr/commit/d4f533b39db726cc61b0c8a5baab0f8c01c1fe7b --- src/coreclr/src/CMakeLists.txt | 4 - src/coreclr/src/debug/daccess/enummem.cpp | 21 - src/coreclr/src/debug/di/rspriv.h | 4 - src/coreclr/src/debug/ee/debugger.cpp | 8 - src/coreclr/src/debug/ee/debugger.h | 24 - src/coreclr/src/debug/ee/funceval.cpp | 1 - src/coreclr/src/debug/ee/rcthread.cpp | 52 +- src/coreclr/src/dlls/mscordbi/CMakeLists.txt | 1 - src/coreclr/src/inc/corhost.h | 35 - src/coreclr/src/inc/dacvars.h | 4 - src/coreclr/src/inc/ipcfunccall.h | 117 -- src/coreclr/src/inc/ipcmanagerinterface.h | 204 ---- src/coreclr/src/ipcman/CMakeLists.txt | 14 - src/coreclr/src/ipcman/ipcenums.h | 92 -- src/coreclr/src/ipcman/ipcfunccallimpl.cpp | 35 - src/coreclr/src/ipcman/ipcheader.h | 560 ---------- src/coreclr/src/ipcman/ipcheader.inl | 90 -- .../src/ipcman/ipcman-staticcrt/CMakeLists.txt | 3 - src/coreclr/src/ipcman/ipcmanagerimpl.h | 147 --- src/coreclr/src/ipcman/ipcmanagerimpl.inl | 192 ---- src/coreclr/src/ipcman/ipcreaderimpl.cpp | 1113 -------------------- src/coreclr/src/ipcman/ipcshared.h | 94 -- src/coreclr/src/ipcman/ipcsharedsrc.cpp | 890 ---------------- src/coreclr/src/ipcman/ipcwriterimpl.cpp | 861 --------------- src/coreclr/src/ipcman/stdafx.cpp | 10 - src/coreclr/src/ipcman/stdafx.h | 29 - src/coreclr/src/utilcode/dacutil.cpp | 3 - src/coreclr/src/utilcode/securityutil.cpp | 1 - src/coreclr/src/vm/ceemain.cpp | 216 ---- src/coreclr/src/vm/corhost.cpp | 330 ------ src/coreclr/src/vm/vars.cpp | 5 - src/coreclr/src/vm/vars.hpp | 7 - 32 files changed, 2 insertions(+), 5165 deletions(-) delete mode 100644 src/coreclr/src/inc/ipcfunccall.h delete mode 100644 src/coreclr/src/inc/ipcmanagerinterface.h delete mode 100644 src/coreclr/src/ipcman/CMakeLists.txt delete mode 100644 src/coreclr/src/ipcman/ipcenums.h delete mode 100644 src/coreclr/src/ipcman/ipcfunccallimpl.cpp delete mode 100644 src/coreclr/src/ipcman/ipcheader.h delete mode 100644 src/coreclr/src/ipcman/ipcheader.inl delete mode 100644 src/coreclr/src/ipcman/ipcman-staticcrt/CMakeLists.txt delete mode 100644 src/coreclr/src/ipcman/ipcmanagerimpl.h delete mode 100644 src/coreclr/src/ipcman/ipcmanagerimpl.inl delete mode 100644 src/coreclr/src/ipcman/ipcreaderimpl.cpp delete mode 100644 src/coreclr/src/ipcman/ipcshared.h delete mode 100644 src/coreclr/src/ipcman/ipcsharedsrc.cpp delete mode 100644 src/coreclr/src/ipcman/ipcwriterimpl.cpp delete mode 100644 src/coreclr/src/ipcman/stdafx.cpp delete mode 100644 src/coreclr/src/ipcman/stdafx.h diff --git a/src/coreclr/src/CMakeLists.txt b/src/coreclr/src/CMakeLists.txt index 0412226..51ce71e 100644 --- a/src/coreclr/src/CMakeLists.txt +++ b/src/coreclr/src/CMakeLists.txt @@ -83,10 +83,6 @@ add_subdirectory(unwinder) add_subdirectory(ildasm) add_subdirectory(ilasm) -if(WIN32) - add_subdirectory(ipcman) -endif(WIN32) - if(CLR_CMAKE_PLATFORM_UNIX) add_subdirectory(palrt) endif(CLR_CMAKE_PLATFORM_UNIX) diff --git a/src/coreclr/src/debug/daccess/enummem.cpp b/src/coreclr/src/debug/daccess/enummem.cpp index 50bf408..2cb6690 100644 --- a/src/coreclr/src/debug/daccess/enummem.cpp +++ b/src/coreclr/src/debug/daccess/enummem.cpp @@ -18,7 +18,6 @@ #include "typestring.h" #include "daccess.h" -#include "ipcmanagerinterface.h" #include "binder.h" #include "win32threadpool.h" @@ -172,26 +171,6 @@ HRESULT ClrDataAccess::EnumMemCLRHeapCrticalStatic(IN CLRDataEnumMemoryFlags fla CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( EnumSvrGlobalMemoryRegions(flags); ); #endif -#ifdef FEATURE_IPCMAN - // - // Write Out IPC Blocks - // - EX_TRY - { - g_pIPCManagerInterface.EnumMem(); - if (g_pIPCManagerInterface.IsValid()) - { - // write out the instance - DacEnumHostDPtrMem(g_pIPCManagerInterface); - - // Then write out the public and private block - ReportMem(PTR_TO_TADDR(g_pIPCManagerInterface->GetBlockStart()), g_pIPCManagerInterface->GetBlockSize()); - ReportMem(PTR_TO_TADDR(g_pIPCManagerInterface->GetBlockTableStart()), g_pIPCManagerInterface->GetBlockTableSize()); - } - } - EX_CATCH_RETHROW_ONLY_COR_E_OPERATIONCANCELLED -#endif // FEATURE_IPCMAN - m_dumpStats.m_cbClrHeapStatics = m_cbMemoryReported - cbMemoryReported; return S_OK; diff --git a/src/coreclr/src/debug/di/rspriv.h b/src/coreclr/src/debug/di/rspriv.h index a9e525f..40d06df 100644 --- a/src/coreclr/src/debug/di/rspriv.h +++ b/src/coreclr/src/debug/di/rspriv.h @@ -35,10 +35,6 @@ #include #include -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) -#include -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - #include "common.h" #include "primitives.h" diff --git a/src/coreclr/src/debug/ee/debugger.cpp b/src/coreclr/src/debug/ee/debugger.cpp index a8d590e..aeb1702 100644 --- a/src/coreclr/src/debug/ee/debugger.cpp +++ b/src/coreclr/src/debug/ee/debugger.cpp @@ -12,7 +12,6 @@ #include "stdafx.h" #include "debugdebugger.h" -#include "ipcmanagerinterface.h" #include "../inc/common.h" #include "perflog.h" #include "eeconfig.h" // This is here even for retail & free builds... @@ -45,9 +44,6 @@ #include "threadsuspend.h" -class CCLRSecurityAttributeManager; -extern CCLRSecurityAttributeManager s_CLRSecurityAttributeManager; - #ifdef DEBUGGING_SUPPORTED @@ -2038,11 +2034,7 @@ HRESULT Debugger::Startup(void) InitializeHijackFunctionAddress(); // Also initialize the AppDomainEnumerationIPCBlock - #if !defined(FEATURE_IPCMAN) || defined(FEATURE_DBGIPC_TRANSPORT_VM) m_pAppDomainCB = new (nothrow) AppDomainEnumerationIPCBlock(); - #else - m_pAppDomainCB = g_pIPCManagerInterface->GetAppDomainBlock(); - #endif if (m_pAppDomainCB == NULL) { diff --git a/src/coreclr/src/debug/ee/debugger.h b/src/coreclr/src/debug/ee/debugger.h index b443fcf..cf25496 100644 --- a/src/coreclr/src/debug/ee/debugger.h +++ b/src/coreclr/src/debug/ee/debugger.h @@ -3781,30 +3781,6 @@ HANDLE OpenWin32EventOrThrow( LPCWSTR lpName ); -// @todo - should this be moved into where we defined IPCWriterInterface? -// Holder for security Attribute -// Old code: -// hr = g_pIPCManagerInterface->GetSecurityAttributes(GetCurrentProcessId(), &pSA); -// .... foo(pSa)... -// g_pIPCManagerInterface->DestroySecurityAttributes(pSA); -// -// new code: -// { -// SAHolder x(g_pIPCManagerInterface, GetCurrentProcessId()); -// .... foo(x.GetSA()) .. -// } // calls dtor -class IPCHostSecurityAttributeHolder -{ -public: - IPCHostSecurityAttributeHolder(DWORD pid); - ~IPCHostSecurityAttributeHolder(); - - SECURITY_ATTRIBUTES * GetHostSA(); - -protected: - SECURITY_ATTRIBUTES *m_pSA; // the resource we're protecting. -}; - #define SENDIPCEVENT_RAW_BEGIN_EX(pDbgLockHolder, gcxStmt) \ { \ Debugger::DebuggerLockHolder *__pDbgLockHolder = pDbgLockHolder; \ diff --git a/src/coreclr/src/debug/ee/funceval.cpp b/src/coreclr/src/debug/ee/funceval.cpp index 33f16f4..fefdf17 100644 --- a/src/coreclr/src/debug/ee/funceval.cpp +++ b/src/coreclr/src/debug/ee/funceval.cpp @@ -15,7 +15,6 @@ #include "stdafx.h" #include "debugdebugger.h" -#include "ipcmanagerinterface.h" #include "../inc/common.h" #include "perflog.h" #include "eeconfig.h" // This is here even for retail & free builds... diff --git a/src/coreclr/src/debug/ee/rcthread.cpp b/src/coreclr/src/debug/ee/rcthread.cpp index 11dd542..ebdd720 100644 --- a/src/coreclr/src/debug/ee/rcthread.cpp +++ b/src/coreclr/src/debug/ee/rcthread.cpp @@ -17,7 +17,6 @@ #include #include -#include "ipcmanagerinterface.h" #include "eemessagebox.h" #include "genericstackprobe.h" @@ -196,46 +195,6 @@ HANDLE OpenWin32EventOrThrow( RETURN h; } -//----------------------------------------------------------------------------- -// Holder for IPC SecurityAttribute -//----------------------------------------------------------------------------- -IPCHostSecurityAttributeHolder::IPCHostSecurityAttributeHolder(DWORD pid) -{ - CONTRACTL - { - SO_INTOLERANT; - THROWS; - GC_NOTRIGGER; - } - CONTRACTL_END; - - m_pSA = NULL; - -#ifdef FEATURE_IPCMAN - HRESULT hr = CCLRSecurityAttributeManager::GetHostSecurityAttributes(&m_pSA); - IfFailThrow(hr); - - _ASSERTE(m_pSA != NULL); -#endif // FEATURE_IPCMAN -} - -SECURITY_ATTRIBUTES * IPCHostSecurityAttributeHolder::GetHostSA() -{ - LIMITED_METHOD_CONTRACT; - return m_pSA; -} - - -IPCHostSecurityAttributeHolder::~IPCHostSecurityAttributeHolder() -{ - LIMITED_METHOD_CONTRACT; - -#ifdef FEATURE_IPCMAN - CCLRSecurityAttributeManager::DestroyHostSecurityAttributes(m_pSA); -#endif // FEATURE_IPCMAN -} - - //--------------------------------------------------------------------------------------- // // Init @@ -333,11 +292,6 @@ HRESULT DebuggerIPCControlBlock::Init( return S_OK; } -#ifdef FEATURE_IPCMAN -extern CCLRSecurityAttributeManager s_CLRSecurityAttributeManager; -#endif // FEATURE_IPCMAN - - void DebuggerRCThread::WatchForStragglers(void) { WRAPPER_NO_CONTRACT; @@ -421,14 +375,12 @@ HRESULT DebuggerRCThread::Init(void) } #else //FEATURE_DBGIPC_TRANSPORT_VM - IPCHostSecurityAttributeHolder sa(GetCurrentProcessId()); - // Create the events that the thread will need to receive events // from the out of process piece on the right side. // We will not fail out if CreateEvent fails for RSEA or RSER. Because // the worst case is that debugger cannot attach to debuggee. // - HandleHolder rightSideEventAvailable(WszCreateEvent(sa.GetHostSA(), (BOOL) kAutoResetEvent, FALSE, NULL)); + HandleHolder rightSideEventAvailable(WszCreateEvent(NULL, (BOOL) kAutoResetEvent, FALSE, NULL)); // Security fix: // We need to check the last error to see if the event was precreated or not @@ -441,7 +393,7 @@ HRESULT DebuggerRCThread::Init(void) rightSideEventAvailable.Clear(); } - HandleHolder rightSideEventRead(WszCreateEvent(sa.GetHostSA(), (BOOL) kAutoResetEvent, FALSE, NULL)); + HandleHolder rightSideEventRead(WszCreateEvent(NULL, (BOOL) kAutoResetEvent, FALSE, NULL)); // Security fix: // We need to check the last error to see if the event was precreated or not diff --git a/src/coreclr/src/dlls/mscordbi/CMakeLists.txt b/src/coreclr/src/dlls/mscordbi/CMakeLists.txt index e979960..87823a3 100644 --- a/src/coreclr/src/dlls/mscordbi/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscordbi/CMakeLists.txt @@ -81,7 +81,6 @@ set(COREDBI_LIBRARIES if(WIN32) list(APPEND COREDBI_LIBRARIES - ipcmanager-staticcrt mdhotdata-staticcrt mdwinmd_dbi kernel32.lib diff --git a/src/coreclr/src/inc/corhost.h b/src/coreclr/src/inc/corhost.h index 2990576..002f508 100644 --- a/src/coreclr/src/inc/corhost.h +++ b/src/coreclr/src/inc/corhost.h @@ -234,41 +234,6 @@ public: extern CCLRErrorReportingManager g_CLRErrorReportingManager; #endif // defined(FEATURE_WINDOWSPHONE) -#ifdef FEATURE_IPCMAN -// @TODO:: a-meicht -// consolidate the following class with DebuggerManager. -// -class CCLRSecurityAttributeManager -{ -public: - - // Set ACL on shared section, events, and process - STDMETHODIMP SetDACL(PACL pacl); - - // Returning the current ACL that CLR is using - STDMETHODIMP GetDACL(PACL *pacl); - - static void ProcessInit(); - static void ProcessCleanUp(); - - // retrieving Host security attribute setting. If host does not set it, default to - // our default policy. - static HRESULT GetHostSecurityAttributes(SECURITY_ATTRIBUTES **ppSA); - static void DestroyHostSecurityAttributes(SECURITY_ATTRIBUTES *pSA); - - static CrstStatic m_hostSAMutex; - -private: - static PACL m_pACL; - - // Security attributes cached for the current process. - static SECURITY_ATTRIBUTES m_hostSA; - static SECURITY_DESCRIPTOR m_hostSD; - - static HRESULT CopyACL(PACL pAclOriginal, PACL ppAclNew); -}; -#endif // FEATURE_IPCMAN - class CorHost2 : public CorRuntimeHostBase #ifndef FEATURE_PAL diff --git a/src/coreclr/src/inc/dacvars.h b/src/coreclr/src/inc/dacvars.h index a4209f1..54c1ce6 100644 --- a/src/coreclr/src/inc/dacvars.h +++ b/src/coreclr/src/inc/dacvars.h @@ -242,10 +242,6 @@ DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pStressLog, ::g_pStressLog) DEFINE_DACVAR(ULONG, SIZE_T, dac__s_gsCookie, ::s_gsCookie) -#ifdef FEATURE_IPCMAN -DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pIPCManagerInterface, ::g_pIPCManagerInterface) -#endif // FEATURE_IPCMAN - DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__g_FCDynamicallyAssignedImplementations, ::g_FCDynamicallyAssignedImplementations) #ifndef FEATURE_PAL diff --git a/src/coreclr/src/inc/ipcfunccall.h b/src/coreclr/src/inc/ipcfunccall.h deleted file mode 100644 index 15034e0..0000000 --- a/src/coreclr/src/inc/ipcfunccall.h +++ /dev/null @@ -1,117 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -//***************************************************************************** -// File: IPCFuncCall.h -// -// Define class to support a cross process function call. -// -//***************************************************************************** - - -#ifndef _IPCFUNCCALLIMPL_H_ -#define _IPCFUNCCALLIMPL_H_ - -//----------------------------------------------------------------------------- -// 1. Handler creates a IPCFuncCallHandler object and inits it with -// a callback function. -// 2. Source calls IPCFuncCallSource::DoThreadSafeCall(). This will pause the -// thread and trigger the callback on the handlers side. -// -// This mechanism is very robust. See the error return codes on -// DoThreadSafeCall() for more details. -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Send the call -//----------------------------------------------------------------------------- -class IPCFuncCallSource -{ -public: -//............................................................................. -// Error return codes for members. -// Our biggest error concerns are timeouts and no handlers. HRESULTS won't -// help us with these, so we'll have to use our own codes. -//............................................................................. - enum EError - { - // (Common) the function was called, and we waited for the full duration. - Ok, - - // (Common) The function MAY have been called, but we timed out before it - // finished This means either: The function was called, but took too long - // to finish or The handler died on us right after we hooked up to it and - // so the function never even got called. - Fail_Timeout_Call, - - // (Common) There was no handler for us to call - Fail_NoHandler, - - // (rare) The function was never called. We successfully connected to the handler, - // but we timed out waiting for the mutex. - Fail_Timeout_Lock, - - // (very rare) We were unable to create the mutex to serialize - Fail_CreateMutex, - - // (very rare) Catch-all General Failure. - Failed - - }; - - -// Make a call, wrapped in a mutex - static EError DoThreadSafeCall(); - - -protected: - -}; - - -//----------------------------------------------------------------------------- -// AuxThread Callback -//----------------------------------------------------------------------------- -DWORD WINAPI HandlerAuxThreadProc(LPVOID lpParameter); - - -//----------------------------------------------------------------------------- -// Callback for handler. AuxThread will call this. -//----------------------------------------------------------------------------- -typedef void (*HANDLER_CALLBACK)(); - -//----------------------------------------------------------------------------- -// Receieves the call. This should be in a different process than the source -//----------------------------------------------------------------------------- -class IPCFuncCallHandler -{ -public: - HRESULT InitFCHandler(HANDLER_CALLBACK pfnCallback, HANDLER_CALLBACK pfnCleanupCallback); - void TerminateFCHandler(); - void WaitForShutdown(); - - IPCFuncCallHandler(); - ~IPCFuncCallHandler(); - -protected: - BOOL IsShutdownComplete(); - void SafeCleanup(); - HANDLE m_hStartEnum; // event to notify start call - HANDLE m_hDoneEnum; // event to notify end call - - Volatile m_hAuxThread; // thread to listen for m_hStartEnum - - HANDLER_CALLBACK m_pfnCallback; - HANDLER_CALLBACK m_pfnCleanupCallback; - - Volatile m_fShutdownAuxThread; // flag the Aux thread to finish up gracefully - HANDLE m_hShutdownThread; // Event to signal the Aux thread to finish up gracefully - - HMODULE m_hCallbackModule; // Hold the module's ref to make sure that the - // aux thread's code doesn't get unmapped. -// Make auxthread our friend so he can access all our eventing objects - friend DWORD WINAPI HandlerAuxThreadProc(LPVOID); -}; - - -#endif // _IPCFUNCCALLIMPL_H_ diff --git a/src/coreclr/src/inc/ipcmanagerinterface.h b/src/coreclr/src/inc/ipcmanagerinterface.h deleted file mode 100644 index ef71371..0000000 --- a/src/coreclr/src/inc/ipcmanagerinterface.h +++ /dev/null @@ -1,204 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -//***************************************************************************** -// File: IPCManagerInterface.h -// -// Interface for InterProcess Communication with a COM+ process. -// -//***************************************************************************** - - -#ifndef _IPCMANAGERINTERFACE_H_ -#define _IPCMANAGERINTERFACE_H_ - -#include "../ipcman/ipcheader.h" - -struct PerfCounterIPCControlBlock; -struct AppDomainEnumerationIPCBlock; - -#include "../ipcman/ipcmanagerimpl.h" - -// These are the right that we will give to the global section and global events used -// in communicating between debugger and debugee -// -// SECTION_ALL_ACCESS is needed for the IPC block. Unfortunately, we DACL our events and -// IPC block identically. Or this particular right does not need to bleed into here. -// -#define CLR_IPC_GENERIC_RIGHT (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | STANDARD_RIGHTS_ALL | SECTION_ALL_ACCESS) - -//----------------------------------------------------------------------------- -// Writer - create a COM+ IPC Block with security attributes. -//----------------------------------------------------------------------------- -class IPCWriterInterface : public IPCWriterImpl -{ -public: - - BOOL TryAllocBlock(DWORD numRetries); - BOOL TryFreeBlock(); - - //............................................................................. - // Creation / Destruction only on implementation - //............................................................................. - HRESULT Init(); - void Terminate(); - - //............................................................................. - // Marks the data in the IPC block as initialized - //............................................................................. - void Publish(); - - //............................................................................. - // Accessor for the Perf block - //............................................................................. - PerfCounterIPCControlBlock * GetPerfBlock(); - - void DestroySecurityAttributes(SECURITY_ATTRIBUTES *pSA); - -#ifndef DACCESS_COMPILE - - //............................................................................. - // Create the SxS Public IPC block. - //............................................................................. - HRESULT CreateSxSPublicBlockOnPid(DWORD PID); - - //............................................................................. - // Open the SxS Public IPC block that has alread been created. - //............................................................................. - HRESULT OpenSxSPublicBlockOnPid(DWORD PID); - - HRESULT GetSxSPublicSecurityAttributes(DWORD pid, SECURITY_ATTRIBUTES **ppSA); - -#endif - - DWORD GetBlockTableSize(); - PTR_VOID GetBlockTableStart(); - - /*********************************** LEGACY FUNCTIONS *********************************** - * - * Though newer versions of the runtime do not open the LegacyPrivate block or the LegacyPublic - * block, we need functionality in the reader to inspect the LegacyPrivate block and LegacyPublic - * block so reading data from older runtimes. - * - ****************************************************************************************/ - - //............................................................................. - // The AppDomain block resides within the LegacyPrivate IPC block. - //............................................................................. - AppDomainEnumerationIPCBlock * GetAppDomainBlock(); - - //............................................................................. - // Create the LegacyPrivate IPC block. If this fails because the IPC block has already been - // created by another module then the phInstIPCBlockOwner argument will be set to the - // HINSTANCE of the module that created the IPC block. - // Set inService to TRUE if creating from within a service on behalf of a process. - //............................................................................. - HRESULT CreateLegacyPrivateBlockTempV4OnPid(DWORD PID, BOOL inService, HINSTANCE *phInstIPCBlockOwner); - - //............................................................................. - // Open the LegacyPrivate IPC block that has alread been created. - //............................................................................. - HRESULT OpenLegacyPrivateBlockOnPid(DWORD PID); - - //............................................................................. - // ReDacl our LegacyPrivate block after it has been created. - //............................................................................. - HRESULT ReDaclLegacyPrivateBlock(PSECURITY_DESCRIPTOR pSecurityDescriptor); - - //............................................................................. - // Accessors - return info from header - - // These functions work on LegacyPrivate Block - //............................................................................. - DWORD GetBlockSize(); - PTR_VOID GetBlockStart(); - PCWSTR GetInstancePath(); -}; - -//----------------------------------------------------------------------------- -// IPCReader class connects to a COM+ IPC block and reads from it -// @FUTURE - make global & private readers -//----------------------------------------------------------------------------- -class IPCReaderInterface : public IPCReaderImpl -{ -public: - - void MakeInstanceName(const WCHAR * szProcessName, DWORD pid, DWORD runtimeId, SString & sName); - void MakeInstanceNameWhidbey(const WCHAR * szProcessName, DWORD pid, SString & sName); - - BOOL TryOpenBlock(IPCHeaderReadHelper & readHelper, DWORD blockIndex); - - //............................................................................. - // Create & Destroy - //............................................................................. - ~IPCReaderInterface(); - - HRESULT OpenLegacyPrivateBlockTempV4OnPid(DWORD pid); - HRESULT OpenLegacyPrivateBlockTempV4OnPid(DWORD pid, DWORD dwDesiredAccess); - - HRESULT OpenLegacyPrivateBlockOnPid(DWORD pid); - HRESULT OpenLegacyPrivateBlockOnPid(DWORD pid, DWORD dwDesiredAccess); - HRESULT OpenLegacyPrivateBlockOnPidReadWrite(DWORD pid); - HRESULT OpenLegacyPrivateBlockOnPidReadOnly(DWORD pid); - void CloseLegacyPrivateBlock(); - -#ifndef DACCESS_COMPILE - HRESULT OpenLegacyPublicBlockOnPid(DWORD pid); - HRESULT OpenLegacyPublicBlockOnPid(DWORD pid, DWORD dwDesiredAccess); - HRESULT OpenLegacyPublicBlockOnPidReadOnly(DWORD pid); - void CloseLegacyPublicBlock(); - - HRESULT OpenBlockTableOnPid(DWORD pid); - HRESULT OpenBlockTableOnPid(DWORD pid, DWORD dwDesiredAccess); - HRESULT OpenBlockTableOnPidReadOnly(DWORD pid); - void CloseBlockTable(); -#endif - - //............................................................................. - // Accessors - return info from header - // @FUTURE - factor this into IPCWriterInterface as well. - //............................................................................. - USHORT GetBlockVersion(); - USHORT GetLegacyPublicBlockVersion(); - HINSTANCE GetInstance(); - USHORT GetBuildYear(); - USHORT GetBuildNumber(); - PVOID GetBlockStart(); - PCWSTR GetInstancePath(); - - //........................................ - // Check the block to see if its valid - //........................................ - BOOL IsValidLegacy(BOOL fIsLegacyPublicBlock); - -#ifndef DACCESS_COMPILE - //BOOL IsValidForSxSPublic(IPCControlBlock * pBlock); -#endif - - //............................................................................. - // Get different sections of the IPC - //............................................................................. - void * GetLegacyPrivateBlock(ELegacyPrivateIPCClient eClient); - void * GetLegacyPublicBlock(ELegacyPublicIPCClient eClient); -#ifndef DACCESS_COMPILE - //void * GetSxSPublicBlock(DWORD chunkIndex, EIPCClient eClient); -#endif - - void * GetPerfBlockLegacyPrivate(); - void * GetPerfBlockLegacyPublic(); -#ifndef DACCESS_COMPILE - //PerfCounterIPCControlBlock * GetPerfBlockSxSPublic(DWORD chunkIndex); -#endif - AppDomainEnumerationIPCBlock * GetAppDomainBlock(); - - //............................................................................. - // Return true if we're connected to a memory-mapped file, else false. - //............................................................................. - bool IsLegacyPrivateBlockOpen() const; - bool IsLegacyPublicBlockOpen() const; - bool IsBlockTableOpen() const; - - HRESULT IsCompatablePlatformForDebuggerAndDebuggee(DWORD pid, BOOL * pfCompatible); -}; - -#endif - diff --git a/src/coreclr/src/ipcman/CMakeLists.txt b/src/coreclr/src/ipcman/CMakeLists.txt deleted file mode 100644 index 6213fc4..0000000 --- a/src/coreclr/src/ipcman/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -add_definitions(-DFEATURE_NO_HOST) - -set(IPCMAN_SOURCES - ipcsharedsrc.cpp - ipcreaderimpl.cpp - ipcwriterimpl.cpp - ipcfunccallimpl.cpp -) - -convert_to_absolute_path(IPCMAN_SOURCES ${IPCMAN_SOURCES}) - -add_subdirectory(ipcman-staticcrt) diff --git a/src/coreclr/src/ipcman/ipcenums.h b/src/coreclr/src/ipcman/ipcenums.h deleted file mode 100644 index 5714798..0000000 --- a/src/coreclr/src/ipcman/ipcenums.h +++ /dev/null @@ -1,92 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCEnums.h -// -// Define various enums used by IPCMan -// -//***************************************************************************** - -#ifndef _IPCEnums_h_ -#define _IPCEnums_h_ - - - -//enum for factoring security descriptor stuff... -enum EDescriptorType -{ - eDescriptor_Private = 0, - eDescriptor_Public, - -// MAX used for arrays, insert above this. - eDescriptor_MAX -}; - - -//----------------------------------------------------------------------------- -// Each IPC client for an IPC block has one entry. -// IMPORTANT: Do not remove any entries from this enumeration as -// the directory indexing cannot change from version to version -// in order to preserve compatibility. The actual directory -// entry for an obsolete index can be zeroed (which all users -// should be written to handle for forward compatibility) but -// this enumeration can only be appended to. -//----------------------------------------------------------------------------- -enum EIPCClient -{ - eIPC_PerfCounters = 0, - -// MAX used for arrays, insert above this. - eIPC_MAX -}; - -//----------------------------------------------------------------------------- -// Each IPC client for a LegacyPrivate block (debugging, perf counters, etc) -// has one entry. -// IMPORTANT: Do not remove any entries from this enumeration as -// the directory indexing cannot change from version to version -// in order to preserve compatibility. The actual directory -// entry for an obsolete index can be zeroed (which all users -// should be written to handle for forward compatibility) but -// this enumeration can only be appended to. -//----------------------------------------------------------------------------- -enum ELegacyPrivateIPCClient -{ - eLegacyPrivateIPC_PerfCounters = 0, - eLegacyPrivateIPC_Obsolete_Debugger, - eLegacyPrivateIPC_AppDomain, - eLegacyPrivateIPC_Obsolete_Service, - eLegacyPrivateIPC_Obsolete_ClassDump, - eLegacyPrivateIPC_Obsolete_MiniDump, - eLegacyPrivateIPC_InstancePath, - -// MAX used for arrays, insert above this. - eLegacyPrivateIPC_MAX -}; - -//----------------------------------------------------------------------------- -// Each IPC client for a LegacyPublic block has one entry. -// IMPORTANT: Do not remove any entries from this enumeration as -// the directory indexing cannot change from version to version -// in order to preserve compatibility. The actual directory -// entry for an obsolete index can be zeroed (which all users -// should be written to handle for forward compatibility) but -// this enumeration can only be appended to. -//----------------------------------------------------------------------------- -enum ELegacyPublicIPCClient -{ - eLegacyPublicIPC_PerfCounters = 0, - -// MAX used for arrays, insert above this. - eLegacyPublicIPC_MAX -}; - -#endif // _IPCEnums_h_ - diff --git a/src/coreclr/src/ipcman/ipcfunccallimpl.cpp b/src/coreclr/src/ipcman/ipcfunccallimpl.cpp deleted file mode 100644 index ed3a2bc..0000000 --- a/src/coreclr/src/ipcman/ipcfunccallimpl.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCFuncCallImpl.cpp -// -// Implement support for a cross process function call. -// -//***************************************************************************** - -#include "stdafx.h" -#include "ipcfunccall.h" -#include "ipcshared.h" - - - -// Telesto stubs - -//----------------------------------------------------------------------------- -// Wrap an unsafe call in a mutex to assure safety -// Biggest error issues are: -// 1. Timeout (probably handler doesn't exist) -// 2. Handler can be destroyed at any time. -//----------------------------------------------------------------------------- -IPCFuncCallSource::EError IPCFuncCallSource::DoThreadSafeCall() -{ - return Ok; -} - diff --git a/src/coreclr/src/ipcman/ipcheader.h b/src/coreclr/src/ipcman/ipcheader.h deleted file mode 100644 index bbccb52..0000000 --- a/src/coreclr/src/ipcman/ipcheader.h +++ /dev/null @@ -1,560 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCHeader.h -// -// Define the LegacyPrivate header format for COM+ memory mapped files. Everyone -// outside of IPCMan.lib will use the public header, IPCManagerInterface.h -// -//***************************************************************************** - -#ifndef _IPCManagerPriv_h_ -#define _IPCManagerPriv_h_ - - -//----------------------------------------------------------------------------- -// We must pull in the headers of all client blocks -// @todo - resolve these directory links -//----------------------------------------------------------------------------- -#include "../debug/inc/dbgappdomain.h" -#include "perfcounterdefs.h" - -#include "ndpversion.h" -#include "ipcenums.h" - -//----------------------------------------------------------------------------- -// Entry in the IPC Directory. Ensure binary compatibility across versions -// if we add (or remove) entries. If we remove an block, the entry should -// be EMPTY_ENTRY_OFFSET -//----------------------------------------------------------------------------- - -const DWORD EMPTY_ENTRY_OFFSET = 0xFFFFFFFF; -const DWORD EMPTY_ENTRY_SIZE = 0; - -struct IPCEntry -{ - DWORD m_Offset; // offset of the IPC Block from the end of the Full IPC Header - DWORD m_Size; // size (in bytes) of the block -}; - -// Newer versions of the CLR use m_Flags field -const USHORT IPC_FLAG_USES_FLAGS = 0x1; -const USHORT IPC_FLAG_INITIALIZED = 0x2; -const USHORT IPC_FLAG_X86 = 0x4; - -/****************************************************************************** - * The CLR opens memory mapped files to expose perfcounter values and other - * information to other processes. Historically there have been three memory - * mapped files: the BlockTable, the LegacyPrivateBlock, and the - * LegacyPublicBlock. - * - * BlockTable - The block table was designed to work with multiple runtimes - * running side by side in the same process (SxS in-proc). We have defined - * semantics using interlocked operations that allow a runtime to allocate - * a block from the block table in a thread-safe manner. - * - * LegacyPrivateBlock - The legacy private block was used by older versions - * of the runtime to expose various information to the debugger. The - * legacy private block is not compatible with in-proc SxS, and thus it - * must be removed in the near future. Currently it is being used to expose - * information about AppDomains to the debugger. We will need to keep the - * code that knows how to read the legacy private block as long as we - * continue to support .NET 3.5 SP1. - * - * LegacyPublicBlock - The legacy public block was used by older versions - * of the runtime to expose perfcounter values. The legacy public block is - * not compatible with in-proc SxS, and thus it has been removed. We will - * need to keep the code that knows how to read the legacy public block as - * long as we continue to support .NET 3.5 SP1. - ******************************************************************************/ - -/**************************************** BLOCK TABLE ****************************************/ - -const DWORD IPC_BLOCK_TABLE_SIZE = 65536; -const DWORD IPC_BLOCK_SIZE = 2048; -const DWORD IPC_NUM_BLOCKS_IN_TABLE = 32; - -static_assert_no_msg(IPC_BLOCK_TABLE_SIZE == IPC_NUM_BLOCKS_IN_TABLE * IPC_BLOCK_SIZE); - -#if defined(TIA64) -#define IA64MemoryBarrier() MemoryBarrier() -#else -#define IA64MemoryBarrier() -#endif - -struct IPCHeader -{ - // Chunk header - Volatile m_Counter; // value of 0 is special; means that this block has never been touched before by a writer - DWORD m_RuntimeId; // value of 0 is special; means that chunk is currently free (runtime ids are always greater than 0) - DWORD m_Reserved1; - DWORD m_Reserved2; - - // Standard header (m_hInstance was removed) - USHORT m_Version; // version of the IPC Block - USHORT m_Flags; // flags field - DWORD m_blockSize; // Size of the entire shared memory block - USHORT m_BuildYear; // stamp for year built - USHORT m_BuildNumber; // stamp for Month/Day built - DWORD m_numEntries; // Number of entries in the table - - // Directory - IPCEntry m_table[eIPC_MAX]; // entry describing each client's block -}; - -extern BOOL __SwitchToThread(DWORD dwSleepMSec, DWORD dwSwitchCount); - -class IPCHeaderLockHolder -{ - LONG m_Counter; - BOOL m_HaveLock; - IPCHeader & m_Header; - - public: - - IPCHeaderLockHolder(IPCHeader & header) : m_HaveLock(FALSE), m_Header(header) {} - - BOOL TryGetLock() - { - _ASSERTE(!m_HaveLock); - LONG oldCounter = m_Header.m_Counter; - if ((oldCounter & 1) != 0) - return FALSE; - m_Counter = oldCounter + 1; - if (InterlockedCompareExchange((LONG *)(&(m_Header.m_Counter)), m_Counter, oldCounter) != oldCounter) - return FALSE; - m_HaveLock = TRUE; - - return TRUE; - } - - BOOL TryGetLock(DWORD numRetries) - { - DWORD dwSwitchCount = 0; - - for (;;) - { - if (TryGetLock()) - return TRUE; - - if (numRetries == 0) - return FALSE; - - --numRetries; - __SwitchToThread(0, ++dwSwitchCount); - } - } - - void FreeLock() - { - _ASSERTE(m_HaveLock); - _ASSERTE(m_Header.m_Counter == m_Counter); - ++m_Counter; - m_Counter = (m_Counter == 0) ? 2 : m_Counter; - m_Header.m_Counter = m_Counter; - m_HaveLock = FALSE; - } - - ~IPCHeaderLockHolder() - { - if (m_HaveLock) - FreeLock(); - } -}; - -class IPCHeaderReadHelper -{ - IPCHeader m_CachedHeader; - IPCHeader * m_pUnreliableHeader; - BOOL m_IsOpen; - - public: - - IPCHeaderReadHelper() : m_pUnreliableHeader(NULL), m_IsOpen(FALSE) {} - - BOOL TryOpenHeader(IPCHeader * header) - { - _ASSERTE(!m_IsOpen); - - m_pUnreliableHeader = header; - - // Read the counter and the runtime ID from the header - m_CachedHeader.m_Counter = m_pUnreliableHeader->m_Counter; - if ((m_CachedHeader.m_Counter & 1) != 0) - return FALSE; - m_CachedHeader.m_RuntimeId = m_pUnreliableHeader->m_RuntimeId; - - // If runtime ID is 0, then this block is not allocated by - // a runtime, and thus there is no further work to do - if (m_CachedHeader.m_RuntimeId == 0) - { - m_IsOpen = TRUE; - return TRUE; - } - - // Read the rest of the values from the header - m_CachedHeader.m_Reserved1 = m_pUnreliableHeader->m_Reserved1; - m_CachedHeader.m_Reserved2 = m_pUnreliableHeader->m_Reserved2; - m_CachedHeader.m_Version = m_pUnreliableHeader->m_Version; - m_CachedHeader.m_Flags = m_pUnreliableHeader->m_Flags; - m_CachedHeader.m_blockSize = m_pUnreliableHeader->m_blockSize; - m_CachedHeader.m_BuildYear = m_pUnreliableHeader->m_BuildYear; - m_CachedHeader.m_BuildNumber = m_pUnreliableHeader->m_BuildNumber; - m_CachedHeader.m_numEntries = m_pUnreliableHeader->m_numEntries; - - // Verify that the header did not change during the read - LONG counter = m_pUnreliableHeader->m_Counter; - if (m_CachedHeader.m_Counter != counter) - return FALSE; - - // Since we know we got a clean read of numEntries, we - // should be able to assert this with confidence - if (m_CachedHeader.m_numEntries == 0) - { - _ASSERTE(!"numEntries from IPCBlock is zero"); - return FALSE; - } - else if (m_CachedHeader.m_numEntries > eIPC_MAX) - { - _ASSERTE(!"numEntries from IPCBlock is too big"); - return FALSE; - } - - if (m_CachedHeader.m_blockSize == 0) - { - _ASSERTE(!"blockSize from IPCBlock is zero"); - return FALSE; - } - else if (m_CachedHeader.m_blockSize > IPC_BLOCK_SIZE) - { - _ASSERTE(!"blockSize from IPCBlock is too big"); - return FALSE; - } - - // Copy the table - for (DWORD i = 0; i < m_CachedHeader.m_numEntries; ++i) - { - m_CachedHeader.m_table[i].m_Offset = m_pUnreliableHeader->m_table[i].m_Offset; - m_CachedHeader.m_table[i].m_Size = m_pUnreliableHeader->m_table[i].m_Size; - if (i == eIPC_PerfCounters) - { - if(!((SIZE_T)m_CachedHeader.m_table[i].m_Offset < IPC_BLOCK_SIZE) && ((SIZE_T)m_CachedHeader.m_table[i].m_Offset + m_CachedHeader.m_table[i].m_Size <= IPC_BLOCK_SIZE)) - { - _ASSERTE(!"PerfCounter section offset + size is too large"); - return FALSE; - } - } - } - - // If eIPC_MAX > numEntries, then mark the left over - // slots in m_table as "empty". - for (DWORD i = m_CachedHeader.m_numEntries; i < eIPC_MAX; ++i) - { - m_CachedHeader.m_table[i].m_Offset = EMPTY_ENTRY_OFFSET; - m_CachedHeader.m_table[i].m_Size = EMPTY_ENTRY_SIZE; - } - - // Verify again that the header did not change during the read - counter = m_pUnreliableHeader->m_Counter; - if (m_CachedHeader.m_Counter != counter) - return FALSE; - - m_IsOpen = TRUE; - return TRUE; - } - - void CloseHeader() - { - m_IsOpen = FALSE; - m_pUnreliableHeader = NULL; - } - - BOOL HeaderHasChanged() - { - _ASSERTE(m_IsOpen); - LONG counter = m_pUnreliableHeader->m_Counter; - return (m_CachedHeader.m_Counter != counter) ? TRUE : FALSE; - } - - BOOL IsSentinal() - { - _ASSERTE(m_IsOpen); - return (m_CachedHeader.m_Counter == 0); - } - - DWORD GetRuntimeId() - { - _ASSERTE(m_IsOpen); - return m_CachedHeader.m_RuntimeId; - } - - USHORT GetIPCVersion() - { - _ASSERTE(m_IsOpen); - return m_CachedHeader.m_Version; - } - - BOOL UseWow64Structs() - { - _ASSERTE(m_IsOpen); -#if !defined(_TARGET_X86_) - return ((m_CachedHeader.m_Flags & IPC_FLAG_X86) != 0) ? TRUE : FALSE; -#else - return FALSE; -#endif - } - - IPCHeader * GetCachedCopyOfHeader() - { - _ASSERTE(m_IsOpen); - return &m_CachedHeader; - } - - IPCHeader * GetUnreliableHeader() - { - _ASSERTE(m_IsOpen); - return m_pUnreliableHeader; - } - - private: - - void * GetUnreliableSection(EIPCClient eClient) - { - if (!m_IsOpen) - { - _ASSERTE(!"IPCHeaderReadHelper is not open"); - return NULL; - } - - if (eClient < 0 || eClient >= eIPC_MAX) - { - _ASSERTE(!"eClient is out of bounds"); - return NULL; - } - - if (m_CachedHeader.m_table[eClient].m_Offset == EMPTY_ENTRY_OFFSET) - { - _ASSERTE(!"Section is empty"); - return NULL; - } - - return (BYTE*)m_pUnreliableHeader + (SIZE_T)m_CachedHeader.m_table[eClient].m_Offset; - } - - public: - - // We opted to return void* instead of PerfCounterIPCControlBlock* because this - // forces the caller to do an explicit cast. If UseWow64Structs() returns FALSE, - // then the caller should cast to PerfCounterIPCControlBlock*. If UseWow64Structs() - // return TRUE, then the caller should cast to PerfCounterWow64IPCControlBlock* - - void * GetUnreliablePerfBlock() - { - return GetUnreliableSection(eIPC_PerfCounters); - } -}; - -const DWORD SXSPUBLIC_IPC_SIZE_NO_PADDING = sizeof(IPCHeader) + sizeof(struct PerfCounterIPCControlBlock); -const DWORD SXSPUBLIC_WOW64_IPC_SIZE_NO_PADDING = sizeof(IPCHeader) + sizeof(struct PerfCounterWow64IPCControlBlock); - -const DWORD SXSPUBLIC_IPC_PAD_SIZE = IPC_BLOCK_SIZE - SXSPUBLIC_IPC_SIZE_NO_PADDING; -const DWORD SXSPUBLIC_WOW64_IPC_PAD_SIZE = IPC_BLOCK_SIZE - SXSPUBLIC_WOW64_IPC_SIZE_NO_PADDING; - -struct IPCControlBlock -{ -// Header - IPCHeader m_Header; - -// Client blocks - struct PerfCounterIPCControlBlock m_perf; - -// Padding - BYTE m_Padding[SXSPUBLIC_IPC_PAD_SIZE]; -}; - -#pragma pack(push, 4) -struct IPCControlBlockWow64 -{ -// Header - IPCHeader m_Header; - -// Client blocks - PerfCounterWow64IPCControlBlock m_perf; - -// Padding - BYTE m_Padding[SXSPUBLIC_WOW64_IPC_PAD_SIZE]; -}; -#pragma pack(pop) - -static_assert_no_msg(sizeof(IPCControlBlock) == IPC_BLOCK_SIZE); -static_assert_no_msg(sizeof(IPCControlBlockWow64) == IPC_BLOCK_SIZE); - -struct IPCControlBlockTable -{ - IPCControlBlock m_blocks[IPC_NUM_BLOCKS_IN_TABLE]; - - IPCControlBlock * GetBlock(DWORD index) - { return &(m_blocks[index]); } -}; - -static_assert_no_msg(sizeof(IPCControlBlockTable) == IPC_BLOCK_TABLE_SIZE); - -typedef DPTR(IPCControlBlockTable) PTR_IPCControlBlockTable; -typedef DPTR(IPCControlBlock) PTR_IPCControlBlock; - - -/**************************************** LEGACY ****************************************/ - -//----------------------------------------------------------------------------- -// LegacyPrivate header - put in its own structure so we can easily get the -// size of the header. It will compile to the same thing either way. -// This header must remain completely binary compatible w/ older versions. -// Notes: -// This header contains a "module handle" field which is platform dependent in size. -// That means for a 64 bit process to read IPC header of a 32 bit process, we cannot -// use the same class definition. The class would be different on the two platforms. -// Hence LegacyPrivateIPCHeaderTemplate is templatized on the type of the module handle. The -// IPC writers always use HINSTANCE as the parameter. The IPC reader has to know -// whether it is reading IPC block of a 32 bit process. If so it uses DWORD as the -// parameter so that the resulting LegacyPrivateIPCHeader is similar in format to the one -// written by the 32 bit process at the other end. -// The DWORD 'm_dwVersion' was split into two two USHORTS named 'm_Version' and -// 'm_Flags'. The upper bits of 'm_dwVersion' were never used, nor was 'm_dwVersion' -// used to determine whether an IPC block was valid or compatible. Thus, splitting -// the 'm_dwVersion' into two USHORTs should not introduce any compatibility issues. -//----------------------------------------------------------------------------- -template -struct LegacyPrivateIPCHeaderTemplate -{ -// header - USHORT m_Version; // version of the IPC Block - USHORT m_Flags; // flags field - DWORD m_blockSize; // Size of the entire shared memory block - TModuleHandle m_hInstance; // instance of module that created this header - USHORT m_BuildYear; // stamp for year built - USHORT m_BuildNumber; // stamp for Month/Day built - DWORD m_numEntries; // Number of entries in the table -}; - -typedef LegacyPrivateIPCHeaderTemplate LegacyPrivateIPCHeader; - -//----------------------------------------------------------------------------- -// This fixes alignment & packing issues. -// This header must remain completely binary compatible w/ older versions. -//----------------------------------------------------------------------------- -struct FullIPCHeaderLegacyPrivate -{ -// Header - LegacyPrivateIPCHeader m_header; - -// Directory - IPCEntry m_table[eLegacyPrivateIPC_MAX]; // entry describing each client's block - -}; - -//----------------------------------------------------------------------------- -// This fixes alignment & packing issues. -// This header must remain completely binary compatible w/ older versions. -//----------------------------------------------------------------------------- -template -struct FullIPCHeaderLegacyPublicTemplate -{ -// Header - struct LegacyPrivateIPCHeaderTemplate m_header; - -// Directory - IPCEntry m_table[eLegacyPublicIPC_MAX]; // entry describing each client's block - -}; - -// In hindsight, we should have made the offsets be absolute, but we made them -// relative to the end of the FullIPCHeader. -// The problem is that as future versions added new Entries to the directory, -// the header size grew. -// Thus we make IPCEntry::m_Offset is relative to LEGACY_IPC_ENTRY_OFFSET_BASE, which -// corresponds to sizeof(LegacyPrivateIPCHeader) for an v1.0 /v1.1 build. -#ifdef _TARGET_X86_ - const DWORD LEGACY_IPC_ENTRY_OFFSET_BASE = 0x14; -#else - // On non-x86 platforms, we don't need to worry about backwards compat. - // But we do need to worry about alignment, so just pretend that everett was 0, - // and solve both problems. - const DWORD LEGACY_IPC_ENTRY_OFFSET_BASE = 0x0; -#endif - -// When a 64 bit process reads IPC block of a 32 bit process, we need to know the -// LEGACY_IPC_ENTRY_OFFSET_BASE of the latter from the former. So this constant is defined -const DWORD LEGACY_IPC_ENTRY_OFFSET_BASE_WOW64 = 0x14; - -// Size of LegacyPublicIPCControlBlock for Everett and Whidbey -const DWORD LEGACYPUBLIC_IPC_BLOCK_SIZE_32 = 0x134; -const DWORD LEGACYPUBLIC_IPC_BLOCK_SIZE_64 = 0x1a0; - -//----------------------------------------------------------------------------- -// LegacyPrivate (per process) IPC Block for COM+ apps -//----------------------------------------------------------------------------- -struct LegacyPrivateIPCControlBlock -{ - FullIPCHeaderLegacyPrivate m_FullIPCHeader; - - -// Client blocks - struct PerfCounterIPCControlBlock m_perf; // no longer used but kept for compat - struct AppDomainEnumerationIPCBlock m_appdomain; - WCHAR m_instancePath[MAX_LONGPATH]; -}; - -typedef DPTR(LegacyPrivateIPCControlBlock) PTR_LegacyPrivateIPCControlBlock; - -#if defined(_TARGET_X86_) -// For perf reasons, we'd like to keep the IPC block small enough to fit on -// a single page. This assert ensures it won't silently grow past the page boundary -// w/o us knowing about it. If this assert fires, then either: -// - consciously adjust it to let the IPC block be 2 pages. -// - shrink the IPC blocks. -static_assert_no_msg(sizeof(LegacyPrivateIPCControlBlock) <= 4096); -#endif - -//----------------------------------------------------------------------------- -// LegacyPublic (per process) IPC Block for CLR apps -//----------------------------------------------------------------------------- -struct LegacyPublicIPCControlBlock -{ - FullIPCHeaderLegacyPublicTemplate m_FullIPCHeaderLegacyPublic; - -// Client blocks - struct PerfCounterIPCControlBlock m_perf; -}; - -//----------------------------------------------------------------------------- -// LegacyPublicWow64IPCControlBlock is used by a 64 bit process to read the IPC block -// of a 32 bit process. This struct is similar to LegacyPublicIPCControlBlock, except -// that all pointer (ie platform dependent) sized fields are substituted with -// DWORDs, so as to match the exact layout of LegacyPublicIPCControlBlock in a 32 bit process -//----------------------------------------------------------------------------- -#pragma pack(push, 4) -struct LegacyPublicWow64IPCControlBlock -{ - FullIPCHeaderLegacyPublicTemplate m_FullIPCHeaderLegacyPublic; - -// Client blocks - PerfCounterWow64IPCControlBlock m_perf; -}; -#pragma pack(pop) - -typedef DPTR(LegacyPublicIPCControlBlock) PTR_LegacyPublicIPCControlBlock; - -//----------------------------------------------------------------------------- -// Inline definitions -//----------------------------------------------------------------------------- - -#include "ipcheader.inl" - -#endif // _IPCManagerPriv_h_ diff --git a/src/coreclr/src/ipcman/ipcheader.inl b/src/coreclr/src/ipcman/ipcheader.inl deleted file mode 100644 index 9a3c196..0000000 --- a/src/coreclr/src/ipcman/ipcheader.inl +++ /dev/null @@ -1,90 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCHeader.inl -// -// Define the LegacyPrivate header format for COM+ memory mapped files. Everyone -// outside of IPCMan.lib will use the public header, IPCManagerInterface.h -// -//***************************************************************************** - -#ifndef _IPCManagerPriv_inl_ -#define _IPCManagerPriv_inl_ - -#include "ipcheader.h" - -//============================================================================= -// Internal Helpers: Encapsulate any error-prone math / comparisons. -// The helpers are very streamlined and don't handle error conditions. -// Also, Table access functions use DWORD instead of typesafe Enums -// so they can be more flexible (not just for LegacyPrivate blocks). -//============================================================================= - -//----------------------------------------------------------------------------- -// Returns true if the entry is empty and false if the entry is usable. -// This is an internal helper that Enforces a formal definition for an -// "empty" entry -// -// Arguments: -// block - IPC block of interest -// Id - index of the desired entry in the IPC block's table -//----------------------------------------------------------------------------- -inline bool Internal_CheckEntryEmptyLegacyPrivate( - const LegacyPrivateIPCControlBlock & block, - DWORD Id -) -{ -// Directory has offset in bytes of block - const DWORD offset = block.m_FullIPCHeader.m_table[Id].m_Offset; - - return (EMPTY_ENTRY_OFFSET == offset); -} - -//----------------------------------------------------------------------------- -// Returns the base that entry offsets for the specified IPC block -// are relative to. -// -// Arguments: -// block - IPC block of interest -//----------------------------------------------------------------------------- -inline SIZE_T Internal_GetOffsetBaseLegacyPrivate(const LegacyPrivateIPCControlBlock & block) -{ - return LEGACY_IPC_ENTRY_OFFSET_BASE + - block.m_FullIPCHeader.m_header.m_numEntries - * sizeof(IPCEntry); // skip over directory (variable size) -} - -//----------------------------------------------------------------------------- -// Returns a BYTE* to a block within a header. This is an internal -// helper that encapsulates error-prone math. -// -// Arguments: -// block - IPC block of interest -// Id - index of the desired entry in the IPC block's table -//----------------------------------------------------------------------------- -inline BYTE* Internal_GetBlockLegacyPrivate( - const LegacyPrivateIPCControlBlock & block, - DWORD Id -) -{ - -// Directory has offset in bytes of block - const DWORD offset = block.m_FullIPCHeader.m_table[Id].m_Offset; - - -// This block has been removed. Callee should have caught that and not called us. - _ASSERTE(!Internal_CheckEntryEmptyLegacyPrivate(block, Id)); - return - ((BYTE*) &block) // base pointer to start of block - + Internal_GetOffsetBaseLegacyPrivate(block) - +offset; // jump to block -} - -#endif // _IPCManagerPriv_inl_ diff --git a/src/coreclr/src/ipcman/ipcman-staticcrt/CMakeLists.txt b/src/coreclr/src/ipcman/ipcman-staticcrt/CMakeLists.txt deleted file mode 100644 index a9f5880..0000000 --- a/src/coreclr/src/ipcman/ipcman-staticcrt/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_definitions(-D_CRTIMP=) #static link of crt -add_precompiled_header(stdafx.h ../stdafx.cpp IPCMAN_SOURCES) -add_library_clr(ipcmanager-staticcrt STATIC ${IPCMAN_SOURCES}) \ No newline at end of file diff --git a/src/coreclr/src/ipcman/ipcmanagerimpl.h b/src/coreclr/src/ipcman/ipcmanagerimpl.h deleted file mode 100644 index 19e6119..0000000 --- a/src/coreclr/src/ipcman/ipcmanagerimpl.h +++ /dev/null @@ -1,147 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCManagerImpl.h -// -// Defines Classes to implement InterProcess Communication Manager for a COM+ -// -//***************************************************************************** - -#ifndef _IPCManagerImpl_H_ -#define _IPCManagerImpl_H_ - -#include - -#include "contract.h" -#include "ipcenums.h" - - -// Version of the IPC Block that this lib was compiled for -const USHORT VER_IPC_BLOCK = 4; - -// Versions for the legacy IPC Blocks -const USHORT VER_LEGACYPRIVATE_IPC_BLOCK = 2; -const USHORT VER_LEGACYPUBLIC_IPC_BLOCK = 3; - -struct LegacyPrivateIPCControlBlock; - - -//----------------------------------------------------------------------------- -// Implementation for the IPCManager for COM+. -//----------------------------------------------------------------------------- -class IPCWriterImpl -{ -public: - - IPCWriterImpl(); - ~IPCWriterImpl(); - - BOOL IsLegacyPrivateBlockOpen() const; - BOOL IsBlockTableOpen() const; - - HRESULT CreateWinNTDescriptor(DWORD pid, SECURITY_ATTRIBUTES **ppSA, EDescriptorType descType); - -protected: - -#ifndef DACCESS_COMPILE - - void CloseMemoryMappedFile(HANDLE & hMemFile, void * & pBlock); - - HRESULT CreateNewIPCBlock(); - void CreateIPCHeader(); - void WriteEntryHelper(EIPCClient eClient, DWORD offs, DWORD size); - -#endif - - // Cache pointers to each section - struct PerfCounterIPCControlBlock *m_pPerf; - struct AppDomainEnumerationIPCBlock *m_pAppDomain; - PCWSTR m_pInstancePath; - - // Info on the Block Table - HANDLE m_handleBlockTable; - HANDLE m_handleBoundaryDesc; - HANDLE m_handlePrivateNamespace; - PSID m_pSID; - PTR_IPCControlBlockTable m_pBlockTable; - PTR_IPCControlBlock m_pBlock; - PTR_IPCControlBlockTable m_pBackupBlock; - -#ifndef DACCESS_COMPILE - - HRESULT CreateNewLegacyPrivateIPCBlock(); - void CreateLegacyPrivateIPCHeader(); - void WriteEntryHelper(ELegacyPrivateIPCClient eClient, DWORD offs, DWORD size); - -#endif - - // Stats on MemoryMapped file for the given pid - HANDLE m_handleLegacyPrivateBlock; - PTR_LegacyPrivateIPCControlBlock m_ptrLegacyPrivateBlock; - PTR_LegacyPrivateIPCControlBlock m_pIPCBackupBlockLegacyPrivate; - - // Security attributes cached for the current process. - SECURITY_ATTRIBUTES *m_cachedPrivateDescriptor; - -}; - -//----------------------------------------------------------------------------- -// IPCReader class connects to a COM+ IPC block and reads from it -// @todo - make global & private readers -//----------------------------------------------------------------------------- -class IPCReaderImpl -{ -public: - IPCReaderImpl(); - ~IPCReaderImpl(); - - BOOL TryOpenBlock(IPCHeaderReadHelper & readHelper, DWORD blockIndex); - - BOOL UseWow64StructsLegacy(); - BOOL Internal_CheckEntryEmptyLegacyPublic(DWORD Id); - BYTE * Internal_GetBlockLegacyPublic(DWORD Id); - DWORD GetNumEntriesLegacy(void * pBlock); - IPCEntry * GetDirectoryLegacy(void * pBlock); - DWORD GetOffsetBaseLegacy(); - DWORD GetFirstExpectedOffsetLegacy(); - USHORT GetFlagsLegacy(void * pBlock); - DWORD GetBlockSizeLegacy(void * pBlock); - -protected: - - HANDLE m_handleBlockTable; - HANDLE m_handleBoundaryDesc; - HANDLE m_handlePrivateNamespace; - PSID m_pSID; - IPCControlBlockTable * m_pBlockTable; - - BOOL m_fIsTarget32Bit; -#ifdef _DEBUG - BOOL m_fInitialized; -#endif - - HANDLE m_handleLegacyPrivateBlock; - LegacyPrivateIPCControlBlock * m_ptrLegacyPrivateBlock; - HANDLE m_handleLegacyPublicBlock; - - union - { - LegacyPublicIPCControlBlock * m_ptrLegacyPublicBlock; - LegacyPublicWow64IPCControlBlock * m_ptrWow64LegacyPublicBlock; - }; -}; - -//----------------------------------------------------------------------------- -// Inline definitions -//----------------------------------------------------------------------------- - -#include "ipcmanagerimpl.inl" - -#endif // _IPCManagerImpl_H_ diff --git a/src/coreclr/src/ipcman/ipcmanagerimpl.inl b/src/coreclr/src/ipcman/ipcmanagerimpl.inl deleted file mode 100644 index 4cf4017..0000000 --- a/src/coreclr/src/ipcman/ipcmanagerimpl.inl +++ /dev/null @@ -1,192 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCManagerImpl.inl -// -// Defines Classes to implement InterProcess Communication Manager for a COM+ -// -//***************************************************************************** - -#ifndef _IPCManagerImpl_INL_ -#define _IPCManagerImpl_INL_ - -#include "ipcmanagerimpl.h" - -//----------------------------------------------------------------------------- -// Return true if the IPCBlockTable is available. -//----------------------------------------------------------------------------- -inline BOOL IPCWriterImpl::IsBlockTableOpen() const -{ - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - return (m_pBlockTable != NULL); -} - -//----------------------------------------------------------------------------- -// Return true if our LegacyPrivate block is available. -//----------------------------------------------------------------------------- -inline BOOL IPCWriterImpl::IsLegacyPrivateBlockOpen() const -{ - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - return (m_ptrLegacyPrivateBlock != NULL); -} - -//----------------------------------------------------------------------------- -// Returns a BOOL indicating whether the Wow64 structs should be used instead -// of the normal structs. -// -// It is NOT safe to call this function before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline BOOL IPCReaderImpl::UseWow64StructsLegacy() -{ -#if !defined(_X86_) - _ASSERTE(m_fInitialized); - return m_fIsTarget32Bit; -#else - return FALSE; -#endif -} - -//----------------------------------------------------------------------------- -// Returns the value of the flags field of the specified IPC block. This is -// safe to call before m_fIsTarget32Bit has been initialized since the flags -// field is in the same position for 32-bit and 64-bit targets. -// -// It is safe to call this function before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline USHORT IPCReaderImpl::GetFlagsLegacy(void * pBlock) -{ - return ((LegacyPrivateIPCHeader*)pBlock)->m_Flags; -} - -//----------------------------------------------------------------------------- -// Returns the value of the block size field of the specified IPC block. -// -// It is safe to call this function before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline DWORD IPCReaderImpl::GetBlockSizeLegacy(void * pBlock) -{ - return ((LegacyPrivateIPCHeader*)pBlock)->m_blockSize; -} - -//----------------------------------------------------------------------------- -// Returns true if the specified entry is empty and false if the entry is -// usable. This is an internal helper that enforces the formal definition -// for an "empty" entry -// -// Arguments: -// Id - index of the entry to check -// -// It is NOT safe to call this function before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline BOOL IPCReaderImpl::Internal_CheckEntryEmptyLegacyPublic(DWORD Id) -{ - // Directory has offset in bytes of block - return (GetDirectoryLegacy(m_ptrLegacyPublicBlock)[Id].m_Offset == EMPTY_ENTRY_OFFSET); -} - -//----------------------------------------------------------------------------- -// Returns a BYTE* to a block within a header. This is an internal -// helper that encapsulates error-prone math. -// -// Arguments: -// Id - index of the entry containing the desired LegacyPublic block -// -// It is NOT safe to call this function before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline BYTE * IPCReaderImpl::Internal_GetBlockLegacyPublic(DWORD Id) -{ - // This block has been removed. Callee should have caught that and not called us. - _ASSERTE(!Internal_CheckEntryEmptyLegacyPublic(Id)); - - return ((BYTE*) m_ptrLegacyPublicBlock) + (SIZE_T)GetOffsetBaseLegacy() + - (SIZE_T)GetNumEntriesLegacy(m_ptrLegacyPublicBlock) * sizeof(IPCEntry) + - (SIZE_T)GetDirectoryLegacy(m_ptrLegacyPublicBlock)[Id].m_Offset; -} - -//----------------------------------------------------------------------------- -// Returns a value that is used to calculate the actual offset of an entry in -// an IPC block. Internal_GetBlockLegacyPublic() shows how to use GetOffsetBaseLegacy() -// to calculate the actual offset of an entry. -// -// It is NOT safe to call this funciton before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline DWORD IPCReaderImpl::GetOffsetBaseLegacy() -{ - if (UseWow64StructsLegacy()) - return LEGACY_IPC_ENTRY_OFFSET_BASE_WOW64; - - return LEGACY_IPC_ENTRY_OFFSET_BASE; -} - -//----------------------------------------------------------------------------- -// Returns the expected value for the specified offset of the first entry in -// an IPC block. -// -// It is NOT safe to call this funciton before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline DWORD IPCReaderImpl::GetFirstExpectedOffsetLegacy() -{ - if (GetOffsetBaseLegacy() == 0) - return sizeof(LegacyPrivateIPCHeader); - - return 0; -} - -//----------------------------------------------------------------------------- -// Returns the number of entries in the specified IPC block. -// -// It is NOT safe to call this funciton before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline DWORD IPCReaderImpl::GetNumEntriesLegacy(void * pBlock) -{ - if (UseWow64StructsLegacy()) - return ((LegacyPrivateIPCHeaderTemplate*)pBlock)->m_numEntries; - - return ((LegacyPrivateIPCHeader*)pBlock)->m_numEntries; -} - -//----------------------------------------------------------------------------- -// Returns a pointer to the directory ('m_table') in the specified IPC block. -// -// It is NOT safe to call this funciton before m_fIsTarget32Bit has been -// initialized. -//----------------------------------------------------------------------------- -inline IPCEntry * IPCReaderImpl::GetDirectoryLegacy(void * pBlock) -{ - if (UseWow64StructsLegacy()) - return ((FullIPCHeaderLegacyPublicTemplate*)pBlock)->m_table; - - return ((FullIPCHeaderLegacyPublicTemplate*)pBlock)->m_table; -} - -//----------------------------------------------------------------------------- -// Compile-time asserts that check the values of LEGACY_IPC_ENTRY_OFFSET_BASE and -// LEGACY_IPC_ENTRY_OFFSET_BASE_WOW64 -//----------------------------------------------------------------------------- - -#ifdef _TARGET_X86_ - C_ASSERT(sizeof(LegacyPrivateIPCHeaderTemplate) == LEGACY_IPC_ENTRY_OFFSET_BASE); -#endif - -C_ASSERT(sizeof(LegacyPrivateIPCHeaderTemplate) == LEGACY_IPC_ENTRY_OFFSET_BASE_WOW64); - - -#endif // _IPCManagerImpl_INL_ - diff --git a/src/coreclr/src/ipcman/ipcreaderimpl.cpp b/src/coreclr/src/ipcman/ipcreaderimpl.cpp deleted file mode 100644 index 4ecfa5f..0000000 --- a/src/coreclr/src/ipcman/ipcreaderimpl.cpp +++ /dev/null @@ -1,1113 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCReaderImpl.cpp -// -// Read a COM+ memory mapped file -// -//***************************************************************************** - -#include "stdafx.h" - -#include "ipcmanagerinterface.h" -#include "ipcheader.h" -#include "ipcshared.h" -#include - -#include - -#if defined(FEATURE_IPCMAN) -//----------------------------------------------------------------------------- -// Ctor sets members -//----------------------------------------------------------------------------- -IPCReaderImpl::IPCReaderImpl() -{ - LIMITED_METHOD_CONTRACT; -#ifdef _DEBUG - m_fInitialized = FALSE; -#endif - m_fIsTarget32Bit = FALSE; - m_handleLegacyPrivateBlock = NULL; - m_ptrLegacyPrivateBlock = NULL; - m_handleLegacyPublicBlock = NULL; - m_ptrLegacyPublicBlock = NULL; - m_handleBlockTable = NULL; - m_pBlockTable = NULL; - m_handleBoundaryDesc = NULL; - m_handlePrivateNamespace = NULL; - m_pSID = NULL; -} - -//----------------------------------------------------------------------------- -// dtor -//----------------------------------------------------------------------------- -IPCReaderImpl::~IPCReaderImpl() -{ - LIMITED_METHOD_CONTRACT; - - LOG((LF_CORDB, LL_INFO10, "IPCRI::IPCReaderImpl::~IPCReaderImpl 0x%08x (LegacyPrivate)\n", m_handleLegacyPrivateBlock)); - LOG((LF_CORDB, LL_INFO10, "IPCRI::IPCReaderImpl::~IPCReaderImpl 0x%08x (LegacyPublic)\n", m_handleLegacyPublicBlock)); - LOG((LF_CORDB, LL_INFO10, "IPCRI::IPCReaderImpl::~IPCReaderImpl 0x%08x (SxSPublic)\n", m_handleBlockTable)); - - _ASSERTE(m_handleLegacyPrivateBlock == NULL); - _ASSERTE(m_ptrLegacyPrivateBlock == NULL); - - _ASSERTE(m_handleLegacyPublicBlock == NULL); - _ASSERTE(m_ptrLegacyPublicBlock == NULL); - - _ASSERTE(m_handleBlockTable == NULL); - _ASSERTE(m_pBlockTable == NULL); - _ASSERTE(m_handleBoundaryDesc == NULL); - _ASSERTE(m_pSID == NULL); - _ASSERTE(m_handlePrivateNamespace == NULL); - - -} - -//----------------------------------------------------------------------------- -// dtor -//----------------------------------------------------------------------------- -IPCReaderInterface::~IPCReaderInterface() -{ - LIMITED_METHOD_CONTRACT; - - LOG((LF_CORDB, LL_INFO10, "IPCRI::IPCReaderInterface::~IPCReaderInterface 0x%08x (BlockTable)\n", m_handleBlockTable)); - LOG((LF_CORDB, LL_INFO10, "IPCRI::IPCReaderInterface::~IPCReaderInterface 0x%08x (LegacyPrivate)\n", m_handleLegacyPrivateBlock)); - LOG((LF_CORDB, LL_INFO10, "IPCRI::IPCReaderInterface::~IPCReaderInterface 0x%08x (LegacyPublic)\n", m_handleLegacyPublicBlock)); - - if (m_handleLegacyPrivateBlock) - { - CloseLegacyPrivateBlock(); - } - _ASSERTE(m_handleLegacyPrivateBlock == NULL); - _ASSERTE(m_ptrLegacyPrivateBlock == NULL); - -#ifndef DACCESS_COMPILE - if (m_handleLegacyPublicBlock) - { - CloseLegacyPublicBlock(); - } - _ASSERTE(m_handleLegacyPublicBlock == NULL); - _ASSERTE(m_ptrLegacyPublicBlock == NULL); - - if (m_handleBlockTable) - { - CloseBlockTable(); - } - _ASSERTE(m_handleBlockTable == NULL); - _ASSERTE(m_pBlockTable == NULL); -#endif -} - -//----------------------------------------------------------------------------- -// Close whatever block we opened -//----------------------------------------------------------------------------- -void IPCReaderInterface::CloseLegacyPrivateBlock() -{ - WRAPPER_NO_CONTRACT; - - LOG((LF_CORDB, LL_INFO10, "IPCRI::CloseLegacyPrivateBlock 0x%08x\n", m_handleLegacyPrivateBlock)); - - IPCShared::CloseMemoryMappedFile( - m_handleLegacyPrivateBlock, - (void * &) m_ptrLegacyPrivateBlock - ); - _ASSERTE(m_handleLegacyPrivateBlock == NULL); - _ASSERTE(m_ptrLegacyPrivateBlock == NULL); -} - -#ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Close whatever block we opened -//----------------------------------------------------------------------------- -void IPCReaderInterface::CloseLegacyPublicBlock() -{ - WRAPPER_NO_CONTRACT; - - LOG((LF_CORDB, LL_INFO10, "IPCRI::CloseLegacyPublicBlock 0x%08x\n", m_handleLegacyPublicBlock)); - - IPCShared::CloseMemoryMappedFile( - m_handleLegacyPublicBlock, - (void * &) m_ptrLegacyPublicBlock - ); - _ASSERTE(m_handleLegacyPublicBlock == NULL); - _ASSERTE(m_ptrLegacyPublicBlock == NULL); -} - -//----------------------------------------------------------------------------- -// Close whatever block we opened -//----------------------------------------------------------------------------- -void IPCReaderInterface::CloseBlockTable() -{ - WRAPPER_NO_CONTRACT; - - LOG((LF_CORDB, LL_INFO10, "IPCRI::CloseBlockTable 0x%08x\n", m_handleBlockTable)); - - IPCShared::CloseMemoryMappedFile( - m_handleBlockTable, - (void * &) m_pBlockTable - ); - _ASSERTE(m_handleBlockTable == NULL); - _ASSERTE(m_pBlockTable == NULL); -} - -#endif - -//----------------------------------------------------------------------------- -// Check to see if Debugger and Debuggee are on compatible platform -// Currently, we only consider incompatible if one process is on WOW64 box and the other is not. -// If so, return false. -// For all other cases, return true for now. -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::IsCompatablePlatformForDebuggerAndDebuggee( - DWORD pid, - BOOL * pfCompatible) -{ - if (pfCompatible == NULL) - return E_INVALIDARG; - - // assume compatible unless otherwise - *pfCompatible = TRUE; - - // assume that the target has the same bitness as - // this process unless otherwise -#ifdef _TARGET_X86_ - m_fIsTarget32Bit = TRUE; -#else - m_fIsTarget32Bit = FALSE; -#endif -#ifdef _DEBUG - m_fInitialized = TRUE; -#endif - - BOOL fThisProcessIsWow64 = FALSE; - BOOL fSuccess = FALSE; - HANDLE hThisProcess = GetCurrentProcess(); - fSuccess = IsWow64Process(hThisProcess, &fThisProcessIsWow64); - CloseHandle(hThisProcess); - hThisProcess = NULL; - - if (!fSuccess) - return HRESULT_FROM_GetLastError(); - - HANDLE hTargetProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); - if (hTargetProcess == NULL) - return HRESULT_FROM_GetLastError(); - - BOOL fTargetProcessIsWow64 = FALSE; - fSuccess = IsWow64Process(hTargetProcess, &fTargetProcessIsWow64); - CloseHandle(hTargetProcess); - hTargetProcess = NULL; - - if (!fSuccess) - return HRESULT_FROM_GetLastError(); - - // We don't want to expose the IPC block if one process is x86 and - // the other is ia64 or amd64 - if (fTargetProcessIsWow64 != fThisProcessIsWow64) - { - *pfCompatible = FALSE; - m_fIsTarget32Bit = !m_fIsTarget32Bit; - } - - return S_OK; -} - - -void IPCReaderInterface::MakeInstanceName(const WCHAR * szProcessName, DWORD pid, DWORD runtimeId, SString & sName) -{ - WRAPPER_NO_CONTRACT; - - const WCHAR * szFormat = CorSxSPublicInstanceName; - - sName.Printf(szFormat, szProcessName, pid, runtimeId); -} - - -void IPCReaderInterface::MakeInstanceNameWhidbey(const WCHAR * szProcessName, DWORD pid, SString & sName) -{ - WRAPPER_NO_CONTRACT; - - const WCHAR * szFormat = CorSxSPublicInstanceNameWhidbey; - - sName.Printf(szFormat, szProcessName, pid); -} - - -//----------------------------------------------------------------------------- -// Open our LegacyPrivate block -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPrivateBlockOnPid(DWORD pid, DWORD dwDesiredAccess) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - -#if 0 -// Note, PID != GetCurrentProcessId(), b/c we're expected to be opening -// someone else's IPCBlock, not our own. If this isn't the case, just remove -// this assert - -// exception: if we're enumerating provesses, we'll hit our own -// _ASSERTE(pid != GetCurrentProcessId()); -#endif - - // Note: if our LegacyPrivate block is open, we shouldn't be attaching to a new one. - _ASSERTE(!IsLegacyPrivateBlockOpen()); - if (IsLegacyPrivateBlockOpen()) - { - // if we goto errExit, it will close the file. We don't want that. - return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - } - - HRESULT hr = S_OK; - - EX_TRY - { - // We should not be trying to open the IPC block of an x86 process from - // within an ia64 process, or vice versa. This can only happen on - // Server2003 and later. - - BOOL fCompatible = FALSE; - hr = IsCompatablePlatformForDebuggerAndDebuggee(pid, &fCompatible); - if (FAILED(hr)) - { - goto end; - } - if (fCompatible == FALSE) - { - hr = CORDBG_E_UNCOMPATIBLE_PLATFORMS; - goto end; - } - - // In order to verify handle's owner, we need READ_CONTROL. - dwDesiredAccess |= READ_CONTROL; - - { - SString szMemFileName; - IPCShared::GenerateName(pid, szMemFileName); - m_handleLegacyPrivateBlock = WszOpenFileMapping(dwDesiredAccess, - FALSE, - szMemFileName); - if (m_handleLegacyPrivateBlock == NULL) - { - hr = HRESULT_FROM_GetLastError(); - } - - LOG((LF_CORDB, LL_INFO10, "IPCRI::OPBOP: CreateFileMapping of %S, handle = 0x%08x, pid = 0x%8.8x GetLastError=%d\n", - szMemFileName.GetUnicode(), m_handleLegacyPrivateBlock, pid, GetLastError())); - if (m_handleLegacyPrivateBlock == NULL) - { - goto end; - } - } - - // Verify that the owner of the handle is the same as the user of that pid. - // This protects us against a 3rd user pre-creating the IPC block underneath us - // and tricking us into attaching to that. - // Even if a 3rd-party is able to spoof the IPC block, they themselves won't - // have access to it and so the IPC block will remain all zeros. - // That radically limits potential attacks that a 3rd-party could do. - // - if (IsHandleSpoofed(m_handleLegacyPrivateBlock, pid)) - { - hr = E_ACCESSDENIED; - goto end; - } - - m_ptrLegacyPrivateBlock = (LegacyPrivateIPCControlBlock*) MapViewOfFile( - m_handleLegacyPrivateBlock, - dwDesiredAccess, - 0, 0, 0); - - if (m_ptrLegacyPrivateBlock== NULL) - { - hr = HRESULT_FROM_GetLastError(); - goto end; - } - - // Check if LegacyPrivate block is valid; if it is not valid, - // report the block as "not compatible" - if (!IsValidLegacy(FALSE)) - hr = CORDBG_E_UNCOMPATIBLE_PLATFORMS; - - end:; - } - EX_CATCH - { - Exception *e = GET_EXCEPTION(); - hr = e->GetHR(); - if (hr == S_OK) - { - hr = E_FAIL; - } - } - EX_END_CATCH(SwallowAllExceptions); - - if (!SUCCEEDED(hr)) - { - CloseLegacyPrivateBlock(); - } - - return hr; -} - -//----------------------------------------------------------------------------- -// Open our LegacyPrivate block -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPrivateBlockTempV4OnPid(DWORD pid, DWORD dwDesiredAccess) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - -#if 0 -// Note, PID != GetCurrentProcessId(), b/c we're expected to be opening -// someone else's IPCBlock, not our own. If this isn't the case, just remove -// this assert - -// exception: if we're enumerating provesses, we'll hit our own -// _ASSERTE(pid != GetCurrentProcessId()); -#endif - - // Note: if our LegacyPrivate block is open, we shouldn't be attaching to a new one. - _ASSERTE(!IsLegacyPrivateBlockOpen()); - if (IsLegacyPrivateBlockOpen()) - { - // if we goto errExit, it will close the file. We don't want that. - return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - } - - HRESULT hr = S_OK; - - EX_TRY - { - // We should not be trying to open the IPC block of an x86 process from - // within an ia64 process, or vice versa. This can only happen on - // Server2003 and later. - - BOOL fCompatible = FALSE; - hr = IsCompatablePlatformForDebuggerAndDebuggee(pid, &fCompatible); - if (FAILED(hr)) - { - goto end; - } - if (fCompatible == FALSE) - { - hr = CORDBG_E_UNCOMPATIBLE_PLATFORMS; - goto end; - } - - // In order to verify handle's owner, we need READ_CONTROL. - dwDesiredAccess |= READ_CONTROL; - - { - SString szMemFileName; - IPCShared::GenerateNameLegacyTempV4(pid, szMemFileName); - m_handleLegacyPrivateBlock = WszOpenFileMapping(dwDesiredAccess, - FALSE, - szMemFileName); - if (m_handleLegacyPrivateBlock == NULL) - { - hr = HRESULT_FROM_GetLastError(); - } - - LOG((LF_CORDB, LL_INFO10, "IPCRI::OLPBTV4OP: CreateFileMapping of %S, handle = 0x%08x, pid = 0x%8.8x GetLastError=%d\n", - szMemFileName.GetUnicode(), m_handleLegacyPrivateBlock, pid, GetLastError())); - if (m_handleLegacyPrivateBlock == NULL) - { - goto end; - } - } - - // Verify that the owner of the handle is the same as the user of that pid. - // This protects us against a 3rd user pre-creating the IPC block underneath us - // and tricking us into attaching to that. - // Even if a 3rd-party is able to spoof the IPC block, they themselves won't - // have access to it and so the IPC block will remain all zeros. - // That radically limits potential attacks that a 3rd-party could do. - // - if (IsHandleSpoofed(m_handleLegacyPrivateBlock, pid)) - { - hr = E_ACCESSDENIED; - goto end; - } - - m_ptrLegacyPrivateBlock = (LegacyPrivateIPCControlBlock*) MapViewOfFile( - m_handleLegacyPrivateBlock, - dwDesiredAccess, - 0, 0, 0); - - if (m_ptrLegacyPrivateBlock== NULL) - { - hr = HRESULT_FROM_GetLastError(); - goto end; - } - - // Check if LegacyPrivate block is valid; if it is not valid, - // report the block as "not compatible" - if (!IsValidLegacy(FALSE)) - hr = CORDBG_E_UNCOMPATIBLE_PLATFORMS; - - end:; - } - EX_CATCH - { - Exception *e = GET_EXCEPTION(); - hr = e->GetHR(); - if (hr == S_OK) - { - hr = E_FAIL; - } - } - EX_END_CATCH(SwallowAllExceptions); - - if (!SUCCEEDED(hr)) - { - CloseLegacyPrivateBlock(); - } - - return hr; -} - -#ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Open our LegacyPublic block -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPublicBlockOnPid(DWORD pid, DWORD dwDesiredAccess) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Note: if our LegacyPublic block is open, we shouldn't be attaching to a new one. - _ASSERTE(!IsLegacyPublicBlockOpen()); - if (IsLegacyPublicBlockOpen()) - { - // if we goto errExit, it will close the file. We don't want that. - return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - } - - HRESULT hr = S_OK; - - EX_TRY - { - { - SString szMemFileName; - IPCShared::GenerateLegacyPublicName(pid, szMemFileName); - m_handleLegacyPublicBlock = WszOpenFileMapping(dwDesiredAccess, - FALSE, - szMemFileName); - if (m_handleLegacyPublicBlock == NULL) - { - hr = HRESULT_FROM_GetLastError(); - } - - LOG((LF_CORDB, LL_INFO10, "IPCRI::OPBOP: CreateFileMapping of %S, handle = 0x%08x, pid = 0x%8.8x GetLastError=%d\n", - szMemFileName.GetUnicode(), m_handleLegacyPublicBlock, pid, GetLastError())); - if (m_handleLegacyPublicBlock == NULL) - { - goto end; - } - } - - m_ptrLegacyPublicBlock = (LegacyPublicIPCControlBlock*) MapViewOfFile( - m_handleLegacyPublicBlock, - dwDesiredAccess, - 0, 0, 0); - if (m_ptrLegacyPublicBlock == NULL) - { - hr = HRESULT_FROM_GetLastError(); - goto end; - } - - // Check if the target is valid and compatible - if (!IsValidLegacy(TRUE)) - { - hr = CORDBG_E_UNCOMPATIBLE_PLATFORMS; - goto end; - } - - end:; - } - EX_CATCH - { - Exception *e = GET_EXCEPTION(); - hr = e->GetHR(); - if (hr == S_OK) - { - hr = E_FAIL; - } - } - EX_END_CATCH(SwallowAllExceptions); - - if (!SUCCEEDED(hr)) - { - if (m_handleLegacyPrivateBlock != NULL) - CloseLegacyPrivateBlock(); - - if (m_handleLegacyPublicBlock != NULL) - CloseLegacyPublicBlock(); - } - - return hr; -} - - - - - -//----------------------------------------------------------------------------- -// Open our IPCBlockTable -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenBlockTableOnPid(DWORD pid, DWORD dwDesiredAccess) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Note: if our IPCBlockTable is open, we shouldn't be attaching to a new one. - _ASSERTE(!IsBlockTableOpen()); - if (IsBlockTableOpen()) - { - // if we goto errExit, it will close the file. We don't want that. - return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - } - - HRESULT hr = S_OK; - - EX_TRY - { - { - SString szMemFileName; - - hr = IPCShared::GenerateBlockTableName(pid, szMemFileName, m_handleBoundaryDesc,m_handlePrivateNamespace, &m_pSID, FALSE); - if (FAILED(hr)) - { - goto end; - } - - m_handleBlockTable = WszOpenFileMapping(dwDesiredAccess, - FALSE, - szMemFileName); - if (m_handleBlockTable == NULL) - { - hr = HRESULT_FROM_GetLastError(); - } - - LOG((LF_CORDB, LL_INFO10, "IPCRI::OPBOP: CreateFileMapping of %S, handle = 0x%08x, pid = 0x%8.8x GetLastError=%d\n", - szMemFileName.GetUnicode(), m_handleBlockTable, pid, GetLastError())); - if (m_handleBlockTable == NULL) - { - goto end; - } - } - - m_pBlockTable = (IPCControlBlockTable*) MapViewOfFile( - m_handleBlockTable, - dwDesiredAccess, - 0, 0, 0); - - if (m_pBlockTable == NULL) - { - hr = HRESULT_FROM_GetLastError(); - goto end; - } -#if defined(_TARGET_X86_) - //get the flags of the first available block. - BOOL isInitialized = FALSE; - for (DWORD i = 0; i < IPC_NUM_BLOCKS_IN_TABLE; ++i) { - USHORT flags = m_pBlockTable->GetBlock(i)->m_Header.m_Flags; - if ((flags & IPC_FLAG_INITIALIZED) == 0) { - continue; - } - m_fIsTarget32Bit = ((flags & IPC_FLAG_X86) != 0); - isInitialized = TRUE; - // If this process is 32 bit and the target is 64 bit, - // then the target is incompatible - if (!m_fIsTarget32Bit){ - hr = E_FAIL; - goto end; - } - break; - } - if (!isInitialized) { - //none of the blocks are initialized - hr = E_FAIL; - goto end; - } -#endif // defined(_TARGET_X86_) - - end:; - } - EX_CATCH - { - Exception *e = GET_EXCEPTION(); - hr = e->GetHR(); - if (hr == S_OK) - { - hr = E_FAIL; - } - } - EX_END_CATCH(SwallowAllExceptions); - - if (!SUCCEEDED(hr)) - { - if (m_handleBlockTable != NULL) - CloseBlockTable(); - } - if(!SUCCEEDED(IPCShared::FreeHandles(m_handleBoundaryDesc,m_pSID,m_handlePrivateNamespace))) - { - hr = E_FAIL; - } - return hr; -} - -HRESULT IPCReaderInterface::OpenBlockTableOnPid(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenBlockTableOnPid(pid, FILE_MAP_ALL_ACCESS)); -} - -HRESULT IPCReaderInterface::OpenBlockTableOnPidReadOnly(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenBlockTableOnPid(pid, FILE_MAP_READ)); -} - -#endif - - -//----------------------------------------------------------------------------- -// Open our LegacyPrivate block for all access -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPrivateBlockOnPid(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenLegacyPrivateBlockOnPid(pid, FILE_MAP_ALL_ACCESS)); -} - -//----------------------------------------------------------------------------- -// Open our LegacyPrivate block for all access -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPrivateBlockTempV4OnPid(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenLegacyPrivateBlockTempV4OnPid(pid, FILE_MAP_ALL_ACCESS)); -} - -#ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Open our LegacyPublic block for all access -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPublicBlockOnPid(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenLegacyPublicBlockOnPid(pid, FILE_MAP_ALL_ACCESS)); -} - -#endif - -//----------------------------------------------------------------------------- -// Open our LegacyPrivate block for read/write access -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPrivateBlockOnPidReadWrite(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenLegacyPrivateBlockOnPid(pid, FILE_MAP_READ | FILE_MAP_WRITE)); -} - -//----------------------------------------------------------------------------- -// Open our LegacyPrivate block for read only access -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPrivateBlockOnPidReadOnly(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenLegacyPrivateBlockOnPid(pid, FILE_MAP_READ)); -} - -#ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Open our LegacyPublic block for read only access -//----------------------------------------------------------------------------- -HRESULT IPCReaderInterface::OpenLegacyPublicBlockOnPidReadOnly(DWORD pid) -{ - WRAPPER_NO_CONTRACT; - - return (OpenLegacyPublicBlockOnPid(pid, FILE_MAP_READ)); -} - -#endif - -//----------------------------------------------------------------------------- -// Get a client's LegacyPrivate block based on enum -// This is a robust function. -// It will return NULL if: -// * the IPC block is closed (also ASSERT), -// * the eClient is out of range (From version mismatch) -// * the request block is removed (probably version mismatch) -// Else it will return a pointer to the requested block -//----------------------------------------------------------------------------- -void * IPCReaderInterface::GetLegacyPrivateBlock(ELegacyPrivateIPCClient eClient) -{ - WRAPPER_NO_CONTRACT; - - _ASSERTE(IsLegacyPrivateBlockOpen()); - - // This block doesn't exist if we're closed or out of the table's range - if (!IsLegacyPrivateBlockOpen() || (DWORD) eClient >= m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_numEntries) - { - return NULL; - } - - if (Internal_CheckEntryEmptyLegacyPrivate(*m_ptrLegacyPrivateBlock,eClient)) - { - return NULL; - } - - return Internal_GetBlockLegacyPrivate(*m_ptrLegacyPrivateBlock,eClient); -} - -#ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Get a client's LegacyPublic block based on enum -// This is a robust function. -// It will return NULL if: -// * the IPC block is closed (also ASSERT), -// * the eClient is out of range (From version mismatch) -// * the requested block is removed (probably version mismatch) -// Else it will return a pointer to the requested block -//----------------------------------------------------------------------------- -void * IPCReaderInterface::GetLegacyPublicBlock(ELegacyPublicIPCClient eClient) -{ - WRAPPER_NO_CONTRACT; - - _ASSERTE(IsLegacyPublicBlockOpen()); - - // This block doesn't exist if we're closed or out of the table's range - if (!IsLegacyPublicBlockOpen()) - return NULL; - - DWORD dwNumEntries = GetNumEntriesLegacy(m_ptrLegacyPublicBlock); - - if ((DWORD) eClient >= dwNumEntries) - return NULL; - - if (Internal_CheckEntryEmptyLegacyPublic(eClient)) - return NULL; - - return Internal_GetBlockLegacyPublic(eClient); -} - -#endif - -//----------------------------------------------------------------------------- -// Is our LegacyPrivate block open? -//----------------------------------------------------------------------------- -bool IPCReaderInterface::IsLegacyPrivateBlockOpen() const -{ - LIMITED_METHOD_CONTRACT; - - return m_ptrLegacyPrivateBlock != NULL; -} - -#ifndef DACCESS_COMPILE - -bool IPCReaderInterface::IsLegacyPublicBlockOpen() const -{ - LIMITED_METHOD_CONTRACT; - - return m_ptrLegacyPublicBlock != NULL; -} - -bool IPCReaderInterface::IsBlockTableOpen() const -{ - LIMITED_METHOD_CONTRACT; - - return m_pBlockTable != NULL; -} - -void * IPCReaderInterface::GetPerfBlockLegacyPublic() -{ - WRAPPER_NO_CONTRACT; - - return (PerfCounterIPCControlBlock*) GetLegacyPublicBlock(eLegacyPublicIPC_PerfCounters); -} - -#endif - -void * IPCReaderInterface::GetPerfBlockLegacyPrivate() -{ - WRAPPER_NO_CONTRACT; - - return (PerfCounterIPCControlBlock*) GetLegacyPrivateBlock(eLegacyPrivateIPC_PerfCounters); -} - -AppDomainEnumerationIPCBlock * IPCReaderInterface::GetAppDomainBlock() -{ - WRAPPER_NO_CONTRACT; - - return (AppDomainEnumerationIPCBlock*) GetLegacyPrivateBlock(eLegacyPrivateIPC_AppDomain); -} - -//----------------------------------------------------------------------------- -// Check if the block is valid. Current checks include: -// * Check Flags -// * Check Directory structure -// * Check Bitness (LegacyPublic block only) -//----------------------------------------------------------------------------- -BOOL IPCReaderInterface::IsValidLegacy(BOOL fIsLegacyPublicBlock) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Initialize the pBlock pointer to point to the specified block; - // specified block must be open - - void * pBlock = (fIsLegacyPublicBlock ? (void*)m_ptrLegacyPublicBlock : (void*)m_ptrLegacyPrivateBlock); - _ASSERTE(pBlock != NULL); - - // Check if block size has been initialized - DWORD dwBlockSize = GetBlockSizeLegacy(pBlock); - if (dwBlockSize == 0) - return FALSE; - - // If this IPC block uses the flags field and the initialized flag isn't set, - // then the block has not been initialized - USHORT flags = GetFlagsLegacy(pBlock); - BOOL fUsesFlags = (flags & IPC_FLAG_USES_FLAGS); - if (fUsesFlags && (flags & IPC_FLAG_INITIALIZED) == 0) - return FALSE; - - // If this is the LegacyPublic block, then we need to check bitness; if it - // turns out that the bitness is incompatible, return FALSE - if (fIsLegacyPublicBlock) - { - // If this IPC block uses the flags field, then use the flags to - // determine the bitness of the target block - if (fUsesFlags) - { - m_fIsTarget32Bit = ((flags & IPC_FLAG_X86) != 0); - } - - // Otherwise, this IPC block does not use the flags field - else - { - // Use block size to determine the bitness of the target block - m_fIsTarget32Bit = (dwBlockSize == LEGACYPUBLIC_IPC_BLOCK_SIZE_32); - - // If block size is not equal known values from used by older - // versions of the CLR, then assume this block is not compatible - _ASSERTE(m_fIsTarget32Bit || dwBlockSize == LEGACYPUBLIC_IPC_BLOCK_SIZE_64); - } - -#if defined(_DEBUG) - m_fInitialized = TRUE; -#endif //_DEBUG - -#if defined(_TARGET_X86_) - // If this process is 32 bit and the target is 64 bit, - // then the target is incompatible - if (!m_fIsTarget32Bit) - return FALSE; -#endif //_TARGET_X86_ - } - - // If this IPC block uses the flags field and this is not a - // debug build, then no further checks are necessary. -#if !defined(_DEBUG) - if (fUsesFlags) - return TRUE; -#endif //_DEBUG - - // Make sure numEntries has been initialized - DWORD dwNumEntries = GetNumEntriesLegacy(pBlock); - if (dwNumEntries == 0) - { - // This assert will fail only if the IPC block uses flags and - // 'm_numEntries' has not been initialized - _ASSERTE(!fUsesFlags && "m_numEntries is not initialized"); - return FALSE; - } - - // Make sure that block size is not too small - SIZE_T cbOffsetBase = (SIZE_T)GetOffsetBaseLegacy() + dwNumEntries * sizeof(IPCEntry); - if (dwBlockSize < cbOffsetBase) - { - _ASSERTE(!"m_blockSize is too small or m_numEntries is too big (1)"); - return FALSE; - } - - // Check to make sure that the expected offset for the end of - // m_table does not go past the end of the block - SIZE_T offsetExpected = GetFirstExpectedOffsetLegacy(); - SIZE_T offsetLast = dwBlockSize - cbOffsetBase; - if (offsetExpected > offsetLast) - { - _ASSERTE(!"m_blockSize is too small or m_numEntries is too big (2)"); - return FALSE; - } - - // Check each entries offset and size to make sure they are correct - IPCEntry * table = GetDirectoryLegacy(pBlock); - for(DWORD i = 0; i < dwNumEntries; ++i) - { - SIZE_T entryOffset = table[i].m_Offset; - SIZE_T entrySize = table[i].m_Size; - - if (entryOffset == EMPTY_ENTRY_OFFSET) - { - // Verify that this entry has size of EMPTY_ENTRY_SIZE - if (entrySize != EMPTY_ENTRY_SIZE) - { - _ASSERTE(!"Empty entry has size that does not equal EMPTY_ENTRY_SIZE"); - return FALSE; - } - } - else - { - // Verify that this entry has non-zero size - if (entrySize == 0) - { - // This assert will fail only if the IPC block uses flags and - // 'm_Size' has not been initialized - _ASSERTE(!fUsesFlags && "m_Size is not initialized"); - return FALSE; - } - - // Verify that the actual offset equals the expected offset - if (entryOffset != offsetExpected) - { - if (entryOffset == 0) - { - // This assert will only fail if the IPC block uses flags and - // 'm_Offset' has not been initialized - _ASSERTE(!fUsesFlags && "m_Offset is not initialized"); - } - else - { - // This assert will fail if 'm_Offset' has been initialized - // but does not equal the expected value - _ASSERTE(!"Actual offset does not equal to expected offset"); - } - - return FALSE; - } - - // Compute the next expected offset - offsetExpected += entrySize; - } - } - - // Verify that the end of the last entry is equal to the - // end of the IPC block - if (offsetExpected != offsetLast) - { - _ASSERTE(!"End of last entry does not equal end of IPC block"); - return FALSE; - } - - return TRUE; -} - -BOOL IPCReaderInterface::TryOpenBlock(IPCHeaderReadHelper & readHelper, DWORD blockIndex) -{ - _ASSERTE(blockIndex < IPC_NUM_BLOCKS_IN_TABLE); - readHelper.CloseHeader(); - return readHelper.TryOpenHeader(&m_pBlockTable->m_blocks[blockIndex].m_Header); -} - -USHORT IPCReaderInterface::GetBlockVersion() -{ - WRAPPER_NO_CONTRACT; - - _ASSERTE(IsLegacyPrivateBlockOpen()); - return m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_Version; -} - -#ifndef DACCESS_COMPILE - -USHORT IPCReaderInterface::GetLegacyPublicBlockVersion() -{ - WRAPPER_NO_CONTRACT; - - _ASSERTE(IsLegacyPublicBlockOpen()); - return m_ptrLegacyPublicBlock->m_FullIPCHeaderLegacyPublic.m_header.m_Version; -} - -#endif - -HINSTANCE IPCReaderInterface::GetInstance() -{ - WRAPPER_NO_CONTRACT; - - _ASSERTE(IsLegacyPrivateBlockOpen()); - return m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_hInstance; -} - -USHORT IPCReaderInterface::GetBuildYear() -{ - WRAPPER_NO_CONTRACT; - - _ASSERTE(IsLegacyPrivateBlockOpen()); - return m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_BuildYear; -} - -USHORT IPCReaderInterface::GetBuildNumber() -{ - WRAPPER_NO_CONTRACT; - - _ASSERTE(IsLegacyPrivateBlockOpen()); - return m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_BuildNumber; -} - -PVOID IPCReaderInterface::GetBlockStart() -{ - LIMITED_METHOD_CONTRACT; - - return (PVOID) m_ptrLegacyPrivateBlock; -} - -PCWSTR IPCReaderInterface::GetInstancePath() -{ - WRAPPER_NO_CONTRACT; - - return (PCWSTR) GetLegacyPrivateBlock(eLegacyPrivateIPC_InstancePath); -} - -#endif // FEATURE_IPCMAN diff --git a/src/coreclr/src/ipcman/ipcshared.h b/src/coreclr/src/ipcman/ipcshared.h deleted file mode 100644 index 865509d..0000000 --- a/src/coreclr/src/ipcman/ipcshared.h +++ /dev/null @@ -1,94 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCShared.h -// -// Shared LegacyPrivate utility functions for COM+ IPC operations -// -//***************************************************************************** - -#ifndef _IPCSHARED_H_ -#define _IPCSHARED_H_ - - -#include "ipcenums.h" - - -class SString; - -// This is the name of the file backed session's name on the LS (debuggee) -// Name of the LegacyPrivate (per-process) block. %d resolved to a PID -#define CorLegacyPrivateIPCBlock L"Cor_Private_IPCBlock_%d" -#define CorLegacyPrivateIPCBlockTempV4 L"Cor_Private_IPCBlock_v4_%d" -#define CorLegacyPublicIPCBlock L"Cor_Public_IPCBlock_%d" -#define CorSxSPublicIPCBlock L"Cor_SxSPublic_IPCBlock_%d" -#define CorSxSBoundaryDescriptor L"Cor_CLR_IPCBlock_%d" -#define CorSxSWriterPrivateNamespacePrefix L"Cor_CLR_WRITER" -#define CorSxSReaderPrivateNamespacePrefix L"Cor_CLR_READER" -#define CorSxSVistaPublicIPCBlock L"Cor_SxSPublic_IPCBlock" - -#define CorLegacyPrivateIPCBlock_RS L"CLR_PRIVATE_RS_IPCBlock_%d" -#define CorLegacyPrivateIPCBlock_RSTempV4 L"CLR_PRIVATE_RS_IPCBlock_v4_%d" -#define CorLegacyPublicIPCBlock_RS L"CLR_PUBLIC_IPCBlock_%d" -#define CorSxSPublicIPCBlock_RS L"CLR_SXSPUBLIC_IPCBlock_%d" - -#define CorSxSPublicInstanceName L"%s_p%d_r%d" -#define CorSxSPublicInstanceNameWhidbey L"%s_p%d" - -// NOTE: we cannot just remove this otherwise 'FeatureCoreClr' build breaks -// since this is not defined in old SDK header -#ifndef CREATE_BOUNDARY_DESCRIPTOR_ADD_APPCONTAINER_SID -#define CREATE_BOUNDARY_DESCRIPTOR_ADD_APPCONTAINER_SID 0x1 -#endif -// ENDNOTE - -enum KernelObject -{ - Section, - Event, - PrivateNamespace, - TotalKernelObjects -}; - - -class IPCShared -{ -public: -// Close a handle and pointer to any memory mapped file - static void CloseMemoryMappedFile(HANDLE & hMemFile, void * & pBlock); - -// Based on the pid, write a unique name for a memory mapped file - static void GenerateName(DWORD pid, SString & sName); - static void GenerateNameLegacyTempV4(DWORD pid, SString & sName); - static void GenerateLegacyPublicName(DWORD pid, SString & sName); - - static HRESULT GenerateBlockTableName(DWORD pid, - SString & sName, - HANDLE & pBoundaryDesc, - HANDLE & pPrivateNamespace, - PSID* pSID, - BOOL bCreate); - static HRESULT FreeHandles(HANDLE & hDescriptor, PSID & pSID); - static HRESULT FreeHandles(HANDLE & hBoundaryDescriptor, PSID & pSID, HANDLE & hPrivateNamespace); - static HRESULT CreateWinNTDescriptor(DWORD pid, BOOL bRestrictiveACL, SECURITY_ATTRIBUTES **ppSA, KernelObject whatObject); - static HRESULT CreateWinNTDescriptor(DWORD pid, BOOL bRestrictiveACL, SECURITY_ATTRIBUTES **ppSA, KernelObject whatObject, EDescriptorType descType); - static void DestroySecurityAttributes(SECURITY_ATTRIBUTES *pSA); - -private: - static const int MaxNumberACEs = 5; - static BOOL InitializeGenericIPCAcl(DWORD pid, BOOL bRestrictiveACL, PACL *ppACL, KernelObject whatObject, EDescriptorType descType); - static DWORD GetAccessFlagsForObject(KernelObject whatObject, BOOL bRestrictiveACL); - static HRESULT GetSidForProcess(HINSTANCE hDll, - DWORD pid, - PSID *ppSID, - __deref_out_opt char **ppBufferToFreeByCaller); -}; - -#endif diff --git a/src/coreclr/src/ipcman/ipcsharedsrc.cpp b/src/coreclr/src/ipcman/ipcsharedsrc.cpp deleted file mode 100644 index bb0f46b..0000000 --- a/src/coreclr/src/ipcman/ipcsharedsrc.cpp +++ /dev/null @@ -1,890 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCSharedSrc.cpp -// -// Shared source for COM+ IPC Reader & Writer classes -// -//***************************************************************************** - -#include "stdafx.h" -#include "ipcshared.h" -#include "ipcmanagerinterface.h" - - -#if defined(FEATURE_IPCMAN) - -//----------------------------------------------------------------------------- -// Close a handle and pointer to any memory mapped file -//----------------------------------------------------------------------------- -void IPCShared::CloseMemoryMappedFile(HANDLE & hMemFile, void * & pBlock) -{ - WRAPPER_NO_CONTRACT; - - LOG((LF_CORDB, LL_INFO10, "IPCS::CloseMemoryMappedFile: closing 0x%08x\n", hMemFile)); - - if (pBlock != NULL) { - if (!UnmapViewOfFile(pBlock)) - _ASSERTE(!"UnmapViewOfFile failed"); - pBlock = NULL; - } - - if (hMemFile != NULL) { - CloseHandle(hMemFile); - hMemFile = NULL; - } -} - -//----------------------------------------------------------------------------- -// Based on the pid, write a unique name for a memory mapped file -//----------------------------------------------------------------------------- -void IPCShared::GenerateName(DWORD pid, SString & sName) -{ - WRAPPER_NO_CONTRACT; - - const WCHAR * szFormat = CorLegacyPrivateIPCBlock; - szFormat = L"Global\\" CorLegacyPrivateIPCBlock; - - sName.Printf(szFormat, pid); -} - -//----------------------------------------------------------------------------- -// Based on the pid, write a unique name for a memory mapped file -//----------------------------------------------------------------------------- -void IPCShared::GenerateNameLegacyTempV4(DWORD pid, SString & sName) -{ - WRAPPER_NO_CONTRACT; - - const WCHAR * szFormat = CorLegacyPrivateIPCBlockTempV4; - szFormat = L"Global\\" CorLegacyPrivateIPCBlockTempV4; - - sName.Printf(szFormat, pid); -} - -//----------------------------------------------------------------------------- -// Based on the pid, write a unique name for a memory mapped file -//----------------------------------------------------------------------------- -void IPCShared::GenerateLegacyPublicName(DWORD pid, SString & sName) -{ - WRAPPER_NO_CONTRACT; - - const WCHAR * szFormat = CorLegacyPublicIPCBlock; - szFormat = L"Global\\" CorLegacyPublicIPCBlock; - - sName.Printf(szFormat, pid); -} - -#ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Based on the pid, write a unique name for the IPCBlockTable on Vista and Higher -//----------------------------------------------------------------------------- -HRESULT IPCShared::GenerateBlockTableName(DWORD pid, SString & sName, HANDLE & pBoundaryDesc, HANDLE & pPrivateNamespace, PSID* pSID, BOOL bCreate) -{ - WRAPPER_NO_CONTRACT; - HRESULT hr = E_FAIL; - -#define SIZE 100 - const WCHAR * szFormat = CorSxSPublicIPCBlock; - static HMODULE hKernel32 = NULL; - if(hKernel32 == NULL) - hKernel32 = WszGetModuleHandle(L"kernel32.dll"); - if(hKernel32 == NULL) - { - hr = HRESULT_FROM_GetLastError(); - return hr; - } - //We are using static function pointers so that we dont call GetProcAddress every time - //We know that the Writer will call this function only once and the reader (perfmon) is a single - //threaded App. Therefore its safe to assign static local variables in this case. - typedef WINBASEAPI BOOL (WINAPI ADD_SID_TO_BOUNDARY_DESCRIPTOR)(HANDLE*, PSID); - static ADD_SID_TO_BOUNDARY_DESCRIPTOR * pAddSIDToBoundaryDescriptor = NULL; - - typedef WINBASEAPI HANDLE (WINAPI CREATE_BOUNDARY_DESCRIPTOR)(LPCWSTR,ULONG); - static CREATE_BOUNDARY_DESCRIPTOR * pCreateBoundaryDescriptor = NULL; - - typedef WINBASEAPI HANDLE (WINAPI CREATE_PRIVATE_NAMESPACE )(LPSECURITY_ATTRIBUTES, LPVOID, LPCWSTR); - static CREATE_PRIVATE_NAMESPACE * pCreatePrivateNamespace = NULL; - - typedef WINBASEAPI HANDLE (WINAPI OPEN_PRIVATE_NAMESPACE)(LPVOID,LPCWSTR); - static OPEN_PRIVATE_NAMESPACE * pOpenPrivateNamespace = NULL; - - if(pAddSIDToBoundaryDescriptor == NULL) - pAddSIDToBoundaryDescriptor = (ADD_SID_TO_BOUNDARY_DESCRIPTOR *)GetProcAddress(hKernel32, "AddSIDToBoundaryDescriptor"); - if(pCreateBoundaryDescriptor == NULL) - pCreateBoundaryDescriptor = (CREATE_BOUNDARY_DESCRIPTOR *)GetProcAddress(hKernel32, "CreateBoundaryDescriptorW"); - if(pCreatePrivateNamespace == NULL) - pCreatePrivateNamespace = (CREATE_PRIVATE_NAMESPACE *)GetProcAddress(hKernel32, "CreatePrivateNamespaceW"); - if(pOpenPrivateNamespace==NULL) - pOpenPrivateNamespace = (OPEN_PRIVATE_NAMESPACE *)GetProcAddress(hKernel32, "OpenPrivateNamespaceW"); - _ASSERTE((pAddSIDToBoundaryDescriptor != NULL) && - (pCreateBoundaryDescriptor != NULL) && - (pCreatePrivateNamespace != NULL) && - (pOpenPrivateNamespace != NULL)); - - if ((pAddSIDToBoundaryDescriptor == NULL) || - (pCreateBoundaryDescriptor == NULL) || - (pCreatePrivateNamespace == NULL) || - (pOpenPrivateNamespace == NULL)) - { - return ERROR_PROC_NOT_FOUND; - } - - WCHAR wsz[SIZE]; - swprintf_s(wsz,SIZE, CorSxSBoundaryDescriptor, pid); - - ULONG flags = 0; - if (RunningOnWin8()) - { - // on win8 we specify this flag regardless if the process is inside an appcontainer, the kernel will do the right thing. - // note that for appcontainers this flag is necessary regardless of producer or consumer, ie you can't create a boundary - // descriptor in an appcontainer process without adding the appcontainer SID (the API call will fail). - flags |= CREATE_BOUNDARY_DESCRIPTOR_ADD_APPCONTAINER_SID; - } - - pBoundaryDesc = (*pCreateBoundaryDescriptor)((LPCWSTR)&wsz, flags); - if(!pBoundaryDesc) - { - hr = HRESULT_FROM_GetLastError(); - return hr; - } - SID_IDENTIFIER_AUTHORITY SIDWorldAuth = SECURITY_WORLD_SID_AUTHORITY; - if(!AllocateAndInitializeSid( &SIDWorldAuth, 1,SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, pSID)) - { - hr = HRESULT_FROM_GetLastError(); - return hr; - } - if(!(*pAddSIDToBoundaryDescriptor) (&pBoundaryDesc,*pSID)) - { - hr = HRESULT_FROM_GetLastError(); - return hr; - } - - - if(bCreate) - { - SECURITY_ATTRIBUTES *pSA = NULL; - IPCShared::CreateWinNTDescriptor(pid, FALSE, &pSA, PrivateNamespace, eDescriptor_Public); - pPrivateNamespace = (*pCreatePrivateNamespace)(pSA, (VOID *)(pBoundaryDesc), - (LPCWSTR)CorSxSWriterPrivateNamespacePrefix); - if(!pPrivateNamespace) - { - hr = HRESULT_FROM_GetLastError(); - } - IPCShared::DestroySecurityAttributes(pSA); - - if(!pPrivateNamespace) - { - //if already created by a different version of the runtime we return OK. - if(hr ==HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) - { - hr = S_OK; - } - else - { - return hr; - } - } - } - else - { - pPrivateNamespace = (*pOpenPrivateNamespace)((VOID *)(pBoundaryDesc), (LPCWSTR)CorSxSReaderPrivateNamespacePrefix); - if(!pPrivateNamespace) - { - hr = HRESULT_FROM_GetLastError(); - return hr; - } - } - szFormat = (bCreate ? CorSxSWriterPrivateNamespacePrefix L"\\" CorSxSVistaPublicIPCBlock : CorSxSReaderPrivateNamespacePrefix L"\\" CorSxSVistaPublicIPCBlock); - sName.Printf(szFormat); - hr=S_OK; - - return hr; -} - -#endif - -//----------------------------------------------------------------------------- -// Free's the handle to a boundary descriptor and a SID -//----------------------------------------------------------------------------- -HRESULT IPCShared::FreeHandles(HANDLE & hBoundaryDescriptor, PSID & pSID) -{ - WRAPPER_NO_CONTRACT; - HRESULT hr = S_OK; - if(hBoundaryDescriptor != NULL) - { - static HMODULE hKernel32 = NULL; - if(hKernel32 == NULL) - hKernel32 = WszGetModuleHandle(L"kernel32.dll"); - if(hKernel32 == NULL) - { - hr = HRESULT_FROM_GetLastError(); - return hr; - } - typedef WINBASEAPI VOID (WINAPI DELETE_BOUNDARY_DESCRIPTOR)(HANDLE); - static DELETE_BOUNDARY_DESCRIPTOR * pDeleteBoundaryDescriptor = NULL; - if(pDeleteBoundaryDescriptor == NULL) - pDeleteBoundaryDescriptor = (DELETE_BOUNDARY_DESCRIPTOR *)GetProcAddress(hKernel32, "DeleteBoundaryDescriptor"); - _ASSERTE(pDeleteBoundaryDescriptor != NULL); - if (pDeleteBoundaryDescriptor == NULL) - { - hr = ERROR_PROC_NOT_FOUND; - } - else - { - (*pDeleteBoundaryDescriptor)(hBoundaryDescriptor); - hBoundaryDescriptor = NULL; - - } - } - if(pSID != NULL) - { - FreeSid(pSID); - pSID = NULL; - } - - return hr; -} - -//-------------------------------------------------------------------------------------- -// Free's the handle to a boundary descriptor, a SID and a handle to a privatenamespace -//-------------------------------------------------------------------------------------- -HRESULT IPCShared::FreeHandles(HANDLE & hBoundaryDescriptor, PSID & pSID, HANDLE & hPrivateNamespace) -{ - WRAPPER_NO_CONTRACT; - HRESULT hr = S_OK; - - hr = IPCShared::FreeHandles(hBoundaryDescriptor,pSID); - if(!SUCCEEDED(hr)) - return hr; - if(hPrivateNamespace != NULL) - { - static HMODULE hKernel32 = NULL; - if(hKernel32 == NULL) - hKernel32 = WszGetModuleHandle(L"kernel32.dll"); - if(hKernel32 == NULL) - { - hr = HRESULT_FROM_GetLastError(); - return hr; - } - typedef WINBASEAPI BOOL (WINAPI CLOSE_PRIVATE_NAMESPACE)(HANDLE, ULONG); - static CLOSE_PRIVATE_NAMESPACE * pClosePrivateNamespace; - if(pClosePrivateNamespace == NULL) - pClosePrivateNamespace = (CLOSE_PRIVATE_NAMESPACE *)GetProcAddress(hKernel32, "ClosePrivateNamespace"); - _ASSERTE(pClosePrivateNamespace != NULL); - if (pClosePrivateNamespace == NULL) - { - hr = ERROR_PROC_NOT_FOUND; - } - else - { - BOOL isClosed = (*pClosePrivateNamespace)(hPrivateNamespace,0); - hPrivateNamespace = NULL; - if(!isClosed) - { - hr = HRESULT_FROM_GetLastError(); - } - - } - } - - return hr; -} - -HRESULT IPCShared::CreateWinNTDescriptor(DWORD pid, BOOL bRestrictiveACL, SECURITY_ATTRIBUTES **ppSA, KernelObject whatObject) -{ - WRAPPER_NO_CONTRACT; - - return IPCShared::CreateWinNTDescriptor(pid, bRestrictiveACL, ppSA, whatObject, eDescriptor_Private); -} - -//----------------------------------------------------------------------------- -// Setup a security descriptor for the named kernel objects if we're on NT. -//----------------------------------------------------------------------------- - -HRESULT IPCShared::CreateWinNTDescriptor(DWORD pid, BOOL bRestrictiveACL, SECURITY_ATTRIBUTES **ppSA, KernelObject whatObject, EDescriptorType descType) -{ - WRAPPER_NO_CONTRACT; - - HRESULT hr = NO_ERROR; - - // Gotta have a place to stick the new SA... - if (ppSA == NULL) - { - _ASSERTE(!"Caller must supply ppSA"); - return E_INVALIDARG; - } - - *ppSA = NULL; - - ACL *pACL = NULL; - SECURITY_DESCRIPTOR *pSD = NULL; - SECURITY_ATTRIBUTES *pSA = NULL; - - // Allocate a SD. - _ASSERTE (SECURITY_DESCRIPTOR_MIN_LENGTH == sizeof(SECURITY_DESCRIPTOR)); - pSD = new (nothrow) SECURITY_DESCRIPTOR; - - if (pSD == NULL) - { - hr = E_OUTOFMEMORY; - goto errExit; - } - - // Do basic SD initialization - if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) - { - hr = HRESULT_FROM_GetLastError(); - goto errExit; - } - - // Grab the ACL for the IPC block for the given process - if (!InitializeGenericIPCAcl(pid, bRestrictiveACL, &pACL, whatObject, descType)) - { - hr = E_FAIL; - goto errExit; - } - - // Add the ACL as the DACL for the SD. - if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) - { - hr = HRESULT_FROM_GetLastError(); - goto errExit; - } - - // Allocate a SA. - pSA = new (nothrow) SECURITY_ATTRIBUTES; - - if (pSA == NULL) - { - hr = E_OUTOFMEMORY; - goto errExit; - } - - // Pass out the new SA. - *ppSA = pSA; - - pSA->nLength = sizeof(SECURITY_ATTRIBUTES); - pSA->lpSecurityDescriptor = pSD; - pSA->bInheritHandle = FALSE; - - // uncomment this line if you want to see the DACL being generated. - //DumpSD(pSD); - -errExit: - if (FAILED(hr)) - { - if (pACL != NULL) - { - for(int i = 0; i < pACL->AceCount; i++) - DeleteAce(pACL, i); - - delete [] pACL; - } - - if (pSD != NULL) - delete pSD; - } - - return hr; -} - -//----------------------------------------------------------------------------- -// Helper to destroy the security attributes for the shared memory for a given -// process. -//----------------------------------------------------------------------------- -void IPCShared::DestroySecurityAttributes(SECURITY_ATTRIBUTES *pSA) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // We'll take a NULL param just to be nice. - if (pSA == NULL) - return; - - // Cleanup the DACL in the SD. - SECURITY_DESCRIPTOR *pSD = (SECURITY_DESCRIPTOR*) pSA->lpSecurityDescriptor; - - if (pSD != NULL) - { - // Grab the DACL - BOOL isDACLPresent = FALSE; - BOOL isDefaultDACL = FALSE; - ACL *pACL = NULL; - - BOOL res = GetSecurityDescriptorDacl(pSD, &isDACLPresent, &pACL, &isDefaultDACL); - - // If we got the DACL, then free the stuff inside of it. - if (res && isDACLPresent && (pACL != NULL) && !isDefaultDACL) - { - for(int i = 0; i < pACL->AceCount; i++) - DeleteAce(pACL, i); - - delete [] pACL; - } - - // Free the SD from within the SA. - delete pSD; - } - - // Finally, free the SA. - delete pSA; -} - -//----------------------------------------------------------------------------- -// Given a PID, grab the SID for the owner of the process. -// -// NOTE:: Caller has to free *ppBufferToFreeByCaller. -// This buffer is allocated to hold the PSID return by GetPrcoessTokenInformation. -// The tkOwner field may contain a poniter into this allocated buffer. So we cannot free -// the buffer in GetSidForProcess. -// -//----------------------------------------------------------------------------- -HRESULT IPCShared::GetSidForProcess(HINSTANCE hDll, - DWORD pid, - PSID *ppSID, - __deref_out_opt char **ppBufferToFreeByCaller) -{ - WRAPPER_NO_CONTRACT; - - HRESULT hr = S_OK; - HANDLE hProc = NULL; - HANDLE hToken = NULL; - PSID_IDENTIFIER_AUTHORITY pSID = NULL; - TOKEN_OWNER *ptkOwner = NULL; - DWORD dwRetLength; - - LOG((LF_CORDB, LL_INFO10, "IPCWI::GSFP: GetSidForProcess 0x%x (%d)", pid, pid)); - - // Grab a handle to the target process. - hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); - - *ppBufferToFreeByCaller = NULL; - - if (hProc == NULL) - { - hr = HRESULT_FROM_GetLastError(); - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::GSFP: Unable to get SID for process. " - "OpenProcess(%d) failed: 0x%08x\n", pid, hr)); - - goto ErrorExit; - } - - // Get the pointer to the requested function - FARPROC pProcAddr = GetProcAddress(hDll, "OpenProcessToken"); - - // If the proc address was not found, return error - if (pProcAddr == NULL) - { - hr = HRESULT_FROM_GetLastError(); - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::GSFP: Unable to get SID for process. " - "GetProcAddr (OpenProcessToken) failed: 0x%08x\n", hr)); - - goto ErrorExit; - } - - typedef BOOL WINAPI OPENPROCESSTOKEN(HANDLE, DWORD, PHANDLE); - - // Retrieve a handle of the access token - if (!((OPENPROCESSTOKEN *)pProcAddr)(hProc, TOKEN_QUERY, &hToken)) - { - hr = HRESULT_FROM_GetLastError(); - - LOG((LF_CORDB, LL_INFO100, - "IPCWI::GSFP: OpenProcessToken() failed: 0x%08x\n", hr)); - - goto ErrorExit; - } - - // Get the pointer to the requested function - pProcAddr = GetProcAddress(hDll, "GetTokenInformation"); - - // If the proc address was not found, return error - if (pProcAddr == NULL) - { - hr = HRESULT_FROM_GetLastError(); - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::GSFP: Unable to get SID for process. " - "GetProcAddr (GetTokenInformation) failed: 0x%08x\n", hr)); - - goto ErrorExit; - } - - typedef BOOL GETTOKENINFORMATION(HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, - DWORD, PDWORD); - - // get the required size of buffer - ((GETTOKENINFORMATION *)pProcAddr) (hToken, TokenOwner, NULL, - 0, &dwRetLength); - _ASSERTE (dwRetLength); - - *ppBufferToFreeByCaller = new (nothrow) char [dwRetLength]; - if ((ptkOwner = (TOKEN_OWNER *) *ppBufferToFreeByCaller) == NULL) - { - hr = E_OUTOFMEMORY; - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::GSFP: OutOfMemory... " - "GetTokenInformation() failed.\n")); - - goto ErrorExit; - } - - if (!((GETTOKENINFORMATION *)pProcAddr) (hToken, TokenOwner, (LPVOID)ptkOwner, - dwRetLength, &dwRetLength)) - { - hr = HRESULT_FROM_GetLastError(); - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::GSFP: Unable to get SID for process. " - "GetTokenInformation() failed: 0x%08x\n", hr)); - - goto ErrorExit; - } - - *ppSID = ptkOwner->Owner; - -ErrorExit: - if (hProc != NULL) - CloseHandle(hProc); - - if (hToken != NULL) - CloseHandle(hToken); - - return hr; -} - -/* static */ -DWORD IPCShared::GetAccessFlagsForObject(KernelObject whatObject, BOOL bFullControlACL) -{ - _ASSERTE(whatObject >= 0 && whatObject < TotalKernelObjects); - - DWORD dwAccessFlags = 0; - - if (!bFullControlACL) - { - if (whatObject == Section) - dwAccessFlags = (STANDARD_RIGHTS_ALL | SECTION_MAP_READ) & ~WRITE_DAC & ~WRITE_OWNER & ~DELETE; - else if (whatObject == Event) - dwAccessFlags = (EVENT_ALL_ACCESS) & ~WRITE_DAC & ~WRITE_OWNER & ~DELETE; - else if (whatObject == PrivateNamespace) - dwAccessFlags = FILE_MAP_READ; - } - else - { - _ASSERTE(whatObject != PrivateNamespace); - if (whatObject == Section) - dwAccessFlags = CLR_IPC_GENERIC_RIGHT; - else if (whatObject == Event) - dwAccessFlags = EVENT_ALL_ACCESS; - } - - _ASSERTE(dwAccessFlags != 0); - return dwAccessFlags; -} - - -//----------------------------------------------------------------------------- -// This function will initialize the Access Control List with three -// Access Control Entries: -// The first ACE entry grants all permissions to "Administrators". -// The second ACE grants all permissions to the monitoring users (for perfcounters). -// The third ACE grants all permissions to "Owner" of the target process. -//----------------------------------------------------------------------------- -BOOL IPCShared::InitializeGenericIPCAcl(DWORD pid, BOOL bRestrictiveACL, PACL *ppACL, KernelObject whatObject, EDescriptorType descType) -{ - WRAPPER_NO_CONTRACT; - - struct PermissionStruct - { - PSID rgPSID; - DWORD rgAccessFlags; - } PermStruct[MaxNumberACEs]; - - SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; - HRESULT hr = S_OK; - DWORD dwAclSize; - BOOL returnCode = false; - *ppACL = NULL; - DWORD i; - DWORD cActualACECount = 0; - char *pBufferToFreeByCaller = NULL; - int iSIDforAdmin = -1; - int iSIDforUsers = -1; - int iSIDforLoggingUsers = -1; - - PermStruct[0].rgPSID = NULL; - - HINSTANCE hDll = WszGetModuleHandle(L"advapi32"); - - if (hDll == NULL) - { - LOG((LF_CORDB, LL_INFO10, "IPCWI::IGIPCA: Unable to generate ACL for IPC. LoadLibrary (advapi32) failed.\n")); - return false; - } - _ASSERTE(hDll != NULL); - - // Get the pointer to the requested function - FARPROC pProcAddr = GetProcAddress(hDll, "AllocateAndInitializeSid"); - - // If the proc address was not found, return error - if (pProcAddr == NULL) - { - LOG((LF_CORDB, LL_INFO10, - "IPCWI::IGIPCA: Unable to generate ACL for IPC. " - "GetProcAddr (AllocateAndInitializeSid) failed.\n")); - goto ErrorExit; - } - - typedef BOOL ALLOCATEANDINITIALIZESID(PSID_IDENTIFIER_AUTHORITY, - BYTE, DWORD, DWORD, DWORD, DWORD, - DWORD, DWORD, DWORD, DWORD, PSID *); - - - BOOL bGrantAllAccess = ((descType == eDescriptor_Private) ? TRUE : FALSE); - // Create a SID for the BUILTIN\Administrators group. - // SECURITY_BUILTIN_DOMAIN_RID + DOMAIN_ALIAS_RID_ADMINS = all Administrators. This translates to (A;;GA;;;BA). - if (!((ALLOCATEANDINITIALIZESID *) pProcAddr)(&SIDAuthNT, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &PermStruct[0].rgPSID)) - { - hr = HRESULT_FROM_GetLastError(); - _ASSERTE(SUCCEEDED(hr)); - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::IGIPCA: failed to allocate AdminSid: 0x%08x\n", hr)); - - goto ErrorExit; - } - // GENERIC_ALL access for Administrators - PermStruct[cActualACECount].rgAccessFlags = GetAccessFlagsForObject(whatObject, bGrantAllAccess); - - iSIDforAdmin = cActualACECount; - cActualACECount++; - - // Next, we get the SID for the owner of the current process. - hr = GetSidForProcess(hDll, GetCurrentProcessId(), &(PermStruct[cActualACECount].rgPSID), &pBufferToFreeByCaller); - DWORD accessFlags = 0; - if (whatObject == Section) { - //special case, grant SECTION_MAP_WRITE for current owner just to support inProc SxS. - accessFlags = GetAccessFlagsForObject(whatObject, bGrantAllAccess) | SECTION_MAP_WRITE; - } - else { - accessFlags = GetAccessFlagsForObject(whatObject, bGrantAllAccess); - } - PermStruct[cActualACECount].rgAccessFlags = accessFlags; - - // Don't fail out if we cannot get the SID for the owner of the current process. In this case, the - // share memory block will be created with only Admin (and optionall "Users") permissions. - // Currently we discovered the anonymous user doesn't have privilege to call OpenProcess. Without OpenProcess, - // we cannot get the SID... - // - if (SUCCEEDED(hr)) - { - cActualACECount++; - } -#if _DEBUG - else - LOG((LF_CORDB, LL_INFO100, "IPCWI::IGIPCA: GetSidForProcess() failed: 0x%08x\n", hr)); -#endif // _DEBUG - - - if (descType == eDescriptor_Public) - { - DWORD dwRet = ((ALLOCATEANDINITIALIZESID *) pProcAddr)(&SIDAuthNT, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_MONITORING_USERS, - 0, 0, 0, 0, 0, 0, - &PermStruct[cActualACECount].rgPSID); - - if (dwRet) - { - // "Users" shouldn't be able to write to block, delete object, change DACLs, or change ownership - PermStruct[cActualACECount].rgAccessFlags = GetAccessFlagsForObject(whatObject, FALSE); - - iSIDforUsers = cActualACECount; - cActualACECount++; - } - else - { - hr = HRESULT_FROM_GetLastError(); - _ASSERTE(SUCCEEDED(hr)); - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::IGIPCA: failed to allocate Users Sid: 0x%08x\n", hr)); - - // non-fatal error, so don't goto errorexit - } - - dwRet = ((ALLOCATEANDINITIALIZESID *) pProcAddr)(&SIDAuthNT, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_LOGGING_USERS, - 0, 0, 0, 0, 0, 0, - &PermStruct[cActualACECount].rgPSID); - if (dwRet) - { - PermStruct[cActualACECount].rgAccessFlags = GetAccessFlagsForObject(whatObject, FALSE); - - iSIDforLoggingUsers = cActualACECount; - cActualACECount++; - } - else - { - hr = HRESULT_FROM_GetLastError(); - _ASSERTE(SUCCEEDED(hr)); - - LOG((LF_CORDB, LL_INFO10, - "IPCWI::IGIPCA: failed to allocate Domain Logging Users Sid: 0x%08x\n", hr)); - - // non-fatal error, so don't goto errorexit - } - - } - - _ASSERTE(cActualACECount <= MaxNumberACEs); - - // Now, create an Initialize an ACL and add the ACE entries to it. NOTE: We're not using "SetEntriesInAcl" because - // it loads a bunch of other dlls which can be avoided by using this roundabout way!! - - // Get the pointer to the requested function - pProcAddr = GetProcAddress(hDll, "InitializeAcl"); - - // If the proc address was not found, return error - if (pProcAddr == NULL) - { - LOG((LF_CORDB, LL_INFO10, - "IPCWI::IGIPCA: Unable to generate ACL for IPC. " - "GetProcAddr (InitializeAcl) failed.\n")); - goto ErrorExit; - } - - // Also calculate the memory required for ACE entries in the ACL using the - // following method: - // "sizeof (ACCESS_ALLOWED_ACE) - sizeof (ACCESS_ALLOWED_ACE.SidStart) + GetLengthSid (pAceSid);" - - dwAclSize = sizeof (ACL) + (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD)) * cActualACECount; - - for (i = 0; i < cActualACECount; i++) - { - dwAclSize += GetLengthSid(PermStruct[i].rgPSID); - } - - // now allocate memory - if ((*ppACL = (PACL) new (nothrow) char[dwAclSize]) == NULL) - { - LOG((LF_CORDB, LL_INFO10, "IPCWI::IGIPCA: OutOfMemory... 'new Acl' failed.\n")); - - goto ErrorExit; - } - - typedef BOOL INITIALIZEACL(PACL, DWORD, DWORD); - - if (!((INITIALIZEACL *)pProcAddr)(*ppACL, dwAclSize, ACL_REVISION)) - { - hr = HRESULT_FROM_GetLastError(); - - LOG((LF_CORDB, LL_INFO100, - "IPCWI::IGIPCA: InitializeACL() failed: 0x%08x\n", hr)); - - goto ErrorExit; - } - - // Get the pointer to the requested function - pProcAddr = GetProcAddress(hDll, "AddAccessAllowedAce"); - - // If the proc address was not found, return error - if (pProcAddr == NULL) - { - LOG((LF_CORDB, LL_INFO10, - "IPCWI::IGIPCA: Unable to generate ACL for IPC. " - "GetProcAddr (AddAccessAllowedAce) failed.\n")); - goto ErrorExit; - } - - typedef BOOL ADDACCESSALLOWEDACE(PACL, DWORD, DWORD, PSID); - - for (i=0; i < cActualACECount; i++) - { - if (!((ADDACCESSALLOWEDACE *)pProcAddr)(*ppACL, - ACL_REVISION, - PermStruct[i].rgAccessFlags, - PermStruct[i].rgPSID)) - - { - hr = HRESULT_FROM_GetLastError(); - - LOG((LF_CORDB, LL_INFO100, - "IPCWI::IGIPCA: AddAccessAllowedAce() failed: 0x%08x\n", hr)); - goto ErrorExit; - } - } - - returnCode = true; - goto NormalExit; - - -ErrorExit: - returnCode = FALSE; - - if (*ppACL) - { - delete [] (*ppACL); - *ppACL = NULL; - } - -NormalExit: - - if (pBufferToFreeByCaller != NULL) - delete [] pBufferToFreeByCaller; - - // Get the pointer to the requested function - pProcAddr = GetProcAddress(hDll, "FreeSid"); - - // If the proc address was not found, return error - if (pProcAddr == NULL) - { - LOG((LF_CORDB, LL_INFO10, - "IPCWI::IGIPCA: Unable to generate ACL for IPC. " - "GetProcAddr (FreeSid) failed.\n")); - return false; - } - - typedef BOOL FREESID(PSID); - - // Free the SID created earlier. Function does not return a value. - if( iSIDforAdmin != -1 ) - ((FREESID *) pProcAddr)(PermStruct[iSIDforAdmin].rgPSID); - - // free the SID for "Users" - if (iSIDforUsers != -1) - ((FREESID *) pProcAddr)(PermStruct[iSIDforUsers].rgPSID); - - // free the SID for "Performance Logging Users" - if (iSIDforLoggingUsers != -1) - ((FREESID *) pProcAddr)(PermStruct[iSIDforLoggingUsers].rgPSID); - - return returnCode; -} - -#endif // FEATURE_IPCMAN diff --git a/src/coreclr/src/ipcman/ipcwriterimpl.cpp b/src/coreclr/src/ipcman/ipcwriterimpl.cpp deleted file mode 100644 index b2d5ba2..0000000 --- a/src/coreclr/src/ipcman/ipcwriterimpl.cpp +++ /dev/null @@ -1,861 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: IPCWriterImpl.cpp -// -// Implementation for COM+ memory mapped file writing -// -//***************************************************************************** - -#include "stdafx.h" - -#include "ipcmanagerinterface.h" -#include "ipcheader.h" -#include "ipcshared.h" -#include "ipcmanagerimpl.h" - -// Declared in threads.h, but including that file seems to cause problems -DWORD GetRuntimeId(); - -#include - -#if defined(TIA64) -#define IA64MemoryBarrier() MemoryBarrier() -#else -#define IA64MemoryBarrier() -#endif - -#if defined(FEATURE_IPCMAN) - -const USHORT BuildYear = VER_ASSEMBLYMAJORVERSION; -const USHORT BuildNumber = VER_ASSEMBLYBUILD; - -// Import from mscorwks.obj -HINSTANCE GetModuleInst(); - -#if defined(_DEBUG) -static void DumpSD(PSECURITY_DESCRIPTOR sd) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - HINSTANCE hDll = WszGetModuleHandle(L"advapi32"); - - // Get the pointer to the requested function - FARPROC pProcAddr = GetProcAddress(hDll, "ConvertSecurityDescriptorToStringSecurityDescriptorW"); - - // If the proc address was not found, return error - if (pProcAddr == NULL) - { - LOG((LF_CORDB, LL_INFO10, - "IPCWI::DumpSD: GetProcAddr (ConvertSecurityDescriptorToStringSecurityDescriptorW) failed.\n")); - goto ErrorExit; - } - - typedef BOOL WINAPI SDTOSTR(PSECURITY_DESCRIPTOR, DWORD, SECURITY_INFORMATION, LPSTR *, PULONG); - - LPSTR str = NULL; - - if (!((SDTOSTR*)pProcAddr)(sd, SDDL_REVISION_1, 0xF, &str, NULL)) - { - LOG((LF_CORDB, LL_INFO10, - "IPCWI::DumpSD: ConvertSecurityDescriptorToStringSecurityDescriptorW failed %d\n", - GetLastError())); - goto ErrorExit; - } - - fprintf(stderr, "SD for IPC: %S\n", str); - LOG((LF_CORDB, LL_INFO10, "IPCWI::DumpSD: SD for IPC: %s\n", str)); - - (LocalFree)(str); - -ErrorExit: - return; -} -#endif // _DEBUG - -//----------------------------------------------------------------------------- -// Generic init -//----------------------------------------------------------------------------- -HRESULT IPCWriterInterface::Init() -{ - LIMITED_METHOD_CONTRACT; - - // Nothing to do anymore in here... - return S_OK; -} - -//----------------------------------------------------------------------------- -// Generic publish -//----------------------------------------------------------------------------- -void IPCWriterInterface::Publish() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - IA64MemoryBarrier(); - - // Set the appropriate bit to mark the LegacyPrivate IPC block as initialized - if (m_ptrLegacyPrivateBlock != NULL) - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_Flags |= IPC_FLAG_INITIALIZED; - - // Set the appropriate bit to mark the SxS Public IPC block as initialized - if (m_pBlock != NULL) - m_pBlock->m_Header.m_Flags |= IPC_FLAG_INITIALIZED; -} - - -#ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Generic terminate -//----------------------------------------------------------------------------- -void IPCWriterInterface::Terminate() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - LOG((LF_CORDB, LL_INFO10, "IPCWI::Terminate: Writer: closing 0x%08x and 0x%08x\n", m_handleLegacyPrivateBlock, m_handleBlockTable)); - - if (m_ptrLegacyPrivateBlock == m_pIPCBackupBlockLegacyPrivate) - { - // This is the case that we allocate a block of memory and pretending it is the map file view, - // so we don't need to unmap the file view on m_ptrLegacyPrivateBlock - m_ptrLegacyPrivateBlock = NULL; - } - - IPCShared::CloseMemoryMappedFile(m_handleLegacyPrivateBlock, (void*&) m_ptrLegacyPrivateBlock); - - if (m_pBlockTable == m_pBackupBlock) - { - // This is the case that we allocate a block of memory and pretending it is the map file view, - // so we don't need to unmap the file view on m_pBlock - m_pBlockTable = NULL; - m_pBlock = NULL; - } - else - { - BOOL fFreedChunk = TryFreeBlock(); - - // Release our handle to the shared memory region - IPCShared::CloseMemoryMappedFile(m_handleBlockTable, (void*&) m_pBlockTable); - - m_pBlockTable = NULL; - m_pBlock = NULL; - } - - // If we have a cached SA for this process, go ahead and clean it up. - if (m_cachedPrivateDescriptor != NULL) - { - // DestroySecurityAttributes won't destroy our cached SA, so save the ptr to the SA and clear the cached value - // before calling it. - SECURITY_ATTRIBUTES *pSA = m_cachedPrivateDescriptor; - m_cachedPrivateDescriptor = NULL; - DestroySecurityAttributes(pSA); - } -} - -#endif - -//----------------------------------------------------------------------------- -// Have ctor zero everything out -//----------------------------------------------------------------------------- -IPCWriterImpl::IPCWriterImpl() -{ - LIMITED_METHOD_CONTRACT; - - // Cache pointers to sections - m_pPerf = NULL; - m_pAppDomain = NULL; - m_pInstancePath = NULL; - - // Mem-Mapped file for LegacyPrivate Block - m_handleLegacyPrivateBlock = NULL; - m_ptrLegacyPrivateBlock = NULL; - - // Mem-Mapped file for SxS Public Block - m_handleBlockTable = NULL; - m_pBlock = NULL; - m_pBlockTable = NULL; - m_handleBoundaryDesc = NULL; - m_handlePrivateNamespace = NULL; - m_pSID = NULL; - - // Security - m_cachedPrivateDescriptor = NULL; - - m_pIPCBackupBlockLegacyPrivate = NULL; - m_pBackupBlock = NULL; -} - -//----------------------------------------------------------------------------- -// Assert that everything was already shutdown by a call to terminate. -// Shouldn't be anything left to do in the dtor -//----------------------------------------------------------------------------- -IPCWriterImpl::~IPCWriterImpl() -{ -#ifndef DACCESS_COMPILE - LIMITED_METHOD_CONTRACT; - - _ASSERTE(!IsLegacyPrivateBlockOpen()); - if (m_pIPCBackupBlockLegacyPrivate) - { - delete [] ((BYTE *)m_pIPCBackupBlockLegacyPrivate); - } - - _ASSERTE(!IsBlockTableOpen()); - //Note: m_handlePrivateNamespace is not NULL. This is because we do not Close the handle to PNS and instead - //let the OS close it for us. This is because if we close the PNS, then the reader(perfmon) cannot open this PNS. - _ASSERTE(!m_handleBoundaryDesc); - _ASSERTE(!m_pSID); - if (m_pBackupBlock) - { - delete [] ((BYTE *)m_pBackupBlock); - } -#endif // DACCESS_COMPILE -} - -//----------------------------------------------------------------------------- -// Accessors to get each clients' blocks -//----------------------------------------------------------------------------- -struct PerfCounterIPCControlBlock * IPCWriterInterface::GetPerfBlock() -{ - LIMITED_METHOD_CONTRACT; - return m_pPerf; -} - -struct AppDomainEnumerationIPCBlock * IPCWriterInterface::GetAppDomainBlock() -{ - LIMITED_METHOD_CONTRACT; - return m_pAppDomain; -} - -//----------------------------------------------------------------------------- -// Helper to destroy the security attributes for the shared memory for a given -// process. -//----------------------------------------------------------------------------- -void IPCWriterInterface::DestroySecurityAttributes(SECURITY_ATTRIBUTES *pSA) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Don't destroy our cached SA! - if (pSA == m_cachedPrivateDescriptor) - return; - - IPCShared::DestroySecurityAttributes(pSA); -} - -/************************************ IPC BLOCK TABLE ************************************/ - -#ifndef DACCESS_COMPILE - -BOOL IPCWriterInterface::TryAllocBlock(DWORD numRetries) -{ - _ASSERTE(m_pBlock == NULL); - - for (DWORD i = 0; i < IPC_NUM_BLOCKS_IN_TABLE; ++i) - { - m_pBlock = m_pBlockTable->GetBlock(i); - - IPCHeaderLockHolder lockHolder(m_pBlock->m_Header); - if (lockHolder.TryGetLock(numRetries) == FALSE) - continue; - - DWORD runtimeId = m_pBlock->m_Header.m_RuntimeId; - if (runtimeId == 0) - { - // Set the runtime ID - m_pBlock->m_Header.m_RuntimeId = GetRuntimeId(); - - // Set up the IPC header while we - // still hold the lock - CreateIPCHeader(); - - return TRUE; - } - } - - m_pBlock = NULL; - return FALSE; -} - -BOOL IPCWriterInterface::TryFreeBlock() -{ - _ASSERTE(m_pBlock != NULL); - - DWORD retriesLeft = 100; - DWORD dwSwitchCount = 0; - - IPCHeaderLockHolder lockHolder(m_pBlock->m_Header); - - // Try getting the lock, and retry up to 100 times. - // If lock cannot be acquired, give up and return FALSE - - if (lockHolder.TryGetLock(100) == FALSE) - return FALSE; - - // If the lock was acquired successfully, mark this - // block as free, release the lock, and return TRUE - - m_pBlock->m_Header.m_RuntimeId = 0; - m_pBlock = NULL; - - return TRUE; -} - - -//----------------------------------------------------------------------------- -// Open our SxS Public IPC block on the given pid. -//----------------------------------------------------------------------------- -HRESULT IPCWriterInterface::CreateSxSPublicBlockOnPid(DWORD pid) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Note: if our SxS Public block is open, we shouldn't be creating it again. - _ASSERTE(!IsBlockTableOpen()); - - if (IsBlockTableOpen()) - { - // if we goto errExit, it will close the file. We don't want that. - return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - } - - - // Note: if PID != GetCurrentProcessId(), we're expected to be opening - // someone else's IPCBlock, so if it doesn't exist, we should assert. - HRESULT hr = S_OK; - - SECURITY_ATTRIBUTES *pSA = NULL; - - EX_TRY - { - // Grab the SA - SString szMemFileName; - hr = GetSxSPublicSecurityAttributes(pid, &pSA); - if (FAILED(hr)) - goto failedToGetBlock; - - hr = IPCShared::GenerateBlockTableName(pid, szMemFileName, m_handleBoundaryDesc, m_handlePrivateNamespace, &m_pSID, TRUE); - if (FAILED(hr)) - goto failedToGetBlock; - - BOOL openedExistingBlock = FALSE; - - m_handleBlockTable = NULL; - - // If unsuccessful, don't ever bail out. - if (m_handleBlockTable != NULL) - { - // Get the pointer - must get it even if ERROR_ALREADY_EXISTS, - // since the IPC block is allowed to already exist if there is - // another runtime in the process. - m_pBlockTable = (IPCControlBlockTable *) MapViewOfFile(m_handleBlockTable, - FILE_MAP_ALL_ACCESS, - 0, 0, 0); - // If the IPC Block already exists, then we need to check its size and other - // properties. This is needed because a low privledged user may have spoofed - // a block with the same name before the CLR started. - - if (m_pBlockTable != NULL && openedExistingBlock) - { - // If the BlockTable does not fit in this memory region, - // then it is not safe to use - //The following is a security check to ensure that incase the BlockTable was opened by a - //malicious user we simply commit the block table to ensure that its of the required size4 - PTR_IPCControlBlockTable pBlockTable = (PTR_IPCControlBlockTable) ClrVirtualAlloc(m_pBlockTable,sizeof(IPCControlBlockTable),MEM_COMMIT, PAGE_READWRITE); - if(pBlockTable == NULL || pBlockTable != m_pBlockTable) - { - goto failedToGetBlock; - } - } - } - - BOOL fGotBlock = FALSE; - - // If opening the shared memory block failed, then we need to go down an error path - if (m_pBlockTable == NULL) - goto failedToGetBlock; - - // Try allocating a chunk by iterating over the chunks; - // if a chunk is locked, don't spin waiting on the lock - fGotBlock = TryAllocBlock(0); - - // If we failed to allocate a chunk, try iterating over the chunks again, - // but this time if a chunk is locked, spin for a while to wait on the lock - if (!fGotBlock) - fGotBlock = TryAllocBlock(100); - - // If we succeeded in allocating a chunk, we're done - if (fGotBlock) - { - _ASSERTE(m_pBlock != NULL); - goto done; - } - - // If we failed to allocate a chunk, so we need to do some - // cleanup and set up a "backup" block. When we go into this - // code path, our perf counters won't work. But our code will - // continue to run. - - -failedToGetBlock: - - // Release our handle to the shared memory region - if(m_pBlockTable != NULL) - IPCShared::CloseMemoryMappedFile(m_handleBlockTable, (void*&) m_pBlockTable); - - // Set all out SxSPublic pointers to NULL - m_pBlockTable = NULL; - m_pBlock = NULL; - - // Allocate a "backup" block - DWORD arraySize = sizeof(IPCControlBlockTable); - m_pBackupBlock = (IPCControlBlockTable *) new BYTE[arraySize]; - - // Assert that allocation succeeded - _ASSERTE(m_pBackupBlock != NULL); - - // Zero out the backup block - ZeroMemory(m_pBackupBlock, arraySize); - m_pBlockTable = m_pBackupBlock; - - // Since we are allocating a chunk from the backup block, there - // should be no contention, and we should always succeed - fGotBlock = TryAllocBlock(0); - _ASSERTE(fGotBlock); - _ASSERTE(m_pBlock != NULL); - -done: - - ; - } - EX_CATCH - { - Exception *e = GET_EXCEPTION(); - hr = e->GetHR(); - if (hr == S_OK) - { - hr = E_FAIL; - } - } - EX_END_CATCH(SwallowAllExceptions); - - if (!SUCCEEDED(hr)) - { - IPCShared::CloseMemoryMappedFile(m_handleBlockTable, (void*&)m_pBlock); - } - DestroySecurityAttributes(pSA); - if(!SUCCEEDED(IPCShared::FreeHandles(m_handleBoundaryDesc,m_pSID))) - { - hr = E_FAIL; - } - - return hr; -} - -//----------------------------------------------------------------------------- -// Return the security attributes for the shared memory for a given process. -//----------------------------------------------------------------------------- -HRESULT IPCWriterInterface::GetSxSPublicSecurityAttributes(DWORD pid, SECURITY_ATTRIBUTES **ppSA) -{ - WRAPPER_NO_CONTRACT; - return CreateWinNTDescriptor(pid, ppSA, eDescriptor_Public); -} - - -//----------------------------------------------------------------------------- -// Setup a security descriptor for the named kernel objects if we're on NT. -//----------------------------------------------------------------------------- -HRESULT IPCWriterImpl::CreateWinNTDescriptor(DWORD pid, SECURITY_ATTRIBUTES **ppSA, EDescriptorType descType) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - HRESULT hr = NO_ERROR; - *ppSA = NULL; - - // If the caller wants the private descriptor for the current process - // and a cached copy exists, return the cached copy - if (descType == eDescriptor_Private && m_cachedPrivateDescriptor != NULL && pid == GetCurrentProcessId()) - { - *ppSA = m_cachedPrivateDescriptor; - return hr; - } - - hr = IPCShared::CreateWinNTDescriptor(pid, (descType == eDescriptor_Private ? TRUE : FALSE), ppSA, Section, descType); - - // Cache the private descriptor for the current process. - // We do not cache the public descriptor because it isn't - // used frequently. - if (descType == eDescriptor_Private && pid == GetCurrentProcessId()) - m_cachedPrivateDescriptor = *ppSA; - - return hr; -} - -//----------------------------------------------------------------------------- -// Helper: Fill out a directory entry. -//----------------------------------------------------------------------------- -void IPCWriterImpl::WriteEntryHelper(EIPCClient eClient, - DWORD offs, - DWORD size) -{ - LIMITED_METHOD_CONTRACT; - - m_pBlock->m_Header.m_table[eClient].m_Offset = offs; - m_pBlock->m_Header.m_table[eClient].m_Size = size; -} - -//----------------------------------------------------------------------------- -// Initialize the header for our SxS public IPC block -//----------------------------------------------------------------------------- -void IPCWriterImpl::CreateIPCHeader() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - -#if defined(_TARGET_X86_) - m_pBlock->m_Header.m_Flags = IPC_FLAG_USES_FLAGS | IPC_FLAG_X86; -#else - m_pBlock->m_Header.m_Flags = IPC_FLAG_USES_FLAGS; -#endif - - // Stamp the IPC block with the version - m_pBlock->m_Header.m_Version = VER_IPC_BLOCK; - m_pBlock->m_Header.m_blockSize = SXSPUBLIC_IPC_SIZE_NO_PADDING; - - m_pBlock->m_Header.m_BuildYear = BuildYear; - m_pBlock->m_Header.m_BuildNumber = BuildNumber; - - m_pBlock->m_Header.m_numEntries = eIPC_MAX; - - // - // Fill out directory (offset and size of each block). - // First fill in the used entries. - // - - WriteEntryHelper(eIPC_PerfCounters, - offsetof(IPCControlBlock, m_perf), - sizeof(PerfCounterIPCControlBlock)); - - // Cache our client pointers - m_pPerf = &(m_pBlock->m_perf); -} - -#endif - -/*********************************** LEGACY FUNCTIONS *********************************** - * - * We plan to remove the LegacyPrivate block in the near future. However, the debugger - * still currently relies on the LegacyPrivate block for AppDomain enumeration, and we - * cannot rip out the LegacyPrivate block until the debugger is changed accordingly. - * - ****************************************************************************************/ - -#ifndef DACCESS_COMPILE - - -//----------------------------------------------------------------------------- -// Open our LegacyPrivate IPC block on the given pid. -//----------------------------------------------------------------------------- -HRESULT IPCWriterInterface::CreateLegacyPrivateBlockTempV4OnPid(DWORD pid, BOOL inService, HINSTANCE *phInstIPCBlockOwner) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Init the IPC block owner HINSTANCE to 0. - *phInstIPCBlockOwner = 0; - - // Note: if our LegacyPrivate block is open, we shouldn't be creating it again. - _ASSERTE(!IsLegacyPrivateBlockOpen()); - - if (IsLegacyPrivateBlockOpen()) - { - // if we goto errExit, it will close the file. We don't want that. - return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - } - - // Note: if PID != GetCurrentProcessId(), we're expected to be opening - // someone else's IPCBlock, so if it doesn't exist, we should assert. - HRESULT hr = S_OK; - - SECURITY_ATTRIBUTES *pSA = NULL; - - EX_TRY - { - // Grab the SA - hr = CreateWinNTDescriptor(pid, &pSA, eDescriptor_Private); - if (FAILED(hr)) - ThrowHR(hr); - - SString szMemFileName; - - IPCShared::GenerateNameLegacyTempV4(pid, szMemFileName); - - // Connect the handle - m_handleLegacyPrivateBlock = WszCreateFileMapping(INVALID_HANDLE_VALUE, - pSA, - PAGE_READWRITE, - 0, - sizeof(LegacyPrivateIPCControlBlock), - szMemFileName); - - DWORD dwFileMapErr = GetLastError(); - - LOG((LF_CORDB, LL_INFO10, "IPCWI::CPBOP: CreateFileMapping of %S, handle = 0x%08x, pid = 0x%8.8x GetLastError=%d\n", - szMemFileName.GetUnicode(), m_handleLegacyPrivateBlock, pid, GetLastError())); - - // If unsuccessful, don't ever bail out. - if (m_handleLegacyPrivateBlock != NULL && dwFileMapErr != ERROR_ALREADY_EXISTS) - { - m_ptrLegacyPrivateBlock = (LegacyPrivateIPCControlBlock *) MapViewOfFile(m_handleLegacyPrivateBlock, - FILE_MAP_ALL_ACCESS, - 0, 0, 0); - } - - if (m_ptrLegacyPrivateBlock == NULL) - { - // when we go into this code path, our debugging and perf counter won't work. But - // our managed code will continue to run. - SIZE_T cbLen = sizeof(LegacyPrivateIPCControlBlock); - m_pIPCBackupBlockLegacyPrivate = (LegacyPrivateIPCControlBlock *) new BYTE[cbLen]; - _ASSERTE(m_pIPCBackupBlockLegacyPrivate != NULL); // throws on OOM. - - ZeroMemory(m_pIPCBackupBlockLegacyPrivate, cbLen); // simulate that OS zeros out memory - m_ptrLegacyPrivateBlock = m_pIPCBackupBlockLegacyPrivate; - } - - // Hook up each sections' pointers - CreateLegacyPrivateIPCHeader(); - } - EX_CATCH - { - Exception *e = GET_EXCEPTION(); - hr = e->GetHR(); - if (hr == S_OK) - { - hr = E_FAIL; - } - } - EX_END_CATCH(SwallowAllExceptions); - - if (!SUCCEEDED(hr)) - { - IPCShared::CloseMemoryMappedFile(m_handleLegacyPrivateBlock, (void*&)m_ptrLegacyPrivateBlock); - } - DestroySecurityAttributes(pSA); - - return hr; -} - -//----------------------------------------------------------------------------- -// ReDacl our LegacyPrivate block after it has been created. -//----------------------------------------------------------------------------- -HRESULT IPCWriterInterface::ReDaclLegacyPrivateBlock(PSECURITY_DESCRIPTOR pSecurityDescriptor) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - if (!IsLegacyPrivateBlockOpen()) - { - // nothing to reDACL. - return S_OK; - } - - // note that this call will succeed only if we are the owner of this LegacyPrivate block. - // That is this call will fail if you call from debugger RS. If this is needed in the - // future, you can add WRITE_DAC access when we open LegacyPrivate block on the debugger RS. - // - if (SetKernelObjectSecurity(m_handleLegacyPrivateBlock, DACL_SECURITY_INFORMATION, pSecurityDescriptor) == 0) - { - // failed! - return HRESULT_FROM_GetLastError(); - } - - return S_OK; -} - -//----------------------------------------------------------------------------- -// Helper: Fill out a directory entry. -//----------------------------------------------------------------------------- -void IPCWriterImpl::WriteEntryHelper(ELegacyPrivateIPCClient eClient, - DWORD offs, - DWORD size) -{ - LIMITED_METHOD_CONTRACT; - - if (offs != EMPTY_ENTRY_OFFSET) - { - // The incoming offset is the actual data structure offset - // but the directory is relative to the end of the full header - // (on v1.2) so subtract that out. - - DWORD offsetBase = (DWORD)Internal_GetOffsetBaseLegacyPrivate(*m_ptrLegacyPrivateBlock); - _ASSERTE(offs >= offsetBase); - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_table[eClient].m_Offset = (offs - offsetBase); - } - else - { - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_table[eClient].m_Offset = offs; - } - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_table[eClient].m_Size = size; -} - -//----------------------------------------------------------------------------- -// Initialize the header for our LegacyPrivate IPC block -//----------------------------------------------------------------------------- -void IPCWriterImpl::CreateLegacyPrivateIPCHeader() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Set the flags - -#if defined(_TARGET_X86_) - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_Flags = IPC_FLAG_USES_FLAGS | IPC_FLAG_X86; -#else - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_Flags = IPC_FLAG_USES_FLAGS; -#endif - - // Stamp the IPC block with the version - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_Version = VER_LEGACYPRIVATE_IPC_BLOCK; - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_blockSize = sizeof(LegacyPrivateIPCControlBlock); - - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_hInstance = GetModuleInst(); - - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_BuildYear = BuildYear; - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_BuildNumber = BuildNumber; - - m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_numEntries = eLegacyPrivateIPC_MAX; - - // - // Fill out directory (offset and size of each block). - // First fill in the used entries. - // - - // Even though this first entry is obsolete, it needs to remain - // here for binary compatibility and can't be marked empty/obsolete - // as long as m_perf exists in the struct. - WriteEntryHelper(eLegacyPrivateIPC_PerfCounters, - offsetof(LegacyPrivateIPCControlBlock, m_perf), - sizeof(PerfCounterIPCControlBlock)); - - WriteEntryHelper(eLegacyPrivateIPC_AppDomain, - offsetof(LegacyPrivateIPCControlBlock, m_appdomain), - sizeof(AppDomainEnumerationIPCBlock)); - WriteEntryHelper(eLegacyPrivateIPC_InstancePath, - offsetof(LegacyPrivateIPCControlBlock, m_instancePath), - sizeof(m_ptrLegacyPrivateBlock->m_instancePath)); - - // - // Now explicitly mark the unused entries as empty. - // - - WriteEntryHelper(eLegacyPrivateIPC_Obsolete_Debugger, - EMPTY_ENTRY_OFFSET, EMPTY_ENTRY_SIZE); - WriteEntryHelper(eLegacyPrivateIPC_Obsolete_ClassDump, - EMPTY_ENTRY_OFFSET, EMPTY_ENTRY_SIZE); - WriteEntryHelper(eLegacyPrivateIPC_Obsolete_MiniDump, - EMPTY_ENTRY_OFFSET, EMPTY_ENTRY_SIZE); - WriteEntryHelper(eLegacyPrivateIPC_Obsolete_Service, - EMPTY_ENTRY_OFFSET, EMPTY_ENTRY_SIZE); - - // Cache our client pointers - m_pAppDomain = &(m_ptrLegacyPrivateBlock->m_appdomain); - m_pInstancePath = m_ptrLegacyPrivateBlock->m_instancePath; -} - -PCWSTR IPCWriterInterface::GetInstancePath() -{ - LIMITED_METHOD_CONTRACT; - - _ASSERTE(IsLegacyPrivateBlockOpen()); - return m_pInstancePath; -} - -#endif - -PTR_VOID IPCWriterInterface::GetBlockStart() -{ - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - - return m_ptrLegacyPrivateBlock; -} - -DWORD IPCWriterInterface::GetBlockSize() -{ - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - - _ASSERTE(IsLegacyPrivateBlockOpen()); - return m_ptrLegacyPrivateBlock->m_FullIPCHeader.m_header.m_blockSize; -} - -PTR_VOID IPCWriterInterface::GetBlockTableStart() -{ - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - - return m_pBlockTable; -} - -DWORD IPCWriterInterface::GetBlockTableSize() -{ - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - - _ASSERTE(IsBlockTableOpen()); - return IPC_BLOCK_TABLE_SIZE; -} - -#endif // FEATURE_IPCMAN diff --git a/src/coreclr/src/ipcman/stdafx.cpp b/src/coreclr/src/ipcman/stdafx.cpp deleted file mode 100644 index 89a1764..0000000 --- a/src/coreclr/src/ipcman/stdafx.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -#include "stdafx.h" diff --git a/src/coreclr/src/ipcman/stdafx.h b/src/coreclr/src/ipcman/stdafx.h deleted file mode 100644 index bb3a576..0000000 --- a/src/coreclr/src/ipcman/stdafx.h +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// ==++== -// - -// -// ==--== -//***************************************************************************** -// File: src\IPCMan\StdAfx.h -// -// Precompiled header for COM+ IPC Manager -// -//***************************************************************************** - -#include -#include -#include -#include -#include -#include -#include -#include -#include "utilcode.h" -#include "ex.h" -#include "corpriv.h" -#include "warningcontrol.h" -#include "log.h" diff --git a/src/coreclr/src/utilcode/dacutil.cpp b/src/coreclr/src/utilcode/dacutil.cpp index c26f802..03aaa93 100644 --- a/src/coreclr/src/utilcode/dacutil.cpp +++ b/src/coreclr/src/utilcode/dacutil.cpp @@ -13,9 +13,6 @@ #include #include #include -#ifdef FEATURE_IPCMAN -#include -#endif // FEATURE_IPCMAN //---------------------------------------------------------------------------- // diff --git a/src/coreclr/src/utilcode/securityutil.cpp b/src/coreclr/src/utilcode/securityutil.cpp index b79d3ea..47e4704 100644 --- a/src/coreclr/src/utilcode/securityutil.cpp +++ b/src/coreclr/src/utilcode/securityutil.cpp @@ -10,7 +10,6 @@ #include "securitywrapper.h" -// This is defined in ipcmanagerinterface.h, but including that is problematic at the moment... // These are the right that we will give to the global section and global events used // in communicating between debugger and debugee // diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 2af2b27..83f1b23 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -145,16 +145,12 @@ #include "comdelegate.h" #include "appdomain.hpp" #include "perfcounters.h" -#ifdef FEATURE_IPCMAN -#include "ipcmanagerinterface.h" -#endif // FEATURE_IPCMAN #include "eventtrace.h" #include "corhost.h" #include "binder.h" #include "olevariant.h" #include "comcallablewrapper.h" #include "apithreadstress.h" -#include "ipcfunccall.h" #include "perflog.h" #include "../dlls/mscorrc/resource.h" #ifdef FEATURE_USE_LCID @@ -235,12 +231,6 @@ #include "gdbjit.h" #endif // FEATURE_GDBJIT -#ifdef FEATURE_IPCMAN -static HRESULT InitializeIPCManager(void); -static void PublishIPCManager(void); -static void TerminateIPCManager(void); -#endif // FEATURE_IPCMAN - #ifndef CROSSGEN_COMPILE static int GetThreadUICultureId(__out LocaleIDValue* pLocale); // TODO: This shouldn't use the LCID. We should rely on name instead @@ -705,14 +695,6 @@ void EEStartupHelper(COINITIEE fFlags) ETWFireEvent(EEStartupStart_V1); #endif // FEATURE_EVENT_TRACE -#ifdef FEATURE_IPCMAN - // Give PerfMon a chance to hook up to us - // Do this both *before* and *after* ipcman init so corperfmonext.dll - // has a chance to release stale private blocks that IPCMan could collide with. - // do this early to maximize window between perfmon refresh and ipc block creation. - IPCFuncCallSource::DoThreadSafeCall(); -#endif // FEATURE_IPCMAN - InitGSCookie(); Frame::Init(); @@ -820,23 +802,12 @@ void EEStartupHelper(COINITIEE fFlags) } #endif // FEATURE_PREJIT -#ifdef FEATURE_IPCMAN - // Initialize all our InterProcess Communications with COM+ - IfFailGoLog(InitializeIPCManager()); -#endif // FEATURE_IPCMAN - #ifdef ENABLE_PERF_COUNTERS hr = PerfCounters::Init(); _ASSERTE(SUCCEEDED(hr)); IfFailGo(hr); #endif -#ifdef FEATURE_IPCMAN - // Marks the data in the IPC blocks as initialized so that readers know - // that it is safe to read data from the blocks - PublishIPCManager(); -#endif //FEATURE_IPCMAN - #ifdef FEATURE_INTERPRETER Interpreter::Initialize(); #endif // FEATURE_INTERPRETER @@ -884,11 +855,6 @@ void EEStartupHelper(COINITIEE fFlags) g_pEEShutDownEvent = new CLREvent(); g_pEEShutDownEvent->CreateManualEvent(FALSE); -#ifdef FEATURE_IPCMAN - // Initialize CCLRSecurityAttributeManager - CCLRSecurityAttributeManager::ProcessInit(); -#endif // FEATURE_IPCMAN - VirtualCallStubManager::InitStatic(); GCInterface::m_MemoryPressureLock.Init(CrstGCMemoryPressure); @@ -963,14 +929,6 @@ void EEStartupHelper(COINITIEE fFlags) } #endif -#ifdef FEATURE_IPCMAN - // Give PerfMon a chance to hook up to us - // Do this both *before* and *after* ipcman init so corperfmonext.dll - // has a chance to release stale private blocks that IPCMan could collide with. - IPCFuncCallSource::DoThreadSafeCall(); - STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "Returned successfully from second call to IPCFuncCallSource::DoThreadSafeCall"); -#endif // FEATURE_IPCMAN - InitPreStubManager(); #ifdef FEATURE_COMINTEROP @@ -1880,22 +1838,10 @@ part2: //@TODO: find the right place for this VirtualCallStubManager::UninitStatic(); -#ifdef FEATURE_IPCMAN - // Terminate the InterProcess Communications with COM+ - TerminateIPCManager(); -#endif // FEATURE_IPCMAN - #ifdef ENABLE_PERF_LOG PerfLog::PerfLogDone(); #endif //ENABLE_PERF_LOG -#ifdef FEATURE_IPCMAN - // Give PerfMon a chance to hook up to us - // Have perfmon resync list *after* we close IPC so that it will remove - // this process - IPCFuncCallSource::DoThreadSafeCall(); -#endif // FEATURE_IPCMAN - Frame::Term(); if (!g_fFastExitProcess) @@ -2629,12 +2575,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error. return TRUE; } - -#ifdef FEATURE_IPCMAN -extern CCLRSecurityAttributeManager s_CLRSecurityAttributeManager; -#endif // FEATURE_IPCMAN - - #ifdef DEBUGGING_SUPPORTED // // InitializeDebugger initialized the Runtime-side COM+ Debugging Services @@ -2752,164 +2692,8 @@ static void TerminateDebugger(void) } - -#ifdef FEATURE_IPCMAN -// --------------------------------------------------------------------------- -// Initialize InterProcess Communications for COM+ -// 1. Allocate an IPCManager Implementation and hook it up to our interface * -// 2. Call proper init functions to activate relevant portions of IPC block -// --------------------------------------------------------------------------- -static HRESULT InitializeIPCManager(void) -{ - CONTRACTL{ - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; - - HRESULT hr = S_OK; - HINSTANCE hInstIPCBlockOwner = 0; - - DWORD pid = 0; - // Allocate the Implementation. Everyone else will work through the interface - g_pIPCManagerInterface = new (nothrow) IPCWriterInterface(); - - if (g_pIPCManagerInterface == NULL) - { - hr = E_OUTOFMEMORY; - goto errExit; - } - - pid = GetCurrentProcessId(); - - - // Do general init - hr = g_pIPCManagerInterface->Init(); - - if (!SUCCEEDED(hr)) - { - goto errExit; - } - - // Generate private IPCBlock for our PID. Note that for the other side of the debugger, - // they'll hook up to the debuggee's pid (and not their own). So we still - // have to pass the PID in. - EX_TRY - { - // This should go away in the future. - hr = g_pIPCManagerInterface->CreateLegacyPrivateBlockTempV4OnPid(pid, FALSE, &hInstIPCBlockOwner); - } - EX_CATCH_HRESULT(hr); - - if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) - { - // We failed to create the IPC block because it has already been created. This means that - // two mscoree's have been loaded into the process. - PathString strFirstModule; - PathString strSecondModule; - EX_TRY - { - // Get the name and path of the first loaded MSCOREE.DLL. - if (!hInstIPCBlockOwner || !WszGetModuleFileName(hInstIPCBlockOwner, strFirstModule)) - strFirstModule.Set(W("")); - - // Get the name and path of the second loaded MSCOREE.DLL. - if (!WszGetModuleFileName(g_pMSCorEE, strSecondModule)) - strSecondModule.Set(W("")); - } - EX_CATCH_HRESULT(hr); - // Load the format strings for the title and the message body. - EEMessageBoxCatastrophic(IDS_EE_TWO_LOADED_MSCOREE_MSG, IDS_EE_TWO_LOADED_MSCOREE_TITLE, strFirstModule, strSecondModule); - goto errExit; - } - else - { - PathString temp; - if (!WszGetModuleFileName(GetModuleInst(), - temp - )) - { - hr = HRESULT_FROM_GetLastErrorNA(); - } - else - { - EX_TRY - { - if (temp.GetCount() + 1 > MAX_LONGPATH) - { - hr = E_FAIL; - } - else - { - wcscpy_s((PWSTR)g_pIPCManagerInterface->GetInstancePath(),temp.GetCount() + 1,temp); - } - } - EX_CATCH_HRESULT(hr); - } - } - - // Generate public IPCBlock for our PID. - EX_TRY - { - hr = g_pIPCManagerInterface->CreateSxSPublicBlockOnPid(pid); - } - EX_CATCH_HRESULT(hr); - - -errExit: - // If any failure, shut everything down. - if (!SUCCEEDED(hr)) - TerminateIPCManager(); - - return hr; -} -#endif // FEATURE_IPCMAN - #endif // DEBUGGING_SUPPORTED - -// --------------------------------------------------------------------------- -// Marks the IPC block as initialized so that other processes know that the -// block is safe to read -// --------------------------------------------------------------------------- -#ifdef FEATURE_IPCMAN -static void PublishIPCManager(void) -{ - CONTRACTL{ - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - if (g_pIPCManagerInterface != NULL) - g_pIPCManagerInterface->Publish(); -} -#endif // FEATURE_IPCMAN - - - -#ifdef FEATURE_IPCMAN -// --------------------------------------------------------------------------- -// Terminate all InterProcess operations -// --------------------------------------------------------------------------- -static void TerminateIPCManager(void) -{ - CONTRACTL{ - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - if (g_pIPCManagerInterface != NULL) - { - g_pIPCManagerInterface->Terminate(); - delete g_pIPCManagerInterface; - g_pIPCManagerInterface = NULL; - } - -} -#endif // FEATURE_IPCMAN - #ifndef LOCALE_SPARENT #define LOCALE_SPARENT 0x0000006d #endif diff --git a/src/coreclr/src/vm/corhost.cpp b/src/coreclr/src/vm/corhost.cpp index c93c2d8..ef99dec 100644 --- a/src/coreclr/src/vm/corhost.cpp +++ b/src/coreclr/src/vm/corhost.cpp @@ -22,9 +22,6 @@ #include "hosting.h" #include "eepolicy.h" #include "clrex.h" -#ifdef FEATURE_IPCMAN -#include "ipcmanagerinterface.h" -#endif // FEATURE_IPCMAN #include "comcallablewrapper.h" #include "invokeutil.h" #include "appdomain.inl" @@ -92,10 +89,6 @@ ULONG CorRuntimeHostBase::m_Version = 0; CCLRErrorReportingManager g_CLRErrorReportingManager; #endif // defined(FEATURE_WINDOWSPHONE) -#ifdef FEATURE_IPCMAN -static CCLRSecurityAttributeManager s_CLRSecurityAttributeManager; -#endif // FEATURE_IPCMAN - #endif // !DAC typedef DPTR(CONNID) PTR_CONNID; @@ -2617,329 +2610,6 @@ CCLRErrorReportingManager::~CCLRErrorReportingManager() #endif // defined(FEATURE_WINDOWSPHONE) -#ifdef FEATURE_IPCMAN - -CrstStatic CCLRSecurityAttributeManager::m_hostSAMutex; -PACL CCLRSecurityAttributeManager::m_pACL; - -SECURITY_ATTRIBUTES CCLRSecurityAttributeManager::m_hostSA; -SECURITY_DESCRIPTOR CCLRSecurityAttributeManager::m_hostSD; - -/* -* constructor -* -*/ -void CCLRSecurityAttributeManager::ProcessInit() -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } - CONTRACTL_END; - - m_hostSAMutex.Init(CrstReDacl, CRST_UNSAFE_ANYMODE); - m_pACL = NULL; -} - -/* -* destructor -* -*/ -void CCLRSecurityAttributeManager::ProcessCleanUp() -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - } - CONTRACTL_END; - - m_hostSAMutex.Destroy(); - if (m_pACL) - CoTaskMemFree(m_pACL); -} - -// Set private block and events to the new ACL. -HRESULT CCLRSecurityAttributeManager::SetDACL(PACL pacl) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - DWORD dwError; - PACL pNewACL = NULL; - HANDLE hProc = NULL; - DWORD pid = 0; - - // @todo: How can we make sure that debugger attach will not attempt to happen during this time??? - // - CrstHolder ch(&m_hostSAMutex); - - // make sure our host pass our a valid ACL - if (!IsValidAcl(pacl)) - { - dwError = GetLastError(); - hr = HRESULT_FROM_WIN32(dwError); - goto ErrExit; - } - - // Cannnot set DACL while debugger is attached. Because the events are already all hooked up - // between LS and RS. - if (CORDebuggerAttached()) - return CORDBG_E_DEBUGGER_ALREADY_ATTACHED; - - // make a copy of the new ACL - pNewACL = (PACL) CoTaskMemAlloc(pacl->AclSize); - if (FAILED( CopyACL(pacl, pNewACL))) - goto ErrExit; - - _ASSERTE (SECURITY_DESCRIPTOR_MIN_LENGTH == sizeof(SECURITY_DESCRIPTOR)); - - if (!InitializeSecurityDescriptor(&m_hostSD, SECURITY_DESCRIPTOR_REVISION)) - { - hr = HRESULT_FROM_GetLastError(); - goto ErrExit; - } - - if (!SetSecurityDescriptorDacl(&m_hostSD, TRUE, pNewACL, FALSE)) - { - hr = HRESULT_FROM_GetLastError(); - goto ErrExit; - } - - // Now cache the pNewACL to m_pACL and delete m_pACL. - if (m_pACL) - CoTaskMemFree(m_pACL); - - m_pACL = pNewACL; - pNewACL = NULL; - - m_hostSA.nLength = sizeof(SECURITY_ATTRIBUTES); - m_hostSA.lpSecurityDescriptor = &m_hostSD; - m_hostSA.bInheritHandle = FALSE; - - // first of all, try to reDacl on the process token - pid = GetCurrentProcessId(); - hProc = OpenProcess(WRITE_DAC, FALSE, pid); - if (hProc == NULL) - { - hr = HRESULT_FROM_GetLastError(); - goto ErrExit; - } - if (SetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, &m_hostSD) == 0) - { - // failed! - hr = HRESULT_FROM_GetLastError(); - goto ErrExit; - } - - - // now reset all of the kernel object token's DACL. - // This will reDACL the global shared section - if (FAILED(g_pIPCManagerInterface->ReDaclLegacyPrivateBlock(&m_hostSD))) - goto ErrExit; - - // This will reDacl on debugger events. - if (g_pDebugInterface) - { - g_pDebugInterface->ReDaclEvents(&m_hostSD); - } - -ErrExit: - if (pNewACL) - CoTaskMemFree(pNewACL); - if (hProc != NULL) - CloseHandle(hProc); - - return hr; -} - -// cLen - specify the size of input buffer ppacl. If cLen is zero or ppacl is null, -// pcLenTotal will return the total size of required pacl buffer. -// pacl - caller allocated space. We will fill acl in this buffer. -// pcLenTotal - the total size of ACL. -// -HRESULT CCLRSecurityAttributeManager::GetDACL(PACL *ppacl) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - PACL pNewACL = NULL; - PACL pDefaultACL = NULL; - SECURITY_ATTRIBUTES *pSA = NULL; - - // output parameter cannot be NULL - if (ppacl == NULL) - return E_INVALIDARG; - - *ppacl = NULL; - - CrstHolder ch(&m_hostSAMutex); - - // we want to return the ACL of our default policy - if (m_pACL == NULL) - { - hr = g_pIPCManagerInterface->CreateWinNTDescriptor(GetCurrentProcessId(), &pSA, eDescriptor_Private); - if (FAILED(hr)) - { - goto ErrExit; - } - EX_TRY - { - BOOL bDaclPresent; - BOOL bDaclDefault; - - ::GetSecurityDescriptorDacl(pSA->lpSecurityDescriptor, &bDaclPresent, &pDefaultACL, &bDaclDefault); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - if (FAILED(hr) || pDefaultACL == NULL || pDefaultACL->AclSize == 0) - { - goto ErrExit; - } - } - else - { - pDefaultACL = m_pACL; - } - - pNewACL = (PACL) CoTaskMemAlloc(pDefaultACL->AclSize); - if (pNewACL == NULL) - { - hr = E_OUTOFMEMORY; - goto ErrExit; - } - - // make a copy of ACL - hr = CCLRSecurityAttributeManager::CopyACL(pDefaultACL, pNewACL); - if (SUCCEEDED(hr)) - *ppacl = pNewACL; - -ErrExit: - if (FAILED(hr)) - { - if (pNewACL) - { - CoTaskMemFree(pNewACL); - } - } - if (pSA != NULL) - { - g_pIPCManagerInterface->DestroySecurityAttributes(pSA); - } - return hr; -} - - -// This API will duplicate a copy of pAclOrigingal and pass it out on ppAclNew -HRESULT CCLRSecurityAttributeManager::CopyACL(PACL pAclOriginal, PACL pNewACL) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - HRESULT hr = NO_ERROR; - DWORD dwError = GetLastError(); - int i; - ACE_HEADER *pDACLAce; - - _ASSERTE(pNewACL && pAclOriginal); - - // initialize the target ACL buffer - if (!InitializeAcl(pNewACL, pAclOriginal->AclSize, ACL_REVISION)) - { - dwError = GetLastError(); - hr = HRESULT_FROM_WIN32(dwError); - goto ErrExit; - } - - // loop through each existing ace and copy it over - for (i = 0; i < pAclOriginal->AceCount; i++) - { - if (!GetAce(pAclOriginal, i, (LPVOID *) &pDACLAce)) - { - dwError = GetLastError(); - hr = HRESULT_FROM_WIN32(dwError); - goto ErrExit; - } - - if (!AddAce(pNewACL, ACL_REVISION, i, pDACLAce, pDACLAce->AceSize)) - { - dwError = GetLastError(); - hr = HRESULT_FROM_WIN32(dwError); - goto ErrExit; - } - } - - // make sure everything went well with the new ACL - if (!IsValidAcl(pNewACL)) - { - dwError = GetLastError(); - hr = HRESULT_FROM_WIN32(dwError); - goto ErrExit; - } - -ErrExit: - return hr; -} - - -HRESULT CCLRSecurityAttributeManager::GetHostSecurityAttributes(SECURITY_ATTRIBUTES **ppSA) -{ - WRAPPER_NO_CONTRACT; - - if(!ppSA) - return E_POINTER; - - HRESULT hr = S_OK; - - *ppSA = NULL; - - // host has specified ACL - if (m_pACL != NULL) - *ppSA = &(m_hostSA); - - else - hr = g_pIPCManagerInterface->CreateWinNTDescriptor(GetCurrentProcessId(), ppSA, eDescriptor_Private); - - return hr; -} - -void CCLRSecurityAttributeManager::DestroyHostSecurityAttributes(SECURITY_ATTRIBUTES *pSA) -{ - WRAPPER_NO_CONTRACT; - - // no pSA to cleanup - if (pSA == NULL) - return; - - // it is our current host SA. - if (&(m_hostSA) == pSA) - return; - - g_pIPCManagerInterface->DestroySecurityAttributes(pSA); -} -#endif // FEATURE_IPCMAN - void GetProcessMemoryLoad(LPMEMORYSTATUSEX pMSEX) { CONTRACTL diff --git a/src/coreclr/src/vm/vars.cpp b/src/coreclr/src/vm/vars.cpp index 04437f9..4884449 100644 --- a/src/coreclr/src/vm/vars.cpp +++ b/src/coreclr/src/vm/vars.cpp @@ -149,11 +149,6 @@ ETW::CEtwTracer * g_pEtwTracer = NULL; #endif // #ifndef DACCESS_COMPILE -#ifdef FEATURE_IPCMAN -// support for IPCManager -GPTR_IMPL(IPCWriterInterface, g_pIPCManagerInterface); -#endif // FEATURE_IPCMAN - // // Support for the COM+ Debugger. // diff --git a/src/coreclr/src/vm/vars.hpp b/src/coreclr/src/vm/vars.hpp index b6da9c5..d01757d 100644 --- a/src/coreclr/src/vm/vars.hpp +++ b/src/coreclr/src/vm/vars.hpp @@ -85,7 +85,6 @@ class MethodDesc; class SyncBlockCache; class SyncTableEntry; class ThreadStore; -class IPCWriterInterface; namespace ETW { class CEtwTracer; }; class DebugInterface; class DebugInfoManager; @@ -438,12 +437,6 @@ typedef DPTR(RCWCleanupList) PTR_RCWCleanupList; GPTR_DECL(RCWCleanupList,g_pRCWCleanupList); #endif // FEATURE_COMINTEROP -#ifdef FEATURE_IPCMAN -// support for IPCManager -typedef DPTR(IPCWriterInterface) PTR_IPCWriterInterface; -GPTR_DECL(IPCWriterInterface, g_pIPCManagerInterface); -#endif // FEATURE_IPCMAN - // support for Event Tracing for Windows (ETW) EXTERN ETW::CEtwTracer* g_pEtwTracer; -- 2.7.4