If you call SCardEstablishContext API in a Windows service running under a specific user account (domain\user) or NETWORK SERVICE, you may get the following error on Vista/Server 2008 or Windows 7/Server 2008 R2:
0x8010001d - SCARD_E_NO_SERVICE - "The Smart card resource manager is not running.".
If the service runs as SYSTEM, the same code works. If the API is called in a standard desktop application, it works too. Additionally, the same service works fine on Windows XP. Why?
SCardEstablishContext API is returning that error because it gets an Access Denied error when trying to open an event called "Global\Microsoft Smart Card Resource Manager Started" with OpenEvent API. The default security for that event on Vista and Windows 7 specifies that only SYSTEM, LOCAL SERVICE and INTERACTIVE users have access to it. NETWORK SERVICE or non-interactive users won’t be able to access the event.
Enabling "Allow service to interact with desktop" won't help.
When looking for workarounds other than the obvious (use any of the accounts with default access to the event), I found a solution that a colleague of mine applied in a similar case in the past. They used the following code to grant users access to the event:
int _tmain(int argc, _TCHAR* argv)
DWORD result = AddAceToObjectsSecurityDescriptor (
_T("Global\\Microsoft Smart Card Resource Manager Started"),
_tprintf(_T("Result = %d\n"), result);
AddAceToObjectsSecurityDescriptor method can be found here: Modifying the ACLs of an Object in C++. Note I haven’t tried this code myself.
Additionally, this issue didn’t happen on Windows XP because on older OS versions LOCAL accounts had permissions on the event instead of INTERACTIVE accounts like on Vista/Server 2008 or Windows 7/Server 2008 R2.
I hope this helps.
Alex (Alejandro Campos Magencio)
UPDATE!!! Some customers are reporting that the code above returns Access Denied errors when running it with elevated admin accounts, with admin accounts and UAC disabled, and even with System account. But it looks like running it with LOCAL SERVICE works. Actually, I verified with Process Explorer that only LOCAL SERVICE account can modify the event (note that with that tool we can modify the security descriptor of the event too).
Now, we must take into account that the security of the event is set when the smart card service creates the event (see Synchronization Object Security and Access Rights for details). This means that when we restart the machine, we will lose the changes we made to the security descriptor.
So if changing the permissions every time you restart the machine or using one of the default accounts won't work for you, I'm afraid there is nothing we can do at the moment.
On Windows Server 2008 R2 the method GetNamedSecurityInfo returns Access Denied and it cannot grant access to the SC resource manager. Anyone knows how to solve this problem?
I try to change in SYSTEM but is no possible, because this service is connected to Plug and Play service.
What i have to do to change it?
please try to run your application service with LocalSystem account instead of a user account.
This is a by design issue with Microsoft on Windows Vista and above platforms.
Actually the issue is- the application tries to communicate with smartcard by calling the token APIs and when windows smartcard resource manager is being called, it calls SCardEstablishContext API to AcquireContext on the smartcard. If in a Windows service running under a specific user account (domain\user) or NETWORK SERVICE this call fails, you may get the this error on Vista/Server 2008 or Windows 7/Server 2008 R2
In XP and Windows 2003, there were no ACLs in the event creation hence the service app worked with all types of accounts. With Vista onwards, they introduced ACLs to event creation function which restricted the event creation to just 3 types of accounts- Local System, Local Service and Interactive users. ACLing is a new design in Windows Vista and Windows 2008 which was not present in XP or earlier OSes.