Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с LPT портом 
V
    Опции темы
Pakshin A. S.
  Дата 24.8.2006, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Есть внешнее устройство, подключаемое к порту LPT. У устройства есть два режима: включено и выключено. При положении включено к устройству подается напряжение 12V, а при режиме отключено к нему поступает 0V. 

Данное напряжение может дать именно LPT порт. Как реализуется поставленная задача?

P. S.
А к каким ножкам подключать минус и плюс устройства?

P. P. S.
Что-то поиск с первого раза не дал мне ответа конкретного на поставленный вопрос...  smile 
PM   Вверх
Pakshin A. S.
Дата 25.8.2006, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Вот тут с CreateFile выискал работу с COM портом. С LPT вроде работать также можно (логично).

Что мне писать нужно в этот файл, чтобы напряжение появилось на контактах Data?
PM   Вверх
Fedia
Дата 25.8.2006, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 8
Всего: 13



Напряжение на выходах Com\LPT вроде всегда подается с материнской платы, вне зависимости от того подключено к нему устройство или нет.
Цитата(Pakshin A. S. @  24.8.2006,  22:39 Найти цитируемый пост)
А к каким ножкам подключать минус и плюс устройства?

Попробуй посмотреть здесь


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 25.8.2006, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Цитата(Fedia @  25.8.2006,  01:59 Найти цитируемый пост)
Попробуй посмотреть 

Ага, спасибо! Понятно... smile


а про это что скажете?
Цитата(Pakshin A. S. @  25.8.2006,  01:26 Найти цитируемый пост)
Что мне писать нужно в этот файл, чтобы напряжение появилось на контактах Data? 


PM   Вверх
Fedia
Дата 25.8.2006, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 8
Всего: 13



Оказывается это уже обсуждалось ранее:
http://forum.vingrad.ru/index.php?showtopic=20791&hl=lpt


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 25.8.2006, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Цитата(Fedia @  25.8.2006,  02:17 Найти цитируемый пост)
Оказывается это уже обсуждалось ранее:

Я видел данную тему, но (!) ссылка на статью из FAQ не работает... 
PM   Вверх
Fedia
Дата 25.8.2006, 02:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 8
Всего: 13



Есть пример класса для работы с LPT портом, реализованный Snowy:
Код

unit lptport;
interface
uses Windows;
type
  TLptPort=class(TObject)
    protected
      h: THandle;
      b: ^char;
      public
      Port: byte;
      constructor Create;
      destructor Destroy; override;
      function  Connect: Boolean;
      procedure Disconnect;
      function  Connected: Boolean;
      procedure SendString(str:string);
      function  GetChar(var ch: char):boolean;
    published
  end;
implementation
constructor TLptPort.Create;
begin
  Port:=1; h:=0;
end;
destructor TLptPort.Destroy;
begin
  Disconnect;
  inherited Destroy;
end;
function TLptPort.Connected: Boolean;
begin
  Result:=h>0;
end;
procedure TLptPort.Disconnect;
begin
  if Connected then
    CloseHandle(h);
  h:=0;
end;
function TLptPort.Connect: Boolean;
var
  LptName: string;
