You are on page 1of 24

Лабораторна робота №4

1. Основні теоретичні відомості

Функції WinAPI забезпечують спрощену взаємодію та розподіл ресурсів


між процесами. Механізм взаємодії між процесами називається міжпроцесовою
взаємодією (Interprocess Communication - IPC), механізми, котрі забезпечують
синхронізацію процесів та потоків називають механізмами синхронізації
процесів (Interprocess Syncronization).
Зазвичай, програми, котрі взаємодіють між собою, поділяють на програми
- клієнти та програми - сервери. Клієнт – програма вимагає обслуговування
сервер - програмою. Сервер – програма відповідає на відповідні запити програми
– клієнта.

1.1 Механізми міжпроцесової взаємодії

Функції WinAPI підтримують наступні механізми міжпроцесової


взаємоїді IPC:
• Clipboard
• Component Object Model (COM)
• Dynamic Data Exchange (DDE)
• File Mapping
• Mailslot
• Pipe
• Remote Procedure Call (RPC)
• Windows Sockets
• WM_COPYDATA
• Atom

Clipboard – буфер. Цей механізм міжпросесової взаємодії використовується


для копіювання та вставки текстової чи графічної інформації.
COM – це протокол, котрий з’єднує один програмний модуль з іншим. COM
є потужною інтеграційною технологією, котра дозволяє складати різні
частини програмного забезпечення в одну програму.
DDE - це протокол, котрий дає змогу програмам обмінюватись даними різних
форматів.

20
File Mapping – даний механізм дає можливість процесові користуватись
файлом на диску та як би він був занесений у пам’ять, в адресний простір
даного процесу.
Mailslot – цей механізм забезпечує однонаправлену міжпроцесову взаємодію.
Будь – який процес, котрий створить mailslot стає mailslot – сервером. Інший
процес, mailslot – клієнт, передає інформацію серверу, вписуючи її у mailslot
сервера.
Pipe – канал. Існує однонаправлений механізм передачі даних через канал,
використовуючи анонімні канали та двонаправлений – використовуючи
іменовані канали.
RPC – віддалений виклик процедур. Даний механізм дозволяє керувати
процесами на віддалених комп’ютерах.
Windows Sockets – незалежний від протоколу інтерфейс передачі даних.
WM_COPYDATA – повідомлення, котре шле Windows у випадку передачі
даних між процесами. Дані передаються за допомогою структури
COPYDATASTRUCT. Один процес записує дані у структуру
COPYDATASTRUCT, а інший зчитує їх.
Atom – це число або стрічка, котрі повертаються програмі після того, як вона
зробила запис у загальній таблиці атомів. Люба програма маючи atom може
мати доступ до відповідного запису у таблиці атомів. Запис у таблиці атомів
називається ім’ям атома. Бувають глобальні та локальні таблиці атомів.

1.2 Механізми синхронізації процесів та потоків

Функції WinAPI також забезпечують синхронізацію процесів та потоків


(Interprocess Syncronization).
Для синхронізації доступу декількох програм до одного ресурсу
використовують об’єкти синхронізації (synchronization objects) та очікуючі
функції (wait functions).
Також існують інші механізми синхронізації:
• Взаємо – виключний ввід і вивід (overlapped input and output)
• Асинхронний виклик процедур (asynchronous procedure calls)
• Об’єкти критичної секції (critical section objects)
• Блокований змінний доступ (interlocked variable access)

1.3 Об’єкти синхронізації

Об’єкти синхронізації - це такі об’єкти, дескриптор котрих може


використовуватись в одній з функцій очікування для корегування виконання
багатьох потоків. Більше ніж один процес може мати дескриптор до одного і того
ж об’єкту синхронізації, таким чином роблячи міжпроцесову синхронізацію
можливою.

21
Дані типи об’єктів використовуються виключно для синхронізації процесів та
потоків:
• Event – повідомляє один або декілька очікуючих процесів/потоків про те
що подія відбулась.
• Mutex – може бути використовуваним тільки одним процесом/потоком
для доступу до розділеного ресурсу.
• Semaphore – вміщує лічильник від нуля до якогось максимального
значення. Даний лічильник містить кількість процесів/потоків котрі
одночасно хочуть мати доступ до розділеного ресурсу.
• Waitable timer – повідомляє один або декілька процесів/потоків про
завершення визначеного часу.
Наступні об’єкти також можуть використовуватись для синхронізації
процесів/потоків:
• Change notification – даний об’єкт створюється функцією
FindFirstChangeNotification. Стан даного об’єкту змінюється в
сигналізований, коли відбувається визначений тип змін.
• Console input – даний об’єкт створюється під час створення консолі. Стан
даного об’єкту змінюється в сигналізований, коли є ще не прочитаний ввід
в буфері вводу консолі. У випадку, коли буфер вводу консолі пустий - стан
об’єкту змінюється в несигналізований.
• Job - даний об’єкт створюється під час виклику функції CreateJobObject.
Стан даного об’єкту змінюється в сигналізований під час завершення всіх
процесів даного об’єкту або у випадку закінчення ліміту часу вказаного
для даного процесу.
• Process - даний об’єкт створюється під час виклику функції CreateProcess.
Поки процес виконується, його об’єкт у несигналізованому стані. Під час
завершення процесу об’єкт встановлюється у сигналізований стан.
• Thread - даний об’єкт створюється під час виклику функції CreateThread
або CreateRemoteThread. Під час виконання процесу його об’єкт у
несигналізованому стані. Коли процес завершується, його об’єкт
встановлюється у сигналізований стан.

