服务和用户模式进程之间的共享全局事件不起作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了服务和用户模式进程之间的共享全局事件不起作用相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个可以在我的服务和用户进程(-es)之间共享的命名全局事件。用户进程可以在任何低权限登录Windows用户(甚至是内置guest虚拟机)的凭据下运行。也无法知道哪个进程将首先创建此事件,即服务或用户进程。

因此,从服务和用户模式过程中,事件都是这样创建/打开的:

//Event name is made up using special/shared file path, and basically becomes something like this
strEventName = L"Global\sa_evt_C:_Users_Name_C++_Mod0110_debug_TmLog0";

//Create descriptor for "ALL access"
PSECURITY_DESCRIPTOR psdAll;
if(::ConvertStringSecurityDescriptorToSecurityDescriptor(
    isWindowsVistaOrLater ? L"D:(A;;GA;;;WD)(A;;GA;;;AN)S:(ML;;;;;S-1-16-0)" : L"D:(A;;GA;;;WD)(A;;GA;;;AN)",
    SDDL_REVISION_1, &psdAll, NULL))
{
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = FALSE;
    sa.lpSecurityDescriptor = psdAll;

    hEvent = ::CreateEvent(&sa, TRUE, FALSE, strEventName);

    LocalFree(psdAll);
}

我遇到的问题是事件是由服务和用户模式进程(-es)创建的,但它几乎就像是他们每个人创建自己的(非共享)事件副本,即当我发出信号时其他模块没有看到它(通过WaitForSingleObject API。)

我也通过调试器运行它,比如说,在服务中创建此事件之后,我希望用户进程中的CreateEvent()API成功并将GetLastError作为ERROR_ALREADY_EXISTS返回,但它返回NO_ERROR

知道我在这里做错了什么以及如何使它工作?

答案

固定它。愚蠢的错误。忘记那些内核对象名称区分大小写。我应该做的是在CharLower之后的名称上使用Global()来使它全部小写,然后它就能正常工作。

至于内核对象名称的长度和允许的字符,我基本上有两个限制:

  1. Global(或LocalSession)之后的名称部分可能包含任何字符,但斜线除外,即/
  2. 完整的对象名称本身不能超过MAX_PATH字符(这是260.)所以它可能会很长。
另一答案

因此,从服务和用户模式过程中,事件都是这样创建/打开的

有一种更简单的方法来创建允许不受限制地访问事件的安全描述符:

SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);

SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;

hEvent = ::CreateEvent(&sa, TRUE, FALSE, strEventName);

也无法知道哪个进程将首先创建此事件,即服务或用户进程。

您可以要求用户进程使用OpenEvent()而不是CreateEvent()。如果服务尚未运行,则该进程将无法使用该事件。非管理员/提升的进程不应该在Global命名空间中创建对象,只会消耗它们,因为默认情况下它们没有SeCreateGlobalPrivilege权限。

另一答案
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);

我曾经在IE activeX和本机应用程序之间进行同步,但它再次失败了。然后我切换到ConvertStringSecurityDescriptorToSecurityDescriptor,它运作良好。

以上是关于服务和用户模式进程之间的共享全局事件不起作用的主要内容,如果未能解决你的问题,请参考以下文章

共享内存的访问控制不起作用?

从Python角度理解多线程和多进程

在发布模式下部署后应用程序组不起作用

linux内核同步问题

.NET面试题系列[17] - 多线程概念

变量的四种作用域是?