TDriver.cpp
上传用户:wlquartz
上传日期:2022-03-04
资源大小:89k
文件大小:14k
开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "TDriver.h"
  3. //Constructor. Inicializacion de variables.
  4. TDriver::TDriver(void)
  5. {
  6. driverHandle = NULL;
  7.    
  8. removable = TRUE;
  9. driverName = NULL;
  10. driverPath = NULL;
  11. driverDosName = NULL;
  12. initialized = FALSE;
  13. loaded = FALSE;
  14. started = FALSE;
  15. }
  16. //Destructor. Libera recursos.
  17. TDriver::~TDriver(void)
  18. {
  19. if(driverHandle != NULL)
  20. {
  21. CloseHandle(driverHandle); 
  22. driverHandle = NULL; 
  23. }
  24.    
  25.     UnloadDriver();
  26. }
  27. //Si removable = TRUE, no se descarga el driver en la "destruccion" del objeto
  28. void TDriver::SetRemovable(BOOL value)
  29. {
  30. removable = value;
  31. }
  32. // Esta inicializado el driver?
  33. BOOL TDriver::IsInitialized(void)
  34. {
  35. return initialized;
  36. }
  37. // Esta cargado el driver?
  38. BOOL TDriver::IsLoaded(void)
  39. {
  40. return loaded;
  41. }
  42. // Esta en estado Start el driver?
  43. BOOL TDriver::IsStarted(void)
  44. {
  45. return started;
  46. }
  47. // Inicia las variables del driver
  48. DWORD TDriver::InitDriver(LPCTSTR path)
  49. {
  50. // Si ya esta cargado primero lo descargo
  51. if(initialized)
  52. {
  53. if(UnloadDriver() != DRV_SUCCESS)
  54. return DRV_ERROR_ALREADY_INITIALIZED;
  55. }
  56. //  Reservo memoria para almacenar el path del driver
  57. driverPath = (LPTSTR)malloc(strlen(path) + 1);
  58. if(driverPath == NULL)
  59. return DRV_ERROR_MEMORY;
  60. strcpy(driverPath, path);
  61. // Voy a extraer el nombre del driver
  62. //Primero busco el caracter ''
  63. LPTSTR sPos1 = strrchr(driverPath, (int)'\');
  64. // Si no existe, me loco al principio
  65. if (sPos1 == NULL)
  66. sPos1 = driverPath;
  67. // Ahora busco la extension .sys
  68. LPTSTR sPos2 = strrchr(sPos1, (int)'.');
  69. // Si no tiene extension .sys salgo sin hacer nada mas
  70. if (sPos2 == NULL || sPos1 > sPos2)
  71. {
  72. free(driverPath);
  73. driverPath = NULL;
  74. return DRV_ERROR_INVALID_PATH_OR_FILE;
  75. }
  76. // Me quedo con el nombre del driver
  77. driverName = (LPTSTR) malloc (sPos2 - sPos1);
  78. if(driverName == NULL)
  79. {
  80. free(driverPath);
  81. driverPath = NULL;
  82. return DRV_ERROR_MEMORY;
  83. }
  84. // Copio los caracteres
  85. memcpy(driverName, sPos1 + 1, sPos2 - sPos1 - 1);
  86. driverName[sPos2 - sPos1 - 1] = 0;
  87. //driverDosName = \.driverName 
  88. driverDosName = (LPTSTR) malloc (strlen(driverName) + 5);
  89. if(driverDosName == NULL)
  90. {
  91. free(driverPath);
  92. driverPath = NULL;
  93. free(driverName);
  94. driverName = NULL;
  95. return DRV_ERROR_MEMORY;
  96. }
  97. sprintf(driverDosName, "\\.\%s", driverName);
  98. initialized = TRUE;
  99. return DRV_SUCCESS;
  100. }
  101. // Inicia las variables del driver
  102. DWORD TDriver::InitDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName)
  103. {
  104. // Si ya esta cargado primero lo descargo
  105. if(initialized)
  106. {
  107. if(UnloadDriver() != DRV_SUCCESS)
  108. return DRV_ERROR_ALREADY_INITIALIZED;
  109. }
  110. LPTSTR dirBuffer;
  111. // Compruebo si el usuario introdujo un path
  112. if (path != NULL) 
  113. {
  114. // Lo copio en un buffer auxiliar para su posterior procesamiento
  115. DWORD len = (DWORD)(strlen(name) + strlen(path) + 1);
  116. dirBuffer = (LPTSTR) malloc (len);
  117. if(dirBuffer == NULL)
  118. return DRV_ERROR_MEMORY;
  119. strcpy(dirBuffer, path);
  120. }
  121. else 
  122. {
  123. // Si no tenemos path, supongo el directorio actual
  124. LPTSTR pathBuffer;
  125.         DWORD len = GetCurrentDirectory(0, NULL);
  126.       
  127. pathBuffer = (LPTSTR) malloc (len);
  128. if(pathBuffer == NULL)
  129. return DRV_ERROR_MEMORY;
  130.         
  131.         if (GetCurrentDirectory(len, pathBuffer) != 0) 
  132. {
  133. len = (DWORD)(strlen(pathBuffer) + strlen(name) + 6);
  134. dirBuffer = (LPTSTR) malloc (len);
  135. if(dirBuffer == NULL)
  136. {
  137. free(pathBuffer);
  138. return DRV_ERROR_MEMORY;
  139. }
  140. // Path = directoriodriverName.sys
  141. sprintf(dirBuffer, "%s\%s.sys", pathBuffer, name);
  142. // Compruebo si existe el fichero en cuestion
  143. if(GetFileAttributes(dirBuffer) == 0xFFFFFFFF)
  144. {
  145. free(pathBuffer);
  146. free(dirBuffer);
  147. // Si no existe, busco en system32Drivers
  148. LPCTSTR sysDriver = "\system32\Drivers\";
  149. LPTSTR sysPath;
  150.          
  151. DWORD len = GetWindowsDirectory(NULL, 0);
  152.       sysPath = (LPTSTR) malloc (len + strlen(sysDriver));
  153. if(sysPath == NULL)
  154. return DRV_ERROR_MEMORY;
  155. if (GetWindowsDirectory(sysPath, len) == 0) 
  156. {
  157. free(sysPath);
  158. return DRV_ERROR_UNKNOWN;
  159. }
  160. // Completo el path y compruebo si existe el fichero de nuevo
  161. strcat(sysPath, sysDriver);
  162. len = (DWORD)(strlen(sysPath) + strlen(name) + 5);
  163. dirBuffer = (LPTSTR) malloc (len);
  164. if(dirBuffer == NULL)
  165. return DRV_ERROR_MEMORY;
  166. sprintf(dirBuffer, "%s%s.sys", sysPath, name);
  167. free(sysPath);
  168. // Si el fichero no existe, salgo
  169. if(GetFileAttributes(dirBuffer) == 0xFFFFFFFF)
  170. {
  171. free(dirBuffer);
  172. return DRV_ERROR_INVALID_PATH_OR_FILE;
  173. }
  174. }
  175. free(pathBuffer);
  176.         }
  177. else
  178. {
  179. free(pathBuffer);
  180. return DRV_ERROR_UNKNOWN;
  181. }
  182. }
  183. // Escribo las variables del driver
  184. driverPath = dirBuffer;
  185. driverName = (LPTSTR)malloc(strlen(name) + 1);
  186. if(driverName == NULL)
  187. {
  188. free(driverPath);
  189. driverPath = NULL;
  190. return DRV_ERROR_MEMORY;
  191. }
  192. strcpy(driverName, name);
  193. LPCTSTR auxBuffer;
  194. if(dosName != NULL)
  195.         auxBuffer = dosName;
  196. else
  197. auxBuffer = name;
  198. //dosName=\.driverName
  199. if(auxBuffer[0] != '\' && auxBuffer[1] != '\')
  200. {
  201. driverDosName = (LPTSTR) malloc (strlen(auxBuffer) + 5);
  202. if(driverDosName == NULL)
  203. {
  204. free(driverPath);
  205. driverPath = NULL;
  206. free(driverName);
  207. driverName = NULL;
  208. return DRV_ERROR_MEMORY;
  209. }
  210. sprintf(driverDosName, "\\.\%s", auxBuffer);
  211. }
  212. else
  213. {
  214. driverDosName = (LPTSTR) malloc (strlen(auxBuffer));
  215. if(driverDosName == NULL)
  216. {
  217. free(driverPath);
  218. driverPath = NULL;
  219. free(driverName);
  220. driverName = NULL;
  221. return DRV_ERROR_MEMORY;
  222. }
  223. strcpy(driverDosName, auxBuffer);
  224. }
  225. // Pongo el estado en inicializado
  226. initialized = TRUE;
  227. return DRV_SUCCESS;
  228. }
  229. // Funcion para cargar el driver.
  230. DWORD TDriver::LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, BOOL start)
  231. {
  232. // Primero es necesario inicializarlo
  233. DWORD retCode = InitDriver(name, path, dosName);
  234. // Despues lo cargo
  235. if(retCode == DRV_SUCCESS)
  236. retCode = LoadDriver(start);
  237. return retCode;
  238. }
  239. // Funcion para cargar el driver
  240. DWORD TDriver::LoadDriver(LPCTSTR path, BOOL start)
  241. {
  242. // Primero lo inicializo
  243. DWORD retCode = InitDriver(path);
  244. // Despues lo cargo
  245. if(retCode == DRV_SUCCESS)
  246. retCode = LoadDriver(start);
  247. return retCode;
  248. }
  249. // Funcion para cargar el driver
  250. DWORD TDriver::LoadDriver(BOOL start)
  251. {
  252. // Si ya esta cargado no hago nada
  253. if(loaded)
  254. return DRV_SUCCESS;
  255. if(!initialized)
  256. return DRV_ERROR_NO_INITIALIZED;
  257. // Abro el Service Manager para crear el nuevo driver
  258. SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  259. DWORD retCode = DRV_SUCCESS;
  260. if (SCManager == NULL) 
  261. return DRV_ERROR_SCM;
  262.     
  263.     // Creo el driver ("Servicio")
  264.     SC_HANDLE  SCService = CreateService(SCManager,   // SCManager database
  265.      driverName,            // nombre del servicio
  266.       driverName,            // nombre a mostrar
  267.  SERVICE_ALL_ACCESS,    // acceso total
  268.  SERVICE_KERNEL_DRIVER, // driver del kernel
  269.  SERVICE_DEMAND_START,  // comienzo bajo demanda
  270.  SERVICE_ERROR_NORMAL,  // control de errores normal
  271.  driverPath,           // path del driver
  272.  NULL,                  // no pertenece a un grupo
  273.  NULL,                  // sin tag
  274.  NULL,                  // sin dependencias
  275.  NULL,                  // cuenta local del sistema
  276.  NULL                   // sin password
  277.  );
  278.     
  279. // Si no puedo crearlo, miro si es porque ya fue cargado por otro proceso.
  280. if (SCService == NULL) 
  281. {
  282. SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
  283. if (SCService == NULL) 
  284. retCode = DRV_ERROR_SERVICE;
  285. }
  286.     CloseServiceHandle(SCService);
  287. SCService=NULL;
  288. CloseServiceHandle(SCManager);
  289. SCManager = NULL;
  290. // Si todo fue bien, actualizo el estado e inicio si fuera necesario.
  291. if(retCode == DRV_SUCCESS)
  292. {
  293. loaded = TRUE;
  294. if(start)
  295. retCode = StartDriver();
  296. }
  297. return retCode;
  298. }
  299. // Funcion para descargar el driver.
  300. DWORD TDriver::UnloadDriver(BOOL forceClearData)
  301. {
  302. DWORD retCode = DRV_SUCCESS;
  303. // Si esta en estado started, primero lo paro
  304. if (started)
  305. {
  306. if ((retCode = StopDriver()) == DRV_SUCCESS) 
  307. {
  308. // Solo lo extraigo del service manager si es removable
  309. if(removable)
  310. {
  311. // Abro el servicio y elimino el driver
  312. SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  313. if (SCManager == NULL) 
  314. return DRV_ERROR_SCM;
  315. SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
  316. if (SCService != NULL)
  317. {
  318. if(!DeleteService(SCService))
  319. retCode = DRV_ERROR_REMOVING;
  320. else
  321. retCode = DRV_SUCCESS;
  322. }
  323. else
  324. retCode = DRV_ERROR_SERVICE;
  325. CloseServiceHandle(SCService);
  326. SCService = NULL;
  327. CloseServiceHandle(SCManager);
  328. SCManager = NULL;
  329. // Si todo fue bien, actualizo el estado
  330. if(retCode == DRV_SUCCESS)
  331. loaded = FALSE;
  332. }
  333. }
  334. }
  335. // Si el driver esta inicializado...
  336. if(initialized) 
  337. {
  338. // Si hubo algun problema pero esta a TRUE forceClear borro las variables de igual forma
  339. if(retCode != DRV_SUCCESS && forceClearData == FALSE)
  340. return retCode;
  341. // Actualizo el estado
  342. initialized = FALSE;
  343. // Libero memoria
  344. if(driverPath != NULL)
  345. {
  346. free(driverPath);
  347. driverPath = NULL;
  348. }
  349. if(driverDosName != NULL)
  350. {
  351. free(driverDosName);
  352. driverDosName = NULL;
  353. }
  354. if(driverName != NULL)
  355. {
  356. free(driverName);
  357. driverName = NULL;
  358. }
  359. }
  360. return retCode;
  361. }
  362. // Funcion para poner en Start al driver
  363. DWORD TDriver::StartDriver(void)
  364. {
  365. // Si ya esta comenzado, no hago nada
  366. if(started)
  367. return DRV_SUCCESS;
  368. // Abro el servicio y lo pongo en estado Start
  369. SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  370. DWORD retCode;
  371. if (SCManager == NULL) 
  372. return DRV_ERROR_SCM;
  373.     SC_HANDLE SCService = OpenService(SCManager,
  374.                               driverName,
  375.                       SERVICE_ALL_ACCESS);
  376.     
  377. if (SCService == NULL) 
  378.         return DRV_ERROR_SERVICE;
  379.     
  380.     if (!StartService( SCService, 0, NULL)) 
  381. {
  382. // Si el driver fue puesto en Start antes de mi, no lo elimino al destruir el objeto
  383. // debido a que fue creado por otro aplicacion que posiblemente lo este usando
  384.         if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) 
  385. {
  386. removable = FALSE;
  387. retCode = DRV_SUCCESS;
  388. }
  389. else
  390. retCode = DRV_ERROR_STARTING;
  391.     }
  392. else
  393. retCode = DRV_SUCCESS;
  394.   
  395.     CloseServiceHandle(SCService);
  396. SCService = NULL;
  397. CloseServiceHandle(SCManager);
  398. SCManager = NULL;
  399. // Actualizo el estado y abro el dispositivo para comunicacion Usuario -> Driver
  400. if(retCode == DRV_SUCCESS)
  401. {
  402. started = TRUE;
  403. retCode = OpenDevice();
  404. }
  405.     return retCode;
  406. }
  407. // Funcion para parar el driver
  408. DWORD TDriver::StopDriver(void)
  409. {
  410. // Si ya esta parado, no tengo que hacer nada
  411. if(!started)
  412. return DRV_SUCCESS;
  413. // Cambio el estado del proceso
  414. SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  415. DWORD retCode;
  416. if (SCManager == NULL) 
  417. return DRV_ERROR_SCM;
  418.    
  419.     SERVICE_STATUS  status;
  420.     SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
  421.     
  422. if (SCService != NULL)
  423. {
  424. // Cierro tambien el handle al driver abierto en funcion start
  425. CloseHandle(driverHandle); 
  426. driverHandle = NULL; 
  427. if(!ControlService(SCService, SERVICE_CONTROL_STOP, &status))
  428. retCode = DRV_ERROR_STOPPING;
  429. else
  430. retCode = DRV_SUCCESS;
  431. }
  432. else
  433. retCode = DRV_ERROR_SERVICE;
  434.     CloseServiceHandle(SCService);
  435. SCService = NULL;
  436. CloseServiceHandle(SCManager);
  437. SCManager = NULL;
  438. // Actualizo el estado
  439. if(retCode == DRV_SUCCESS)
  440. started = FALSE;
  441.     return retCode;
  442. }
  443. // Funcion para abrir el dispositivo
  444. DWORD TDriver::OpenDevice(void)
  445. {
  446. // Si ya tengo un handle al driver, primero lo cierro
  447. if (driverHandle != NULL) 
  448. CloseHandle(driverHandle);
  449.     driverHandle = CreateFile(driverDosName,
  450.   GENERIC_READ | GENERIC_WRITE,
  451.   0,
  452.                               NULL,
  453.                               OPEN_EXISTING,
  454.                               FILE_ATTRIBUTE_NORMAL,
  455.                               NULL);
  456.     if(driverHandle == INVALID_HANDLE_VALUE)
  457. return DRV_ERROR_INVALID_HANDLE;
  458. return DRV_SUCCESS;
  459. }
  460. // Devuelve un handle al driver
  461. HANDLE TDriver::GetDriverHandle(void)
  462. {
  463. return driverHandle;
  464. }
  465. // Funcion para enviar datos al driver
  466. DWORD TDriver::WriteIo(DWORD code, PVOID buffer, DWORD count)
  467. {
  468. if(driverHandle == NULL)
  469. return DRV_ERROR_INVALID_HANDLE;
  470. DWORD bytesReturned;
  471. BOOL returnCode = DeviceIoControl(driverHandle,
  472.       code,
  473.       buffer,
  474.       count,
  475.       NULL,
  476.       0,
  477.       &bytesReturned,
  478.       NULL);
  479. if(!returnCode)
  480. return DRV_ERROR_IO;
  481. return DRV_SUCCESS;
  482. }
  483. // Funcion para leer datos del driver
  484. DWORD TDriver::ReadIo(DWORD code, PVOID buffer, DWORD count)
  485. {
  486. if(driverHandle == NULL)
  487. return DRV_ERROR_INVALID_HANDLE;
  488. DWORD bytesReturned;
  489. BOOL retCode = DeviceIoControl(driverHandle,
  490.    code,
  491.    NULL,
  492.    0,
  493.    buffer,
  494.    count,
  495.    &bytesReturned,
  496.    NULL);
  497. if(!retCode)
  498. return DRV_ERROR_IO;
  499. return bytesReturned;
  500. }
  501. // Funcion para realizar operacion de E/S con el driver (leer y/o escribir)
  502. DWORD TDriver::RawIo(DWORD code, PVOID inBuffer, DWORD inCount, PVOID outBuffer, DWORD outCount)
  503. {
  504. if(driverHandle == NULL)
  505. return DRV_ERROR_INVALID_HANDLE;
  506. DWORD bytesReturned;
  507. BOOL retCode = DeviceIoControl(driverHandle,
  508.    code,
  509.    inBuffer,
  510.    inCount,
  511.    outBuffer,
  512.    outCount,
  513.    &bytesReturned,
  514.    NULL);
  515. if(!retCode)
  516. return DRV_ERROR_IO;
  517. return bytesReturned;
  518. }