1.4 Очікуючі функції

Очікуючі функції – це функції, котрі не передають керування іншій


частині програми поки не виконається вказаний в них критерій, або поки не
завершиться час очікування на даний критерій. Вказаний критерій визначає тип
функції.
Існують три типи очікуючих функцій:
• Одно – об’єктні (single-object)
• Багато – об’єктні (multiple-object)

22
• Функції застереження (alertable)
До одно-об’єктних відносять такі очікуючі функції: SignalObjectAndWait,
WaitForSingleObjet (див. додаток 1,2), WaitForSingleObjectEx. Дані функції
мають два критерії очікування: об'єкт, якого очікують завершив своє виконання
та у випадку коли закінчився вказаний час очікування.
До багато – об’єкних відносять: WaitForMultipleObjects,
WaitForMultipleObjectsEx, MsgWaitForMultipleObjects,
MsgWaitForMultipleObjectsEx. Дані функції мають два критерії очікування:
об'єкт або об’єкти, яких очікують завершили своє виконання та у випадку коли
закінчився вказаний час очікування.
До функцій застереження відносять: MsgWaitForMultipleObjects,
SignalObjectAndWait, WaitForMultipleObjectsEx, WaitForSingleObjectEx. Дані
функції відрізняються від попередніх тим, що вони можуть виконувати
застережені операції очікування.

1.5 Створення атома

Атом - це число або стрічка, котрі повертаються програмі після того, як


вона зробила запис у загальній таблиці атомів. В цій таблиці розміщуються
ідентифікатори (атоми) та стрічки (імена атомів).
Створити атом можна за допомогою функції AddAtom, створити глобальний атом
можна за допомогою функції GlobalAddAtom (Див. додаток 3). Функція, котра
створює атом, тобто заносить певну стрічку у таблицю атомів, отримує
ідентифікатор (атом). Знаючи цей атом люба функція може мати доступ до
відповідного запису у таблиці атомів.
Знищити атом можна за допомогою функцій DeleteAtom та
GlobalDeleteAtom.
Отримати запис з таблиці атомів можна за допомогою функції
GetAtomName та GlobalGetAtomName.
Щоб отримати ідентифікатор (атом), знаючи ім’я атома можна використати
функції FindAtom та GlobalFindAtom (див. додаток 4). Будь – яка програма, може
за глобальним атомом дістати відповідний запис у таблиці атомів. Локальний
атом дійсний тільки в межах однієї програми.

1.6 Створення каналу

Pipe – це канал з двома кінцями. Канал можна використовувати для обміну


даними між двома різними процесами, або всередині одного процесу.
Існує два види каналів: анонімні та іменовані. Створити анонімний канал
можна за допомогою функції CreatePipe. (див. додаток 5). Створити іменований
канал можна за допомогою функції CreateNamedPipe (див. додаток 6).
Канали бувають однонаправлені, або двонаправлені. В однонаправленому
каналі дані передаються в одному напрямку, в двонаправленому каналі дані

23
можуть передаватись в обох напрямках. Анонімний канал завжди має один
напрямок. Іменований канал може бути як однонаправлений так і
двонаправлений.
Зазвичай іменовані канали використовуються в мережевому оточенні – де
сервер може контактувати з декількома клієнтами (див. додаток 7, 8).
Анонімний канал використовується для зв’язку між батьківським та
дочірнім процесом. Анонімний канал найбільш часто використовується під час
взаємодії з консольною програмою, тобто програмою, котра свій ввід/вивід
здійснює через консоль (Див. додаток 9, 10). Так можна перенаправити
ввід/вивід консольної програми у вікно власної програми.
Оскільки анонімний канал одно направлений, тобто з нього можна або
тільки зчитувати дані, або записувати, то відкритим може бути тільки один
кінець каналу.
Після створення каналу користувач отримує два дескриптори на запис та
зчитування з каналу. Один із них потрібно закрити, використовуючи функцію
CloseHandle.

2. Хід роботи

1. Ознайомитись з основними теоретичними відомостями даної лабораторної


роботи.
2. Ознайомитись з приведеними в додатках прикладами програм.
3. Ознайомитись з додатковими джерелами, приведеними в п. 6 (Література).
4. Затвердити номер індивідуального завдання у викладача.
5. Виконати завдання згідно з номером.

3. Зміст звіту

