跨越进程边界共享内核对象
来源:互联网 发布:web编程基础 编辑:程序博客网 时间:2024/05/14 13:43
有3个不同的机制 :
1对象句柄的继承性
只有当进程具有父子关系时,才能使用对象句柄的继承性。
首先,当父进程创建内核对象时,必须向系统指明,它希望对象的句柄是个可继承的句柄。请记住,虽然内核对象句柄具有继承性,但是内核对象本身不具备继承性。
若要创建能继承的句柄,父进程必须指定一个SECURITY_A TTRIBUTES结构并对它进行初始化 ,
下 面 的 代 码 用 于 创 建 一 个 互 斥 对 象 ,并将一个可继承的句柄返回给它:
SECURITY_ATTRIBUTES sa;sa.nLength=sizeof(sa);sa.lpSecurityDescriptor=NULL;//默认安全性sa.bInheritHandle=TRUE;//让该句柄具有继承性
HANDLE hMutex = CreateMutex(&sa,FALSE,NULL);
使用对象句柄继承性时要执行的下一个步骤是让父进程生成子进程。这要使用C r e a t eP r o c e s s函数来完成:
BOOL CreateProcess(PCTSTR pszApplicationName,PTSTR pszCommandLine,PSECURITY_ATTRIBUTES psaProcess,PSECURITY_ATTRIBUTES pszThread,BOOL bInheritHandles,DWORD dwCreationFlags,PVOID pvEnviroment,PCTSTR pszCurrentDirectory,LPSTARTUPINFO pStartupInfo,PPROCESS_INFORMATION pProcessInformation);
注意 bInheritHandles这个参数 ,一般 来 说 , 当 生 成 一 个 进 程 时 , 将 为 该 参 数 传 递 FA L S E。 该 值 告 诉 系 统 , 不 希 望 子 进 程 继 承 父 进程的句柄表中的可继承句柄。但是,如果为该参数传递T R U E ,那么子进程就可以继承父进程的可继承句柄值。
除了拷贝句柄表项目外,系统还要递增内核对象的使用计数,因为现在两个进程都使用该对象。如果要撤消内核对象,那么父进程和子进程必须调用该对象上的C l o s e H a n d l e函 数 , 也可以终止进程的运行。
2改变句柄的标志
有时会遇到这样一种情况,父进程创建一个内核对象,以便检索可继承的句柄,然后生成两个子进程。父进程只想要一个子进程来继承内核对象的句柄。
可以调用SeHandleInformation函数:
BOOL SetHandleInformation(HANDLE hObject,DWORD daMask,DWORD dwFlags);
可以看到,该函数拥有 3 个参数。第一个参数h O b j e c t用 于 标 识 一 个 有 效 的 句 柄 。 第 二 个 参数d w M a s k告 诉 该 函 数 想 要 改 变 哪 个 或 那 几 个 标 志 。 目 前 有 两 个 标 志 与 每 个 句 柄 相 关 联 :
#define HANDLE_FLAG_INFERIT 0✖️00000001
#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0✖️00000002
要 打开一个内核对象句柄的继承标志,请创建下面的代码:
SetHandleInformation(hobj,HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
若要关闭该标志,请创建下面的代码:
SetHandleInformation(hobj,HANDLE_FLAG_INHERIT,0);
H A N D L E _ F L A G _ P R O T E C T _ F R O M _ C L O S E标 志 用 于 告 诉 系 统 , 该 句 柄 不 应 该 被 关 闭 :
SetHandleInformation(hobj,HANDLE_FLAG_PROTECT_FROM_CLOSE,HANDLE_FLAG_PROTECT_FROM_CLOSE);CloseHandle(hobj);//Exception is raised
3命名对象
共享跨越进程边界的内核对象的第二种方法是给对象命名 ,下面的所有函数都可以创建命名的内核对象 :
HANDLE CreateMutex(PSECURITY_ATTRIBUTES psa,BOOL bInitialOwner,PCTSTR pszName);..CreateEvent..CreateSemaphore..CreateWaitableTimer..CreateFileMapping..CreateJobObject..
所有这些函数都有一个共同的最后参数 p s z N a m e。当为该参数传递N U L L时,就向系统指明了想创建一个未命名的(匿名)内核对象。
如果试图创建一个称为“ J e ff O b j” 的 对 象 , 那 么 不 能 保 证 系 统 中不存在一个名字为“J e ff O b j” 的 对 象 。 更 为 糟 糕 的 是 , 所 有 这 些 对 象 都 共 享 单 个 名 空 间 。 由 于这个原因,对下面这个C r e a t e S e m a p h o r e函数的调用将总是返回N U L L :
HANDLE hMutex=CreateMutex(NULL,FALSE,"JeffObj");HANDLE hSem=CreateSemaphore(NULL,1,1,"JeffObj");DWORD dwErrorCode=GetLastError();
如果在执行上面的代码后观察d w E r r o r c o d e的值,会看到返回的代码是6(E R R O R _INV ALID_HANDLE)。
应用程序先确定是否创建了一个新内核对象,否则就打开了一个现有的对象。方法是在调用C r e a t e *函数后立即调用G e t L a s t E r r o r:
if(GetLastError()==ERROR_ALREADY_EXISTS){<span style="white-space:pre"></span>//打开一个现有的句柄对象}else{<span style="white-space:pre"></span>//创建一个新句柄对象}
打开一个现有的句柄对象,调用下面显示的O p e n * 函数中的某一个:
HANDLE OpenMutex(DWORD dwDesiredAccess,BOOL bInheritHandle,PCTSTR pszName);..OpenEvent..OpenSemaphore..OpenWaitableTimer..OpenFileMapping..OpenJobObject..
最后一个参数p s z N a m e用 于 指 明 内 核 对 象 的 名 字 。
Window程序防止双开:
i
nt WINAPI WinMain(HINSTANCE hinstExe,HINSTANCE,PSTR pszCmdLine,int nCmdShow){HANDLE h= CreateMutex(NULL,FLASE,"myMutex");if(GetLastError()==ERROR_ALREADY_EXITSTS){//说明已经有一个实例程序在运行,这个试图双开的程序即将结束return 0;}//这里是你的第一个实例程序,依然在运行中...//结束时要把句柄关闭CloseHandle(h);return 0;}
5复制对象句柄
共享跨越进程边界的内核对象的最后一个方法是使用D u p l i c a t e H a n d l e函数 :
BOOL DuplicateHandle(HANDLE hSourceProcessHandle,HANDLE hSourceHandle,HANDLE hTargetProcessHandle,PHANDLE phTargetHandle,DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwOptions);
D u p l i c a t e H a n d l e函数最普通的用法要涉及系统中运行的3个不同进程。
当调用 D u p l i c a t e H a n d l e函数时,第一和第三个参数h S o u r c e P r o c e s s H a n d l e和h Ta rg e tP r o c e s s H a n d l e是内核对象句柄。这些句柄本身必须与调用D u p l i c a t e H a n d l e函 数 的 进 程 相 关 。
第二个参数 h S o u r c e H a n d l e是任何类型的内核对象的句柄。但是该句柄值与调用D u p l i c a t eH a n d l e的进程并无关系。相反,该句柄必须与h S o u r c e P r o c e s s H a n d l e句 柄 标 识 的 进 程 相 关 。 第四个参数phTargetHandle是HANDLE变量的地址,它将接收获取源进程句柄信息拷贝的项目索引。
D u p l i c a t e H a n d l e的最后3个 参 数 用 于 指 明 该 目 标 进 程 的 内 核 对 象 句 柄 表 项 目 中 使 用 的 访 问屏 蔽 值 和 继 承 性 标 志 。d w O p t i o n s参 数 可 以 是0 ( 零 ), 也 可 以 是 下 面 两 个 标 志 的 任 何 组 合 :DUPLICA TE_SAME_ACCESS和DUPLICA TE_CLOSE_SOURCE。
如果设定了DUPLICATE_SAME_ACCESS标志,则告诉DuplicateHandle函数,你希望目标进程的句柄拥有与源进程句柄相同的访问屏蔽。使用该标志将使D u p l i c a t e H a n d l e忽略它的d w D e s i r e d A c c e s s参数。
如果设定了 DUPLICA TE_CLOSE_SOURCE标志,则可以关闭源进程中的句柄。该标志使得一个进程能够很容易地将内核对象传递给另一个进程。当使用该标志时,内核对象的使用计数不会受到影响。
可以像下面这样调用 D u p l i c a t e H a n d l e :
//下面这些代码是运行在Process S//在Process S中创建互次对象HANDLE hObjProcessS=CreateMutes(NULL,FALSE,NULL);//匿名对象//打开Process T的内核对象HANDLE hProcessT=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessIdT);//没有初始化的句柄对象,即将把 hObjProcessS复制给它并属于Process THANDLE hObjProcessT;DuplicateHandle(GetCurrentProcess(),HObjProcessS,hProcessT,&hObjProcessT,0,FALSE,DUPLICATE_SAME_ACESS);....//不再使用ProcessT 时,关闭CloseHandle(hProcessT);//不再使用互斥对象时,CloseHandle(hObjProcessS);//一旦 D u p l i c a t e H a n d l e返回, h O b j P r o c e s s T 就是与 P r o c e s s T 相关的句柄 //一定不要执行下面的代码。//CloseHandle(hObjProcessT);
下面是使用 D u p l i c a t e H a n d l e函 数 的 另 一 种 方 法 。 假 设 一 个 进 程 拥 有 对 一 个 文 件 映 射 对 象 的读和写访问权。在某个位置上,一个函数被调用,它通过读取文件映射对象来访问它。为了使应 用 程 序 更 加 健 壮 , 可 以 使 用D u p l i c a t e H a n d l e为 现 有 的 对 象 创 建 一 个 新 句 柄 , 并 确 保 这 个 新 句柄拥有对该对象的只读访问权。然后将只读句柄传递给该函数,这样,该函数中的代码就永远不会偶然对该文件映射对象执行写入操作。下面这个代码说明了这个例子:
int WINAPI WinMain(HINSTANCE,hinstExe,HINSTANCE,LPSTR szCmdLine,intnCmdShow){HANDLE hFileMapRW= CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,10240,NULL);HANDLE hFileMapRO;DuplicateHandle(GetCurrentProcess(),hFileMapRW,GetCurrentProcess(),&hFileMapRO,FILE_MAP_READ,FALSE,0);ReadFromTheFileMapping(hFileMapRO);//...Read onlyCloseHandle(hFileMapRO);//....Read and writeCloseHandle(hFileMapRW);}
- 3.3 跨越进程边界共享内核对象
- 3.3 跨越进程边界共享内核对象
- 3.3 跨越进程边界共享内核对象
- 跨越进程边界共享内核对象
- 内核对象(2)之跨越边界进程共享内核对象
- windows笔记-跨越进程边界共享内核对象【命名对象】
- -跨越进程边界共享内核对象【复制对象句柄】
- -跨越进程边界共享内核对象【命名对象】
- 跨越进程边界共享内核对象【命名对象】
- 跨越进程边界共享内核对象【复制对象句柄】
- 共享跨越进程边界内核对象的方法?
- windows笔记-跨越进程边界共享内核对象【对象句柄的继承性】
- windows笔记-跨越进程边界共享内核对象【复制对象句柄】
- -跨越进程边界共享内核对象【对象句柄的继承性】
- windows笔记-跨越进程边界共享内核对象【对象句柄的继承性】
- windows笔记-跨越进程边界共享内核对象【复制对象句柄】
- windows笔记-跨越进程边界共享内核对象【对象句柄的继承性】
- windows笔记-跨越进程边界共享内核对象【复制对象句柄】
- Spring In Action 04 ---构建SpringWeb应用程序
- Python异常处理try...except...finally raise assert
- 简单的Hex文件解析
- DOM对象与jQuery对象的理解与分析
- 进入保护模式(一)
- 跨越进程边界共享内核对象
- mysql中的if条件语句
- 进入保护模式(二)
- SAP云采购解决方案入华在即
- 100天土鸡饲养计划(42)
- OS音频开发之音乐播放器 - 后台播放音乐
- WebService发布时java.net.ConnectException: Connection refused错误解决办法
- 进入保护模式(三)
- 操作系统面试题总结