Powrót do strony wyboru lekcji

Wykorzystanie funkcji GetDriveTypeA



W czasie tworzenia aplikacji często zachodzi potrzeba zidentyfikowania poszczególnych urządzeń podłączonych do komputera. API udostępnia specjalną funkcję do tego przeznaczoną. Jej nazwa to GetDriveTypeA .

Przykład

Tworzymy program, który na podstawie litery zasobu wypisuje nam napędy optyczne. Na początku deklarujemy wszystkie stałe , funkcje i dane programu:


.586 ;typ instrukcji procesora

.MODEL FLAT,STDCALL

includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

IDC_BTN1      EQU   101

IDC_LST2      EQU   103

IDC_LST1      EQU   102


LB_ADDSTRING                  EQU   180h
LB_RESETCONTENT               EQU   184h
WM_INITDIALOG                 EQU   110h
WM_CLOSE                      EQU   10h
WM_COMMAND                    EQU   111h

EXTERN lstrcpyA@8:NEAR

EXTERN lstrcatA@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


.DATA?
HINST         DD    ?

.DATA
PA            DB   'IDD_DLG1',   0 ;nazwa dialogu
APOS          DB    "?:\",   0
BUFER         DB    40  DUP (0)

Ciąg znaków APOS to argument funkcji GetDriveTypeA. Funkcja zwraca odpowiednią wartość w zależności od rodzaju wykrytego urządzenia. W przypadku napędów optycznych CD-ROM/DVD-ROM jest to wartość 5. Pozostałe wartości, za pomocą których identyfikujemy odpowiednie urządzenie - można znaleźć na stronie MSDN Library. Sekcja kodu programu wygląda następująco:


.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

;parametry:
;[EBP +14H] LPARAM
;[EBP +10H] WPARAM
;[EBP +0CH] MES
;[EBP +8] HWND

WNDPROC   PROC


PUSH  EBP
MOV  EBP,ESP
PUSH  EBX
PUSH  ESI
PUSH  EDI

CMP  DWORD  PTR  [EBP + 0CH],WM_CLOSE;komunikat związany ze zniszczeniem okna
JNE  NIEKONCZ

PUSH  0
PUSH  DWORD  PTR  [EBP+ 08H]
CALL  EndDialog@8
JMP  KONCZ


NIEKONCZ:

CMP  DWORD  PTR  [EBP + 0CH],WM_COMMAND;komunikat związany z kontrolkami
JNE  KONCZ

CMP  WORD  PTR  [EBP + 10H],IDC_BTN1  ;czy uruchamiamy wyszukiwanie napędów ;optycznych?
JNE  KONCZ

PUSH  0
PUSH  0
PUSH  LB_RESETCONTENT
PUSH  IDC_LST1
PUSH  DWORD  PTR  [EBP+ 08H]
CALL  SendDlgItemMessageA@20

MOV  EDX,65

Na początku sekcji standardowo tworzymy okno dialogowe i definiujemy funkcję obsługi okna. Za pomocą przycisku umieszczonego w dialogu, będziemy uruchamiać sekcję kodu odpowiedzialną za wypełnianie odpowiednimi literami listy, identyfikującymi nasze napędy CD-ROM/DVD-ROM. W pierwszym kroku zawsze czyścimy listę podając jako parametr LB_RESETCONTENT funkcji SendDlgItemMessageA@20. Do rejestru EDX kopiujemy wartość 65 - kod ASCII litery A . Od niej zaczynamy przeszukiwanie, zwiększając ją w każdym przebiegu pętli i uzyskując tym samym kolejne kody ASCII dużych liter:


PETLA:

PUSH  EDX
MOV   APOS,DL

PUSH  OFFSET APOS
CALL  GetDriveTypeA@4

CMP  EAX,5
JNE   OMIN

PUSH  OFFSET  APOS
PUSH  0
PUSH  LB_ADDSTRING
PUSH  IDC_LST1
PUSH  DWORD  PTR  [EBP+ 08H]
CALL  SendDlgItemMessageA@20

OMIN:

POP  EDX

CMP  EDX,91
JE  KONCZ

INC  EDX

JMP  PETLA

KONCZ:

FINISH:

XOR  EAX,EAX