Звіт повинен містити:


- титульну сторінку;
- мету роботи;
- завдання, робочий варіант тексту програми, результат виконання
програми;
- короткі висновки по проведеній роботі.

4. Завдання

Розробити на мові асемблер для ОС Windows програму, використовуючи


пакет MASM32. Результат виводиться на екран.
На 60 балів одна програма має створювати глобальний атом, який має
містити П.І.П. Інша програма має виводити атом (ідентифікатор у таблиці
атомів) у вікно повідомлення вказаного типу:

24
Тип вікна повідомлення – згідно варіанту:
№ № Тип
1 2 MB_ABORTRETRYIGNORE
3 4 MB_OK
5 6 MB_OKCANCEL
7 8 MB_RETRYCANCEL
9 10 MB_YESNO
11 12 MB_YESNOCANCEL
13 14 MB_ICONEXCLAMATION
15 16 MB_ICONWARNING
17 18 MB_ICONINFORMATION
19 20 MB_ICONASTERISK
21 22 MB_ICONQUESTION
23 24 MB_ICONSTOP
25 26 MB_ICONERROR
27 28 MB_ICONHAND

На 75 балів програма має перенаправити консольний вивід у вікно


повідомлення, використовуючи анонімні канали. Консольна програма має
виводити П.І.П та групу. Тип вікна повідомлення вибрати з завдання на 60 балів
згідно варіанту.

На 95 балів потрібно розробити програму згідно варіанту. Консольні


програми розробляються в MASM32.
1. Розробити програму, котра перенаправляє вивід поточного дня тижня
(Понеділок, …) з консольної програми у вікно повідомлення за
допомогою анонімного пайпу.
2. Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточну директорію розміщення системних файлів ОС
Windows. Результат вивести у вікно повідомлення.
3. Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточні
координати курсору, інша має зчитати цей запис і вивести його у вікні
повідомлення .
4. Розробити програму, котра перенаправляє вивід поточного часу
(00:00:00) з консольної програми у вікно повідомлення за допомогою
анонімного пайпу.

25
5. Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточний
день тижня (Понеділок,…), інша має зчитати цей запис і вивести його у
вікні повідомлення .
6. Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточне
ім’я користувача, інша має зчитати цей запис і вивести його у вікні
повідомлення .
7. Розробити програму, котра перенаправляє вивід поточного імені
комп’ютера з консольної програми у вікно повідомлення за допомогою
анонімного пайпу.
8. Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточний час (00:00:00). Результат вивести у вікно
повідомлення.
9. Розробити програму, котра перенаправляє вивід поточного місяця
(Січень,…) з консольної програми у вікно повідомлення за допомогою
анонімного пайпу
10.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточні координати курсору. Результат вивести у вікно
повідомлення.
11.Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточний
місяць (Січень,…) інша має зчитати цей запис і вивести його у вікні
повідомлення .
12.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточний місяць (Січень,..). Результат вивести у вікно
повідомлення.
13.Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточне
ім’я комп’ютера, інша має зчитати цей запис і вивести його у вікні
повідомлення .
14.Розробити програму, котра перенаправляє вивід поточної директорії
розміщення ОС Windows з консольної програми у вікно повідомлення за
допомогою анонімного пайпу.
15.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточне ім’я комп’ютера. Результат вивести у вікно
повідомлення.
16.Розробити програму, котра перенаправляє вивід поточних координат
курсору з консольної програми у вікно повідомлення за допомогою
анонімного пайпу

26
17.Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточний
час (00:00:00), інша має зчитати цей запис і вивести його у вікні
повідомлення .
18.Розробити програму, котра перенаправляє вивід поточної директорії
розміщення системних файлів ОС Windows з консольної програми у
вікно повідомлення за допомогою анонімного пайпу.
19.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточний місяць (Січень,..). Результат вивести у вікно
повідомлення.
20.Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточну
дату (00.00.00), інша має зчитати цей запис і вивести його у вікні
повідомлення .
21.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточну дату (00.00.00). Результат вивести у вікно
повідомлення.
22.Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточну
директорію розміщення ОС Windows, інша має зчитати цей запис і
вивести його у вікні повідомлення .
23.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточний день тижня (Понеділок,…). Результат вивести у
вікно повідомлення.
24.Використовуючи синхронізацію процесів розробити програми, котрі
взаємодіють через файл. Одна програма має записувати у файл поточну
директорію розміщення системних файлів ОС Windows, інша має
зчитати цей запис і вивести його у вікні повідомлення .
25.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточне ім’я користувача. Результат вивести у вікно
повідомлення.
26.Розробити програму, котра перенаправляє вивід поточної дати (00.00.00)
з консольної програми у вікно повідомлення за допомогою анонімного
пайпу.
27.Розробити програми, котрі за допомогою іменованих каналів передають
між собою поточну директорію розміщення ОС Windows. Результат
вивести у вікно повідомлення.
28.Розробити програму, котра перенаправляє вивід поточного імені
користувача з консольної програми у вікно повідомлення за допомогою
анонімного пайпу.

