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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с LPT портом 
V
    Опции темы
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   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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