2.内核对象之<创建和关闭内核对象,跨进程共享>

当一个进程被初始化时,系统要为它分配一个句柄表.这个句柄表只用于内核对象,不用于用户对象或GDI对象.进程句柄表是一个数据结构的数组,每个结构都包括一个指向内核对象的指针,一个访问屏蔽和一些标志.

当进程初次被初始化时,它的句柄表是空的.当进程中的线程调用创建内核对象的函数后时,内核就为该对象分配一个内存块,并将其初始化.这时,内核对进程的句柄表进行扫描,找到一个空项.将该索引位置上结构中的指针成员设置为该内核对象数据结构的内存地址,并设置访问屏蔽,以及标志位.

1 function CreateEvent(lpEventAttributes: PSecurityAttributes;   
2 bManualReset, bInitialState: BOOL; lpName: PChar): THandle; stdcall;
3 function CreateFileMapping(hFile: THandle; lpFileMappingAttributes: PSecurityAttributes;
4 flProtect, dwMaximumSizeHigh, dwMaximumSizeLow: DWORD; lpName: PChar): THandle; stdcall;
5 function CreateSemaphore(lpSemaphoreAttributes: PSecurityAttributes;
6 lInitialCount, lMaximumCount: Longint; lpName: PChar): THandle; stdcall;

如果返回是0(NULL,nil),原因可能是系统内存非常短缺,或者遇到了安全问题.有少数函数返回的句柄值为-1(INVALID_HANDLE_VALUE),比如CreateFile无法打开指定的文件,那么它将返回INVALID_HANDLE_VALUE,而不是0.

关闭内核对象,之前已经提过,用CloseHandle函数:

1 function CloseHandle(hObject: THandle): BOOL; stdcall; 

如果传递一个无效句柄,那么该函数会返回一个False.

文件映射对象使你能够在同一台机器上运行的两个进程之间共享数据块.
邮箱和指定的管道使得应用程序能够在联网的不同机器上运行的进程之间发送数据块.
互斥对象,信标和事件使得不同进程中的线程能够同步它们的连续运行,这与一个应用程序在完成某项任务时需要将情况通知另一个应用程序的情况相同.

因为这些应用,在不同的进程需要共享内核对象.
内核对象的句柄是与进程相关的.如果内核对象句柄是系统相关的,那么不同进程间直接使用内核对象,可能对其他进程造成很大的破坏.内核对象的安全性要求内核对象在使用时,必须申请操作该对象的许可权(前提是该对象创建时设置了安全性描述符).那么只要在创建对象时设置安全性描述符,就可以防止未经授权的用户接触该对象.
共享对象有几种不同的机制.
1.对象句柄的继承性,改变句柄的标志.
2.命名对象.中断服务器的名字空间.
3.复制对象句柄,DuplicateHandle.

1 function DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle: THandle;   
2 lpTargetHandle: PHandle; dwDesiredAccess: DWORD;
3 bInheritHandle: BOOL; dwOptions: DWORD): BOOL; stdcall;

写太多就等于直接抄书了,有兴趣可以参考.

原文地址:https://www.cnblogs.com/solokey/p/2126607.html