IPC in Vista (service and application)

I am creating an appcation for Vista that includes a service and a console application. Both work in the same user account

In the service, I create an event and wait for this event. In a console application, I open the same event (the problem starts here) and calls the SetEvent function. I can not open the event (receiving error 5, access is denied) in the console application. I searched on the net and saw something about the integrity level (I'm not sure if the problem is related to the integrity level). He reports that service and application have received different levels of integrity.

here is the piece of code where IPC has

service

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 } } 

Console application

Here, in the application, opening an event and setting up an event

 unsigned int event_notification() { HANDLE ghRequestEvent = NULL ; ghRequestEvent = OpenEvent(SYNCHRONIZE|EVENT_MODIFY_STATE, FALSE, "Global\\Event1") ; if(NULL == ghRequestEvent) { //error } SetEvent(ghRequestEvent) ; } 

I run the application (serivce and console application) with administrator privileges (I logged in as Administraor and started the console application by right-clicking and using the "run as administrator" option).

The error that I get in the console application (where I open the event) is error No. 5 (access is denied.).

So, it will be very useful if you tell how to make IPC between a service and an application in Vista p>

Thank you in advance

Navaneeth

+4
source share
5 answers

Are the services and the application used as the same user with different integrity levels, or are they executed as different users?

If this is the first, then this MSDN article that talks about integrity levels can help . They have sample code to reduce file integrity. I'm not sure if this can make a difference to the event.

 #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); } } 

If this is the last one, you can look at this link, which suggests creating a NULL ACL and associating it with the object (in the example, this is a named pipe, but the approach is similar for the event, I'm sure:

 BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = &sd; InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, (PACL) 0, FALSE); CreateNamedPipe(..., &sa); 
+3
source

I notice that you are creating an object in the global namespace, but trying to open it in the local namespace. Does the "Global" name add to the help of an open call?

Also, in the // error area, is there anything to say that it was not created?

+1
source

First, it is important to conceptually understand what is required. Once this is understood, we can take it from there.

On the server, it should look something like this:

 { 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 */ } } 

On the client:

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

A few notes:

  • ResetEvent should be as early as possible, immediately after WaitForSingleObject or WaitForMultipleObjects. If several clients use the server, and processing the first client takes time, the second client may set up an event, and it may not be caught while the server processes the first request.
  • You should implement a mechanism that will notify the client of the completion of server processing.
  • Before executing any win32 mumbo-jumbo service, the server works as a simple application. This will fix any security issues.
0
source

@Navaneeth:

Great feedback. Since your mistake is Access Denied, then I would change the desired access from EVENT_ALL_ACCESS, which you really don't need,

 (SYNCHRONIZE | EVENT_MODIFY_STATE) 

SYNCHRONIZE allows you to wait for an event, and EVENT_MODIFY_STATE allows you to call SetEvent, ResetEvent, and PulseEvent.

You may need more access, but this is very unusual.

0
source

"INFORMATION" 1800 "is a UIPI problem; do not use events in the new code in any case, the event signal may be lost if the target blocking of the event occurs in the user mode APC code when it starts. The canonical way in Win32 to write a service / application is using RPC calls to cross the UIPI border.

0
source

Source: https://habr.com/ru/post/1277010/


All Articles