2008-09-22 91 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邊界。