#include "stdafx.h"

BOOL InstallDriver(IN SC_HANDLE SchSCManager, 
				   IN LPCTSTR DriverName, IN LPCTSTR ServiceExe)
{
    SC_HANDLE  schService;


    schService = CreateService(SchSCManager, DriverName, DriverName,          
                                SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, 
                                SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,  
                                ServiceExe, NULL, NULL, NULL, NULL, NULL);

    if (schService == NULL)
        return FALSE;

    CloseServiceHandle(schService);

    return TRUE;
}

BOOL StartDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName)
{
    SC_HANDLE  schService;
    BOOL       ret;

    schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);

    if (schService == NULL)
        return FALSE;

    ret = StartService( schService, 0, NULL )
       || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING 
	   || GetLastError() == ERROR_SERVICE_DISABLED;

    CloseServiceHandle(schService);

    return ret;
}

BOOL OpenDevice(IN LPCTSTR DriverName, HANDLE * lphDevice)
{
    TCHAR    completeDeviceName[64];
    HANDLE   hDevice;

	if ( (GetVersion() & 0xFF) >= 5 ) {

		wsprintf(completeDeviceName, TEXT("\\\\.\\Global\\%s"), DriverName);

	} else {

		wsprintf(completeDeviceName, TEXT("\\\\.\\%s"), DriverName);
	}

    hDevice = CreateFile(completeDeviceName, GENERIC_READ | GENERIC_WRITE, 0,
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hDevice == ((HANDLE)-1))
        return FALSE;

	if (lphDevice)
		*lphDevice = hDevice;
	else
	    CloseHandle(hDevice);

    return TRUE;
}


BOOL StopDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName)
{
    SC_HANDLE       schService;
    BOOL            ret;
    SERVICE_STATUS  serviceStatus;

    schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
    if (schService == NULL)
        return FALSE;

    ret = ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus );

    CloseServiceHandle(schService);

    return ret;
}

BOOL RemoveDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName)
{
    SC_HANDLE  schService;
    BOOL       ret;

    schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);

    if (schService == NULL)
        return FALSE;

    ret = DeleteService(schService);

    CloseServiceHandle(schService);

    return ret;
}


BOOL UnloadDeviceDriver(const TCHAR * Name)
{
	SC_HANDLE	schSCManager;

	schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

	if(!schSCManager) return FALSE;

	if(StopDriver(schSCManager, Name) == FALSE)
		return FALSE;
	 
	CloseServiceHandle(schSCManager);

	return TRUE;
}

BOOL UnloadDeviceDriverAndRemoveService(const TCHAR * Name)
{
	SC_HANDLE	schSCManager;

	schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

	if(!schSCManager) return FALSE;

	if(StopDriver(schSCManager, Name) == FALSE)
		return FALSE;

	if(RemoveDriver(schSCManager, Name) == FALSE)
		return FALSE;
	 
	CloseServiceHandle(schSCManager);

	return TRUE;
}

BOOL RemoveService(const TCHAR * Name)
{
	SC_HANDLE	schSCManager;

	schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

	if(!schSCManager) return FALSE;

	if(RemoveDriver(schSCManager, Name) == FALSE)
		return FALSE;
	 
	CloseServiceHandle(schSCManager);

	return TRUE;
}

BOOL LoadDeviceDriver(const TCHAR * Name, const TCHAR * Path, 
					  HANDLE * lphDevice, PDWORD Error)
{
	SC_HANDLE	schSCManager;
	BOOL		okay;

	schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

	RemoveDriver(schSCManager, Name);
	RemoveService(Name);

	InstallDriver(schSCManager, Name, Path);

	StartDriver(schSCManager, Name);

	okay = OpenDevice(Name, lphDevice);
	*Error = GetLastError();
 	CloseServiceHandle(schSCManager);

	return okay;
}