27
5. Контрольні запитання

1. Назвати основні механізми міжпроцесової взаємодії.


2. Назвати основні механізми синхронізації процесів та потоків.
3. Які об’єкти використовують для синхронізації процесів та потоків?.
4. Назвати основні типи очікуючих функцій.
5. Що таке атом?
6. Як компонувати та транслювати консольні програми в MASM32?

6.Список використаної літератури

1. Help по функціях API - www.nan32asm.cjb.net


2. Microsoft Windows Help - Win32 Programmers Reference
3. Технічна документація Microsoft - MSDN

28
1
Текст програми синхронізації спільного доступу до файлу.
Дана програма створює семафор та файл і чекає на під’єднання іншої програми.
----------------------------------
; Sem_File.asm
;----------------------------------
.386
.model flat, stdcall option
casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

wsprintfA PROTO C :DWORD, :VARARG


wsprintf equ <wsprintfA>

.data
MsgCaption db "Повiдомлення!",0
ErrorCreateSem db "Помилка створення семафору",0
ErrorCreateFile db "Помилка створення файлу",0
ErrorWriteFile db "Помилка запису у файл",0
Message db "Повiдомлення для файлу",0
Success db "Успiшне завершення програми",0
TimeOut db "Завершився час очiкування",0
ErrorRelease db "Помилка знищення семафору",0
buffer db 256 dup (?) parameter db "%u"
check DWORD 0 written DWORD 0 sName
db "MySemaphore",0 fName db
"C:\Temp\MYFILE.TXT",0 .data? hSemaphore HANDLE
? hFile HANDLE ?
.code
start
:

invoke CreateSemaphore, NULL, 0, 1, addr sName


.if eax==0 invoke
MessageBox, NULL,addr
ErrorCreateSem,\ addr MsgCaption, MB_OK
jmp exit
.endif
mov hSemaphore, eax

invoke CreateFile, addr fName,\


GENERIC_READ or GENERIC_WRITE,\
FILE_SHARE_READ, NULL, CREATE_ALWAYS,\
FILE_ATTRIBUTE_NORMAL,NULL
.if eax==INVALID_HANDLE_VALUE
invoke GetLastError invoke
wsprintf,addr buffer,addr
parameter,eax
invoke MessageBox, NULL,addr
ErrorCreateFile, \
addr buffer, MB_OK
invoke ReleaseSemaphore, hSemaphore, 1, NULL
jmp exit
.endif
29
Додаток
mov hFile, eax

invoke WriteFile, hFile, addr Message, 23,\


addr written, NULL
.if eax==0
invoke GetLastError
invoke wsprintf,addr buffer,addr
parameter,eax
invoke MessageBox, NULL,addr
ErrorWriteFile,\
addr buffer, MB_OK
invoke ReleaseSemaphore, hSemaphore, 1, NULL
jmp exit
.endif

invoke CloseHandle, hFile


invoke WaitForSingleObject, hSemaphore, 10000
.if eax==WAIT_OBJECT_0
invoke MessageBox, NULL,addr Success,\
addr MsgCaption, MB_OK
invoke ReleaseSemaphore, hSemaphore, 1, NULL
jmp exit
.endif

.if eax==WAIT_TIMEOUT
invoke MessageBox, NULL, addr TimeOut, \
addr MsgCaption, MB_OK
invoke ReleaseSemaphore, hSemaphore, 1, NULL
.if eax==0
invoke GetLastError
invoke
wsprintf,addr buffer,\
addr parameter,eax
invoke MessageBox, NULL, addr
ErrorRelease,\ addr buffer, MB_OK
jmp exit
.endif
jmp exit
.endif
exit:
invoke ExitProcess,NULL

end start

Результат виконання програми:

Дана програма створює семафор та файл, записує у


файл інформацію, очікує поки інша програма не прочитає даний файл і не
знищить семафор .

30
У випадку успішного створення семафору і файлу, та зчитування з
файлу, результат має виглядати так:

2
Текст програми, котра відкриває семафор, зчитує дані з файлу та знищує
семафор.
;----------------------------------
; Sem_Read.asm ;
.386
.model flat, stdcall option
casemap:none
include \masm32\include\windows.inc include
\masm32\include\kernel32.inc include
\masm32\include\user32.inc includelib
\masm32\lib\user32.lib includelib
\masm32\lib\kernel32.lib ;wsprintfA PROTO C
:DWORD, :VARARG ;wsprintf equ <wsprintfA>

