www.pudn.com > 18900_netwall_lite.rar > Driver.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#include #include "Driver.h" #include "logprintcomm.h" //Constructor. Initialize variables. CDriver::CDriver(void) { driverHandle = NULL; removable = TRUE; driverName = NULL; driverPath = NULL; driverDosName = NULL; initialized = FALSE; loaded = FALSE; started = FALSE; } // // Destructor. Free resources and unload the driver. // CDriver::~CDriver(void) { if (NULL != driverHandle) { CloseHandle(driverHandle); driverHandle = NULL; } UnloadDriver(); } // // If removable = TRUE, the driver isnt unload when exit // void CDriver::SetRemovable(BOOL value) { removable = value; } // //is driver initialized? // BOOL CDriver::IsInitialized(void) { return initialized; } // // is driver loaded? BOOL CDriver::IsLoaded(void) // { return loaded; } // // is driver started? // BOOL CDriver::IsStarted(void) { return started; } // // Init the driver class variables // DWORD CDriver::InitDriver(LPCTSTR path) { // If already initialized, first unload if (initialized) { if (DRV_SUCCESS != UnloadDriver()) { return DRV_ERROR_ALREADY_INITIALIZED; } } // If yes, i analized the path to extract driver name driverPath = (LPTSTR)malloc(strlen(path) + 1); if (NULL == driverPath) { return DRV_ERROR_MEMORY; } strcpy(driverPath, path); // First I search the last backslash LPTSTR sPos1 = strrchr(driverPath, (int)'\\'); // If null, the string havent any backslash if (sPos1 == NULL) { sPos1 = driverPath; } // Now, i search .sys LPTSTR sPos2 = strrchr(sPos1, (int)'.'); if (sPos2 == NULL || sPos1 > sPos2) { free(driverPath); driverPath = NULL; return DRV_ERROR_INVALID_PATH_OR_FILE; } // Extract the driver name driverName = (LPTSTR)malloc(sPos2 - sPos1); if (NULL == driverName) { free(driverPath); driverPath = NULL; return DRV_ERROR_MEMORY; } memcpy(driverName, sPos1 + 1, sPos2 - sPos1 - 1); driverName[sPos2 - sPos1 - 1] = 0; //driverDosName = \\.\driverName driverDosName = (LPTSTR)malloc(strlen(driverName) + 5); if (NULL == driverDosName) { free(driverPath); driverPath = NULL; free(driverName); driverName = NULL; return DRV_ERROR_MEMORY; } sprintf(driverDosName, "\\\\.\\%s", driverName); initialized = TRUE; return DRV_SUCCESS; } // // Init the driver class variables // DWORD CDriver::InitDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName) { // If already initialized, first unload if (initialized) { if (DRV_SUCCESS != UnloadDriver()) { return DRV_ERROR_ALREADY_INITIALIZED; } } LPTSTR dirBuffer; // If the user introduced path, first I will ckeck it if (NULL != path) { // If yes, copy in auxiliar buffer and continue DWORD len = (DWORD)(strlen(name) + strlen(path) + 1); dirBuffer = (LPTSTR)malloc(len); if (NULL == dirBuffer) { return DRV_ERROR_MEMORY; } strcpy(dirBuffer, path); } else { // If the user dont introduced path, I search in curren directory LPTSTR pathBuffer; DWORD len = GetCurrentDirectory(0, NULL); pathBuffer = (LPTSTR)malloc(len); if (NULL == pathBuffer) { return DRV_ERROR_MEMORY; } if (0 != GetCurrentDirectory(len, pathBuffer)) { len = (DWORD)(strlen(pathBuffer) + strlen(name) + 6); dirBuffer = (LPTSTR)malloc(len); if (NULL == dirBuffer) { free(pathBuffer); return DRV_ERROR_MEMORY; } // complete de total path, currentdirectory\driverName.sys sprintf(dirBuffer, "%s\\%s.sys", pathBuffer, name); // exists this file? if (GetFileAttributes(dirBuffer) == 0xFFFFFFFF) { free(pathBuffer); free(dirBuffer); // If no, i search in \system32\drivers\ LPCTSTR sysDriver = "\\system32\\Drivers\\"; LPTSTR sysPath; //i have to get the windows directory DWORD len = GetWindowsDirectory(NULL, 0); sysPath = (LPTSTR)malloc(len + strlen(sysDriver)); if (NULL == sysPath) { return DRV_ERROR_MEMORY; } if (0 == GetWindowsDirectory(sysPath, len)) { free(sysPath); return DRV_ERROR_UNKNOWN; } //complete the path and check it strcat(sysPath, sysDriver); len = (DWORD)(strlen(sysPath) + strlen(name) + 5); dirBuffer = (LPTSTR)malloc(len); if (NULL == dirBuffer) { return DRV_ERROR_MEMORY; } sprintf(dirBuffer, "%s%s.sys", sysPath, name); free(sysPath); // If the file neither exist, I dont know where is it -> I dont initialize if (GetFileAttributes(dirBuffer) == 0xFFFFFFFF) { free(dirBuffer); return DRV_ERROR_INVALID_PATH_OR_FILE; } } } else { free(pathBuffer); return DRV_ERROR_UNKNOWN; } } // Write driver's variables with obtained data driverPath = dirBuffer; driverName = (LPTSTR)malloc(strlen(name) + 1); if (NULL == driverName) { free(driverPath); driverPath = NULL; return DRV_ERROR_MEMORY; } strcpy(driverName, name); LPCTSTR auxBuffer; if (NULL != dosName) { auxBuffer = dosName; } else { auxBuffer = name; } //dosName = \\.\driverName if (auxBuffer[0] != '\\' && auxBuffer[1] != '\\') { driverDosName = (LPTSTR)malloc(strlen(auxBuffer) + 5); if (NULL == driverDosName) { free(driverPath); driverPath = NULL; free(driverName); driverName = NULL; return DRV_ERROR_MEMORY; } sprintf(driverDosName, "\\\\.\\%s", auxBuffer); } else { driverDosName = (LPTSTR)malloc(strlen(auxBuffer)); if (NULL == driverDosName) { free(driverPath); driverPath = NULL; free(driverName); driverName = NULL; return DRV_ERROR_MEMORY; } strcpy(driverDosName, auxBuffer); } //set the state to initialized initialized = TRUE; return DRV_SUCCESS; } // // Function to Load the driver. // DWORD CDriver::LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, BOOL start) { // First initialized it DWORD retCode = InitDriver(name, path, dosName); //then load if (DRV_SUCCESS == retCode) { retCode = LoadDriver(start); } return retCode; } // // Function to load the driver // DWORD CDriver::LoadDriver(LPCTSTR path, BOOL start) { //first initialized it DWORD retCode = InitDriver(path); //then load if (DRV_SUCCESS == retCode) { retCode = LoadDriver(start); } return retCode; } // //Function to Load the driver // DWORD CDriver::LoadDriver(BOOL start) { // if the driver is already started, i havent to do nothing if (loaded) { return DRV_SUCCESS; } if (! initialized) { return DRV_ERROR_NO_INITIALIZED; } // Open Service manager to create the new "service" SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); DWORD retCode = DRV_SUCCESS; if (NULL == SCManager) { return DRV_ERROR_SCM; } //Create the driver "service" SC_HANDLE SCService = CreateService(SCManager, // SCManager database driverName, // nombre del servicio driverName, // nombre a mostrar SERVICE_ALL_ACCESS, // acceso total SERVICE_KERNEL_DRIVER, // driver del kernel SERVICE_DEMAND_START, // comienzo bajo demanda SERVICE_ERROR_NORMAL, // control de errores normal driverPath, // path del driver NULL, // no pertenece a un grupo NULL, // sin tag NULL, // sin dependencias NULL, // cuenta local del sistema NULL // sin password ); //if i cant create, first i check if the driver already was loaded. if (NULL == SCService) { SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS); if (NULL == SCService) { retCode = DRV_ERROR_SERVICE; } } CloseServiceHandle(SCService); SCService = NULL; CloseServiceHandle(SCManager); SCManager = NULL; //if all ok, update the state and start if necessary if (DRV_SUCCESS == retCode) { loaded = TRUE; if (start) { retCode = StartDriver(); } } return retCode; } // // Function to Unload a driver // DWORD CDriver::UnloadDriver(BOOL forceClearData) { DWORD retCode = DRV_SUCCESS; //if the driver is started, first i will stop it if (started) { if ((retCode = StopDriver()) == DRV_SUCCESS) { // I only remove it, if it is mark to be removable if (removable) { // open service and delete it SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (NULL == SCManager) { return DRV_ERROR_SCM; } SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS); if (NULL != SCService) { if (! DeleteService(SCService)) { retCode = DRV_ERROR_REMOVING; } else { retCode = DRV_SUCCESS; } } else { retCode = DRV_ERROR_SERVICE; } CloseServiceHandle(SCService); SCService = NULL; CloseServiceHandle(SCManager); SCManager = NULL; // if all ok, update the state if (retCode == DRV_SUCCESS) { loaded = FALSE; } } } } // if the driver is initialized... if (initialized) { //if there was some problem but i mark foreceClear, i will remove the data if (DRV_SUCCESS != retCode && FALSE == forceClearData) { return retCode; } // update the state initialized = FALSE; //free memory if (NULL != driverPath) { free(driverPath); driverPath = NULL; } if (NULL != driverDosName) { free(driverDosName); driverDosName = NULL; } if (NULL != driverName) { free(driverName); driverName = NULL; } } return retCode; } // // Function to start the driver "service" // DWORD CDriver::StartDriver(void) { //if already started, all ok if (started) { return DRV_SUCCESS; } //open the service manager and the service and change driver state SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); DWORD retCode; if (NULL == SCManager) { return DRV_ERROR_SCM; } SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS); if (NULL == SCService) { return DRV_ERROR_SERVICE; } if (! StartService(SCService, 0, NULL)) { //if the driver was started before i try to do it, //i will not remove, because it was created by other application if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) { removable = FALSE; retCode = DRV_SUCCESS; } else { retCode = DRV_ERROR_STARTING; } } else { retCode = DRV_SUCCESS; } CloseServiceHandle(SCService); SCService = NULL; CloseServiceHandle(SCManager); SCManager = NULL; //update the state and open device if (DRV_SUCCESS == retCode) { started = TRUE; retCode = OpenDevice(); } return retCode; } // // Function to stop driver "service" // DWORD CDriver::StopDriver(void) { //if already stopped, all ok if (! started) { return DRV_SUCCESS; } //open the service manager and the service and change driver state SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); DWORD retCode; if (NULL == SCManager) { return DRV_ERROR_SCM; } SERVICE_STATUS status; SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS); if (NULL != SCService) { //close the driver handle too CloseHandle(driverHandle); driverHandle = NULL; if (! ControlService(SCService, SERVICE_CONTROL_STOP, &status)) { retCode = DRV_ERROR_STOPPING; } else { retCode = DRV_SUCCESS; } } else { retCode = DRV_ERROR_SERVICE; } CloseServiceHandle(SCService); SCService = NULL; CloseServiceHandle(SCManager); SCManager = NULL; //update the state if(DRV_SUCCESS == retCode) { started = FALSE; } return retCode; } // // Funtion to open a driver handle // DWORD CDriver::OpenDevice(void) { //if i already have a handle, first close it if (NULL != driverHandle) { CloseHandle(driverHandle); } driverHandle = CreateFile(driverDosName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (INVALID_HANDLE_VALUE == driverHandle) { return DRV_ERROR_INVALID_HANDLE; } return DRV_SUCCESS; } // // Return the driverHandle obtained // HANDLE CDriver::GetDriverHandle(void) { return driverHandle; } // // Funtion to send data to the driver // DWORD CDriver::WriteIo(DWORD code, PVOID buffer, DWORD count) { if (NULL == driverHandle) { return DRV_ERROR_INVALID_HANDLE; } DWORD bytesReturned; BOOL retCode = DeviceIoControl(driverHandle, code, buffer, count, NULL, 0, &bytesReturned, NULL ); if (! retCode) { return DRV_ERROR_IO; } return DRV_SUCCESS; } // //Functions to read data from the driver // DWORD CDriver::ReadIo(DWORD code, PVOID buffer, DWORD count) { if (NULL == driverHandle) { 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 CDriver::RawIo(DWORD code, PVOID inBuffer, DWORD inCount, PVOID outBuffer, DWORD outCount) { if (NULL == driverHandle) { 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; } /************************************************************************/ /* N T D E V I C E D R I V E R R O U T I N E */ /************************************************************************/ /**************************************************************************** * * FUNCTION: UnloadDeviceDriver( const TCHAR *) * * PURPOSE: Stops the driver and has the configuration manager unload it. * ****************************************************************************/ BOOL CDriver::UnloadDeviceDriver(LPCTSTR lpszDriverName, LPTSTR lpszError) { // // Open service control manager // SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (NULL == hSCManager) { _stprintf(lpszError, _T("%s"), _T("Could not open Service Control Manager.")); return FALSE; } // // Driver is there // SC_HANDLE hDriver = OpenService(hSCManager, lpszDriverName, SERVICE_ALL_ACCESS); if (NULL == hDriver) { _stprintf(lpszError, _T("%s"), _T("Could not open driver service")); CloseServiceHandle(hSCManager); return FALSE; } SERVICE_STATUS ss; if (ControlService(hDriver, SERVICE_CONTROL_INTERROGATE, &ss)) { _stprintf(lpszError, _T("%s"), _T("Could not interrogate driver service")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } if (SERVICE_STOPPED == ss.dwCurrentState) { BOOL bRet = DeleteService(hDriver); if (! bRet) { _stprintf(lpszError, _T("%s"), _T("Could not delete driver service")); } CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return bRet; } if (! ControlService(hDriver, SERVICE_CONTROL_STOP, &ss)) { _stprintf(lpszError, _T("%s"), _T("Could not stop driver")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } // // Give it 10 seconds to stop // BOOL Stopped = FALSE; for (int seconds = 0; seconds < 10; seconds++) { Sleep(1000); if (ControlService(hDriver, SERVICE_CONTROL_INTERROGATE, &ss) && SERVICE_STOPPED == ss.dwCurrentState) { Stopped = TRUE; break; } } if (! Stopped) { _stprintf(lpszError, _T("%s"), _T("Could not stop driver")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } BOOL bRet = DeleteService(hDriver); if (! bRet) { _stprintf(lpszError, _T("%s"), _T("Could not delete driver service")); } CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return bRet; } /**************************************************************************** * * FUNCTION: LoadDeviceDriver( const TCHAR, const TCHAR, HANDLE *) * * PURPOSE: Registers a driver with the system configuration manager * and then loads it. * ****************************************************************************/ BOOL CDriver::LoadDeviceDriver(LPCTSTR lpszDriverName, LPCTSTR lpszDriverFromPath, LPTSTR lpszError ) { assert(lpszDriverName && lpszDriverFromPath); assert(lpszError); // // Get System32 directory // _asm int 3; _TCHAR System32Directory[_MAX_PATH]; if (0 == GetSystemDirectory(System32Directory, _MAX_PATH)) // C:\WINNT\System32 { _stprintf(lpszError, _T("%s"), _T("Could not find Windows system directory.")); return FALSE; } // // Copy driver .sys file across // _TCHAR szDriverFullPath[_MAX_PATH]; _stprintf(szDriverFullPath, _T("%s\\drivers\\%s.sys"), System32Directory, lpszDriverName); if (FALSE == CopyFile(lpszDriverFromPath, szDriverFullPath, FALSE)) // Overwrite OK { _stprintf(lpszError, _T("Unable to copy %s to %s\n\nMake sure that logprint.sys is in the current directory."), lpszDriverName, szDriverFullPath); return FALSE; } // // Create driver (or stop existing driver) // if (! CreateDriver(lpszDriverName, szDriverFullPath, lpszError)) { return FALSE; } // // Create/Open driver registry key and set its values // Overwrite registry values written in driver creation // HKEY hKey; DWORD disposition; TCHAR szDriverpath[_MAX_PATH]; _stprintf(szDriverpath, _T("SYSTEM\\CurrentControlSet\\Services\\%s"), lpszDriverName); if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE, szDriverpath, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, &disposition )) { _stprintf(lpszError, _T("%s"), _T("Could not create driver registry key.")); return FALSE; } /* // Delete ImagePath RegDeleteValue(hKey, _T("ImagePath")); // Delete DisplayName RegDeleteValue(hKey, _T("DisplayName")); // ErrorControl DWORD dwRegValue = SERVICE_ERROR_NORMAL; if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("ErrorControl"), 0, REG_DWORD, (CONST BYTE*)&dwRegValue, sizeof(DWORD))) { _stprintf(lpszError, _T("%s"), _T("Could not create driver registry value ErrorControl.")); return FALSE; } // Start dwRegValue = SERVICE_DEMAND_START;//SERVICE_AUTO_START; if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("Start"), 0, REG_DWORD, (CONST BYTE*)&dwRegValue, sizeof(DWORD))) { _stprintf(lpszError, _T("%s"), _T("Could not create driver registry value Start.")); return FALSE; } // Type dwRegValue = SERVICE_KERNEL_DRIVER; if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("Type"), 0, REG_DWORD, (CONST BYTE*)&dwRegValue, sizeof(DWORD))) { _stprintf(lpszError, _T("%s"), _T("Could not create driver registry value Type.")); return FALSE; } RegCloseKey(hKey); // // Create/Open driver\Parameters registry key and set its values // TCHAR szParapath[_MAX_PATH]; _stprintf(szParapath, _T("SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters"), lpszDriverName); if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE, szParapath, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, &disposition )) { _stprintf(lpszError, _T("%s"), _T("Could not create driver\\Parameters registry key.")); return FALSE; } // EventLogLevel dwRegValue = 1; if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("EventLogLevel"), 0, REG_DWORD, (CONST BYTE*)&dwRegValue, sizeof(DWORD))) { _stprintf(lpszError, _T("%s"), _T("Could not create driver\\Parameters registry value EventLogLevel.")); return FALSE; } // Default or No Name int DeviceNameLen = _tcslen(lpszDriverName) + 1; if (ERROR_SUCCESS != RegSetValueEx(hKey, _T(""), 0, REG_SZ, (CONST BYTE*)lpszDriverName, DeviceNameLen)) { _stprintf(lpszError, _T("%s"), _T("Could not create driver\\Parameters default registry value.")); return FALSE; } RegCloseKey(hKey); // // Open EventLog\System registry key and set its values // if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\System"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, &disposition )) { _stprintf(lpszError, _T("%s"), _T("Could not open EventLog\\System registry key.")); return FALSE; } // get Sources size DWORD DataSize = 0; DWORD Type; if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("Sources"), NULL, &Type, NULL, &DataSize)) { _stprintf(lpszError, _T("%s"), _T("Could not read size of EventLog\\System registry value Sources.")); return FALSE; } // read Sources int DriverNameLen = _tcslen(lpszDriverName); DataSize += DriverNameLen + 1; LPTSTR Sources = new _TCHAR[DataSize]; if (NULL == Sources || ERROR_SUCCESS != RegQueryValueEx(hKey, _T("Sources"), NULL, &Type, (LPBYTE)Sources, &DataSize)) { _stprintf(lpszError, _T("%s"), _T("Could not read EventLog\\System registry value Sources.")); if (NULL != Sources) { delete []Sources; Sources = NULL; } return FALSE; } delete []Sources; // // If driver not there, add and write // if (-1 == FindInMultiSz(Sources, DataSize, lpszDriverName)) { _tcscpy(Sources + DataSize - 1, lpszDriverName); DataSize += DriverNameLen; *(Sources + DataSize) = '\0'; if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("Sources"), 0, REG_MULTI_SZ, (CONST BYTE*)Sources, DataSize)) { _stprintf(lpszError, _T("%s"), _T("Could not create driver registry value Sources.")); return FALSE; } } RegCloseKey(hKey); // // Create/Open EventLog\System\driver registry key and set its values // _stprintf(szParapath, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\System\\%s"), lpszDriverName); if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE, szParapath, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, &disposition )) { _stprintf(lpszError, _T("%s"), _T("Could not create EventLog\\System\\driver registry key.")); return FALSE; } // TypesSupported dwRegValue = 7; if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("TypesSupported"), 0, REG_DWORD, (CONST BYTE*)&dwRegValue, sizeof(DWORD))) { _stprintf(lpszError, _T("%s"), _T("Could not create EventLog\\System\\driver registry value TypesSupported.")); return FALSE; } // EventMessageFile TCHAR szEventMessageFile[_MAX_PATH]; _stprintf(szEventMessageFile, _T(%s%s.sys"), _T("%SystemRoot%\\System32\\IoLogMsg.dll;%SystemRoot%\\System32\\Drivers\\"), lpszDriverName); if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("EventMessageFile"), 0, REG_EXPAND_SZ, (CONST BYTE*)szEventMessageFile, _tcslen(szEventMessageFile) + 1)) { _stprintf(lpszError, _T("%s"), _T("Could not create EventLog\\System\\driver registry value EventMessageFile.")); return FALSE; } RegCloseKey(hKey); */ ///////////////////////////////////////////////////////////////////////// // Start driver service if (! StartDriver(lpszDriverName, lpszError)) { return FALSE; } return FALSE; } ///////////////////////////////////////////////////////////////////////////// BOOL CDriver::CreateDriver(LPCTSTR lpszDriverName, LPCTSTR lpszFullDriver, LPTSTR lpszError) { // // Open service control manager // SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (NULL == hSCManager) { _stprintf(lpszError, _T("%s"), _T("Could not open Service Control Manager")); return FALSE; } // // If driver is running, stop it // SC_HANDLE hDriver = OpenService(hSCManager, lpszDriverName, SERVICE_ALL_ACCESS); if (NULL != hDriver) { SERVICE_STATUS ss; if (ControlService(hDriver, SERVICE_CONTROL_INTERROGATE, &ss)) { if (SERVICE_STOPPED != ss.dwCurrentState) { if (! ControlService(hDriver, SERVICE_CONTROL_STOP, &ss)) { _stprintf(lpszError, _T("%s"), _T("Could not stop driver")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } // // Give it 10 seconds to stop // BOOL Stopped = FALSE; for (int seconds = 0; seconds < 10; seconds++) { Sleep(1000); if (ControlService(hDriver, SERVICE_CONTROL_INTERROGATE, &ss) && SERVICE_STOPPED == ss.dwCurrentState) { Stopped = TRUE; break; } } if (! Stopped) { _stprintf(lpszError, _T("%s"), _T("Could not stop driver")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } } CloseServiceHandle(hDriver); } return TRUE; } // // Create driver service // hDriver = CreateService(hSCManager, // SCManager database lpszDriverName, // name of service lpszDriverName, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_KERNEL_DRIVER, // service type SERVICE_DEMAND_START, // start type SERVICE_ERROR_NORMAL, // error control type lpszFullDriver, // service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL // no password ); /* ERROR_ACCESS_DENIED 5L ERROR_CIRCULAR_DEPENDENCY 1059L ERROR_DUP_NAME 52L ERROR_INVALID_HANDLE 6L ERROR_INVALID_NAME 123L ERROR_INVALID_PARAMETER 87L ERROR_INVALID_SERVICE_ACCOUNT 1057L ERROR_SERVICE_EXISTS 1073L */ if (NULL == hDriver) { DWORD error = GetLastError(); _stprintf(lpszError, _T("%s"), _T("Could not install driver with Service Control Manager")); CloseServiceHandle(hSCManager); return FALSE; } CloseServiceHandle(hSCManager); return TRUE; } ///////////////////////////////////////////////////////////////////////////// BOOL CDriver::StartDriver(LPCTSTR lpszDriverName, LPTSTR lpszError) { // // Open service control manager // SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (NULL == hSCManager) { _stprintf(lpszError, _T("%s"), _T("Could not open Service Control Manager.")); return FALSE; } // // Driver isn't there // SC_HANDLE hDriver = OpenService(hSCManager, lpszDriverName, SERVICE_ALL_ACCESS); if (NULL == hDriver) { _stprintf(lpszError, _T("%s"), _T("Could not open driver service")); CloseServiceHandle(hSCManager); return FALSE; } /* ERROR_ACCESS_DENIED 5 ERROR_DEPENDENT_SERVICES_RUNNING 1051 ERROR_INVALID_HANDLE 6 ERROR_INVALID_PARAMETER 87 ERROR_INVALID_SERVICE_CONTROL 1052 ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061 ERROR_SERVICE_NOT_ACTIVE 1062 ERROR_SERVICE_REQUEST_TIMEOUT 1053 ERROR_SHUTDOWN_IN_PROGRESS 1115L */ SERVICE_STATUS ss; if (! ControlService(hDriver, SERVICE_CONTROL_INTERROGATE, &ss)) { DWORD error = GetLastError(); _stprintf(lpszError, _T("%s"), _T("Could not interrogate driver service")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } if (SERVICE_STOPPED != ss.dwCurrentState) { _stprintf(lpszError, _T("%s"), _T("Driver service already running.")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } /*ERROR_ACCESS_DENIED 5L ERROR_INVALID_HANDLE 6L ERROR_PATH_NOT_FOUND 3L ERROR_SERVICE_ALREADY_RUNNING 1056L ERROR_SERVICE_DATABASE_LOCKED 1055L ERROR_SERVICE_DEPENDENCY_DELETED 1075L ERROR_SERVICE_DEPENDENCY_FAIL 1068L ERROR_SERVICE_DISABLED 1058L ERROR_SERVICE_LOGON_FAILED 1069L ERROR_SERVICE_MARKED_FOR_DELETE 1072L ERROR_SERVICE_NO_THREAD 1054L ERROR_SERVICE_REQUEST_TIMEOUT 1053L */ if (! StartService(hDriver, 0, NULL)) { DWORD error = GetLastError(); _stprintf(lpszError, _T("%s"), _T("Could not start driver")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } // // Give it 10 seconds to start // BOOL Started = FALSE; for (int seconds = 0; seconds < 10; seconds++) { Sleep(1000); if (ControlService(hDriver, SERVICE_CONTROL_INTERROGATE, &ss) && SERVICE_RUNNING == ss.dwCurrentState) { Started = TRUE; break; } } if (! Started) { _stprintf(lpszError, _T("%s"), _T("Could not start driver")); CloseServiceHandle(hSCManager); CloseServiceHandle(hDriver); return FALSE; } CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return TRUE; } /**************************************************************************** * * FUNCTION: OpenDevice( IN LPCTSTR, HANDLE *) * * PURPOSE: Opens the device and returns a handle if desired. * ****************************************************************************/ BOOL CDriver::OpenDevice(DWORD dwInst, HANDLE * lphDevice, LPTSTR lpszError, IN GUID * pGuid) { BOOL bRet = FALSE; HDEVINFO info = INVALID_HANDLE_VALUE; do { // Get handle to relevant device information set if (NULL == pGuid) { pGuid = (LPGUID)&LOGPRINT_GUID; } assert(NULL != pGuid); info = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if (INVALID_HANDLE_VALUE == info) { _stprintf(lpszError, _T("%s"), _T("Could not get device info set.")); break; } // Get interface data for the requested instance SP_INTERFACE_DEVICE_DATA ifdata; ifdata.cbSize = sizeof(ifdata); if (! SetupDiEnumDeviceInterfaces(info, NULL, pGuid, dwInst, &ifdata)) { _stprintf(lpszError, _T("%s"), _T("Could not get interface data for the requested instance.")); break; } // Get size of symbolic link name DWORD ReqLen; SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL); PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]); if (NULL == ifDetail) { _stprintf(lpszError, _T("%s"), _T("Could not get size of symbolic link name.")); break; } // Get symbolic link name ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); if( !SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL)) { delete ifDetail; _stprintf(lpszError, _T("%s"), _T("Could not get symbolic link name.")); break; } // Open file HANDLE hDevice = CreateFile(ifDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if (INVALID_HANDLE_VALUE == hDevice) { _stprintf(lpszError, _T("%s"), _T("Could not open LogPrint device.")); } // Tidy up delete ifDetail; // If user wants handle, give it to them. Otherwise, just close it. *lphDevice = hDevice; bRet = TRUE; } while (FALSE); if (INVALID_HANDLE_VALUE != info) { SetupDiDestroyDeviceInfoList(info); } return bRet; } ///////////////////////////////////////////////////////////////////////////// // Try to find Match in MultiSz, including Match's terminating \0 int CDriver::FindInMultiSz(LPTSTR MultiSz, int MultiSzLen, LPCTSTR Match) { int MatchLen = _tcslen(Match); _TCHAR FirstChar = *Match; for (int i = 0; i < MultiSzLen - MatchLen; i++) { if (*MultiSz++ == FirstChar) { BOOL Found = TRUE; LPTSTR Try = MultiSz; for (int j = 1; j <= MatchLen; j++) { if (*Try++ != Match[j]) { Found = FALSE; break; } } if (Found) { return i; } } } return -1; } /* extern CDriver * pDriver; BOOL CMainFrame::TestLoadDriver() { #define SYS_FILE _T("logprint.sys") #define SYS_NAME _T("LogPrint") static TCHAR szLogFile[_MAX_PATH]; // Driver's registry key TCHAR DriverRegistryKey[] = _T("System\\CurrentControlSet\\Services\\LogPrint"); CWaitCursor wait; TCHAR szDriverPath[_MAX_PATH]; GetCurrentDirectory(sizeof(szDriverPath), szDriverPath); _stprintf(szDriverPath + _tcslen(szDriverPath), _T("\\%s"), SYS_FILE); WIN32_FIND_DATA findData; HANDLE findHandle = FindFirstFile(szDriverPath, &findData); if (INVALID_HANDLE_VALUE == findHandle) { TCHAR * pFile; if (! SearchPath(NULL, SYS_FILE, NULL, sizeof(szDriverPath), szDriverPath, &pFile)) { CString strTmp; strTmp.Format(_T("%s was not found."), SYS_FILE); AfxMessageBox(strTmp); return; } } else { FindClose(findHandle); } // read driver start type to see if boot-logging is enabled HKEY hDriverKey; DWORD type, driverStart = SERVICE_DEMAND_START; if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, DriverRegistryKey, &hDriverKey)) { DWORD length = sizeof(driverStart); RegQueryValueEx(hDriverKey, _T("Start"), NULL, &type, (PBYTE)&driverStart, &length); RegCloseKey(hDriverKey); } BOOL bBootLog = (driverStart != SERVICE_DEMAND_START); // // Load LogPrint Driver // TCHAR lpszError[MAX_PATH]; RtlZeroMemory(lpszError, MAX_PATH); if (! (pDriver->LoadDeviceDriver(SYS_NAME, szDriverPath, lpszError)) { AfxMessageBox((LPCTSTR)lpszError); return; } // // Open LogPrint Device // TCHAR lpszError[MAX_PATH]; RtlZeroMemory(lpszError, MAX_PATH); if (! (pDriver->OpenDevice(0, &m_hLogPrint, lpszError)) { AfxMessageBox((LPCTSTR)lpszError); return; } ASSERT(INVALID_HANDLE_VALUE != m_hLogPrint); // // Correct driver version? // DWORD nb, versionNumber; if (! DeviceIoControl(m_hLogPrint, IOCTL_LOGPRINT_GET_VERSION, NULL, 0, &versionNumber, sizeof(DWORD), &nb, NULL) || versionNumber != LOGPRINT_VERSION) { AfxMessageBox(_T("LogPrint located a driver with the wrong version.\n") _T("\nIf you just installed a new version you must reboot before you are") _T("able to use it.")); return; } } */