// SetHC25Status.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "driver_installation.h"

#ifdef	_MFC_VER
#include "DK02Control_MFC.h"
#include "DK02ControlDlg.h"
#endif

HANDLE	hDriver = INVALID_HANDLE_VALUE;
char	szMxDriverPath[MAX_PATH];
bool	IsNT;
bool	IsDriverInitialized =false;

BOOL _stdcall stop_driver()
{
  SC_HANDLE hSCManager;
  SC_HANDLE hService;
  SERVICE_STATUS ServiceStatus;
  BOOL bResult;

  hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

  if (hSCManager)
  {
	  hService = OpenService(hSCManager, DRIVER_SERVICE_NAME, SERVICE_ALL_ACCESS);

	  CloseServiceHandle(hSCManager);
	
	  if (hService)
	  {
		  bResult = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);

		  CloseServiceHandle(hService);
	  }
	  else{
		return false;
	  }
  }
  else{
    return false;
  }

  return bResult;
}

BOOL _stdcall remove_driver()
{
  SC_HANDLE hSCManager;
  SC_HANDLE hService;
  BOOL		bResult;

  /*stop the driver before we remove it*/
  stop_driver();

  hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

  if (hSCManager)
  {
    hService = OpenService(hSCManager, "mxgpio", SERVICE_ALL_ACCESS);

    CloseServiceHandle(hSCManager);

    if (hService)
    {
      bResult = DeleteService(hService);
      
      CloseServiceHandle(hService);
    }
	else{
      return false;
	}
  }
  else{
    return false;
  }

  return bResult;
}


bool _stdcall install_driver(char* DriverPath, bool IsDemandLoaded)
{
  SC_HANDLE hSCManager;
  SC_HANDLE hService;

  // Remove any previous instance of the driver

  remove_driver();

  hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

  if (hSCManager)
  {
    /* Install the driver*/
    hService = CreateService(hSCManager,
                             "mxgpio",
                             "mxgpio",
                             SERVICE_ALL_ACCESS,
                             SERVICE_KERNEL_DRIVER,
                             (IsDemandLoaded == true) ? SERVICE_DEMAND_START : SERVICE_SYSTEM_START,
                             SERVICE_ERROR_NORMAL,
							 "C:\\temp\\EPM-DK02.sys",
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL);

    CloseServiceHandle(hSCManager);
	
	if (hService == NULL){
		 MessageBox(NULL,"hService == NULL","Error",MB_OK);
		return false;
	}
  }
  else{
    return false;
	 MessageBox(NULL,"hSCManager fail","Error",MB_OK);
  }

  CloseServiceHandle(hService);
  
  return true;
}


bool start_driver()
{

	SC_HANDLE	hSCManager;
	SC_HANDLE	hService;
	bool		bResult;

	hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

	if (hSCManager)
	{
		hService = OpenService(hSCManager, "mxgpio", SERVICE_ALL_ACCESS);

		CloseServiceHandle(hSCManager);

		if (hService)
		{
			bResult = StartService(hService, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING;

			CloseServiceHandle(hService);
		}
		else{
			MessageBox(NULL,"start_driver : !hService ","Error",MB_OK);
			return false;
		}
	 }
	else{
		MessageBox(NULL,"start_driver : !hSCManager","Error",MB_OK);
		return false;
	}

	return bResult;
}

bool check_os_version()
{
	OSVERSIONINFO OSVersionInfo;

	OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

	GetVersionEx(&OSVersionInfo);

	return OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}

bool get_driver_path()
{
	PSTR pszSlash;

	if (!GetModuleFileName(GetModuleHandle(NULL), szMxDriverPath, sizeof(szMxDriverPath))){
		return false;
	}

	pszSlash = strrchr(szMxDriverPath, '\\');

	if (pszSlash){
		pszSlash[1] = 0;
	}
	else{
		return false;
	}

	strcat_s(szMxDriverPath,MAX_PATH,"EPM-DK02.sys");

	return true;
}


bool  driver_open()
{
	bool bResult;

	IsNT = check_os_version();

	if (IsNT)
	{

		hDriver = CreateFile("\\\\.\\mxgpio",
						 GENERIC_READ | GENERIC_WRITE,
						 0,
						 NULL,
						 OPEN_EXISTING,
						 FILE_ATTRIBUTE_NORMAL,
						 NULL);

		/* If the driver is not running, install it*/
		if (hDriver == INVALID_HANDLE_VALUE)
		{
			get_driver_path();

			bResult = install_driver("C:\\temp\\EPM-DK02.sys", true);

			if (!bResult){
				 MessageBox(NULL,"install_driver fail","Error",MB_OK);
				return false;
			}

			bResult = start_driver();

			if (!bResult){
				 MessageBox(NULL,"start_driver fail","Error",MB_OK);
				return false;
			}

			hDriver = CreateFile("\\\\.\\mxgpio",
								   GENERIC_READ | GENERIC_WRITE,
								   0,
								   NULL,
								   OPEN_EXISTING,
								   FILE_ATTRIBUTE_NORMAL,
								   NULL);

			if (hDriver == INVALID_HANDLE_VALUE){
				 MessageBox(NULL,"INVALID_HANDLE_VALUE","Error",MB_OK);
				return false;
			}
		}
	  }
	  else{
		  printf("Not NT system\r\n");
		  MessageBox(NULL,"Not NT system","Error",MB_OK);
		  return false;
	  }

	  IsDriverInitialized = true;

	return true;
}

void  driver_close()
{
  if (IsNT)
  {
    if (hDriver != INVALID_HANDLE_VALUE)
    {

		CloseHandle(hDriver);
    }

    remove_driver();
  }
  else{
    CloseHandle(hDriver);
  }

	IsDriverInitialized = false;
}
