Now and then when I get some time I like to spend it writing code and I usually like to relate this to some work/activity that helps in my main work i.e. SQL Server. I have many small single-purpose applications/utilities written over time and I realized that having them saved on my PC is of no use. Don’t be surprised if you find C/C++ code samples posted on TheSQLDude. For the time being let me be the TheCDude and Long Live Dennis Ritchie & Ken Thompson!
Service Control Manager Test
I wrote some code to test if I can open the Windows Service Control Manager (SCM) for the local machine or remote machine with the current logged-in account. This helps me validate permissions or spot other errors when performing service related activities. For those of you who don’t know what SCM is read this article.
SCM is a system component that takes care of service management, service start-up and other service related activities.
You might ask, How did I come to care about SCM all of a sudden? What the hell does this have to do with SQL Server?
Let me explain. I came about SCM when a customer of mine came up with a SQL Server Setup issue. When SQL Server setup goes about installing the various SQL Server components, one of the things it has to do is to create the SQL Server services like SQL Engine, RS, AS, Browser service, SQL Writer service etc. Obviously if setup is not able to do this, it will fail. For someone to create/delete/modify a Windows service, they need to talk to the Service Control Manager (SCM). How do you isolate whether the problem is with SQL Setup or some other component? This is how I ended writing this code to test SCManager.
If you want to perform windows service related activities, it works like this:-
1. You need to open the SCManager, which will let you access its database which has the list of registered services
2. If this succeeds, then depending on the operation you can either Open an existing service and modify/query its properties or create a new service and register it with SCM.
The code below is simple C code written on Visual Studio 2010. This has no copyright so feel free to re-distribute.
// scmantest.cpp : Defines the entry point for the console application.
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "Kernel32.lib")
int _tmain(int argc, _TCHAR* argv)
if (argc < 2)
_tprintf(_T("Usage : %s name_of_machine_to_test"), argv);
//CHAR lpMachine ;
BOOL bReturn = FALSE;
// Check that we can open the SCManager on the machine
hScm = OpenSCManager(argv, NULL, SC_MANAGER_ALL_ACCESS);
bReturn = TRUE;
printf("OpenSCManager completed successfully\n");
_tprintf(_T("Could not OpenSCManager on %s. GLE = 0x%08x\n"),argv,GetLastError());
The above code tries to Open the SCM and if that fails then it reports the Win32 error. You can Bing! this error to find out what action to take. The application scmantest takes 1 parameter which is the Machine Name. So if you PC is called WorkPC.domain.company.com, then you would run this from the command prompt like this
Here is an output for a non-existent machine and you can see that the Win32 Error reported is 0x000006ba (The RPC server is unavailable).
This can help isolate permission issues when trying to open SCM database as you need to have Administrator rights. Sometimes certain permissions to create might be missing which you will have to grant.
If you are a Windows Admin reading this then here are some command-line instructions to operate on Windows Services
1. Query the state of an existing Windows Service – sc query ServiceName
e.g. Checking state of default instance of SQL Server.
sc query MSSQLSERVER
TYPE : 10 WIN32_OWN_PROCESS
STATE : 4 RUNNING
(STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
If you specified an invalid service name, you will get this error,
[SC] EnumQueryServicesStatus:OpenService Failed 1060:The specified service does not exist as an installed server.
2. Create a new Windows Service – sc create …
Let me take an example of creating a SQL Server service
e.g. Creating a Default instance of SQL Server
sc create MSSQLSERVER type= own start= demand error= normal binPath= D:\MSSQL\MSSQL.1\MSSQL\Binn\sqlservr.exe obj= LocalSystem DisplayName= "SQL Server (MSSQLSERVER)"
type –> Type of service you want to create. Leave it at OWN.
start –> Start type for the service. You can have it at automatic, disabled. We choose demand which means manual start-up.
binpath –> Complete path to the sqlservr.exe
obj –> Startup account for the service.
DisplayName –> can be anything, this is what services.msc will show us.
a) There must be a space between ‘=’ and the value.
b) Double-quotes are mandatory is there is a space in the path.
For those of you who didn’t know this, the windows service entries are present in registry in HKLM\SYSTEM\CurrentControlSet\Services\. This is the same location from where services.msc reads and displays the list of services.
3. Using SUBINACL to check permissions for Windows Services:
SubInACL is a command-line tool that is available for download here and shows you security information about files, registry keys, and services.
e.g. Query permissions on the service for default SQL Server instance
subinacl /verbose /service MSSQLSERVER /display
/primary group =system
/audit ace count =1
/aace =everyone SYSTEM_AUDIT_ACE_TYPE-0x2
/perm. ace count =6
/pace =system ACCESS_ALLOWED_ACE_TYPE-0x0
SERVICE_QUERY_CONFIG-0x1 SERVICE_QUERY_STATUS-0x4 SERVICE_ENUMERATE_DEPEND-0x8
SERVICE_START-0x10 SERVICE_STOP-0x20 SERVICE_PAUSE_CONTINUE-0x40 SERVICE_INTERROGATE-0x80
/pace =builtin\administrators ACCESS_ALLOWED_ACE_TYPE-0x0
4. Granting permissions using SUBINACL
e.g. Grant Full Control to TestUser1 on the default SQL Server instance’s service.
subinacl /service MSSQLSERVER /Grant=Domain\TestUser1=F
MSSQLSERVER : new ace for anselm\administrator
MSSQLSERVER : 1 change(s)
Other useful Resources
Using SC.EXE to Develop Windows NT Services
How to create a Windows service by using Sc.exe
I hope this post was useful for both Developers as well as Administrators. Would appreciate any feedback on this post since I am thinking of posting other useful code samples in the future. As always stay tuned for more geeky info….