Exemple #1
0
// For coresys we need to look for an API in some apiset dll on win8 if we can't find it  
// in the traditional dll.
HINSTANCE LoadDllForAPI(WCHAR* dllTraditional, WCHAR* dllApiSet)
{
    HINSTANCE hinst = WszLoadLibrary(dllTraditional);

    if (!hinst)
    {
        if(RunningOnWin8())
            hinst = WszLoadLibrary(dllApiSet);
    }

    return hinst;
}
Exemple #2
0
// Detach
HRESULT WindowsNativePipeline::DebugActiveProcessStop(DWORD processId)
{
#if !defined(FEATURE_CORESYSTEM)
    // Late-bind to DebugActiveProcessStop since it's WinXP and above only
    HModuleHolder hKernel32;
    hKernel32 = WszLoadLibrary(W("kernel32"));
    if (hKernel32 == NULL)
        return HRESULT_FROM_GetLastError();

    typedef BOOL (*DebugActiveProcessStopSig) (DWORD);
    DebugActiveProcessStopSig pDebugActiveProcessStop = 
        reinterpret_cast<DebugActiveProcessStopSig>(GetProcAddress(hKernel32, "DebugActiveProcessStop"));

    // Win2K will fail here - can't find DebugActiveProcessStop
    if (pDebugActiveProcessStop == NULL)
        return HRESULT_FROM_GetLastError();

    // Ok, the API exists, call it
    if (!pDebugActiveProcessStop(processId))
    {
        // Detach itself failed
        return HRESULT_FROM_GetLastError();
    }
#else
	// The API exists, call it
    if (!::DebugActiveProcessStop(processId))
    {
        // Detach itself failed
        return HRESULT_FROM_GetLastError();
    }
#endif
    return S_OK;
}
Exemple #3
0
// Determine (if possible) whether a debugger is attached to the target process
HRESULT WindowsNativePipeline::IsRemoteDebuggerPresent(DWORD processId, BOOL* pfDebuggerPresent)
{
#if !defined(FEATURE_CORESYSTEM)

    // Get a process handle for the process ID.
    HandleHolder hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
    if (hProc == NULL)
        return HRESULT_FROM_GetLastError();

    // Delay-bind to CheckRemoteDebuggerPresent - WinXP SP1 and above only
    HModuleHolder hKernel32;
    hKernel32 = WszLoadLibrary(W("kernel32"));
    if (hKernel32 == NULL)
        return HRESULT_FROM_GetLastError();

    typedef BOOL (*CheckRemoteDebuggerPresentSig) (HANDLE, PBOOL);
    CheckRemoteDebuggerPresentSig pCheckRemoteDebuggerPresent = 
        reinterpret_cast<CheckRemoteDebuggerPresentSig>(GetProcAddress(hKernel32, "CheckRemoteDebuggerPresent"));
    if (pCheckRemoteDebuggerPresent == NULL)
        return HRESULT_FROM_GetLastError();

    // API exists - call it
    if (!pCheckRemoteDebuggerPresent(hProc, pfDebuggerPresent))
        return HRESULT_FROM_GetLastError();

    return S_OK;
#else

	//CoreSystem doesn't have this API
	return E_FAIL;
#endif
}
Exemple #4
0
// Enforces the bit set in code:WindowsNativePipeline::DebugSetProcessKillOnExit
void WindowsNativePipeline::UpdateDebugSetProcessKillOnExit()
{
#if !defined(FEATURE_CORESYSTEM)
    // Late bind to DebugSetProcessKillOnExit - WinXP and above only
    HModuleHolder hKernel32;
    hKernel32 = WszLoadLibrary(W("kernel32"));
    SIMPLIFYING_ASSUMPTION(hKernel32 != NULL);
    if (hKernel32 == NULL)
        return;

    typedef BOOL (*DebugSetProcessKillOnExitSig) (BOOL);
    DebugSetProcessKillOnExitSig pDebugSetProcessKillOnExit = 
        reinterpret_cast<DebugSetProcessKillOnExitSig>(GetProcAddress(hKernel32, "DebugSetProcessKillOnExit"));

    // If the API doesn't exist (eg. Win2k) - there isn't anything we can do, just
    // silently ignore the request.
    if (pDebugSetProcessKillOnExit == NULL)
        return;

    BOOL ret = pDebugSetProcessKillOnExit(m_fKillOnExit);

    // Not a good failure path here. 
    // 1) This shouldn't fail.
    // 2) Even if it does, this is likely called after the debuggee
    // has already been created, and if this API fails, most scenarios will
    // be unaffected, so we don't want to fail the overall debugging session. 
    SIMPLIFYING_ASSUMPTION(ret);

#else
	// The API doesn't exit on CoreSystem, just return
	return;
#endif
}
Exemple #5
0
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.
#if !defined(FEATURE_CORESYSTEM)
    m_hPSAPIdll = WszLoadLibrary(W("psapi.dll"));
