Шаг 77.
Доступ к ресурсам локальной сети

    На этом шаге мы рассмотрим организацию доступа к различным ресурсам сети.

    В следующих шагах мы рассмотрим вопрос о доступе к ресурсам локальной сети. При этом следует выделить две проблемы:

    Начнем с того, что перечислим основные функции для работы с сетевыми ресурсами. Это не все функции, но их вполне достаточно, чтобы ваша программа самостоятельно искала сетевые ресурсы и подключалась к ним.

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

NETRESOURCE  STRUC
             dwScope       DWORD  ?
             dwType        DWORD  ?
             dwDisplayType DWORD  ?
             dwUsage       DWORD  ?
             lpLocalName   DWORD  ?
             lpRemoteName  DWORD  ?
             lpComment     DWORD  ?
             lpProvider    DWORD  ? 
NETRESOURCE ENDS

    Рассмотрим назначение каждого поля:

    Функция WNetAddConnection2 используется для подсоединения к вашему компьютеру сетевого ресурса (диска или принтера). Ее параметры:

    При успешном завершении функция возвращает 0 (NO_ERROR). Это касается и всех остальных рассмотренных ниже функций.

    Функция WNetCancelConnection2 используется для отсоединения ресурса. Перечислим ее параметры:

    Функция WnetOpenEnum осуществляет поиск сетевых ресурсов. Вообще говоря, сетевые ресурсы представляют собой структуру в виде дерева. Об этом мы будем говорить позже, поэтому поиск сетевых ресурсов весьма напоминает поиск файлов по дереву каталогов. Ее параметры:

    Функция WNetCloseEnum закрывает поиск. Единственным параметром этой функции является дескриптор, полученный при выполнении функции WNetOpenEnum.

    WNetEnumResource - функция, осуществляющая непосредственный поиск сетевых ресурсов. Ее параметры:

    Подчеркнем, что данная функция осуществляет поиск не всех ресурсов, а лишь ресурсов данного иерархического уровня. Так что без рекурсии не обойтись.

    Функция WNetGetConnection - с помощью данной функции можно получить информацию о данном соединении. Ее параметры:

    Завершая краткий обзор сетевых функций и переходя к программированию, заметим, что нами описана лишь часть наиболее важных сетевых функций. Кроме того, в Windows NT имеются еще и свои функции для работы с сетевыми ресурсами, которые отсутствуют в операционной системе Windows 9x. Кстати, будьте готовы к тому, что поведение описанных функций может несколько отличаться в Windows 9x, Windows NT, Windows 2000 и Windows XP.

    Ниже представлена программа, позволяющая подключаться к сетевым дискам. Командная строка программы: pr77_1 \\SERVER\CC Z:. Первый параметр - имя подключаемого устройства, включающее имя сетевого сервера. Второй параметр - локальный диск, на который будет спроецирован сетевой диск.

.386P
;Плоская модель.
.MODEL FLAT, STDCALL
;Константы.
STD_OUTPUT_HANDLE equ -11
RESOURCETYPE_DISK equ 1h
;Прототипы внешних процедур.
IFDEF MASM
    EXTERN  lstrcat@8:NEAR 
    EXTERN  lstrlen@4:NEAR
    EXTERN  GetStdHandle@4:NEAR 
    EXTERN  WriteConsoleA@20:NEAR 
    EXTERN  ExitProcess@4:NEAR 
    EXTERN  GetCommandLineA@0:NEAR
    EXTERN  WNetAddConnection2A@16:NEAR 
ELSE
    LOCALS
    EXTERN  lstrcat:NEAR
    EXTERN  lstrlen:NEAR
    EXTERN  GetStdHandle:NEAR
    EXTERN  WriteConsoleA:NEAR
    EXTERN  ExitProcess:NEAR
    EXTERN  GetCommandLineA:NEAR
    EXTERN  WNetAddConnection2A:NEAR 
    lstrcat@8              = lstrcat 
    lstrlen@4              = lstrlen 
    GetStdHandle@4         = GetStdHandle 
    WriteConsoleA@20       = WriteConsoleA 
    ExitProcess@4          = ExitProcess 
    GetCommandLineA@0      = GetCommandLineA 
    WNetAddConnection2A@16 = WNetAddConnection2A 
ENDIF
;Структуры.
NETRESOURCE  STRUC
             dwScope       DWORD  ?
             dwType        DWORD  ?
             dwDisplayType DWORD  ?
             dwUsage       DWORD  ?
             lpLocalName   DWORD  ?
             lpRemoteName  DWORD  ?
             lpComment     DWORD  ?
             lpProvider    DWORD  ? 
NETRESOURCE ENDS

;Директивы компоновщику для подключения библиотек.
IFDEF MASM
;Для компоновщика  LINK.EXE.
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\mpr.lib
ELSE
;Для компоновщика  TLINK32.EXE.
    includelib c:\tasm32\lib\import32.lib
ENDIF
;------------------------------------------------
;Сегмент данных. 
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
     BUF1       DB 100 DUP(0)
     BUF2       DB 100 DUP(0)
     LENS       DWORD  ? ;Количество выведенных символов.
     HANDL      DWORD  ? 
     NR         NETRESOURCE <?>
     PUSTO      DB  0
     ERR2       DB  "Ошибка!",0
     ERR1       DB  "Мало параметров!",0
     ST1        DB "->",0
