#include <windows.h>
#include <winioctl.h>
#include "winsvc.h"
#include "DriverWork.h"
#include "HandleGuard.h"
#include "FormatError.h"
namespace utils
{
void DriverWork::Install(LPCTSTR driverName,LPCTSTR driverExec,DWORD startType)
{
SC_HANDLE hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hSCManager == INVALID_HANDLE_VALUE)
throw std::runtime_error("Can't open service manager: " + GetLastErrorStr());
ServiceHandleGuard guard(hSCManager);
SC_HANDLE hService =
CreateService ( hSCManager,
driverName,
driverName,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
startType,
SERVICE_ERROR_NORMAL,
driverExec,
NULL, NULL, NULL, NULL, NULL);
if (hService == INVALID_HANDLE_VALUE)
throw std::runtime_error("Can't create service: " + GetLastErrorStr());
CloseServiceHandle(hService);
}
void OpenServiceImpl(LPCTSTR driverName,ServiceHandleGuard* pGuard)
{
SC_HANDLE hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hSCManager == INVALID_HANDLE_VALUE)
throw std::runtime_error("Can't open service manager: " + GetLastErrorStr());
ServiceHandleGuard guard(hSCManager);
SC_HANDLE hService = OpenService (hSCManager, driverName, SERVICE_ALL_ACCESS);
if (hService == INVALID_HANDLE_VALUE)
throw std::runtime_error("Can't open service: " + GetLastErrorStr());
pGuard->reset(hService);
}
void DriverWork::Remove(LPCTSTR driverName,LPCTSTR driverExec)
{
ServiceHandleGuard guard;
OpenServiceImpl(driverName,&guard);
if ( DeleteService(guard.get()) == FALSE )
{
throw std::runtime_error("Can't delete service: " + GetLastErrorStr());
}
}
void DriverWork::Start(LPCTSTR driverName)
{
ServiceHandleGuard guard;
OpenServiceImpl(driverName,&guard);
if ( StartService(guard.get(),0,NULL) == FALSE )
{
throw std::runtime_error("Can't start service: " + GetLastErrorStr());
}
}
void DriverWork::Stop(LPCTSTR driverName)
{
ServiceHandleGuard guard;
OpenServiceImpl(driverName,&guard);
SERVICE_STATUS serviceStatus;
BOOL ret = ControlService(guard.get(), SERVICE_CONTROL_STOP, &serviceStatus);
if ( ret == FALSE )
{
throw std::runtime_error("Can't stop service: " + GetLastErrorStr());
}
}
void DriverWork::Exchange(LPCTSTR driverName,
unsigned long ioctlCode,
PWCHAR pInStr,
DWORD inStr_size,
PWCHAR pOutStr,
DWORD outStr_size,
PDWORD bytesReturned)
{
HANDLE hHandle =
CreateFile( driverName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if(hHandle == INVALID_HANDLE_VALUE)
throw std::runtime_error("Can't get handle to driver: " + GetLastErrorStr());
HandleGuard guard1(hHandle);
if( !DeviceIoControl(hHandle,
ioctlCode,
pInStr, inStr_size, // Input
pOutStr, outStr_size,// Output
bytesReturned,
NULL) )
{
throw std::runtime_error("Driver communication error: " + GetLastErrorStr());
}
}
}// namespace utils