📄 tdriver.cpp
字号:
//if you use this code in a mfc program:
//add the header stdafx.h or disable precompiled header
//Unless you do it, when compiling vc will say: Unexpected end
//of file while looking for precompiled header
#include "stdafx.h"
#include "TDriver.h"
CServiceControl::CServiceControl()
{
driverHandle = INVALID_HANDLE_VALUE;
SchSCManager = (SC_HANDLE) INVALID_HANDLE_VALUE;
UnloadInDestructor = TRUE;
RemoveInDestructor = FALSE;
lastError = 0;
ChangeIfExists = FALSE;
}
DWORD CServiceControl::init(LPCTSTR Name,
DWORD flagsAndAttributes,
LPCTSTR Path,
LPCTSTR DosName)
{
attributes = flagsAndAttributes;
DriverName = Name;
if (Path) {
BinaryPath = Path;
} else {
//
// allow two choices, first the CWD, second the system root.
//
DWORD length = GetCurrentDirectory(0, NULL);
CString cwd;
LPTSTR buff = cwd.GetBufferSetLength(length);
DWORD result = GetCurrentDirectory(length, buff);
cwd.ReleaseBuffer();
if (result ) {
BinaryPath = CString(cwd) + DriverName + CString(".sys");
result = GetFileAttributes(LPCTSTR(BinaryPath));
}
if (result == 0xffffffff) {
BinaryPath = CString("%SystemRoot%\\system32\\Drivers\\") + DriverName + CString(".sys");
}
}
if (DosName) {
DosDevice = DosName;
} else {
DosDevice = DriverName;
}
//
// if the current string is not the fully qualified
// dos device name, make it so.
//
if ( CString(DosDevice.Left(2)) != CString("\\\\")) {
DosDevice = CString("\\\\.\\") + DosDevice;
}
try {
LoadDriver();
}
catch (DWORD error)
{
//
// don't throw a simple interface error as
// an exception or we get a leak (ugh.)
//
lastError = error;
}
if (lastError != 0) {
try {
closeDevice();
}
catch (...) {};
}
return lastError;
}
CServiceControl::~CServiceControl()
{
try {
closeDevice();
}
catch (...) {};
if (UnloadInDestructor) {
try {
UnloadDriver();
}
catch (...) {};
}
}
/****************************************************************************
*
* FUNCTION: LoadDeviceDriver( const TCHAR, const TCHAR, HANDLE *)
*
* PURPOSE: Registers a driver with the system configuration manager
* and then loads it.
*
****************************************************************************/
void CServiceControl::LoadDriver()
{
BOOL okay;
SchSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if (SchSCManager == INVALID_HANDLE_VALUE) {
throw GetLastError();
}
// Ignore success of installation: it may already be installed.
(void) InstallDriver();
// Ignore success of start: it may already be started.
(void) StartDriver();
// Do make sure we can open it.
okay = OpenDevice();
if (!okay) {
throw GetLastError();
}
SchSCManager = closeSVC(SchSCManager);
}
/****************************************************************************
*
* FUNCTION: InstallDriver( IN SC_HANDLE, IN LPCTSTR, IN LPCTSTR)
*
* PURPOSE: Creates a driver service.
*
****************************************************************************/
BOOL CServiceControl::InstallDriver( )
{
SC_HANDLE schService;
//
// 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.).
//
schService = CreateService( SchSCManager, // SCManager database
DriverName, // name of service
DriverName, // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_KERNEL_DRIVER, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
BinaryPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL // no password
);
if ( schService == NULL ) {
//
// Fine, try to Open it and change it
//
schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
if (schService == NULL) {
//
// this is truly hosed
//
return FALSE;
} else if (ChangeIfExists) {
if (FALSE == ChangeServiceConfig(
schService, // handle to service
SERVICE_KERNEL_DRIVER, // type of service
SERVICE_DEMAND_START, // when to start service
SERVICE_ERROR_NORMAL, // severity if service fails to start
BinaryPath, // pointer to service binary file name
NULL, // pointer to load ordering group name
NULL, // pointer to variable to get tag identifier
NULL, // pointer to array of dependency names
NULL, // pointer to account name of service
NULL, // pointer to password for service account
DriverName // pointer to display name
)) {
//
// oh mama, we are not going to be happy
//
return FALSE;
}
}
}
schService = closeSVC( schService );
return TRUE;
}
/****************************************************************************
*
* FUNCTION: StartDriver( IN SC_HANDLE, IN LPCTSTR)
*
* PURPOSE: Starts the driver service.
*
****************************************************************************/
BOOL CServiceControl::StartDriver()
{
SC_HANDLE schService;
BOOL ret;
schService = OpenService( SchSCManager,
DriverName,
SERVICE_ALL_ACCESS
);
if ( schService == NULL ) {
return FALSE;
}
ret = StartService( schService, 0, NULL );
if (!ret) {
if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) {
ret = 1; // OK
//
// we didn't start it, we don't unload it
//
UnloadInDestructor = FALSE;
}
}
//
// whatever happened close our handle to the SCManager
//
schService = closeSVC( schService );
return ret;
}
/****************************************************************************
*
* FUNCTION: OpenDevice( IN LPCTSTR, HANDLE *)
*
* PURPOSE: Opens the device and returns a handle if desired.
*
****************************************************************************/
BOOL CServiceControl::OpenDevice( )
{
if (driverHandle != INVALID_HANDLE_VALUE) {
CloseHandle(driverHandle);
}
driverHandle = CreateFile( DosDevice,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
attributes,
NULL
);
return driverHandle != INVALID_HANDLE_VALUE;
}
/****************************************************************************
*
* FUNCTION: UnloadDeviceDriver( const TCHAR *)
*
* PURPOSE: Stops the driver and has the configuration manager unload it.
*
****************************************************************************/
void CServiceControl::UnloadDriver()
{
if (SchSCManager == INVALID_HANDLE_VALUE) {
SchSCManager = OpenSCManager( NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
}
if (SchSCManager != INVALID_HANDLE_VALUE) {
if (TRUE == StopDriver()) {
if (RemoveInDestructor) {
RemoveDriver();
}
}
SchSCManager = closeSVC(SchSCManager);
}
}
/****************************************************************************
*
* FUNCTION: StopDriver( IN SC_HANDLE, IN LPCTSTR)
*
* PURPOSE: Has the configuration manager stop the driver (unload it)
*
****************************************************************************/
BOOL CServiceControl::StopDriver()
{
SC_HANDLE schService;
BOOL ret;
SERVICE_STATUS serviceStatus;
schService = OpenService( SchSCManager, DriverName, SERVICE_ALL_ACCESS );
if ( schService == NULL )
return FALSE;
closeDevice();
ret = ControlService( schService, SERVICE_CONTROL_STOP, &serviceStatus );
schService = closeSVC( schService );
return ret;
}
/****************************************************************************
*
* FUNCTION: RemoveDriver( IN SC_HANDLE, IN LPCTSTR)
*
* PURPOSE: Deletes the driver service.
*
****************************************************************************/
BOOL CServiceControl::RemoveDriver( )
{
SC_HANDLE schService;
BOOL ret;
schService = OpenService( SchSCManager,
DriverName,
SERVICE_ALL_ACCESS
);
if ( schService == NULL ) {
return FALSE;
}
ret = DeleteService( schService );
schService = closeSVC( schService );
return ret;
}
void CServiceControl::RemoveDriverOnExit(BOOL val)
{
RemoveInDestructor = val;
}
//Return the driverHandle obtained
HANDLE CServiceControl::GetDriverHandle(void)
{
return driverHandle;
}
//Funtion to send data to the driver
DWORD CServiceControl::WriteIo(DWORD code, PVOID buffer, DWORD count)
{
if(driverHandle == NULL)
return DRV_ERROR_INVALID_HANDLE;
DWORD bytesReturned;
BOOL returnCode = DeviceIoControl(driverHandle,
code,
buffer,
count,
NULL,
0,
&bytesReturned,
NULL);
if(!returnCode)
return DRV_ERROR_IO;
return DRV_SUCCESS;
}
//Functions to read data from the driver
DWORD CServiceControl::ReadIo(DWORD code, PVOID buffer, DWORD count)
{
if(driverHandle == NULL)
return DRV_ERROR_INVALID_HANDLE;
DWORD bytesReturned;
BOOL retCode = DeviceIoControl(driverHandle,
code,
NULL,
0,
buffer,
count,
&bytesReturned,
NULL);
if(!retCode)
return DRV_ERROR_IO;
return bytesReturned;
}
//Function to do IO operation with the driver, read or write or both
DWORD CServiceControl::RawIo(DWORD code, PVOID inBuffer, DWORD inCount, PVOID outBuffer, DWORD outCount)
{
if(driverHandle == NULL)
return DRV_ERROR_INVALID_HANDLE;
DWORD bytesReturned;
BOOL retCode = DeviceIoControl(driverHandle,
code,
inBuffer,
inCount,
outBuffer,
outCount,
&bytesReturned,
NULL);
if(!retCode)
return DRV_ERROR_IO;
return bytesReturned;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -