zoukankan      html  css  js  c++  java
  • Windows NtQueryInformationProcess()

    {

      https://www.orcode.com/article/Processes_20126324.html

    }

    {



    {A}
    {S0}简介
    本文将展示一种方法来读取一个过程的下列项目,主要是使用{A2}进程ID父ID关联掩码退出代码状态命令行过程过程映像文件的路径终端服务会话ID标志,如果目前正在调试过程地址进程环境块(PEB)
    这个信息是一个变量声明为一个结构,smPROCESSINFO返回。这种结构是在NtProcessInfo.h定义:

    typedef struct _smPROCESSINFO
    
    {
    
        DWORD   dwPID;
    
        DWORD   dwParentPID;
    
        DWORD   dwSessionID;
    
        DWORD   dwPEBBaseAddress;
    
        DWORD   dwAffinityMask;
    
        LONG    dwBasePriority;
    
        LONG    dwExitStatus;
    
        BYTE    cBeingDebugged;
    
        TCHAR   szImgPath[MAX_UNICODE_PATH];
    
        TCHAR   szCmdLine[MAX_UNICODE_PATH];
    
    } smPROCESSINFO;

    虽然有Windows API的检索上述值,本文将展示如何获得这些值,而让那些不通过Windows API的。注:此方法使用核心NTDLL.DLL中,这可能在未来的版本中改变结构和功能。 Microsoft建议使用Windows API的"; safelyquot";从系统获得的信息。
    的核心职能,以获取上述信息提供NtProcessInfo.h和NtProcessInfo.cpp。只包含到您的项目H / CPP文件中,引用的职能,并编译。如果这些文件包括在您的项目/解决方案列表,不要忘了排除他们从构建。 sm_GetNtProcessInfo(),主要功能,需要一个过程ID和一个变量声明为smPROCESSINFO。我建议调用的顺序如下(可以被交换的步骤5和6)的功能: sm_EnableTokenPrivilege或您自定义令牌的特权功能,使SE_DEBUG_NAME。sm_LoadNTDLLFunctions。保持免费库后的变量返回的HMODULE。获得进程ID。一个手动指定,或使用EnumProcesses,GetCurrentProcessId,CreateToolhelp32Snapshot等。sm_GetNtProcessInfo进程ID和smPROCESSINFO变量。您的smPROCESSINFO变量/数组的内容输出到您所需的介质。从sm_LoadNTDLLFunctions返回的HMODULE变量sm_FreeNTDLLFunctions。
    本文的演示应用程序是一个基本的Win32,一个ListView共同控制子窗口,以清单的编制过程内容。也可用于在MFC应用程序没有问题的代码。代码是在Visual Studio。NET 2003 SP1的,是Win2K或以后的打算。启用调试特权
    在当前用户读取大多数进程的详细信息,我们必须使调试特权。用户令牌或用户所属的组令牌必须已经调试特权分配。要确定哪些特权令牌,使用{A3}{C}枚举进程ID
    为了得到一个正在运行的进程列表,我们将使用{A4}
    DWORD EnumProcesses2Array(smPROCESSINFO lpi[MAX_PI])
    
    {
    
        DWORD dwPIDs[MAX_PI] = {0};
    
        DWORD dwArraySize    = MAX_PI * sizeof(DWORD);
    
        DWORD dwSizeNeeded   = 0;
    
        DWORD dwPIDCount     = 0;
    
    
    
        //== only to have better chance to read processes =====
    
    
    
        if(!sm_EnableTokenPrivilege(SE_DEBUG_NAME))
    
            return 0;
    
    
    
        // Get a list of Process IDs of current running processes
    
    
    
        if(EnumProcesses((DWORD*)&dwPIDs, dwArraySize, &dwSizeNeeded))
    
        {
    
            HMODULE hNtDll = sm_LoadNTDLLFunctions();
    
    
    
            if(hNtDll)
    
            {
    
                // Get detail info on each process
    
    
    
                dwPIDCount = dwSizeNeeded / sizeof(DWORD);
    
                for(DWORD p = 0; p < MAX_PI && p < dwPIDCount; p++)
    
                {
    
                    if(sm_GetNtProcessInfo(dwPIDs[p], &lpi[p]))
    
                    {
    
                          // Do something else upon success
    
    
    
                    }
    
                }
    
                sm_FreeNTDLLFunctions(hNtDll);
    
            }
    
        }
    
    
    
        // Return either PID count or MAX_PI whichever is smaller
    
    
    
        return (DWORD)(dwPIDCount > MAX_PI) ? MAX_PI : dwPIDCount;
    
    }
    访问NT​​DLL的功能
    NtQueryInformationProcess()函数不导入库,所以我们必须使用{A5}
    typedef NTSTATUS (NTAPI *pfnNtQueryInformationProcess)(
    
        IN  HANDLE ProcessHandle,
    
        IN  PROCESSINFOCLASS ProcessInformationClass,
    
        OUT PVOID ProcessInformation,
    
        IN  ULONG ProcessInformationLength,
    
        OUT PULONG ReturnLength    OPTIONAL
    
        );
    
    
    
    pfnNtQueryInformationProcess gNtQueryInformationProcess;
    
    
    
    
    
    HMODULE sm_LoadNTDLLFunctions()
    
    {
    
        // Load NTDLL Library and get entry address
    
    
    
        // for NtQueryInformationProcess
    
    
    
        HMODULE hNtDll = LoadLibrary(_T("ntdll.dll"));
    
    
    
        if(hNtDll == NULL) return NULL;
    
    
    
        gNtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(hNtDll,
    
                                                            "NtQueryInformationProcess");
    
        if(gNtQueryInformationProcess == NULL) {
    
            FreeLibrary(hNtDll);
    
            return NULL;
    
        }
    
        return hNtDll;
    
    }
    获取进程的基本信息
    我们{A6} PROCESS_QUERY_INFORMATION访问权利得到基本的信息,因为我们将使用ReadProcessMemory()函数来读取在PEB过程,这个过程还必须打开PROCESS_VM_READ访问权。
    // Attempt to access process
    
    
    
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | 
    
                                  PROCESS_VM_READ, FALSE, dwPID);
    
    if(hProcess == INVALID_HANDLE_VALUE)
    
    {
    
         return FALSE;
    
    }

    现在,我们为我们的PROCESS_BASIC_INFORMATION结构变量分配内存。
    // Try to allocate buffer 
    
    
    
    hHeap = GetProcessHeap();
    
    
    
    dwSize = sizeof(smPROCESS_BASIC_INFORMATION);
    
    
    
    pbi = (smPPROCESS_BASIC_INFORMATION)HeapAlloc(hHeap,
    
                                                  HEAP_ZERO_MEMORY,
    
                                                  dwSize);
    
    // Did we successfully allocate memory
    
    
    
    if(!pbi) {
    
        CloseHandle(hProcess);
    
        return FALSE;
    
    }

    这个结构定义在winternl.h和ntddk.h。下面的定义是从WIN2003 {A7} ntddk.h,因为我winternl.h在Visual Studio 2003和微软MSDN之一不包含尽可能多的细节。我还发现,winternl.h和ntddk.h在编译过程中的相互冲突,所以我决定复制一个新的名字在我的头文件NtProcessInfo.h(包括下载)(作为前缀添加SM)的最新定义。
    typedef struct _smPROCESS_BASIC_INFORMATION {
    
        LONG ExitStatus;
    
        smPPEB PebBaseAddress;
    
        ULONG_PTR AffinityMask;
    
        LONG BasePriority;
    
        ULONG_PTR UniqueProcessId;
    
        ULONG_PTR InheritedFromUniqueProcessId;
    
    } smPROCESS_BASIC_INFORMATION, *smPPROCESS_BASIC_INFORMATION;

    然后,我们通过NtQueryInformationProcess()函数得到一个进程的基本信息。
    // Attempt to get basic info on process
    
    
    
    NTSTATUS dwStatus = gNtQueryInformationProcess(hProcess,
    
                                                   ProcessBasicInformation,
    
                                                   pbi,
    
                                                   dwSize,
    
                                                   &dwSizeNeeded);
    
    // Did we successfully get basic info on process
    
    
    
    if(dwStatus >= 0)
    
    {
    
        // Basic Info
    
    
    
        spi.dwPID            = (DWORD)pbi->UniqueProcessId;
    
        spi.dwParentPID      = (DWORD)pbi->InheritedFromUniqueProcessId;
    
        spi.dwBasePriority   = (LONG)pbi->BasePriority;
    
        spi.dwExitStatus     = (NTSTATUS)pbi->ExitStatus;
    
        spi.dwPEBBaseAddress = (DWORD)pbi->PebBaseAddress;
    
        spi.dwAffinityMask   = (DWORD)pbi->AffinityMask;
    读在PEB
    从基本的信息,我们已经得到PebBaseAddress指针变量PEB的基地址,如果有的话,。如果地址是不等于零,我们刚刚通过的ReadProcessMemory()函数的地址。如果成功的话,它应该在我们的{A8}结构变量,其中还包含BeingDebugged和SessionID变量返回的信息的过程。
    // Read Process Environment Block (PEB)
    
    
    
    if(pbi->PebBaseAddress)
    
    {
    
        if(ReadProcessMemory(hProcess, pbi->PebBaseAddress, &peb, sizeof(peb), &dwBytesRead))
    
        {
    
            spi.dwSessionID    = (DWORD)peb.SessionId;
    
            spi.cBeingDebugged = (BYTE)peb.BeingDebugged;

    在PEB结构的定义为:
    typedef struct _smPEB {
    
        BYTE Reserved1[2];
    
        BYTE BeingDebugged;
    
        BYTE Reserved2[1];
    
        PVOID Reserved3[2];
    
        smPPEB_LDR_DATA Ldr;
    
        smPRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    
        BYTE Reserved4[104];
    
        PVOID Reserved5[52];
    
        smPPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    
        BYTE Reserved6[128];
    
        PVOID Reserved7[1];
    
        ULONG SessionId;
    
    } smPEB, *smPPEB;

    从这一点来说,我们也有内存地址LDR,这是我们本文中未使用。基本上,{A9}
    // We got Process Parameters, is CommandLine filled in
    
    
    
    if(peb_upp.CommandLine.Length > 0) {
    
        // Yes, try to read CommandLine
    
    
    
        pwszBuffer = (WCHAR *)HeapAlloc(hHeap,
    
                                        HEAP_ZERO_MEMORY,
    
                                        peb_upp.CommandLine.Length);
    
        // If memory was allocated, continue
    
    
    
        if(pwszBuffer)
    
        {
    
           if(ReadProcessMemory(hProcess,
    
                                peb_upp.CommandLine.Buffer,
    
                                pwszBuffer,
    
                                peb_upp.CommandLine.Length,
    
                                &dwBytesRead))
    
           {
    
                // if commandline is larger than our variable, truncate
    
    
    
                if(peb_upp.CommandLine.Length >= sizeof(spi.szCmdLine)) 
    
                    dwBufferSize = sizeof(spi.szCmdLine) - sizeof(TCHAR);
    
                else
    
                    dwBufferSize = peb_upp.CommandLine.Length;
    
                                
    
                // Copy CommandLine to our structure variable
    
    
    
    #if defined(UNICODE) || (_UNICODE)
    
                // Since core NT functions operate in Unicode
    
    
    
                // there is no conversion if application is
    
    
    
                // compiled for Unicode
    
    
    
                StringCbCopyN(spi.szCmdLine, sizeof(spi.szCmdLine),
    
                              pwszBuffer, dwBufferSize);
    
    #else
    
                // Since core NT functions operate in Unicode
    
    
    
                // we must convert to Ansi since our application
    
    
    
                // is not compiled for Unicode
    
    
    
                WideCharToMultiByte(CP_ACP, 0, pwszBuffer,
    
                                    (int)(dwBufferSize / sizeof(WCHAR)),
    
                                    spi.szCmdLine, sizeof(spi.szCmdLine),
    
                                    NULL, NULL);
    
    #endif
    
            }
    
            if(!HeapFree(hHeap, 0, pwszBuffer)) {
    
                // failed to free memory
    
    
    
                bReturnStatus = FALSE;
    
                goto gnpiFreeMemFailed;
    
            }
    
        }
    
    }    // Read CommandLine in Process Parameters

    ... ... ImagePathName变量{A10}
    // We got Process Parameters, is ImagePathName filled in
    
    
    
    if(peb_upp.ImagePathName.Length > 0) {
    
        // Yes, try to read Image Path
    
    
    
        pwszBuffer = (WCHAR *)HeapAlloc(hHeap,
    
                                        HEAP_ZERO_MEMORY,
    
                                        peb_upp.ImagePathName.Length);
    
        // If memory was allocated, continue
    
    
    
        if(pwszBuffer)
    
        {
    
           if(ReadProcessMemory(hProcess,
    
                                peb_upp.ImagePathName.Buffer,
    
                                pwszBuffer,
    
                                peb_upp.ImagePathName.Length,
    
                                &dwBytesRead))
    
           {
    
                // if image path is larger than our variable, truncate
    
    
    
                if(peb_upp.ImagePathName.Length >= sizeof(spi.szImgPath)) 
    
                    dwBufferSize = sizeof(spi.szImgPath) - sizeof(TCHAR);
    
                else
    
                    dwBufferSize = peb_upp.ImagePathName.Length;
    
                                
    
                // Copy ImagePathName to our structure variable
    
    
    
    #if defined(UNICODE) || (_UNICODE)
    
                // Since core NT functions operate in Unicode
    
    
    
                // there is no conversion if application is
    
    
    
                // compiled for Unicode
    
    
    
                StringCbCopyN(spi.szImgPath, sizeof(spi.szImgPath),
    
                              pwszBuffer, dwBufferSize);
    
    #else
    
                // Since core NT functions operate in Unicode
    
    
    
                // we must convert to Ansi since our application
    
    
    
                // is not compiled for Unicode
    
    
    
                WideCharToMultiByte(CP_ACP, 0, pwszBuffer,
    
                                    (int)(dwBufferSize / sizeof(WCHAR)),
    
                                    spi.szImgPath, sizeof(spi.szImgPath),
    
                                    NULL, NULL);
    
    #endif
    
            }
    
            if(!HeapFree(hHeap, 0, pwszBuffer)) {
    
                // failed to free memory
    
    
    
                bReturnStatus = FALSE;
    
                goto gnpiFreeMemFailed;
    
            }
    
        }
    
    }    // Read ImagePathName in Process Parameters

    (PID = 4在XP上WIN2K后,8,并在NT 4 2)对于系统的过程中,我们手动指定进程的路径,因为我们知道它是%SystemRoot% SYSTEM32 NTOSKRNL.EXE但不是由API返回。 NTOSKRNL.EXE也可以被NTKRNLMP.EXE {A11}
    // System process for WinXP and later is PID 4 and we cannot access
    
    // PEB, but we know it is aka ntoskrnl.exe so we will manually define it
    
    
    
    if(spi.dwPID == 4)
    
    {
    
        ExpandEnvironmentStrings(_T("%SystemRoot%\System32\ntoskrnl.exe"),
    
                                 spi.szImgPath, sizeof(spi.szImgPath));
    
    }

    上述与PROCESS_BASIC_INFORMATION结构,{A12}
    typedef struct _smRTL_USER_PROCESS_PARAMETERS {
    
        BYTE Reserved1[16];
    
        PVOID Reserved2[10];
    
        UNICODE_STRING ImagePathName;
    
        UNICODE_STRING CommandLine;
    
    } smRTL_USER_PROCESS_PARAMETERS, *smPRTL_USER_PROCESS_PARAMETERS;
    净化
    在这里,我们免费NTDLL.DLL中我们前面加载。这就是它!
    void sm_FreeNTDLLFunctions(HMODULE hNtDll)
    
    {
    
        if(hNtDll)
    
           FreeLibrary(hNtDll);
    
        gNtQueryInformationProcess = NULL;
    
    }
    兴趣点
    我写这篇文章分享我学到的方法,而试图得到我自己的经验,而无需使用简单的{A13}一个基本的过程中浏览器的进程信息。
    一些quot; safequot; Windows API函数来获得另一个进程的信息是:ProcessIdToSessionIdCheckRemoteDebuggerPresentGetExitCodeProcessGetProcessAffinityMaskGetProcessImageFileNameCreateRemoteThread的其他{A14}
    注:我没有在演示应用程序的调试过程中收到以下消息,但出现之前发生,以WinMain的,似乎是因为第二次机会没有抛出异常处理:
    "First-chance exception at 0x7c918fea in GetNtProcessInfo.exe: 
    
                  0xC0000005: Access violation writing location 0x00000010."

    我没有得到与现实世界实现NtProcessInfo.h和NtProcessInfo.cpp此异常。历史最初的版本。

    回答

     
    评论会员:jlkdaslkfjd 时间:2011/12/14
    谢谢你张贴,GetProcessimagefilename现在已经一个星期的痛苦
    但我只是想知道,如果有什么办法可以在Vb.net?

    'All the code I could scrape together
    
    'Some of these functions are VB6, I tried converting Strptr,varptr etc..
    
    Imports Microsoft.VisualBasic
    
    Imports System.Runtime.InteropServices
    
    Public Class getimagefilename
    
        Private Const ProcessImageFileName = 27
    
        Private Const STATUS_INFO_LENGTH_MISMATCH = &HC0000004
    
        Private Const PROCESS_QUERY_INFORMATION = &H400&
    
        Private Const PROCESS_VM_READ = &H10&
    
        Private Const HEAP_ZERO_MEMORY = &H8&
    
        Private Const MAX_PATH = 260
    
        Private Structure UNICODE_STRING
    
            Dim Length As Integer
    
            Dim MaximumLength As Integer
    
            Dim Buffer As Long
    
        End Structure
    
        Private Declare Function GetProcessHeap Lib "kernel32.dll" () As Long
    
        Private Declare Function HeapAlloc Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
    
        Private Declare Function HeapFree Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal lpMem As Long) As Long
    
        Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessid As Long) As Long
    
        Private Declare Function NtQueryInformationProcess Lib "ntdll.dll" (ByVal ProcessHandle As Long, ByVal ProcessInformationClass As Long, ByVal ProcessInformation As Long, ByVal ProcessInformationLength As Long, ByRef ReturnLength As Long) As Long
    
        Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
    
        Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (ByVal lpDest As Long, ByVal lpSource _ 
    
    As Long, ByVal cbCopy As Long)
    
     
    
        Public Function VarPtr(ByVal e As Object) As Integer
    
            Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)
    
            Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32
    
            GC.Free()
    
            Return GC2
    
        End Function
    
        Public Function strptr(ByVal source As String, ByVal dest As String) As String
    
            Return dest = dest.Insert(0, source)
    
        End Function
    
     
    
        Public Function GetProcessNameByPid(ByVal pid As Long) As String
    
            Dim uni As UNICODE_STRING
    
            Dim Buffer As Long
    
            Dim hProcess As Long
    
            Dim FileName As String
    
            Dim cbNeeded As Long
    
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, pid)
    
            If hProcess = 0 Then
    
            Else
    
                ' Get the buffer size needed for the call.
    
                If NtQueryInformationProcess(hProcess, ProcessImageFileName, VarPtr(uni), 8, cbNeeded) = STATUS_INFO_LENGTH_MISMATCH Then
    
                    ' Allocate the required buffer from the heap.
    
                    Buffer = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, cbNeeded)
    
                    If NtQueryInformationProcess(hProcess, ProcessImageFileName, Buffer, cbNeeded, cbNeeded) = 0 Then
    
                        ' UNICODE_STRING
    
                        RtlMoveMemory(VarPtr(uni), Buffer&, Len(uni))
    
                        FileName = Strings.Left(uni.Length / 2, vbNullChar)
    
                        RtlMoveMemory(strptr(FileName, FileName), uni.Buffer, uni.Length)
    
                        Return FileName
    
                    End If
    
                    HeapFree(GetProcessHeap, 0, Buffer)
    
                End If
    
            End If
    
          
    
            CloseHandle(hProcess)
    
        End Function
    
     
    
    End Class
    
    
     
    评论会员:zinodream 时间:2011/12/14
    我编译成功

    感谢
    修改上,3月29日(星期一),2010 0:25
     
    评论会员:baron43 时间:2011/12/14
    。通缉致以谢意缺少魔法酱,制作精良的代码

    我有一个过程的阅读器应用程序(,因为每个人),但我是越来越少的进程在任务管理器,然后在"Iarsn TaskInfo"计划上市。一个非常关键的一块,使DEGUG privaledges令牌。
    你是唯一的编程细节这非常关键的一点,我所看到的许多代码和程序样本。
    谢谢你们,让您的旅途好运!

    荃湾
     
    评论会员:。Chury 时间:2011/12/14
    BOOL sm_EnableTokenPrivilege(​​LPCTSTR pszPrivilege)
    {处理hToken = 0;TOKEN_PRIVILEGES TKP = {0}

    / /获取了这一进程的令牌。
    如果(OpenProcessToken(GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES |
    TOKEN_QUERY,放大器; hToken))
    {
    返回FALSE;
    }

    / /获取特权的LUID。
    (LookupPrivilegeValue(NULL,pszPrivilege,
    安培。tkp.Privileges [0] LUID))
    {
    & #160; tkp.PrivilegeCount = 1; / /一个权限设置
    tkp.Privileges [0]属性= SE_PRIVILEGE_ENABLED;

    / /设置为这一进程的特权。
    AdjustTokenPrivileges(hToken,FALSE,则放大器; TKP,0,
    (PTOKEN_PRIVILEGES)NULL,0);

    如果(GetLastError函数()!= ERROR_SUCCESS)
    返回FALSE;
    返回TRUE;}

    返回FALSE;
    }

    这种方法是发生句柄泄漏...

    所以..下面的

    BOOL sm_EnableTokenPrivilege(​​LPCTSTR pszPrivilege)
    {处理hToken = 0;TOKEN_PRIVILEGES TKP = {0}
    BOOL bResult = FALSE;
    / /获取这个过程中的信物。
    如果(OpenProcessToken(GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES |
    TOKEN_QUERY,放大器; hToken))
    {
    &# 160;返回FALSE;
    }

    / /获取特权的LUID。
    (LookupPrivilegeValue(NULL,pszPrivilege,
    安培。tkp.Privileges [0] LUID))
    {
    tkp.PrivilegeCount = 1; / /一个权限设置
    tkp.Privileges [0]属性= SE_PRIVILEGE_ENABLED;

    / /设置为这一进程的特权。
    AdjustTokenPrivileges(hToken,FALSE,则放大器; TKP,0,
    (PTOKEN_PRIVILEGES)NULL,0);

    如果(GetLastError函数()== ERROR_SUCCESS)
    bResult = TRUE;
    }


    CloseHandle(hToken);返回bResult;
    }

    THX ...

    11
     
    评论会员:gabrielmaldi 时间:2011/12/14
    您好,

    我下载的,这与VC 6工程的最后一个平台SDK(二月
    2003年):http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm

    然而IM得到一个奇怪的错误,当我编译。我做的是
    以下内容:

    - 从开始菜单运行这个快捷方式来设置变量:设置Windows
    XP的32位编译环境(零售)。LNK

    - 打开VC 6,创建一个新的Win32简单的应用程序

    - 包括winternl.h

    这是代码:

    #包括"stdafx.h中"


    INT APIENTRY的WinMain(HINSTANCE HINSTANCE,HINSTANCE hPrevInstance,
    INT LPSTR lpCmdLine,nCmdShow){
     0;PROCESS_BASIC_INFORMATION P;

    返回0;
    }

    编译时,我得到这些错误:

    错误C2065:'PROCESS_BASIC_INFORMATION":未声明的标识符
    错误C2146:语法错误:缺少";"前标识符'P'
    错误C2065:"P":未声明的标识符

    包括是正确的,但仍认为(任何)成员从
    头不被认可。
    如果我使用其他头(只试过一对夫妇)一切正常。

    任何想法?
     
    评论会员:open_mind_core 时间:2011/12/14
    它是一个无论是暂停或无NTDLL,suspendthread / ResumeThread线程的状态可以查询?
     
    评论会员:OrionScorpion 时间:2011/12/14
    在2006年1月MSDN库,它说:"NtQueryInformationProcess是在Windows 2000和Windows XP中使用,它可能会改变或在后续版本中不可用的应用程序应该使用列在候补功能。这个话题。"

    但在目前的DVD的MSDN库,这是使先进的我可以不甚至管理的"帮助"菜单中的版本的邮票的,它只是说"[NtQueryInformationProcess可能被改变或在未来的Windows版本中不可用的应用程序应该使用的第二功能本主题中列出。]",和在线的MSDN说同样的事情。

    我没有实际测试,诱惑来推断,他们留在Vista的功能,但谁知道什么政策将在下一个版本中,HMM的呢?

    PG - AZ

    }

  • 相关阅读:
    LINQ学习(1)
    [转]键盘上的标点符号的中英文名称对照表
    微信Android ANR原理解析及解决方案
    IOS错误日志抓取和分析
    蚂蚁金服测开面试题--转账功能
    MySQL CONV()函数
    分页功能
    在alert里面加入一个页面,子页面传值父页面
    com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; che
    缘起 网络编程
  • 原文地址:https://www.cnblogs.com/YZFHKMS-X/p/11869872.html
Copyright © 2011-2022 走看看