class DriverControl { private IntPtr hSCManager; private IntPtr hService; private IntPtr hDevice; private uint dwErrorCode; public const int MAX_SERVICE_NAME = 256; public const int MAX_DISPLAY_NAME = 256; public const int MAX_PATH_LENGTH = 260; private void initialize() { hSCManager = Advapi32.OpenSCManager(null, null, Advapi32.SC_MANAGER_ALL_ACCESS); if (hSCManager == IntPtr.Zero) { dwErrorCode = Kernel32.GetLastError(); } hService = IntPtr.Zero; hDevice = (IntPtr)Kernel32.INVALID_HANDLE_VALUE; dwErrorCode = 0; } private bool queryCurrentStatus(out uint dwCurrentState) { dwCurrentState = 0; if (hService != IntPtr.Zero) { Advapi32.SERVICE_STATUS serviceStatus = new Advapi32.SERVICE_STATUS(); if (Advapi32.QueryServiceStatus(hService, ref serviceStatus) != 0) { dwCurrentState = serviceStatus.dwCurrentState; return true; } else { dwErrorCode = Kernel32.GetLastError(); } } return false; } public uint getLastError() { return dwErrorCode; } public bool isOpened() { return !hService.Equals(IntPtr.Zero); } public bool open(string driverName) { if (hSCManager != IntPtr.Zero) { if (driverName == "") { return false; } if (hService != IntPtr.Zero) { Advapi32.CloseServiceHandle(hService); } hService = Advapi32.OpenService(hSCManager, driverName, Advapi32.SERVICE_ALL_ACCESS); if (hService != IntPtr.Zero) { return true; } else { dwErrorCode = Kernel32.GetLastError(); } } return false; } public bool install(string driverName, string driverPath, string displayName) { if (hSCManager != IntPtr.Zero) { if (driverName == "" || driverPath == "" || displayName == "") { return false; } if (hService != IntPtr.Zero) { Advapi32.CloseServiceHandle(hService); } //CreateService(scHandle, szDrvSvcName, szDrvDisplayName, //SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, //SERVICE_ERROR_NORMAL, szDrvFilePath, 0, 0, 0, 0, 0) hService = Advapi32.CreateService(hSCManager, driverName, displayName, Advapi32.SERVICE_ALL_ACCESS, Advapi32.SERVICE_KERNEL_DRIVER, Advapi32.SERVICE_DEMAND_START, Advapi32.SERVICE_ERROR_NORMAL, driverPath, null, IntPtr.Zero, null, null, null); if (hService != IntPtr.Zero) { return true; } else { dwErrorCode = Kernel32.GetLastError(); } } return false; } public bool start() { if (hService != IntPtr.Zero) { if (Advapi32.StartService(hService, 0, null) != 0) { uint dwCurrentState = 0; long nCount = 0; bool bRet = queryCurrentStatus(out dwCurrentState); while (nCount < 31 || (bRet && dwCurrentState != Advapi32.SERVICE_RUNNING)) { Interlocked.Increment(ref nCount); bRet = queryCurrentStatus(out dwCurrentState); Thread.Sleep(31); } return true; } else { dwErrorCode = Kernel32.GetLastError(); } } return false; } public bool stop() { unlink(); if (hService != IntPtr.Zero) { Advapi32.SERVICE_STATUS serviceStatus = new Advapi32.SERVICE_STATUS(); if (Advapi32.ControlService(hService, Advapi32.SERVICE_CONTROL_STOP, ref serviceStatus) != 0) { long nCount = 0; uint dwCurrentState; bool bRet = queryCurrentStatus(out dwCurrentState); while (nCount < 31 || (bRet && dwCurrentState != Advapi32.SERVICE_STOPPED)) { Interlocked.Increment(ref nCount); bRet = queryCurrentStatus(out dwCurrentState); Thread.Sleep(31); } return true; } else { dwErrorCode = Kernel32.GetLastError(); } } return false; } public bool uninstall() { if (hService != IntPtr.Zero) { stop(); if (Advapi32.DeleteService(hService) != 0) { Advapi32.CloseServiceHandle(hService); hService = IntPtr.Zero; return true; } else { dwErrorCode = Kernel32.GetLastError(); } } return false; } public bool link(string deviceLink) { if (hDevice == (IntPtr)Kernel32.INVALID_HANDLE_VALUE) { if (deviceLink == "") { return false; } if (!deviceLink.StartsWith("\\\\.\\")) { deviceLink = "\\\\.\\" + deviceLink; } hDevice = Kernel32.CreateFile( deviceLink, Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE, 0, IntPtr.Zero, Kernel32.OPEN_EXISTING, Kernel32.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (hDevice != (IntPtr)Kernel32.INVALID_HANDLE_VALUE) { return true; } else { dwErrorCode = Kernel32.GetLastError(); } } return false; } public bool ioControl(uint dwIoCtlCode, byte[] pBufferIn, uint dwBufferIn, byte[] pBufferOut, uint dwBufferOut) { if (hDevice != (IntPtr)Kernel32.INVALID_HANDLE_VALUE) { uint bytesReturn = 0; int ioret = Kernel32.DeviceIoControl(hDevice, dwIoCtlCode, pBufferIn, dwBufferIn, pBufferOut, dwBufferOut, ref bytesReturn, IntPtr.Zero); if (ioret == 0) { dwErrorCode = Kernel32.GetLastError(); } else { return true; } } return false; } public void unlink() { Kernel32.CloseHandle(hDevice); hDevice = (IntPtr)Kernel32.INVALID_HANDLE_VALUE; } public DriverControl() { initialize(); } public DriverControl(string serviceName) { initialize(); open(serviceName); } ~DriverControl() { if (hDevice != (IntPtr)Kernel32.INVALID_HANDLE_VALUE) { Kernel32.CloseHandle(hDevice); } if (hService != IntPtr.Zero) { Advapi32.CloseServiceHandle(hService); } if (hSCManager != IntPtr.Zero) { Advapi32.CloseServiceHandle(hSCManager); } } }