Home Page

  • June 17, 2019, 07:57:13 PM *
  • Welcome, Guest
Please login or register.

Login with username, password and session length
Advanced search  


Official site launch very soon, hurrah!

Author Topic: Windows Driver Service Loader  (Read 3395 times)


  • Programmer Person
  • Administrator
  • Hero Member
  • *****
  • Posts: 522
    • View Profile
    • Dakusan's Domain
Windows Driver Service Loader
« on: August 02, 2016, 08:55:57 PM »

Original post for Windows Driver Service Loader can be found at https://www.castledragmire.com/Posts/Windows_Driver_Service_Loader.
Originally posted on: 08/03/16

Following is some C++ source code for a Windows kernel-driver service loader. It could be used to load other service types too by changing the dwServiceType flag on the CreateService call. I threw this together for another project I am currently working on. It is also used in the following post (posting soon).

It works in the following way:
  • It is a command line utility which takes 3 arguments:
    1. The service name. Hereby referred to as SERVICE_NAME
    2. The service display name. Hereby referred to as DISPLAY_NAME
    3. The driver path (to the .sys file). Hereby referred to as DRIVER_PATH
  • This program (most likely) requires administrative access. There are also some caveats regarding driver code signing requirements that are thoroughly explored elsewhere.
  • It first checks to see if a service already exists with the given SERVICE_NAME. If it does:
    1. If the DISPLAY_NAME matches, the service is kept as is.
    2. If the DISPLAY_NAME does not match, the user is prompted on if they want to delete the current service. If they do not, the program exits.
  • If the service needs to be created (it did not already exist or was deleted), it creates the service with the given SERVICE_NAME, DISPLAY_NAME, and DRIVER_PATH. If the service is not created during this run, the DRIVER_PATH is ignored.
    Note: The DRIVER_PATH must be to a direct local file system file. I have found that network links and symbolic links do not work.
  • The service is started up:
    • If it is already running, the user is prompted on if they want to stop the currently running service. If they say no, the program exits.
  • The program then waits for a final user input on if they want to close the service before exiting the program.
  • If there was an error, the program reports the error, otherwise, it reports “Success”.
  • The program pauses at the end until the user presses any key to exit.
  • The program returns 0 on success, and 1 if an error occurred.

//Compiler flags
#define WIN32_LEAN_AND_MEAN  //Include minimum amount of windows stuff
#ifndef _UNICODE //Everything in this script is unicode
   #define _UNICODE

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <memory>

//Smart pointers
typedef std::unique_ptr<WCHAR, void(*)(WCHAR*)> SmartWinAlloc;
typedef std::unique_ptr<SC_HANDLE, void(*)(SC_HANDLE*)> SmartCloseService;
void Delete_SmartWinAlloc(WCHAR *p) { if(p) LocalFree(p); }
void Delete_SmartCloseService(SC_HANDLE *h) { if(h && *h) CloseServiceHandle(*h); }

//Function declarations
WCHAR* InitDriver(int argc, WCHAR *argv[]);
WCHAR* FormatError(WCHAR* Format, ...);
SmartWinAlloc GetLastErrorStr();
BOOLEAN AskQuestion(WCHAR* Question); //Returns if user answered yes

int wmain(int argc, WCHAR *argv[])
   //Run the init routine
   WCHAR* Ret=InitDriver(argc, argv);

   //If there is an error, report it, or otherwise, report success
   wprintf(L"%s\n", Ret ? Ret : L"Success");
   wprintf(L"%s\n", L"Press any key to exit");

   //Return if successful
   return (Ret ? 1 : 0);

