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);
}
}
}