.data
MsgCaption db "Повiдомлення!",0
ErrorOpenSem db "Помилка вiдкриття семафору",0
ErrorCreateFile db "Помилка створення файлу",0
ErrorReadFile db "Помилка зчитування з файл",0
ErrorReleaseSem db "Помилка знищення семафору",0
;buffer db 256 dup (?)
;parameter db "%u" check
DWORD 0 Readed DWORD 0 fBuffer
db 25 dup (0) sName db
"MySemaphore",0 fName db
"C:\Temp\MYFILE.TXT",0
.data? hSemaphore
HANDLE ? hFile
HANDLE ?
.code start:
invoke OpenSemaphore, SEMAPHORE_ALL_ACCESS, TRUE, addr sName
.if eax==0
invoke MessageBox, NULL,addr ErrorOpenSem, addr MsgCaption, MB_OK
jmp exit
.endif
mov hSemaphore, eax
invoke CreateFile, addr fName, GENERIC_READ or GENERIC_WRITE,\
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL
.if eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL,addr ErrorCreateFile, addr MsgCaption, MB_OK
invoke ReleaseSemaphore, hSemaphore, 1, NULL
jmp exit
.endif
mov hFile, eax
invoke ReadFile, hFile, addr fBuffer, 25,addr Readed, NULL
.if eax==0
invoke MessageBox, NULL,addr ErrorReadFile, addr MsgCaption, MB_OK
invoke ReleaseSemaphore, hSemaphore, 1, NULL
jmp exit
.endif
invoke MessageBox, NULL,addr fBuffer, addr MsgCaption, MB_OK

31
Додаток
invoke CloseHandle, hFile invoke
ReleaseSemaphore, hSemaphore, 1, NULL
.if eax==0
invoke MessageBox, NULL,addr ErrorReleaseSem, addr MsgCaption, MB_OK
jmp exit
.endif
exit:
invoke ExitProcess,NULL
end start

32
Додаток
3
Текст програми створення глобального атома.
;----------------------------------
; AddAtom.asm
;----------------------------------
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
MsgCaption db "Повiдомлення!",0
MyAtom DWORD 0
AtomName db "Привіт атом",0
ErrorAddAtom db "Неможливо створити атом",0
Success db "Атом успiшно створено",0

.code
start
:

invoke GlobalAddAtom, addr AtomName


.if eax==0
invoke MessageBox, NULL,addr ErrorAddAtom,\
addr MsgCaption, MB_OK
jmp exit
.endif
mov MyAtom, eax
invoke MessageBox, NULL,addr Success,\ addr
MsgCaption, MB_OK
exit:
invoke ExitProcess,NULL
end start

Результат виконання програми:

Опис програми:
Дана програма створює за допомогою функції GlobalAddAtom глобальний атом,
тобто атом, котрий можуть “бачити” інші програми.
Для того, щоб звернутися до глобально атома (дізнатись його ім’я), потрібно
використовувати функцію GlobalGetAtomName, якій потрібно передати
дескриптор, котрий був отриманий після створення атома. Цей дескриптор
може наслідуватись для використання іншими програмами. Для того, щоб
дізнатись значення атома (ідентифікатор імені атома в таблиці атомів) потрібно
використовувати функцію GlobalGetAtom, котрій передається параметром ім’я
атома.
33
Додаток
4
Текст програми відкриття глобального атома.
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

wsprintfA PROTO C :DWORD, :VARARG


wsprintf equ <wsprintfA>

.data
MsgCaption db "Повiдомлення!",0
MyAtom DWORD 0
AtomName db "Привіт Атом",0
MyAtomName db "Iм’я атома",0
ErrorFindAtom db "Атома з таким iм'ям не iснує",0
ErrorDA db "Помилка знищення атома",0
Success db "Атом успiшно знайдено",0
SuccessDA db "Aтом успiшно знищено",0
AtomCaption db "Значення атома в таблицi атомiв",0
buffer db 256 dup (?) parameter db "%u"

.code
start
:

invoke GlobalFindAtom,addr AtomName


.if eax==0
invoke MessageBox, NULL,addr ErrorFindAtom, addr
MsgCaption, MB_OK
jmp exit
.endif
mov MyAtom, eax invoke MessageBox, NULL,addr
Success, addr MsgCaption, MB_OK invoke wsprintf,addr
buffer,addr parameter,MyAtom invoke MessageBox, NULL, addr
buffer, addr AtomCaption, MB_OK invoke
GlobalGetAtomName, MyAtom,addr buffer,256 invoke
MessageBox, NULL ,addr buffer, addr MyAtomName,
MB_OK
invoke GlobalDeleteAtom, MyAtom
.if eax==0
invoke MessageBox,
NULL,addr SuccessDA,\ addr
MsgCaption, MB_OK
jmp exit
.endif
invoke MessageBox, NULL,addr ErrorDA, addr MsgCaption,
MB_OK exit:
invoke ExitProcess,NULL

end start

Результат виконання програми:

34
Додаток

5
Детальний опис функції створення анонімного каналу

CreatePipe proto pReadHandle:DWORD, \


pWriteHandle:DWORD, \
pPipeAttributes:DWORD, \ nBufferSize:DWORD
pReadHandle – це вказівник на змінну типу DWORD, котрий отримає дескриптор кінця читання
каналу.
pWriteHandle - це вказівник на змінну типу DWORD, котрий отримає дескриптор кінця запису
каналу.
pPipeAttributes – вказує на структуру SECURITY_ATTRIBUTES

