На этом шаге мы рассмотрим организацию доступа к различным ресурсам сети.
В следующих шагах мы рассмотрим вопрос о доступе к ресурсам локальной сети. При этом следует выделить две проблемы:
Начнем с того, что перечислим основные функции для работы с сетевыми ресурсами. Это не все функции, но их вполне достаточно, чтобы ваша программа самостоятельно искала сетевые ресурсы и подключалась к ним.
Прежде всего рассмотрим структуру, которая используется в данных функциях.
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
Трансляция программы:
ML /с /coff /DMASM pr77_1.asm LINK /SUBSYSTEM:CONSOLE pr77_1.obj
TASM32 /ml pr77_1.asm TLINK32 -aa pr77_1.obj
Рассматривая приведенную программу, прежде всего обратите внимание на использование локальных меток. MASM распознает локальные метки автоматически. TASM требует, чтобы локальная метка имела в начале два символа @@. Кроме того, в начале программы требуется директива LOCALS.
Оотметим одну существенную особенность функции WNetAddConnection2A@16. При заполнении структуры NETRESOURCE поле dwType для операционной системы Windows NT должно заполняться нулем, а не RESOURCETYPE_DISK. К сожалению, имеются и другие подобные нюансы при работе с ресурсами локальной сети. Если вы всерьез займетесь программированием в локальной сети, вам придется проверять свою программу на разных компьютерах и разных сетях.
Данная программа далека от совершенства. Попробуйте над ней поработать. В частности, не мешало бы проверять, является ли локальное устройство сетевым или нет, и если является, спросить разрешение на переподключение данного устройства. В этом случае необходимо вначале отключить устройство от старого сетевого ресурса при помощи известной вам функции WNetCancelConnection2.
Если необходимо подключать сетевой принтер, то поле dwType должно быть равно RESOURCETYPE_PRINT.
На следующем шаге мы рассмотрим поиск сетевых ресурсов.