begin
  Result:=Connected;
  if Connected then Exit;
  LptName:='LPT'+chr(48+Port);
  try
    h:=CreateFile(PChar(LptName),GENERIC_READ OR GENERIC_WRITE,0,nil,
                  OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  except 
    h:=0 
  end;
  if h=INVALID_HANDLE_VALUE then h:=0;
  Result:=Connected;
end;
procedure TLptPort.SendString(str:string);
var
  buf: PChar;
  btw,bwt : DWORD;
begin
  if not Connected then exit;
  btw:=Length(str); buf:=PChar(str);
  WriteFile(h, buf, btw, bwt,nil);
end;

function TLptPort.GetChar(var ch: char): boolean;
var
  r:  dword;
begin
  result:=false;
  if not Connected then exit;
  if ReadFile(h,ch,1,r,nil) then
    if r>0 then result:=true;
end;

end.

На сколько я понял, запись в порт реализуется так:
Код

var
  LptPort: TLptPort;
  s: string;
begin
  LptPort:=TLptPort.Create;
  if LptPort.Connect then
  begin
    s:=chr(213)+chr(11)+chr(54)+chr(18);
    LptPort.SendString(s);
  end;
end;

При этом первый и третий отправляемые байты определяют наличие питания на контактах 2..9 и 18..25. Если посылаем нули, то питания не будет, и наоборот.

Это сообщение отредактировал(а) Fedia - 25.8.2006, 02:22


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 25.8.2006, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Так и не ответили..  smile 

В качестве строки, помещаемой в "файл" (в порт в данном случае), мы берем:
00000000 - всё отключено
10000000 - первый контакт включен
01000000 - второй контакт включен
...
00000001 - последний контакт включен

Верно?
PM   Вверх
Fedia
Дата 25.8.2006, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 8
Всего: 13



Цитата(Pakshin A. S. @  25.8.2006,  09:05 Найти цитируемый пост)
00000000 - всё отключено
10000000 - первый контакт включен
01000000 - второй контакт включен
...
00000001 - последний контакт включен

Верно?

Ну логично. 1-н байт ~ 8 бит ~ 8 контактов. Это для меня (думаю что и для тебя) было само собой разумеющееся smile Т.е. что бы подключить все контакты с 2 по 9 в порт отправляем 
s:=chr(255)+chr(11)+chr(54)+chr(18).
А для подключения всех контактов с 18 по 25:
s:=chr(11)+chr(54)+chr(255)+chr(18).   Проверить не могу, нет под рукой LPT устройств. Работает?

Это сообщение отредактировал(а) Fedia - 25.8.2006, 13:06


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 25.8.2006, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Брр... Давно за компом не сидел..  smile 

Понятно что писать, если включать все контакты со 2-ого по 9-ый, но как включить отдельно второй, третий и так далее до девятого?
PM   Вверх
Albinos_x
Дата 25.8.2006, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Цитата(Pakshin A. S. @  25.8.2006,  14:48 Найти цитируемый пост)
Понятно что писать, если включать все контакты со 2-ого по 9-ый, но как включить отдельно второй, третий и так далее до девятого?


считываешь состояние порта, потом через xor , к примеру:
Код

   CRValue:=CRValue xor 04


потом записываешь опять в порт, получишь, что состояние бита инвертируется...

к примеру я использовал следующий код для опроса состояния входов порта:
Код

{----------------- Изменяем состояние линии Init ------------------}
   //CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG);
   CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG);
   CRValue:=CRValue xor 04;
   Lpt.WritePort(LPT2,LPT_CONTROL_REG,CRValue);
   // опрос                                       состояние  SelectIn одно
....
   {--------------- Изменяем состояние линии SelectIn ----------------}
   CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG);
   CRValue:=CRValue xor 08;
   Lpt.WritePort(LPT2,LPT_CONTROL_REG,CRValue);
   // опрос                                    меняем  SelectIn
...
   {----------------- Изменяем состояние линии Init ------------------}
   CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG);
   CRValue:=CRValue xor 04;
   Lpt.WritePort(LPT2,LPT_CONTROL_REG,CRValue);
   // опрос                                     состояние  SelectIn одно
...
   {--------------- Изменяем состояние линии SelectIn ----------------}
   CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG);
   CRValue:=CRValue xor 08;
   Lpt.WritePort(LPT2,LPT_CONTROL_REG,CRValue);
   // опрос                                      меняем  SelectIn
...



--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Fedia
Дата 25.8.2006, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 8
Всего: 13



Pakshin A. S., Изменять строку в зависимости от контактов, которые необходимо активировать можно так:
Код

type
  TArContact = array[1..8] of Boolean;

//формируем отправляемое значение
function GetContactValue(ArContact: TArContact): Byte;
var
  i: Integer;
begin
  Result:=0;
  for i:=1 to 8 do
  case i of
    1: if ArContact[i] then Result:=Result or 128;
    2: if ArContact[i] then Result:=Result or 64;
    3: if ArContact[i] then Result:=Result or 32;
    4: if ArContact[i] then Result:=Result or 16;
    5: if ArContact[i] then Result:=Result or 8;
    6: if ArContact[i] then Result:=Result or 4;
    7: if ArContact[i] then Result:=Result or 2;
    8: if ArContact[i] then Result:=Result or 1;
  end;
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  ArContact: TArContact;
  s: string;
