
Новичок
Профиль
Группа: Участник
Сообщений: 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
|
|