Модемы и факс-модемы. Программирование для MS-DOS и Windows

       

Определение доступных портов


Драйвер асинхронного последовательного адаптера VCD предоставляет приложениям Windows программный интерфейс через точку входа, адрес которой можно определить, вызвав мультиплексное прерывание INT 2Fh.

Реализация этих функций зависит от конкретного драйвера VCD. Если у вас установлен драйвер, не совместимый с драйвером VCD из DDK, то эти функции могут не работать.

В листинге 7.3. мы приводим исходный текст приложения FINDPORT, которое определяет порты асинхронного последовательного адаптера, доступные приложениям Windows, посредством вызова функции драйвера VCD.

Листинг 7.3. Файл FINDPORT.CPP

#define            STRICT

#include          <windows.h>

#include          <bwcc.h>

// Прототип функции

BYTE FAR FindCOMPorts( void );

// =========================================================

// Функция WinMain

// =========================================================

#pragma argsused



int PASCAL

WinMain( HINSTANCE hInstance,

                  

HINSTANCE hPrevInstance,

                  

LPSTR lpCmdLine,

                  

int nCmdShow )

{

     

char  szMsg[ 60 ] = "";

     

BYTE  bFindPort;

     

// Определяем работает ли Windows в расширенном режиме

     

if(GetWinFlags() & WF_ENHANCED)

     

{

            

bFindPort = FindCOMPorts();

            

for (int i = 0; i < 8; i++)

            

{

                  

if (bFindPort & (BYTE) (1 << (BYTE)i))

                               

wsprintf( szMsg, "%sCOM%d ", (LPSTR) szMsg, i + 1 ) ;

            

}

            

BWCCMessageBox(NULL,

                  

szMsg, "Обнаружены COM-порты:",

                  

MB_OK | MB_ICONINFORMATION);

     

}

     

else

            

BWCCMessageBox(NULL,

                  

"Зпустите Windows в расширенном режиме", "Сообщение",

                  

MB_OK | MB_ICONSTOP);

     

return 0;

}

После запуска приложения, WinMain вызывает функцию GetWinFlags для определения режима работы Windows. Если Windows работает в стандартном режиме, приложение выводит соответствующее сообщение и завершает свою работу.


Если Windows работает в расширенном режиме, выполняется вызов функции FindCOMPorts, определяющей список доступных COM-портов. Затем полученный список доступных портов отображается на экране.

Функция FindCOMPorts возвращает байт, каждый бит которого отвечает за свой COM-порт. Младший бит соответствует порту COM1, а старший COM8. Исходный текст функции FindCOMPorts представлен в листинге 7.4.

Листинг 7.4. Файл COMM_DRV.CPP

#include    <windows.h>

#include    "comm_drv.h"

// Идентификатор драйвера асинхронного последовательного

// адаптера

#define      VCD_Device_ID  0x0E

// ===========================================================

// Функция FindCOMPorts вызывает драйвер асинхронного адаптера

// и определяет какие COM-порты установлены в компьютере и 

// доступны для использования

// ===========================================================

BYTE FAR FindCOMPorts( void )

{

      BYTE     bResult;

      FARPROC  lpCOMM;

      asm {

             // Определяем адрес точки входа программного интерфейса

             // драйвера асинхронного последовательного адаптера

             mov   ax, 1684h

             mov   bx, VCD_Device_ID

             xor   di, di

             mov   es, di

             int   2Fh

             // Проверяем значение регистров ES:DI

             mov   ax, es

             or    ax, di

             // Если в регистрах ES:DI записаны нулевые значения,

             // драйвер не имеет программного интерфейса и не доступен

             jz    FunctionFailed

             // Драйвер доступен, сохраняем адрес его интерфейса в

             // переменной lpCOMM

             mov   word ptr lpCOMM,      di

             mov   word ptr lpCOMM+2, es

             // Вызываем функцию из драйвера COM-порта

             mov   dx, 1

             call  dword ptr lpCOMM

             // Сохраняем результат, полученный в регистре AL

             mov   bResult, al

             // Завершаем выполнение функции

             jmp   FunctionQuit



      }

      FunctionFailed:

      asm {

             // В случае возникновения ошибки возвращаем нулевое

             // значение

             mov   bResult, 0

      }

      FunctionQuit:

      return( bResult ) ;

}

В исходном тексте функции FindCOMPorts нет ни вызова функции OpenComm, ни вызовов других телекоммуникационных функций, она содержит только десяток строк на языке ассемблера. Рассмотрим функцию FindCOMPorts подробней.

Сначала вызывается функция 1684h мультиплексного прерывания INT 2Fh. Для нее в регистре BX передается константа VCD_Device_ID, означающая, что необходимо получить точку входа для драйвера VCD.

mov   ax, 1684h

mov   bx, VCD_Device_ID

xor   di, di

mov   es, di

int   2Fh

Если после вызова мультиплексного прерывания в регистрах ES:DI сохраняются нулевые значения, значит драйвер VCD не поддерживает программный интерфейс и, следовательно, мы не можем получить к нему доступ. В этом случае возвращаем нулевое значение.

Если содержимое регистров ES:DI не равно нулю, значит драйвер VCD доступен. Сохраняем адрес точки входа его интерфейса в переменной lpCOMM:

mov   word ptr lpCOMM,      di

mov   word ptr lpCOMM+2, es

Затем вызываем функцию из драйвера VCD, предварительно записав в регистр DX значение 1.

mov   dx, 1

call  dword ptr lpCOMM

После возвращения из этой функции по содержимому регистра AL можно определить, какие из портов асинхронного последовательного адаптера доступны для использования.

Затем мы завершаем выполнение функции FindCOMPorts и возвращаем значение регистра AL.

Файл определения модуля приложения FINDPORT приведен в листинге 7.5.

Листинг 7.5. Файл FINDPORT.DEF

; =============================================================

; Файл определения модуля

; =============================================================

NAME OPENCOMM

DESCRIPTION 'Приложение FINDPORT, (C) 1994, Frolov G.V.'

EXETYPE windows

STUB 'winstub.exe'

STACKSIZE  5120

HEAPSIZE  1024

CODE preload moveable discardable

DATA preload moveable multiple


Содержание раздела