#else
	m_hPSAPIdll = WszLoadLibrary(W("api-ms-win-obsolete-psapi-l1-1-0.dll"));
#endif

    if (m_hPSAPIdll != NULL)
    {
        m_fpGetModuleFileNameEx = (FPGetModuleFileNameEx*) GetProcAddress(m_hPSAPIdll, "GetModuleFileNameExW");
    }

    CordbCommonBase::InitializeCommon();
}
CoreClrCallbacks *GetCoreClrCallbacks()
{
    static CoreClrCallbacks coreClrCallbacks = { 0 };
    if (coreClrCallbacks.m_hmodCoreCLR == NULL)
    {
        // Run against the desktop CLR
        coreClrCallbacks.m_hmodCoreCLR = WszLoadLibrary(W("mscoree.dll"));
        coreClrCallbacks.m_pfnIEE = SnIEE;
        coreClrCallbacks.m_pfnGetCORSystemDirectory = SnGetCorSystemDirectory;
        coreClrCallbacks.m_pfnGetCLRFunction = NULL;
    }

    return &coreClrCallbacks;
}
Exemple #7
0
void WINAPI InitializeGetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
{
    pfnGetSystemTimeAsFileTime func = NULL;

#ifndef FEATURE_PAL
    HMODULE hKernel32 = WszLoadLibrary(W("kernel32.dll"));
    if (hKernel32 != NULL)
    {
        func = (pfnGetSystemTimeAsFileTime)GetProcAddress(hKernel32, "GetSystemTimePreciseAsFileTime");
        if (func != NULL)
        {
            // GetSystemTimePreciseAsFileTime exists and we'd like to use it.  However, on
            // misconfigured systems, it's possible for the "precise" time to be inaccurate:
            //     https://github.com/dotnet/coreclr/issues/14187
            // If it's inaccurate, though, we expect it to be wildly inaccurate, so as a
            // workaround/heuristic, we get both the "normal" and "precise" times, and as
            // long as they're close, we use the precise one. This workaround can be removed
            // when we better understand what's causing the drift and the issue is no longer
            // a problem or can be better worked around on all targeted OSes.

            FILETIME systemTimeResult;
            ::GetSystemTimeAsFileTime(&systemTimeResult);

            FILETIME preciseSystemTimeResult;
            func(&preciseSystemTimeResult);

            LONG64 systemTimeLong100ns = (LONG64)((((ULONG64)systemTimeResult.dwHighDateTime) << 32) | (ULONG64)systemTimeResult.dwLowDateTime);
            LONG64 preciseSystemTimeLong100ns = (LONG64)((((ULONG64)preciseSystemTimeResult.dwHighDateTime) << 32) | (ULONG64)preciseSystemTimeResult.dwLowDateTime);

            const INT32 THRESHOLD_100NS = 1000000; // 100ms
            if (abs(preciseSystemTimeLong100ns - systemTimeLong100ns) > THRESHOLD_100NS)
            {
                // Too much difference.  Don't use GetSystemTimePreciseAsFileTime.
                func = NULL;
            }
        }
    }
    if (func == NULL)
#endif
    {
        func = &::GetSystemTimeAsFileTime;
    }

    g_pfnGetSystemTimeAsFileTime = func;
    func(lpSystemTimeAsFileTime);
}
Exemple #8
0
void WINAPI InitializeGetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
{
    pfnGetSystemTimeAsFileTime func = NULL;

#ifndef FEATURE_PAL
    HMODULE hKernel32 = WszLoadLibrary(W("kernel32.dll"));
    if (hKernel32 != NULL)
    {
        func = (pfnGetSystemTimeAsFileTime)GetProcAddress(hKernel32, "GetSystemTimePreciseAsFileTime");
    }
    if (func == NULL)
#endif
    {
        func = &::GetSystemTimeAsFileTime;
    }
    
    g_pfnGetSystemTimeAsFileTime = func;
    func(lpSystemTimeAsFileTime);
}
Exemple #9
0
static size_t GetRestrictedPhysicalMemoryLimit()
{
    LIMITED_METHOD_CONTRACT;

    // The limit was cached already
    if (g_RestrictedPhysicalMemoryLimit != (size_t)MAX_PTR)
        return g_RestrictedPhysicalMemoryLimit;

    size_t job_physical_memory_limit = (size_t)MAX_PTR;
    BOOL in_job_p = FALSE;
#ifdef FEATURE_CORECLR
    HINSTANCE hinstApiSetPsapiOrKernel32 = 0;
    // these 2 modules will need to be freed no matter what as we only use them locally in this method.
    HINSTANCE hinstApiSetJob1OrKernel32 = 0;
    HINSTANCE hinstApiSetJob2OrKernel32 = 0;
#else
    HINSTANCE hinstPsapi = 0;
#endif

    PIS_PROCESS_IN_JOB GCIsProcessInJob = 0;
    PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0;

#ifdef FEATURE_CORECLR
    hinstApiSetJob1OrKernel32 = LoadDllForAPI(L"kernel32.dll", L"api-ms-win-core-job-l1-1-0.dll");
    if (!hinstApiSetJob1OrKernel32)
        goto exit;

    GCIsProcessInJob = (PIS_PROCESS_IN_JOB)GetProcAddress(hinstApiSetJob1OrKernel32, "IsProcessInJob");
    if (!GCIsProcessInJob)
        goto exit;
#else
    GCIsProcessInJob = &(::IsProcessInJob);
#endif

    if (!GCIsProcessInJob(GetCurrentProcess(), NULL, &in_job_p))
        goto exit;

    if (in_job_p)
    {
#ifdef FEATURE_CORECLR
        hinstApiSetPsapiOrKernel32 = LoadDllForAPI(L"kernel32.dll", L"api-ms-win-core-psapi-l1-1-0");
        if (!hinstApiSetPsapiOrKernel32)
            goto exit;

        GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstApiSetPsapiOrKernel32, "K32GetProcessMemoryInfo");
#else
        // We need a way to get the working set in a job object and GetProcessMemoryInfo 
        // is the way to get that. According to MSDN, we should use GetProcessMemoryInfo In order to 
        // compensate for the incompatibility that psapi.dll introduced we are getting this dynamically.
        hinstPsapi = WszLoadLibrary(L"psapi.dll");
        if (!hinstPsapi)
            return 0;
        GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstPsapi, "GetProcessMemoryInfo");
