summaryrefslogtreecommitdiff
path: root/general/event/exe/install.c
diff options
context:
space:
mode:
Diffstat (limited to 'general/event/exe/install.c')
-rw-r--r--general/event/exe/install.c558
1 files changed, 558 insertions, 0 deletions
diff --git a/general/event/exe/install.c b/general/event/exe/install.c
new file mode 100644
index 00000000..b52178e5
--- /dev/null
+++ b/general/event/exe/install.c
@@ -0,0 +1,558 @@
+/*++
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ install.c
+
+Abstract:
+
+ Win32 routines to dynamically load and unload a Windows NT kernel-mode
+ driver using the Service Control Manager APIs.
+
+Environment:
+
+ User mode only
+
+--*/
+
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strsafe.h>
+#include "public.h"
+
+BOOLEAN
+InstallDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName,
+ _In_ LPCTSTR ServiceExe
+ );
+
+
+BOOLEAN
+RemoveDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName
+ );
+
+BOOLEAN
+StartDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName
+ );
+
+BOOLEAN
+StopDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName
+ );
+
+BOOLEAN
+InstallDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName,
+ _In_ LPCTSTR ServiceExe
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ SC_HANDLE schService;
+ DWORD err;
+
+ //
+ // NOTE: This creates an entry for a standalone driver. If this
+ // is modified for use with a driver that requires a Tag,
+ // Group, and/or Dependencies, it may be necessary to
+ // query the registry for existing driver information
+ // (in order to determine a unique Tag, etc.).
+ //
+
+ //
+ // Create a new a service object.
+ //
+
+ schService = CreateService(SchSCManager, // handle of service control manager database
+ DriverName, // address of name of service to start
+ DriverName, // address of display name
+ SERVICE_ALL_ACCESS, // type of access to service
+ SERVICE_KERNEL_DRIVER, // type of service
+ SERVICE_DEMAND_START, // when to start service
+ SERVICE_ERROR_NORMAL, // severity if service fails to start
+ ServiceExe, // address of name of binary file
+ NULL, // service does not belong to a group
+ NULL, // no tag requested
+ NULL, // no dependency names
+ NULL, // use LocalSystem account
+ NULL // no password for service account
+ );
+
+ if (schService == NULL) {
+
+ err = GetLastError();
+
+ if (err == ERROR_SERVICE_EXISTS) {
+
+ //
+ // Ignore this error.
+ //
+
+ return TRUE;
+
+ } else if (err == ERROR_SERVICE_MARKED_FOR_DELETE) {
+ //
+ // Previous instance of the service is not fully deleted so sleep
+ // and try again.
+ //
+ printf("Previous instance of the service is not fully deleted. Try again...\n");
+ return FALSE;
+ }
+ else {
+
+ printf("CreateService failed! Error = %d \n", err );
+
+ //
+ // Indicate an error.
+ //
+
+ return FALSE;
+ }
+ }
+
+ //
+ // Close the service object.
+ //
+
+ if (schService) {
+
+ CloseServiceHandle(schService);
+ }
+
+ //
+ // Indicate success.
+ //
+
+ return TRUE;
+
+} // InstallDriver
+
+BOOLEAN
+ManageDriver(
+ _In_ LPCTSTR DriverName,
+ _In_ LPCTSTR ServiceName,
+ _In_ USHORT Function
+ )
+{
+
+ SC_HANDLE schSCManager;
+
+ BOOLEAN rCode = TRUE;
+
+ //
+ // Insure (somewhat) that the driver and service names are valid.
+ //
+
+ if (!DriverName || !ServiceName) {
+
+ printf("Invalid Driver or Service provided to ManageDriver() \n");
+
+ return FALSE;
+ }
+
+ //
+ // Connect to the Service Control Manager and open the Services database.
+ //
+
+ schSCManager = OpenSCManager(NULL, // local machine
+ NULL, // local database
+ SC_MANAGER_ALL_ACCESS // access required
+ );
+
+ if (!schSCManager) {
+
+ printf("Open SC Manager failed! Error = %d \n", GetLastError());
+
+ return FALSE;
+ }
+
+ //
+ // Do the requested function.
+ //
+
+ switch( Function ) {
+
+ case DRIVER_FUNC_INSTALL:
+
+ //
+ // Install the driver service.
+ //
+
+ if (InstallDriver(schSCManager,
+ DriverName,
+ ServiceName
+ )) {
+
+ //
+ // Start the driver service (i.e. start the driver).
+ //
+
+ rCode = StartDriver(schSCManager,
+ DriverName
+ );
+
+ } else {
+
+ //
+ // Indicate an error.
+ //
+
+ rCode = FALSE;
+ }
+
+ break;
+
+ case DRIVER_FUNC_REMOVE:
+
+ //
+ // Stop the driver.
+ //
+
+ StopDriver(schSCManager,
+ DriverName
+ );
+
+ //
+ // Remove the driver service.
+ //
+
+ RemoveDriver(schSCManager,
+ DriverName
+ );
+
+ //
+ // Ignore all errors.
+ //
+
+ rCode = TRUE;
+
+ break;
+
+ default:
+
+ printf("Unknown ManageDriver() function. \n");
+
+ rCode = FALSE;
+
+ break;
+ }
+
+ //
+ // Close handle to service control manager.
+ //
+
+ if (schSCManager) {
+
+ CloseServiceHandle(schSCManager);
+ }
+
+ return rCode;
+
+} // ManageDriver
+
+
+BOOLEAN
+RemoveDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName
+ )
+{
+ SC_HANDLE schService;
+ BOOLEAN rCode;
+
+ //
+ // Open the handle to the existing service.
+ //
+
+ schService = OpenService(SchSCManager,
+ DriverName,
+ SERVICE_ALL_ACCESS
+ );
+
+ if (schService == NULL) {
+
+ printf("OpenService failed! Error = %d \n", GetLastError());
+
+ //
+ // Indicate error.
+ //
+
+ return FALSE;
+ }
+
+ //
+ // Mark the service for deletion from the service control manager database.
+ //
+
+ if (DeleteService(schService)) {
+
+ //
+ // Indicate success.
+ //
+
+ rCode = TRUE;
+
+ } else {
+
+ printf("DeleteService failed! Error = %d \n", GetLastError());
+
+ //
+ // Indicate failure. Fall through to properly close the service handle.
+ //
+
+ rCode = FALSE;
+ }
+
+ //
+ // Close the service object.
+ //
+
+ if (schService) {
+
+ CloseServiceHandle(schService);
+ }
+
+ return rCode;
+
+} // RemoveDriver
+
+
+
+BOOLEAN
+StartDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName
+ )
+{
+ SC_HANDLE schService;
+ DWORD err;
+
+ //
+ // Open the handle to the existing service.
+ //
+
+ schService = OpenService(SchSCManager,
+ DriverName,
+ SERVICE_ALL_ACCESS
+ );
+
+ if (schService == NULL) {
+
+ printf("OpenService failed! Error = %d \n", GetLastError());
+
+ //
+ // Indicate failure.
+ //
+
+ return FALSE;
+ }
+
+ //
+ // Start the execution of the service (i.e. start the driver).
+ //
+
+ if (!StartService(schService, // service identifier
+ 0, // number of arguments
+ NULL // pointer to arguments
+ )) {
+
+ err = GetLastError();
+
+ if (err == ERROR_SERVICE_ALREADY_RUNNING) {
+
+ //
+ // Ignore this error.
+ //
+
+ return TRUE;
+
+ } else {
+
+ printf("StartService failure! Error = %d \n", err );
+
+ //
+ // Indicate failure. Fall through to properly close the service handle.
+ //
+
+ return FALSE;
+ }
+
+ }
+
+ //
+ // Close the service object.
+ //
+
+ if (schService) {
+
+ CloseServiceHandle(schService);
+ }
+
+ return TRUE;
+
+} // StartDriver
+
+
+
+BOOLEAN
+StopDriver(
+ _In_ SC_HANDLE SchSCManager,
+ _In_ LPCTSTR DriverName
+ )
+{
+ BOOLEAN rCode = TRUE;
+ SC_HANDLE schService;
+ SERVICE_STATUS serviceStatus;
+
+ //
+ // Open the handle to the existing service.
+ //
+
+ schService = OpenService(SchSCManager,
+ DriverName,
+ SERVICE_ALL_ACCESS
+ );
+
+ if (schService == NULL) {
+
+ printf("OpenService failed! Error = %d \n", GetLastError());
+
+ return FALSE;
+ }
+
+ //
+ // Request that the service stop.
+ //
+
+ if (ControlService(schService,
+ SERVICE_CONTROL_STOP,
+ &serviceStatus
+ )) {
+
+ //
+ // Indicate success.
+ //
+
+ rCode = TRUE;
+
+ } else {
+
+ printf("ControlService failed! Error = %d \n", GetLastError() );
+
+ //
+ // Indicate failure. Fall through to properly close the service handle.
+ //
+
+ rCode = FALSE;
+ }
+
+ //
+ // Close the service object.
+ //
+
+ if (schService) {
+
+ CloseServiceHandle (schService);
+ }
+
+ return rCode;
+
+} // StopDriver
+
+BOOLEAN
+SetupDriverName(
+ _Inout_updates_bytes_all_(BufferLength) PCHAR DriverLocation,
+ _In_ ULONG BufferLength
+ )
+{
+ HANDLE fileHandle;
+ DWORD driverLocLen = 0;
+
+ //
+ // Get the current directory.
+ //
+
+ driverLocLen = GetCurrentDirectory(BufferLength,
+ DriverLocation
+ );
+
+ if (driverLocLen == 0) {
+
+ printf("GetCurrentDirectory failed! Error = %d \n", GetLastError());
+
+ return FALSE;
+ }
+
+ //
+ // Setup path name to driver file.
+ //
+ if (FAILED( StringCbCat(DriverLocation, BufferLength, "\\"DRIVER_NAME".sys") )) {
+ return FALSE;
+ }
+
+ //
+ // Insure driver file is in the specified directory.
+ //
+
+ if ((fileHandle = CreateFile(DriverLocation,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ )) == INVALID_HANDLE_VALUE) {
+
+
+ printf("%s.sys is not loaded.\n", DRIVER_NAME);
+
+ //
+ // Indicate failure.
+ //
+
+ return FALSE;
+ }
+
+ //
+ // Close open file handle.
+ //
+
+ if (fileHandle) {
+
+ CloseHandle(fileHandle);
+ }
+
+ //
+ // Indicate success.
+ //
+
+ return TRUE;
+
+
+} // SetupDriverName
+
+
+