Как вам всем известно - в Винде ХР нельзя напрямую работать с портами переферии работать, поэтому функции _outp и _inp из стандартного conio.h - курят в сторонке ибо выскакивает исключение..
К книге Всеволода Несвижского на эту тему прилагается 3 любопытнейших файлика - драйверок виртуального устройства и два листинга, которые описывают функции не выдащие ошибок..
Но почему-то они нифига не пашут..
Приведу листинги файлов на С.
и
В частности - мне непонятно место
в реализации функции..
Мб из-за этого не пашет, а мб из-за чего-то другого...
Реально ли эту гадость заставить работать или что вообще надо сделать, чтобы заработала данная тема работы с устройствами?
К книге Всеволода Несвижского на эту тему прилагается 3 любопытнейших файлика - драйверок виртуального устройства и два листинга, которые описывают функции не выдащие ошибок..
Но почему-то они нифига не пашут..
Приведу листинги файлов на С.
Код:
// реализация класса СIO32NT
#include "stdafx.h"
#include "IO32NT.h"
#include <conio.h>
#include <Winsvc.h>
// конструктор
CIO32NT :: CIO32NT ( )
{
hSYS = NULL;
}
// деструктор
CIO32NT :: ~CIO32NT ( )
{
DWORD dwReturn;
if ( hSYS != INVALID_HANDLE_VALUE )
{
// блокируем драйвер
DeviceIoControl ( hSYS, IOCTL_WINIO_DISABLEDIRECTIO, NULL,
0, NULL, 0, &dwReturn, NULL );
CloseHandle ( hSYS ); // закрываем драйвер
}
// освобождаем системные ресурсы
_freeService ( );
hSYS = NULL;
}
// функции
bool CIO32NT :: InitPort ( )
{
bool bResult;
PSTR pszTemp;
char szExe[MAX_PATH];
DWORD dwRet;
// открываем драйвер
hSYS = CreateFile ( "\\\\.\\IOtrserv", GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
// если не удалось, инициализируем службу сервисов
if ( hSYS == INVALID_HANDLE_VALUE )
{
// получаем имя программы
if ( !GetModuleFileName ( GetModuleHandle ( NULL ), szExe,
sizeof ( szExe ) ) )
return false;
// ищем указатель на последнюю косую черту
pszTemp = strrchr ( szExe, '\\' );
// убираем имя программы
pszTemp[1] = 0;
// а вместо него добавляем имя драйвера
strcat ( szExe, "IOtrserv.sys" );
// загружаем сервис
bResult = _loadService ( szExe );
// если ошибка, выходим из функции
if ( !bResult ) return false;
// запускаем наш сервис
bResult = _goService ( );
// если ошибка, выходим из функции
if ( !bResult ) return false;
// открываем драйвер
hSYS = CreateFile ( "\\\\.\\IOtrserv", GENERIC_READ |
GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
// если не удалось, выходим из функции
if ( hSYS == INVALID_HANDLE_VALUE ) return false;
}
if ( !DeviceIoControl ( hSYS, IOCTL_WINIO_ENABLEDIRECTIO, NULL,
0, NULL, 0, &dwRet, NULL ) )
return false; // драйвер недоступен
return true;
}
bool CIO32NT :: _loadService ( PSTR pszDriver )
{
SC_HANDLE hSrv;
SC_HANDLE hMan;
// на всякий случай выгружаем открытый сервис
_freeService ( );
// открываем менеджер сервисов
hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
// создаем объект сервиса из нашего драйвера
if ( hMan )
{
hSrv = CreateService ( hMan, "IOtrserv", "IOtrserv",
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL, pszDriver, NULL, NULL, NULL, NULL, NULL );
// освобождаем менеджер объектов
CloseServiceHandle ( hMan );
if ( hSrv == NULL ) return false;
}
else
return false;
CloseServiceHandle ( hMan );
return true;
}
bool CIO32NT :: _goService (
{
bool bRes;
SC_HANDLE hSrv;
SC_HANDLE hMan;
// открываем менеджер сервисов
hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if ( hMan )
{
// открываем сервис
hSrv = OpenService ( hMan, "IOtrserv", SERVICE_ALL_ACCESS );
// закрываем менеджер сервисов
CloseServiceHandle ( hMan );
if ( hSrv )
{
// запускаем сервис
bRes = StartService ( hSrv, 0, NULL );
// в случае ошибки закрываем дескриптор
if( !bRes )
CloseServiceHandle ( hSrv );
}
else
return false;
}
else
return false;
return bRes;
}
bool CIO32NT :: _stopService ( )
{
bool bRes;
SERVICE_STATUS srvStatus;
SC_HANDLE hMan;
SC_HANDLE hSrv;
// открываем менеджер сервисов
hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if ( hMan )
{
// открываем сервис
hSrv = OpenService ( hMan, "IOtrserv", SERVICE_ALL_ACCESS );
// закрываем менеджер сервисов
CloseServiceHandle ( hMan );
if ( hSrv )
{
// останавливаем сервис
bRes = ControlService ( hSrv, SERVICE_CONTROL_STOP, &srvStatus );
// закрываем сервис
CloseServiceHandle ( hSrv );
}
else
return false;
}
else
return false;
return bRes;
}
bool CIO32NT :: _freeService ( )
{
bool bRes;
SC_HANDLE hSrv;
SC_HANDLE hMan;
// останавливаем наш сервис
_stopService ( );
// открываем менеджер сервисов
hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if ( hMan )
{
// открываем сервис
hSrv = OpenService ( hMan, "IOtrserv", SERVICE_ALL_ACCESS );
// закрываем менеджер сервисов
CloseServiceHandle ( hMan );
if ( hSrv )
{
// удаляем наш сервис из системы и освобождаем ресурсы
bRes = DeleteService ( hSrv );
// закрываем дескриптор нашего сервиса
CloseServiceHandle ( hSrv );
}
else
return false;
}
else
return false;
return bRes;
}
// пишем функции ввода-вывода
void CIO32NT :: inPort ( WORD wPort, PDWORD pdwValue, BYTE bSize )
{
switch ( bSize )
{
case 1:
*pdwValue = _inp( wPort );
break;
case 2:
*pdwValue = _inpw ( wPort );
break;
case 4:
*pdwValue = _inpd ( wPort );
break;
}
}
void CIO32NT :: outPort ( WORD wPort, DWORD dwValue, BYTE bSize )
{
switch ( bSize )
{
case 1:
_outp ( wPort, ( BYTE ) dwValue );
break;
case 2:
_outpw ( wPort, ( WORD ) dwValue );
break;
case 4:
_outpd ( wPort, dwValue );
break;
}
}
и
Код:
// IO32NT.h: interface for the CIO32NT class.
#include <winioctl.h>
// определяем коды функций драйвера
#define FILE_DEVICE_WINIO 0x00008010
#define WINIO_IOCTL_INDEX 0x810
#define IOCTL_WINIO_ENABLEDIRECTIO CTL_CODE ( FILE_DEVICE_WINIO, \
WINIO_IOCTL_INDEX + 2, METHOD_BUFFERED, FILE_ANY_ACCESS )
#define IOCTL_WINIO_DISABLEDIRECTIO CTL_CODE ( FILE_DEVICE_WINIO, \
WINIO_IOCTL_INDEX + 3, METHOD_BUFFERED, FILE_ANY_ACCESS )
// объявляем класс
class CIO32NT
{
public:
CIO32NT ( );
~CIO32NT ( );
// общие функции
bool InitPort ( ); // инициализация драйвера
// функция для считывания значения из порта
void inPort ( WORD wPort, PDWORD pdwValue, BYTE bSize );
// функция для записи значения в порт
void outPort ( WORD wPort, DWORD dwValue, BYTE bSize );
private:
// закрытая часть класса
HANDLE hSYS; // дескриптор драйвера
// служебные функции
// загрузка сервиса
bool _loadService ( PSTR pszDriver );
bool _goService ( ); // запуск сервиса
bool _stopService ( ); // остановка сервиса
bool _freeService ( ); // закрытие сервиса
}; // окончание класса
В частности - мне непонятно место
Код:
// ищем указатель на последнюю косую черту
pszTemp = strrchr ( szExe, '\\' );
// убираем имя программы
pszTemp[1] = 0;
// а вместо него добавляем имя драйвера
strcat ( szExe, "IOtrserv.sys" );
Мб из-за этого не пашет, а мб из-за чего-то другого...
Реально ли эту гадость заставить работать или что вообще надо сделать, чтобы заработала данная тема работы с устройствами?