Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [ 53 ] 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

Нижеприведенная профамма - это каркас DLL. Каждая DLL должна иметь стартовую функцию. Windows вызывает эту функцию каждый раз, когда DLL подключается к процессу и отключается от него (если быть более точным, в случае создания и за, вершения очередной нити выполнения профаммы) с целью инициализации внуфенннх сфуктур данных.

TestDll.asm

.386

.model flat,stdcall option casemaprnone

include \masm32\include\windows.inc include \masm32\include\user32.inc include lib \masm3 2\lib\kernel32.lib include \masm32\include\kernel32.inc includelib \masm32\lib\user3 2.1ib

. data

. code

DllEntry proc hInstDLL:HbNSTANCE, reason:DWORD, reservedl:DWORD mov eax,TRUE

DllEntry Endp

TestFunction proc param:DWORD mov eax, param ret

TestFunction endp

End DllEntry

TestDU . inc TestFunction proc param:DWORD

TestDll.def

LIBRARY TestDll EXPORTS TestFunction

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

hInstDLL - это описатель модуля DLL. Вам следует сохранить это значение, посколь- оно понадобится для работы библиотеки

reason - ситуация, в которой проиходит поключение/отключение библиотеки, -(ожет иметь одно из следующих четырех значений, определенных в файле windows.inc.

DLLPROCESSATTACH - DLL получает это значение, когда впервые зафужается в адресное просфанство процесса. Вы можете использовать эту возможность для того, чтобы осуществить инициализацию.

DLLPROCESSDETACK - DLL получает это значение, когда выфужается из адресного просфанства процесса. Вы можете использовать эту возможность для того, чтобы освободить память, закрыть открытые файлы и т. д.

DLLTHREADATTACK - DLL получает это значение, когда процесс создает новую нить.

DLL THREAD DETACK - DLL получает это значение, когда нить в процессе уничтожается.

Признаком успешной инициализации библиотеки является возвращение стартовой функцией значения TRUE в регисфс еах. Если вы возвратите FALSE, DLL не будет зафужена. Например, если ваш инициализационный код должен зарезервировать память и он не может это сделать, стартовой функции следует возвратить FALSE, чтобы показать, что DLL не может запуститься.

Вы можете поместить ваши функции в DLL следом за стартовой функцией или до нее. Но если вы хотите, чтобы их можно было вызвать из других профамм, вы должны поместить их имена в спис1<е экспорта в файле установок модуля (см. файл TestDll.def).

Обычно в первой сфоке этого файла должна быть сфока с ключевым словом LIBRARY, которое определяет модуль DLL. Раздел экспорта, задаваемый ключевым словом EXPORTS, сообщает линкеру, какие функции в DLL экспортируются для создания файла с расширением .lib - библиотеки экспорта. В нашем примере нужно, чтобы другие модули могли вызывать TestFunction, поэтому мы указываем здесь ее имя.

Наша тестовая экспортируемая функция получает в качестве парамефа значение двойного слова и в качестве подтверждения своей работоспособности возвращает его в виде результата (в регисфе еах).

5.5. Разработка приложения

вычисления контрольных сумм

5.5.1. Интерфейс пользователя

в заключение нашего небольшого экскурса в профаммйрование на языке ассемблера для Windows рассмофим профамму, осуществляющую вычисление конфольной суммы, задаваемой пользователем сфоки по алгоритму MD5 из библиотеки Microsoft Crypto




Md5.asm

.386

. model

flat,stdcall

include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib kernel32.1ib include \masm32\include\user32.inc includelib user32.1ib

file exit

i dm

help about

idd"

"child DLG

"input edit

1000

IDC"

"output edit

1001

key edit

1002

idc"

go button

1008

"exit button

1009

. data

LibName DllNotFound Funct ionName FunctionNotFound found",0

windowt itle class name

about title

db "mscapit.dll",0 db "Cannot load library", 0 db "TestFunction", 0

db "TestFunction function

db MD5 hash calculator,0 db mscapit , 0

db About...,(

Глава

about string

.data?

hinst

message class struct openfilename

main win handle child dlg handle

hLib

TestFunction enc dec

result buffer

. code

db MD5 hash ca1culator,13,10,13,10 db (c) 2003 by my,0

dd ?

MSG О WNDCLASS о OPENFILENAME О

dd ? dd ?

dd ?

dd ? dd ? db 512 dup

ChildDlgProc proc stdcall, e@wparam:dword, @@Ipaгаш:dword

pushad

mov eax, [@ @wmsg]

cmp eax,WM INITDIALOG je Initialize

cmp eax,WM COMMAND jne Done Not Handled

Handle Command;

mov eax,@ @wparam

cmp ax,IDC GO BUTTON je go button

cmp ax,IDC EXIT BUTTON je Exit Button

@@hwnd:dword, @@wmsg:dword,

jmp Initialize:

Done Not Handled

API. В ней будет продемонстрирована техника "ручного" связывания с динамичес. загружаемой библиотекой, а также реализован диалоговый интерфейс пользовэтр " посредством оконных средств GUI ОС Windows. "

Для дальнейшего обсуждения необходимо в среде RadASM подготовить 2 проект-файль! исходных кодов представлены ниже. Один проект представляет собой диалого вую оболочку и создается мастером проектов как приложение Win32App с именем riids и, соответственно, файлами mdS.asm, indS.rc, mdS.def; второй проект - динамически за гружаемая библиотека (D11 Project) с именем mscapit и файлами mscapit.asm, mscapit.def Следует обратить особое внимание на название проекта DLL и соответствующий резуль! тирующий файл mscapit.dll, поскольку именно это имя используется в диалоговой про-фамме при "ручном" связывании.



Done Handled

Exit Button:

invoke PostQuitMessage,0

Done Handled: popad

mov eax,l ret

Done Not Handled: popad

xor eax,eax ret

ChildDlgProc endp START:

invoke LoadLibrary,addr LibName

.if eax==NULL i nvoke window title,MB OK

jmp exit

MessageBox,NULL,addr

DUNotFound, addr

.else

mov hLib,eax

invoke GetProcAddress,hLib,addr FunctionName

.if eax==NULL

invoke MessageBox,NULL,addr FunctionNotFound,addr

window title,MB 0K

jmp end loop else

mov [TestFunction],eax

. endi f

.endif

invoke GetModuleHandle,0

mov [hinst],eax

mov [class struct.style],CS HREDRAW or CS VREDRAW mov [class struct.IpfnWndProc],offset WindowProc mov [class struct.cbClsExtra] , 0 mov [class struct.cbWndExtra],0 mov [class struct.hinstance],eax

. invoke Loadlcon,0,IDI APPLICATION mov [class struct.hicon],eax

invoke LoadCursor,0,IDC ARROW mov [class struct.hCursor],eax

mov [class sbruct.hbrBackground],COLOR BACKGROUND+1

mov [class struct.IpszMenuName],offset class name mov [class struct.IpszClassName],offset class name

invoke RegisterClass,offset class struct

eax,WS CAPTION or WS SYSMENU or WS MINIMIZEBOX or

mov WS BORDER

invoke CreateWindowEx,0,offset class name,offset

window title,eax,CW USEDEFAULT,CW USEDEFAULT,4 20,140,0,0,hInst,0 mov [main win handle],eax

invoke

CreateDialogParam,[hInst],IDD CHILD DLG,[main win handle],offse t -hildDlgProc,0

or eax,eax

jz end loop

[child dlg handle],eax

jmp Done Handled go button:

invoke GetDlgltera,[chiId dlg handle],IDC INPUT EDIT

invoke GetWindowText,eax,offset resu1t buffer,256

mov ebx, offset result buffer

add ebx,eax

mov byte ptr [ebx],0

push offset result buffer call [TestFunction]

.if eax==NULL

invoke GetDlgltem,[child dlg handle],IDC OUTPUT EDIT invoke SetWindowText,eax,offset resu1t buffer



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [ 53 ] 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88