2008-09-22 89 views
4

我创建在Vista上的appcation,其中包括一个服务,并在相同的用户帐户运行IPC在Vista(服务和应用程序)

在服务我创建了该事件的事件,并等待一个控制台应用程序。无论是。在控制台应用程序中,我打开相同的事件(问题从此处开始),并调用SetEvent函数。我无法在控制台应用程序中打开事件(获取错误5,Access被拒绝)。我在网络中搜索并看到了关于完整性级别的一些信息(我不确定问题与完整性级别有关)。它告诉服务并且应用得到不同的完整性水平。

这里是代码,其中IPC occures

服务

DWORD 
WINAPI IpcThread(LPVOID lpParam) 
{ 
HANDLE ghRequestEvent = NULL ; 

ghRequestEvent = CreateEvent(NULL, FALSE, 
FALSE, "Global\\Event1") ; //creating the event 

if(NULL == ghRequestEvent) 
{ 
//error 
} 
while(1) 
{ 
WaitForSingleObject(ghRequestEvent, INFINITE) //waiting for the event 
//here some action related to event 
} 
} 

控制台应用程序

在这里,在应用程序的一部分,打开该事件并塞汀事件

unsigned int 
event_notification() 
{ 
HANDLE ghRequestEvent = NULL ; 



ghRequestEvent = OpenEvent(SYNCHRONIZE|EVENT_MODIFY_STATE, FALSE, "Global\\Event1") ; 

if(NULL == ghRequestEvent) 
{ 
//error 
} 
SetEvent(ghRequestEvent) ; 
} 

我正在运行具有管理特权的应用程序(serivce和控制台应用程序)(我以管理员身份登录并通过右键单击并使用“以管理员身份运行”选项运行控制台应用程序)。

我在控制台应用程序(我打开该事件)中收到的错误是错误否5(访问被拒绝。)。

所以,如果你告诉怎么做IPC服务,在Vista应用程序之间预先

感谢

Navaneeth

回答

3

是服务和运行的应用程序将是非常有益的具有不同完整性级别的相同用户,还是以不同的用户身份运行?

如果是前者,那么这篇文章来自MSDN which talks about integrity levels might help。他们有一些示例代码用于降低文件的完整性级别。但我不确定这可能与事件相关。

#include <sddl.h> 
#include <AccCtrl.h> 
#include <Aclapi.h> 

void SetLowLabelToFile() 
{ 
    // The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity 
    #define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)" 
    DWORD dwErr = ERROR_SUCCESS; 
    PSECURITY_DESCRIPTOR pSD = NULL;  

    PACL pSacl = NULL; // not allocated 
    BOOL fSaclPresent = FALSE; 
    BOOL fSaclDefaulted = FALSE; 
    LPCWSTR pwszFileName = L"Sample.txt"; 

    if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
     LOW_INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD;, NULL)) 
    { 
    if (GetSecurityDescriptorSacl(pSD, &fSaclPresent;, &pSacl;, 
     &fSaclDefaulted;)) 
    { 
     // Note that psidOwner, psidGroup, and pDacl are 
     // all NULL and set the new LABEL_SECURITY_INFORMATION 
     dwErr = SetNamedSecurityInfoW((LPWSTR) pwszFileName, 
       SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION, 
       NULL, NULL, NULL, pSacl); 
    } 
    LocalFree(pSD); 
    } 
} 

如果是后者,你可以看看这个链接,suggests creating a NULL ACL,并将它与对象(关联的例子是一个命名管道,但该方法是一个事件我相信类似:

​​
+0

我可以作为同一用户运行。 – Navaneeth 2008-09-22 10:00:44

+0

从哪里可以得到上面使用的LOW_INTEGRITY_SDDL_SACL_W字符串的描述?我只看到它在示例代码中使用,从未正式定义过。 – Clay 2008-11-09 14:22:23

0

首先,从概念上理解需要什么是很重要的,一旦理解了,我们就可以从中获得。

在服务器上,它应该类似于:

{ 
    HANDLE hEvent; 
    hEvent = CreateEvent(null, true, false, TEXT("MyEvent")); 
    while (1) 
    { 
     WaitForSingleObject (hEvent); 
     ResetEvent (hEvent); 
     /* Do something -- start */ 
     /* Processing 1 */ 
     /* Processing 2 */ 
     /* Do something -- end */ 
    } 
} 

在客户端:

{ 
    HANDLE hEvent; 
    hEvent = OpenEvent(0, false, TEXT("MyEvent")); 
    SetEvent (hEvent); 
} 

几点需要注意:

  • ResetEvent应早可能的,在WaitForSingleObject或WaitForMultipleObjects之后。如果多个客户端正在使用服务器,并且第一个客户端的处理需要时间,则第二个客户端可能会设置该事件,并且在服务器处理第一个请求时可能不会捕获它。
  • 您应该实施一些机制,通知客户端服务器已完成处理。
  • 在做任何win32服务之前,请将服务器作为简单的应用程序运行。这将消除任何与安全有关的问题。
1

我注意到你在“Global”命名空间中创建对象,但是试图在本地命名空间中打开它。在公开呼叫帮助中是否将“Global \”添加到名称中?

另外,在//错误区域,有什么东西让你知道它没有被创建?

0

@Navaneeth:

非常好的反馈。由于您的错误是拒绝访问,然后我会改变从EVENT_ALL_ACCESS所需的访问,你真的不需要,到

(SYNCHRONIZE | EVENT_MODIFY_STATE) 

SYNCHRONIZE让你等待该事件,并EVENT_MODIFY_STATE可调用SetEvent的,ResetEvent和PulseEvent 。

您可能需要更多访问权限,但这非常不寻常。

0

“1800 INFORMATION”是正确的 - 这是一个UIPI问题;不要在新代码中使用事件,如果事件中的目标阻塞发生在用户模式APC代码中,则该事件信号可能会丢失。 Win32中编写服务/应用程序的规范方式是使用RPC调用来跨越UIPI边界。