#endif

        if (!GCGetProcessMemoryInfo)
            goto exit;

#ifdef FEATURE_CORECLR
        hinstApiSetJob2OrKernel32 = LoadDllForAPI(L"kernel32.dll", L"api-ms-win-core-job-l2-1-0");
        if (!hinstApiSetJob2OrKernel32)
            goto exit;

        GCQueryInformationJobObject = (PQUERY_INFORMATION_JOB_OBJECT)GetProcAddress(hinstApiSetJob2OrKernel32, "QueryInformationJobObject");
#else
        GCQueryInformationJobObject = &(::QueryInformationJobObject);
#endif 

        if (!GCQueryInformationJobObject)
            goto exit;

        JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info;
        if (GCQueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, &limit_info, 
            sizeof(limit_info), NULL))
        {
            size_t job_memory_limit = (size_t)MAX_PTR;
            size_t job_process_memory_limit = (size_t)MAX_PTR;
            size_t job_workingset_limit = (size_t)MAX_PTR;

            // Notes on the NT job object:
            //
            // You can specific a bigger process commit or working set limit than 
            // job limit which is pointless so we use the smallest of all 3 as
            // to calculate our "physical memory load" or "available physical memory"
            // when running inside a job object, ie, we treat this as the amount of physical memory
            // our process is allowed to use.
            // 
            // The commit limit is already reflected by default when you run in a 
            // job but the physical memory load is not.
            //
            if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_JOB_MEMORY) != 0)
                job_memory_limit = limit_info.JobMemoryLimit;
            if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_PROCESS_MEMORY) != 0)
                job_process_memory_limit = limit_info.ProcessMemoryLimit;
            if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET) != 0)
                job_workingset_limit = limit_info.BasicLimitInformation.MaximumWorkingSetSize;

            job_physical_memory_limit = min (job_memory_limit, job_process_memory_limit);
            job_physical_memory_limit = min (job_physical_memory_limit, job_workingset_limit);

            MEMORYSTATUSEX ms;
            ::GetProcessMemoryLoad(&ms);

            // A sanity check in case someone set a larger limit than there is actual physical memory.
            job_physical_memory_limit = (size_t) min (job_physical_memory_limit, ms.ullTotalPhys);
        }
    }