Додаток 6
Детальний опис функції створення іменованого каналу
CreateNamedPipe proto lpName:DWORD,\ ; вказує на ім’я файлу
dwOpenMode:DWORD, \; режим відкриття каналу
dwPipeMode:DWORD, \ ; pipe-specific modes
nMaxInstances:DWORD,\;максимальна кількість екземплярів каналу
nOutBufferSize: DWORD, \;розмір буферу для виводу
nInBufferSize : DWORD,\ ;розмір буферу для вводу
nDefaultTimeOut : DWORD,\; час тривання екземпляра каналу
lpSecurityAttributes LPSECURITY_ATTRIBUTES <> ;вказівник на структуру безпеки

Параметр lpName вказує на стрічку, котра завершується нулем і має наступний вигляд:
\\.\pipe\pipename. Ім’я каналу не повинно перевищувати 256 символів.
Параметр dwOpenMode має наступні типи:
PIPE_ACCESS_DUPLEX – канал має двонаправлений тип. Клієнт та сервер можуть читати та
записувати з каналу. Цей режим дає серверу такий самий як GENERIC_READ | GENERIC_WRITE
доступ до каналу. Клієнт може встановити параметри GENERIC_READ або GENERIC_WRITE, або
обидва, під час під’єднання до каналу функцією CreateFile.
PIPE_ACCESS_INBOUND - Потік даних направлений тільки від клієнта до сервера. Цей
режим дає серверу такий самий доступ до каналу як GENERIC_READ. Клієнт – програма повинна
мати GENERIC_WRITE доступ до каналу..
PIPE_ACCESS_OUTBOUND – Потік даних напрямлений тільки від сервера до клієнта . Цей
режим дає серверу такий самий доступ до каналу як GENERIC_WRITE. Клієнт – програма повинна
мати GENERIC_READ доступ до каналу..
Параметр dwPipeMode визначає параметри запису, параметри очікування.
PIPE_TYPE_BYTE – Діні записуються у канал як потік байтів .
PIPE_TYPE_MESSAGE - Діні записуються у канал як потік повідомлень

35
Додаток
PIPE_WAIT - Встановлено режим очікування. В цьому режимі функції ReadFile, WriteFile, або
ConnectNamedPipe не виконуються поки є дані для зчитування, дані для запису або до каналу
під’єднаний клієнт.
PIPE_NOWAIT – Знято режим очікування.
Параметр nMaxInstances визначає максимальну кількість екземплярів каналу, може бути
встановленим у PIPE_UNLIMITED_INSTANCES – необмежена кількість екземплярів каналу.
Дана функція повертає дескриптор на екземпляр іменованого файлу програми- сервера. У
випадку помилки функція повертає INVALID_HANDLE_VALUE. За допомогою функції GetLastError
можна дізнатись номер помилки, по якому можна знайти причину її виникнення. Помилка
ERROR_INVALID_PARAMETER виникає у випадку коли параметр nMaxInstances є більшим ніж
PIPE_UNLIMITED_INSTANCES.
7
Текст програми створення сервера ,що отримує повідомлення від клієнт –
програми за допомогою іменованих каналів.
;----------------------------------
; Server.asm
;----------------------------------
.386
.model flat, stdcall option
casemap:none
include \masm32\include\windows.inc include
\masm32\include\kernel32.inc include
\masm32\include\user32.inc includelib
\masm32\lib\user32.lib includelib
\masm32\lib\kernel32.lib include
\masm32\include\masm32.inc includelib
\masm32\lib\masm32.lib

wsprintfA PROTO C :DWORD, :VARARG wsprintf


equ <wsprintfA>

.data
PIPE_TIMEOUT DWORD 0 fConnected
DWORD 0 dwThreadId DWORD 0
lpszPipename db
"\\.\pipe\mypipename",0 MsgCaption db
"Сервер - програма",0 ErrCreatePipe db
"Error create pipe",0
ErrPipeCount db "Error connect pipe",0
ErrCreateThread db "Error create thread", 0
chRequest db 256 dup(0) theEnter
db 0ah, 0dh, 0 buffer db 256 dup
(?) parameter db "%u" .data? hPipe
HANDLE ? hThread HANDLE ?

.const
BUFSIZE DWORD 256

.code
InstanceThread PROC Param:DWORD
LOCAL cbBytesRead:DWORD
mov eax, Param mov hPipe,
eax
invoke ReadFile, \
hPipe, \

36
Додаток
addr chRequest, \
BUFSIZE, \
addr cbBytesRead,\
NULL

invoke StdOut, addr chRequest


invoke StdOut, addr theEnter

invoke FlushFileBuffers, hPipe


invoke DisconnectNamedPipe, hPipe invoke
CloseHandle, hPipe

ret
InstanceThread ENDP

