-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathRaiseThreadException.c
57 lines (49 loc) · 1.9 KB
/
RaiseThreadException.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/******************************************************************************
File: RaiseThreadException.c
Description:
Handy routine for raising an exception in another thread by queueing
an APC (will only get executed when the thread enters an alertable state
such as when calls WaitForSingleObjectEx())
******************************************************************************/
#define _WIN32_WINNT 0x0400
#include <wtypes.h>
#include <stdlib.h>
#include <malloc.h>
#include <winbase.h>
#include "RaiseThreadException.h"
#pragma warning(disable:4200)
typedef struct _ThreadExceptionInfoBlock
{
DWORD dwExceptionCode;
DWORD dwExceptionFlags;
DWORD nNumberOfArguments;
CONST DWORD lpArguments[];
} ThreadExceptionInfoBlock;
static void __stdcall APCFunc(DWORD dwParam)
{
ThreadExceptionInfoBlock* pBlock = (ThreadExceptionInfoBlock*)dwParam;
DWORD dwExceptionCode = pBlock->dwExceptionCode;
DWORD dwExceptionFlags = pBlock->dwExceptionFlags;
DWORD nNumberOfArguments = pBlock->nNumberOfArguments;
DWORD argsSize = nNumberOfArguments*sizeof(DWORD);
DWORD* lpArguments = (DWORD*)alloca(argsSize);
memcpy(lpArguments, pBlock->lpArguments, argsSize);
free(pBlock);
RaiseException(dwExceptionCode, dwExceptionFlags, nNumberOfArguments, lpArguments);
}
// Raise an exception in the specified thread, at the next opportunity
void __stdcall RaiseThreadException(
HANDLE hThread,
DWORD dwExceptionCode,
DWORD dwExceptionFlags,
DWORD nNumberOfArguments,
CONST DWORD *lpArguments)
{
DWORD argsSize = nNumberOfArguments*sizeof(DWORD);
ThreadExceptionInfoBlock* pBlock = (ThreadExceptionInfoBlock*)malloc(sizeof(ThreadExceptionInfoBlock)+argsSize);
pBlock->dwExceptionCode = dwExceptionCode;
pBlock->dwExceptionFlags = dwExceptionFlags;
pBlock->nNumberOfArguments = nNumberOfArguments;
memcpy((void*)pBlock->lpArguments, lpArguments, argsSize);
QueueUserAPC(APCFunc, hThread, (DWORD)pBlock);
}