スレッドを開始する前に、ヒープに構造体を割り当て、エラーリターンパラメータを格納します。それをCreateThreadのlpParameter引数を介してスレッドに渡します。終了する前に、エラーコードをそこに残しておきます。
このスレッドを待っているスレッドの構造体の位置を覚えておき、そこから結果を読み込みます。例えば
:リモートスレッドに話をしている場合は
struct threadinfo {
void *someArgument;
DWORD error_code;
int error_flag;
};
DWORD WINAPI threadproc(LPVOID arg) {
struct threadinfo *ti = (struct threadinfo *)arg;
// do things using ti->someArgument
ti->error_code = GetLastError();
ti->error_flag = 42;
return 0; // return code ignored
}
void start_and_wait() {
struct threadinfo *ti = (struct threadinfo *)malloc(sizeof(*ti));
ti->someArgument = &something;
HANDLE hThread = CreateThread(NULL, 0, threadproc, (LPVOID)ti, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
printf("Exit code %08x, flag %d\n", ti->error_code, ti->error_flag);
free((void*)ti);
}
、一つの選択肢はlpParameterなどの共有メモリ・セグメントへのハンドルを渡すことがあります。ハンドルをDuplicateHandle
経由でリモートプロセスに注入してから、スレッドを起動することができます。スレッドは、戻される前に共有メモリー・セグメントをマップし(まだない場合)、その結果を共有メモリー・セグメントに入れてから、マップ解除してハンドルを閉じることができます。
例えば
、リモートプロセス内:
DWORD WINAPI threadproc(LPVOID arg) {
LPVOID shmem = MapViewOfFile((HANDLE)arg, FILE_MAP_ALL_ACCESS, 0, 0, 4096);
struct threadinfo *ti = (struct threadinfo *)shmem;
// do stuff
ti->error_code = GetLastError();
ti->error_flag = 42;
UnmapViewOfFile(shmem);
CloseHandle((HANDLE)arg);
return 0;
}
そして、呼び出し元のプロセスで:
HANDLE mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, NULL);
LPVOID shmem = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 4096);
struct threadinfo *ti = (struct threadinfo *)shmem;
ti->someArgument = ...;
HANDLE remote_handle;
DuplicateHandle(GetCurrentProcess(), mapping, hRemoteProcess, &remote_handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, startAddress, remote_handle, 0, NULL);
WaitForSingleObject(hRemoteThread);
printf("err %08x flag %d\n", ti->error_code, ti->error_flag);
UnmapViewOfFile(shmem);
CloseHandle(mapping);
構造体へのポインタをリモートスレッドに渡すことはできますか? – wonderer
ああ、私は参照してください。私はCreateThreadではなくCreateRemoteThread()を使用しています。スレッドは別のプロセスのコンテキストで実行されるので、私は構造体へのポインタを送ることができないと思う。 – wonderer
ああ、申し訳ありません - それを見ませんでした。この技術は共有メモリを使用しても動作します。 – bdonlan