代码改变世界

Visual C++ 2011-5-18

  Clingingboy  阅读(764)  评论(0编辑  收藏  举报

 

一.获取进程句柄

参考:http://wenku.baidu.com/view/286c30d084254b35eefd3466.html

二.获取父进程ID

http://www.vckbase.com/bbs/prime/viewprime.asp?id=337

typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);


PROCNTQSIP NtQueryInformationProcess;

DWORD GetParentProcessID(DWORD dwId);

void main(int argc, char* argv[])
{

    NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(
                                            GetModuleHandle("ntdll"),
                                            "NtQueryInformationProcess"
                                            );

    if (!NtQueryInformationProcess)
       return;

    DWORD dwId=2984;
    printf("Parent PID for %lu is %lu\n",dwId,GetParentProcessID(dwId));

}

DWORD GetParentProcessID(DWORD dwId)
{
    LONG                      status;
    DWORD                     dwParentPID = (DWORD)-1;
    HANDLE                    hProcess;
    PROCESS_BASIC_INFORMATION pbi;

    // Get process handle
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwId);
    if (!hProcess)
       return (DWORD)-1;

    // Retrieve information
    status = NtQueryInformationProcess( hProcess,
                                        ProcessBasicInformation,
                                        (PVOID)&pbi,
                                        sizeof(PROCESS_BASIC_INFORMATION),
                                        NULL
                                      );

    // Copy parent Id on success
    if  (!status)
        dwParentPID = pbi.InheritedFromUniqueProcessId;

    CloseHandle (hProcess);

   return dwParentPID;
}

三.Unicode和ANSI互转

来自windows核心编程

  1. Call MultiByteToWideChar, passing NULL for the pWideCharStr parameter and 0 for the cchWideChar parameter and -1 for the cbMultiByte parameter.

  2. Allocate a block of memory large enough to hold the converted Unicode string. This size is computed based on the value returned by the previous call to MultiByteToWideChar multiplied by sizeof(wchar_t).

  3. Call MultiByteToWideChar again, this time passing the address of the buffer as the pWideCharStr parameter and passing the size computed based on the value returned by the first call to MultiByteToWideChar multiplied by sizeof(wchar_t) as the cchWideChar parameter.

  4. Use the converted string.

  5. Free the memory block occupying the Unicode string.

MultiByteToWideChar的使用

char btyeStr[]="hello";
DWORD nLenOfWideCharStr = MultiByteToWideChar(CP_ACP, 0,btyeStr, -1, NULL, 0);
PWSTR pWideCharStr = (PWSTR)HeapAlloc(GetProcessHeap(), 0,nLenOfWideCharStr * sizeof(wchar_t));
ZeroMemory(pWideCharStr,nLenOfWideCharStr * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0,btyeStr, sizeof(btyeStr), pWideCharStr, nLenOfWideCharStr);
HeapFree(GetProcessHeap(), 0, pWideCharStr);

WideCharToMultiByte的使用

char btyeStr[]="hello";
int length=(int)strlen(btyeStr);
ZeroMemory(btyeStr,length);
WideCharToMultiByte(CP_ACP, 0, pWideCharStr, nLenOfWideCharStr * sizeof(wchar_t),
    btyeStr, length, NULL, NULL);

四.WaitForInputIdle

A thread can also suspend itself by calling WaitForInputIdle:

DWORD WaitForInputIdle(
   HANDLE hProcess,
   DWORD dwMilliseconds);

This function waits until the process identified by hProcess has no input pending in the thread that created the application's first window. This function is useful for a parent process. The parent process spawns a child process to do some work. When the parent process' thread calls Create-Process, the parent's thread continues to execute while the child process initializes. The parent's thread might need to get the handle of a window created by the child. The only way for the parent's thread to know when the child process has been fully initialized is to wait until the child is no longer processing any input. So after the call to CreateProcess, the parent's thread places a call to WaitForInputIdle.