exit:
#ifdef FEATURE_CORECLR
    if (hinstApiSetJob1OrKernel32)
        FreeLibrary(hinstApiSetJob1OrKernel32);
    if (hinstApiSetJob2OrKernel32)
        FreeLibrary(hinstApiSetJob2OrKernel32);
#endif

    if (job_physical_memory_limit == (size_t)MAX_PTR)
    {
        job_physical_memory_limit = 0;

#ifdef FEATURE_CORECLR
        FreeLibrary(hinstApiSetPsapiOrKernel32);
#else
        FreeLibrary(hinstPsapi);
#endif
    }

    VolatileStore(&g_RestrictedPhysicalMemoryLimit, job_physical_memory_limit);
    return g_RestrictedPhysicalMemoryLimit;
}
Exemple #10
0
// This function enumerates all the process in the system and returns
// their PIDs
BOOL GetAllProcessesInSystem(DWORD *ProcessId,
                             DWORD dwArraySize,
                             DWORD *pdwNumEntries)
{    
    HandleHolder hSnapshotHolder;

#if !defined(FEATURE_CORESYSTEM)
    // Load the dll "kernel32.dll".
    HModuleHolder hDll = WszLoadLibrary(W("kernel32"));
    _ASSERTE(hDll != NULL);

    if (hDll == NULL)
    {
        LOG((LF_CORDB, LL_INFO1000,
                "Unable to load the dll for enumerating processes. "
                "LoadLibrary (kernel32.dll) failed.\n"));
        return FALSE;
    }
#else
	// Load the dll "api-ms-win-obsolete-kernel32-l1-1-0.dll".
    HModuleHolder hDll = WszLoadLibrary(W("api-ms-win-obsolete-kernel32-l1-1-0.dll"));
    _ASSERTE(hDll != NULL);

    if (hDll == NULL)
    {
        LOG((LF_CORDB, LL_INFO1000,
                "Unable to load the dll for enumerating processes. "
                "LoadLibrary (api-ms-win-obsolete-kernel32-l1-1-0.dll) failed.\n"));
        return FALSE;
    }
#endif
  
    
    // Create the Process' Snapshot
    // Get the pointer to the requested function
    FARPROC pProcAddr = GetProcAddress(hDll, "CreateToolhelp32Snapshot");

    // If the proc address was not found, return error
    if (pProcAddr == NULL)
    {
        LOG((LF_CORDB, LL_INFO1000,
                "Unable to enumerate processes in the system. "
                "GetProcAddr (CreateToolhelp32Snapshot) failed.\n"));
        return FALSE;
    }

    

    // Handle from CreateToolHelp32Snapshot must be freed via CloseHandle().    
    typedef HANDLE CREATETOOLHELP32SNAPSHOT(DWORD, DWORD);

    HANDLE hSnapshot =
            ((CREATETOOLHELP32SNAPSHOT *)pProcAddr)(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);

    // Get the first process in the process list
    // Get the pointer to the requested function
    pProcAddr = GetProcAddress(hDll, "Process32First");

    // If the proc address was not found, return error
    if (pProcAddr == NULL)
    {
        LOG((LF_CORDB, LL_INFO1000,
                "Unable to enumerate processes in the system. "
                "GetProcAddr (Process32First) failed.\n"));
        return FALSE;
    }

    PROCESSENTRY32  PE32;

    // need to initialize the dwSize field before calling Process32First
    PE32.dwSize = sizeof (PROCESSENTRY32);

    typedef BOOL PROCESS32FIRST(HANDLE, LPPROCESSENTRY32);

    BOOL succ =
            ((PROCESS32FIRST *)pProcAddr)(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
    // Get the pointer to the requested function
    pProcAddr = GetProcAddress(hDll, "Process32Next");

    // If the proc address was not found, return error
    if (pProcAddr == NULL)
    {
        LOG((LF_CORDB, LL_INFO1000,
                "Unable to enumerate processes in the system. "
                "GetProcAddr (Process32Next) failed.\n"));
        return FALSE;
    }

    typedef BOOL PROCESS32NEXT(HANDLE, LPPROCESSENTRY32);

    int iIndex = 0;

    do
    {
        ProcessId [iIndex++] = PE32.th32ProcessID;

        succ = ((PROCESS32NEXT *)pProcAddr)(hSnapshot, &PE32);

    } while ((succ == TRUE) && (iIndex < (int)dwArraySize));

    // I would like to know if we're running more than 512 processes on Win95!!
    _ASSERTE (iIndex < (int)dwArraySize);

    *pdwNumEntries = iIndex;

    // If we made it this far, we succeeded
    return TRUE;
}
Exemple #11
0
static size_t GetRestrictedPhysicalMemoryLimit()
{
    LIMITED_METHOD_CONTRACT;

    // The limit was cached already
    if (g_RestrictedPhysicalMemoryLimit != (size_t)MAX_PTR)
        return g_RestrictedPhysicalMemoryLimit;

    size_t job_physical_memory_limit = (size_t)MAX_PTR;
    BOOL in_job_p = FALSE;
    HINSTANCE hinstKernel32 = 0;

    PIS_PROCESS_IN_JOB GCIsProcessInJob = 0;
    PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0;

    GCIsProcessInJob = &(::IsProcessInJob);

    if (!GCIsProcessInJob(GetCurrentProcess(), NULL, &in_job_p))
        goto exit;

    if (in_job_p)
    {
        hinstKernel32 = WszLoadLibrary(L"kernel32.dll");
        if (!hinstKernel32)
            goto exit;

        GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstKernel32, "K32GetProcessMemoryInfo");

        if (!GCGetProcessMemoryInfo)
            goto exit;

        GCQueryInformationJobObject = &(::QueryInformationJobObject);

        if (!GCQueryInformationJobObject)
            goto exit;

        JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info;
        if (GCQueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, &limit_info, 
            sizeof(limit_info), NULL))
        {
            size_t job_memory_limit = (size_t)MAX_PTR;
            size_t job_process_memory_limit = (size_t)MAX_PTR;
            size_t job_workingset_limit = (size_t)MAX_PTR;

            // Notes on the NT job object:
            //
            // You can specific a bigger process commit or working set limit than 
            // job limit which is pointless so we use the smallest of all 3 as
            // to calculate our "physical memory load" or "available physical memory"
            // when running inside a job object, ie, we treat this as the amount of physical memory
            // our process is allowed to use.
            // 
            // The commit limit is already reflected by default when you run in a 
            // job but the physical memory load is not.
            //
            if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_JOB_MEMORY) != 0)
                job_memory_limit = limit_info.JobMemoryLimit;
            if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_PROCESS_MEMORY) != 0)
                job_process_memory_limit = limit_info.ProcessMemoryLimit;
            if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET) != 0)
                job_workingset_limit = limit_info.BasicLimitInformation.MaximumWorkingSetSize;

            job_physical_memory_limit = min (job_memory_limit, job_process_memory_limit);
            job_physical_memory_limit = min (job_physical_memory_limit, job_workingset_limit);

            MEMORYSTATUSEX ms;
            ::GetProcessMemoryLoad(&ms);

            // A sanity check in case someone set a larger limit than there is actual physical memory.
            job_physical_memory_limit = (size_t) min (job_physical_memory_limit, ms.ullTotalPhys);
        }
    }

