• XSS.stack #1 – первый литературный журнал от юзеров форума

Программирование аппаратных средств

Namelles One

(L2) cache
Пользователь
Регистрация
24.02.2006
Сообщения
440
Реакции
6
Как вам всем известно - в Винде ХР нельзя напрямую работать с портами переферии работать, поэтому функции _outp и _inp из стандартного conio.h - курят в сторонке ибо выскакивает исключение..

К книге Всеволода Несвижского на эту тему прилагается 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" );
в реализации функции..

Мб из-за этого не пашет, а мб из-за чего-то другого...
Реально ли эту гадость заставить работать или что вообще надо сделать, чтобы заработала данная тема работы с устройствами?
 
Смотря с чем тебе надо работать. Можно и CreateFile/WriteFile/ReadFile обойтись.
 
Короче, х знает, почему не работает авторский текст, зато та либа, о которой сказал Грейт - работает первостатейно...

Всем спасибо, все свободны... :)
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх