⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdriver.cpp

📁 这是一本学习 window编程的很好的参考教材
💻 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 + -