问题
I have created a windows service. Under which I am creating a event "test". I want to use the same event object to be set/reset by my application. But I do not seem to get the Handle of the event object through my app. But can see the Event being listed in the BaseNamed objects.
I think I need to do something with the security Attribute of the create Event.
I am creating this event in my service
CreateEvent(NULL, TRUE, FALSE, TEXT("Test"))
and using OpenEvent in my application.
OpenEvent( EVENT_ALL_ACCESS, TRUE, TEXT("Test"))
Please suggest what changes I would need to make, for my app to get the handle.
update
After Replacing TEXT("Test") with TEXT("Global\\Test")
. Still I didn't get the Event object handle.
Yes, now at least its recognizing the existence of the event object with the Error return(Access Denied). It was getting a Error return (the system cannot find the file specified) earlier.
As I said, I think there is some security aspect here.
This is what I found out: As the session creates the Event in Session 0. It cannot be inherited by my application which is being created in Session 1. For that while creating the Event object, I need to specify the security attribute structure with a proper Security Dispatcher to do so.
Could somebody tell me how to do so?
回答1:
Try this:
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(psd, TRUE, NULL, FALSE);
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = psd;
sa.bInheritHandle = FALSE;
HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, TEXT("Global\\Test"));
LocalFree(psd);
HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, TEXT("Global\\Test"));
回答2:
Service and application are likely to run in different sessions, and you need to use "Global" kernel object namespace prefix to have the object visible by both service and application.
See example and description in Kernel object namespaces on MSDN:
The separate client session namespaces enable multiple clients to run the same applications without interfering with each other. For processes started under a client session, the system uses the session namespace by default. However, these processes can use the global namespace by prepending the "Global\" prefix to the object name. For example, the following code calls CreateEvent and creates an event object named CSAPP in the global namespace:
CreateEvent( NULL, FALSE, FALSE, "Global\\CSAPP" );
See also:
- Windows service cannot see named semaphore
As default event security might deny access from the application, you need to update it as soon as you created the event and you are ready to expose it.
- API:
SetSecurityDescriptorDacl
and friends. - Code Snippet: Configuring a DACL for full access - event semaphores in a service app
来源:https://stackoverflow.com/questions/18890783/open-an-event-object-created-by-my-service-from-my-application