NT Service中OpenFileMapping"拒绝访问"错误之分析

最近在写一个双接口的组件,当中用到了内存映射文件的共享:通过启动一个程序 CreateFileMapping创建内存映射,然后在组件OpenFileMapping进行读取.在对双接口的调试中,一切都还顺利:直接在程序中 CoCreateInstanse,或者在windows脚本中CreateObject,组件都很正常的工作.但是当我在一个ASP页面中调用该组件 后,却发现组件出错了.
跟踪程序后发现,组件在OpenFileMapping后返回NULL值,GetLastError返回5,该错误 为"ERROR_ACCESS_DEINED"即"拒绝访问".奇怪的是,在程序和脚本中OpenFileMapping都没有出错,那么ASP执行与脚 本或程序执行的差别是在哪里呢?
在NT系统中运行的IIS,对ASP的解释执行是由World Wide Web Publishing这个服务来完成的,那么ASP脚本中的CreateObject,以及后续的对组件的操作,实际上是由Web服务程序来调用的,因此 ASP执行与脚本(由WScript.exe解释)或程序执行的区别就是:在ASP中,前者的OpenFileMapping是NTService调用 的,而后者是普通的Win32程序调用的.
在NTService中的OpenFileMapping返回"拒绝访问"错误,正是因为CreateFileMapping创建的内存文件对象,在 NTService中对其没有访问权限.我们在使用CreateFileMapping函数时,通常忽略掉了一个参 数"LPSECURITY_ATTRIBUTES lpFileMappingAttributes",我们一般将其置为NULL.MSDN对该参数的描述是,当该值为NULL时,该对象具有默认的访问权 限.而默认的访问权限就是,同一账户启动的所有程序都可以访问该对象,这些程序一般包括我们自己写的Win32程序,windows脚本解释器.
于是我做了一个测试,另外建了一个Administraotrs组的账户,然后用原账户启动服务程序CreateFileMapping,再把我之前运行正常的测试客户程序以新建账户的身份运行,不出所料,我的测试客户程序也出错了,与ASP页面的错误原因是一模一样的.
大部分系统服务(NTService)并不是以当前登录用户的身份启动运行的,它们一般是运行在LocalSystem这个账户 下.LocalSystem这个账户比较有意思,在"计算机管理"中我们看不到这个用户,但它却实实在在存在,只是它只能被本地计算机识别,而无法远程登 录.Web服务也是由LocalSystem启动的,自然它也无法访问由Administrator用户创建的内存映射文件对象.
错误原因分析完了,解决方法自然也就出来了.只要在CreateFileMapping的时候指定一个访问权限即可,这个权限可以允许任何人访问该对象,代码如下:
PSECURITY_DESCRIPTOR pSec = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, SECURITY_DESCRIPTOR_MIN_LENGTH);
if(!pSec)
{
return GetLastError();
}
if(!InitializeSecurityDescriptor(pSec, SECURITY_DESCRIPTOR_REVISION))
{
LocalFree(pSec);
return GetLastError();
}
if(!SetSecurityDescriptorDacl(pSec, TRUE, NULL, TRUE))
{
LocalFree(pSec);
return GetLastError();
}
SECURITY_ATTRIBUTES attr;
attr.bInheritHandle = FALSE;
attr.lpSecurityDescriptor = pSec;
attr.nLength = sizeof(SECURITY_ATTRIBUTES);
HANDLE hFile = CreateFileMapping(INVALID_HANDLE_VALUE, &attr, PAGE_READWRITE, 0, 1024, "test");
LocalFree(pSec);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值