exit:
    if (job_physical_memory_limit == (size_t)MAX_PTR)
    {
        job_physical_memory_limit = 0;

        FreeLibrary(hinstKernel32);
    }

    VolatileStore(&g_RestrictedPhysicalMemoryLimit, job_physical_memory_limit);
    return g_RestrictedPhysicalMemoryLimit;
}
Exemple #12
0
//-----------------------------------------------------------------------------
// Receieves the call. This should be in a different process than the source
//-----------------------------------------------------------------------------
HRESULT IPCFuncCallHandler::InitFCHandler(HANDLER_CALLBACK pfnCallback)
{
    m_pfnCallback = pfnCallback;

    HRESULT hr = NOERROR;
    DWORD dwThreadId;
    DWORD dwErr = 0;

    SetLastError(0);

    SECURITY_ATTRIBUTES *pSA = NULL;

    // Grab the SA
    DWORD dwPid = GetCurrentProcessId();
    hr = IPCShared::CreateWinNTDescriptor(dwPid, &pSA);

    if (FAILED(hr))
        goto errExit;;

    // Create the StartEnum Event
    m_hStartEnum = WszCreateEvent(pSA,
                                    FALSE,
                                    FALSE,
                                    FixupName(StartEnumEventName));    
    if (m_hStartEnum == NULL)
    {
        dwErr = GetLastError();
        hr = HRESULT_FROM_WIN32(dwErr); 
        goto errExit;
    }

    // Create the EndEnumEvent
    m_hDoneEnum = WszCreateEvent(pSA,
                                    FALSE,  
                                    FALSE,
                                    FixupName(DoneEnumEventName));
    if (m_hDoneEnum == NULL)
    {
        dwErr = GetLastError();
        hr = HRESULT_FROM_WIN32(dwErr); 
        goto errExit;
    }

    // Create the ShutdownThread Event
    m_hShutdownThread = WszCreateEvent(pSA,
                                       TRUE, /* Manual Reset */
                                       FALSE, /* Initial state not signalled */
                                       NULL);
    
    dwErr = GetLastError();
    if (m_hShutdownThread == NULL)
    {
        hr = HRESULT_FROM_WIN32(dwErr); 
        goto errExit;
    }

    // Create the AuxThreadShutdown Event
    m_hAuxThreadShutdown = WszCreateEvent(pSA,
                                          TRUE, /* Manual Reset */
                                          FALSE,
                                          NULL);

    dwErr = GetLastError();
    if (m_hAuxThreadShutdown == NULL)
    {
        hr = HRESULT_FROM_WIN32(dwErr); 
        goto errExit;
    }

    // The thread that we are about to create should always 
    // find the code in memory. So we take a ref on the DLL. 
    // and do a free library at the end of the thread's start function
    m_hCallbackModule = WszLoadLibrary (L"CorPerfmonExt.dll");

    dwErr = GetLastError();
    if (m_hCallbackModule == NULL)
    {
        hr = HRESULT_FROM_WIN32(dwErr); 
        goto errExit;
    }

    // Create thread
    m_hAuxThread = CreateThread(
        NULL,
        0,
        HandlerAuxThreadProc,
        this,
        0,
        &dwThreadId);

    dwErr = GetLastError();
    if (m_hAuxThread == NULL)
    {
        hr = HRESULT_FROM_WIN32(dwErr);	

        // In case of an error free this library here otherwise
        // the thread's exit would take care of it.
        if (m_hCallbackModule)
            FreeLibrary (m_hCallbackModule);
        goto errExit;
    }

errExit:
    if (!SUCCEEDED(hr)) 
    {
        TerminateFCHandler();
    }
    return hr;
 
}
Exemple #13
0
//*****************************************************************************
// This function will handle ignore codes and tell the user what is happening.
//*****************************************************************************
int _DbgBreakCheck(
    LPCSTR      szFile, 
    int         iLine, 
    LPCSTR      szExpr)
{
    TCHAR       rcBuff[1024+_MAX_PATH];
    TCHAR       rcPath[_MAX_PATH];
    TCHAR       rcTitle[64];
    _DBGIGNOREDATA *psData;
    long        i;

    if (DebugBreakOnAssert())
    {        
        DebugBreak();
    }

    DBGIGNORE* pDBGIFNORE = GetDBGIGNORE();

    // Check for ignore all.
    for (i=0, psData = pDBGIFNORE->Ptr();  i<pDBGIFNORE->Count();  i++, psData++)
    {
        if (psData->iLine == iLine && _stricmp(psData->rcFile, szFile) == 0 && 
            psData->bIgnore == true)
            return (false);
    }

    // Give assert in output for easy access.
    WszGetModuleFileName(0, rcPath, NumItems(rcPath));
    swprintf(rcBuff, L"Assert failure(PID %d [0x%08x], Thread: %d [0x%x]): %hs\n"
                L"    File: %hs, Line: %d Image:\n%s\n", 
                GetCurrentProcessId(), GetCurrentProcessId(),
                GetCurrentThreadId(), GetCurrentThreadId(), 
                szExpr, szFile, iLine, rcPath);
    WszOutputDebugString(rcBuff);
    // Write out the error to the console
    printf("%S\n", rcBuff);

    LogAssert(szFile, iLine, szExpr);
    FlushLogging();         // make certain we get the last part of the log
    fflush(stdout);

    if (NoGuiOnAssert())
    {
        TerminateOnAssert();
    }

    if (DebugBreakOnAssert())
    {        
        return(true);       // like a retry
    }

    // Change format for message box.  The extra spaces in the title
    // are there to get around format truncation.
    swprintf(rcBuff, L"%hs\n\n%hs, Line: %d\n\nAbort - Kill program\nRetry - Debug\nIgnore - Keep running\n"
             L"\n\nImage:\n%s\n",
        szExpr, szFile, iLine, rcPath);
    swprintf(rcTitle, L"Assert Failure (PID %d, Thread %d/%x)        ", 
             GetCurrentProcessId(), GetCurrentThreadId(), GetCurrentThreadId());

    // Tell user there was an error.
    _DbgBreakCount++;
    int ret = WszMessageBoxInternal(NULL, rcBuff, rcTitle, 
            MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | COMPLUS_MB_SERVICE_NOTIFICATION);
	--_DbgBreakCount;

    HMODULE hKrnl32;

    switch(ret)
    {
        // For abort, just quit the app.
        case IDABORT:
          TerminateProcess(GetCurrentProcess(), 1);
//        WszFatalAppExit(0, L"Shutting down");
        break;

        // Tell caller to break at the correct loction.
        case IDRETRY:

        hKrnl32 = WszLoadLibrary(L"kernel32.dll");
        _ASSERTE(hKrnl32 != NULL);

        if(hKrnl32)
        {
            typedef BOOL (WINAPI *t_pDbgPres)();
            t_pDbgPres pFcn = (t_pDbgPres) GetProcAddress(hKrnl32, "IsDebuggerPresent");

            // If this function is available, use it.
            if (pFcn)
            {
                if (pFcn())
                {
                    SetErrorMode(0);
                }
                else
    				LaunchJITDebugger();
            }

            FreeLibrary(hKrnl32);
        }

        return (true);

        // If we want to ignore the assert, find out if this is forever.
        case IDIGNORE:
        swprintf(rcBuff, L"Ignore the assert for the rest of this run?\nYes - Assert will never fire again.\nNo - Assert will continue to fire.\n\n%hs\nLine: %d\n",
            szFile, iLine);
        if (WszMessageBoxInternal(NULL, rcBuff, L"Ignore Assert Forever?", MB_ICONQUESTION | MB_YESNO | COMPLUS_MB_SERVICE_NOTIFICATION) != IDYES)
            break;

        if ((psData = pDBGIFNORE->Append()) == 0)
            return (false);
        psData->bIgnore = true;
        psData->iLine = iLine;
        strcpy(psData->rcFile, szFile);
        break;
    }

    return (false);
}
HRESULT
LoadDataAccessDll(HINSTANCE mscorModule,
                  REFIID ifaceId,
                  ICLRDataTarget* target,
                  HMODULE* dllHandle,
                  void** iface)
{
    HRESULT status;
    WCHAR accessDllPath[MAX_PATH];
    HMODULE accessDll;

    //
    // Load the access DLL from the same directory
    // as the runtime DLL.
    //

    if (!WszGetModuleFileName(mscorModule,
                              accessDllPath, NumItems(accessDllPath)))
    {
        return HRESULT_FROM_GetLastError();
    }

    PWSTR pathTail = wcsrchr(accessDllPath, '\\');
    if (!pathTail)
    {
        return E_INVALIDARG;
    }
    pathTail++;

    PWSTR eeFlavor = L"wks";    
    if (_snwprintf_s(pathTail, _countof(accessDllPath) + (accessDllPath - pathTail),
                   NumItems(accessDllPath) - (pathTail - accessDllPath),
                   MAKEDLLNAME_W(L"mscordac%s"), eeFlavor) <= 0)
    {
        return E_INVALIDARG;
    }

    accessDll = WszLoadLibrary(accessDllPath);
    if (!accessDll)
    {
        return HRESULT_FROM_GetLastError();
    }

    //
    // Get the access interface and have it
    // enumerate the interesting memory in the target process.
    //

    void* ifacePtr;
    PFN_CLRDataCreateInstance entry = (PFN_CLRDataCreateInstance)
        GetProcAddress(accessDll, "CLRDataCreateInstance");
    if (!entry)
    {
        status = HRESULT_FROM_GetLastError();
        FreeLibrary(accessDll);
    }
    else if ((status = entry(ifaceId, target, &ifacePtr)) != S_OK)
    {
        FreeLibrary(accessDll);
    }
    else
    {
        *dllHandle = accessDll;
        *iface = ifacePtr;
    }

    return status;
}