diff --git a/src/coreclr/debug/di/cordb.cpp b/src/coreclr/debug/di/cordb.cpp index d7d3957ec7db26..9f93d0bcfd6dfe 100644 --- a/src/coreclr/debug/di/cordb.cpp +++ b/src/coreclr/debug/di/cordb.cpp @@ -32,10 +32,9 @@ //----------------------------------------------------------------------------- // In v1.0, we declared that mscordbi was a "shared" component, which means // that we promised to provide it from now until the end of time. So every CLR implementation -// needs an Mscordbi that implements the everett guids for CorDebug + CorPublish. +// needs an Mscordbi that implements the everett guids for CorDebug // -// This works fine for CorPublish, which is truly shared. -// CorDebug however is "versioned" not "shared" - each version of the CLR has its own disjoint copy. +// CorDebug is "versioned" not "shared" - each version of the CLR has its own disjoint copy. // // Thus creating a CorDebug object requires a version parameter. // CoCreateInstance doesn't have a the version param, so we use the new (v2.0+) @@ -307,14 +306,6 @@ STDAPI DLLEXPORT DllGetClassObjectInternal( // Return code. CClassFactory *pClassFactory; // To create class factory object. PFN_CREATE_OBJ pfnCreateObject = NULL; - -#if defined(FEATURE_DBG_PUBLISH) - if (rclsid == CLSID_CorpubPublish) - { - pfnCreateObject = CorpubPublish::CreateObject; - } - else -#endif #if defined(FEATURE_DBGIPC_TRANSPORT_DI) if (rclsid == CLSID_CorDebug_Telesto) { diff --git a/src/coreclr/debug/di/publish.cpp b/src/coreclr/debug/di/publish.cpp deleted file mode 100644 index 0a7bad24642885..00000000000000 --- a/src/coreclr/debug/di/publish.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// File: publish.cpp -// - -// -//***************************************************************************** - - -#include "stdafx.h" -#ifdef FEATURE_DBG_PUBLISH - -#include "check.h" - -#include - -#ifndef SM_REMOTESESSION -#define SM_REMOTESESSION 0x1000 -#endif - -#include "corpriv.h" -#include "../../dlls/mscorrc/resource.h" -#include - -// Publish shares header files with the rest of ICorDebug. -// ICorDebug should not call ReadProcessMemory & other APIs directly, it should instead go through -// the Data-target. ICD headers #define these APIs to help enforce this. -// Since Publish is separate and doesn't use data-targets, it can access the APIs directly. -// see code:RSDebuggingInfo#UseDataTarget -#undef ReadProcessMemory - -//**************************************************************************** -//************ App Domain Publishing Service API Implementation ************** -//**************************************************************************** - -// This function enumerates all the process in the system and returns -// their PIDs -BOOL GetAllProcessesInSystem(DWORD *ProcessId, - DWORD dwArraySize, - DWORD *pdwNumEntries) -{ - HandleHolder hSnapshotHolder; - - // Create the Process' Snapshot - HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - LOG((LF_CORDB, LL_INFO1000, - "Unable to create snapshot of processes in the system. " - "CreateToolhelp32Snapshot() failed.\n")); - return FALSE; - } - // HandleHolder doesn't deal with INVALID_HANDLE_VALUE, so we only assign if we have a legal value. - hSnapshotHolder.Assign(hSnapshot); - - PROCESSENTRY32 PE32; - - // need to initialize the dwSize field before calling Process32First - PE32.dwSize = sizeof (PROCESSENTRY32); - - // Get the first process in the process list - BOOL succ = Process32First(hSnapshot, &PE32); - if (succ != TRUE) - { - LOG((LF_CORDB, LL_INFO1000, - "Unable to create snapshot of processes in the system. " - "Process32First() returned FALSE.\n")); - return FALSE; - } - - // Loop over and get all the remaining processes - int iIndex = 0; - - do - { - ProcessId [iIndex++] = PE32.th32ProcessID; - - succ = Process32Next(hSnapshot, &PE32); - - } while ((succ == TRUE) && (iIndex < (int)dwArraySize)); - - _ASSERTE (iIndex < (int)dwArraySize); - - *pdwNumEntries = iIndex; - - // If we made it this far, we succeeded - return TRUE; -} - - -// We never want to wait infinite on an object that we can't verify. -// Wait with a timeout. -const DWORD SAFETY_TIMEOUT = 2000; - -// ****************************************** -// CorpubPublish -// ****************************************** - -CorpubPublish::CorpubPublish() - : CordbCommonBase(0) - , m_fpGetModuleFileNameEx(NULL) -{ - // Try to get psapi!GetModuleFileNameExW once, and then every process object can use it. - // If we can't get it, then we'll fallback to getting information from the IPC block. - m_hPSAPIdll = WszLoadLibrary(W("api-ms-win-obsolete-psapi-l1-1-0.dll")); - - if (m_hPSAPIdll != NULL) - { - m_fpGetModuleFileNameEx = (FPGetModuleFileNameEx*) GetProcAddress(m_hPSAPIdll, "GetModuleFileNameExW"); - } - - CordbCommonBase::InitializeCommon(); -} - -CorpubPublish::~CorpubPublish() -{ - // m_hPSAPIdll is a module holder, so the dtor will free it automatically for us. -} - - -COM_METHOD CorpubPublish::QueryInterface(REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublish) - *ppInterface = (ICorPublish*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublish*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - ExternalAddRef(); - return S_OK; -} - - -COM_METHOD CorpubPublish::EnumProcesses(COR_PUB_ENUMPROCESS Type, - ICorPublishProcessEnum **ppIEnum) -{ - HRESULT hr = E_FAIL; - CorpubProcess* pProcessList = NULL ; - CorpubProcessEnum* pProcEnum = NULL; - *ppIEnum = NULL; - - if( Type != COR_PUB_MANAGEDONLY ) - { - hr = E_INVALIDARG; - goto exit; - } - - // call function to get PIDs for all processes in the system -#define MAX_PROCESSES 512 - - DWORD ProcessId[MAX_PROCESSES]; - DWORD dwNumProcesses = 0; - if( !GetAllProcessesInSystem(ProcessId, MAX_PROCESSES, &dwNumProcesses) ) - { - hr = E_FAIL; - goto exit; - } - - // iterate over all the processes to fetch all the managed processes - for (int i = 0; i < (int)dwNumProcesses; i++) - { - CorpubProcess *pProcess = NULL; - hr = GetProcessInternal( ProcessId[i], &pProcess ); - if( FAILED(hr) ) - { - _ASSERTE( pProcess == NULL ); - goto exit; // a serious error has occurred, abort - } - - if( hr == S_OK ) - { - // Success, Add the process to the list. - _ASSERTE( pProcess != NULL ); - pProcess->SetNext( pProcessList ); - pProcessList = pProcess; - } - else - { - // Ignore this process (isn't managed, or shut down, etc.) - _ASSERTE( pProcess == NULL ); - } - } - - // create and return the ICorPublishProcessEnum - pProcEnum = new (nothrow) CorpubProcessEnum(pProcessList); - if (pProcEnum == NULL) - { - hr = E_OUTOFMEMORY; - goto exit; - } - pProcEnum->AddRef(); - - hr = pProcEnum->QueryInterface(IID_ICorPublishProcessEnum, (void**)ppIEnum); - if( FAILED(hr) ) - { - goto exit; - } - - hr = S_OK; - -exit: - // release our handle on the process objects - while (pProcessList != NULL) - { - CorpubProcess *pTmp = pProcessList; - pProcessList = pProcessList->GetNextProcess(); - pTmp->Release(); - } - if( pProcEnum != NULL ) - { - pProcEnum->Release(); - pProcEnum = NULL; - } - - return hr; -} - - -HRESULT CorpubPublish::GetProcess(unsigned pid, - ICorPublishProcess **ppProcess) -{ - *ppProcess = NULL; - - // Query for this specific process (even if we've already handed out a - // now-stale process object for this pid) - CorpubProcess * pProcess = NULL; - HRESULT hr = GetProcessInternal( pid, &pProcess ); - if( hr != S_OK ) - { - // Couldn't get this process (doesn't exist, or isn't managed) - _ASSERTE( pProcess == NULL ); - if( FAILED(hr) ) - { - return hr; // there was a serious error trying to get this process info - } - return E_INVALIDARG; // this process doesn't exist, isn't managed or is shutting down - } - - // QI to ICorPublishProcess and return it - _ASSERTE( pProcess != NULL ); - hr = pProcess->QueryInterface(IID_ICorPublishProcess, (void**)ppProcess); - pProcess->Release(); - return hr; -} - - -// Attempts to create a CorpubProcess object for a specific managed process -// On success returns S_OK and sets ppProcess to a new AddRef'd CorpubProcess -// object. Otherwise, returns S_FALSE if the process isn't managed or if it has -// terminated (i.e. it should be ignored), or and error code on a serious failure. -HRESULT CorpubPublish::GetProcessInternal( - unsigned pid, - CorpubProcess **ppProcess ) -{ -#if defined(FEATURE_DBGIPC_TRANSPORT_DI) - return E_NOTIMPL; - -#else // !FEATURE_DBGIPC_TRANSPORT_DI - HRESULT hr = S_OK; - *ppProcess = NULL; - - NewHolder pIPCReader( new (nothrow) IPCReaderInterface() ); - if (pIPCReader == NULL) - { - LOG((LF_CORDB, LL_INFO100, "CP::EP: Failed to allocate memory for IPCReaderInterface.\n")); - return E_OUTOFMEMORY; - } - - // See if it is a managed process by trying to open the shared - // memory block. - hr = pIPCReader->OpenLegacyPrivateBlockTempV4OnPid(pid); - if (FAILED(hr)) - { - return S_FALSE; // Not a managed process - } - - // Get the AppDomainIPCBlock - AppDomainEnumerationIPCBlock *pAppDomainCB = pIPCReader->GetAppDomainBlock(); - if (pAppDomainCB == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: Failed to obtain AppDomainIPCBlock.\n")); - return S_FALSE; - } - - // Get the process handle. - HANDLE hProcess = OpenProcess((PROCESS_VM_READ | - PROCESS_QUERY_INFORMATION | - PROCESS_DUP_HANDLE | - SYNCHRONIZE), - FALSE, pid); - if (hProcess == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: OpenProcess() returned NULL handle.\n")); - return S_FALSE; - } - - // If the mutex isn't filled in, the CLR is either starting up or shutting down - if (pAppDomainCB->m_hMutex == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: IPC block isn't properly filled in.\n")); - return S_FALSE; - } - - // Dup the valid mutex handle into this process. - HANDLE hMutex; - if( !pAppDomainCB->m_hMutex.DuplicateToLocalProcess(hProcess, &hMutex) ) - { - return S_FALSE; - } - - // Acquire the mutex, only waiting two seconds. - // We can't actually guarantee that the target put a mutex object in here. - DWORD dwRetVal = WaitForSingleObject(hMutex, SAFETY_TIMEOUT); - - if (dwRetVal == WAIT_OBJECT_0) - { - // Make sure the mutex handle is still valid. If - // its not, then we lost a shutdown race. - if (pAppDomainCB->m_hMutex == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: lost shutdown race, skipping...\n")); - - ReleaseMutex(hMutex); - CloseHandle(hMutex); - return S_FALSE; - } - } - else - { - // Again, landing here is most probably a shutdown race. Its okay, though... - LOG((LF_CORDB, LL_INFO1000, "CP::EP: failed to get IPC mutex.\n")); - - if (dwRetVal == WAIT_ABANDONED) - { - ReleaseMutex(hMutex); - } - CloseHandle(hMutex); - return S_FALSE; - } - // Beware: if the target pid is not properly honoring the mutex, the data in the - // IPC block may still shift underneath us. - - // If we get here, then hMutex is held by this process. - - // Now create the CorpubProcess object for the ProcessID - CorpubProcess *pProc = new (nothrow) CorpubProcess(pid, - true, - hProcess, - hMutex, - pAppDomainCB, - pIPCReader, - m_fpGetModuleFileNameEx); - - // Release our lock on the IPC block. - ReleaseMutex(hMutex); - - if (pProc == NULL) - { - return E_OUTOFMEMORY; - } - pIPCReader.SuppressRelease(); - - // Success, return the Process object - pProc->AddRef(); - *ppProcess = pProc; - return S_OK; - -#endif // FEATURE_DBGIPC_TRANSPORT_DI -} - - - -// ****************************************** -// CorpubProcess -// ****************************************** - -// Constructor -CorpubProcess::CorpubProcess(DWORD dwProcessId, - bool fManaged, - HANDLE hProcess, - HANDLE hMutex, - AppDomainEnumerationIPCBlock *pAD, -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - IPCReaderInterface *pIPCReader, -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - FPGetModuleFileNameEx * fpGetModuleFileNameEx) - : CordbCommonBase(0, enumCorpubProcess), - m_dwProcessId(dwProcessId), - m_fIsManaged(fManaged), - m_hProcess(hProcess), - m_hMutex(hMutex), - m_AppDomainCB(pAD), -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - m_pIPCReader(pIPCReader), -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - m_pNext(NULL) -{ - { - // First try to get the process name from the OS. That can't be spoofed by badly formed IPC block. - // psapi!GetModuleFileNameExW can get that, but it's not available on all platforms so we - // need to load it dynamically. - if (fpGetModuleFileNameEx != NULL) - { - // MSDN is very confused about whether the length is in bytes (MSDN 2002) or chars (MSDN 2004). - // We err on the safe side by having buffer that's twice as large, and ignoring - // the units on the return value. - WCHAR szName[MAX_LONGPATH * sizeof(WCHAR)]; - - DWORD lenInCharsOrBytes = MAX_LONGPATH*sizeof(WCHAR); - - // Pass NULL module handle to get "Main Module", which will give us the process name. - DWORD ret = (*fpGetModuleFileNameEx) (hProcess, NULL, szName, lenInCharsOrBytes); - if (ret > 0) - { - // Recompute string length because we don't know if 'ret' is in bytes or char. - SIZE_T len = u16_strlen(szName) + 1; - m_szProcessName = new (nothrow) WCHAR[len]; - if (m_szProcessName != NULL) - { - wcscpy_s(m_szProcessName, len, szName); - goto exit; - } - } - } - - // This is a security feature on WinXp + above, so make sure it worked there. - CONSISTENCY_CHECK_MSGF(FALSE, ("On XP/2k03 OSes + above, we should have been able to get\n" - "the module name from psapi!GetModuleFileNameEx. fp=0x%p\n.", fpGetModuleFileNameEx)); - } - // We couldn't get it from the OS, so fallthrough to getting it from the IPC block. - - // Fetch the process name from the AppDomainIPCBlock - _ASSERTE (pAD->m_szProcessName != NULL); - - if (pAD->m_szProcessName == NULL) - m_szProcessName = NULL; - else - { - SIZE_T nBytesRead; - - _ASSERTE(pAD->m_iProcessNameLengthInBytes > 0); - - // Note: this assumes we're reading the null terminator from - // the IPC block. - m_szProcessName = (WCHAR*) new (nothrow) char[pAD->m_iProcessNameLengthInBytes]; - - if (m_szProcessName == NULL) - { - LOG((LF_CORDB, LL_INFO1000, - "CP::CP: Failed to allocate memory for ProcessName.\n")); - - goto exit; - } - - BOOL bSucc = ReadProcessMemory(hProcess, - pAD->m_szProcessName, - m_szProcessName, - pAD->m_iProcessNameLengthInBytes, - &nBytesRead); - - if ((bSucc == 0) || - (nBytesRead != (SIZE_T)pAD->m_iProcessNameLengthInBytes)) - { - // The EE may have done a rude exit - LOG((LF_CORDB, LL_INFO1000, - "CP::EAD: ReadProcessMemory (ProcessName) failed.\n")); - } - } - -exit: - ; -} - -CorpubProcess::~CorpubProcess() -{ - delete [] m_szProcessName; -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - delete m_pIPCReader; -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - CloseHandle(m_hProcess); - CloseHandle(m_hMutex); -} - - -HRESULT CorpubProcess::QueryInterface(REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishProcess) - *ppInterface = (ICorPublishProcess*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishProcess*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -// Helper to tell if this process has exited. -bool CorpubProcess::IsExited() -{ - DWORD res = WaitForSingleObject(this->m_hProcess, 0); - return (res == WAIT_OBJECT_0); -} - - -HRESULT CorpubProcess::IsManaged(BOOL *pbManaged) -{ - *pbManaged = (m_fIsManaged == true) ? TRUE : FALSE; - - return S_OK; -} - -// Helper. -// Allocates a local buffer (using 'new') and fills it by copying it from remote memory. -// Returns: -// - on success, S_OK, *ppNewLocalBuffer points to a newly allocated buffer containing -// the full copy from remote memoy. Caller must use 'delete []' to free this. -// - on failure, a failing HR. No memory is allocated. -HRESULT AllocateAndReadRemoteBuffer( - HANDLE hProcess, - void * pRemotePtr, - SIZE_T cbSize, // size of buffer to allocate + copy. - BYTE * * ppNewLocalBuffer -) -{ - _ASSERTE(ppNewLocalBuffer != NULL); - *ppNewLocalBuffer = NULL; - - - if (pRemotePtr == NULL) - { - return E_INVALIDARG; - } - - BYTE *pLocalBuffer = new (nothrow) BYTE[cbSize]; - - if (pLocalBuffer == NULL) - { - _ASSERTE(!"Failed to alloc memory. Likely size is bogusly large, perhaps from an attacker."); - return E_OUTOFMEMORY; - } - - SIZE_T nBytesRead; - - // Need to read in the remote process' memory - BOOL bSucc = ReadProcessMemory(hProcess, - pRemotePtr, - pLocalBuffer, cbSize, - &nBytesRead); - - if ((bSucc == 0) || (nBytesRead != cbSize)) - { - // The EE may have done a rude exit - delete [] pLocalBuffer; - return E_FAIL; - } - - *ppNewLocalBuffer = pLocalBuffer; - return S_OK; -} - -// Wrapper around AllocateAndReadRemoteBuffer, -// to ensure that we're reading an remote-null terminated string. -// Ensures that string is null-terminated. -HRESULT AllocateAndReadRemoteString( - HANDLE hProcess, - void * pRemotePtr, - SIZE_T cbSize, // size of buffer to allocate + copy. - _Outptr_result_bytebuffer_(cbSize) WCHAR * * ppNewLocalBuffer - ) -{ - // Make sure buffer has right geometry. - if (cbSize < 0) - { - return E_INVALIDARG; - } - - // If it's not on a WCHAR boundary, then we may have a 1-byte buffer-overflow. - SIZE_T ceSize = cbSize / sizeof(WCHAR); - if ((ceSize * sizeof(WCHAR)) != cbSize) - { - return E_INVALIDARG; - } - - // It should at least have 1 char for the null terminator. - if (ceSize < 1) - { - return E_INVALIDARG; - } - - - HRESULT hr = AllocateAndReadRemoteBuffer(hProcess, pRemotePtr, cbSize, (BYTE**) ppNewLocalBuffer); - if (SUCCEEDED(hr)) - { - // Ensure that the string we just read is actually null terminated. - // We can't call u16_strlen() on it yet, since that may AV on a non-null terminated string. - WCHAR * pString = *ppNewLocalBuffer; - - if (pString[ceSize - 1] == W('\0')) - { - // String is null terminated. - return S_OK; - } - pString[ceSize - 1] = W('\0'); - - SIZE_T ceTestLen = u16_strlen(pString); - if (ceTestLen == ceSize - 1) - { - // String was not previously null-terminated. - delete [] ppNewLocalBuffer; - return E_INVALIDARG; - } - } - return S_OK; -} - -// -// Enumerate the list of known application domains in the target process. -// -HRESULT CorpubProcess::EnumAppDomains(ICorPublishAppDomainEnum **ppIEnum) -{ - VALIDATE_POINTER_TO_OBJECT(ppIEnum, ICorPublishAppDomainEnum **); - *ppIEnum = NULL; - - int i; - - HRESULT hr = S_OK; - WCHAR *pAppDomainName = NULL; - CorpubAppDomain *pAppDomainHead = NULL; - - // Lock the IPC block: - // We can't trust any of the data in the IPC block (including our own mutex handle), - // because we don't want bugs in the debuggee escalating into bugs in the debugger. - DWORD res = WaitForSingleObject(m_hMutex, SAFETY_TIMEOUT); - - if (res == WAIT_TIMEOUT) - { - // This should only happen if the target process is illbehaved. - return CORDBG_E_TIMEOUT; - } - - // If the process has gone away, or if it has cleared out its control block, then - // we've lost the race to access this process before it is terminated. - // Note that if the EE does a rude process exit, it won't have cleared the control block so there - // will be a small race window. - if (this->IsExited() || this->m_AppDomainCB->m_hMutex == NULL ) - { - // This is the common case. A process holding the mutex shouldn't normally exit, - // but once it releases the mutex, it may exit asynchronously. - return CORDBG_E_PROCESS_TERMINATED; - } - - if (res == WAIT_FAILED) - { - // This should be the next most common failure case - return HRESULT_FROM_GetLastError(); - } - - if (res != WAIT_OBJECT_0) - { - // Catch all other possible failures - return E_FAIL; - } - - int iAppDomainCount = 0; - AppDomainInfo *pADI = NULL; - - // Make a copy of the IPC block so that we can guarantee that it's not changing on us. - AppDomainEnumerationIPCBlock tempBlock; - memcpy(&tempBlock, m_AppDomainCB, sizeof(tempBlock)); - - // Allocate memory to read the remote process' memory into - const SIZE_T cbADI = tempBlock.m_iSizeInBytes; - - // It's possible the process will not have any appdomains. - if ((tempBlock.m_rgListOfAppDomains == NULL) != (tempBlock.m_iSizeInBytes == 0)) - { - _ASSERTE(!"Inconsistent IPC block in publish."); - hr = E_FAIL; - goto exit; - } - - // All the data in the IPC block is signed integers. They should never be negative, - // so check that now. - if ((tempBlock.m_iTotalSlots < 0) || - (tempBlock.m_iNumOfUsedSlots < 0) || - (tempBlock.m_iLastFreedSlot < 0) || - (tempBlock.m_iSizeInBytes < 0) || - (tempBlock.m_iProcessNameLengthInBytes < 0)) - { - hr = E_FAIL; - goto exit; - } - - // Check other invariants. - if (cbADI != tempBlock.m_iTotalSlots * sizeof(AppDomainInfo)) - { - _ASSERTE(!"Size mismatch"); - hr = E_FAIL; - goto exit; - } - - hr = AllocateAndReadRemoteBuffer(m_hProcess, tempBlock.m_rgListOfAppDomains, cbADI, (BYTE**) &pADI); - if (FAILED(hr)) - { - goto exit; - } - _ASSERTE(pADI != NULL); - - // Collect all the AppDomain info info a list of CorpubAppDomains - for (i = 0; i < tempBlock.m_iTotalSlots; i++) - { - if (!pADI[i].IsEmpty()) - { - // Should be positive, and at least have a null-terminator character. - if (pADI[i].m_iNameLengthInBytes <= 1) - { - hr = E_INVALIDARG; - goto exit; - } - hr = AllocateAndReadRemoteString(m_hProcess, - (void*) pADI[i].m_szAppDomainName, pADI[i].m_iNameLengthInBytes, // remote string + size in bytes - &pAppDomainName); - if (FAILED(hr)) - { - goto exit; - } - - // create a new AppDomainObject. This will take ownership of pAppDomainName. - // We know the string is a well-formed null-terminated string, - // but beyond that, we can't verify that the data is actually truthful. - CorpubAppDomain *pCurrentAppDomain = new (nothrow) CorpubAppDomain(pAppDomainName, - pADI[i].m_id); - - if (pCurrentAppDomain == NULL) - { - LOG((LF_CORDB, LL_INFO1000, - "CP::EAD: Failed to allocate memory for CorpubAppDomain.\n")); - - hr = E_OUTOFMEMORY; - goto exit; - } - - // Since CorpubAppDomain now owns pAppDomain's memory, we don't worry about freeing it. - pAppDomainName = NULL; - - // Add the appdomain to the list. - pCurrentAppDomain->SetNext(pAppDomainHead); - pAppDomainHead = pCurrentAppDomain; - - // Shortcut to opt out of reading the rest of the array if it's empty. - if (++iAppDomainCount >= tempBlock.m_iNumOfUsedSlots) - break; - } - } - - { - _ASSERTE ((iAppDomainCount >= tempBlock.m_iNumOfUsedSlots) - && (i <= tempBlock.m_iTotalSlots)); - - // create and return the ICorPublishAppDomainEnum object, handing off the AppDomain list to it - CorpubAppDomainEnum *pTemp = new (nothrow) CorpubAppDomainEnum(pAppDomainHead); - - if (pTemp == NULL) - { - hr = E_OUTOFMEMORY; - goto exit; - } - - pAppDomainHead = NULL; // handed off AppDomain list to enum, don't delete below - - hr = pTemp->QueryInterface(IID_ICorPublishAppDomainEnum, - (void **)ppIEnum); - } - -exit: - ReleaseMutex(m_hMutex); - - // If we didn't hand off the AppDomain objects, delete them - while( pAppDomainHead != NULL ) - { - CorpubAppDomain *pTemp = pAppDomainHead; - pAppDomainHead = pAppDomainHead->GetNextAppDomain(); - delete pTemp; - } - - if (pADI != NULL) - delete[] pADI; - - if (pAppDomainName != NULL) - delete [] pAppDomainName; - - // Either we succeeded && provided an enumerator; or we failed and didn't provide an enum. - _ASSERTE(SUCCEEDED(hr) == (*ppIEnum != NULL)); - return hr; -} - -/* - * Returns the OS ID for the process in question. - */ -HRESULT CorpubProcess::GetProcessID(unsigned *pid) -{ - *pid = m_dwProcessId; - - return S_OK; -} - -/* - * Get the display name for a process. - */ -HRESULT CorpubProcess::GetDisplayName(ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(szName, WCHAR, cchName, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcchName, ULONG32 *); - - // Reasonable defaults - if (szName) - *szName = 0; - - if (pcchName) - *pcchName = 0; - - const WCHAR *szTempName = m_szProcessName; - - // In case we didn't get the name (most likely out of memory on ctor). - if (!szTempName) - szTempName = W(""); - - return CopyOutString(szTempName, cchName, pcchName, szName); -} - - -// ****************************************** -// CorpubAppDomain -// ****************************************** - -CorpubAppDomain::CorpubAppDomain (_In_ LPWSTR szAppDomainName, ULONG Id) - : CordbCommonBase (0, enumCorpubAppDomain), - m_pNext (NULL), - m_szAppDomainName (szAppDomainName), - m_id (Id) -{ - _ASSERTE(m_szAppDomainName != NULL); -} - -CorpubAppDomain::~CorpubAppDomain() -{ - delete [] m_szAppDomainName; -} - -HRESULT CorpubAppDomain::QueryInterface (REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishAppDomain) - *ppInterface = (ICorPublishAppDomain*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishAppDomain*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -/* - * Get the name and ID for an application domain. - */ -HRESULT CorpubAppDomain::GetID (ULONG32 *pId) -{ - VALIDATE_POINTER_TO_OBJECT(pId, ULONG32 *); - - *pId = m_id; - - return S_OK; -} - -/* - * Get the name for an application domain. - */ -HRESULT CorpubAppDomain::GetName(ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(szName, WCHAR, cchName, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcchName, ULONG32 *); - - const WCHAR *szTempName = m_szAppDomainName; - - // In case we didn't get the name (most likely out of memory on ctor). - if (!szTempName) - szTempName = W(""); - - return CopyOutString(szTempName, cchName, pcchName, szName); -} - - - -// ****************************************** -// CorpubProcessEnum -// ****************************************** - -CorpubProcessEnum::CorpubProcessEnum (CorpubProcess *pFirst) - : CordbCommonBase (0, enumCorpubProcessEnum), - m_pFirst (pFirst), - m_pCurrent (pFirst) -{ - // Increment the ref count on each process, we own the list - CorpubProcess * cur = pFirst; - while( cur != NULL ) - { - cur->AddRef(); - cur = cur->GetNextProcess(); - } -} - -CorpubProcessEnum::~CorpubProcessEnum() -{ - // Release each process in the list (our client may still have a reference - // to some of them) - while (m_pFirst != NULL) - { - CorpubProcess *pTmp = m_pFirst; - m_pFirst = m_pFirst->GetNextProcess(); - pTmp->Release(); - } -} - -HRESULT CorpubProcessEnum::QueryInterface (REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishProcessEnum) - *ppInterface = (ICorPublishProcessEnum*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishProcessEnum*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -HRESULT CorpubProcessEnum::Skip(ULONG celt) -{ - while ((m_pCurrent != NULL) && (celt-- > 0)) - { - m_pCurrent = m_pCurrent->GetNextProcess(); - } - - return S_OK; -} - -HRESULT CorpubProcessEnum::Reset() -{ - m_pCurrent = m_pFirst; - - return S_OK; -} - -HRESULT CorpubProcessEnum::Clone(ICorPublishEnum **ppEnum) -{ - VALIDATE_POINTER_TO_OBJECT(ppEnum, ICorPublishEnum **); - return E_NOTIMPL; -} - -HRESULT CorpubProcessEnum::GetCount(ULONG *pcelt) -{ - VALIDATE_POINTER_TO_OBJECT(pcelt, ULONG *); - - CorpubProcess *pTemp = m_pFirst; - - *pcelt = 0; - - while (pTemp != NULL) - { - (*pcelt)++; - pTemp = pTemp->GetNextProcess(); - } - - return S_OK; -} - -HRESULT CorpubProcessEnum::Next(ULONG celt, - ICorPublishProcess *objects[], - ULONG *pceltFetched) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY(objects, ICorPublishProcess *, - celt, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pceltFetched, ULONG *); - - if ((pceltFetched == NULL) && (celt != 1)) - { - return E_INVALIDARG; - } - - if (celt == 0) - { - if (pceltFetched != NULL) - { - *pceltFetched = 0; - } - return S_OK; - } - - HRESULT hr = S_OK; - - ULONG count = 0; - - while ((m_pCurrent != NULL) && (count < celt)) - { - hr = m_pCurrent->QueryInterface (IID_ICorPublishProcess, - (void**)&objects[count]); - - if (hr != S_OK) - { - break; - } - - count++; - m_pCurrent = m_pCurrent->GetNextProcess(); - } - - if (pceltFetched != NULL) - { - *pceltFetched = count; - } - - // - // If we reached the end of the enumeration, but not the end - // of the number of requested items, we return S_FALSE. - // - if (count < celt) - { - return S_FALSE; - } - - return hr; -} - -// ****************************************** -// CorpubAppDomainEnum -// ****************************************** -CorpubAppDomainEnum::CorpubAppDomainEnum (CorpubAppDomain *pFirst) - : CordbCommonBase (0, enumCorpubAppDomainEnum), - m_pFirst (pFirst), - m_pCurrent (pFirst) -{ - CorpubAppDomain *pCur = pFirst; - while( pCur != NULL ) - { - pCur->AddRef(); - pCur = pCur->GetNextAppDomain(); - } -} - -CorpubAppDomainEnum::~CorpubAppDomainEnum() -{ - // Delete all the app domains - while (m_pFirst != NULL ) - { - CorpubAppDomain *pTemp = m_pFirst; - m_pFirst = m_pFirst->GetNextAppDomain(); - pTemp->Release(); - } -} - -HRESULT CorpubAppDomainEnum::QueryInterface (REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishAppDomainEnum) - *ppInterface = (ICorPublishAppDomainEnum*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishAppDomainEnum*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -HRESULT CorpubAppDomainEnum::Skip(ULONG celt) -{ - while ((m_pCurrent != NULL) && (celt-- > 0)) - { - m_pCurrent = m_pCurrent->GetNextAppDomain(); - } - - return S_OK; -} - -HRESULT CorpubAppDomainEnum::Reset() -{ - m_pCurrent = m_pFirst; - - return S_OK; -} - -HRESULT CorpubAppDomainEnum::Clone(ICorPublishEnum **ppEnum) -{ - VALIDATE_POINTER_TO_OBJECT(ppEnum, ICorPublishEnum **); - return E_NOTIMPL; -} - -HRESULT CorpubAppDomainEnum::GetCount(ULONG *pcelt) -{ - VALIDATE_POINTER_TO_OBJECT(pcelt, ULONG *); - - CorpubAppDomain *pTemp = m_pFirst; - - *pcelt = 0; - - while (pTemp != NULL) - { - (*pcelt)++; - pTemp = pTemp->GetNextAppDomain(); - } - - return S_OK; -} - -HRESULT CorpubAppDomainEnum::Next(ULONG celt, - ICorPublishAppDomain *objects[], - ULONG *pceltFetched) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY(objects, ICorPublishProcess *, - celt, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pceltFetched, ULONG *); - - if ((pceltFetched == NULL) && (celt != 1)) - { - return E_INVALIDARG; - } - - if (celt == 0) - { - if (pceltFetched != NULL) - { - *pceltFetched = 0; - } - return S_OK; - } - - HRESULT hr = S_OK; - - ULONG count = 0; - - while ((m_pCurrent != NULL) && (count < celt)) - { - hr = m_pCurrent->QueryInterface (IID_ICorPublishAppDomain, - (void **)&objects[count]); - - if (hr != S_OK) - { - break; - } - - count++; - m_pCurrent = m_pCurrent->GetNextAppDomain(); - } - - - if (pceltFetched != NULL) - { - *pceltFetched = count; - } - - // - // If we reached the end of the enumeration, but not the end - // of the number of requested items, we return S_FALSE. - // - if (count < celt) - { - return S_FALSE; - } - - return hr; -} - -#endif // defined(FEATURE_DBG_PUBLISH) diff --git a/src/coreclr/debug/di/rsmain.cpp b/src/coreclr/debug/di/rsmain.cpp index 33c9e82878c30e..d34c84974a0bb7 100644 --- a/src/coreclr/debug/di/rsmain.cpp +++ b/src/coreclr/debug/di/rsmain.cpp @@ -452,7 +452,7 @@ void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pP * ------------------------------------------------------------------------- */ extern void* GetClrModuleBase(); -// Do any initialization necessary for both CorPublish and CorDebug +// Do any initialization necessary for CorDebug // This includes enabling logging and adding the SEDebug priv. void CordbCommonBase::InitializeCommon() { diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index d0be92394f1500..21a7703838f134 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -114,13 +114,6 @@ class CordbEval; class CordbMDA; -class CorpubPublish; -class CorpubProcess; -class CorpubAppDomain; -class CorpubProcessEnum; -class CorpubAppDomainEnum; - - class RSLock; class NeuterList; @@ -1094,11 +1087,11 @@ typedef enum { enumCordbEnCSnapshot, // 21 enumCordbEval, // 22 enumCordbUnmanagedThread,// 23 - enumCorpubPublish, // 24 - enumCorpubProcess, // 25 - enumCorpubAppDomain, // 26 - enumCorpubProcessEnum, // 27 - enumCorpubAppDomainEnum,// 28 + // unused, // 24 + // unused, // 25 + // unused, // 26 + // unused, // 27 + // unused, // 28 enumCordbEnumFilter, // 29 enumCordbEnCErrorInfo, // 30 enumCordbEnCErrorInfoEnum,//31 @@ -1157,7 +1150,7 @@ class CordbHashTable; #define CORDB_COMMON_BASE_SIGNATURE 0x0d00d96a #define CORDB_COMMON_BASE_SIGNATURE_DEAD 0x0dead0b1 -// Common base for both CorPublish + CorDebug objects. +// Common base for CorDebug objects. class CordbCommonBase : public IUnknown { public: @@ -10691,12 +10684,6 @@ class CordbUnmanagedThread : public CordbBase }; #endif // FEATURE_INTEROP_DEBUGGING - -//******************************************************************************** -//**************** App Domain Publishing Service API ***************************** -//******************************************************************************** - - class EnumElement { public: @@ -10716,293 +10703,6 @@ class EnumElement EnumElement *m_pNext; }; -#if defined(FEATURE_DBG_PUBLISH) - -// Prototype of psapi!GetModuleFileNameEx. -typedef DWORD FPGetModuleFileNameEx(HANDLE, HMODULE, LPTSTR, DWORD); - - -class CorpubPublish : public CordbCommonBase, public ICorPublish -{ -public: - CorpubPublish(); - virtual ~CorpubPublish(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CordbPublish"; } -#endif - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublish - //----------------------------------------------------------- - - COM_METHOD EnumProcesses( - COR_PUB_ENUMPROCESS Type, - ICorPublishProcessEnum **ppIEnum); - - COM_METHOD GetProcess( - unsigned pid, - ICorPublishProcess **ppProcess); - - //----------------------------------------------------------- - // CreateObject - //----------------------------------------------------------- - static COM_METHOD CreateObject(REFIID id, void **object) - { - *object = NULL; - - if (id != IID_IUnknown && id != IID_ICorPublish) - return (E_NOINTERFACE); - - CorpubPublish *pCorPub = new (nothrow) CorpubPublish(); - - if (pCorPub == NULL) - return (E_OUTOFMEMORY); - - *object = (ICorPublish*)pCorPub; - pCorPub->AddRef(); - - return (S_OK); - } - -private: - HRESULT GetProcessInternal( unsigned pid, CorpubProcess **ppProcess ); - - // Cached information to get the process name. Not available on all platforms, so may be null. - HModuleHolder m_hPSAPIdll; - FPGetModuleFileNameEx * m_fpGetModuleFileNameEx; -}; - -class CorpubProcess : public CordbCommonBase, public ICorPublishProcess -{ -public: - CorpubProcess(const ProcessDescriptor * pProcessDescriptor, - bool fManaged, - HANDLE hProcess, - HANDLE hMutex, - AppDomainEnumerationIPCBlock *pAD, -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - IPCReaderInterface *pIPCReader, -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - FPGetModuleFileNameEx * fpGetModuleFileNameEx); - virtual ~CorpubProcess(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CorpubProcess"; } -#endif - - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishProcess - //----------------------------------------------------------- - COM_METHOD IsManaged(BOOL *pbManaged); - - /* - * Enumerate the list of known application domains in the target process. - */ - COM_METHOD EnumAppDomains(ICorPublishAppDomainEnum **ppEnum); - - /* - * Returns the OS ID for the process in question. - */ - COM_METHOD GetProcessID(unsigned *pid); - - /* - * Get the display name for a process. - */ - COM_METHOD GetDisplayName(ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]); - - CorpubProcess *GetNextProcess () { return m_pNext;} - void SetNext (CorpubProcess *pNext) { m_pNext = pNext;} - - // Helper to tell if this process has exited - bool IsExited(); - -public: - ProcessDescriptor m_processDescriptor; - -private: - bool m_fIsManaged; - HANDLE m_hProcess; - HANDLE m_hMutex; - AppDomainEnumerationIPCBlock *m_AppDomainCB; -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - IPCReaderInterface *m_pIPCReader; // controls the lifetime of the AppDomainEnumerationIPCBlock -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - CorpubProcess *m_pNext; // pointer to the next process in the process list - WCHAR *m_szProcessName; - -}; - -class CorpubAppDomain : public CordbCommonBase, public ICorPublishAppDomain -{ -public: - CorpubAppDomain (_In_ LPWSTR szAppDomainName, ULONG Id); - virtual ~CorpubAppDomain(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CorpubAppDomain"; } -#endif - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface (REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishAppDomain - //----------------------------------------------------------- - - /* - * Get the name and ID for an application domain. - */ - COM_METHOD GetID (ULONG32 *pId); - - /* - * Get the name for an application domain. - */ - COM_METHOD GetName (ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]); - - CorpubAppDomain *GetNextAppDomain () { return m_pNext;} - void SetNext (CorpubAppDomain *pNext) { m_pNext = pNext;} - -private: - CorpubAppDomain *m_pNext; - WCHAR *m_szAppDomainName; - ULONG m_id; - -}; - -class CorpubProcessEnum : public CordbCommonBase, public ICorPublishProcessEnum -{ -public: - CorpubProcessEnum(CorpubProcess *pFirst); - virtual ~CorpubProcessEnum(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CorpubProcessEnum"; } -#endif - - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishProcessEnum - //----------------------------------------------------------- - - COM_METHOD Skip(ULONG celt); - COM_METHOD Reset(); - COM_METHOD Clone(ICorPublishEnum **ppEnum); - COM_METHOD GetCount(ULONG *pcelt); - COM_METHOD Next(ULONG celt, - ICorPublishProcess *objects[], - ULONG *pceltFetched); - -private: - CorpubProcess *m_pFirst; - CorpubProcess *m_pCurrent; - -}; - -class CorpubAppDomainEnum : public CordbCommonBase, public ICorPublishAppDomainEnum -{ -public: - CorpubAppDomainEnum(CorpubAppDomain *pFirst); - virtual ~CorpubAppDomainEnum(); - - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CordbAppDomainEnum"; } -#endif - - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishAppDomainEnum - //----------------------------------------------------------- - COM_METHOD Skip(ULONG celt); - COM_METHOD Reset(); - COM_METHOD Clone(ICorPublishEnum **ppEnum); - COM_METHOD GetCount(ULONG *pcelt); - - COM_METHOD Next(ULONG celt, - ICorPublishAppDomain *objects[], - ULONG *pceltFetched); - -private: - CorpubAppDomain *m_pFirst; - CorpubAppDomain *m_pCurrent; - -}; - -#endif // defined(FEATURE_DBG_PUBLISH) - class CordbHeapEnum : public CordbBase, public ICorDebugHeapEnum { public: diff --git a/src/coreclr/debug/di/stdafx.h b/src/coreclr/debug/di/stdafx.h index 8ee806f88f2718..0f1ae48265b9de 100644 --- a/src/coreclr/debug/di/stdafx.h +++ b/src/coreclr/debug/di/stdafx.h @@ -29,7 +29,6 @@ using std::max; #include "ex.h" #include "sigparser.h" -#include "corpub.h" #include "rspriv.h" // This is included to deal with GCC limitations around templates. diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 7d7c4e9b96be7b..9bc5cda485d176 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -926,7 +926,6 @@ Debugger::Debugger() m_jitAttachInProgress(FALSE), m_launchingDebugger(FALSE), m_LoggingEnabled(TRUE), - m_pAppDomainCB(NULL), m_dClassLoadCallbackCount(0), m_pModules(NULL), m_RSRequestedSync(FALSE), @@ -1896,22 +1895,6 @@ 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) - { - LOG((LF_CORDB, LL_INFO100, "D::S: Failed to get AppDomain IPC block from IPCManager.\n")); - ThrowHR(E_FAIL); - } - - hr = InitAppDomainIPC(); - _ASSERTE(SUCCEEDED(hr)); // throws on error. - // Allows the debugger (and profiler) diagnostics to be disabled so resources like // the named pipes and semaphores are not created. if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableDiagnostics) == 0) @@ -1939,7 +1922,7 @@ HRESULT Debugger::Startup(void) #if defined(FEATURE_DBGIPC_TRANSPORT_VM) // Create transport session and initialize it. g_pDbgTransport = new DbgTransportSession(); - hr = g_pDbgTransport->Init(m_pRCThread->GetDCB(), m_pAppDomainCB); + hr = g_pDbgTransport->Init(m_pRCThread->GetDCB()); if (FAILED(hr)) { ShutdownTransport(); @@ -2406,9 +2389,6 @@ void Debugger::StopDebugger(void) m_pRCThread->AsyncStop(); } - // Also clean up the AppDomain stuff since this is cross-process. - TerminateAppDomainIPC (); - // // Tell the VM to clear out all references to the debugger before we start cleaning up, // so that nothing will reference (accidentally) through the partially cleaned up debugger. @@ -9180,7 +9160,7 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC) //--------------------------------------------------------------------------------------- // -// Debugger::SendCreateAppDomainEvent - notify the RS of an AppDomain +// Debugger::AppDomainCreated - notify the RS of an AppDomain // // Arguments: // pRuntimeAppdomain - pointer to the AppDomain @@ -9190,18 +9170,13 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC) // // Notes: // This is used to notify the debugger of either a newly created -// AppDomain (when fAttaching is FALSE) or of existing AppDomains -// at attach time (fAttaching is TRUE). In both cases, this should +// AppDomain. This should // be called before any LoadModule/LoadAssembly events are sent for // this domain. Otherwise the RS will get an event for an AppDomain // it doesn't recognize and ASSERT. // -// For the non-attach case this means there is no need to enumerate -// the assemblies/modules in an AppDomain after sending this event -// because we know there won't be any. -// -void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain) +void Debugger::AppDomainCreated(AppDomain * pRuntimeAppDomain) { CONTRACTL { @@ -9225,8 +9200,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain) Thread *pThread = g_pEEInterface->GetThread(); SENDIPCEVENT_BEGIN(this, pThread); - - // We may have detached while waiting in LockForEventSending, // in which case we can't send the event. if (CORDebuggerAttached()) @@ -9734,43 +9707,31 @@ BOOL Debugger::SendSystemClassLoadUnloadEvent(mdTypeDef classMetadataToken, Assembly *pAssembly = classModule->GetAssembly(); - if (!m_pAppDomainCB->Lock()) - return (FALSE); + AppDomain *pAppDomain = GetAppDomain(); + _ASSERTE(pAppDomain != NULL); - AppDomainInfo *pADInfo = m_pAppDomainCB->FindFirst(); - - while (pADInfo != NULL) + // Only notify for app domains where the module has been fully loaded already + // We used to make a different check here domain->ContainsAssembly() but that + // triggers too early in the loading process. FindDomainAssembly will not become + // non-NULL until the module is fully loaded into the domain which is what we + // want. + if (classModule->GetDomainAssembly() != NULL ) { - AppDomain *pAppDomain = pADInfo->m_pAppDomain; - _ASSERTE(pAppDomain != NULL); + // Find the Left Side module that this class belongs in. + DebuggerModule* pModule = LookupOrCreateModule(classModule); + _ASSERTE(pModule != NULL); - // Only notify for app domains where the module has been fully loaded already - // We used to make a different check here domain->ContainsAssembly() but that - // triggers too early in the loading process. FindDomainAssembly will not become - // non-NULL until the module is fully loaded into the domain which is what we - // want. - if (classModule->GetDomainAssembly() != NULL ) + // Only send a class load event if they're enabled for this module. + if (pModule && pModule->ClassLoadCallbacksEnabled()) { - // Find the Left Side module that this class belongs in. - DebuggerModule* pModule = LookupOrCreateModule(classModule); - _ASSERTE(pModule != NULL); - - // Only send a class load event if they're enabled for this module. - if (pModule && pModule->ClassLoadCallbacksEnabled()) - { - SendClassLoadUnloadEvent(classMetadataToken, - pModule, - pAssembly, - fIsLoadEvent); - fRetVal = TRUE; - } + SendClassLoadUnloadEvent(classMetadataToken, + pModule, + pAssembly, + fIsLoadEvent); + fRetVal = TRUE; } - - pADInfo = m_pAppDomainCB->FindNext(pADInfo); } - m_pAppDomainCB->Unlock(); - return fRetVal; } @@ -14487,399 +14448,6 @@ void Debugger::SendCustomDebuggerNotification(Thread * pThread, SENDIPCEVENT_END; } - -//----------------------------------------------------------------------------- -// -// Add the AppDomain to the list stored in the IPC block. It adds the id and -// the name. -// -// Arguments: -// pAppDomain - The runtime app domain object to add. -// -// Return Value: -// S_OK on success, else detailed error code. -// -HRESULT Debugger::AddAppDomainToIPC(AppDomain *pAppDomain) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - LPCWSTR szName = NULL; - - LOG((LF_CORDB, LL_INFO100, "D::AADTIPC: Executing AADTIPC for AppDomain 0x%08x.\n", - pAppDomain)); - - STRESS_LOG1(LF_CORDB, LL_INFO10000, "D::AADTIPC: AddAppDomainToIPC:%#08x\n", - pAppDomain); - - - - _ASSERTE(m_pAppDomainCB->m_iTotalSlots > 0); - _ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL); - - { - // - // We need to synchronize this routine with the attach logic. The "normal" - // attach case uses the HelperThread and TrapAllRuntimeThreads to synchronize - // the runtime before sending any of the events (including AppDomainCreates) - // to the right-side. Thus, we can synchronize with this case by forcing us - // to go co-operative. If we were already co-op, then the helper thread will - // wait to start the attach until all co-op threads are paused. If we were - // pre-emptive, then going co-op will suspend us until the HelperThread finishes. - // - // The second case is under the IPC event for ATTACHING, which is where there are - // zero app domains, so it is considered an 'early attach' case. To synchronize - // with this we have to grab and hold the AppDomainDB lock. - // - - GCX_COOP(); - - // Lock the list - if (!m_pAppDomainCB->Lock()) - { - return E_FAIL; - } - - // Get a free entry from the list - AppDomainInfo *pAppDomainInfo = m_pAppDomainCB->GetFreeEntry(); - - // Function returns NULL if the list is full and a realloc failed. - if (!pAppDomainInfo) - { - hr = E_OUTOFMEMORY; - goto LErrExit; - } - - // Now set the AppDomainName. - - /* - * TODO : - * - * Make sure that returning NULL here does not result in a catastrophic - * failure. - * - * GetFriendlyNameNoThrow may call SetFriendlyName, which may call - * UpdateAppDomainEntryInIPC. There is no recursive death, however, because - * the AppDomainInfo object does not contain a pointer to the app domain - * yet. - */ - szName = pAppDomain->GetFriendlyNameForDebugger(); - pAppDomainInfo->SetName(szName); - - // Save on to the appdomain pointer - pAppDomainInfo->m_pAppDomain = pAppDomain; - - // bump the used slot count - m_pAppDomainCB->m_iNumOfUsedSlots++; - -LErrExit: - // UnLock the list - m_pAppDomainCB->Unlock(); - - // Send event to debugger if one is attached. - if (CORDebuggerAttached()) - { - SendCreateAppDomainEvent(pAppDomain); - } - } - - return hr; -} - - -/****************************************************************************** - * Remove the AppDomain from the list stored in the IPC block and send an ExitAppDomain - * event to the debugger if attached. - ******************************************************************************/ -HRESULT Debugger::RemoveAppDomainFromIPC (AppDomain *pAppDomain) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - - HRESULT hr = E_FAIL; - - LOG((LF_CORDB, LL_INFO100, "D::RADFIPC: Executing RADFIPC for AppDomain 0x%08x.\n", - pAppDomain)); - - // if none of the slots are occupied, then simply return. - if (m_pAppDomainCB->m_iNumOfUsedSlots == 0) - return hr; - - // Lock the list - if (!m_pAppDomainCB->Lock()) - return (E_FAIL); - - - // Look for the entry - AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain); - - // Shouldn't be trying to remove an appdomain that was never added - if (!pADInfo) - { - // We'd like to assert this, but there is a small window where we may have - // called AppDomain::Init (and so it's fair game to call Stop, and hence come here), - // but not yet published the app domain. - // _ASSERTE(!"D::RADFIPC: trying to remove an AppDomain that was never added"); - hr = (E_FAIL); - goto ErrExit; - } - - // Release the entry - m_pAppDomainCB->FreeEntry(pADInfo); - -ErrExit: - // UnLock the list - m_pAppDomainCB->Unlock(); - - // - // The Debugger expects to never get an unload event for the default AppDomain. - // - - return hr; -} - -/****************************************************************************** - * Update the AppDomain in the list stored in the IPC block. - ******************************************************************************/ -HRESULT Debugger::UpdateAppDomainEntryInIPC(AppDomain *pAppDomain) -{ - CONTRACTL - { - NOTHROW; - if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);} - } - CONTRACTL_END; - - HRESULT hr = S_OK; - LPCWSTR szName = NULL; - - LOG((LF_CORDB, LL_INFO100, - "D::UADEIIPC: Executing UpdateAppDomainEntryInIPC ad:0x%x.\n", - pAppDomain)); - - // if none of the slots are occupied, then simply return. - if (m_pAppDomainCB->m_iNumOfUsedSlots == 0) - return (E_FAIL); - - // Lock the list - if (!m_pAppDomainCB->Lock()) - return (E_FAIL); - - // Look up the info entry - AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain); - - if (!pADInfo) - { - hr = E_FAIL; - goto ErrExit; - } - - // Update the name only if new name is non-null - szName = pADInfo->m_pAppDomain->GetFriendlyNameForDebugger(); - pADInfo->SetName(szName); - -ErrExit: - // UnLock the list - m_pAppDomainCB->Unlock(); - - return hr; -} - -/****************************************************************************** - * - ******************************************************************************/ -HRESULT Debugger::InitAppDomainIPC(void) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - - PRECONDITION(CheckPointer(m_pAppDomainCB)); - } - CONTRACTL_END; - - // Ensure that if we throw here, the Terminate will get called and cleanup all resources. - // This will make Init an atomic operation - it either fully inits or fully fails. - class EnsureCleanup - { - Debugger * m_pThis; - - public: - EnsureCleanup(Debugger * pThis) - { - m_pThis = pThis; - } - - void SuppressCleanup() - { - m_pThis = NULL; - } - - ~EnsureCleanup() - { - if (m_pThis != NULL) - { - m_pThis->TerminateAppDomainIPC(); - } - } - } hEnsureCleanup(this); - - DWORD dwStrLen = 0; - SString szExeName; - int i; - - // all fields in the object can be zero initialized. - // If we throw, before fully initializing this, then cleanup won't try to free - // uninited values. - ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB)); - - // Create a mutex to allow the Left and Right Sides to properly - // synchronize. The Right Side will spin until m_hMutex is valid, - // then it will acquire it before accessing the data. - HandleHolder hMutex(CreateMutex(NULL, TRUE/*hold*/, NULL)); - if (hMutex == NULL) - { - ThrowLastError(); - } - if (!m_pAppDomainCB->m_hMutex.SetLocal(hMutex)) - { - ThrowLastError(); - } - hMutex.SuppressRelease(); - - m_pAppDomainCB->m_iSizeInBytes = INITIAL_APP_DOMAIN_INFO_LIST_SIZE * - sizeof (AppDomainInfo); - - // Number of slots in AppDomainListElement array - m_pAppDomainCB->m_rgListOfAppDomains = new AppDomainInfo[INITIAL_APP_DOMAIN_INFO_LIST_SIZE]; - _ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL); // throws on oom - - - m_pAppDomainCB->m_iTotalSlots = INITIAL_APP_DOMAIN_INFO_LIST_SIZE; - - // Initialize each AppDomainListElement - for (i = 0; i < INITIAL_APP_DOMAIN_INFO_LIST_SIZE; i++) - { - m_pAppDomainCB->m_rgListOfAppDomains[i].FreeEntry(); - } - - // also initialize the process name - dwStrLen = WszGetModuleFileName(NULL, - szExeName); - - - // If we couldn't get the name, then use a nice default. - if (dwStrLen == 0) - { - szExeName.Set(W("")); - dwStrLen = szExeName.GetCount(); - } - - // If we got the name, copy it into a buffer. dwStrLen is the - // count of characters in the name, not including the null - // terminator. - m_pAppDomainCB->m_szProcessName = new WCHAR[dwStrLen + 1]; - _ASSERTE(m_pAppDomainCB->m_szProcessName != NULL); // throws on oom - - wcscpy_s(m_pAppDomainCB->m_szProcessName, dwStrLen + 1, szExeName); - - // Add 1 to the string length so the Right Side will copy out the - // null terminator, too. - m_pAppDomainCB->m_iProcessNameLengthInBytes = (dwStrLen + 1) * sizeof(WCHAR); - - if (m_pAppDomainCB->m_hMutex != NULL) - { - m_pAppDomainCB->Unlock(); - } - - hEnsureCleanup.SuppressCleanup(); - return S_OK; -} - -/****************************************************************************** - * Uninitialize the AppDomain IPC block - * Returns: - * S_OK -if fully uninitialized - * E_FAIL - if we can't get ownership of the block, and thus no uninitialization - * work is done. - ******************************************************************************/ -HRESULT Debugger::TerminateAppDomainIPC(void) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // If we have no AppDomain block, then we can consider it's already terminated. - if (m_pAppDomainCB == NULL) - return S_OK; - - HRESULT hr = S_OK; - - // Lock the list - // If there's no mutex, then we're in a partially created state. - // This means InitAppDomainIPC failed halfway through. But we're still thread safe - // since other threads can't access us if we don't have the mutex. - if ((m_pAppDomainCB->m_hMutex != NULL) && !m_pAppDomainCB->Lock()) - { - // The callers don't check our return value, we may want to know when we can't gracefully clean up - LOG((LF_CORDB, LL_INFO10, "Debugger::TerminateAppDomainIPC: Failed to get AppDomain IPC lock, not cleaning up.\n")); - - // If the lock is valid, but we can't get it, then we can't really - // uninitialize since someone else is using the block. - return (E_FAIL); - } - - // The shared IPC segment could still be around after the debugger - // object has been destroyed during process shutdown. So, reset - // the UsedSlots count to 0 so that any out of process clients - // enumeratingthe app domains in this process see 0 AppDomains. - m_pAppDomainCB->m_iNumOfUsedSlots = 0; - m_pAppDomainCB->m_iTotalSlots = 0; - - // Now delete the memory allocated for AppDomainInfo array - delete [] m_pAppDomainCB->m_rgListOfAppDomains; - m_pAppDomainCB->m_rgListOfAppDomains = NULL; - - delete [] m_pAppDomainCB->m_szProcessName; - m_pAppDomainCB->m_szProcessName = NULL; - m_pAppDomainCB->m_iProcessNameLengthInBytes = 0; - - // Set the mutex handle to NULL. - // If the Right Side acquires the mutex, it will verify - // that the handle is still not NULL. If it is, then it knows it - // really lost. - RemoteHANDLE m = m_pAppDomainCB->m_hMutex; - m_pAppDomainCB->m_hMutex.m_hLocal = NULL; - - // And bring us back to a fully uninitialized state. - ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB)); - - // We're done. release and close the mutex. Note that this must be done - // after we clear it out above to ensure there is no race condition. - if( m != NULL ) - { - VERIFY(ReleaseMutex(m)); - m.Close(); - } - - return hr; -} - - #ifndef DACCESS_COMPILE // diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 79ba57770b2a4f..49359f64d724ef 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -2617,11 +2617,7 @@ class Debugger : public DebugInterface BOOL ShouldAutoAttach(); BOOL FallbackJITAttachPrompt(); - HRESULT AddAppDomainToIPC (AppDomain *pAppDomain); - HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain); - HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain); - - void SendCreateAppDomainEvent(AppDomain * pAppDomain); + void AppDomainCreated(AppDomain * pAppDomain); // Notify the debugger that an assembly has been unloaded void UnloadAssembly(DomainAssembly * pDomainAssembly); @@ -2837,9 +2833,6 @@ class Debugger : public DebugInterface DebuggerLaunchSetting GetDbgJITDebugLaunchSetting(); public: - HRESULT InitAppDomainIPC(void); - HRESULT TerminateAppDomainIPC(void); - bool ResumeThreads(AppDomain* pAppDomain); void ProcessAnyPendingEvals(Thread *pThread); @@ -2920,7 +2913,6 @@ class Debugger : public DebugInterface Volatile m_jitAttachInProgress; BOOL m_launchingDebugger; BOOL m_LoggingEnabled; - AppDomainEnumerationIPCBlock *m_pAppDomainCB; LONG m_dClassLoadCallbackCount; diff --git a/src/coreclr/debug/inc/dbgappdomain.h b/src/coreclr/debug/inc/dbgappdomain.h index de8a06b38c9e51..1e77c89d71ee0f 100644 --- a/src/coreclr/debug/inc/dbgappdomain.h +++ b/src/coreclr/debug/inc/dbgappdomain.h @@ -140,239 +140,6 @@ struct RemoteHANDLE { } }; - -// AppDomain publishing server support: -// Information about all appdomains in the process will be maintained -// in the shared memory block for use by the debugger, etc. -// This structure defines the layout of the information that will -// be maintained. -struct AppDomainEnumerationIPCBlock -{ - // !!! The binary format of this layout must remain the same across versions so that - // !!! a V2.0 publisher can inspect a v1.0 app. - - // lock for serialization while manipulating AppDomain list. - RemoteHANDLE m_hMutex; - - // Number of slots in AppDomainListElement array - int m_iTotalSlots; - int m_iNumOfUsedSlots; - int m_iLastFreedSlot; - int m_iSizeInBytes; // Size of AppDomainInfo in bytes - - // We can use psapi!GetModuleFileNameEx to get the module name. - // This provides an alternative. - int m_iProcessNameLengthInBytes; - WCHAR *m_szProcessName; - - AppDomainInfo *m_rgListOfAppDomains; - BOOL m_fLockInvalid; - - -#ifndef RIGHT_SIDE_COMPILE - /************************************************************************* - * Locks the list - *************************************************************************/ - BOOL Lock() - { - DWORD dwRes = WaitForSingleObject(m_hMutex, 3000); - if (dwRes == WAIT_TIMEOUT) - { - // Nobody should get stuck holding this lock. - // If we timeout on the wait, then either: - // - it's a really bad race and somebody got preempted for a long time - // - perhaps somebody's doing a DOS attack and holding onto the mutex. - m_fLockInvalid = TRUE; - } - - - // The only time this can happen is if we're in shutdown and a thread - // that held this lock is killed. If this happens, assume that this - // IPC block is in an invalid state and return FALSE to indicate - // that people shouldn't do anything with the block anymore. - if (dwRes == WAIT_ABANDONED) - { - m_fLockInvalid = TRUE; - } - - if (m_fLockInvalid) - { - Unlock(); - } - - return (dwRes == WAIT_OBJECT_0 && !m_fLockInvalid); - } - - /************************************************************************* - * Unlocks the list - *************************************************************************/ - void Unlock() - { - // Lock may or may not be valid at this point. Thus Release may fail, - // but we'll just ignore that. - ReleaseMutex(m_hMutex); - } - - /************************************************************************* - * Gets a free AppDomainInfo entry, and will allocate room if there are - * no free slots left. - *************************************************************************/ - AppDomainInfo *GetFreeEntry() - { - // first check to see if there is space available. If not, then realloc. - if (m_iNumOfUsedSlots == m_iTotalSlots) - { - // need to realloc - AppDomainInfo *pTemp = - new (nothrow) AppDomainInfo [m_iTotalSlots*2]; - - if (pTemp == NULL) - { - return (NULL); - } - - memcpy (pTemp, m_rgListOfAppDomains, m_iSizeInBytes); - - delete [] m_rgListOfAppDomains; - - // Initialize the increased portion of the realloced memory - int iNewSlotSize = m_iTotalSlots * 2; - - for (int iIndex = m_iTotalSlots; iIndex < iNewSlotSize; iIndex++) - pTemp[iIndex].FreeEntry(); - - m_rgListOfAppDomains = pTemp; - m_iTotalSlots = iNewSlotSize; - m_iSizeInBytes *= 2; - } - - // Walk the list looking for an empty slot. Start from the last - // one which was freed. - { - int i = m_iLastFreedSlot; - - do - { - // Pointer to the entry being examined - AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]); - - // is the slot available? - if (pADInfo->IsEmpty()) - return (pADInfo); - - i = (i + 1) % m_iTotalSlots; - - } while (i != m_iLastFreedSlot); - } - - _ASSERTE(!"ADInfo::GetFreeEntry: should never get here."); - return (NULL); - } - - /************************************************************************* - * Returns an AppDomainInfo slot to the free list. - *************************************************************************/ - void FreeEntry(AppDomainInfo *pADInfo) - { - _ASSERTE(pADInfo >= m_rgListOfAppDomains && - pADInfo < m_rgListOfAppDomains + m_iSizeInBytes); - _ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) % - sizeof(AppDomainInfo) == 0); - - // Mark this slot as free - pADInfo->FreeEntry(); - -#ifdef _DEBUG - *pADInfo = {}; -#endif - - // decrement the used slot count - m_iNumOfUsedSlots--; - - // Save the last freed slot. - m_iLastFreedSlot = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains) / - sizeof(AppDomainInfo); - } - - /************************************************************************* - * Finds an AppDomainInfo entry corresponding to the AppDomain pointer. - * Returns NULL if no such entry exists. - *************************************************************************/ - AppDomainInfo *FindEntry(AppDomain *pAD) - { - // Walk the list looking for a matching entry - for (int i = 0; i < m_iTotalSlots; i++) - { - AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]); - - if (!pADInfo->IsEmpty() && - pADInfo->m_pAppDomain == pAD) - return pADInfo; - } - - return (NULL); - } - - /************************************************************************* - * Returns the first AppDomainInfo entry in the list. Returns NULL if - * no such entry exists. - *************************************************************************/ - AppDomainInfo *FindFirst() - { - // Walk the list looking for a non-empty entry - for (int i = 0; i < m_iTotalSlots; i++) - { - AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]); - - if (!pADInfo->IsEmpty()) - return pADInfo; - } - - return (NULL); - } - - /************************************************************************* - * Returns the next AppDomainInfo entry after pADInfo. Returns NULL if - * pADInfo was the last in the list. - *************************************************************************/ - AppDomainInfo *FindNext(AppDomainInfo *pADInfo) - { - _ASSERTE(pADInfo >= m_rgListOfAppDomains && - pADInfo < m_rgListOfAppDomains + m_iSizeInBytes); - _ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) % - sizeof(AppDomainInfo) == 0); - - // Walk the list looking for the next non-empty entry - for (int i = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains) - / sizeof(AppDomainInfo) + 1; - i < m_iTotalSlots; - i++) - { - AppDomainInfo *pADInfoTemp = &(m_rgListOfAppDomains[i]); - - if (!pADInfoTemp->IsEmpty()) - return pADInfoTemp; - } - - return (NULL); - } -#endif // RIGHT_SIDE_COMPILE -}; - -// Enforce the AppDomain IPC block binary layout doesn't change between versions. -// Only an issue for x86 since that's the only platform w/ multiple versions. -#if defined(TARGET_X86) -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_hMutex) == 0x0); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iTotalSlots) == 0x4); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iNumOfUsedSlots) == 0x8); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iLastFreedSlot) == 0xc); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iSizeInBytes) == 0x10); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iProcessNameLengthInBytes) == 0x14); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_szProcessName) == 0x18); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_rgListOfAppDomains) == 0x1c); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_fLockInvalid) == 0x20); -#endif - #endif //DbgAppDomain_H diff --git a/src/coreclr/debug/inc/dbgtransportsession.h b/src/coreclr/debug/inc/dbgtransportsession.h index 3bc9521e9c5251..276bd00a6aa93b 100644 --- a/src/coreclr/debug/inc/dbgtransportsession.h +++ b/src/coreclr/debug/inc/dbgtransportsession.h @@ -341,7 +341,7 @@ class DbgTransportSession #ifdef RIGHT_SIDE_COMPILE HRESULT Init(const ProcessDescriptor& pd, HANDLE hProcessExited); #else - HRESULT Init(DebuggerIPCControlBlock * pDCB, AppDomainEnumerationIPCBlock * pADB); + HRESULT Init(DebuggerIPCControlBlock * pDCB); #endif // RIGHT_SIDE_COMPILE // Drive the session to the SS_Closed state, which will deallocate all remaining transport resources @@ -426,9 +426,6 @@ class DbgTransportSession HRESULT GetDCB(DebuggerIPCControlBlock *pDCB); HRESULT SetDCB(DebuggerIPCControlBlock *pDCB); - // Read the AppDomain control block on the LS from the RS. - HRESULT GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB); - #endif // RIGHT_SIDE_COMPILE private: @@ -469,7 +466,6 @@ class DbgTransportSession MT_WriteMemory, // RS <-> LS : RS wants to write LS memory block (or LS is replying to such a request) MT_GetDCB, // RS <-> LS : RS wants to read LS DCB (or LS is replying to such a request) MT_SetDCB, // RS <-> LS : RS wants to write LS DCB (or LS is replying to such a request) - MT_GetAppDomainCB, // RS <-> LS : RS wants to read LS AppDomainCB (or LS is replying to such a request) }; // Reasons the LS can give for rejecting a session. These codes should *not* be changed other than by @@ -589,7 +585,6 @@ class DbgTransportSession LONG m_cSentWriteMemory; LONG m_cSentGetDCB; LONG m_cSentSetDCB; - LONG m_cSentGetAppDomainCB; LONG m_cSentDDMessage; // Message type counts for receives. @@ -603,7 +598,6 @@ class DbgTransportSession LONG m_cReceivedWriteMemory; LONG m_cReceivedGetDCB; LONG m_cReceivedSetDCB; - LONG m_cReceivedGetAppDomainCB; LONG m_cReceivedDDMessage; // Low level block counts. @@ -747,7 +741,6 @@ class DbgTransportSession // The LS requires the addresses of a couple of runtime data structures in order to service MT_GetDCB etc. // These are provided by the runtime at initialization time. DebuggerIPCControlBlock *m_pDCB; - AppDomainEnumerationIPCBlock *m_pADB; #endif // !RIGHT_SIDE_COMPILE HRESULT SendEventWorker(DebuggerIPCEvent * pEvent, IPCEventType type); diff --git a/src/coreclr/debug/shared/dbgtransportsession.cpp b/src/coreclr/debug/shared/dbgtransportsession.cpp index f2547ffc8aefcf..edd2897f02c104 100644 --- a/src/coreclr/debug/shared/dbgtransportsession.cpp +++ b/src/coreclr/debug/shared/dbgtransportsession.cpp @@ -67,7 +67,7 @@ DbgTransportSession::~DbgTransportSession() #ifdef RIGHT_SIDE_COMPILE HRESULT DbgTransportSession::Init(const ProcessDescriptor& pd, HANDLE hProcessExited) #else // RIGHT_SIDE_COMPILE -HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumerationIPCBlock *pADB) +HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB) #endif // RIGHT_SIDE_COMPILE { _ASSERTE(m_eState == SS_Closed); @@ -111,7 +111,6 @@ HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumer m_fDebuggerAttached = false; #else // RIGHT_SIDE_COMPILE m_pDCB = pDCB; - m_pADB = pADB; #endif // RIGHT_SIDE_COMPILE m_sStateLock.Init(); @@ -555,17 +554,6 @@ HRESULT DbgTransportSession::SetDCB(DebuggerIPCControlBlock *pDCB) } -// Read the AppDomain control block on the LS from the RS. -HRESULT DbgTransportSession::GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB) -{ - DbgTransportLog(LC_Requests, "Sending 'GetAppDomainCB'"); - DBG_TRANSPORT_INC_STAT(SentGetAppDomainCB); - - Message sMessage; - sMessage.Init(MT_GetAppDomainCB, NULL, 0, (PBYTE)pADB, sizeof(AppDomainEnumerationIPCBlock)); - return SendRequestMessageAndWait(&sMessage); -} - #endif // RIGHT_SIDE_COMPILE // Worker function for code:DbgTransportSession::SendEvent and code:DbgTransportSession::SendDebugEvent. @@ -948,8 +936,7 @@ void DbgTransportSession::FlushSendQueue(DWORD dwLastProcessedId) if (eType != MT_ReadMemory && eType != MT_WriteMemory && eType != MT_GetDCB && - eType != MT_SetDCB && - eType != MT_GetAppDomainCB) + eType != MT_SetDCB) #endif // RIGHT_SIDE_COMPILE { #ifdef RIGHT_SIDE_COMPILE @@ -1658,8 +1645,7 @@ void DbgTransportSession::TransportWorker() // Since we care about security here, perform some additional validation checks that make it // harder for a malicious sender to attack with random message data. - if (sReceiveHeader.m_eType > MT_GetAppDomainCB || - (sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen && + if ((sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen && sReceiveHeader.m_dwId != (DWORD)0) || (sReceiveHeader.m_dwReplyId >= m_dwNextMessageId && sReceiveHeader.m_dwReplyId != (DWORD)0) || @@ -1974,17 +1960,6 @@ void DbgTransportSession::TransportWorker() #endif // RIGHT_SIDE_COMPILE break; - case MT_GetAppDomainCB: -#ifdef RIGHT_SIDE_COMPILE - if (!ProcessReply(&sReceiveHeader)) - HANDLE_TRANSIENT_ERROR(); -#else // RIGHT_SIDE_COMPILE - fReplyRequired = true; - pbOptReplyData = (PBYTE)m_pADB; - cbOptReplyData = sizeof(AppDomainEnumerationIPCBlock); -#endif // RIGHT_SIDE_COMPILE - break; - default: _ASSERTE(!"Unknown message type"); HANDLE_CRITICAL_ERROR(); @@ -2089,7 +2064,6 @@ void DbgTransportSession::TransportWorker() case MT_WriteMemory: case MT_GetDCB: case MT_SetDCB: - case MT_GetAppDomainCB: // On the RS these are the original requests. Signal the completion event. SignalReplyEvent(pMsg); break; @@ -2098,7 +2072,6 @@ void DbgTransportSession::TransportWorker() case MT_WriteMemory: case MT_GetDCB: case MT_SetDCB: - case MT_GetAppDomainCB: // On the LS these are replies to the original request. Nobody's waiting on these. break; #endif // RIGHT_SIDE_COMPILE @@ -2501,8 +2474,6 @@ const char *DbgTransportSession::MessageName(MessageType eType) return "GetDCB"; case MT_SetDCB: return "SetDCB"; - case MT_GetAppDomainCB: - return "GetAppDomainCB"; default: _ASSERTE(!"Unknown message type"); return NULL; @@ -2561,10 +2532,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader) DbgTransportLog(LC_Requests, "Received 'SetDCB' reply"); DBG_TRANSPORT_INC_STAT(ReceivedSetDCB); return; - case MT_GetAppDomainCB: - DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB' reply"); - DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB); - return; #else // RIGHT_SIDE_COMPILE case MT_ReadMemory: DbgTransportLog(LC_Requests, "Received 'ReadMemory(0x%08X, %u)'", @@ -2586,10 +2553,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader) DbgTransportLog(LC_Requests, "Received 'SetDCB'"); DBG_TRANSPORT_INC_STAT(ReceivedSetDCB); return; - case MT_GetAppDomainCB: - DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB'"); - DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB); - return; #endif // RIGHT_SIDE_COMPILE default: _ASSERTE(!"Unknown message type"); diff --git a/src/coreclr/dlls/mscordbi/mscordbi.src b/src/coreclr/dlls/mscordbi/mscordbi.src index ec3aa1303fb232..3cb62f540475db 100644 --- a/src/coreclr/dlls/mscordbi/mscordbi.src +++ b/src/coreclr/dlls/mscordbi/mscordbi.src @@ -4,7 +4,7 @@ LIBRARY mscordbi EXPORTS - // COM-instantiation - for CorPublish + // COM-instantiation DllGetClassObjectInternal private // In-proc (Whidbey-style) creation path from the shim - CDIFV and it's replacement diff --git a/src/coreclr/inc/CMakeLists.txt b/src/coreclr/inc/CMakeLists.txt index 714bde62d01117..4edac3b4f1ed9c 100644 --- a/src/coreclr/inc/CMakeLists.txt +++ b/src/coreclr/inc/CMakeLists.txt @@ -5,7 +5,6 @@ set( CORGUIDS_IDL_SOURCES clrinternal.idl xclrdata.idl corprof.idl - corpub.idl corsym.idl sospriv.idl ) diff --git a/src/coreclr/inc/corpub.idl b/src/coreclr/inc/corpub.idl deleted file mode 100644 index 16d3e6359a60db..00000000000000 --- a/src/coreclr/inc/corpub.idl +++ /dev/null @@ -1,264 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/* -------------------------------------------------------------------------- * - * Common Language Runtime Process Publishing Interfaces - * -------------------------------------------------------------------------- */ - -cpp_quote("#if 0") -#ifndef DO_NO_IMPORTS -import "unknwn.idl"; -#endif -cpp_quote("#endif") - -typedef enum -{ - COR_PUB_MANAGEDONLY = 0x00000001 // Must always be set, - // only enumerates - // managed processes -} COR_PUB_ENUMPROCESS; - - -/* -------------------------------------------------------------------------- * - * Forward declarations - * -------------------------------------------------------------------------- */ -#pragma warning(push) -#pragma warning(disable:28718) //Unable to annotate as this is not a local interface - -interface ICorPublish; -interface ICorPublishProcess; -interface ICorPublishAppDomain; -interface ICorPublishProcessEnum; -interface ICorPublishAppDomainEnum; - -#pragma warning(pop) - -/* ------------------------------------------------------------------------- * - * Library definition - * ------------------------------------------------------------------------- */ - -[ - uuid(e97ca460-657d-11d3-8d5b-00104b35e7ef), - version(1.0), - helpstring("Common Language Runtime Process Publishing Library") -] -library CorpubProcessLib -{ - importlib("STDOLE2.TLB"); - - // CorPublish is a shared component across all version of the runtime. - [ - uuid(047a9a40-657e-11d3-8d5b-00104b35e7ef) - ] - coclass CorpubPublish - { - [default] interface ICorPublish; - interface ICorPublishProcess; - interface ICorPublishAppDomain; - interface ICorPublishProcessEnum; - interface ICorPublishAppDomainEnum; - }; -}; - - -/* -------------------------------------------------------------------------- * - * Interface definitions - * -------------------------------------------------------------------------- */ - -/* - * This interface is the top level interface for publishing of processes. - */ -[ - object, - uuid(9613A0E7-5A68-11d3-8F84-00A0C9B4D50C), - pointer_default(unique), - local -] -interface ICorPublish : IUnknown -{ - /* - * Retrieves a list of managed processes on this machine which - * the current user has permission to debug. In this version, - * Type must always be equal to COR_PUB_MANAGEDONLY. - * The list is based on a snapshot of the processes running when - * the enum method is called. The enumerator will not reflect any - * processes that start before or terminate after EnumProcesses is called. - * If EnumProcesses is called more than once on this ICorPublish - * instance, a new up-to-date enumeration will be returned without - * affecting any previous ones. - */ - HRESULT EnumProcesses([in] COR_PUB_ENUMPROCESS Type, - [out] ICorPublishProcessEnum **ppIEnum); - - /* - * Gets a new ICorPublishProcess object for the managed process - * with the given process ID. Returns failure if the process doesn't - * exist, or isn't a managed process that can be debugged by the current - * user. - */ - HRESULT GetProcess([in] unsigned pid, - [out] ICorPublishProcess **ppProcess); -} - -/* - * An abstract enumerator. - */ -[ - object, - uuid(C0B22967-5A69-11d3-8F84-00A0C9B4D50C), - pointer_default(unique), - local -] -interface ICorPublishEnum : IUnknown -{ - /* - * Moves the current position forward the given number of - * elements. - */ - HRESULT Skip([in] ULONG celt); - - /* - * Sets the position of the enumerator to the beginning of the - * enumeration. - */ - HRESULT Reset(); - - /* - * Creates another enumerator with the same current position - * as this one. - */ - HRESULT Clone([out] ICorPublishEnum **ppEnum); - - /* - * Gets the number of elements in the enumeration - */ - HRESULT GetCount([out] ULONG *pcelt); -}; - -#pragma warning(push) -#pragma warning(disable:28718) -/* - * Describes a process on a machine. - */ -[ - object, - uuid(18D87AF1-5A6A-11d3-8F84-00A0C9B4D50C), - pointer_default(unique), - local -] -interface ICorPublishProcess : IUnknown -{ - /* - * Returns true if the process is known to have managed code - * running in it. Since this version of ICorPublish only provides access - * to managed processes, this method always returns true. - */ - HRESULT IsManaged([out] BOOL *pbManaged); - - /* - * Enumerates the list of known application domains in this process. - * This list is based on a snapshot of the existing AppDomains when - * this method is called. This method may be called more than - * once to create a new up-to-date list. Existing enumerations will not - * be affected by calls to this method. If the process has been - * terminated, this will fail with CORDBG_E_PROCESS_TERMINATED. - */ - HRESULT EnumAppDomains([out] ICorPublishAppDomainEnum **ppEnum); - - /* - * Returns the OS ID for this process. - */ - HRESULT GetProcessID([out] unsigned *pid); - - /* - * Get the full path of the executable for this process. - * If szName is non-null, this copies up to cchName characters (including - * the null terminator) into szName, and ensures it is null-terminated. - * If pcchName is non-null, the actual number of characters in the name - * (including the null terminator) is stored there. This method returns - * S_OK regardless of how many characters were copied. - */ - HRESULT GetDisplayName([in] ULONG32 cchName, - [out] ULONG32 *pcchName, - [out, size_is(cchName), - length_is(*pcchName)] WCHAR *szName); -} -#pragma warning(pop) - -#pragma warning(push) -#pragma warning(disable:28718) -/* - * Provide information on an Application Domain object. - */ -[ - object, - uuid(D6315C8F-5A6A-11d3-8F84-00A0C9B4D50C), - pointer_default(unique), - local -] -interface ICorPublishAppDomain : IUnknown -{ - /* - * Gets the identification number of this application domain. - * Note that this number is unique to this AppDomain, but only - * within the containing process. - */ - HRESULT GetID([out] ULONG32 *puId); - - /* - * Get the name for an application domain. - * If szName is non-null, this copies up to cchName characters (including - * the null terminator) into szName, and ensures it is null-terminated. - * If pcchName is non-null, the actual number of characters in the name - * (including the null terminator) is stored there. This method returns - * S_OK regardless of how many characters were copied. - */ - HRESULT GetName([in] ULONG32 cchName, - [out] ULONG32 *pcchName, - [out, size_is(cchName), - length_is(*pcchName)] WCHAR *szName); -} -#pragma warning(pop) - - -/* - * Enumerate a list of processes based on the filter criteria given - * when the enumerator object was created. - */ -[ - object, - uuid(A37FBD41-5A69-11d3-8F84-00A0C9B4D50C), - pointer_default(unique), - local -] -interface ICorPublishProcessEnum : ICorPublishEnum -{ - /* - * Gets the next "celt" processes in the enumeration. - */ - HRESULT Next([in] ULONG celt, - [out, size_is(celt), - length_is(*pceltFetched)] ICorPublishProcess **objects, - [out] ULONG *pceltFetched); -} - -/* - * Enumerate a list of app domains based in a process. - */ -[ - object, - uuid(9F0C98F5-5A6A-11d3-8F84-00A0C9B4D50C), - pointer_default(unique), - local -] -interface ICorPublishAppDomainEnum : ICorPublishEnum -{ - /* - * Gets the next "celt" application domains in the enumeration. - */ - HRESULT Next([in] ULONG celt, - [out, size_is(celt), - length_is(*pceltFetched)] ICorPublishAppDomain **objects, - [out] ULONG *pceltFetched); -} - diff --git a/src/coreclr/pal/prebuilt/idl/corpub_i.cpp b/src/coreclr/pal/prebuilt/idl/corpub_i.cpp deleted file mode 100644 index 8aa67f88876171..00000000000000 --- a/src/coreclr/pal/prebuilt/idl/corpub_i.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - - -/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ - -/* link this file in with the server and any clients */ - - - /* File created by MIDL compiler version 8.00.0603 */ -/* @@MIDL_FILE_HEADING( ) */ - -#pragma warning( disable: 4049 ) /* more than 64k source lines */ - - -#ifdef __cplusplus -extern "C"{ -#endif - - -#include -#include - -#ifdef _MIDL_USE_GUIDDEF_ - -#ifndef INITGUID -#define INITGUID -#include -#undef INITGUID -#else -#include -#endif - -#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ - DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) - -#else // !_MIDL_USE_GUIDDEF_ - -#ifndef __IID_DEFINED__ -#define __IID_DEFINED__ - -typedef struct _IID -{ - unsigned long x; - unsigned short s1; - unsigned short s2; - unsigned char c[8]; -} IID; - -#endif // __IID_DEFINED__ - -#ifndef CLSID_DEFINED -#define CLSID_DEFINED -typedef IID CLSID; -#endif // CLSID_DEFINED - -#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ - EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} - -#endif // !_MIDL_USE_GUIDDEF_ - -MIDL_DEFINE_GUID(IID, LIBID_CorpubProcessLib,0xe97ca460,0x657d,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef); - - -MIDL_DEFINE_GUID(CLSID, CLSID_CorpubPublish,0x047a9a40,0x657e,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublish,0x9613A0E7,0x5A68,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishEnum,0xC0B22967,0x5A69,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishProcess,0x18D87AF1,0x5A6A,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishAppDomain,0xD6315C8F,0x5A6A,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishProcessEnum,0xA37FBD41,0x5A69,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishAppDomainEnum,0x9F0C98F5,0x5A6A,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - -#undef MIDL_DEFINE_GUID - -#ifdef __cplusplus -} -#endif - - - diff --git a/src/coreclr/pal/prebuilt/inc/corpub.h b/src/coreclr/pal/prebuilt/inc/corpub.h deleted file mode 100644 index bc1ef7630802ec..00000000000000 --- a/src/coreclr/pal/prebuilt/inc/corpub.h +++ /dev/null @@ -1,820 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - - -/* this ALWAYS GENERATED file contains the definitions for the interfaces */ - - - /* File created by MIDL compiler version 8.00.0603 */ -/* @@MIDL_FILE_HEADING( ) */ - -#pragma warning( disable: 4049 ) /* more than 64k source lines */ - - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCNDR_H_VERSION__ -#define __REQUIRED_RPCNDR_H_VERSION__ 475 -#endif - -#include "rpc.h" -#include "rpcndr.h" - -#ifndef __RPCNDR_H_VERSION__ -#error this stub requires an updated version of -#endif // __RPCNDR_H_VERSION__ - -#ifndef COM_NO_WINDOWS_H -#include "windows.h" -#include "ole2.h" -#endif /*COM_NO_WINDOWS_H*/ - -#ifndef __corpub_h__ -#define __corpub_h__ - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -#pragma once -#endif - -/* Forward Declarations */ - -#ifndef __CorpubPublish_FWD_DEFINED__ -#define __CorpubPublish_FWD_DEFINED__ - -#ifdef __cplusplus -typedef class CorpubPublish CorpubPublish; -#else -typedef struct CorpubPublish CorpubPublish; -#endif /* __cplusplus */ - -#endif /* __CorpubPublish_FWD_DEFINED__ */ - - -#ifndef __ICorPublish_FWD_DEFINED__ -#define __ICorPublish_FWD_DEFINED__ -typedef interface ICorPublish ICorPublish; - -#endif /* __ICorPublish_FWD_DEFINED__ */ - - -#ifndef __ICorPublishEnum_FWD_DEFINED__ -#define __ICorPublishEnum_FWD_DEFINED__ -typedef interface ICorPublishEnum ICorPublishEnum; - -#endif /* __ICorPublishEnum_FWD_DEFINED__ */ - - -#ifndef __ICorPublishProcess_FWD_DEFINED__ -#define __ICorPublishProcess_FWD_DEFINED__ -typedef interface ICorPublishProcess ICorPublishProcess; - -#endif /* __ICorPublishProcess_FWD_DEFINED__ */ - - -#ifndef __ICorPublishAppDomain_FWD_DEFINED__ -#define __ICorPublishAppDomain_FWD_DEFINED__ -typedef interface ICorPublishAppDomain ICorPublishAppDomain; - -#endif /* __ICorPublishAppDomain_FWD_DEFINED__ */ - - -#ifndef __ICorPublishProcessEnum_FWD_DEFINED__ -#define __ICorPublishProcessEnum_FWD_DEFINED__ -typedef interface ICorPublishProcessEnum ICorPublishProcessEnum; - -#endif /* __ICorPublishProcessEnum_FWD_DEFINED__ */ - - -#ifndef __ICorPublishAppDomainEnum_FWD_DEFINED__ -#define __ICorPublishAppDomainEnum_FWD_DEFINED__ -typedef interface ICorPublishAppDomainEnum ICorPublishAppDomainEnum; - -#endif /* __ICorPublishAppDomainEnum_FWD_DEFINED__ */ - - -/* header files for imported files */ -#include "unknwn.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - -/* interface __MIDL_itf_corpub_0000_0000 */ -/* [local] */ - -#if 0 -#endif -typedef /* [public][public] */ -enum __MIDL___MIDL_itf_corpub_0000_0000_0001 - { - COR_PUB_MANAGEDONLY = 0x1 - } COR_PUB_ENUMPROCESS; - -#pragma warning(push) -#pragma warning(disable:28718) - - - - - -#pragma warning(pop) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0000_v0_0_s_ifspec; - - -#ifndef __CorpubProcessLib_LIBRARY_DEFINED__ -#define __CorpubProcessLib_LIBRARY_DEFINED__ - -/* library CorpubProcessLib */ -/* [helpstring][version][uuid] */ - - -EXTERN_C const IID LIBID_CorpubProcessLib; - -EXTERN_C const CLSID CLSID_CorpubPublish; - -#ifdef __cplusplus - -class DECLSPEC_UUID("047a9a40-657e-11d3-8d5b-00104b35e7ef") -CorpubPublish; -#endif -#endif /* __CorpubProcessLib_LIBRARY_DEFINED__ */ - -#ifndef __ICorPublish_INTERFACE_DEFINED__ -#define __ICorPublish_INTERFACE_DEFINED__ - -/* interface ICorPublish */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublish; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("9613A0E7-5A68-11d3-8F84-00A0C9B4D50C") - ICorPublish : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE EnumProcesses( - /* [in] */ COR_PUB_ENUMPROCESS Type, - /* [out] */ ICorPublishProcessEnum **ppIEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetProcess( - /* [in] */ unsigned int pid, - /* [out] */ ICorPublishProcess **ppProcess) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublish * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublish * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublish * This); - - HRESULT ( STDMETHODCALLTYPE *EnumProcesses )( - ICorPublish * This, - /* [in] */ COR_PUB_ENUMPROCESS Type, - /* [out] */ ICorPublishProcessEnum **ppIEnum); - - HRESULT ( STDMETHODCALLTYPE *GetProcess )( - ICorPublish * This, - /* [in] */ unsigned int pid, - /* [out] */ ICorPublishProcess **ppProcess); - - END_INTERFACE - } ICorPublishVtbl; - - interface ICorPublish - { - CONST_VTBL struct ICorPublishVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublish_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublish_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublish_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublish_EnumProcesses(This,Type,ppIEnum) \ - ( (This)->lpVtbl -> EnumProcesses(This,Type,ppIEnum) ) - -#define ICorPublish_GetProcess(This,pid,ppProcess) \ - ( (This)->lpVtbl -> GetProcess(This,pid,ppProcess) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublish_INTERFACE_DEFINED__ */ - - -#ifndef __ICorPublishEnum_INTERFACE_DEFINED__ -#define __ICorPublishEnum_INTERFACE_DEFINED__ - -/* interface ICorPublishEnum */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishEnum; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("C0B22967-5A69-11d3-8F84-00A0C9B4D50C") - ICorPublishEnum : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Skip( - /* [in] */ ULONG celt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( - /* [out] */ ICorPublishEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( - /* [out] */ ULONG *pcelt) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishEnumVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishEnum * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - ICorPublishEnum * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - ICorPublishEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - ICorPublishEnum * This, - /* [out] */ ICorPublishEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - ICorPublishEnum * This, - /* [out] */ ULONG *pcelt); - - END_INTERFACE - } ICorPublishEnumVtbl; - - interface ICorPublishEnum - { - CONST_VTBL struct ICorPublishEnumVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) - -#define ICorPublishEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) - -#define ICorPublishEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) - -#define ICorPublishEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishEnum_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_corpub_0000_0003 */ -/* [local] */ - -#pragma warning(push) -#pragma warning(disable:28718) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0003_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0003_v0_0_s_ifspec; - -#ifndef __ICorPublishProcess_INTERFACE_DEFINED__ -#define __ICorPublishProcess_INTERFACE_DEFINED__ - -/* interface ICorPublishProcess */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishProcess; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("18D87AF1-5A6A-11d3-8F84-00A0C9B4D50C") - ICorPublishProcess : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE IsManaged( - /* [out] */ BOOL *pbManaged) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumAppDomains( - /* [out] */ ICorPublishAppDomainEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetProcessID( - /* [out] */ unsigned int *pid) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDisplayName( - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishProcessVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishProcess * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishProcess * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishProcess * This); - - HRESULT ( STDMETHODCALLTYPE *IsManaged )( - ICorPublishProcess * This, - /* [out] */ BOOL *pbManaged); - - HRESULT ( STDMETHODCALLTYPE *EnumAppDomains )( - ICorPublishProcess * This, - /* [out] */ ICorPublishAppDomainEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetProcessID )( - ICorPublishProcess * This, - /* [out] */ unsigned int *pid); - - HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( - ICorPublishProcess * This, - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName); - - END_INTERFACE - } ICorPublishProcessVtbl; - - interface ICorPublishProcess - { - CONST_VTBL struct ICorPublishProcessVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishProcess_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishProcess_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishProcess_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishProcess_IsManaged(This,pbManaged) \ - ( (This)->lpVtbl -> IsManaged(This,pbManaged) ) - -#define ICorPublishProcess_EnumAppDomains(This,ppEnum) \ - ( (This)->lpVtbl -> EnumAppDomains(This,ppEnum) ) - -#define ICorPublishProcess_GetProcessID(This,pid) \ - ( (This)->lpVtbl -> GetProcessID(This,pid) ) - -#define ICorPublishProcess_GetDisplayName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetDisplayName(This,cchName,pcchName,szName) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishProcess_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_corpub_0000_0004 */ -/* [local] */ - -#pragma warning(pop) -#pragma warning(push) -#pragma warning(disable:28718) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0004_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0004_v0_0_s_ifspec; - -#ifndef __ICorPublishAppDomain_INTERFACE_DEFINED__ -#define __ICorPublishAppDomain_INTERFACE_DEFINED__ - -/* interface ICorPublishAppDomain */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishAppDomain; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("D6315C8F-5A6A-11d3-8F84-00A0C9B4D50C") - ICorPublishAppDomain : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetID( - /* [out] */ ULONG32 *puId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetName( - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishAppDomainVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishAppDomain * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishAppDomain * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishAppDomain * This); - - HRESULT ( STDMETHODCALLTYPE *GetID )( - ICorPublishAppDomain * This, - /* [out] */ ULONG32 *puId); - - HRESULT ( STDMETHODCALLTYPE *GetName )( - ICorPublishAppDomain * This, - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName); - - END_INTERFACE - } ICorPublishAppDomainVtbl; - - interface ICorPublishAppDomain - { - CONST_VTBL struct ICorPublishAppDomainVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishAppDomain_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishAppDomain_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishAppDomain_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishAppDomain_GetID(This,puId) \ - ( (This)->lpVtbl -> GetID(This,puId) ) - -#define ICorPublishAppDomain_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishAppDomain_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_corpub_0000_0005 */ -/* [local] */ - -#pragma warning(pop) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0005_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0005_v0_0_s_ifspec; - -#ifndef __ICorPublishProcessEnum_INTERFACE_DEFINED__ -#define __ICorPublishProcessEnum_INTERFACE_DEFINED__ - -/* interface ICorPublishProcessEnum */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishProcessEnum; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("A37FBD41-5A69-11d3-8F84-00A0C9B4D50C") - ICorPublishProcessEnum : public ICorPublishEnum - { - public: - virtual HRESULT STDMETHODCALLTYPE Next( - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishProcess **objects, - /* [out] */ ULONG *pceltFetched) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishProcessEnumVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishProcessEnum * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishProcessEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishProcessEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - ICorPublishProcessEnum * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - ICorPublishProcessEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - ICorPublishProcessEnum * This, - /* [out] */ ICorPublishEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - ICorPublishProcessEnum * This, - /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( - ICorPublishProcessEnum * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishProcess **objects, - /* [out] */ ULONG *pceltFetched); - - END_INTERFACE - } ICorPublishProcessEnumVtbl; - - interface ICorPublishProcessEnum - { - CONST_VTBL struct ICorPublishProcessEnumVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishProcessEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishProcessEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishProcessEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishProcessEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) - -#define ICorPublishProcessEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) - -#define ICorPublishProcessEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) - -#define ICorPublishProcessEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) - - -#define ICorPublishProcessEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishProcessEnum_INTERFACE_DEFINED__ */ - - -#ifndef __ICorPublishAppDomainEnum_INTERFACE_DEFINED__ -#define __ICorPublishAppDomainEnum_INTERFACE_DEFINED__ - -/* interface ICorPublishAppDomainEnum */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishAppDomainEnum; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("9F0C98F5-5A6A-11d3-8F84-00A0C9B4D50C") - ICorPublishAppDomainEnum : public ICorPublishEnum - { - public: - virtual HRESULT STDMETHODCALLTYPE Next( - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishAppDomain **objects, - /* [out] */ ULONG *pceltFetched) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishAppDomainEnumVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishAppDomainEnum * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishAppDomainEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishAppDomainEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - ICorPublishAppDomainEnum * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - ICorPublishAppDomainEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - ICorPublishAppDomainEnum * This, - /* [out] */ ICorPublishEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - ICorPublishAppDomainEnum * This, - /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( - ICorPublishAppDomainEnum * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishAppDomain **objects, - /* [out] */ ULONG *pceltFetched); - - END_INTERFACE - } ICorPublishAppDomainEnumVtbl; - - interface ICorPublishAppDomainEnum - { - CONST_VTBL struct ICorPublishAppDomainEnumVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishAppDomainEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishAppDomainEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishAppDomainEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishAppDomainEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) - -#define ICorPublishAppDomainEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) - -#define ICorPublishAppDomainEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) - -#define ICorPublishAppDomainEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) - - -#define ICorPublishAppDomainEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishAppDomainEnum_INTERFACE_DEFINED__ */ - - -/* Additional Prototypes for ALL interfaces */ - -/* end of Additional Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/src/coreclr/pal/src/handlemgr/handleapi.cpp b/src/coreclr/pal/src/handlemgr/handleapi.cpp index 90683bc2c30889..5f08f2fae51423 100644 --- a/src/coreclr/pal/src/handlemgr/handleapi.cpp +++ b/src/coreclr/pal/src/handlemgr/handleapi.cpp @@ -169,14 +169,8 @@ CorUnix::InternalDuplicateHandle( goto InternalDuplicateHandleExit; } - /* Since handles can be remoted to others processes using PAL_LocalHsndleToRemote - and PAL_RemoteHandleToLocal, DuplicateHandle needs some special handling - when this scenario occurs. - - if hSourceProcessHandle is from another process OR - hTargetProcessHandle is from another process but both aren't - ( handled above ) return hSourceHandle. - */ + // Handles can't be remoted cross-process. + // Just return the same handle. if (source_process_id != cur_process_id || target_process_id != cur_process_id) { diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index 2ebaf707c8785a..8f0617377b1117 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -762,7 +762,6 @@ void SystemDomain::DetachBegin() // Shut down the domain and its children (but don't deallocate anything just // yet). - // TODO: we should really not running managed DLLMain during process detach. if (GetThreadNULLOk() == NULL) { return; @@ -1504,11 +1503,26 @@ void SystemDomain::PublishAppDomainAndInformDebugger (AppDomain *pDomain) LOG((LF_CORDB, LL_INFO100, "SD::PADAID: Adding 0x%x\n", pDomain)); - // Call the publisher API to add this appdomain entry to the list - // The publisher will handle failures, so we don't care if this succeeds or fails. - if (g_pDebugInterface != NULL) + // + // We need to synchronize this routine with the attach logic. The "normal" + // attach case uses the HelperThread and TrapAllRuntimeThreads to synchronize + // the runtime before sending any of the events (including AppDomainCreates) + // to the right-side. Thus, we can synchronize with this case by forcing us + // to go co-operative. If we were already co-op, then the helper thread will + // wait to start the attach until all co-op threads are paused. If we were + // pre-emptive, then going co-op will suspend us until the HelperThread finishes. + // + // The second case is under the IPC event for ATTACHING, which is where there are + // zero app domains, so it is considered an 'early attach' case. To synchronize + // with this we have to grab and hold the AppDomainDB lock. + // + + + // Send event to debugger if one is attached. + if (CORDebuggerAttached()) { - g_pDebugInterface->AddAppDomainToIPC(pDomain); + GCX_COOP(); + g_pDebugInterface->AppDomainCreated(pDomain); } } @@ -1738,13 +1752,6 @@ void AppDomain::Stop() #ifdef DEBUGGING_SUPPORTED if (IsDebuggerAttached()) NotifyDebuggerUnload(); - - if (NULL != g_pDebugInterface) - { - // Call the publisher API to delete this appdomain entry from the list - CONTRACT_VIOLATION(ThrowsViolation); - g_pDebugInterface->RemoveAppDomainFromIPC (this); - } #endif // DEBUGGING_SUPPORTED } @@ -2811,13 +2818,9 @@ void AppDomain::SetFriendlyName(LPCWSTR pwzFriendlyName) if(g_pDebugInterface) { - // update the name in the IPC publishing block - if (SUCCEEDED(g_pDebugInterface->UpdateAppDomainEntryInIPC(this))) - { - // inform the attached debugger that the name of this appdomain has changed. - if (IsDebuggerAttached()) - g_pDebugInterface->NameChangeEvent(this, NULL); - } + // inform the attached debugger that the name of this appdomain has changed. + if (IsDebuggerAttached()) + g_pDebugInterface->NameChangeEvent(this, NULL); } } #endif // !DACCESS_COMPILE diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index c1174c44cabce9..cd5a0799bfd6b1 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -1362,11 +1362,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) { g_fEEShutDown |= ShutDown_Phase2; - // @TODO: This does things which shouldn't occur in part 2. Namely, - // calling managed dll main callbacks (AppDomain::SignalProcessDetach), and - // RemoveAppDomainFromIPC. - // - // (If we move those things to earlier, this can be called only if fShouldWeCleanup.) if (!g_fFastExitProcess) { SystemDomain::DetachBegin(); diff --git a/src/coreclr/vm/dbginterface.h b/src/coreclr/vm/dbginterface.h index 23fec81a3474be..a72102ef62ad0b 100644 --- a/src/coreclr/vm/dbginterface.h +++ b/src/coreclr/vm/dbginterface.h @@ -60,10 +60,12 @@ class DebugInterface virtual void DetachThread(Thread *pRuntimeThread) = 0; + virtual void AppDomainCreated(AppDomain * pAppDomain) = 0; + // Called when a module is being loaded into an AppDomain. // This includes when a domain neutral module is loaded into a new AppDomain. // This is called only when a debugger is attached, and will occur after the - // related LoadAssembly and AddAppDomainToIPCBlock calls and before any + // related LoadAssembly calls and before any // LoadClass calls for this module. virtual void LoadModule(Module * pRuntimeModule, // the module being loaded LPCWSTR psModuleName, // module file name @@ -289,16 +291,6 @@ class DebugInterface virtual DWORD GetHelperThreadID(void ) = 0; - // Called whenever a new AppDomain is created, regardless of whether a debugger is attached. - // This will be called before any LoadAssembly calls for assemblies in this domain. - virtual HRESULT AddAppDomainToIPC (AppDomain *pAppDomain) = 0; - - // Called whenever an AppDomain is unloaded, regardless of whether a Debugger is attached - // This will occur after any UnloadAssembly and UnloadModule callbacks for this domain (if any). - virtual HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain) = 0; - - virtual HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain) = 0; - // Called for all assemblies in an AppDomain when the AppDomain is unloaded. // This includes domain neutral assemblies that are also loaded into other domains. // This is called only when a debugger is attached, and will occur after all UnloadClass