Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/HostingCLR_inject/HostingCLR/ReflectiveFree.cpp
Views: 11779
#include "stdafx.h"1#include "ReflectiveFree.h"2#include <Windows.h>34typedef NTSTATUS5(*NtQueueApcThread)(6HANDLE ThreadHandle,7PVOID ApcRoutine,8ULONG_PTR SystemArgument1,9ULONG_PTR SystemArgument2,10ULONG_PTR SystemArgument311);121314VOID ReflectiveFree(HINSTANCE hAppInstance) {15NtQueueApcThread pNtQueueApcThread = (NtQueueApcThread)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQueueApcThread");16HANDLE hThread = NULL;17HANDLE hThisThread = NULL;18do {19if (!pNtQueueApcThread)20break;2122// create a suspended thread that will just exit once the APCs have executed23hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ExitThread, 0, CREATE_SUSPENDED, NULL);24if (!hThread)25break;2627// open a real handle to this thread to pass in the APC so it operates on this thread and not itself28hThisThread = OpenThread(THREAD_QUERY_INFORMATION | SYNCHRONIZE, FALSE, GetCurrentThreadId());29if (!hThisThread)30break;3132// tell that thread to wait on this thread, ensures VirtualFree isn't called until this thread has exited33NTSTATUS status = pNtQueueApcThread(hThread, WaitForSingleObjectEx, (ULONG_PTR)hThisThread, INFINITE, FALSE);3435// then close the handle so it's not leaked36DWORD result = QueueUserAPC((PAPCFUNC)CloseHandle, hThread, (ULONG_PTR)hThisThread);37// then free the memory38status = pNtQueueApcThread(hThread, VirtualFree, (ULONG_PTR)hAppInstance, 0, MEM_RELEASE);39ResumeThread(hThread);40} while (FALSE);4142if (hThread)43CloseHandle(hThread);44}4546VOID ReflectiveFreeAndExitThread(HINSTANCE hAppInstance, DWORD dwExitCode) {47ReflectiveFree(hAppInstance);4849ExitThread(dwExitCode);50return;51}5253