参考:

http://www.cnblogs.com/carekee/articles/1748718.html

五.I/O完成端口

理解这个东西花了点时间.

通过两次调用CreateIoCompletionPort方法,其会将一个设备与完成端口关联起来,在内部I/O完成端口会创建一个队列,那么当你对I/O进行读写的时候就可以用GetQueuedCompletionStatus函数来接受,
注意:如果没有读写I/O的话,才GetQueuedCompletionStatus将会阻塞,这其实就是异步I/O完成端口等待的功能,还可以利用PostQueuedCompletionStatus方法向I/O完成端口发送传递信息,其中会有一个键值作为标识,
否则你将无法知道是哪个操作(比如读和写),还要注意的是队列中的执行顺序.

参考:http://www.codeproject.com/KB/IP/IOCompletionPort.aspx

使用CreateIoCompletionPort创建一个I/O完成端口,这里指定了hSource,那么默认将会与hSource关联,然后再次与hDestination关联(CreateIoCompletionPort函数名并不恰当)

hSource = CreateFile(argv[1],
                        GENERIC_READ | GENERIC_WRITE,
                        NULL,
                        NULL,
                        OPEN_EXISTING,
                        FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
                        NULL);
fileSize = GetFileSize(hSource,NULL);
hDestination = CreateFile(argv[2],
                            GENERIC_READ | GENERIC_WRITE,
                            NULL,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
                            NULL);
// Extending the size of the destination file. Read MSDN for more detail.
destFileSize = (fileSize + pageSize - 1) & ~(pageSize-1);
DWORD dwStatus = SetFilePointer(hDestination,
                                destFileSize,
                                NULL,
                                FILE_BEGIN);
BOOL bReturn = SetEndOfFile(hDestination);
// Associate Source file with IO Completion Port.
hIOCompPort = CreateIoCompletionPort(hSource,NULL,read,10);                
// Associate Destination File with IO Completion Port.
hIOCompPort = CreateIoCompletionPort(hDestination,hIOCompPort,write,10);

线程中的方法,GetQueuedCompletionStatus函数,大多数参数均为输出的.

DWORD WINAPI ThreadProc(LPVOID lpParameter) 
{
    BOOL  bSuccess;
    DWORD bytesTransferred;
    DWORD key;
    LPOVERLAPPED overlappedComp;
 
    // Worker Thread will be waiting on IO Completion Port 
    // to process IO Completion packets.
    bSuccess = GetQueuedCompletionStatus(hIOCompPort,
                                            &bytesTransferred,
                                            &key,
                                            &overlappedComp,
                                            (DWORD)-1);

    if( !bSuccess && (overlappedComp == NULL))
    {
        cout<<"::GetQueuedCompletionStatus Failed::"<<endl;
        ExitThread(-1);
    }
}

读写I/O,在main函数中WaitForMultipleObjects是为了防止程序退出,纯演示作用

// Spawing writer threads which will wait for IO packets to be dispatched
// on IO Completion Port.
for (int iThreads = 0; iThreads < g_NoOfThreads; iThreads++)
{
    lpHandle[iThreads] = CreateThread(NULL,NULL,ThreadProc,NULL,0,NULL);                            
}
CopySourceToDestination(fileSize);

WaitForMultipleObjects(g_NoOfThreads,lpHandle,TRUE,60000);

CloseHandle(hDestination);
CloseHandle(hSource);

CopySourceToDestination是真正操作I/O,调用ReadFile异步方法,完成后GetQueuedCompletionStatus就会收到通知,也可以用PostQueuedCompletionStatus函数发送

bSuccess = ReadFile(hSource,
                   lpBufferData[iReadAsynOperations].lpData,
                   BUFFER_SIZE,
                   &bytesRead,
                   &lpBufferData[iReadAsynOperations].overLapped);

另外请参考Windows核心编程,不过其做了部分的封装,学习过程中还是不要做太多封装比较好.

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示