WINDOWS核心编程——内核对象(续)

上篇讲到通过DuplicateHandle共享内核对象的用法。下面先讲讲DuplicateHandle另一种用法:

假设一个进程对一个文件映射对象拥有读写权限。在程序的某个位置,调用一个函数,并希望它对文件只有读权限。应该使用DuplicateHandle为现有的对象创建一个新的只有读权限的句柄。然后把这个句柄传给该函数,而不是用原来的句柄。

int WINAPI_tWinMain(HINSTANCE hInstExe, HINSTANCE hPrevInstance, LPTSTR szCmdLine, int nCmdShow){
   HANDLE hFileMapRW = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,
PAGE_READWRITE,0,10240,NULL);

   HANDLE hFileMapRO;

   DuplicateHandle(GetCurrentProcess(), hFileMapRW, GetCurrentProcess(), 
&hFileMapRO, FILE_MAP_READ, FALSE,0);
//......
}
 

下面讨论(内核)对象命名中遗留下来的问题。

终端服务(Terminal Service)和前面的描述有些差别。在运行终端服务的计算机中,有多个内核对象的命名空间。其中一个是全局的,主要由服务使用,每个客户端都能够访问。另外,每个客户端都有自己的内核对象命名空间。

//通过ProcessIdToSessionId获得该进程所在的终端会话。
DWORD processID = GetCurrentProcessId();
DWORD sessionID;
if(ProcessIdToSessionId(processID, &sessioId)){
   tprintf(TEXT("^^^^^^^"));
}else{
  //.............
}

//显示的将内核对象创建在全局命名空间中。
HANDLE h = CreateEvent(NULL,FALSE, FALSE,TEXT("Global\\MyName"));

//显示的将内核对象创建在当前会话的命名空间中。
HANDLE h = CreateEvent(NULL,FALSE, FALSE,TEXT("Local\\MyName"));
 

对于一般的内核对象,我们最好应该模仿上面的方式,创建自己专有的命名空间,从而防止恶意程序的Dos攻击。

相关推荐