(3)内核对象
何为内核对象
内核对象是Windows操作系统内核分配和访问的对象,每个内核对象对应于一个内存块,该内存块只能由内核分配,访问和释放。该内存块是一个数据结构,维护着与对象相关的信息。少数成员是所有内核对象所共有的,如:安全描述符和使用计数,其他多数成员则是每种内核对象所特有的。
内核对象有很多种,如:访问令牌,事件,文件,文件映射,作业,互斥体,管道,进程,线程,信号量,可等待计时器以及线程池工厂等。可使用一些工具来观察,如:WinObj,Process Explorer等。
内核对象在应用程序中只能通过Windows的一组函数Create*/Open*/CloseHandle以及相应的内核对象句柄(*Handle)来访问,内核对象句柄(32位Windows进程中句柄为32位,64位进程中,句柄也变成64位)是一个不透明值,其具体意义也可能与Windows不同版本的具体实现相关,不过能够确定的是:
使用计数
内核对象安全性
进程的内核对象句柄
每个句柄包含一个索引值,能够只想该表中的一条记录,而该句柄表中每一条记录都是一个数据结构,这个数据结构包含了:
创建内核对象
CreateProcess/CreateThread/CreateFile/CreateFileMapping/CreateMutex/CreateSemaphore
关闭内核对象
关闭内核对象,无论是哪种类型,如何创建的,都使用CloseHandle;如果关闭失败,CloseHandle将返回FALSE。
调用CloseHandle后,将导致进程句柄表中相应的记录被清空,并且将相应内核对象引用计数减1,如果计数变成0则销毁该内核对象。
跨进程共享内核对象
示例:
DWORD currentProcessId=GetCurrentProcessId();
HANDLE hMutexInSource=CreateMutex(NULL, FALSE, _T("MyTestMutex"));
STARTUPINFO si = { sizeof(si) };
si.dwFlags = STARTF_USESHOWWINDOW;
TCHAR cmdline[] =TEXT("c://program files//internet explorer//iexplore.exe http://www.baidu.com/");
if(CreateProcess(NULL, cmdline, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)){
HANDLE hSourceProcess = GetCurrentProcess();
tcout<<"before duplicate handle"<<endl;
//display_process_handles(pi.dwProcessId);
tcout<<"after duplicate handle"<<endl;
//display_process_handles(pi.dwProcessId);
_tprintf(_T(" 新进程的进程ID号:%d\n"), pi.dwProcessId);