代码改变世界

Visual C++ 2011-5-18

2011-05-20 23:41  Clingingboy  阅读(757)  评论(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核心编程,不过其做了部分的封装,学习过程中还是不要做太多封装比较好.