begin
  ArContact[1]:=True;  //второй контакт включен
  ArContact[2]:=false; //третий контакт выключен
  ArContact[3]:=True;  //четвертый контакт включен  и т.д.
  ArContact[4]:=True;
  ArContact[5]:=True;
  ArContact[6]:=False;
  ArContact[7]:=True;
  ArContact[8]:=True;
  //...
  //получаем строку
  s:=chr(GetContactValue(ArContact))+chr(11)+chr(54)+chr(18);
end;



--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 26.8.2006, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Огромное спасибо!  smile 

И последнее приставание с моей стороны (точнее уточнение): чтобы на протяжении некоторого времени держать контакт под напряжением нужно отправлять данные в порт в цикле или достаточно один раз отправить данные, а потом их обнулить через некоторое время?

Добавлено @ 10:50 
Цитата(Fedia @  25.8.2006,  01:59 Найти цитируемый пост)
Попробуй посмотреть здесь 

Вдумчиво перечитал весь текст. Так какое напряжение будет получать устройство при подключении его на LPT порт? Там везде про 5 вольт говорится... smile
PM   Вверх
Albinos_x
Дата 26.8.2006, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Цитата(Pakshin A. S. @  26.8.2006,  10:36 Найти цитируемый пост)
И последнее приставание с моей стороны (точнее уточнение): чтобы на протяжении некоторого времени держать контакт под напряжением нужно отправлять данные в порт в цикле или достаточно один раз отправить данные, а потом их обнулить через некоторое время?

достаточно один раз послать...


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Fedia
Дата 27.8.2006, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 8
Всего: 13



Цитата(Pakshin A. S. @  26.8.2006,  10:36 Найти цитируемый пост)
Там везде про 5 вольт говорится...

Я сейчас немного покопался в инете. Похоже что напряжение с LPT подается 5-ти вольтовое, а для того, чтобы получить 12-ть используют преобразователи напряжения.
Вот здесь есть немного информации по этому поводу. Надеюсь что поможет.
А на счет поддержания напряжения тебе уже ответили smile Удачи !


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Albinos_x
Дата 27.8.2006, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Цитата(Fedia @  27.8.2006,  22:40 Найти цитируемый пост)
 Похоже что напряжение с LPT подается 5-ти вольтовое,

так и есть, единственное, где-то читал, что оно может быть меньше ~ 4,7 В, но вот когда сам делал под LTP прогу с устройством, то было чисто 5 В...


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
NiТR0
Дата 30.8.2006, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 28.6.2005

Репутация: нет
Всего: нет



Товарисчи! Помогите!
Вообщем, тема работы с LPT обсуждалась не раз везде где можно.
Я пошел по следующему пути: скачал LPTIO.pas и бинарник lptwdmio.sys, и попытался переложить написанный в дельфи LPTIO.pas на С++, динамически подключив ADVAPI32.DLL. Но возникла проблема с созданием и открытием сервиса. Прошу помощи. Может у кого-нибудь есть готовый класс для работы с LPT на С++... не откажите.
Здесь представлен класс для работы с LPT (*.cpp и ниже *.h), но! не могу понять, как исправить 2 ошибки: 1078 и 1060(!). Они обозначены в коде (ф-я Init()).
Код

// CPP-File
#include <vcl.h>
#include <stdio.h>
#include <Winsvc.h>
#pragma hdrstop

#include <LptPortClass.h>
#pragma package(smart_init)

