Ассемблер для Windows

В прикладном программировании часто возникает вопрос определения сетевых устройств



I

В прикладном программировании часто возникает вопрос определения сетевых устройств. В принципе, вопрос можно поставить более широко: как определить тип того или иного устройства. Тот, кто программировал в MS DOS, помнит, что там правильное определение типа устройства было не простой задачей. Операционная система Windows и здесь облегчает нам задачу. Здесь имеется очень полезная функция GetDriveType, единственным аргументом которой является строка корневого каталога искомого устройства, например "А:\" или "D:\". По возвращаемому функцией значению мы и определяем тип устройства (см. файл driv.inc на Рисунок 3.4.1). Результат работы программы представлен на Рисунок 3.4.2.

// файл driv.rc // определение констант

#define WS_SYSMENU 0x00080000L #define WS_MINIMIZEBOX 0x00020000L #define WS_MAXIMIZEBOX 0x00010000L #define WS_VISIBLE 0x10000000L #define WS_TABSTOP 0x00010000L #define WS_VSCROLL 0x00200000L #define DS_3DLOOK 0x0004L #define LBS_NOTIFY 0x0001L #define LBS_SORT 0x0002L #define LBS_WANTKEYBOARDINPUT 0x0400L

// идентификаторы #define LIST1 101

//определение диалогового окна DIAL1 DIALOG 0, 0, 180, 110 STYLE WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | DS_3DLOOK CAPTION "Определение типов устройств" FONT 8, "Arial" { CONTROL "ListBox1",LIST1,"listbox", WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY | LBS_WANTKEYBOARDINPUT, 16, 16, 100, 75 }

; файл driv.inc ; константы ; значения, возвращаемые функцией GetDriveType ; значения 0 и 1 можно считать признаком отсутствия устройства

DRIVE_REMOVABLE equ 2 ; накопитель на гибком диске DRIVE_FIXED equ 3 ; устройство жесткого диска DRIVE_REMOTE equ 4 ; сетевой диск DRIVE_CDROM equ 5 ; накопитель на лазерном диске DRIVE_RAMDISK equ 6 ; электронный диск

; сообщение приходит при закрытии окна WM_CLOSE equ 10h WM_INITDIALOG equ 110h WM_COMMAND equ 111h LB_ADDSTRING equ 180h LB_RESETCONTENT equ 184h WM_LBUTTONDOWN equ 201h

; прототипы внешних процедур IFDEF MASM EXTERN lstrcpy@8:NEAR EXTERN lstrcat@8:NEAR EXTERN GetDriveTypeA@4:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN DialogBoxParamA@20:NEAR EXTERN EndDialog@8:NEAR EXTERN SendDlgItemMessageA@20:NEAR ELSE EXTERN lstrcpy:NEAR EXTERN lstrcat:NEAR EXTERN GetDriveTypeA:NEAR EXTERN ExitProcess:NEAR EXTERN GetModuleHandleA:NEAR EXTERN DialogBoxParamA:NEAR EXTERN EndDialog:NEAR EXTERN SendDlgItemMessageA:NEAR lstrcpy@8 = lstrcpy lstrcat@8 = lstrcat GetDriveTypeA@4 = GetDriveTypeA ExitProcess@4 = ExitProcess GetModuleHandleA@4 = GetModuleHandleA DialogBoxParamA@20 = DialogBoxParamA EndDialog@8 = EndDialog SendDlgItemMessageA@20 = SendDlgItemMessageA ENDIF




; структуры ; структура сообщения MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS

; файл driv.asm .386P ; плоская модель .MODEL FLAT, stdcall include driv.inc ; директивы компоновщику для подключения библиотек IFDEF MASM includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE includelib c:\tasm32\lib\import32.lib ENDIF ;-------------------------------------------------

; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' PRIZ DB 0 MSG MSGSTRUCT <?> HINST DD 0 ; дескриптор приложения PA DB "DIAL1",0 ROO DB "?:\", 0 BUFER DB 40 DUP (0) TYP0 DB " Нет устройства",0 TYP1 DB " Нет устройства",0 TYP2 DB " Гибкий диск",0 TYP3 DB " Жесткий диск",0 TYP4 DB " Сетевой диск",0 TYP5 DB " Лазерный диск",0 TYP6 DB " Электронный диск",0 INDEX DD OFFSET TYP0 DD OFFSET TYP1 DD OFFSET TYP2 DD OFFSET TYP3 DD OFFSET TYP4 DD OFFSET TYP5 DD OFFSET TYP6 _DATA ENDS

; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить дескриптор приложения PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX ;-------------------------------------- PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL DialogBoxParamA@20 CMP EAX,-1 JNE KOL ; сообщение об ошибке KOL: ;-------------------------------------- PUSH 0 CALL ExitProcess@4 ;-------------------------------------- ; процедура окна ; расположение параметров в стеке ; [BP+014Н] ; LPARAM ; [BP+10Н] ; WAPARAM ; [BP+0CН] ; MES ; [BP+8] ; HWND WNDPROC PROC PUSH EBP MOV EBP,ESP PUSH EBX PUSH ESI PUSH EDI ;-------------------------------------- CMP DWORD PTR [EBP+0CH],WM_CLOSE JNE L1 PUSH 0 PUSH DWORD PTR [EBP+08H] CALL EndDialog@8 JMP FINISH L1: CMP DWORD PTR [EBP+0CH],WM_INITDIALOG JNE L2 L4: ; здесь анализ устройств и заполнение списка MOV ECX,65 L00: PUSH ECX MOV ROO, CL ; определить тип устройства PUSH OFFSET ROO CALL GetDriveTypeA@4 ; полный список CMP PRIZ,0 JZ _ALL CMP EAX,2 JB L3 _ALL: ; получить индекс SHL EAX,2 PUSH EAX ; создать строку для списка PUSH OFFSET ROO PUSH OFFSET BUFER CALL lstrcpy@8 POP EBX PUSH INDEX[EBX] PUSH OFFSET BUFER CALL lstrcat@8 ; отправить строку в список PUSH OFFSET BUFER PUSH 0 PUSH LB_ADDSTRING PUSH 101 PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA@20 L3: ; проверить, не достигнута ли граница цикла POP ECX INC ECX CMP ECX,91 JNE L00 JMP FINISH L2: CMP DWORD PTR [EBP+0CH],WM_LBUTTONDOWN JNE FINISH PUSH 0 PUSH 0 PUSH LB_RESETCONTENT PUSH 101 PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA@20 CMP PRIZ,0 JE YES_0 MOV PRIZ,0 JMP L4 YES_0: MOV PRIZ,1 JMP L4 FINISH: MOV EAX,0 POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START


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