본문 바로가기
Programming/System Programming

[WIN32/C] Driver Loader

by Winduck 2017. 3. 27.
반응형

최근 드라이버 로드기가 필요해서 간단한 코드로 구현하였다. 최종목표는 서비스컨트롤프로그램이기 때문에 이후에 코딩을 차근차근 코드를 수정할 예정이다.


※Driver Loader Code

 

#include<stdio.h>
#include<stdlib.h>
#include<tchar.h>
#include<string.h>
#include<Windows.h>
#include<locale.h>

#define STR_LEN 256
#define TOKEN_NUM 10
bool Control_Service();
bool Open_Service(TCHAR syspath);
bool Load_Driver(TCHAR *sysname, TCHAR *syspath);
bool Stop_Driver(TCHAR *sysname);
TCHAR *StrLower(TCHAR *pStr);

int _tmain(int argc, TCHAR *argv[])
{
 //한국어 입력가능
 _tsetlocale(LC_ALL,_T("Korean"));
 bool isExit = false;
 while (1)
 {
  isExit = Control_Service();
  if (isExit == 0)
  {
   _fputts(_T("프로그램을 종료합니다. \n"),stdout);
   break;
  }
 }
 return 0;
}

bool Control_Service()
{
 TCHAR seps[] = _T(" ");
 TCHAR cmdString[STR_LEN] = { _T(""), };
 TCHAR cmd_list[TOKEN_NUM][STR_LEN];
 int tokenNum = 0;
 bool bResult = FALSE;
 TCHAR *token = NULL;
 _fputts(_T("명령어 : [cmd] [servicename] [driverfilepath] \n"), stdout);
 _getts_s(cmdString);
 token = _tcstok(cmdString, seps);

 while (token != NULL)
 {
  if (tokenNum == 0)
  {
   StrLower(token);
  }
  _tcscpy(cmd_list[tokenNum++], token);
  token = _tcstok(NULL, seps);
 }

 if (!_tcscmp(cmd_list[0], _T("load")) && tokenNum == 3)
 {
  bResult = Load_Driver(cmd_list[1], cmd_list[2]);
 }

 else if (!_tcscmp(cmd_list[0], _T("stop")) && tokenNum == 2)
 {
  bResult = Stop_Driver(cmd_list[1]);
 }
 else
 {
  _fputts(_T("명령어를 다시 입력하세요.  \n"), stdout);
  bResult = TRUE;
 }
 return bResult;
}

bool Load_Driver(TCHAR *sysname,TCHAR *syspath)
{
 SC_HANDLE sh = NULL;
 SC_HANDLE lh = NULL;
 
 sh= OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

 if (sh == NULL)
 {
  _tprintf(_T("OpenSCManager fail : %d\n"), GetLastError());
  return false;
 }

 lh = CreateService(sh,
  sysname,
  sysname,
  SERVICE_ALL_ACCESS,
  SERVICE_KERNEL_DRIVER,
  SERVICE_DEMAND_START,
  SERVICE_ERROR_NORMAL,
  syspath,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL);

 if (lh == NULL)
 {
  _tprintf(_T("CreateService fail : %d\n"), GetLastError());
  CloseHandle(lh);
  return false;
 }

 if (!StartService(lh, 0, NULL))
 {
  _tprintf(_T("StartService fail : %d\n"), GetLastError());
  CloseHandle(lh);
  CloseHandle(sh);
  return false;
 }

 _fputts(_T("Load Success!!! \n"), stdout);
 
 CloseHandle(lh);
 CloseHandle(sh);
 return true;
}

TCHAR *StrLower(TCHAR *pStr)
{
 TCHAR *ret = pStr;
 while (*pStr)
 {
  if (*pStr)
  {
   *pStr = _totlower(*pStr);
   pStr++;
  }
 }
 return ret;
}
bool Stop_Driver(TCHAR *sysname)
{
 SC_HANDLE sh = NULL;
 SC_HANDLE lh = NULL;
 bool bResult = false;
 SERVICE_STATUS status;


 sh = OpenSCManager(NULL, NULL, GENERIC_READ);
 if (sh == NULL)
 {
  _tprintf(_T("OpenSCManager fail : %d\n"), GetLastError());
  return false;
 }

 lh = OpenService(sh, sysname, SERVICE_STOP | SERVICE_QUERY_STATUS);
 if (lh == NULL)
 {
  _tprintf(_T("OpenSCManager fail : %d\n"), GetLastError());
  CloseHandle(sh);
  return false;
 }

 if (!ControlService(lh, SERVICE_CONTROL_STOP, &status))
 {
  _tprintf(_T("ControlService fail : %d\n"), GetLastError());
  CloseHandle(sh);
  CloseHandle(lh);
  return false;
 }
 
 if(!QueryServiceStatus(lh, &status))
 {
  _tprintf(_T("QueryServiceStatus fail : %d\n"), GetLastError());
  CloseHandle(sh);
  CloseHandle(lh);
  return false;
 }
 while(status.dwCurrentState != SERVICE_STOPPED)
 {
  QueryServiceStatus(lh,&status);
  Sleep(2000);
 }
 _fputts(_T("Service Stop!!!  \n"), stdout);
 CloseHandle(sh);
 CloseHandle(lh);
 return true;
}




※실행결과




※공부

1.Visual Stdio 2015부터 _getts함수가  _getts_s함수로 대체됨

2.CreateService

 SC_HANDLE WINAPI CreateService(
  _In_      SC_HANDLE hSCManager, //서비스 Manager 핸들
  _In_      LPCTSTR   lpServiceName, //서비스이름
  _In_opt_  LPCTSTR   lpDisplayName, //표시되는 서비스 이름
  _In_      DWORD     dwDesiredAccess, //서비스 접근권한
  _In_      DWORD     dwServiceType, //서비스타입
  _In_      DWORD     dwStartType, //서비스시작을 위한 옵션
  _In_      DWORD     dwErrorControl,
  _In_opt_  LPCTSTR   lpBinaryPathName,
  _In_opt_  LPCTSTR   lpLoadOrderGroup,
  _Out_opt_ LPDWORD   lpdwTagId,
  _In_opt_  LPCTSTR   lpDependencies,
  _In_opt_  LPCTSTR   lpServiceStartName,
  _In_opt_  LPCTSTR   lpPassword
);



반응형

댓글