37
Додаток
start:
invoke SetConsoleTitle, addr MsgCaption
.while TRUE
invoke CreateNamedPipe,\
addr lpszPipename,\ ;PipeName
PIPE_ACCESS_DUPLEX, \ ;read access
PIPE_TYPE_MESSAGE + PIPE_READMODE_MESSAGE +
PIPE_WAIT,\
;blocking mode

PIPE_UNLIMITED_INSTANCES, \ ;max instances


BUFSIZE, \ ;output buffer
size
BUFSIZE, \ ;input buffer
size
PIPE_TIMEOUT,\ ;client time-out
NULL ;no security
atribute

mov hPipe,eax
.if hPipe==INVALID_HANDLE_VALUE
invoke StdOut,addr ErrCreatePipe
invoke StdOut, addr theEnter
.endif

invoke ConnectNamedPipe, hPipe, NULL


mov fConnected, eax

.if fConnected==ERROR_PIPE_CONNECTED
invoke StdOut, addr ErrPipeCount
invoke StdOut, addr theEnter
.break
.endif

.if fConnected != NULL


invoke CreateThread,\
NULL,\ ;No security attribute
0,\ ;Default stack size
addr InstanceThread,\ ;Addr thread proc
hPipe,\ ;Thread parameter
0, \ ;Not suspended
addr dwThreadId ;Returns thread ID
.if eax == INVALID_HANDLE_VALUE
invoke StdOut,addr ErrCreateThread
invoke StdOut,addr theEnter
.endif

.else
invoke CloseHandle ,hPipe
.endif
.endw
exit:
invoke ExitProcess,NULL
end start

38
Примітка: сервер – прграму потрібно лінкувати та транслювати як консольну програму. Windows 9x не підтримує іменованих каналів.
8
Текст клієнт - програми передачі повідомлення програмі - серверу.
;----------------------------------
; Client.asm
;----------------------------------
.386
.model flat, stdcall option
casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
wsprintfA PROTO C :DWORD, :VARARG wsprintf
equ <wsprintfA>
.data
cbWritten DWORD 0
MyLength DWORD 0 dwMode
DWORD 0
lpszPipename db "\\.\pipe\mypipename",0 MsgCaption
db "Message!",0
ErrOpenPipe db "Error oрen pipe", 0
ErrSetState db "Error set cannal state",0
ErrWriteFile db "Error write pipe",0
ErrCreateFile db "Error connect pipe",0
Message db "Hello from client to server program!",0
theTitle db "Дана програма вiдiшле програмi - серверу
повiдомлення ",0 buffer db 256 dup (?) parameter
db "%u" .data? hPipe DWORD ?
.code start:
invoke MessageBox, NULL, addr theTitle, addr MsgCaption, MB_OK
invoke CreateFile,\
addr lpszPipename,\ ;pipe name
GENERIC_WRITE, \ ;write access
0, ;no sharing
NULL, \ ;no security atribute
OPEN_EXISTING, \ ;open existing file
0, \ ;default attributes
NULL ;no template file
mov hPipe,eax
.if hPipe==INVALID_HANDLE_VALUE
invoke GetLastError
invoke wsprintf,addr buffer,addr parameter,eax
invoke MessageBox, NULL, addr ErrCreateFile,\
addr buffer,MB_ICONERROR + MB_OK
jmp exit
.endif

invoke WaitNamedPipe,addr lpszPipename,100


.if eax == 0
invoke MessageBox, NULL, addr ErrOpenPipe,\
addr MsgCaption,MB_ICONERROR + MB_OK
jmp exit

39
Додаток
.endif
mov eax,PIPE_READMODE_MESSAGE
mov dwMode,eax
invoke SetNamedPipeHandleState,\
hPipe,\
addr dwMode,\
NULL,\
NULL
.if eax == 0
invoke MessageBox, NULL, addr ErrSetState,\
addr MsgCaption,MB_ICONERROR + MB_OK
.endif
invoke lstrlen, addr Message
mov MyLength,eax
invoke WriteFile, \
hPipe, \
addr Message, \
MyLength,\
addr cbWritten,\
NULL
.if !eax
invoke GetLastError
invoke wsprintf,addr buffer,addr parameter,eax
invoke MessageBox, NULL, addr ErrWriteFile,\
addr buffer,MB_ICONERROR + MB_OK
.endif
invoke CloseHandle, hPipe
exit:
invoke
ExitProcess,NULL end
start

Результат виконання сервер –


програми:

Результат виконання клієнт -


програми:

Вид консольного вікна сервер –


програми після передачі йому
повідомлення від клієнт - програми:

Опис взаємодії сервер та клієнт – програми: Під час завантаження сервер –