WCHAR* InitDriver(int argc, WCHAR *argv[])
   //Confirm arguments
      return FormatError(L"%s", L"3 arguments are required: Service Name, Display Name, Driver Path");
   const WCHAR* Param_ServiceName=argv[1];
   const WCHAR* Param_DisplayName=argv[2];
   const WCHAR* Param_DriverPath =argv[3];

   //Open the service manager
   wprintf(L"%s\n", L"Opening the service manager");
   SC_HANDLE HSCManager=OpenSCManager(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE);
      return FormatError(L"%s: %s", L"Error opening service manager", GetLastErrorStr());
   SmartCloseService FreeHSCManager(&HSCManager, Delete_SmartCloseService);

   //Check if the service already exists
   wprintf(L"%s\n", L"Checking previously existing service state");
   BOOL ServiceExists=false;
      //Get the service name
      const DWORD NameBufferSize=255;
      WCHAR NameBuffer[NameBufferSize];
      WCHAR *NamePointer=NameBuffer;
      DWORD NamePointerSize=NameBufferSize;
      std::unique_ptr<WCHAR> Buf(nullptr); //May be swapped with a real pointer later
      for(INT_PTR i=0;i<2;i++)
         //If we found the service, exit the lookup here
         if(GetServiceDisplayName(HSCManager, Param_ServiceName, NamePointer, &NamePointerSize))

         //If the service does not exist, we can exit the lookup here

         //If error is not insufficient buffer size, return the error
            return FormatError(L"%s: %s", L"Could not query service information", GetLastErrorStr());

         //If second pass, error out
            return FormatError(L"%s: %s", L"Could not query service information", L"Second buffer pass failed");

         //Create a buffer of appropriate size (and make sure it will later be released)
         NamePointer=new WCHAR[++NamePointerSize];
         std::unique_ptr<WCHAR> Buf2(NamePointer);

      //If the service already exists, confirm the service name matches, and if not, ask if user wants to delete the current service
         wprintf(L"%s\n", L"The service already exists");
         if(wcsncmp(NamePointer, Param_DisplayName, NamePointerSize+1))
            //If the server names do not match, ask the user what to do
            wprintf(L"%s:\nCurrent: %s\nRequested: %s\n", L"The service names do not match", NamePointer, Param_DisplayName);

            //Make the request
            if(!AskQuestion(L"Would you like to replace the service? (y/n)")) //If user does not wish to replace the service
               return FormatError(L"%s", L"Cannot continue if service names do not match");

            //Delete the service
            wprintf(L"%s\n", L"Deleting the old service");
            SC_HANDLE TheService=OpenService(HSCManager, Param_ServiceName, DELETE);
               return FormatError(L"%s: %s", L"Could not open the service to delete it", GetLastErrorStr());
            SmartCloseService CloseTheService(&TheService, Delete_SmartCloseService); //Close the service handle
               return FormatError(L"%s: %s", L"Could not delete the service", GetLastErrorStr());
            wprintf(L"%s\n", L"The service has been deleted");

   //Create the service
   SC_HANDLE TheService;
      //Confirm the driver path exists
      wprintf(L"%s\n", L"Checking the driver file");
      DWORD FileAttrs=GetFileAttributes(Param_DriverPath);
         return FormatError(L"%s: %s", L"Given path is invalid", GetLastErrorStr());
         return FormatError(L"%s: %s", L"Given path is invalid", L"Path is a folder");

      //Create the service
      wprintf(L"%s\n", L"Creating the service");
         HSCManager, Param_ServiceName, Param_DisplayName,
         Param_DriverPath, nullptr, nullptr, nullptr, nullptr, nullptr);
         return FormatError(L"%s: %s", L"Could not create the service", GetLastErrorStr());

   //Open the service if not creating
   } else {
      TheService=OpenService(HSCManager, Param_ServiceName, SERVICE_START|SERVICE_STOP);
         return FormatError(L"%s: %s", L"Could not open the service", GetLastErrorStr());
   SmartCloseService CloseTheService(&TheService, Delete_SmartCloseService); //Close the service on exit

   //Start the service
   wprintf(L"%s\n", L"Starting the service");
   for(INT_PTR i=0;i<2;i++)
      if(StartService(TheService, 0, nullptr))

      //If not "service already running" error, or user does not want to stop the current service
      if(i==1 || GetLastError()!=ERROR_SERVICE_ALREADY_RUNNING || !AskQuestion(L"The service is already running. Would you like to stop it? (y/n)"))
         return FormatError(L"%s: %s", L"Could not start the service", GetLastErrorStr());

      //Stop the service
      wprintf(L"%s\n", L"Stopping the current service");
      if(!ControlService(TheService, SERVICE_CONTROL_STOP, &ss))
         return FormatError(L"%s: %s", L"Could not stop the current service", GetLastErrorStr());
   wprintf(L"%s\n", L"Started the service");

   //Ask if the user wants to close the service
   if(!AskQuestion(L"Would you like to stop the service before exit? (y/n)"))
      return nullptr;

   //Stop the service
   if(!ControlService(TheService, SERVICE_CONTROL_STOP, &ss))
      return FormatError(L"%s: %s", L"Could not stop the service", GetLastErrorStr());
   if(ss.dwCurrentState!=SERVICE_STOP_PENDING && ss.dwCurrentState!=SERVICE_STOPPED)
      return FormatError(L"%s", L"The service does not appear to be closing");
   wprintf(L"%s\n", L"The service has been stopped");

   //Return success
   return nullptr;

WCHAR* FormatError(WCHAR* Format, ...)
   static WCHAR Err[255];
   va_list VAList;
   va_start(VAList, Format);
   vswprintf(Err, sizeof(Err)/sizeof(Err[0]), Format, VAList);
   return Err;

SmartWinAlloc GetLastErrorStr()
   LPWSTR MessageBuffer=nullptr;
      nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&MessageBuffer, 0, nullptr);
   return SmartWinAlloc(MessageBuffer, Delete_SmartWinAlloc);

BOOLEAN AskQuestion(WCHAR* Question)
   //Make the request and wait for an input character
      //Ask the question and get the answer
      wprintf(L"%s:", Question);
      char InputChar=_getch();

      //Check for a valid answer
      if(InputChar=='n' || InputChar=='N')
         return FALSE;
      if(InputChar=='y' || InputChar=='Y')
         return TRUE;