TLptPort::TLptPort()
{
    hDll = 0;
    UnregisterService = false;

    // Имя символuческой связи
    sprintf(DRV_LINK_NAME, "\\.\LptAccessAgent");

    sprintf(SWC_NAME, "lptwdmio"); //Системное имя сервиса
    sprintf(SWC_DISPLAY_NAME, "LPT port direct access service"); // Название сервиса, чтобы показать пользователю

    IOCTL_READ_PORTS = 0x00220050; // Чтение регистров LPT
    IOCTL_WRITE_PORTS =    0x00220060; // Запись в регистры LPT

    LPT1 = 0x10; // база $3BC
    LPT2 = 0x20; //      $378
    LPT3 = 0x30; //      $278

    // Смещения регистров порта
    LPT_DATA_REG    = 0; // Регистр данных
    LPT_STATE_REG   = 1; // Регистр состояния
    LPT_CONTROL_REG = 2; // Регистр управления
    LPT_EPP_ADDRESS = 3; // Регистр адреса EPP
    LPT_EPP_DATA    = 4; // Регистр данных EPP

    Port = INVALID_HANDLE_VALUE;
    Init();
}
TLptPort::~TLptPort()
{
    Release();
}
//==============================================================================
void TLptPort::Init()
{
    SC_HANDLE    hSCMahager;        // Хэндл менеджера сервисов
    SC_HANDLE   hServiceHandle;    // Хэндл сервиса lptwdmio
    AnsiString SysBinaryName;
    
    // --- Попытка связаться с драйвером ---
    //открываем порт
    Port = CreateFile(DRV_LINK_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    // если ошибка - выходим
    if (Port == INVALID_HANDLE_VALUE)
    {
        // Не удалось связаться с драйвером. Он не был установлен вручную.
        // Windows NT -- пробуем запустить драйвер через менеджер управления сервисами
     hDll = LoadLibrary("ADVAPI32.DLL"); // Получим указатели на ф-и менеджера сервисов.
        if(hDll != 0)
        {
            // Re: чтобы программа работала и на NT, и на 9x, используем динамическую загрузку AdvApi32.dll
            // Получим указатели на ф-и в AdvApi32.dll
            OpenSCManager_      = POpenSCManager(GetProcAddress(hDll, "OpenSCManagerA"));
            CloseServiceHandle_ = PCloseServiceHandle(GetProcAddress(hDll, "CloseServiceHandle"));
            CreateService_      = PCreateService(GetProcAddress(hDll, "CreateServiceA"));
            StartService_       = PStartService (GetProcAddress(hDll, "StartServiceA"));
            OpenService_        = POpenService  (GetProcAddress(hDll, "OpenServiceA"));
            DeleteService_      = PDeleteService(GetProcAddress(hDll, "DeleteService"));

            // Свяжемся с менеджером сервисов
            hSCMahager = OpenSCManager_(NULL, NULL, SC_MANAGER_CREATE_SERVICE /*0xF003F = SC_MANAGER_ALL_ACCESS */);
            if(hSCMahager != 0)
            {
             SysBinaryName = ExtractFilePath(Application->ExeName) + "LPTWDMIO.SYS" ; // имя бинарника sys
              // Попытка создания сервиса
                SetLastError(0);
                hServiceHandle = CreateService_(hSCMahager,
                                                SWC_NAME,            // имя сервиса
                                                SWC_DISPLAY_NAME,    // отображаемое имя
                                                0xF01FF,            // права доступа  SERVICE_ALL_ACCESS
                                                1,                    // SERVICE_KERNEL_DRIVER
                                                3,                  // SERVICE_DEMAND_START
                                                1,                  // SERVICE_ERROR_NORMAL
                                                SysBinaryName.c_str(),
                                                NULL,
                                                NULL,
                                                NULL,
                                                NULL,
                                                NULL);
                RezLastError = GetLastError(); <<< ERROR! 1078 - Такой сервис уже запущен (хотя это неправда) <<< Почему???
                if (hServiceHandle == 0)
                {// Возможно, сервис был создан ранее
                    SetLastError(0);
                    hServiceHandle = OpenService_(hSCMahager, SWC_NAME, SERVICE_ALL_ACCESS); // откроем его
                    RezLastError = GetLastError(); <<< ERROR! 1060 - ERROR_SERVICE_DOES_NOT_EXIST - The specified service does not exist as an installed service. <<< Почему???????????
                }
                if(hServiceHandle != 0)
                {// ОК, запускаем сервис

                    SetLastError(0);
                    if( !StartService_(hServiceHandle, 0, NULL) ) // Наш драйвер должен загрузиться...
                    {
                        RezLastError = GetLastError();
                    }
                    else
                    {
                        UnregisterService = true;             // При разрушении объекта не забыть пометить сервис для удаления
                        CloseServiceHandle_(hServiceHandle); // Освобождаем хэндл
                    }
                }

                CloseServiceHandle_(hSCMahager); // Освобождаем хэндл
            }
        }

        // Вторично пытаемся связаться с драйвером
        Port = CreateFile("\\.\LptAccessAgent", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    }

    // Флаги наличия портов
    bool PortPresent[3];
    if( Ready() )
    {
      // Определим порты, представленные в системе
      PortPresent[0] = IsPortPresent(LPT1);
      PortPresent[1] = IsPortPresent(LPT2);
      PortPresent[2] = IsPortPresent(LPT3);
    }                                        //*/
}

void TLptPort::Release()
{
    SC_HANDLE    hSCMahager;        // Хэндл менеджера сервисов
    SC_HANDLE   hServiceHandle;    // Хэндл сервиса lptwdmio
    
    if (Port != INVALID_HANDLE_VALUE) CloseHandle(Port);
    if(UnregisterService)
    {// разрегистрировать сервис
        if(hDll != 0)
        {
            hSCMahager = OpenSCManager_(NULL, NULL, SC_MANAGER_ALL_ACCESS); // Связаться с менеджером сервисов
            if(hSCMahager != 0)
            {
             hServiceHandle = OpenService_(hSCMahager, SWC_NAME, SERVICE_ALL_ACCESS); // Получить хэндл сервиса lptwdmio
             if(hServiceHandle != 0)
                {
                  DeleteService_(hServiceHandle);      // Пометить сервис как подлежащий удалению. Драйвер останется в памяти до ближайшей перезагрузки.
                  CloseServiceHandle_(hServiceHandle); // Освобождаем хэндл
             }
             CloseServiceHandle_(hSCMahager); // Высвободить хэндл менеджера сервисов
            }
            FreeLibrary(hDll); // Высвободить хэндл библиотеки AdvApi32.dll
       }
    }
}

// Возвращает признак готовности/неготовности
bool TLptPort::Ready()
{
    return (Port != INVALID_HANDLE_VALUE ); // Загружен драйвер
}

// Функция для чтения регистров LPT. Возвращает true, если чтение прошло успешно.
bool TLptPort::ReadPorts(ADRDATASTRUCT* PairArray, DWORD PairCount)
{
    DWORD cb;
    ADRDATASTRUCT* Pair;
    DWORD ct;
    WORD adr;

    if( Ready() && (Port != INVALID_HANDLE_VALUE) )
    {// Чтение через драйвер
        cb = 0;
        if( DeviceIoControl( Port, IOCTL_READ_PORTS, PairArray, PairCount*2, PairArray, PairCount*2, &cb, NULL ) ) return true;
        else return false;
    }
    else    return false;
}

// Функция для вывода данных в регистры LPT. Возвращает true, если запись прошла успешно.
bool TLptPort::WritePorts(ADRDATASTRUCT* PairArray, DWORD PairCount)
{
    DWORD cb;
    ADRDATASTRUCT* Pair;
    DWORD ct;
    WORD adr;

    if( Ready() && (Port != INVALID_HANDLE_VALUE) )
    {// Запись через драйвер
        cb = 0;
        if( DeviceIoControl(Port, IOCTL_WRITE_PORTS, PairArray, PairCount*2, PairArray, PairCount*2, &cb, NULL ) ) return true;
        else false;
    }
    return false;
}

// Функция для чтения одного регистра указанного порта
BYTE TLptPort::ReadPort  (BYTE LptNumber, BYTE RegOffset)
{
    ADRDATASTRUCT Pair;
    Pair.Adr = LptNumber;    // or RegOffset;
    Pair.Data = 0;
    ReadPorts(&Pair,1);
    return Pair.Data;
}

// Процедура для вывода значения в регистр порта
BYTE TLptPort::WritePort (BYTE LptNumber, BYTE RegOffset, BYTE Value)
{
    ADRDATASTRUCT Pair;
    Pair.Adr = LptNumber;    // or RegOffset;
    Pair.Data = Value;
    WritePorts(&Pair,1);
    return Pair.Data;
}

// Ф-я тестирования наличия порта. Возвратит true, если порт присутствует.
bool TLptPort::IsPortPresent(BYTE LptNumber)
{
    BYTE data;
    bool present = true;

    data = ReadPort(LptNumber, LPT_DATA_REG); // Сохраняем текущее значение регистра данных
    WritePort(LptNumber,LPT_DATA_REG,0x00); // Пишем 0
    if(ReadPort(LptNumber,LPT_DATA_REG) == 0) // Проверим -- что записали, то и прочитали?
    {
     WritePort(LptNumber,LPT_DATA_REG,0x55); // Пишем 0x55
        if(ReadPort(LptNumber,LPT_DATA_REG) == 0x55)
        {
            WritePort(LptNumber,LPT_DATA_REG,0xAA); // Пишем 0xAA
            if(ReadPort(LptNumber,LPT_DATA_REG) == 0xAA)
         {
             WritePort(LptNumber,LPT_DATA_REG,data); // Восстанавливаем прежнее значение регистра данных
            }
            else present = false;
        }
        else present = false;
    }
    else present = false;
    // Проверим наличие регистров управления и данных, если порт не обнаружен (в случае однонаправленного порта)
    if(!present)
    {
        data = ReadPort(LptNumber,LPT_CONTROL_REG);  // Читаем регистр управления
        if((data != 0x00) && (data != 0xFF)) present = true;    // Не пустое значение? -- порт присутствует
        if(!present)
        {
            data = ReadPort(LptNumber,LPT_STATE_REG);             // Читаем регистр состояния
            if((data != 0x00) && (data != 0xFF)) present = true;
        }
    }
    return present;
}

//---------------------------------------------------------------------------------------------------------------

// H-File
#ifndef LptPortClassH
#define LptPortClassH

struct ADRDATASTRUCT
{
    BYTE Adr;
    BYTE Data;
};

class TLptPort
{
private:
    HANDLE Port;
    HINSTANCE    hDll;
    
    char DRV_LINK_NAME[100];    // Имя символuческой связи

    // Константы для работы с менеджером сервисов
    char        SWC_NAME[100];                //Системное имя сервиса
    char        SWC_DISPLAY_NAME[100];        // Название сервиса, чтобы показать пользователю

    bool        UnregisterService;        // флаг, показывающий необходимость удаления
    char        ServiceArgVectors[100];    // Вспомогательная переменная для вызова StartService

    // Коды сообщений драйверу
    DWORD        IOCTL_READ_PORTS; // Чтение регистров LPT
    DWORD        IOCTL_WRITE_PORTS; // Запись в регистры LPT

    // Номера портов LPT
    BYTE LPT1; // база $3BC
    BYTE LPT2; //      $378
    BYTE LPT3; //      $278

    // Смещения регистров порта
    BYTE LPT_DATA_REG;        // Регистр данных
    BYTE LPT_STATE_REG;    // Регистр состояния
    BYTE LPT_CONTROL_REG;    // Регистр управления
    BYTE LPT_EPP_ADDRESS;    // Регистр адреса EPP
    BYTE LPT_EPP_DATA;        // Регистр данных EPP

    typedef SC_HANDLE    (*POpenSCManager)        (char* lpMachineName, char* lpDatabaseName, DWORD dwDesiredAccess);
    typedef bool        (*PCloseServiceHandle)    (SC_HANDLE hSCObject);
    typedef SC_HANDLE    (*PCreateService)        (SC_HANDLE hSCManager, char* lpServiceName, char* lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, char* lpBinaryPathName, char* lpLoadOrderGroup, LPDWORD lpdwTagId, char* lpDependencies, char* lpServiceStartName, char* lpPassword);
    typedef bool        (*PStartService)        (SC_HANDLE hService, DWORD dwNumServiceArgs, char* lpServiceArgVectors);
    typedef SC_HANDLE    (*POpenService)            (SC_HANDLE hSCManager, char* lpServiceName, DWORD dwDesiredAccess);
    typedef bool        (*PDeleteService)        (SC_HANDLE hService);

    POpenSCManager        OpenSCManager_;
    PCloseServiceHandle CloseServiceHandle_;
    PCreateService      CreateService_;
    PStartService       StartService_;
    POpenService        OpenService_;
    PDeleteService      DeleteService_;

protected:

  virtual void Init();
  virtual void Release();

public:
  TLptPort();
  ~TLptPort();

    bool Ready();
    bool ReadPorts(ADRDATASTRUCT* PairArray, DWORD PairCount);
    bool WritePorts(ADRDATASTRUCT* PairArray, DWORD PairCount);
    BYTE ReadPort(BYTE LptNumber, BYTE RegOffset);
    BYTE WritePort(BYTE LptNumber, BYTE RegOffset, BYTE Value);
    bool IsPortPresent(BYTE LptNumber);
};
#endif

 smile 
PM MAIL   Вверх
Pakshin A. S.
Дата 30.8.2006, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61




M
Pakshin A. S.
NiТR0, В данном разделе обсуждаются проблемы, связанные только с Дельфи, поэтому Вам следует задать свой вопрос в разделе, который решает проблемы, связанные с С++...

PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1094 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.