програма створює іменований канал за допомогою функції CreateNamedPipe у
випадку успішного створення каналу, за допомогою функції ConnectNamedPipe,
програма буде очікувати на під’єднання до неї прграми – клієнта. У випадку
успішного під’єднання сервер - програма створює новий потік, котрий за
допомогою функції ReadFile буде зчитувати дані з каналу.
Клієнт - програма відкриває канал за допомогою функції CreateFile
використовуючи параметр OPEN_EXISTING, після успішного відкриття каналу,
40
клієнт – програма встановлює стан каналу та записує у нього відповідне
повідомлення, котре потрібно передати програмі - серверу.
9
Текст програми створення анонімного каналу
;----------------------------------- ;
Pipe.asm
;-----------------------------------

.386
.model flat, stdcall option
casemap:none
include \masm32\include\windows.inc include
\masm32\include\kernel32.inc include
\masm32\include\user32.inc includelib
\masm32\lib\user32.lib includelib
\masm32\lib\kernel32.lib
.data
sa SECURITY_ATTRIBUTES <>;
stinfo STARTUPINFO <>; pinfo
PROCESS_INFORMATION <>;
hPipeOutputRead DWORD
0 hPipeOutputWrite
DWORD 0
btest BOOL 0
bytesRead DWORD 0
dwNumberOfBytes DWORD 0
buffer db 256 dup(0)
data db "Hello World from pipe",0 CreatePipeError
db "Error during pipe creation",0 CreateProcError db "Error
during process creation",0
AppName db "Message",0
CommandLine db "console.exe",0
.code
start:
mov sa.nLength, SIZEOF SECURITY_ATTRIBUTES mov
sa.bInheritHandle, TRUE ;Дозвіл на наслідування
дескрипторів
mov sa.lpSecurityDescriptor, NULL

;Створюємо канал для стандартного пере направлення виводу


консольної
;програми
invoke CreatePipe,addr hPipeOutputRead, addr
hPipeOutputWrite,\
addr sa, NULL
.if eax==NULL
invoke MessageBox, 0, addr CreatePipeError, \
addr AppName, MB_ICONERROR + MB_OK
.else
;Встановлюємо нові параметри структури stinfo, котра
;відповідає за властивості створеного дочірнього процесу
mov stinfo.cb, sizeof stinfo mov stinfo.dwFlags,\
STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES
mov stinfo.wShowWindow, SW_HIDE ;Приховати вікно консолі
mov eax,hPipeOutputWrite

41
Додаток
mov stinfo.hStdOutput,eax; Робить дескриптор
каналу ;стандартним дескриптором виводу

invoke CreateProcess, NULL, addr CommandLine, \


NULL, NULL, TRUE, NULL, NULL, NULL, addr stinfo,addr
pinfo
.if eax==NULL invoke MessageBox,0,addr
CreateProcError,\ addr
AppName,MB_ICONERROR+MB_OK
.else
invoke CloseHandle,hPipeOutputWrite
.while TRUE
invoke RtlZeroMemory, addr buffer, 256;
;Обнулить буфер
invoke ReadFile,hPipeOutputRead, \
addr buffer,255,addr bytesRead,NULL
.if eax==NULL
.break
.endif

invoke MessageBox, 0, addr buffer, \


addr AppName, MB_OK
.endw
.endif

.endif
invoke CloseHandle, hPipeOutputRead
invoke ExitProcess,NULL
end
start

Результат виконання програми:


Вивід консольної програми console.exe
E:\masm32\Work\IPC\Pipe>Console.exe
Laboratory work for KSN students

Перенаправлений у канал вивід консольної програми

Опис програми:
В програмі створюється анонімний канал за допомогою
функції CreatePipe,Для того, щоб дати змогу дочірньому
процесу наслідувати дескриптор каналу
встановлюються нові параметри структури
SECURITY_ATTRIBUTES. Для того, щоб приховати саме консольне вікно та
пере направити вивід у канал встановлюються нові параметри структури
STARTUP_INFO. Після створення процесу, тобто коли канал уже буде
записаний консольним виводом необхідно закрити дескриптор на запис у канал
(тому що анонімний канал одно направлений – тільки один із дескрипторів
може бути активним). За допомогою функції ReadFile зчитується інформація з

42
каналу і виводиться у вікно повідомлення. Якщо кількість зчитаних даних
більша 256, то створиться інше вікно повідомлення поки канал не буде
прочитано до кінця.
10
Створення консольної програми з використанням MASM32
;-----------------------------------
; Console.asm
;-----------------------------------
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib

.data
ConsoleTitle db "Hello Win32!",0
MsgBoxText db "Laboratory work for KSN students",0
.code
start:
invoke SetConsoleTitle, ADDR ConsoleTitle
invoke StdOut,ADDR MsgBoxText
;invoke Sleep, 1000 ; Може використовуватись для
;затримки появи консольного
вікна invoke ExitProcess,NULL
end start

Для трансляції і компонування програми console.asm потрібно використати наступні


параметри:
ml.exe /c /coff /Cp console.asm
Link.exe /SUBSYSTEM:CONSOLE /LIBPATH:d:\masm32\lib console.obj

43

You might also like