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

时间:2015-04-30 19:51:33

标签: c++ windows winapi synchronization ipc

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

所以从服务和&用户模式过程事件是这样创建/打开的:

>>> for i in ind:
...    s=sum(ind[:i-1])
...    d[i]=l[s:s+i]
... 
>>> d
{1: [23], 2: [12, 33], 3: [42, 5, 6], 4: [7, 8, 39, 10], 5: [11, 102, 4, 0, 5]}

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

我也通过调试器运行它,比如说,在服务中创建此事件之后,我希望用户进程中的CreateEvent()API成功并将GetLastError作为//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); } 返回,但它返回ERROR_ALREADY_EXISTS

知道我在这里做错了什么以及如何让它发挥作用?

3 个答案:

答案 0 :(得分:2)

修正了它。愚蠢的错误。忘记那些内核对象名称区分大小写。我应该做的是在Global\之后的名称上调用CharLower()以使其全部为小写,然后它就可以正常工作。

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

  1. Global\(或Local\Session\)后面的名称部分可能包含除斜杠之外的任何字符,即\或{{ 1}}。

  2. 完整的对象名称本身不能超过/个字符(即260)。所以它可能会很长。

答案 1 :(得分:1)

  

所以从服务和&用户模式过程事件是这样创建/打开的

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

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权限默认情况下。

答案 2 :(得分:-1)

myModule.substract()

我曾经在IE activeX和本机应用之间进行同步,但它再次失败了。然后我切换到InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); ,效果很好。