Question

J'ai créé un fil supplémentaire dans une application petit test et que vous voulez suspendre le thread principal de ce fil supplémentaire. Le fil supplémentaire est créé via CreateRemoteThread d'un processus externe.

Depuis SuspendThread a besoin d'un HANDLE au fil devrait être suspendu, je veux savoir comment obtenir ce HANDLE à partir du code en cours d'exécution dans mon fil supplémentaire.

Était-ce utile?

La solution 2

DWORD GetMainThreadId () {
    const std::tr1::shared_ptr<void> hThreadSnapshot(
        CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0), CloseHandle);
    if (hThreadSnapshot.get() == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("GetMainThreadId failed");
    }
    THREADENTRY32 tEntry;
    tEntry.dwSize = sizeof(THREADENTRY32);
    DWORD result = 0;
    DWORD currentPID = GetCurrentProcessId();
    for (BOOL success = Thread32First(hThreadSnapshot.get(), &tEntry);
        !result && success && GetLastError() != ERROR_NO_MORE_FILES;
        success = Thread32Next(hThreadSnapshot.get(), &tEntry))
    {
        if (tEntry.th32OwnerProcessID == currentPID) {
            result = tEntry.th32ThreadID;
        }
    }
    return result;
}

Autres conseils

Je ne pense pas qu'il y ait quelque chose qui différencie le fil conducteur d'autres threads une fois que le processus a commencé. Cependant, vous pouvez énumèrent toutes les discussions dans le processus , et utiliser GetThreadTimes pour trouver le fil avec le plus tôt de création. OpenThread pour obtenir un HANDLE d'un fil ID.

Obtenez l'ID du sujet avec cette fonction:

/* CAUTION: ONLY x86 TESTED
 * get the thread id of the main thread of a target process
 *
 * params:
 *     DWORD dwPid  process id of the target process
 *
 * return:
 *     Success      thread id
 *     Error        NULL
 */
DWORD GetMainThreadId(DWORD dwPid)
{
    LPVOID lpTid;

    _asm
    {
        mov eax, fs:[18h]
        add eax, 36
        mov [lpTid], eax
    }

    HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, dwPid);
    if(hProcess == NULL)
        return NULL;

    DWORD dwTid;
    if(ReadProcessMemory(hProcess, lpTid, &dwTid, sizeof(dwTid), NULL) == FALSE)
    {
        CloseHandle(hProcess);
        return NULL;
    }

    CloseHandle(hProcess);

    return dwTid;
}

Simple ouvrir le fil pour obtenir la poignée:

/*
 * get a handle to the main thread of a target process
 * if successfull, the returned handle must be closed with CloseHandle()
 *
 * params:
 *     DWORD dwPid              process id of the target process
 *     DWORD dwDesiredAccess    desired access rights to the thread
 *
 * return:
 *     Success      thread handle with desired access rights
 *     Error        NULL
 */
HANDLE GetMainThreadHandle(DWORD dwPid, DWORD dwDesiredAccess)
{
    DWORD dwTid = GetMainThreadId(dwPid);
    if(dwTid == FALSE)
        return NULL;

    return OpenThread(dwDesiredAccess, FALSE, dwTid);
}

Pourquoi ne créez-vous pas seulement un programme à l'échelle mondiale (utilisation extern si vous devez)

HANDLE mainThread ;
DWORD mainThreadId ;

Sur la première ligne du principal, (avant que les fils sont créés) faire

mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;

Vous pouvez utiliser toute forme de IPC de partager l'ID ou la poignée avec le processus distant (ont pas vérifié le partage de la MANCHE fonctionne, mais il se doit!)

Un certain nombre de fonctions API utiles de ce type sont sous le (bien sûr!) Outil d'aide suite . L'API CreateToolhelp32Snapshot() prendra un instantané de les fils en cours d'exécution pour un processus spécifié.

// Take a snapshot of all running threads  
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 
if( hThreadSnap == INVALID_HANDLE_VALUE ) 
  return( FALSE );

Code Exemple complet ici.

Le retour struct ne différencie pas le thread principal des autres. Je ne sais pas un mécanisme pour le faire; tandis que certaines versions du runtime C seront tous ExitProcess () à la fin du fil primaire, dans toutes les versions récentes du processus continue de fonctionner jusqu'à ce que le dernier des sorties de fil.

la recommandation Interjay à utiliser GetThreadTimes peuvent être le meilleur pari. Si vous pouvez CreateProcess() le processus cible, l'élément hThread du bloc PROCESS_INFORMATION contient la TID pour le fil primaire. Bienvenue toutes les idées des autres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top