当由Windows Service生成的进程调用CreateMutex()时,失败并显示ERROR_ACCESS_DENIED

沙绍尔姆

我只是花了几天的时间来寻找一个错误,该错误是由于对:: CreateMutex()的调用失败而引发未处理的异常而导致的。请记住CreateMutex(),不要试图打开互斥锁,而只是打开一个手柄。即使互斥锁已经存在它也不会失败,至少只要我将bInitialOwner设置为FALSE即可。

但是,如果我::CreateMutexA(0, 0, "testtesttest123");从Windows服务(w3wp.exe是其父级,scvhost.exe是其祖父级,并且在IIS APPPOOL\Worker1用户帐户下运行产生的程序中调用则它将失败,并且如果互斥体已经由在其下运行的另一个进程创建,则返回NULL。IIS APPPOOL\*

我创建了一个最小的示例来重现此问题:

void main()
{
    HANDLE handle = CreateMutexA(0, 0, "testtesttest123");
    std::string lastError = MyGetLastErrorAsText();
    MyAppendToLog("%p %s\n", handle, lastError.c_str());
    Sleep(INFINITE);
}

我通过从资源管理器(普通用户帐户)双击两次来运行可执行文件,然后使它由Windows服务生成,然后再次从资源管理器运行它。

这将创建以下日志:

C:\ Test \ ReproduceMutexCrash.exe:00000034错误_成功
C:\ Test \ ReproduceMutexCrash.exe:00000034 ERROR_ALREADY_EXISTS 
c:\ inetpub \ wwwroot \ Worker1 \ ReproduceMutexCrash.exe:00000034
错误00000000 ERROR_ACCESS_DENIED 
C:\ Test \ ReproduceMutexCrash.exe:00000034 ERROR_ALREADY_EXISTS

这里的IIS APPPOOL\Worker1Worker1在下运行,而Worker2在IIS APPPOOL\Worker2用户帐户下运行

从日志中可以明显看出,如果互斥锁是由普通用户进程创建的,则这并不会阻止其他用户进程甚至Windows Service打开句柄。但是,如果Windows服务已创建了互斥锁,则::CreateMutex()尽管其他用户进程仍可以毫无障碍地打开句柄,但在被另一个Windows服务调用时失败。

有谁知道为什么会这样吗?

编辑:我看到互斥对象是\Sessions\1\BaseNamedObjects\testtesttest123资源管理器生成该进程的时间,而\BaseNamedObjects\testtesttest123该进程是由创建的IIS,所有者是Worker1(首先设法创建互斥量的进程)。

沙绍尔姆

多亏了评论的帮助,我终于弄清了为什么会发生这种情况。确实是由于权限,并且因为进程是从不同的用户帐户运行的。我通过运行2个单独的进程(但使用相同的用户帐户-)验证了这一点IIS APPPOOL\Worker1,并且两个进程::CreateMutex()有效并返回了有效的HANDLE。

仅当互斥锁已被其下IIS APPPOOL\Worker1的进程锁定并且正在IIS APPPOOL\Worker2尝试访问它的进程时,它才会失败

另外,我尝试通过创建一个空的DACL创建没有任何安全性的互斥体

SECURITY_ATTRIBUTES sa = { sizeof(sa) };
SECURITY_DESCRIPTOR SD;
InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&SD, TRUE, NULL, FALSE);
sa.lpSecurityDescriptor = &SD;
HANDLE mutex = CreateMutexA(&sa, 0, "testtesttest123");

使用空的DACL,来自不同用户帐户的2个进程可以打开相同的互斥锁。

另外,由用户进程创建的互斥锁未引起ERROR_ACCESS_DENIED的原因是因为它在不同的范围内创建了互斥锁- \Sessions\1\BaseNamedObjects\testtesttest123,因此没有权限冲突,因为Web服务进程正在以下位置创建新的互斥锁\BaseNamedObjects\testtesttest123,因此他们无论如何都不会访问相同的对象。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Windows 2012上的CreateMutex,错误代码为ERROR_ACCESS_DENIED

在 Windows API (CreateProcessAsUser) 上调试 ERROR_ACCESS_DENIED

在Windows脚本中杀死Windows上由批处理文件启动的外部进程

如何在Windows Server 2008上解锁由“系统”进程锁定的文件夹?

atexit() 处理程序中的 Windows 获取由 ::exit() 设置的当前进程退出代码

Xubuntu20.10:第二台显示器(电视),hdmi,由 PC 检测和连接,但图像输入仅在镜像时由电视检测 - linux & windows

比较由PowerShell和Python生成的Windows PowerShell中的两个JSON对象

无法在Windows上使用Eclipse导入由f2py生成的文件

如果Log4net由Windows Service启动,则不会记录日志

由ShellExecuteEx打开时,Windows文件属性对话框中的数据丢失

当目录名称中有“*”由linux创建时,它在windows 10上显示不可读的字符

我可以在Windows上运行由ionic2生成的IOS应用进行仿真吗?

无法在远程计算机上访问Windows Service中由Microsoft.Owin.Hosting.WebApp.Start公开的Urls

WTSQueryUserToken 返回 5 (ERROR_ACCESS_DENIED)

可移植的方式(Linux和Windows)具有只能由1个进程修改的文件,而在C / C ++中不能修改其他文件

如何使用C#在Windows窗体中显示MSSQL中由实时查询统计信息启用的执行查询百分比?

由方法生成的数组

由 generateEmailVerificationLink() 生成的 URL

在 Windows 窗体中由第一个窗体打开的第二个窗体关闭时设置第一个窗体的事件

消除由','。join()调用生成的双引号

由 Windows 任务调度程序触发

VSTS仅在由提交触发时失败

显示不是由getfavorites API调用返回的

由PHP生成为进程时未找到ROS catkin_init_workspace

进程由“ netstat”显示,但不由“ ps -a”显示

信号是由孩子处理的,而不是由父进程处理的?

尝试使用 CreateFileW 打开路径时,ERROR_ACCESS_DENIED 是否始终表示该文件存在?

失败:下载由 jupyter notebook 生成的 Excel 文件时出现网络错误

如何查看当前由进程执行的系统调用?