C/C++ Windows API——线程挂起、唤醒与终止

举报
福州司马懿 发表于 2021/11/19 04:31:19 2021/11/19
【摘要】 // ThreadDemo.cpp : Defines the entry point for the console application. // #include "stdafx.h" #incl...
// ThreadDemo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>//GetModuleFileNameEx

int main()
{
    BOOL ret;
    DWORD dwFlags = TH32CS_SNAPTHREAD;
    HANDLE snapshotHandle = CreateToolhelp32Snapshot(dwFlags, 0);
    if (snapshotHandle == NULL || snapshotHandle == INVALID_HANDLE_VALUE) {
        printf("CreateToolhelp32Snapshot -> processHandle=%p(NULL or INVALID_HANDLE_VALUE) -> fail(%ld)\n", snapshotHandle, GetLastError());
    }
    else {
        printf("CreateToolhelp32Snapshot -> processHandle=%p -> succ\n", snapshotHandle);

        /*
        typedef struct tagTHREADENTRY32 {
        DWORD   dwSize;             //指定结构的长度,以字节为单位。如果你不初始化的dwSizeThread32First将调用失败。
        DWORD   cntUsage;           //deprecated, always zero
        DWORD   th32ThreadID;       // this thread
        DWORD   th32OwnerProcessID; // Process this thread is associated with
        LONG    tpBasePri;          //线程在内核中分配的优先级,tpBasePri值为0到31, 0为最低优先级,更多的信息请看KeQueryPriorityThread
        LONG    tpDeltaPri;         //deprecated, always zero
        DWORD   dwFlags;            //deprecated, always zero
        } THREADENTRY32;
        */
        THREADENTRY32 threadEntry32 = { 0 };
        threadEntry32.dwSize = sizeof(THREADENTRY32);
        /*
        BOOL WINAPI Thread32First(
        HANDLE hSnapshot,
        LPTHREADENTRY32 lpte
        );
        */
        BOOL hasNext = Thread32First(snapshotHandle, &threadEntry32);
        if (!hasNext) {
            printf("Thread32First processHandle=%p -> fail(%ld)\n", snapshotHandle, GetLastError());
        }
        while (hasNext) {
            printf("Thread32Next -> th32ThreadID=%ld, th32OwnerProcessID=%ld, tpBasePri=%ld -> succ\n", threadEntry32.th32ThreadID, threadEntry32.th32OwnerProcessID, threadEntry32.tpBasePri);

            /*
            WINBASEAPI HANDLE WINAPI OpenProcess(
            _In_ DWORD dwDesiredAccess,
            _In_ BOOL bInheritHandle,
            _In_ DWORD dwProcessId
            );

            #define PROCESS_TERMINATE                  (0x0001)
            #define PROCESS_CREATE_THREAD              (0x0002)
            #define PROCESS_SET_SESSIONID              (0x0004)
            #define PROCESS_VM_OPERATION               (0x0008)
            #define PROCESS_VM_READ                    (0x0010)
            #define PROCESS_VM_WRITE                   (0x0020)
            #define PROCESS_DUP_HANDLE                 (0x0040)
            #define PROCESS_CREATE_PROCESS             (0x0080)
            #define PROCESS_SET_QUOTA                  (0x0100)
            #define PROCESS_SET_INFORMATION            (0x0200)
            #define PROCESS_QUERY_INFORMATION          (0x0400)
            #define PROCESS_SUSPEND_RESUME             (0x0800)
            #define PROCESS_QUERY_LIMITED_INFORMATION  (0x1000)
            #define PROCESS_SET_LIMITED_INFORMATION    (0x2000)
            #if (NTDDI_VERSION >= NTDDI_VISTA)
            #define PROCESS_ALL_ACCESS        (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ 0xFFFF)
            #else
            #define PROCESS_ALL_ACCESS        (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ 0xFFF)
            #endif
            */
            DWORD dwProcessDesiredAccess = PROCESS_ALL_ACCESS;
            BOOL bInheritHandle = FALSE;
            DWORD dwProcessID = threadEntry32.th32OwnerProcessID;
            HANDLE processHandle = OpenProcess(dwProcessDesiredAccess, bInheritHandle, dwProcessID);
            if (processHandle == NULL || processHandle == INVALID_HANDLE_VALUE) {
                printf("OpenProcess dwProcessID=%ld -> processHandle=%p(NULL or INVALID_HANDLE_VALUE) -> fail(%ld)\n", dwProcessID, processHandle, GetLastError());
            }
            else {
                printf("OpenProcess dwProcessID=%ld -> processHandle=%p -> succ\n", dwProcessID, processHandle);

                /*
                _Success_(return != 0)
                _Ret_range_(1, nSize)
                DWORD WINAPI GetModuleFileNameExW(
                    _In_opt_ HANDLE hProcess,
                    _In_opt_ HMODULE hModule,
                    _When_(return < nSize, _Out_writes_to_(nSize, return + 1))
                    _When_(return == nSize, _Out_writes_all_(nSize))
                    LPTSTR lpFilename,
                    _In_ DWORD nSize
                );

                If the function succeeds, the return value specifies the length of the string copied to the buffer.
                If the function fails, the return value is zero. To get extended error information, call GetLastError.
                */
                HMODULE hModule = NULL;
                const DWORD nSize = MAX_PATH;
                TCHAR lpFilename[nSize];
                DWORD dwRet = GetModuleFileNameEx(processHandle, hModule, lpFilename, nSize);
                if (dwRet == 0) {
                    printf("GetModuleFileNameEx processHandle=%p -> fail(%ld)\n", processHandle, GetLastError());
                }
                else {
                    _tprintf(_T("GetModuleFileNameEx processHandle=%p -> fileName=%s\n"), processHandle, lpFilename);
                }

                if (_tcsstr(lpFilename, _T("notepad.exe"))) {
                    /*
                    WINBASEAPI _Ret_maybenull_ HANDLE WINAPI OpenThread(
                    _In_ DWORD dwDesiredAccess,
                    _In_ BOOL bInheritHandle,
                    _In_ DWORD dwThreadId
                    );

                    dwDesiredAccess可以是如下值(OpenThread和OpenProcess类似)
                    #define THREAD_TERMINATE                 (0x0001)
                    #define THREAD_SUSPEND_RESUME            (0x0002)
                    #define THREAD_GET_CONTEXT               (0x0008)
                    #define THREAD_SET_CONTEXT               (0x0010)
                    #define THREAD_QUERY_INFORMATION         (0x0040)
                    #define THREAD_SET_INFORMATION           (0x0020)
                    #define THREAD_SET_THREAD_TOKEN          (0x0080)
                    #define THREAD_IMPERSONATE               (0x0100)
                    #define THREAD_DIRECT_IMPERSONATION      (0x0200)
                    // begin_wdm
                    #define THREAD_SET_LIMITED_INFORMATION   (0x0400)  // winnt
                    #define THREAD_QUERY_LIMITED_INFORMATION (0x0800)  // winnt
                    #define THREAD_RESUME                    (0x1000)  // winnt
                    #if (NTDDI_VERSION >= NTDDI_VISTA)
                    #define THREAD_ALL_ACCESS         (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ 0xFFFF)
                    #else
                    #define THREAD_ALL_ACCESS         (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ 0x3FF)
                    #endif
                    */
                    DWORD dwDesiredAccess = THREAD_TERMINATE | THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION;
                    BOOL bInheritHandle = FALSE;
                    DWORD dwThreadId = threadEntry32.th32ThreadID;
                    //打开句柄后都要记得关闭
                    HANDLE threadHandle = OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId);
                    if (threadHandle == NULL || threadHandle == INVALID_HANDLE_VALUE) {
                        printf("OpenThread dwThreadId=%ld -> threadHandle=%p(NULL or INVALID_HANDLE_VALUE) -> fail(%ld)\n", dwThreadId, threadHandle, GetLastError());
                    }
                    else {
                        printf("OpenThread -> threadHandle=%p -> succ\n", threadHandle);
                        /*
                        WINBASEAPI DWORD WINAPI SuspendThread(
                        _In_ HANDLE hThread
                        );

                        If the function succeeds, the return value is the thread's previous suspend count;
                        otherwise, it is (DWORD) -1. To get extended error information, use the GetLastError function.
                        */
                        DWORD preSuspendCnt = SuspendThread(threadHandle);
                        if (preSuspendCnt == -1) {
                            printf("SuspendThread -> fail(%ld)\n", GetLastError());
                        }
                        else {
                            printf("SuspendThread -> preSuspendCnt=%d -> succ\n", preSuspendCnt);
                        }

                        /*
                        WINBASEAPI DWORD WINAPI ResumeThread(
                        _In_ HANDLE hThread
                        );

                        If the function succeeds, the return value is the thread's previous suspend count.
                        If the function fails, the return value is (DWORD) -1. To get extended error information, call GetLastError.
                        */
                        preSuspendCnt = ResumeThread(threadHandle);
                        if (preSuspendCnt == -1) {
                            printf("ResumeThread -> fail(%ld)\n", GetLastError());
                        }
                        else {
                            printf("ResumeThread -> preSuspendCnt=%d -> succ\n", preSuspendCnt);
                        }
                        /*
                        WINBASEAPI BOOL WINAPI TerminateThread(
                        _In_ HANDLE hThread,
                        _In_ DWORD dwExitCode
                        );
                        */
                        ret = TerminateThread(threadHandle, 0);
                        if (ret) {
                            printf("TerminateThread -> succ\n");
                        }
                        else {
                            printf("TerminateThread -> fail(%ld)\n", GetLastError());
                        }

                        ret = CloseHandle(threadHandle);
                        if (ret) {
                            printf("CloseHandle thread -> ret=%d\n", ret);
                        }
                        else {
                            printf("CloseHandle thread -> ret=%d -> fail(%ld)\n", ret, GetLastError());
                        }
                    }
                }
                CloseHandle(processHandle);
            }
            hasNext = Thread32Next(snapshotHandle, &threadEntry32);
            if (!hasNext) {
                //遍历完线程的时候Thread32Next会设置错误码10,为环境错误
                printf("Thread32Next handle=%p -> fail(%ld)\n", snapshotHandle, GetLastError());
            }
        }
        ret = CloseHandle(snapshotHandle);
    }

    system("pause");
    return 0;
}
  
 
  • 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
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214

这里写图片描述

文章来源: blog.csdn.net,作者:福州-司马懿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/chy555chy/article/details/52896653

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。