// дополнение из Driver Developer Kit for Windows NT unit xDDK; // ВНИМАНИЕ! Поля записей в драйверах выравнены не 32 бита (4 байта) interface USES Windows; const GPD_TYPE = 40000; // тип файлового устройства // Device type -- in the "User Defined" range." METHOD_BUFFERED = 0; // управление буфер. вводом/выводом (включено ?) FILE_READ_ACCESS = 1; // устройство для ввода FILE_WRITE_ACCESS = 2;// устройство для вывода // The IOCTL function codes from 0x800 to 0xFFF are for customer use. IOCTL_GPD_READ_PORT=DWord(GPD_TYPE shl 16) or (FILE_READ_ACCESS shl 14) or METHOD_BUFFERED; IOCTL_GPD_WRITE_PORT=DWord(GPD_TYPE shl 16) or (FILE_WRITE_ACCESS shl 14) or METHOD_BUFFERED; IOCTL_GPD_READ_PORT_UCHAR=IOCTL_GPD_READ_PORT or($900 shl 2); IOCTL_GPD_READ_PORT_USHORT=IOCTL_GPD_READ_PORT or($901 shl 2); IOCTL_GPD_READ_PORT_ULONG=IOCTL_GPD_READ_PORT or($902 shl 2); IOCTL_GPD_WRITE_PORT_UCHAR=IOCTL_GPD_WRITE_PORT or($910 shl 2); IOCTL_GPD_WRITE_PORT_USHORT=IOCTL_GPD_WRITE_PORT or($911 shl 2); IOCTL_GPD_WRITE_PORT_ULONG=IOCTL_GPD_WRITE_PORT or($912 shl 2); type UCHAR=byte; SHORT=Smallint; USHORT=WORD; UCHAR_32=packed record case byte of 0:(UCHAR:byte); 1:(Alignment:ULONG); // выравнивает размер на 32 бита end; USHORT_32=packed record case byte of 0:(USHORT:WORD); 1:(Alignment:ULONG); end; LONG = longint; SHORT_32 = packed record case byte of 0:(SHORT:Smallint); 1:(Alignment:ULONG); end; // Данные для вывода в порт через драйвер устройства типа GenPortIO _GENPORT_WRITE_OUTPUT=record PortNumber:ULONG; // Port # to write to case byte of // Data to be output to port 0:(LongData:ULONG); 1:(ShortData:WORD); 2:(CharData:BYTE); end; // Данные для ввода из порта через драйвер устройства типа GenPortIO _GENPORT_WRITE_INPUT=record PortNumber:ULONG; // Port # to read from end; //-------- НОВЫЙ ВАРИАНТ ДРАЙВЕРА ---------------- type // Данные INPUT-буфера для ввода из порта через драйвер устройства типа GenPortIO tGENPORT_READ_INPUT_BUFFER=record PortNumber:ULONG; // Номер порта для чтения end; // Данные OUTNPUT-буфера для ввода из порта через драйвер устройства типа GenPortIO tGENPORT_READ_OUTPUT_BUFFER=record case byte of 1:(ULongData:ULONG); // Данные, возвращаемые драйвером 2:(UShortData:WORD); 3:(UCharData:BYTE); 4:(LongData:LongInt); 5:(ShortData:SmallInt); 6:(CharData:ShortInt); end; // Данные INPUT&OUTNPUT-буфера для ввода из порта через драйвер устройства типа GenPortIO tGENPORT_READ_INPUT_OUTPUT_BUFFER=record case byte of 0:(Input:tGENPORT_READ_INPUT_BUFFER); // Номер порта для чтения 1:(Output:tGENPORT_READ_OUTPUT_BUFFER); // Данные, возвращаемые драйвером end; // Данные INPUT-буфера для вывода в порт через драйвер устройства типа GenPortIO tGENPORT_WRITE_INPUT_BUFFER=record PortNumber:ULONG; // Номер порта для записи case byte of 1:(ULongData:ULONG); // Данные, записываемые в порт 2:(UShortData:WORD); 3:(UCharData:BYTE); 4:(LongData:LongInt); 5:(ShortData:SmallInt); 6:(CharData:ShortInt); end; //-------- Усовершенствование драйвера------------------------------------------- const { Чтение нескольких значений из ПОРТА} IOCTL_GPD_READ_PORT_BUFFER = IOCTL_GPD_READ_PORT or ($903 shl 2); { Ожидание на ПОРТу } IOCTL_GPD_WAIT_ON_PORT = IOCTL_GPD_READ_PORT or ($904 shl 2); { Запись нескольких значений в ПОРТ} IOCTL_GPD_WRITE_PORT_BUFFER = IOCTL_GPD_WRITE_PORT or ($913 shl 2); { Запись в порт 1 + ожидание на ПОРТу 2} IOCTL_GPD_WRITE_AND_WAIT_ON_PORT = IOCTL_GPD_WRITE_PORT or ($914 shl 2); { УПРАВЛЕНИЕ ДРАЙВЕРОМ -------------------------} { Запрос информации о драйвере } IOCTL_MI1201_GET_CONTROL_INFO = IOCTL_GPD_READ_PORT or ($8FF shl 2); IOCTL_MI1201_SET_CONTROL_INFO = IOCTL_GPD_WRITE_PORT or ($8FE shl 2); { Запрос на немедленное прекращение всех операций } IOCTL_MI1201_ABORT = IOCTL_GPD_WRITE_PORT or ($8FD shl 2); type tLSHUnion=record case byte of 0:(ULong: ULONG); 1:(UShort: USHORT); 2:(UChar: UCHAR); 3:(Long: LONG); 4:(Short: SHORT); 5:(Char: CHAR); end; tLSHArrayUnion=record case byte of 0:(ULong: packed array[0..0]of ULONG); 1:(UShort: packed array[0..0]of USHORT); 2:(UChar: packed array[0..0]of UCHAR); 3:(Long: packed array[0..0]of LONG); 4:(Short: packed array[0..0]of SHORT); 5:(Char: packed array[0..0]of CHAR); end; const cMaxByteArraySize=(High(integer)-4); cMaxWordArraySize=cMaxByteArraySize div 2; cMaxDWordArraySize=cMaxByteArraySize div 4; type tArrayOfByte =array[0..cMaxByteArraySize] of byte; ptArrayOfByte=^tArrayOfByte; tArrayOfWord =array[0..cMaxWordArraySize] of word; ptArrayOfWord =^tArrayOfWord; tArrayOfDWord=array[0..cMaxDWordArraySize] of dword; ptArrayOfDWord=^tArrayOfDWord; { Тип порта } tPortType=( PORT_UCHAR, PORT_USHORT, PORT_ULONG ); { Чтение -------------------------} tGENPORT_READ_MULTI_OUTPUT_BUFFER_HEADER = packed record Count: ULONG; { Количество считанных значений } end; tGENPORT_READ_MULTI_OUTPUT_BUFFER = packed record Header:tGENPORT_READ_MULTI_OUTPUT_BUFFER_HEADER; { Заголовок} Data:tLSHArrayUnion; { Данные, прочитанные из порта } end; ptGENPORT_READ_MULTI_OUTPUT_BUFFER = ^tGENPORT_READ_MULTI_OUTPUT_BUFFER; tGENPORT_READ_MULTI_INPUT_BUFFER = packed record Port:ULONG; { Port # to read from } PortType:UCHAR; { 0 - byte; 1 - word; 2 - dword } Filling:array[0..2] of byte; Count:ULONG; { Количество значений для считывания } end; ptGENPORT_READ_MULTI_INPUT_BUFFER = ^tGENPORT_READ_MULTI_INPUT_BUFFER; tGENPORT_READ_MULTI_INPUT_OUTPUT_BUFFER = packed record case byte of 0:(Input: tGENPORT_READ_MULTI_INPUT_BUFFER); { Данные по порту } 1:(Output:tGENPORT_READ_MULTI_OUTPUT_BUFFER); { Данные считанные с порта } end; ptGENPORT_READ_MULTI_INPUT_OUTPUT_BUFFER = ^tGENPORT_READ_MULTI_INPUT_OUTPUT_BUFFER; // Запись ------------------------- tGENPORT_WRITE_MULTI_INPUT_BUFFER_HEADER = packed record Port:ULONG; { Port # to write to} PortType:UCHAR; { 0 - byte; 1 - word; 2 - dword } Filling:array[0..2] of byte; Count:ULONG; { Количество значений для записи } end; ptGENPORT_WRITE_MULTI_INPUT_BUFFER_HEADER = ^tGENPORT_WRITE_MULTI_INPUT_BUFFER_HEADER; tGENPORT_WRITE_MULTI_INPUT_BUFFER = packed record Header:tGENPORT_WRITE_MULTI_INPUT_BUFFER_HEADER; Data:tLSHArrayUnion; { Данные для записи в порт} end; ptGENPORT_WRITE_MULTI_INPUT_BUFFER = ^tGENPORT_WRITE_MULTI_INPUT_BUFFER; tGENPORT_WRITE_MULTI_OUTPUT_BUFFER_HEADER = packed record XXX:ULONG; // ЗАГЛУШКА end; ptGENPORT_WRITE_MULTI_OUTPUT_BUFFER_HEADER = ^tGENPORT_WRITE_MULTI_OUTPUT_BUFFER_HEADER; tGENPORT_WRITE_MULTI_OUTPUT_BUFFER = packed record Header:tGENPORT_WRITE_MULTI_OUTPUT_BUFFER_HEADER; { Заголовок} end; ptGENPORT_WRITE_MULTI_OUTPUT_BUFFER = ^tGENPORT_WRITE_MULTI_OUTPUT_BUFFER; tGENPORT_WRITE_MULTI_INPUT_OUTPUT_BUFFER = packed record case byte of 0:(Input:tGENPORT_WRITE_MULTI_INPUT_BUFFER); { Данные для вывода в порт} 1:(Output:tGENPORT_WRITE_MULTI_OUTPUT_BUFFER); end; ptGENPORT_WRITE_MULTI_INPUT_OUTPUT_BUFFER = ^tGENPORT_WRITE_MULTI_INPUT_OUTPUT_BUFFER; // Ожидание ------------------------- { Результат ожидания события } tPortWaitResult= ( pwrSUCCESS, { дождались} pwrTIMEOUT, // таймаут pwrABANDONED, // ожидание прервано pwrERROR ); {Результат ожидания события } tGENPORT_WAIT_OUTPUT_BUFFER = packed record Event:BOOLEAN; { Результат ожидания: TRUE - дождались.} Filling:array[0..2] of byte; WaitResult:ULONG; { Результат ожидания, см. myPORT_WAIT_xxx } TimeOut:ULONG; { Реальное время, затраченное на ожидание в мс } Data:ULONG; { последние данные, считанные с порта } end; ptGENPORT_WAIT_OUTPUT_BUFFER = ^tGENPORT_WAIT_OUTPUT_BUFFER; tWaitControlFlag=( wcfUserRequest, // запрос пользователя, иначе [Executive] wcfUserMode, // ожидать в режиме UserMode, иначе [KernelMode] wcfAlertable // ожидание можно прервать, иначе [FALSE] ); { Ожидание события (Порт(PortNumber) and Mask) == Patt в течение TimeOut мс опрашивая порт через TimeResolution, но не менее 1 раза } tGENPORT_WAIT_INPUT_BUFFER = packed record Port:ULONG; {Порт для ожидания} PortType:UCHAR; { 0 - byte; 1 - word; 2 - dword} Filling:byte; TimeOut:USHORT; { Время ожидания в мс } TimeResolution:USHORT; { Интервал опроса порта в мс} Filling2:array[0..1] of byte; Mask:ULONG; Patt:ULONG; ControlFlags:ULONG; end; tGENPORT_WAIT_INPUT_OUTPUT_BUFFER = packed record case byte of 0:(Input:tGENPORT_WAIT_INPUT_BUFFER); // Данные по порту 1:(Output:tGENPORT_WAIT_OUTPUT_BUFFER); // Данные считанные с порта end; ptGENPORT_WAIT_INPUT_OUTPUT_BUFFER = ^tGENPORT_WAIT_INPUT_OUTPUT_BUFFER; { Управление драйвером } tMI1201_GET_CONTROL_CODE = ( MI1201_GET_CONTROL_CODE_GET_VERSION, MI1201_GET_CONTROL_CODE_GET_CAPABILITIES, MI1201_GET_CONTROL_CODE_GET_ABORT_STATE ); tMI1201_ABORT_INPUT_BUFFER = packed record Stop:BOOLEAN; { TRUE - останов длинных операций; FALSE - разрешение длинных операций;} // Filler:array[1..(4-SizeOf(BOOLEAN))]of byte; end; ptMI1201_ABORT_INPUT_BUFFER = ^tMI1201_ABORT_INPUT_BUFFER; tMI1201_ABORT_OUTPUT_BUFFER = packed record PreviosState:BOOLEAN; { TRUE - останов длинных операций; FALSE - разрешение длинных операций;} // Filler:array[1..(4-SizeOf(BOOLEAN))]of byte; end; ptMI1201_ABORT_OUTPUT_BUFFER = ^tMI1201_ABORT_OUTPUT_BUFFER; tMI1201_CONTROL_INFO_INPUT_BUFFER_BASE_PART = packed record ControlCode:ULONG; // Основной код операции ControlSubCode:ULONG; // Доп. код операции FullSize:ULONG; // Полный размер данных end; ptMI1201_CONTROL_INFO_INPUT_BUFFER_BASE_PART = ^tMI1201_CONTROL_INFO_INPUT_BUFFER_BASE_PART; tMI1201_CONTROL_INFO_OUTPUT_BUFFER_GET_VERSION = packed record InternalVersion:ULONG; // внутренний номер версии end; ptMI1201_CONTROL_INFO_OUTPUT_BUFFER_GET_VERSION = ^tMI1201_CONTROL_INFO_OUTPUT_BUFFER_GET_VERSION; tMI1201_CONTROL_INFO_INPUT_BUFFER_GET_CAPABILITIES = packed record Capabilities:ULONG; // флаги функциональных возможностей end; ptMI1201_CONTROL_INFO_INPUT_BUFFER_GET_CAPABILITIES =^tMI1201_CONTROL_INFO_INPUT_BUFFER_GET_CAPABILITIES; tMI1201_CONTROL_INFO_OUTPUT_BUFFER_GET_ABORT_STATE = packed record State:BOOLEAN; // состояние // Filler:array[1..(4-SizeOf(BOOLEAN))]of byte; end; ptMI1201_CONTROL_INFO_OUTPUT_BUFFER_GET_ABORT_STATE =^tMI1201_CONTROL_INFO_OUTPUT_BUFFER_GET_ABORT_STATE; const { Флаги возможностей драйвера } MI1201_CAP_FLAG_ARRAY_IO_TO_SINGLE_PORT = 1; // Возможность ввода/вывода в один порт массива (нескольких значений за один раз) MI1201_CAP_FLAG_ARRAY_IO_TO_RAW_PORTS = 2; // Возможность ввода/вывода в несколько портов нескольких массивов (нескольких значений за один раз) MI1201_CAP_FLAG_WAIT_ON_SINGLE_PORT = 4; // Ожидания на порту события по маске и образцу указанное число миллисекунд type // Запись в порт 1 + ожидание события (Порт 2(PortNumber) and Mask) == Patt в течение TimeOut мс опрашивая порт через TimeResolution, // но не менее 1 раза tPORT_DATA = packed record Number:ULONG; // Port # to write to PortType:ULONG; // 0 - byte; 1 - word; 2 - dword MemoryType:ULONG; // опционально end; ptPORT_DATA =^tPORT_DATA; tGENPORT_WRITE_AND_WAIT_WRITE_DATA = packed record Port:tPORT_DATA; // Port # to write to Data:tLSHUnion; // Data to be output to port end; ptGENPORT_WRITE_AND_WAIT_WRITE_DATA =^tGENPORT_WRITE_AND_WAIT_WRITE_DATA; tGENPORT_GENPORT_WRITE_AND_WAIT_WAIT_DATA = packed record Port:tPORT_DATA; // Порт для ожидания TimeOut:ULONG; // Время ожидания в мс TimeResolution:ULONG; // Интервал опроса порта в мс Mask:ULONG; // Маска Patt:ULONG; // Образец ControlFlags:ULONG; // Флаги (битовые) управления ожиданием end; tGENPORT_WRITE_AND_WAIT_INPUT_BUFFER = packed record WriteData:tGENPORT_WRITE_AND_WAIT_WRITE_DATA; WaitData:tGENPORT_GENPORT_WRITE_AND_WAIT_WAIT_DATA; end; ptGENPORT_WRITE_AND_WAIT_INPUT_BUFFER =^tGENPORT_WRITE_AND_WAIT_INPUT_BUFFER; tGENPORT_WRITE_AND_WAIT_INPUT_OUTPUT_BUFFER = packed record Input:tGENPORT_WRITE_AND_WAIT_INPUT_BUFFER; // Данные по порту Output:tGENPORT_WAIT_OUTPUT_BUFFER; // Данные считанные с порта end; ptGENPORT_WRITE_AND_WAIT_INPUT_OUTPUT_BUFFER =^tGENPORT_WRITE_AND_WAIT_INPUT_OUTPUT_BUFFER; implementation end.