POP  EDI
POP  ESI
POP  EBX
POP  EBP
RET
WNDPROC  ENDP

END Start

Przykładowe wywołanie programu przedstawione jest na rysunku poniżej:

Nie można wyświetlić obrazu
Rys.1. Przykładowe wywołanie programu .

Pełny kod programu przedstawiony jest na poniższym listingu:


.586 ;typ instrukcji procesora

.MODEL FLAT,STDCALL

includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

IDC_BTN1      EQU   101

IDC_LST1      EQU   102


LB_ADDSTRING                  EQU   180h
LB_RESETCONTENT               EQU   184h
WM_INITDIALOG                 EQU   110h
WM_CLOSE                      EQU   10h
WM_COMMAND                    EQU   111h

EXTERN lstrcpyA@8:NEAR

EXTERN lstrcatA@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


.DATA?
HINST         DD    ?

.DATA
PA            DB   'IDD_DLG1',   0 ;nazwa dialogu
APOS          DB    "?:\",   0
BUFER         DB    40  DUP (0)
.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

;parametry:
;[EBP +14H] LPARAM
;[EBP +10H] WPARAM
;[EBP +0CH] MES
;[EBP +8] HWND

WNDPROC   PROC


PUSH  EBP
MOV  EBP,ESP
PUSH  EBX
PUSH  ESI
PUSH  EDI

CMP  DWORD  PTR  [EBP + 0CH],WM_CLOSE;komunikat związany ze zniszczeniem okna
JNE  NIEKONCZ

PUSH  0
PUSH  DWORD  PTR  [EBP+ 08H]
CALL  EndDialog@8
JMP  KONCZ


NIEKONCZ:

CMP  DWORD  PTR  [EBP + 0CH],WM_COMMAND;komunikat związany z kontrolkami
JNE  KONCZ

CMP  WORD  PTR  [EBP + 10H],IDC_BTN1  ;czy uruchamiamy wyszukiwanie napędów ;optycznych?
JNE  KONCZ

PUSH  0
PUSH  0
PUSH  LB_RESETCONTENT
PUSH  IDC_LST1
PUSH  DWORD  PTR  [EBP+ 08H]
CALL  SendDlgItemMessageA@20

MOV  EDX,65

PETLA:

PUSH  EDX
MOV   APOS,DL

PUSH  OFFSET APOS
CALL  GetDriveTypeA@4

CMP  EAX,5
JNE   OMIN

PUSH  OFFSET  APOS
PUSH  0
PUSH  LB_ADDSTRING
PUSH  IDC_LST1
PUSH  DWORD  PTR  [EBP+ 08H]
CALL  SendDlgItemMessageA@20

OMIN:

POP  EDX

CMP  EDX,91
JE  KONCZ

INC  EDX

JMP  PETLA

KONCZ:

FINISH:

XOR  EAX,EAX

POP  EDI
POP  ESI
POP  EBX
POP  EBP
RET
WNDPROC  ENDP

END Start

Pobierz kod

Plik .rc programu wygląda następująco:


#include "..\include\resource.h"

#define IDC_BTN1 101
#define IDC_LST1 102
#define IDC_STC1 1001


IDD_DLG1 DIALOGEX 0,10,229,145
CAPTION "Urządzenia"
FONT 8,"MS Sans Serif", 0, 0, 0
STYLE  WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX
BEGIN
  CONTROL "Wyświetl",IDC_BTN1,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,84,99,54,15
  CONTROL "",IDC_LST1,"ListBox",WS_CHILD|WS_VISIBLE|WS_TABSTOP
|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS|LBS_NOTIFY,85,30,54,63,WS_EX_CLIENTEDGE
  CONTROL "Napędy optyczne:",IDC_STC1,"Static",WS_CHILD|WS_VISIBLE,84,12,75,9
END

Pobierz kod

Ćwiczenie 12

Zmodyfikować kod przykładu tak, aby program dodatkowo wyświetlał także litery wszystkich dysków twardych i partycji. Przykładowe wywołanie programu z jednym dyskiem twardym podzielonym na dwie partycje: C:\ i D:\, przedstawiono na rysunku poniżej - Rys.2.

Pobierz szablon

Nie można wyświetlić obrazu
Rys.2. Interfejs programu.

<Poprzednia lekcjaQuiz>