_DATA ENDS 
;Сегмент кода.
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
START: 
;Получить дескриптор вывода.
     PUSH STD_OUTPUT_HANDLE
     CALL GetStdHandle@4
     MOV  HANDL,EAX
;Получить количество параметров. 
     CALL NUMPAR
     CMP  EAX, 3
     JNB  PAR_OK
     LEA  EBX,ERR1
     CALL SETMSG
     JMP  _END 
PAR_OK: 
;Получить параметры.
     MOV  EDI, 2
     LEA  EBX,BUF1
     CALL GETPAR
     MOV  EDI,3
     LEA  EBX,BUF2
     CALL GETPAR 
;Пытаемся произвести подсоединение.
;Вначале заполняем структуру NETRESOURCE. 
;Для Windows NT NR.dwType = 0.
     MOV  NR.dwType, RESOURCETYPE_DISK
     LEA  EAX,BUF2
     MOV  NR.lpLocalName,EAX
     LEA  EAX,BUF1
     MOV  NR.lpRemoteName,EAX
     MOV  NR.lpProvider,0 
;Вызов функции, осуществляющей соединение.
     PUSH 0
     PUSH OFFSET PUSTO
     PUSH OFFSET PUSTO
     PUSH OFFSET NR
     CALL WNetAddConnection2A@16
     CMP  EAX,0
     JE   _OK 
;Сообщение об ошибке.
     LEA  EBX,ERR2
     CALL SETMSG
     JMP  _END 
_OK: 
;Сообщение об успешном соединении.
     PUSH OFFSET  ST1
     PUSH OFFSET  BUF1
     CALL  lstrcat@8
     PUSH OFFSET BUF2
     PUSH OFFSET BUF1
     CALL lstrcat@8
     LEA  EBX,BUF1
     CALL SETMSG 
_END:
     PUSH 0
     CALL ExitProcess@4
;Определить количество параметров (->ЕАХ) 
NUMPAR PROC
     CALL GetCommandLineA@0 
     MOV  ESI,EAX  ;Указатель на строку. 
     XOR  ECX,ECX  ;Счетчик. 
     MOV  EDX,1    ;Признак.
@@L1:
     CMP  BYTE PTR [ESI],0
     JE   @@L4
     CMP  BYTE PTR [ESI],32
     JE   @@L3
     ADD  ECX,EDX ;Номер параметра.
     MOV  EDX,0
     JMP  @@L2
@@L3:
     OR   EDX, 1
@@L2:
     INC  ESI
     JMP  @@L1
@@L4:
     MOV  EAX,ECX
     RET
NUMPAR ENDP
;Получить параметр.
;EBX - указывает на буфер, куда будет помещен параметр.
;В буфер помещается строка с нулем на конце.
;EDI - номер параметра.
GETPAR PROC
     CALL GetCommandLineA@0
     MOV  ESI,EAX ;Указатель на строку.
     XOR  ECX,ECX ;Счетчик.
     MOV  EDX,1   ;Признак.
@@L1:
     CMP  BYTE PTR [ESI],0
     JE   @@L4
     CMP  BYTE PTR [ESI],32
     JE   @@L3
     ADD  ECX,EDX ;Номер параметра.
     MOV  EDX,0
     JMP  @@L2
@@L3:
     OR   EDX,1
@@L2:
     CMP  ECX,EDI
     JNE  @@L5
     MOV  AL,BYTE  PTR   [ESI]
     CMP  AL,32
     JE   @@L5
     MOV  BYTE PTR [EBX],AL
     INC  EBX
@@L5:
     INC  ESI
     JMP  @@L1
@@L4:
     MOV  BYTE PTR [EBX],0
     RET	
GETPAR ENDP
;Вывод сообщения.
;EBX  -> строка.
SETMSG PROC
     PUSH EBX
     CALL lstrlen@4
     PUSH 0
     PUSH OFFSET  LENS
     PUSH EAX
     PUSH EBX
     PUSH HANDL
     CALL WriteConsoleA@20
     RET
SETMSG ENDP
_TEXT  ENDS	
       END  START	
Текст этого файла можно взять здесь.

    Трансляция программы:

    Рассматривая приведенную программу, прежде всего обратите внимание на использование локальных меток. MASM распознает локальные метки автоматически. TASM требует, чтобы локальная метка имела в начале два символа @@. Кроме того, в начале программы требуется директива LOCALS.

    Оотметим одну существенную особенность функции WNetAddConnection2A@16. При заполнении структуры NETRESOURCE поле dwType для операционной системы Windows NT должно заполняться нулем, а не RESOURCETYPE_DISK. К сожалению, имеются и другие подобные нюансы при работе с ресурсами локальной сети. Если вы всерьез займетесь программированием в локальной сети, вам придется проверять свою программу на разных компьютерах и разных сетях.

    Данная программа далека от совершенства. Попробуйте над ней поработать. В частности, не мешало бы проверять, является ли локальное устройство сетевым или нет, и если является, спросить разрешение на переподключение данного устройства. В этом случае необходимо вначале отключить устройство от старого сетевого ресурса при помощи известной вам функции WNetCancelConnection2.

    Если необходимо подключать сетевой принтер, то поле dwType должно быть равно RESOURCETYPE_PRINT.

    На следующем шаге мы рассмотрим поиск сетевых ресурсов.




Предыдущий шаг Содержание Следующий шаг