Межпроцессное взаимодействие

Тема в разделе "WASM.ARTICLES", создана пользователем Mikl___, 24 апр 2022.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795
    Inter Process Communication
    Inter Process Communication или IPC используется для обмена данными между двумя приложениями или процессами. Процессы могут быть запущенными либо на одном и том же компьютере, либо на разных компьютерах объединенных в сеть. Операционная система Windows поддерживает различные методы IPC:
    • Буфер обмена: когда пользователь использует команду копирования или вырезания в любом приложении/окне, скопированные данные сохраняются в буфере обмена окнами (временное хранилище). Другое приложение может получить доступ к данным из буфера обмена.
    • COM: модель компонентных объектов предлагает платформу для взаимодействия между процессами в шаблонах сервера и клиента. COM-сервер может быть локальным сервером или внутрипроцессным сервером. Также может быть несколько COM-клиентов, которые взаимодействуют с COM-сервером и обмениваются данными.
    • WM_COPYDATA: Windows предоставляет сообщение, то есть WM_COPYDATA, которое позволяет процессу обмениваться данными с другим процессом. Можно использовать с SendMessage или SendMessageTimeout, у которого в качестве одного из параметров используется адрес структуры COPYDATASTRUCT. Сообщение WM_COPYDATA используется для обмена данными внутри локального компьютера.
    • DDE: динамический обмен данными — это протокол, который содержит набор рекомендаций и правил для отправки данных между процессами. Процесс использует функцию SendMessage с сообщением WM_DDE_INITIATE или WM_DDE_ACK, отправленным в ответ на сообщение WM_DDE_INITIATE. Для обмена данными используется общая память.
    • Memory Mapped File и Paging File: быстрые механизмы связи между процессами, обеспечивают эффективный способ использования содержимого файла в виртуальной памяти или путем доступа к общей области в памяти. В этих IPC данные файла рассматриваются как часть адресного пространства процесса, так что процесс может легко получить доступ к адресу содержимого. Любой другой процесс, имеющий доступ к общей памяти, должен реализовать синхронизацию, чтобы снизить риск повреждения данных. Сопоставление файлов выполняется в той же системе/машине и недоступно для сетевых процессов.
    • Pipe-каналы: можно использовать как в качестве однонаправленного, так и двунаправленного механизма обмена данными. Windows поддерживает два типа каналов: именованный и анонимный канал.
      • Анонимные каналы могут использоваться в одной сети или только между связанными процессами,
      • Именованные каналы могут использоваться в сети внутри разных процессов.
      Pipe -канал рассматривают как очередь FIFO, где один конец канала действует как сервер, а другой конец канала — как клиент.
    • Mailslot-канал: обеспечивает только одностороннюю связь. Один процесс может создать mailslot-канал в качестве сервера, а другой процесс — клиентский mailslot-канал. Клиент mailslot отправляет сообщение на сервер mailslot, записывая сообщение, и сообщения добавляются к серверу mailslot до тех пор, пока сервер не прочитает их. Процесс может иметь mailslot как на сервере, так и на клиенте, и это помогает в многонаправленной связи. Mailslot предоставляет возможность транслировать сообщение по сети.
    • Sockets: эффективный способ отправки и получения данных по сети и на локальном компьютере. Использует несколько протоколов, таких как TCP/IP и UDP. Используется с комбинацией IP-адреса машины и адреса порта, по которому могут передаваться данные.
    • RPC: Remote Procedure Call (удаленный вызов процедур) обеспечивает способ связи по сети, так что процесс может вызывать функцию в другом процессе. RPC поддерживает тесную связь между клиентом и сервером с высокой производительностью.
    • LPC: Local Procedure Call (локальный вызов процедур). LPC используется операционной системой для передачи сообщений между подсистемами через порты. Основные достоинства LPC:
      • Высокая производительность;
      • Простота и функциональность;
      • Доступность для программ режима пользователя и для драйверов режима ядра.
      LPC использует клиент-серверную архитектуру и предоставляет API схожий с интерфейсом сокетов. Во взаимодействии участвуют поток-сервер и один или несколько потоков-клиентов: каждый клиент предварительно соединяется с сервером, посылает одно или несколько сообщений, на некоторые из этих сообщений получает ответ и разрывает соединение.
    Во вложении приложения для иллюстрации IPC (Mailslot, WM_COPYDATA, DDE, Clipboard, Paging File, Memory Mapped File, Named Pipe). От одного приложения к другому передаются:
    • текстовое сообщение
    • картинки
    • звук из wav-файла
    Картинки и wav-файл находятся во вложении в папке Images.
     

    Вложения:

    • IPC.zip
      Размер файла:
      3,1 МБ
      Просмотров:
      397
    • Images.zip
      Размер файла:
      1,4 МБ
      Просмотров:
      273
    Marylin, ALLIGATOR и youneuoy нравится это.
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    01. WM_COPYDATA

    Перед отправкой сообщения WM_COPYDATA структура COPYDATASTRUCT инициализируется информацией о типе пересылаемых данных, объеме данных и указателем на блок данных. Затем с помощью функции SendMessage сообщение WM_COPYDATA пересылается в принимающую программу; параметр wParam содержит дескриптор окна программы, а lParam ― адрес структуры COPYDATASTRUCT. Для передачи данных должна использоваться только функция синхронной отправки сообщения SendMessage, а не PostMessage, которая передает сообщение асинхронным образом. Память под передаваемые данные резервируется и удерживается до тех пор, пока приложение-приемник не обработает сообщение и не оповестит об этом систему. До этого момента приложение-отправитель переходит в режим ожидания. Если нужно ограничивать время ожидания, пока целевое приложение по какой-то причине может не ответить на сообщение, тогда используют функцию SendMessageTimeout.
    Когда сообщение поступает обработчику WM_COPYDATA принимающей программы, указатель на данные копируется из структуры COPYDATASTRUCT и используется, как любой другой указатель.
    В принимающем процессе размер блока данных, адрес которого содержит lpData, извлекается из элемента cbData. Значение, считываемое из элемента lpData принимающей программой, будет отличаться от значения, помещенного туда отправляющей программой. Перед передачей сообщения WM_COPYDATA операционная система выделяет в адресном пространстве принимающего процесса блок памяти, копирует данные из отправляющего процесса и обновляет значение lpData. В адресных пространствах этих процессов адреса размещении блока не совпадут.
    В структуре COPYDATASTRUCT имеется поле, dwData, в котором можно передать 32-разрядное значение, определяемое в программе. Можно поместить туда любое значение, но я помещаю туда константы определенные для работы с буфером обмена (CF_TEXT, CF_DIB, CF_WAVE) (добавлены некоторые форматы из сообщения SadKo)
    КонстантаhexОписание формата данных
    CF_TEXT
    1​
    Текстовые данные в виде массив символов. Каждая строка завершается комбинацией символов 0Dh и 0Ah, весь массив закрыт нулем
    CF_BITMAP
    2​
    Битовое изображение в формате, который зависит от устройства отображения (Device Dependent Bitmap)
    CF_METAFILEPICT
    3​
    Метафайл
    CF_SYLK
    4​
    Формат Microsoft Symbolic Link. Этот формат предназначен для передачи текстовых данных, причем каждая строка заканчивается комбинацией символов 0Dh и 0Ah. Используется в некоторых программных продуктах Microsoft
    CF_DIF
    5​
    Формат Data Interchange Format. Аналогично формату CF_SYLK, формат CF_DIF предназначен для передачи текстовых данных
    CF_TIFF
    6​
    Графическое изображение в формате Tag Image File Format, который был разработан Microsoft, Aldus Corporation и Hewlett-Packard
    CF_OEMTEXT
    7​
    Аналогично предыдущему, однако буфер содержит символы в кодировке OEM
    CF_DIB
    8​
    Битовое изображение в формате, который не зависит от устройства отображения (Device Independent Bitmap)
    CF_PALETTE
    9​
    Палитра цветов. Используется при записи в Clipboard битовых изображений DIB
    CF_PENDATA
    A​
    Формат данных используется в расширении операционной системы Windows, предназначенном для работы с перьевым вводом
    CF_RIFF
    B​
    Формат Resource Interchange File Format
    CF_WAVE
    C​
    Звуковые данные. Подмножество формата Resource Interchange File Format
    CF_UNICODETEXT
    D​
    Текст в формате UTF-16, аналогично CF_TEXT и CF_OEMTEXT
    CF_ENHMETAFILE
    E​
    Дескриптор (HANDLE) к EMF (Enhanced Metafile) ― HENHMETAFILE
    CF_HDROP
    F​
    Дескриптор к структуре HDROP, которая содержит список путей к файлам, используемая при Drag&Drop. Приложение может запросить информацию о файлах, вызвав функцию DragQueryFile
    CF_LOCALE10Объект HGLOBAL, содержащий информацию о локали текста в буфере обмена
    CF_DIBV511Объект в памяти, содержащий структуру BITMAPV5HEADER, за которой следует информация о цветовом пространстве и данные картинки
    CF_OWNERDISPLAY80Формат данных определяется приложением, записавшим такие данные в Clipboard. Это же приложение отвечает за отображение данных
    CF_DSPTEXT81Текстовое представление данных, формат которых определен приложением
    CF_DSPBITMAP82Представление данных, формат которых определен приложением, в виде битового изображения
    CF_DSPMETAFILEPICT83Представление данных, формат которых определен приложением, в виде метафайла
    CF_DSPENHMETAFILE8EФормат EMF (Enhanced Metafile)
    При использовании метода WM_COPYDATA помните, что сообщения должны пересылаться, а не просто регистрироваться. Чтобы освободить память, выделенную в адресном пространстве принимающего процесса, операционную систему нужно проинформировать о моменте завершении пересылки. Получатель сообщения WM_COPYDATA обращается с блоком данных как будто он предназначен только для чтения. Для внесения изменении в полученные данные, в принимающей программе необходимо подготовить их локальную копию.
    Объект памяти, который должен быть помещен в буфер обмена, должен быть размещен, при помощи использования функции GlobalAlloc с флажками GMEM_DDESHARE и GMEM_MOVEABLE.
    Как только объект памяти помещен в буфер обмена, монопольное использование этого дескриптора памяти переходит к системе. Когда буфер обмена очищается, а объект памяти имеет один из следующих форматов буфера обмена, система освобождает объект памяти, обращаясь к обозначенной функции:
    Наименование функции,
    которая освобождает объект
    Формат буфера обмена
    DeleteMetaFileCF_DSPENHMETAFILE
    CF_DSPMETAFILEPICT
    CF_ENHMETAFILE
    CF_METAFILEPICT
    DeleteObjectCF_BITMAP
    CF_DSPBITMAP
    CF_PALETTE
    GlobalFreeCF_DIB
    CF_DSPTEXT
    CF_OEMTEXT
    CF_TEXT
    CF_UNICODETEXT
    В том случае, если буфер обмена освобожден от объекта памяти, чей формат не показывается в предшествующем списке, прикладная программа сама должна освободить объект памяти.
    02.jpg
    Текст приложения-сервера
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. ID_TXT equ 100
    4. ID_SEND_TXT equ 101
    5. ID_SEND_ICO equ 102
    6. ID_SEND_WAV equ 103
    7. IDC_DIALOG equ 200
    8. IDC_ICON1 equ 500
    9. IDC_IMG1 equ 104
    10. COPYDATASTRUCT struct
    11.   dwData dq ?
    12.   cbData dd ?,?
    13.   lpData dq ?
    14. COPYDATASTRUCT ends
    15. .code
    16. WinMain proc
    17. enter 30h,0
    18. mov r9d,256
    19. mov [rbp-10h],r9
    20. mov qword ptr [rbp-8],LR_DEFAULTCOLOR
    21. invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON
    22. mov r9d,offset DialogProc
    23. mov qword ptr[rbp-10h],rax
    24. invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    25. invoke RtlExitUserProcess,NULL
    26. WinMain endp
    27. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    28. local buffer:qword
    29. local cdata:COPYDATASTRUCT
    30. local FSize:dword
    31. local hFile:dword
    32. local p:qword
    33. local szReadWrite:qword ;number of bytes actually read or write
    34. local hResource:qword
    35. local pResource:qword
    36. mov hWnddlg,rcx
    37. mov lParam,r9
    38. cmp edx,WM_CLOSE
    39. je wmCLOSE
    40. cmp edx,WM_COMMAND
    41. je wmCOMMAND
    42. cmp edx,WM_INITDIALOG
    43. je wmINITDIALOG
    44. xor eax,eax
    45. jmp exit0
    46. wmINITDIALOG:
    47.         invoke GetDlgItem,,IDC_IMG1
    48. invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    49. jmp wmBYE
    50. wmSEND_TXT:invoke GlobalAlloc,GPTR,256
    51. mov buffer,rax
    52.         mov cdata.lpData,rax
    53. invoke  GetDlgItemText,hWnddlg,ID_TXT,eax,256
    54.         or      eax,eax
    55.         jz      wmBYE
    56.         ; Заполнить структуру COPYDATASTRUCT
    57.         mov     cdata.dwData,CF_TEXT
    58.         ; Учитываем закрывающий строку 0
    59.         inc     eax
    60.         mov     cdata.cbData,eax
    61. jmp @f
    62. wmSEND_ICO:; Отправить изображение второму приложению
    63. mov     cdata.dwData,CF_BITMAP
    64. mov edx,p1
    65. invoke FindResource,0,,RT_ICON; find the resource
    66. mov hResource,rax
    67. invoke  SizeofResource,0,eax ; get its size
    68. mov     cdata.cbData,eax
    69. mov FSize,eax
    70. invoke LoadResource,0,hResource ; load the resource
    71. invoke LockResource,eax;pResource
    72. mov cdata.lpData,rax
    73. mov p,rax
    74. ;-------------------------------------------------
    75.         mov ecx,256
    76. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    77. mov [rsp+20h],rcx
    78. mov [rsp+28h],rcx
    79. mov edx,FSize
    80. invoke  CreateIconFromResourceEx,p,,TRUE,30000h;270376,TRUE,30000h
    81. mov [rsp+20h],rax
    82. invoke  SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON
    83. xor p1,11b
    84. ;--------------------------------------------------
    85. jmp @f
    86. wmSEND_WAV:mov ecx,offset wav_file
    87. invoke CreateFile,,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,\
    88.         FILE_ATTRIBUTE_ARCHIVE,0
    89.         mov hFile,eax
    90.         invoke GetFileSize,eax,0
    91. mov FSize,eax
    92.         mov     cdata.dwData,CF_WAVE
    93.         mov     cdata.cbData,eax
    94. invoke GlobalAlloc,GPTR,eax
    95.         mov cdata.lpData,rax
    96. lea r9d,szReadWrite
    97. and qword ptr[rsp+20h],0
    98.         invoke ReadFile,hFile,eax,FSize
    99.         invoke CloseHandle,hFile
    100. @@:; Найти окно получателя
    101. mov edx,offset szWin
    102.         invoke  FindWindow,NULL
    103.         or      eax,eax
    104.         jz      wmBYE
    105. ; Отправить данные получателю
    106. lea r9d,cdata
    107. mov qword ptr[rsp+20h],SMTO_ABORTIFHUNG
    108. mov qword ptr[rsp+28h],500
    109. and qword ptr[rsp+30h],0
    110. invoke  SendMessageTimeout,eax,WM_COPYDATA,hWnddlg
    111. jmp wmBYE
    112. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT
    113.         je      wmSEND_TXT
    114.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO
    115.         je      wmSEND_ICO
    116. cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV
    117.         je      wmSEND_WAV
    118. cmp     r8d,BN_CLICKED shl 16 + IDCANCEL
    119.         jne     wmBYE
    120. wmCLOSE:invoke EndDialog,,0
    121. wmBYE:  mov eax,TRUE
    122. exit0: leave
    123. retn
    124. DialogProc endp
    125. ;---------------------------------------
    126. .data
    127. szWin db 'WM_COPYDATA Reciever',0
    128. wav_file db '..\Images\03.wav',0
    129. p1 dd 1
    130. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define ID_TXT 100
    3. #define ID_SEND_TXT 101
    4. #define ID_SEND_ICO 102
    5. #define ID_SEND_WAV 103
    6. #define IDC_DIALOG 200
    7. #define IDC_ICON1 500
    8. #define IDC_IMG1 104
    9. IDC_ICON1 ICON "..\\Images\\icon1.ico"
    10. IDC_ICON2 ICON "..\\Images\\icon2.ico"
    11. IDC_DIALOG DIALOG 0, 0, 212, 140
    12. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    13. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    14. CAPTION "WM_COPYDATA Sender"
    15. BEGIN
    16.     CONTROL      "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    17.     CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_ICON,5,23,128,128
    18.     CONTROL "Напишите что-нибудь и нажмите 'Отправить текст'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    19.     DEFPUSHBUTTON "Отправить текст",ID_SEND_TXT,149,27,60,15
    20.     PUSHBUTTON  "Отправить ICO",ID_SEND_ICO,  149,45,60,15
    21.     PUSHBUTTON  "Отправить WAV",ID_SEND_WAV,  149,65,60,15
    22.     PUSHBUTTON "Выход", IDCANCEL,            149,85,60,15
    23. END
    Текст приложения-клиента
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. IDC_DIALOG equ 200
    4. IMAGE_BASE equ 400000h
    5. ID_TXT equ 100
    6. ID_ICON equ 102
    7. IDC_ICON1 equ 500
    8. COPYDATASTRUCT struct
    9.   dwData dq ? ;дескриптор типа передаваемых данных
    10.   cbData dd ?,? ;размер данных
    11.   lpData dq ? ;указатель на данные
    12. COPYDATASTRUCT ends
    13. .code
    14. WinMain proc dummy:qword
    15. mov r9d,offset DialogProc
    16. and qword ptr[rsp+20h],0
    17.         invoke  DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    18.         invoke  RtlExitUserProcess,NULL
    19. WinMain endp
    20. DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword
    21. local p:qword
    22. local FSize:dword
    23. local lpwiocb:WAVEHDR
    24. local hWaveOut:qword
    25. mov hWnddlg,rcx
    26. mov lParam,r9
    27. cmp edx,WM_CLOSE
    28. je wmCLOSE
    29. cmp edx,WM_COPYDATA ; Пришло сообщение WM_COPYDATA?
    30. je wmCOPYDATA
    31. cmp edx,WM_COMMAND
    32. je wmCOMMAND
    33. xor eax,eax
    34. jmp exit0
    35. wmCOPYDATA:; Получить строку от первого приложения
    36. ; В lParam приходит указатель на структуру COPYDATASTRUCT
    37.         cmp     [r9+COPYDATASTRUCT.cbData],0; Размер данных нулевой?
    38.         je      wmBYE; Да, пропускаем
    39.         cmp     [r9+COPYDATASTRUCT.dwData],CF_TEXT; Это нужный тип данных?
    40.         je COPYDATA_TEXT; Нет, пропускаем
    41. cmp     [r9+COPYDATASTRUCT.dwData],CF_BITMAP; Это нужный тип данных?
    42.         je COPYDATA_ICON; Нет, пропускаем
    43. cmp     [r9+COPYDATASTRUCT.dwData],CF_WAVE; Это нужный тип данных?
    44.         jne wmBYE
    45. COPYDATA_MUSIC:mov eax,[r9+COPYDATASTRUCT.cbData]
    46. mov FSize,eax
    47. mov r8,[r9+COPYDATASTRUCT.lpData]
    48. mov p,r8
    49.         add r8d,14h
    50.         lea ecx,hWaveOut
    51.         xor r9,r9
    52. mov [rsp+20h],r9
    53. mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
    54.         or edx,WAVE_MAPPER
    55.         invoke waveOutOpen
    56. ; Подготавливаем заголовок для вывода
    57. xor eax,eax
    58. mov ecx,(sizeof WAVEHDR)/8
    59. lea edx,lpwiocb
    60. mov edi,edx
    61. rep stosq
    62. mov rax,p
    63. add rax,2Ch
    64. mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных
    65. mov eax,FSize
    66. sub eax,2Ch
    67. mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных
    68. invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
    69. ; Запускаем проигрывание блока
    70. lea edx,lpwiocb
    71. invoke waveOutWrite,hWaveOut,,sizeof WAVEHDR
    72. @@: test lpwiocb.dwFlags,WHDR_DONE
    73. jz @b
    74. lea edx,lpwiocb
    75. invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
    76. invoke waveOutClose,hWaveOut
    77. jmp wmBYE
    78. COPYDATA_TEXT:
    79.         invoke  SetDlgItemText,,ID_TXT,[r9+COPYDATASTRUCT.lpData]
    80. jmp wmBYE
    81. COPYDATA_ICON:; Создать HICON напрямую из памяти
    82. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    83. mov qword ptr[rsp+20h],256
    84. mov qword ptr[rsp+28h],256
    85. invoke  CreateIconFromResourceEx,[r9+COPYDATASTRUCT.lpData],\
    86. [r9+COPYDATASTRUCT.cbData],TRUE,30000h
    87. mov [rsp+20h],rax
    88. invoke  SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON;,eax
    89. jmp wmBYE
    90. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL
    91. jne wmBYE
    92. wmCLOSE:invoke EndDialog,,0
    93. wmBYE:  mov eax,TRUE
    94. exit0: leave
    95. ret
    96. DialogProc endp
    97. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define IDC_DIALOG 200
    3. #define ID_TXT 100
    4. #define ID_ICON 102
    5. IDC_DIALOG DIALOG 0,0,212,140
    6. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    7. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    8. CAPTION "WM_COPYDATA Reciever"
    9. BEGIN
    10. CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    11. CONTROL "",ID_TXT,"STATIC",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    12. DEFPUSHBUTTON  "Выход",IDCANCEL,149,27,60,15
    13. CONTROL 1,ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128
    14. END
     
    Последнее редактирование: 24 янв 2024
    Marylin нравится это.
  3. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    02. Clipboard

    Функции для работы с Clipboard

    В Windows предусмотрено несколько функций для работы с Clipboard.
    Перед тем как выполнить запись или чтение данных, приложение должно получить доступ к Clipboard, открыв ее при помощи функции OpenClipboard:
    Код (C):
    1. BOOL WINAPI OpenClipboard(HWND hwnd);
    В качестве параметра этой функции передается дескриптор окна, которое будет "владеть" Clipboard. При необходимости функция этого окна будет получать сообщения, извещающие о необходимости выполнения определенных операций с Clipboard. Если доступ к Clipboard получен, OpenClipboard = TRUE. Если же Clipboard уже открыт другим приложением, OpenClipboard вернет FALSE.
    После использования приложение должно закрыть Clipboard, вызвав функцию CloseClipboard:
    Код (C):
    1. BOOL WINAPI CloseClipboard(void);
    Функция в случае успеха возвращает TRUE, в случае ошибки ― FALSE.
    Содержимое открытого Clipboard можно сбросить функцией EmptyClipboard:
    Код (C):
    1. BOOL WINAPI EmptyClipboard(void);
    EmptyClipboard возвращает TRUE при нормальном завершении или FALSE при ошибке.
    Для выполнения записи данных в Clipboard используют функцию SetClipboardData:
    Код (C):
    1. HANDLE WINAPI SetClipboardData(UINT uFormat, HANDLE  hData);
    У SetClipboardData два параметра. Первый параметр определяет формат запоминаемых в Clipboard данных, второй параметр передается дескриптор незафиксированного глобального блока памяти, содержащего запоминаемые данные.
    Для параметра uFormat используют константу, соответствующую одному из предопределенных форматов, или константу полученную от функции RegisterClipboardFormat.
    Функция RegisterClipboardFormat позволяет регистрировать собственные форматы данных для Clipboard.
    Список предопределенных форматов данных для Clipboard в разделе об WM_COPYDATA.
    Для чтения данных из Clipboard используют функцию GetClipboardData:
    Код (C):
    1. HANDLE  WINAPI GetClipboardData(UINT uFormat);
    Единственный параметр задает требуемый формат данных. Если Clipboard содержит данные в указанном формате, функция GetClipboardData возвращает дескриптор незафиксированного глобального блока памяти, содержащего требуемые данные.
    Запись данных в Clipboard
    Для записи данных в Clipboard, выполняют следующую последовательность действий:
    1. Открыть Clipboard функцией OpenClipboard
    2. Сбросить содержимое Clipboard функцией EmptyClipboard
    3. Заказать с помощью GlobalAlloc глобальный блок памяти с размером, достаточным для размещения записываемых в Clipboard данных
    4. Зафиксировать полученный блок памяти функцией GlobalLock
    5. Записать в зафиксированный блок памяти данные
    6. Расфиксировать блок памяти функцией GlobalUnlock
    7. Вызвать функцию SetClipboardData, передав ей через первый параметр формат данных, а через второй ― дескриптор расфиксированного блока памяти, содержащего данные
    8. Закрыть Clipboard функцией CloseClipboard
    Блок памяти, полученный для данных, не уничтожается функцией GlobalFree, после того как его дескриптор был использован в вызове функции SetClipboardData.
    При записи в Clipboard перемещения данных не происходит. Функция SetClipboardData изменяет атрибуты передаваемого ей блока памяти, блок памяти меняет своего "хозяина", переходит в собственность операционной системы Windows и приобретает атрибут GMEM_DDESHARE.
    Если приложение заказало глобальный блок памяти без атрибута GMEM_DDESHARE, этот блок памяти принадлежит приложению. Оно отвечает за уничтожение такого блока памяти. Если же приложение "забыло" уничтожить заказанный ей глобальный блок памяти, блок памяти уничтожает Windows при завершении приложения.
    Блок памяти, предназначенный для хранения данных Clipboard, не уничтожается при завершении работы приложения, создавшего его.
    Если приложение снабдит блок памяти атрибутом GMEM_DDESHARE, Windows не будет автоматически уничтожать его при завершении работы приложения. Приложение обязано уничтожить его самостоятельно, как только этот блок памяти перестанет быть нужным.
    Блоки памяти с атрибутом GMEM_DDESHARE используются в Windows для организации общего поля памяти, доступного всем приложениям. В Windows для адресации памяти все приложения обращаются к одной локальной таблице дескрипторов LDT, все приложения могут адресоваться к одному блоку памяти, если будут знать его селектор.
    Память Clipboard в Windows устроена в виде набора блоков памяти "общего пользования" (по одному на каждый формат данных). Функция SetClipboardData получает у приложения "личный" глобальный блок памяти с данными, и отдает его в "коллективное пользование", добавляя атрибут GMEM_DDESHARE.
    Если данные записаны в Clipboard с передачей дескриптора глобального блока памяти функции SetClipboardData, больше нельзя использовать этот дескриптор для адресации данных.
    В любой момент времени пользователь может уничтожить такой блок памяти записью в Clipboard новых данных. В процессе записи новых данных приложение вызовет функцию EmptyClipboard, которая уничтожит все блоки памяти, распределенные Clipboard раньше.
    Если операция записи данных в Clipboard выполняется при обработке одного сообщения, никакое другое приложение не будет работать с Clipboard во время записи данных. Если этот обработчик попутно создает диалоговые панели, пользователь может записать в Clipboard содержимое, например, однострочного текстового редактора, реализованного в виде органа управления диалоговой панели.
    Для исключения конфликтных ситуаций, связанных с попыткой одновременного доступа к Clipboard со стороны нескольких приложений, используют следующее правило:
    Все операции с Clipboard от его открытия и до закрытия должны выполняться в одном обработчике сообщения. Нельзя открывать Clipboard в обработчике одного сообщения, а закрывать в обработчике другого сообщения. Между открытием и закрытием Clipboard нельзя создавать диалоговые панели или выполнять другие действия, которые могут повлечь за собой создание диалоговых панелей (например, вызов функций SendMessage или PeekMessage)
    Операционная система Windows создает для каждого приложения отдельную локальную таблицу дескрипторов LDT и отдельное адресное пространство. Никакое приложение ни при каких обстоятельствах не может иметь доступа к адресному пространству другого приложения.
    Если для передачи данных между приложениями использовать функции Clipboard, гарантирована совместимость на уровне исходных текстов с операционной системой Windows.
    Чтение данных из Clipboard
    Процедура чтения данных из Clipboard. Приложение должно сделать следующее.
    1. Открыть Clipboard функцией OpenClipboard
    2. Вызвать GetClipboardData, передав ей через единственный параметр требуемый формат данных. Если Clipboard содержит данные в указанном формате, функция GetClipboardData возвратит дескриптор незафиксированного блока памяти, содержащего нужные данные. Если в Clipboard нет данных в указанном формате, будет возвращено значение NULL
    3. Зафиксировать блок памяти, дескриптор которого получен от функции GetClipboardData, функцией GlobalLock
    4. Переписать данные из зафиксированного буфера данных Clipboard в буфер, заказанный специально для этого приложением
    5. Расфиксировать блок памяти, дескриптор которого получен от функции GetClipboardData, функцией GlobalUnlock
    6. Закрыть Clipboard функцией CloseClipboard
    Чтение содержимого Clipboard, как и запись в Clipboard, нужно выполнять в обработчике одного сообщения.
    Приложение должно переписать данные из блока памяти Clipboard в свой, созданный специально, а не пользоваться блоком памяти, дескриптор которого был получен от функции GetClipboardData. В любой момент времени пользователь может уничтожить этот блок памяти, перезаписав содержимое Clipboard новыми данными.
    Текст приложения-сервера
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. IDC_DIALOG equ 200
    4. ID_TXT equ 100
    5. ID_ICON equ 102
    6. IDC_ICON1 equ 500
    7. WM_CLIPBOARDUPDATE  equ 31Dh
    8. .code
    9. WinMain proc  dummy:qword
    10. mov r9d,offset DialogProc
    11. and qword ptr[rsp+20h],0
    12.         invoke  DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    13.         invoke  RtlExitUserProcess,NULL
    14. WinMain endp
    15. DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword
    16. local buffer[96]:BYTE
    17. local hGin:qword
    18. local p:qword
    19. local FSize:dword
    20. local lpwiocb:WAVEHDR
    21. local hWaveOut:qword
    22. mov hWnddlg,rcx
    23. mov lParam,r9
    24. cmp edx,WM_CLOSE
    25. je wmCLOSE
    26. cmp edx,WM_CLIPBOARDUPDATE
    27. je wmCLIPBOARDUPDATE
    28. cmp edx,WM_COMMAND
    29. je wmCOMMAND
    30. xor eax,eax
    31. jmp exit0
    32. wmCLIPBOARDUPDATE:; Получить строку от первого приложения
    33. ; В lParam приходит указатель на тип данных?
    34. invoke OpenClipboard,hWnddlg ;открываем буфер обмена
    35. invoke __imp_GetClipboardData,lParam;извлекаем текст из буфера обмена
    36. mov hGin,rax
    37. invoke GlobalLock,eax  ;блокируем память
    38. cmp     lParam,CF_WAVE; Это нужный тип данных?
    39.         jz WAVE
    40. cmp     lParam,CF_DIB; Это нужный тип данных?
    41.         jz DIB
    42. cmp lParam,CF_TEXT
    43. jnz wmBYE
    44. ;---------------------------------------------------
    45. TXT: mov ecx,96
    46. mov esi,eax
    47. lea edi,buffer
    48. mov r8d,edi
    49. rep movsb
    50.         invoke  SetDlgItemText,hWnddlg,ID_TXT
    51. jmp @0
    52. DIB: and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    53. mov qword ptr[rsp+20h],256
    54. mov qword ptr[rsp+28h],256
    55. invoke  CreateIconFromResourceEx,eax,lParam,TRUE,30000h
    56. mov [rsp+20h],rax
    57. invoke  SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON;,eax
    58. jmp @0
    59. WAVE: mov p,rax
    60. mov r8,rax;p
    61. mov eax,[r8+4]
    62. mov FSize,eax
    63.         add r8d,14h
    64.         lea ecx,hWaveOut
    65.         xor r9,r9
    66. mov [rsp+20h],r9
    67. mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
    68.         or edx,WAVE_MAPPER
    69.         invoke waveOutOpen
    70. ; Подготавливаем заголовок для вывода
    71. lea edx,lpwiocb
    72. mov edi,edx
    73. xor eax,eax
    74. mov ecx,(sizeof WAVEHDR)/8
    75. rep stosq
    76. mov rax,p
    77. add rax,2Ch
    78. mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных
    79. mov eax,FSize
    80. sub eax,2Ch
    81. mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных
    82. invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
    83. ; Запускаем проигрывание блока
    84. lea edx,lpwiocb
    85. invoke waveOutWrite,hWaveOut,,sizeof WAVEHDR
    86. @@: test lpwiocb.dwFlags,WHDR_DONE
    87. jz @b
    88. lea edx,lpwiocb
    89. invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
    90. invoke waveOutClose,hWaveOut
    91. @0: invoke GlobalLock,hGin
    92. invoke CloseClipboard
    93. jmp wmBYE
    94. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL
    95. jne wmBYE
    96. wmCLOSE:invoke EndDialog,,0
    97. wmBYE:  mov eax,TRUE
    98. exit0: leave
    99. ret
    100. DialogProc endp
    101. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define IDC_DIALOG 200
    3. #define ID_TXT 100
    4. #define ID_ICON 102
    5. IDC_DIALOG DIALOG 0,0,212,140
    6. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    7. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    8. CAPTION "Clipboard Reciever"
    9. BEGIN
    10. CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    11. CONTROL "",ID_TXT,"STATIC",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    12. DEFPUSHBUTTON  "Выход",IDCANCEL,149,27,60,15
    13. CONTROL "",ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128
    14. END
    Текст приложения-клиента
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. ID_TXT equ 100
    4. ID_SEND_TXT equ 101
    5. ID_SEND_ICO equ 102
    6. ID_SEND_WAV equ 103
    7. IDC_DIALOG equ 200
    8. IDC_ICON1 equ 500
    9. IDC_IMG1 equ 104
    10. WM_CLIPBOARDUPDATE  equ 31Dh
    11. extern __imp_SetClipboardData:qword
    12. .code
    13. WinMain proc
    14. enter 30h,0
    15. mov r9d,256;cx
    16. mov [rbp-10h],r9
    17. mov qword ptr [rbp-8],LR_DEFAULTCOLOR
    18. invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON;,256,256,LR_DEFAULTCOLOR
    19. mov r9d,offset DialogProc
    20. mov qword ptr[rbp-10h],rax;30h-10h=+20h
    21. invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    22. invoke RtlExitUserProcess,NULL
    23. WinMain endp
    24. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    25. size_of_buffer equ 96
    26. local buffer[size_of_buffer]:BYTE
    27. local hGout:qword
    28. local p:qword
    29. local FSize:dword
    30. local hFile:dword
    31. local szReadWrite:qword ;number of bytes actually read or write
    32. local hResource:qword
    33. local pResource:qword
    34. local type0:qword
    35. mov hWnddlg,rcx
    36. mov lParam,r9
    37. cmp edx,WM_CLOSE
    38. je wmCLOSE
    39. cmp edx,WM_COMMAND
    40. je wmCOMMAND
    41. cmp edx,WM_INITDIALOG
    42. je wmINITDIALOG
    43. xor eax,eax
    44. jmp exit0
    45. wmINITDIALOG:;
    46.         invoke GetDlgItem,,IDC_IMG1
    47. invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    48. jmp wmBYE
    49. wmSEND_TXT:lea r8d,buffer
    50. invoke  GetDlgItemText,,ID_TXT,,size_of_buffer;255
    51.         or      eax,eax
    52.         jz      wmBYE
    53. mov FSize,eax
    54. invoke GlobalAlloc,GPTR,size_of_buffer;GHND or GMEM_DDESHARE
    55. mov hGout,rax
    56. invoke GlobalLock,eax
    57. mov p,rax
    58. mov edi,eax
    59. lea esi,buffer
    60. mov ecx,FSize
    61. rep movsb
    62. and byte ptr[rdi],0
    63. mov type0,CF_TEXT
    64. ;----------------------------------------------------
    65. jmp @f
    66. wmSEND_ICO:; Отправить изображение второму приложению
    67. mov edx,p1
    68. invoke FindResource,0,,RT_ICON; find the resource
    69. mov hResource,rax
    70. invoke  SizeofResource,0,eax ; get its size
    71. mov FSize,eax
    72. invoke GlobalAlloc,GPTR,eax; or GMEM_DDESHARE,eax
    73. mov hGout,rax
    74. invoke GlobalLock,eax
    75. mov p,rax
    76. mov edi,eax
    77. invoke LoadResource,0,hResource ; load the resource
    78. invoke LockResource,eax;pResource
    79. mov esi,eax
    80. mov ecx,FSize
    81. rep movsb
    82. ;------------------------------------------------
    83.         mov ecx,256
    84. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    85. mov [rsp+20h],rcx
    86. mov [rsp+28h],rcx
    87. mov edx,FSize
    88. invoke  CreateIconFromResourceEx,p,,TRUE,30000h
    89. mov [rsp+20h],rax
    90. invoke  SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON
    91. mov type0,CF_DIB
    92. xor p1,11b
    93. ;--------------------------------------------------
    94. jmp @f
    95. wmSEND_WAV:mov ecx,offset wav_file
    96. invoke CreateFile,,GENERIC_READ,0,0,OPEN_EXISTING,\
    97.         FILE_ATTRIBUTE_ARCHIVE,0
    98.         mov hFile,eax
    99.         invoke GetFileSize,eax,0
    100. mov FSize,eax
    101. invoke GlobalAlloc,GPTR,eax
    102. mov hGout,rax
    103. invoke GlobalLock,eax
    104. mov p,rax
    105. lea r9d,szReadWrite
    106.         invoke ReadFile,hFile,eax,FSize,,0
    107.         invoke CloseHandle,hFile
    108. mov type0,CF_WAVE
    109. ;--------------------------------------------------------
    110. @@: invoke GlobalUnlock,hGout
    111. invoke OpenClipboard,hWnddlg
    112. or eax,eax
    113. jz wmBYE
    114. invoke EmptyClipboard
    115. invoke __imp_SetClipboardData,type0,hGout
    116. invoke CloseClipboard
    117. ; Найти окно получателя
    118. mov edx,offset szWin
    119.         invoke  FindWindow,NULL
    120.         or      eax,eax
    121.         jz      wmBYE
    122. ; Отправить данные получателю
    123. invoke  PostMessage,eax,WM_CLIPBOARDUPDATE,hWnddlg,type0
    124. jmp wmBYE
    125. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT
    126.         je      wmSEND_TXT
    127.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO
    128.         je      wmSEND_ICO
    129. cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV
    130.         je      wmSEND_WAV
    131. cmp     r8d,BN_CLICKED shl 16 + IDCANCEL
    132.         jne     wmBYE
    133. wmCLOSE:invoke EndDialog,,0
    134. wmBYE:  mov eax,TRUE
    135. exit0: leave
    136. retn
    137. DialogProc endp
    138. ;---------------------------------------
    139. .data
    140. szWin db 'Clipboard Reciever',0
    141. wav_file db '..\Images\03.wav',0
    142. p1 dd 1
    143. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define ID_TXT 100
    3. #define ID_SEND_TXT 101
    4. #define ID_SEND_ICO 102
    5. #define ID_SEND_WAV 103
    6. #define IDC_DIALOG 200
    7. #define IDC_ICON1 500
    8. #define IDC_IMG1 104
    9. IDC_ICON1 ICON "..\\Images\\icon1.ico"
    10. IDC_ICON2 ICON "..\\Images\\icon2.ico"
    11. IDC_DIALOG DIALOG 0, 0, 212, 140
    12. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    13. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    14. CAPTION "Clipboard Sender"
    15. BEGIN
    16.     CONTROL      "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    17.     CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_ICON,5,23,128,128
    18.     CONTROL "Напишите что-нибудь и нажмите 'Отправить текст'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    19.     DEFPUSHBUTTON "Отправить текст",ID_SEND_TXT,149,27,60,15
    20.     PUSHBUTTON  "Отправить ICO",ID_SEND_ICO,  149,45,60,15
    21.     PUSHBUTTON  "Отправить WAV",ID_SEND_WAV,  149,65,60,15
    22.     PUSHBUTTON "Выход", IDCANCEL,            149,85,60,15
    23. END
     
    Marylin нравится это.
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    04. Paging File (страничный файл)

    Страничный файл входит в общую физическую память вычислительной системы увеличивая ее объем. В физической памяти создается проекция страничного файла, которая отображается на виртуальное адресное пространство нескольких процессов. Первый процесс создает в памяти проекцию страничного файла и отображает ее на свое адресное пространство, записывает в эту память некоторые данные. Второй процесс отображает ту же проекцию страничного файла на свое адресное пространство, читает эти данные. При создании проекции файла в разделе Memory Mapped File в качестве первого параметра функции CreateFileMapping указывают дескриптор открытого файла на диске. Чтобы создать проекцию страничного файла, первый параметр функции CreateFileMapping должен быть равным -1 (INVALID_HANDLE_VALUE). Предпоследний параметр функции задает размер проекции, а последний ― произвольное имя объекта, которое должно быть известно во втором процессе. С помощью функции MapViewOfFile в виртуальной памяти процесса выделяется область в памяти того же размера и проекция страничного файла отображается на эту же область памяти.
    Текст приложения-сервера
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. ID_TXT equ 100
    4. ID_SEND_TXT equ 101
    5. ID_SEND_ICO equ 102
    6. ID_SEND_WAV equ 103
    7. IDC_DIALOG equ 200
    8. IDC_ICON1 equ 500
    9. IDC_IMG1 equ 104
    10. .code
    11. WinMain proc dummy:qword
    12.        mov r9d,256
    13.        mov [rsp+20h],r9
    14.        mov qword ptr [rsp+28],LR_DEFAULTCOLOR
    15.        invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON
    16.        mov r9d,offset DialogProc
    17.        mov qword ptr[rsp+20h],rax
    18.        invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    19.        invoke RtlExitUserProcess,NULL
    20. WinMain endp
    21. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    22. size_of_buffer equ 96
    23. local buffer[size_of_buffer]:BYTE
    24. local hFile:dword
    25. local FSize:dword
    26. local hMapping:qword
    27. local pMapping:qword
    28. local hResource:qword
    29. local pResource:qword
    30. local szReadWrite:qword
    31. local type0:qword
    32.        mov hWnddlg,rcx
    33.        mov lParam,r9
    34.        cmp edx,WM_CLOSE
    35.        je wmCLOSE
    36.        cmp edx,WM_COMMAND
    37.        je wmCOMMAND
    38.        cmp edx,WM_INITDIALOG
    39.        je wmINITDIALOG
    40.        xor eax,eax
    41.        jmp exit0
    42. wmINITDIALOG:;
    43.         invoke GetDlgItem,,IDC_IMG1
    44.        invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    45.        jmp wmBYE
    46. wmSEND_TXT:       lea r8d,buffer
    47.        invoke  GetDlgItemText,,ID_TXT,,size_of_buffer
    48.         or      eax,eax
    49.         jz      wmBYE
    50.         inc     eax
    51.        mov FSize,eax
    52. ;создание в памяти объекта "проекция файла"
    53.        sub esp,30h
    54.        movr qword ptr[rsp+28h],szMapName
    55.        mov eax,FSize
    56.        mov [rsp+20h],rax
    57.        or rcx,INVALID_HANDLE_VALUE
    58.         invoke CreateFileMapping,,0,PAGE_READWRITE,0
    59.        mov hMapping,rax
    60. ;отображение проекции файла на адресное пространство процесса
    61. mov ecx,eax
    62. mov eax,FSize
    63. mov [rsp+20h],rax
    64. invoke MapViewOfFile,,FILE_MAP_ALL_ACCESS,0,0
    65. mov pMapping,rax
    66. mov ecx,FSize
    67. mov edi,eax
    68. lea esi,buffer
    69. rep movsb
    70. mov type0,WM_USER+1
    71. ;--------------------------------------------------
    72. jmp @f
    73. wmSEND_ICO:sub esp,30h
    74. mov edx,p1
    75. invoke FindResource,0,,RT_ICON; find the resource
    76. mov hResource,rax
    77. invoke  SizeofResource,0,eax ; get its size
    78. mov     FSize,eax
    79. invoke LoadResource,0,hResource ; load the resource
    80. invoke LockResource,eax
    81. mov esi,eax
    82. ;созддание в памяти объекта "проекция файла"
    83. movr qword ptr[rsp+28h],szMapName
    84. mov eax,FSize
    85. mov [rsp+20h],rax
    86. or rcx,INVALID_HANDLE_VALUE
    87.         invoke CreateFileMapping,,0,PAGE_READWRITE,0
    88. mov hMapping,rax
    89. ;отображение проекции файла на адресное пространство процесса
    90. mov ecx,eax
    91. mov eax,FSize
    92. mov [rsp+20h],rax
    93. invoke MapViewOfFile,,FILE_MAP_ALL_ACCESS,0,0
    94. mov pMapping,rax
    95. mov ecx,FSize
    96. mov edi,eax;rdi,pMapping
    97. rep movsb
    98. ;--------------------------------------------------
    99.         mov ecx,256
    100. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    101. mov [rsp+20h],rcx
    102. mov [rsp+28h],rcx
    103. mov edx,FSize
    104. invoke  CreateIconFromResourceEx,pMapping,,TRUE,30000h;270376,TRUE,30000h
    105. mov [rsp+20h],rax
    106. invoke  SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON
    107. xor p1,11b
    108. mov type0,WM_USER+2
    109. ;-------------------------------------------------------
    110. jmp @f
    111. wmSEND_WAV:sub esp,40h
    112. mov ecx,offset wav_file
    113. xor r9d,r9d
    114. mov qword ptr[rsp+30h],r9
    115. mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE
    116. mov qword ptr[rsp+20h],OPEN_EXISTING
    117. invoke CreateFile,,GENERIC_READ or GENERIC_WRITE,\
    118. FILE_SHARE_READ or FILE_SHARE_WRITE
    119.         mov hFile,eax
    120.         invoke GetFileSize,eax,0
    121. mov FSize,eax
    122. ;созддание в памяти объекта "проекция файла"
    123. movr qword ptr[rsp+28h],szMapName
    124. mov eax,FSize
    125. mov [rsp+20h],rax
    126. or rcx,INVALID_HANDLE_VALUE
    127.         invoke CreateFileMapping,,0,PAGE_READWRITE,0
    128. mov hMapping,rax
    129. ;отображение проекции файла на адресное пространство процесса
    130. xor r8d,r8d
    131. mov [rsp+20h],r8
    132. invoke MapViewOfFile,eax,FILE_MAP_ALL_ACCESS,,0,FSize
    133. mov pMapping,rax
    134. ;-------------------------------------------------
    135. and qword ptr[rsp+20h],0
    136. lea r9,szReadWrite
    137. invoke ReadFile,hFile,pMapping,FSize
    138. mov type0,WM_USER+3
    139. @@:; Найти окно получателя
    140. mov edx,offset szWin
    141.         invoke  FindWindow,NULL
    142.         or      eax,eax
    143.         jz      wmBYE
    144. ; Отправить данные получателю
    145. mov qword ptr[rsp+20h],SMTO_ABORTIFHUNG
    146. mov qword ptr[rsp+28h],5000
    147. and qword ptr[rsp+30h],0
    148.         invoke  SendMessageTimeout,eax,type0,hWnddlg,FSize
    149. invoke UnmapViewOfFile,pMapping
    150. invoke CloseHandle,hMapping
    151. jmp wmBYE
    152. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT
    153.         je      wmSEND_TXT
    154.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO
    155.         je      wmSEND_ICO
    156. cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV
    157.         je      wmSEND_WAV
    158. cmp     r8d,BN_CLICKED shl 16 + IDCANCEL
    159.         jne     wmBYE
    160. wmCLOSE:invoke EndDialog,,0
    161. wmBYE:  mov eax,TRUE
    162. exit0: leave
    163. retn
    164. DialogProc endp
    165. ;---------------------------------------
    166. .data
    167. szWin db 'Paging File Reciever',0
    168. wav_file db '..\Images\03.wav',0
    169. szMapName db "13-15=Mapping",0
    170. p1 dd 1
    171. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define ID_TXT 100
    3. #define ID_SEND_TXT 101
    4. #define ID_SEND_ICO 102
    5. #define ID_SEND_WAV 103
    6. #define IDC_DIALOG 200
    7. #define IDC_ICON1 500
    8. #define IDC_IMG1 104
    9. IDC_ICON1 ICON "..\\Images\\icon1.ico"
    10. IDC_ICON2 ICON "..\\Images\\icon2.ico"
    11. IDC_DIALOG DIALOG 0, 0, 212, 140
    12. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    13. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    14. CAPTION "Paging File Sender"
    15. BEGIN
    16.     CONTROL      "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    17.     CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_ICON,5,23,128,128
    18.     CONTROL "Напишите что-нибудь и нажмите 'Отправить текст'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    19.     DEFPUSHBUTTON "Отправить текст",ID_SEND_TXT,149,27,60,15
    20.     PUSHBUTTON  "Отправить ICO",ID_SEND_ICO,  149,45,60,15
    21.     PUSHBUTTON  "Отправить WAV",ID_SEND_WAV,  149,65,60,15
    22.     PUSHBUTTON "Выход", IDCANCEL,            149,85,60,15
    23. END
    Текст приложения-клиента
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. IDC_DIALOG equ 200
    4. IMAGE_BASE equ 400000h
    5. ID_TXT equ 100
    6. ID_ICON equ 102
    7. IDC_ICON1 equ 500
    8. .code
    9. WinMain proc dummy:qword
    10. mov r9d,offset DialogProc
    11. and qword ptr[rsp+20h],0
    12.         invoke  DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    13.         invoke  RtlExitUserProcess,NULL
    14. WinMain endp
    15. DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword
    16. local pMapping:qword
    17. local hMapping:qword
    18. local FSize:dword
    19. local lpwiocb:WAVEHDR
    20. local hWaveOut:qword
    21. local type0:dword
    22. mov hWnddlg,rcx
    23. mov lParam,r9
    24. cmp edx,WM_CLOSE
    25. je wmCLOSE
    26. cmp edx,WM_USER+3
    27. je wmUSER_3
    28. cmp edx,WM_USER+1
    29. je wmUSER_1
    30. cmp edx,WM_USER+2
    31. je wmUSER_2
    32. cmp edx,WM_COMMAND
    33. je wmCOMMAND
    34. xor eax,eax
    35. jmp exit0
    36. wmUSER_3:; Получить музыку от первого приложения
    37. mov type0,CF_WAVE
    38. jmp @f
    39. wmUSER_1:; Получить строку от первого приложения
    40. mov type0,CF_TEXT
    41. jmp @f
    42. wmUSER_2:; Получить картинку от первого приложения
    43. mov type0,CF_DIB
    44. @@: mov r8d,offset lpszName
    45. invoke OpenFileMapping,FILE_MAP_ALL_ACCESS,FALSE
    46. mov hMapping,rax
    47. mov ecx,eax
    48. mov rax,lParam
    49. mov [rsp+20h],rax
    50. invoke MapViewOfFile,,FILE_MAP_ALL_ACCESS,0,0
    51. mov pMapping,rax
    52. cmp type0,CF_TEXT
    53. je TXT
    54. cmp type0,CF_DIB
    55. je DIB
    56. WAVE: mov r8,pMapping
    57.         add r8d,14h
    58.         lea ecx,hWaveOut
    59.         xor r9,r9
    60. mov [rsp+20h],r9
    61. mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
    62.         or edx,WAVE_MAPPER
    63.         invoke waveOutOpen
    64. ; Подготавливаем заголовок для вывода
    65. lea edx,lpwiocb
    66. mov edi,edx
    67. xor eax,eax
    68. mov ecx,(sizeof WAVEHDR)/8
    69. rep stosq
    70. mov rax,pMapping
    71. mov ecx,eax
    72. add rax,2Ch
    73. mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных
    74. mov eax,[rcx+4]
    75. sub eax,2Ch
    76. mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных
    77. invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
    78. ; Запускаем проигрывание блока
    79. lea edx,lpwiocb
    80. mov rcx,hWaveOut
    81. mov r8d,sizeof WAVEHDR
    82. invoke waveOutWrite
    83. @@: cmp lpwiocb.dwFlags,WHDR_DONE or WHDR_PREPARED
    84. jnz @b
    85. lea edx,lpwiocb
    86. invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
    87. invoke waveOutClose,hWaveOut
    88. jmp @f
    89. TXT: invoke  SetDlgItemText,hWnddlg,ID_TXT,pMapping
    90. jmp @f
    91. DIB: and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    92. mov qword ptr[rsp+20h],256
    93. mov qword ptr[rsp+28h],256
    94. invoke  CreateIconFromResourceEx,pMapping,lParam,TRUE,30000h
    95. mov [rsp+20h],rax
    96. invoke  SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON
    97. @@: invoke UnmapViewOfFile,pMapping
    98.         invoke CloseHandle,hMapping
    99. jmp wmBYE
    100. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL
    101. jne wmBYE
    102. wmCLOSE:invoke EndDialog,,0
    103. wmBYE:  mov eax,TRUE
    104. exit0: leave
    105. ret
    106. DialogProc endp
    107. lpszName db "13-15=Mapping",0
    108. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define IDC_DIALOG 200
    3. #define ID_TXT 100
    4. #define ID_ICON 102
    5. IDC_DIALOG DIALOG 0,0,212,140
    6. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    7. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    8. CAPTION "Paging File Reciever"
    9. BEGIN
    10. CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    11. CONTROL "",ID_TXT,"STATIC",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    12. DEFPUSHBUTTON  "Выход",IDCANCEL,149,27,60,15
    13. CONTROL "",ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128
    14. END
     
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    06a. Named Pipe

    Средство передачи данных между параллельно работающими процессами. Позволяет организовать передачу данных между локальными процессами, а также между процессами, запущенными на различных рабочих станциях в сети.
    Pipe-каналы похожи на файлы. Pipe просты в использовании.
    Через Pipe-канал можно передавать данные только между двумя процессами. Один из процессов создает канал, другой открывает его. После этого оба процесса могут передавать данные через канал в одну или обе стороны, используя для этого функции, предназначенные для работы с файлами ReadFile и WriteFile. Приложения могут выполнять над Pipe-каналами синхронные или асинхронные операции. При использовании асинхронных операций необходимо обеспечить синхронизацию.

    Именованные и анонимные каналы

    Существуют две разновидности pipe-каналов ― именованные (Named Pipes) и анонимные (Anonymous Pipes). Именованным каналам при создании присваивается имя, которое доступно для других процессов. Зная имя какой-либо рабочей станции в сети, процесс может получить доступ к каналу, созданному на этой рабочей станции.
    Анонимные каналы используются для организации передачи данных между родительскими и дочерними процессами, запущенными на одном компьютере.

    Имена каналов

    Имена каналов имеют следующий вид:
    Код (C):
    1. \\Имя_Сервера\pipe\Имя_Канала
    Если процесс открывает канал, созданный на другой рабочей станции нужно указать имя сервера. Если процесс создает канал или открывает канал на своей рабочей станции, вместо имени указывается символ точки:
    Код (C):
    1. \\.\pipe\Имя_Канала
    Процесс может создать канал только на той рабочей станции, где он запущен, поэтому при создании канала имя сервера никогда не указывается.

    Реализации каналов

    Один серверный процесс создает один канал (одну реализацию канала) для работы с одним клиентским процессом.
    Если требуется организовать взаимодействие одного серверного процесса с несколькими клиентскими. Например, сервер базы данных должен принимать от клиентов запросы и рассылать ответы на них. Тогда серверный процесс создает несколько реализаций канала, по одной реализации для каждого клиентского процесса.

    Функции для работы с каналами

    Наиболее важные функции предназначенные для работы с Pipe-каналами. Более подробная информация в документации MSDN.

    Создание канала

    Для создания именованных и анонимных pipe-каналов используются функции CreatePipe и CreateNamedPipe.

    Функция CreatePipe

    Анонимный канал создается функцией CreatePipe
    Код (C):
    1. BOOL CreatePipe(
    2.   PHANDLE hReadPipe,// адрес переменной, в которую будет записан дескриптор канала для чтения данных
    3.   PHANDLE hWritePipe,// адрес переменной, в которую будет записан дескриптор канала для записи данных
    4.   LPSECURITY_ATTRIBUTES lpPipeAttributes, // адрес переменной для атрибутов защиты
    5.   DWORD nSize);// количество байт памяти, зарезервированной для канала
    Канал может использоваться как для записи в него данных, так и для чтения. Поэтому при создании канала функция CreatePipe возвращает два дескриптора, записывая их по адресу, заданному в параметрах hReadPipe и hWritePipe.
    дескриптор, записанный по адресу hReadPipe, передается как параметр функции ReadFile или ReadFileEx для выполнения операции чтения. дескриптор, записанный по адресу hWritePipe, передается функции WriteFile или WriteFileEx для выполнения операции записи.
    Через параметр lpPipeAttributes передается адрес переменной, содержащей атрибуты защиты для создаваемого канала. Чаще этот параметр указывают как NULL. В результате канал будет иметь атрибуты защиты, принятые по умолчанию.
    Параметр nSize определяет размер буфера для создаваемого канала. Если этот размер указан как нуль, создается буфер с размером, принятым по умолчанию. При необходимости система может изменить указанный размер буфера.
    В случае успеха функция CreatePipe возвращает значение TRUE, при ошибке ― FALSE. Для уточнения причины возникновения ошибки используют функцию GetLastError.

    Функция CreateNamedPipe

    Для создания именованного канала Pipe используют функцию CreateNamedPipe. Прототип этой функции:
    Код (C):
    1. HANDLE CreateNamedPipe(
    2.   LPCTSTR lpName,          // адрес строки имени канала
    3.   DWORD   dwOpenMode,      // режим открытия канала
    4.   DWORD   dwPipeMode,      // режим работы канала
    5.   DWORD   nMaxInstances,   // максимальное количество реализаций канала
    6.   DWORD   nOutBufferSize,  // размер выходного буфера в байтах
    7.   DWORD   nInBufferSize,   // размер входного буфера в байтах
    8.   DWORD   nDefaultTimeOut, // время ожидания в миллисекундах
    9.   LPSECURITY_ATTRIBUTES lpSecurityAttributes); // адрес переменной для атрибутов защиты
    Через параметр lpName передается адрес строки имени канала в форме \\.\pipe\Имя_Канала (при создании канала имя сервера не указывается, так как канал можно создать только на той рабочей станции, где запущен процесс, создающий канал).
    Параметр dwOpenMode задает режим, в котором открывается канал.
    Pipe-канал может быть ориентирован либо на передачу потока байт, либо на передачу сообщений. В первом случае данные через канал передаются по байтам, во втором ― отдельными блоками заданной длины.
    Режим работы канала (ориентированный на передачу байт или сообщений) задается константами PIPE_TYPE_BYTE или PIPE_TYPE_MESSAGE, которые указываются в параметре dwOpenMode. По умолчанию используют режим PIPE_TYPE_BYTE.
    Помимо способа передачи данных через канал, с помощью параметра dwOpenMode можно указать, будет ли данный канал использован только для чтения данных, только для записи или одновременно для чтения и записи. Способ использования канала задается указанием одной из следующих констант:
    КонстантаhexbinИспользование канала
    PIPE_ACCESS_INBOUND
    1​
    00000001Только для чтения
    PIPE_ACCESS_OUTBOUND
    2​
    00000010Только для записи
    PIPE_ACCESS_DUPLEX
    3​
    00000011Для чтения и записи
    Перечисленные параметры должны быть одинаковы для всех реализаций канала. Параметры, которые могут отличаться для разных реализаций канала:
    Константаhex Использование канала
    PIPE_READMODE_BYTE
    0​
    Канал открывается на чтение в режиме последовательной передачи отдельных байт
    PIPE_READMODE_MESSAGE
    2​
    Канал открывается на чтение в режиме передачи отдельных сообщений указанной длины
    PIPE_WAIT
    0​
    Канал будет работать в блокирующем режиме, когда процесс переводится в состояние ожидания до завершения операций в канале
    PIPE_NOWAIT
    1​
    Неблокирующий режим работы канала. Если операция не может быть выполнена немедленно, в неблокирующем режиме функция завершается с ошибкой
    FILE_FLAG_OVERLAPPED
    40000000​
    Использование асинхронных операций (ввод и вывод с перекрытием). Данный режим позволяет процессу выполнять полезную работу параллельно с проведением операций в канале
    FILE_FLAG_WRITE_THROUGH
    80000000​
    В этом режиме функции, работающие с каналом, не возвращают управление до тех пор, пока не будет полностью завершена операция на удаленном компьютере. Используется только с каналом, ориентированном на передачу отдельных байт и только в том случае, когда канал создан между процессами, запущенными на различных станциях сети
    Дополнительно через параметр dwOpenMode можно передавать флаги защиты:
    ФлагhexОписание
    WRITE_DAC
    40000​
    Вызывающий процесс должен иметь права доступа на запись к произвольному управляющему списку доступа именованного канала access control list (ACL)
    WRITE_OWNER
    80000​
    Вызывающий процесс должен иметь права доступа на запись к процессу, владеющему именованным каналом Pipe
    ACCESS_SYSTEM_SECURITY1000000 Вызывающий процесс должен иметь права доступа на запись к управляющему списку доступа именованного канала access control list (ACL)
    Параметр dwPipeMode определяет режим работы канала. В этом параметре можно указать константы PIPE_TYPE_BYTE, PIPE_TYPE_MESSAGE, PIPE_READMODE_BYTE, PIPE_READMODE_MESSAGE, PIPE_WAIT и PIPE_NOWAIT. Для всех реализаций канала необходимо указывать один и тот же набор констант.
    Параметр nMaxInstances определяет максимальное количество реализаций, которые могут быть созданы для канала. Можно указывать значения от 1 до PIPE_UNLIMITED_INSTANCES. В случае максимальное количество реализаций ограничивается только наличием свободных системных ресурсов.
    Если один серверный процесс использует несколько реализаций канала для связи с несколькими клиентскими процессами, общее количество реализаций может быть меньше, чем потенциальное максимальное количество клиентов. Это связано с тем, что клиенты могут использовать реализации по очереди, если только они не пожелают связаться с серверным процессом все одновременно.
    Параметры nOutBufferSize и nInBufferSize определяют размер буферов, используемых для записи в канал и чтения из канала. При необходимости система может использовать буферы других, по сравнению с указанными, размеров.
    Параметр nDefaultTimeOut определяет время ожидания для реализации канала. Для всех реализаций необходимо указывать одинаковое значение этого параметра.
    Через параметр lpPipeAttributes передается адрес переменной, содержащей атрибуты защиты для создаваемого канала. Обычно этот параметр равен NULL. В результате канал будет иметь атрибуты защиты, принятые по умолчанию.
    В случае успеха функция CreateNamedPipe возвращает дескриптор созданной реализации канала, который можно использовать в операциях чтения и записи, выполняемых с помощью функций ReadFile и WriteFile.
    При ошибке CreateNamedPipe возвращает значение INVALID_HANDLE_VALUE. Код ошибки можете уточнить, вызвав функцию GetLastError.

    Использование функции CreateFile

    Функция CreateFile, предназначена для работы с файлами, может использоваться для создания новых каналов и открытия существующих. Вместо имени файла указывают имя pipe-канала.
    Текст приложения-сервера
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. WM_CLIPBOARDUPDATE equ 31Dh
    4. ID_TXT equ 100
    5. ID_SEND_TXT equ 101
    6. ID_SEND_ICO equ 102
    7. ID_SEND_WAV equ 103
    8. IDC_DIALOG equ 200
    9. IDC_ICON1 equ 500
    10. IDC_IMG1 equ 104
    11. .code
    12. WinMain proc dummy:qword
    13. mov r9d,256
    14. mov [rsp+20h],r9
    15. mov qword ptr [rsp+28],LR_DEFAULTCOLOR
    16. invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON;,256,256,LR_DEFAULTCOLOR
    17. mov r9d,offset DialogProc
    18. mov qword ptr[rsp+20h],rax
    19. invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    20. invoke RtlExitUserProcess,NULL
    21. WinMain endp
    22. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    23. size_of_buffer equ 256
    24. local cbWritten:dword;Количество байт, переданных через канал
    25. local FSize:dword;
    26. local hNamePipe:qword; дескриптор канала Mailslot
    27. local hFile:dword
    28. local p:qword
    29. local hResource:qword
    30. local type0:qword
    31. mov hWnddlg,rcx
    32. mov lParam,r9
    33. cmp edx,WM_CLOSE
    34. je wmCLOSE
    35. cmp edx,WM_COMMAND
    36. je wmCOMMAND
    37. cmp edx,WM_INITDIALOG
    38. je wmINITDIALOG
    39. xor eax,eax
    40. jmp exit0
    41. wmINITDIALOG:;
    42.         invoke GetDlgItem,,IDC_IMG1
    43. invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    44. jmp wmBYE
    45. wmSEND_TXT:invoke GlobalAlloc,GPTR,size_of_buffer
    46.         mov p,rax;Буфер для передачи данных через канал
    47. invoke  GetDlgItemText,hWnddlg,ID_TXT,eax,size_of_buffer;255
    48.         or      eax,eax
    49.         jz      wmBYE
    50.         inc     eax
    51. mov FSize,eax
    52. mov type0,WM_USER+1
    53. jmp @f
    54. wmSEND_ICO:mov edx,p1
    55. invoke FindResource,0,,RT_ICON; find the resource
    56. mov hResource,rax
    57. invoke  SizeofResource,0,eax ; get its size
    58. mov FSize,eax
    59. invoke LoadResource,0,hResource ; load the resource
    60. invoke LockResource,eax;pResource
    61.   mov p,rax
    62. ;-------------------------------------------------
    63.         mov ecx,256
    64. and qword ptr[rsp+30h],LR_DEFAULTCOLOR
    65. mov [rsp+20h],rcx
    66. mov [rsp+28h],rcx
    67. mov edx,FSize
    68. invoke  CreateIconFromResourceEx,p,,TRUE,30000h
    69. mov [rsp+20h],rax
    70. invoke  SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON
    71. xor p1,11b
    72. mov type0,WM_USER+2
    73. jmp @f
    74. wmSEND_WAV:mov ecx,offset wav_file
    75. xor r9d,r9d
    76. mov qword ptr[rsp+30h],r9
    77. mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE
    78. mov qword ptr[rsp+20h],OPEN_EXISTING
    79. invoke CreateFile,,GENERIC_READ or GENERIC_WRITE,\
    80. FILE_SHARE_READ or FILE_SHARE_WRITE
    81.         mov hFile,eax
    82.         invoke GetFileSize,eax,0
    83. mov FSize,eax
    84. invoke GlobalAlloc,GPTR,eax
    85.         mov p,rax
    86. lea r9d,cbWritten
    87. and qword ptr[rsp+20h],0
    88.         invoke ReadFile,hFile,eax,FSize
    89.         invoke CloseHandle,hFile
    90. mov type0,WM_USER+3
    91. @@:; Найти окно получателя
    92. mov edx,offset szWin
    93.         invoke  FindWindow,NULL
    94.         or      eax,eax
    95.         jz      wmBYE
    96.         ; Отправить данные получателю
    97. mov qword ptr[rsp+20h],SMTO_ABORTIFHUNG
    98. mov qword ptr[rsp+28h],250
    99. and qword ptr[rsp+30h],0
    100.         invoke  SendMessageTimeout,eax,type0,hWnddlg,FSize
    101. ; Создаем пайп
    102. mov ecx,offset szPipeName
    103. xor r9d,r9d
    104. mov qword ptr[rsp+20h],OPEN_EXISTING
    105. mov [rsp+28h],r9
    106. mov [rsp+30h],r9
    107. invoke CreateFile,,GENERIC_WRITE,FILE_SHARE_READ
    108. mov hNamePipe,rax
    109. mov rdx,p
    110. lea r9d,cbWritten
    111. and qword ptr[rsp+20h],0
    112.         invoke WriteFile,eax,,FSize
    113. ;Закрываем дескриптор канала
    114. invoke CloseHandle,hNamePipe
    115. jmp wmBYE
    116. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT
    117.         je      wmSEND_TXT
    118.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO
    119.         je      wmSEND_ICO
    120.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV
    121.         je      wmSEND_WAV
    122. cmp     r8d,BN_CLICKED shl 16 + IDCANCEL
    123.         jne     wmBYE
    124. wmCLOSE:invoke EndDialog,,0
    125. wmBYE:  mov eax,TRUE
    126. exit0: leave
    127. retn
    128. DialogProc endp
    129. ;---------------------------------------
    130. szWin db 'Pipe Reciever',0
    131. szPipeName db "\\.\pipe\MyPipe",0; Имя создаваемого пайпа
    132. p1 dd 1
    133. wav_file db '..\Images\03.wav',0
    134. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define ID_TXT 100
    3. #define ID_SEND_TXT 101
    4. #define ID_SEND_ICO 102
    5. #define ID_SEND_WAV 103
    6. #define IDC_DIALOG 200
    7. #define IDC_ICON1 500
    8. #define IDC_IMG1 104
    9. IDC_ICON1 ICON "..\\Images\\icon1.ico"
    10. IDC_ICON2 ICON "..\\Images\\icon2.ico"
    11. IDC_DIALOG DIALOG 0, 0, 212, 140
    12. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    13. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    14. CAPTION "Pipe Sender"
    15. BEGIN
    16.     CONTROL      "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    17.     CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_ICON,5,23,128,128
    18.     CONTROL "Напишите что-нибудь и нажмите 'Отправить текст'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    19.     DEFPUSHBUTTON "Отправить текст",ID_SEND_TXT,149,27,60,15
    20.     PUSHBUTTON  "Отправить ICO",ID_SEND_ICO,  149,45,60,15
    21.     PUSHBUTTON  "Отправить WAV",ID_SEND_WAV,  149,65,60,15
    22.     PUSHBUTTON "Выход", IDCANCEL,            149,85,60,15
    23. END
    Текст приложения-клиента
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. WM_CLIPBOARDUPDATE equ 31Dh
    4. IDC_DIALOG equ 200
    5. ID_TXT equ 100
    6. ID_ICON equ 102
    7. IDC_ICON1 equ 500
    8. .code
    9. WinMain proc dummy:qword
    10. mov r9d,offset DialogProc
    11. and qword ptr[rsp+20h],0
    12.         invoke  DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    13.         invoke  RtlExitUserProcess,NULL
    14. WinMain endp
    15. DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword
    16. local cbRead:DWORD;Количество байт данных, принятых через канал
    17. local buffer:qword;Буфер для передачи данных через канал
    18. local lpwiocb:WAVEHDR
    19. local hWaveOut:qword
    20. mov hWnddlg,rcx
    21. mov lParam,r9
    22. cmp edx,WM_CLOSE
    23. je wmCLOSE
    24. cmp edx,WM_USER+1
    25. je wmUSER_1
    26. cmp edx,WM_USER+2
    27. je wmUSER_2
    28. cmp edx,WM_USER+3
    29. je wmUSER_3
    30. cmp edx,WM_COMMAND
    31. je wmCOMMAND
    32. xor eax,eax
    33. jmp exit0
    34. wmUSER_1:; Получить строку от первого приложения
    35. mov type0,CF_TEXT
    36. jmp @f
    37. wmUSER_2:mov type0,CF_DIB
    38. jmp @f
    39. wmUSER_3:mov type0,CF_WAVE
    40. @@: invoke GlobalAlloc,GMEM_FIXED,lParam
    41. mov buffer,rax
    42. mov ecx,offset lpszPipeName
    43. invoke CreateNamedPipe,,PIPE_ACCESS_INBOUND,PIPE_TYPE_BYTE,1,0,lParam,0,0
    44. mov hNamedPipe,rax
    45. invoke ConnectNamedPipe,eax,NULL
    46. lea r9d,cbRead
    47. and qword ptr[rsp+20h],0
    48. invoke ReadFile,hNamedPipe,buffer,lParam
    49. ;----------------------------------------------------
    50. cmp type0,CF_TEXT
    51. je TEXT
    52. cmp type0,CF_DIB
    53. je DIB
    54. WAVE: mov r8,buffer
    55.         add r8d,14h
    56.         lea ecx,hWaveOut
    57.         xor r9,r9
    58. mov [rsp+20h],r9
    59. mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
    60.         or edx,WAVE_MAPPER
    61.         invoke waveOutOpen
    62. ; Подготавливаем заголовок для вывода
    63. lea edx,lpwiocb
    64. mov edi,edx
    65. xor eax,eax
    66. mov ecx,(sizeof WAVEHDR)/8
    67. rep stosq
    68. mov rax,buffer
    69. mov ecx,eax
    70. add rax,2Ch
    71. mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных
    72. mov eax,[rcx+4]
    73. sub eax,2Ch
    74. mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных
    75. invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
    76. ; Запускаем проигрывание блока
    77. lea edx,lpwiocb
    78. mov rcx,hWaveOut
    79. mov r8d,sizeof WAVEHDR
    80. invoke waveOutWrite
    81. @@: test lpwiocb.dwFlags,WHDR_DONE
    82. jz @b
    83. lea edx,lpwiocb
    84. invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
    85. invoke waveOutClose,hWaveOut
    86. jmp @0
    87. ;------------------------------------------------------------
    88. TEXT: invoke  SetDlgItemText,hWnddlg,ID_TXT,buffer
    89. jmp @0
    90. ;----------------------------------------------------
    91. DIB: and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    92. mov qword ptr[rsp+20h],256
    93. mov qword ptr[rsp+28h],256
    94. invoke  CreateIconFromResourceEx,buffer,lParam,TRUE,30000h
    95. mov [rsp+20h],rax
    96. invoke  SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON
    97. ;-----------------------------------------------------------
    98. @0:     invoke GlobalFree,buffer
    99. invoke DisconnectNamedPipe,hNamedPipe
    100. invoke CloseHandle,hNamedPipe
    101. jmp wmBYE
    102. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL
    103. jne wmBYE
    104. wmCLOSE:;Перед завершением приложения закрываем дескриптор канала Mailslot
    105. invoke EndDialog,hWnddlg,0
    106. wmBYE:  mov eax,TRUE
    107. exit0: leave
    108. ret
    109. DialogProc endp
    110. type0 db ?
    111. lpszPipeName db "\\.\pipe\MyPipe",0;Имя создаваемого пайпа
    112. hNamedPipe dq ?;дескриптор пайпа
    113. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define IDC_DIALOG 200
    3. #define ID_TXT 100
    4. #define ID_ICON 102
    5. IDC_DIALOG DIALOG 0,0,212,140
    6. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    7. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    8. CAPTION "Pipe Reciever"
    9. BEGIN
    10. CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    11. CONTROL "",ID_TXT,"STATIC",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    12. DEFPUSHBUTTON  "Выход",IDCANCEL,149,27,60,15
    13. CONTROL "",ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128
    14. END
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    03. Memory Mapped File

    Обмен данными между процессами через файлы, отображенных на память. Обладает высоким быстродействием, так как данные передаются между процессами непосредственно через виртуальную память.
    Отображение создается функцией CreateFileMapping.
    Фрагмент кода в котором создается отображение файла, а затем выполняется отображение этого файла в память:
    Код (C):
    1. hFileMapping = CreateFileMapping(hSrcFile, NULL,PAGE_READWRITE,0,dwFileSize,NULL);
    2. if(hFileMapping == NULL)
    3.   return;
    4. lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
    5. if(lpFileMap == 0)
    6.   return;
    В качестве первого параметра для функции CreateFileMapping передают дескриптор файла, открытого функцией CreateFile. Последний параметр указан как NULL, поэтому отображение не имеет имени.
    Если отображение используется для передачи данных между процессами, указывают имя. Пользуясь этим именем, другие процессы смогут открыть отображение функцией OpenFileMapping.
    дескриптора файла, передаваемого функции CreateFileMapping через первый параметр. Если создается отображение только для того чтобы обеспечить передачу данных между процессами, не нужно создавать файл на диске компьютера. В качестве дескриптора файла указывается значение 0FFFFFFFFh (-1), создается отображение непосредственно в виртуальной памяти без использования дополнительного файла.
    Код (C):
    1. CHAR lpFileShareName[] = "$MyVerySpecialFileShareName$";
    2. hFileMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0, 100,lpFileShareName);
    После того как создан объект-отображение, выполняется отображение файла в память при помощи функции MapViewOfFile. В случае успеха эта функция вернет указатель на отображенную область памяти.
    Первый процесс создал отображение. Второй процесс, который выполняет обмен данными с первым процессом, открывает это отображение по имени при помощи функции OpenFileMapping:
    Код (C):
    1. hFileMapping = OpenFileMapping (FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName);
    Далее второе приложение выполняет отображение, вызывая функцию MapViewOfFile:
    Код (C):
    1. lpFileMap = MapViewOfFile(hFileMapping,FILE_MAP_READ| FILE_MAP_WRITE,0,0,0);
    Используя значением, полученное от функции MapViewOfFile, второе приложение получает указатель на отображенную область памяти. Эта область находится в тех же страницах виртуальной памяти, что и область, созданная первым процессом. Два процесса получили указатели на общие страницы памяти.
    Перед завершением работы процессы должны отменить отображение файла и освободить дескриптор созданного объекта-отображения:
    Код (C):
    1. UnmapViewOfFile(lpFileMap);
    2. CloseHandle(hFileMapping);
    Текст приложения-сервера
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. ID_TXT equ 100
    4. ID_SEND_TXT equ 101
    5. ID_SEND_ICO equ 102
    6. ID_SEND_WAV equ 103
    7. IDC_DIALOG equ 200
    8. IDC_ICON1 equ 500
    9. IDC_IMG1 equ 104
    10. .code
    11. WinMain proc dummy:qword
    12. mov r9d,256
    13. mov [rsp+20h],r9
    14. mov qword ptr [rsp+28],LR_DEFAULTCOLOR
    15. invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON;,256,256,LR_DEFAULTCOLOR
    16. mov r9d,offset DialogProc
    17. mov qword ptr[rsp+20h],rax
    18. invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    19. invoke RtlExitUserProcess,NULL
    20. WinMain endp
    21. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    22. size_of_buffer equ 96
    23. local buffer[size_of_buffer]:BYTE
    24. local FSize:dword
    25. local hResource:qword
    26. local pResource:qword
    27. local szReadWrite:qword
    28. local type0:qword
    29. mov hWnddlg,rcx
    30. mov lParam,r9
    31. cmp edx,WM_CLOSE
    32. je wmCLOSE
    33. cmp edx,WM_COMMAND
    34. je wmCOMMAND
    35. cmp edx,WM_INITDIALOG
    36. je wmINITDIALOG
    37. xor eax,eax
    38. jmp exit0
    39. wmINITDIALOG:;
    40.         invoke GetDlgItem,,IDC_IMG1
    41. invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    42. jmp wmBYE
    43. wmSEND_TXT:mov type0,WM_USER+1
    44. lea r8d,buffer
    45. invoke  GetDlgItemText,,ID_TXT,,size_of_buffer;255
    46.         or      eax,eax
    47.         jz      wmBYE
    48.         inc     eax
    49. mov FSize,eax
    50. ;созддание файла
    51. sub esp,40h
    52. xor r8,r8
    53. mov qword ptr[rsp+20h],OPEN_ALWAYS
    54. mov [rsp+28h],r8
    55. mov [rsp+30h],r8
    56. mov ecx,offset szMapName0
    57. invoke CreateFile,,GENERIC_READ or GENERIC_WRITE,,0
    58. mov hFile,rax
    59. lea edx,buffer
    60. lea r9d,szReadWrite
    61. and qword ptr[rsp+20h],0
    62. invoke WriteFile,eax,,FSize
    63. invoke Func,hFile,0
    64. jmp @0
    65. wmSEND_ICO:sub esp,30h
    66. mov type0,WM_USER+2
    67. mov edx,p1
    68. invoke FindResource,0,,RT_ICON; find the resource
    69. mov hResource,rax
    70. invoke  SizeofResource,0,eax ; get its size
    71. mov     FSize,eax
    72. invoke LoadResource,0,hResource ; load the resource
    73. invoke LockResource,eax
    74. mov esi,eax
    75. ;созддание в памяти объекта "проекция файла" и
    76. ;отображение проекции файла на адресное пространство процесса
    77. invoke Func,INVALID_HANDLE_VALUE,FSize
    78. ;-----------------------------------------------------------------
    79. mov ecx,FSize
    80. mov edi,eax;rdi,pMapping
    81. rep movsb
    82. ;--------------------------------------------------
    83. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    84. mov qword ptr[rsp+20h],256
    85. mov qword ptr[rsp+28h],256
    86. mov edx,FSize
    87. invoke  CreateIconFromResourceEx,pMapping,,TRUE,30000h;270376,TRUE,30000h
    88. mov [rsp+20h],rax
    89. invoke  SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON
    90. xor p1,11b
    91. jmp @0
    92. ;-------------------------------------------------------
    93. wmSEND_WAV:sub esp,40h
    94. mov type0,WM_USER+3
    95. mov ecx,offset wav_file
    96. xor r9d,r9d
    97. mov qword ptr[rsp+30h],r9
    98. mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE
    99. mov qword ptr[rsp+20h],OPEN_EXISTING
    100. invoke CreateFile,,GENERIC_READ or GENERIC_WRITE,\
    101. FILE_SHARE_READ or FILE_SHARE_WRITE
    102.         mov hFile,rax
    103. invoke Func,rax,0
    104. @0:; Найти окно получателя
    105. mov edx,offset szWin
    106.         invoke  FindWindow,NULL
    107.         or      eax,eax
    108.         jz      wmBYE
    109. ; Отправить данные получателю
    110. mov qword ptr[rsp+20h],SMTO_ABORTIFHUNG
    111. mov qword ptr[rsp+28h],5000
    112. and qword ptr[rsp+30h],0
    113.         invoke  SendMessageTimeout,eax,type0,hWnddlg,0
    114. invoke UnmapViewOfFile,pMapping
    115. invoke CloseHandle,hMapping
    116. invoke CloseHandle,hFile
    117. cmp type0,WM_USER+1
    118. jnz     wmBYE
    119. mov ecx,offset szMapName0
    120. invoke DeleteFile
    121. jmp wmBYE
    122. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT
    123.         je      wmSEND_TXT
    124.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO
    125.         je      wmSEND_ICO
    126. cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV
    127.         je      wmSEND_WAV
    128. cmp     r8d,BN_CLICKED shl 16 + IDCANCEL
    129.         jne     wmBYE
    130. wmCLOSE:invoke EndDialog,,0
    131. wmBYE:  mov eax,TRUE
    132. exit0: leave
    133. retn
    134. DialogProc endp
    135. ;----------------------------------------
    136. Func proc hFile:qword,FSize:qword
    137. mov FSize,rdx
    138. ;созддание в памяти объекта "проекция файла"
    139. movr qword ptr[rsp+28h],szMapName
    140. mov [rsp+20h],rdx
    141.         invoke CreateFileMapping,,0,PAGE_READWRITE,0
    142. mov hMapping,rax
    143. ;отображение проекции файла на адресное пространство процесса
    144. mov rax,FSize
    145. mov [rsp+20h],rax
    146. invoke MapViewOfFile,hMapping,FILE_MAP_ALL_ACCESS,0,0
    147. mov pMapping,rax
    148. leave
    149. ret
    150. Func endp
    151. ;---------------------------------------
    152. szWin db 'Memory-Mapped File Reciever',0
    153. wav_file db '..\Images\03.wav',0
    154. szMapName db "13-15=Mapping",0
    155. szMapName0 db "15.txt",0
    156. p1 dd 1
    157. hMapping dq ?
    158. pMapping dq ?
    159. hFile dq ?
    160. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define ID_TXT 100
    3. #define ID_SEND_TXT 101
    4. #define ID_SEND_ICO 102
    5. #define ID_SEND_WAV 103
    6. #define IDC_DIALOG 200
    7. #define IDC_ICON1 500
    8. #define IDC_IMG1 104
    9. IDC_ICON1 ICON "..\\Images\\icon1.ico"
    10. IDC_ICON2 ICON "..\\Images\\icon2.ico"
    11. IDC_DIALOG DIALOG 0, 0, 212, 140
    12. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    13. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    14. CAPTION "Memory-Mapped File Sender"
    15. BEGIN
    16.     CONTROL      "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    17.     CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_ICON,5,23,128,128
    18.     CONTROL "Напишите что-нибудь и нажмите 'Отправить текст'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    19.     DEFPUSHBUTTON "Отправить текст",ID_SEND_TXT,149,27,60,15
    20.     PUSHBUTTON  "Отправить ICO",ID_SEND_ICO,  149,45,60,15
    21.     PUSHBUTTON  "Отправить WAV",ID_SEND_WAV,  149,65,60,15
    22.     PUSHBUTTON "Выход", IDCANCEL,            149,85,60,15
    23. END
    Текст приложения-клиента
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. WM_CLIPBOARDUPDATE equ 31Dh
    4. IDC_DIALOG equ 200
    5. IMAGE_BASE equ 400000h
    6. ID_TXT equ 100
    7. ID_ICON equ 102
    8. IDC_ICON1 equ 500
    9. .code
    10. WinMain proc dummy:qword
    11. mov r9d,offset DialogProc
    12. and qword ptr[rsp+20h],0
    13.         invoke  DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    14.         invoke  RtlExitUserProcess,NULL
    15. WinMain endp
    16. DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword
    17. local pMapping:qword
    18. local hMapping:qword
    19. local FSize:dword
    20. local lpwiocb:WAVEHDR
    21. local hWaveOut:qword
    22. mov hWnddlg,rcx
    23. mov lParam,r9
    24. cmp edx,WM_CLOSE
    25. je wmCLOSE
    26. cmp edx,WM_USER+3
    27. je wmUSER_3
    28. cmp edx,WM_USER+1
    29. je wmUSER_1
    30. cmp edx,WM_USER+2
    31. je wmUSER_2
    32. cmp edx,WM_COMMAND
    33. je wmCOMMAND
    34. xor eax,eax
    35. jmp exit0
    36. wmUSER_2:; Получить иконку от первого приложения
    37. mov type0,CF_DIB
    38. jmp @f
    39. wmUSER_1:; Получить строку от первого приложения
    40. mov type0,CF_TEXT
    41. jmp @f
    42. wmUSER_3:; Получить музыку от первого приложения
    43. mov type0,CF_WAVE
    44. jmp @f
    45. @@: mov r8d,offset lpszName
    46. invoke OpenFileMapping,FILE_MAP_READ,FALSE
    47. mov hMapping,rax
    48. xor r8,r8
    49. mov [rsp+20h],r8
    50. invoke MapViewOfFile,eax,FILE_MAP_READ,,0
    51. mov pMapping,rax
    52. ;-------------------------------------------
    53. cmp type0,CF_DIB
    54. je DIB
    55. cmp type0,CF_TEXT
    56. je TEXT
    57. WAVE: mov r8,pMapping
    58.         add r8d,14h
    59.         lea ecx,hWaveOut
    60.         xor r9,r9
    61. mov [rsp+20h],r9
    62. mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
    63.         or edx,WAVE_MAPPER
    64.         invoke waveOutOpen
    65. ; Подготавливаем заголовок для вывода
    66. lea edx,lpwiocb
    67. mov edi,edx
    68. xor eax,eax
    69.         mov ecx,(sizeof WAVEHDR)/8
    70. rep stosq
    71. mov rax,pMapping
    72. mov ecx,eax
    73. add rax,2Ch
    74. mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных
    75. mov eax,[rcx+4]
    76. sub eax,2Ch
    77. mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных
    78. invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
    79. ; Запускаем проигрывание блока
    80. lea edx,lpwiocb
    81. mov rcx,hWaveOut
    82. mov r8d,sizeof WAVEHDR
    83. invoke waveOutWrite
    84. @@: cmp lpwiocb.dwFlags,WHDR_DONE or WHDR_PREPARED
    85. jnz @b
    86. lea edx,lpwiocb
    87. invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
    88. invoke waveOutClose,hWaveOut
    89.         jmp @f;wmBYE
    90. ;--------------------------------------------------
    91. TEXT: invoke  SetDlgItemText,hWnddlg,ID_TXT,pMapping
    92.         jmp @f;wmBYE
    93. ;------------------------------------------------------
    94. DIB: and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    95. mov qword ptr[rsp+20h],256
    96. mov qword ptr[rsp+28h],256
    97. invoke  CreateIconFromResourceEx,pMapping,lParam,TRUE,30000h
    98. mov [rsp+20h],rax
    99. invoke  SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON
    100. @@: invoke UnmapViewOfFile,pMapping
    101.         invoke CloseHandle,hMapping
    102. jmp wmBYE
    103. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL
    104. jne wmBYE
    105. wmCLOSE:invoke EndDialog,,0
    106. wmBYE:  mov eax,TRUE
    107. exit0: leave
    108. ret
    109. DialogProc endp
    110. align 10h
    111. lpszName db "13-15=Mapping",0
    112. type0 db ?
    113. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define IDC_DIALOG 200
    3. #define ID_TXT 100
    4. #define ID_ICON 102
    5. IDC_DIALOG DIALOG 0,0,212,140
    6. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    7. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    8. CAPTION "Memory-Mapped File Reciever"
    9. BEGIN
    10. CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    11. CONTROL "",ID_TXT,"STATIC",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    12. DEFPUSHBUTTON  "Выход",IDCANCEL,149,27,60,15
    13. CONTROL "",ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128
    14. END
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    07. Dynamic Data Exchange

    Механизм динамического обмена данными DDE (Dynamic Data Exchange), позволяет создать постоянно действующие каналы между несколькими одновременно работающими приложениями Windows. Каналы могут создаваться автоматически при запуске приложения или при необходимости и по явному запросу пользователя. После создания каналов, они будут работать без вмешательства пользователя.
    В Windows механизм DDE реализован через передачу сообщений с помощью функции SendMessage с использованием глобальных блоков памяти, доступных всем приложениям. При создании DDE-приложений программист вынужден вникать во все детали процесса создания канала связи, придерживаясь определенного в SDK протокола.
    Начиная с Windows 3.1 появилось расширение ― управляющая библиотека динамического обмена данными DDEML, выполненная как DLL.
    Библиотека DDEML упрощает DDE-приложения и избавляет программиста от учета деталей протокола обмена сообщениями.
    В Windows динамический обмен данных организуется с помощью библиотеки DDEML. Сетевые возможности Windows базируются на сетевом динамическом обмене данными Network DDE.
    Текст приложения-сервера
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. ID_TXT equ 100
    4. ID_SEND_TXT equ 101
    5. ID_SEND_ICO equ 102
    6. ID_SEND_WAV equ 103
    7. IDC_DIALOG equ 200
    8. IDC_ICON1 equ 500
    9. IDC_IMG1 equ 104
    10. WM_USER_INITIATE equ WM_USER + 1
    11. extern __imp_DdeGetData:qword
    12. .code
    13. WinMain proc dummy:qword
    14. mov r9d,256
    15. mov [rsp+20h],r9
    16. mov qword ptr [rsp+28],LR_DEFAULTCOLOR
    17. invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON;,256,256,LR_DEFAULTCOLOR
    18. mov r9d,offset DialogProc
    19. mov qword ptr[rsp+20h],rax
    20. invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    21. invoke RtlExitUserProcess,NULL
    22. WinMain endp
    23. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    24. local hFile:dword
    25. local cbWritten:dword
    26. local hResource:qword
    27. local pResource:qword
    28. mov hWnddlg,rcx
    29. mov lParam,r9
    30. cmp edx,WM_CLOSE
    31. je wmCLOSE
    32. cmp edx,WM_COMMAND
    33. je wmCOMMAND
    34. cmp edx,WM_INITDIALOG
    35. je wmINITDIALOG
    36. cmp edx,WM_USER_INITIATE
    37. je wmUSER_INITIATE
    38. xor eax,eax
    39. jmp exit0
    40. wmUSER_INITIATE:
    41. mov edx,offset szService
    42. invoke DdeCreateStringHandle,idInst,,CP_WINANSI
    43. mov hszService,rax
    44. mov edx,offset szTopic
    45. invoke DdeCreateStringHandle,idInst,,CP_WINANSI
    46. mov hszTopic,rax
    47. mov edx,offset szItem
    48. invoke DdeCreateStringHandle,idInst,,CP_WINANSI
    49. mov hszItem,rax
    50. ; Регистрируем сервис
    51. invoke DdeNameService,idInst,hszService,NULL,DNS_REGISTER
    52. jmp wmBYE
    53. wmINITDIALOG:
    54. ; mov hwnd,rcx
    55.         invoke GetDlgItem,,IDC_IMG1
    56. invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    57. ; Выполняем инициализацию
    58. mov ecx,offset idInst
    59. mov edx,offset DDEServerCallback
    60. invoke DdeInitialize,,,APPCLASS_STANDARD,0
    61. or eax,eax
    62. jz @f
    63. mov edx,offset Error0
    64. mov edx,offset szAppName
    65. invoke MessageBox,hWnddlg,,,MB_ICONEXCLAMATION or MB_OK
    66. jmp wmCLOSE
    67. ; После успешной инициализации получаем дескрипторы строк для сервиса, раздела и элемента данных
    68. @@:     invoke SendMessage,hWnddlg,WM_USER_INITIATE,0,0
    69. mov eax,TRUE
    70. jmp wmBYE
    71. wmSEND_ICO:mov edx,p1
    72. mov type0,(WM_USER+3)
    73. invoke FindResource,0,,RT_ICON; find the resource
    74. mov hResource,rax
    75. invoke  SizeofResource,0,eax ; get its size
    76. mov FSize,rax
    77. invoke LoadResource,0,hResource ; load the resource
    78. invoke LockResource,eax;pResource
    79. mov p,rax
    80.         mov ecx,eax
    81. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    82. mov qword ptr[rsp+20h],256
    83. mov qword ptr[rsp+28h],256
    84. invoke  CreateIconFromResourceEx,,FSize,TRUE,30000h;270376,TRUE,30000h
    85. mov [rsp+20h],rax
    86. invoke  SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON
    87. xor p1,11b
    88. jmp @f
    89. wmSEND_WAV:mov ecx,offset wav_file
    90. xor r9d,r9d
    91. mov type0,(WM_USER+4)
    92. mov qword ptr[rsp+30h],r9
    93. mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE
    94. mov qword ptr[rsp+20h],OPEN_EXISTING
    95. invoke CreateFile,,GENERIC_READ or GENERIC_WRITE,\
    96. FILE_SHARE_READ or FILE_SHARE_WRITE
    97.         mov hFile,eax
    98.         invoke GetFileSize,eax,0
    99. mov FSize,rax
    100. invoke GlobalAlloc,GPTR,eax
    101.         mov p,rax
    102. lea r9d,cbWritten
    103. and qword ptr[rsp+20h],0
    104.         invoke ReadFile,hFile,eax,FSize
    105.         invoke CloseHandle,hFile
    106. jmp @f
    107. wmSEND_TXT:invoke GlobalAlloc,GPTR,256
    108.         mov p,rax
    109. mov type0,(WM_USER+2)
    110. invoke GetDlgItemText,hWnddlg,ID_TXT,eax,256
    111. inc eax
    112. mov FSize,rax
    113. ; Найти окно получателя
    114. @@: mov edx,offset szWin
    115.         invoke  FindWindow,NULL
    116.         or      eax,eax
    117.         jz      wmBYE
    118.         ; Отправить данные получателю
    119.         invoke  PostMessage,eax,type0,hWnddlg,FSize
    120. jmp wmBYE
    121. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV
    122.         je      wmSEND_WAV
    123.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT
    124.         je      wmSEND_TXT
    125.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO
    126.         je      wmSEND_ICO
    127. cmp     r8d,BN_CLICKED shl 16 + IDCANCEL
    128.         jne     wmBYE
    129. wmCLOSE:;Завершение работы канала связи
    130. cmp hConvApp,NULL
    131. jnz @f
    132. invoke DdeDisconnect,hConvApp
    133. @@:; Сервис больше не доступен
    134. invoke DdeNameService,idInst,hszService,NULL,DNS_UNREGISTER
    135. ; Освобождение дескрипторов строк
    136. invoke DdeFreeStringHandle,idInst, hszService
    137. invoke DdeFreeStringHandle,idInst, hszTopic
    138. invoke DdeFreeStringHandle,idInst, hszItem
    139. invoke EndDialog,hWnddlg,0
    140. wmBYE:  mov eax,TRUE
    141. exit0: leave
    142. retn
    143. DialogProc endp
    144. DDEServerCallback proc wType:qword,wFmt:qword,hConv:qword,hsz1:qword,hsz2:qword,hData:qword,dwData1:qword,dwData2:qword
    145. mov hConv,r8
    146. mov hsz1,r9
    147. cmp ecx,XTYP_CONNECT
    148. je      xtypCONNECT
    149. cmp ecx,XTYP_REQUEST
    150. je xtypREQUEST
    151. cmp ecx,XTYP_EXECUTE
    152. je xtypEXECUTE
    153. cmp ecx,XTYP_ERROR
    154. je xtypERROR
    155. cmp ecx,XTYP_DISCONNECT
    156. je xtypDISCONNECT
    157. cmp ecx,XTYP_CONNECT_CONFIRM
    158. je xtypCONNECT_CONFIRM
    159. xor eax,eax
    160. jmp wmBYE
    161. xtypCONNECT:;Создание канала передачи данных
    162. ; Если сервис поддерживается, возвращаем признак успешного создания канала
    163. mov rax,hsz2
    164. cmp rax,hszService
    165. jne xtypEXECUTE
    166. mov eax,TRUE
    167. jmp wmBYE
    168. xtypDISCONNECT:; Завершение работы канала
    169. and hConvApp,NULL
    170. xtypERROR:; Ошибка
    171. ; Запрос на выполнение команды, отрабатывается вхолостую
    172. xtypEXECUTE: xor eax,eax
    173. jmp wmBYE
    174. xtypREQUEST:; Создаем дескриптор данных
    175.         cmp edx,CF_TEXT
    176. jz @f
    177. cmp edx,CF_BITMAP
    178. jz @f
    179. cmp edx,CF_WAVE
    180. jnz wmBYE
    181. @@: xor r9d,r9d
    182. mov rax,hszItem
    183. mov [rsp+20h],rax
    184. mov [rsp+28h],rdx
    185. mov [rsp+30h],r9
    186. invoke DdeCreateDataHandle,idInst,p,FSize
    187. ; В случае успеха возвращаем созданный дескриптор или ноль
    188. mov hData,rax
    189. jmp wmBYE
    190. ;  Подтверждение создания канала
    191. xtypCONNECT_CONFIRM:
    192. mov hConvApp,r8
    193. @@: xor eax,eax
    194. wmBYE: leave
    195. retn
    196. DDEServerCallback endp
    197. ;---------------------------------------
    198. szWin db 'DDE Reciever',0
    199. wav_file db '..\Images\03.wav',0
    200. Error0 db "Could not initialize server!",0
    201. ; дескриптор приложения, полученный после регистрации в библиотеке DDEML
    202. idInst dq 0
    203. hszService dq 0
    204. hszTopic dq 0
    205. hszItem dq 0
    206. ; дескриптор канала
    207. hConvApp dq 0
    208. ; Буфер для приема данных
    209. p dq ?
    210. szService db "07s",0
    211. szTopic db "Brer Rabbit",0
    212. szItem db "DDEData",0
    213. szAppName db "DDEML Server",0
    214. ;hwnd dq ?
    215. FSize dq ?
    216. type0 dq ?
    217. p1 dd 1
    218. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define ID_TXT 100
    3. #define ID_SEND_TXT 101
    4. #define ID_SEND_ICO 102
    5. #define ID_SEND_WAV 103
    6. #define IDC_IMG1 104
    7. #define IDC_DIALOG 200
    8. #define IDC_ICON1 500
    9. IDC_ICON1 ICON "..\\Images\\icon1.ico"
    10. IDC_ICON2 ICON "..\\Images\\icon2.ico"
    11. IDC_DIALOG DIALOG 0, 0, 212, 140
    12. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    13. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    14. CAPTION "DDE Sender"
    15. BEGIN
    16.     CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    17.     CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_ICON,5,23,128,128
    18.     CONTROL "Напишите что-нибудь и нажмите 'Отправить текст'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    19.     DEFPUSHBUTTON "Отправить текст",ID_SEND_TXT,149,27,60,15
    20.     PUSHBUTTON  "Отправить ICO",ID_SEND_ICO,  149,45,60,15
    21.     PUSHBUTTON "Отправить WAV",ID_SEND_WAV,  149,65,60,15
    22.     PUSHBUTTON "Выход", IDCANCEL,            149,85,60,15
    23. END
    Текст приложения-клиента
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. IDC_DIALOG equ 200
    4. ID_TXT equ 100
    5. ID_ICON equ 102
    6. IDC_ICON1 equ 500
    7. TXT equ 10
    8. ICO equ 11
    9. WAV equ 12
    10. WM_USER_INITIATE equ WM_USER + 1
    11. extern __imp_DdeGetData:qword
    12. .code
    13. WinMain proc dummy:qword
    14. mov r9d,offset DialogProc
    15. and qword ptr[rsp+20h],0
    16.         invoke  DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    17.         invoke  RtlExitUserProcess,NULL
    18. WinMain endp
    19. DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword
    20. local buffer:qword
    21. local lpwiocb:WAVEHDR
    22. local hWaveOut:qword
    23. local dwResult:dword
    24. mov hWnddlg,rcx
    25. mov lParam,r9
    26. cmp edx,WM_CLOSE
    27. je wmCLOSE
    28. cmp edx,WM_USER+4
    29. je MUSIC_FROM_SERVER
    30.         cmp edx,WM_USER+2
    31. je MSG_FROM_SERVER
    32.         cmp edx,WM_USER+3
    33. je ICON_FROM_SERVER
    34. cmp edx,WM_COMMAND
    35. je wmCOMMAND
    36. cmp edx,WM_USER_INITIATE
    37. je wmUSER_INITIATE
    38. cmp edx,WM_INITDIALOG
    39. je wmINITDIALOG
    40. xor eax,eax
    41. jmp exit0
    42. wmINITDIALOG:; Выполняем инициализацию
    43. xor esi,esi
    44. mov ecx,offset idInst
    45. mov edx,offset DDEServerCallback
    46. invoke DdeInitialize,,,APPCMD_CLIENTONLY or APPCLASS_STANDARD,0
    47. or eax,eax
    48. jnz Error
    49. ; После успешной инициализации получаем дескрипторы строк для сервиса, раздела и элемента данных
    50. @@:     invoke SendMessage,hWnddlg,WM_USER_INITIATE,0,0
    51. mov eax,TRUE
    52. jmp wmBYE
    53. ICON_FROM_SERVER:mov wFmt,CF_BITMAP
    54. jmp @f
    55. MSG_FROM_SERVER:mov wFmt,CF_TEXT
    56. jmp @f
    57. MUSIC_FROM_SERVER:mov wFmt,CF_WAVE
    58. @@: invoke GlobalAlloc,GMEM_FIXED,lParam
    59. mov buffer,rax
    60. ; Запускаем транзакцию чтения данных
    61. mov rax,hConv
    62. mov esi,4
    63. or eax,eax
    64. jz Error
    65. mov r8,rax
    66. mov rax,wFmt
    67. mov [rsp+20h],rax
    68. mov qword ptr[rsp+28h],XTYP_REQUEST
    69. mov qword ptr[rsp+30h],TIMEOUT_ASYNC;5000
    70. lea eax,dwResult
    71. mov [rsp+38h],rax
    72. invoke DdeClientTransaction,0,0,,hszItem
    73. ; Получаем строку от сервера
    74. mov esi,5
    75. or eax,eax;if(hData != NULL)
    76. jz Error
    77. invoke __imp_DdeGetData,eax,buffer,lParam,0
    78. mov esi,6
    79. or eax,eax
    80. jz Error
    81. cmp wFmt,CF_BITMAP
    82. jnz @f
    83. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    84. mov qword ptr[rsp+20h],256
    85. mov qword ptr[rsp+28h],256
    86. invoke  CreateIconFromResourceEx,buffer,eax,TRUE,30000h
    87. mov [rsp+20h],rax
    88. invoke  SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON
    89. jmp @0
    90. @@:     cmp wFmt,CF_TEXT
    91. jnz @f
    92. invoke  SetDlgItemText,hWnddlg,ID_TXT,buffer
    93. jmp @0
    94. ;-----------------------------------------------------------
    95. @@: mov r8,buffer
    96.         add r8d,14h
    97.         lea ecx,hWaveOut
    98.         xor r9,r9
    99. mov [rsp+20h],r9
    100. mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
    101.         or edx,WAVE_MAPPER
    102.         invoke waveOutOpen
    103. ; Подготавливаем заголовок для вывода
    104. lea edx,lpwiocb
    105. mov edi,edx
    106. xor eax,eax
    107. mov ecx,(sizeof WAVEHDR)/8
    108. rep stosq
    109. mov rax,buffer
    110. mov ecx,eax
    111. add rax,2Ch
    112. mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных
    113. mov eax,[rcx+4]
    114. sub eax,2Ch
    115. mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных
    116. invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
    117. ; Запускаем проигрывание блока
    118. lea edx,lpwiocb
    119. mov rcx,hWaveOut
    120. mov r8d,sizeof WAVEHDR
    121. invoke waveOutWrite
    122. @@: test lpwiocb.dwFlags,WHDR_DONE
    123. jz @b
    124. lea edx,lpwiocb
    125. invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
    126. invoke waveOutClose,hWaveOut
    127. ;------------------------------------------------------------
    128. @0: invoke GlobalFree,buffer
    129. jmp wmBYE
    130. wmUSER_INITIATE:; Инициализация DDEML и создание канала связи
    131. invoke DDEClientOpen
    132. or eax,eax
    133. jnz wmBYE
    134. mov edx,offset Error1
    135. mov r8d,offset szAppName
    136. invoke MessageBox,hWnddlg,,,MB_ICONEXCLAMATION or MB_YESNO
    137. cmp eax,IDNO
    138. jz      wmBYE
    139. mov ecx,offset szService
    140. invoke WinExec,,SW_SHOW
    141. cmp eax,32
    142. mov esi,2
    143. jb Error
    144. ; После удачного запуска повторяем попытку инициализации DDEML и создания канала связи
    145. invoke DDEClientOpen
    146. jmp wmBYE
    147. Error: mov r8d,offset szAppName
    148. invoke MessageBox,hWnddlg,ErrorMsg[rsi*8],,MB_ICONEXCLAMATION
    149. jmp aExit
    150. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL
    151. jne wmBYE
    152. wmCLOSE:; Завершаем работу с DDEML. Закрываем канал связи
    153. cmp hConv,0
    154. jz @f
    155. invoke DdeDisconnect,hConv
    156. @@:; Освобождаем дескрипторы строк
    157. invoke DdeFreeStringHandle,idInst,hszService
    158. invoke DdeFreeStringHandle,idInst,hszTopic
    159. invoke DdeFreeStringHandle,idInst,hszItem
    160. aExit: invoke EndDialog,hWnddlg,0
    161. wmBYE:  mov eax,TRUE
    162. exit0: leave
    163. ret
    164. DialogProc endp
    165. DDEServerCallback proc wType:qword,wFmt:qword,hConv:qword,hsz1:qword,hsz2:qword,hData:qword,dwData1:qword,dwData2:qword
    166. xor eax,eax
    167. wmBYE: leave
    168. retn
    169. DDEServerCallback endp
    170. DDEClientOpen proc
    171. local dummy:qword
    172. ; При успешной инициализации создаем дескрипторы строк для сервиса,
    173. ; раздела и элемента данных
    174. mov edx,offset szService
    175. invoke DdeCreateStringHandle,idInst,,CP_WINANSI
    176. mov hszService,rax
    177. mov edx,offset szTopic
    178. invoke DdeCreateStringHandle,idInst,,CP_WINANSI
    179. mov hszTopic,rax
    180. mov edx,offset szItem
    181. invoke DdeCreateStringHandle,idInst,,CP_WINANSI
    182. mov hszItem,rax
    183. ; Устанавливаем канал связи
    184. invoke DdeConnect,idInst, hszService, hszTopic,0
    185. mov hConv,rax
    186. ; Возвращаем дескриптор созданного канала связи
    187. leave
    188. ret
    189. DDEClientOpen endp
    190. ;-----------------------------------
    191. szAppName db "DDEML Client",0
    192. szService db "07s",0
    193. szTopic db "Brer Rabbit",0
    194. szItem db "DDEData",0
    195. ErrorMsg dq Error0,Error1,Error2,Error3,Error4,Error5,Error6
    196. Error0 db "Could not initialize client!",0
    197. Error1 db "Сервер не запущен",10,"Запустить?",0
    198. Error2 db "Невозможно запустить сервер",0
    199. Error3 db "Сервер не отвечает",0
    200. Error4 db "hConv = 0",0
    201. Error5 db "hData = 0",0
    202. Error6 db "lParam = 0",0
    203. ; дескриптор приложения для DDEML
    204. hConv dq 0
    205. idInst dq 0
    206. hszService dq ?
    207. hszTopic dq ?
    208. hszItem dq ?
    209. wFmt dq ?
    210. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define IDC_DIALOG 200
    3. #define ID_TXT 100
    4. #define ID_ICON 102
    5. IDC_DIALOG DIALOG 0,0,212,140
    6. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    7. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    8. CAPTION "DDE Reciever"
    9. BEGIN
    10.         CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    11. CONTROL "",ID_TXT,"STATIC",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    12. DEFPUSHBUTTON  "Выход",IDCANCEL,149,27,60,15
    13. CONTROL "",ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128
    14. END
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    05. Mailslot

    Mailslot-каналы позволяют выполнять одностороннюю передачу данных от одного или нескольких клиентов к одному или нескольким серверам. Особенность mailslot-каналов в том, что они позволяют передавать данные в широковещательном режиме.
    На компьютере или в сети могут работать несколько серверных процессов, способных получать сообщения через mailslot-каналы. При этом один клиентский процесс может посылать сообщения сразу всем этим серверным процессам.
    Создание mailslot-канала
    Mailslot-канал создается серверным процессом с помощью функции CreateMailslot. После создания серверный процесс получает дескриптор mailslot-канала. Используя этот дескриптор, сервер может читать сообщения, посылаемые в канал клиентскими процессами. Сервер не может выполнять над mailslot-каналом операцию записи, так как этот канал предназначен только для односторонней передачи данных ― от клиента к серверу.
    Прототип функции CreateMailslot:
    Код (C):
    1. HANDLE CreateMailslot(
    2.   LPCTSTR lpName,          // адрес имени канала Mailslot
    3.   DWORD   nMaxMsgSize,     // максимальный размер сообщения
    4.   DWORD   lReadTimeout,    // время ожидания для чтения
    5.   LPSECURITY_ATTRIBUTES lpSecurityAttributes); // адрес структуры защиты
    Через параметр lpName передают функции CreateMailslot адрес строки символов с именем mailslot-канала. Имя имеет следующий вид:
    Код (C):
    1. \\.\mailslot\[Путь]Имя_Канала
    В этом имени путь необязательная компонента. Но можно указать его аналогично тому, как это делается для файлов. Имя mailslot-канала задается аналогично имени pipe-канала.
    Параметр nMaxMsgSize ― максимальный размер сообщений, передаваемых через mailslot-канал. Можно указать нулевое значение, при этом размер сообщений не будет ограничен. Есть одно исключение ― размер широковещательных сообщений, передаваемых всем рабочим станциям и серверам домена не должен превышать 400 байт.
    С помощью параметра lReadTimeout серверное приложение задает время ожидания для операции чтения в миллисекундах, по истечении которого функция чтения вернет код ошибки. Если в этом параметре указать значение MAILSLOT_WAIT_FOREVER, ожидание будет бесконечным.
    Параметр lpSecurityAttributes задает адрес структуры защиты, который можно указать как NULL.
    При ошибке функцией CreateMailslot возвращается значение INVALID_HANDLE_VALUE. Код ошибки можно определить при помощи функции GetLastError.
    Пример использования функции CreateMailslot в серверном приложении:
    Код (C):
    1. LPSTR lpszMailslotName = "\\\\.\\mailslot\\$MailslotName$";
    2. hMailslot = CreateMailslot(lpszMailslotName, 0, MAILSLOT_WAIT_FOREVER, NULL);
    В примере задан максимальный размер сообщения, поэтому на эту величину нет ограничений (кроме ограничения в 400 байт для сообщений, передаваемых всем компьютерам домена в широковещательном режиме).
    Время ожидания указано как MAILSLOT_WAIT_FOREVER, поэтому функции, работающие с данным mailslot-каналом , будут работать в блокирующем режиме.
    Открытие mailslot-канала
    Сперва клиентский процесс должен открыть mailslot-канал. Для этого используют функцию CreateFile
    Код (C):
    1. LPSTR lpszMailslotName = "\\\\.\\mailslot\\$MailslotName$";
    2. hMailslot = CreateFile( lpszMailslotName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    Здесь в качестве первого параметра функции CreateFile передается имя mailslot-канала. Вы можете открыть mailslot-канал, созданный на другой рабочей станции в сети. Для этого строка имени канала, передаваемая функции CreateFile, должна иметь следующий вид:
    Код (C):
    1.  \\Имя_Рабочей_Станции\mailslot\[Путь]Имя_Канала
    Можно открыть канал для передачи сообщений всем рабочим станциям заданного домена. Для этого необходимо задать имя по следующему образцу:
    Код (C):
    1. \\Имя_Домена\mailslot\[Путь]Имя_Канала
    Для передачи сообщений одновременно всем рабочим станциям сети первичного домена имя задается следующим образом
    Код (C):
    1. \\*\mailslot\[Путь]Имя_Канала
    В качестве второго параметра функции CreateFile используют константу GENERIC_WRITE. Эта константа определяет, что над открываемым каналом будет выполняться операция записи. Клиентский процесс может только посылать сообщения в mailslot-канал, но не читать их оттуда. Чтение сообщений из mailslot-канала ― задача для серверного процесса.
    Третий параметр FILE_SHARE_READ, так как сервер может читать сообщения, посылаемые одновременно несколькими клиентскими процессами.
    Константа OPEN_EXISTING используется потому, что функция CreateFile открывает существующий канал, а не создает новый.
    Запись сообщений в канал Mailslot
    Запись сообщений в mailslot-канал выполняет клиентский процесс, вызывая для этого функцию WriteFile.
    Код (C):
    1. HANDLE hMailslot;
    2. char   szBuf[512];
    3. DWORD  cbWritten;
    4. WriteFile(hMailslot, szBuf, strlen(szBuf) + 1,  &cbWritten, NULL);
    В качестве первого параметра этой функции необходимо передать дескриптор mailslot-канала, полученный от функции CreateFile.
    Второй параметр определяет адрес буфера с сообщением, третий ― размер сообщения. Если сообщение передается в виде текстовой строки, тогда закрыть строку нужно нулем, для определения длины сообщения можно воспользоваться функцией strlen.
    Чтение сообщений из канала Mailslot
    Серверный процесс может читать сообщения из созданного им mailslot-канала при помощи функции ReadFile
    Код (C):
    1. HANDLE hMailslot;
    2. char   szBuf[512];
    3. DWORD  cbRead;
    4. ReadFile(hMailslot, szBuf, 512, &cbRead, NULL);
    Через первый параметр функции ReadFile передается дескриптор созданного mailslot-канала, полученный от функции CreateMailslot. Второй и третий параметры задают, адрес буфера сообщения и его размер.
    Перед выполнением операции чтения следует проверить состояние mailslot-канала. Если в mailslot-канале нет сообщений, то функцию ReadFile вызывать не следует. Для проверки состояния канала воспользуйтесь функцией GetMailslotInfo.
    Определение состояния канала Mailslot
    Серверный процесс может определить текущее состояние mailslot-канала по его дескриптору с помощью функции GetMailslotInfo
    Код (C):
    1. BOOL GetMailslotInfo(
    2.   HANDLE  hMailslot,        // дескриптор канала Mailslot
    3.   LPDWORD lpMaxMessageSize, // адрес максимального размера сообщения
    4.   LPDWORD lpNextSize,    // адрес размера следующего сообщения
    5.   LPDWORD lpMessageCount,   // адрес количества сообщений
    6.   LPDWORD lpReadTimeout);   // адрес времени ожидания
    Через параметр hMailslot передается дескриптор mailslot-канала , состояние которого необходимо определить.
    Остальные параметры ― указатели на переменные типа DWORD, в которые будут записаны параметры состояния mailslot-канала.
    В переменную, адрес которой передается через параметр lpMaxMessageSize, после возвращения из функции GetMailslotInfo будет записан максимальный размер сообщения. Это значение можно использовать для динамического получения буфера памяти, в который это сообщение будет прочитано функцией ReadFile.
    В переменную, адрес которой указан через параметр lpNextSize, записывается размер следующего сообщения, если оно есть в канале. Если в канале больше нет сообщений, в эту переменную будет записана константа MAILSLOT_NO_MESSAGE.
    С помощью параметра lpMessageCount можно определить количество сообщений, записанных в канал клиентскими процессами. Если это количество равно нулю ― не следует вызывать функцию ReadFile для чтения несуществующего сообщения.
    В переменную, адрес которой задается в параметре lpReadTimeout, записывается текущее время ожидания, установленное для канала (в миллисекундах).
    Если вся информация, которую можно получить с помощью функции GetMailslotInfo не нужна, некоторые из ее параметров (первого) можно указать как NULL.
    В случае успешного завершения функция GetMailslotInfo возвращает значение TRUE, а при ошибке ― FALSE. Код ошибки можно получить, вызвав функцию GetLastError.
    Пример использования функции GetMailslotInfo:
    Код (C):
    1. BOOL fReturnCode;
    2. DWORD  cbMessages;
    3. DWORD  cbMsgNumber;
    4. fReturnCode = GetMailslotInfo(hMailslot, NULL, &cbMessages, &cbMsgNumber, NULL);
    Изменение состояния канала Mailslot
    С помощью функции SetMailslotInfo серверный процесс может изменить время ожидания для mailslot-канала уже после его создания.
    Прототип функции SetMailslotInfo
    Код (C):
    1. BOOL SetMailslotInfo(
    2.   HANDLE hMailslot,      // дескриптор канала Mailslot
    3.   DWORD  dwReadTimeout); // время ожидания
    Через параметр hMailslot функции SetMailslotInfo передается дескриптор mailslot-канала, для которого нужно изменить время ожидания.
    Новое значение времени ожидания в миллисекундах задается через параметр dwReadTimeout. Можно указать здесь значение 0 или MAILSLOT_WAIT_FOREVER. Если dwReadTimeout=0 функции, работающие с каналом, вернут управление немедленно, dwReadTimeout=MAILSLOT_WAIT_FOREVER ― будут находиться в состоянии ожидания до тех пор, пока не завершится выполняемая операция.
    Текст приложения-сервера
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. WM_CLIPBOARDUPDATE equ 31Dh
    4. ID_TXT equ 100
    5. ID_SEND_TXT equ 101
    6. ID_SEND_ICO equ 102
    7. ID_SEND_WAV equ 103
    8. IDC_DIALOG equ 200
    9. IDC_ICON1 equ 500
    10. IDC_IMG1 equ 104
    11. .code
    12. WinMain proc dummy:qword
    13. mov r9d,256
    14. mov [rsp+20h],r9
    15. mov qword ptr [rsp+28],LR_DEFAULTCOLOR
    16. invoke LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON;,256,256,LR_DEFAULTCOLOR
    17. mov r9d,offset DialogProc
    18. mov qword ptr[rsp+20h],rax
    19. invoke DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    20. invoke RtlExitUserProcess,NULL
    21. WinMain endp
    22. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    23. local cbWritten:dword;Количество байт, переданных через канал
    24. local FSize:dword;
    25. local p:qword
    26. local hMailslot:qword; дескриптор канала Mailslot
    27. local hResource:qword
    28. local hFile:dword
    29. local szReadWrite:qword ;number of bytes actually read or write
    30. local lpwiocb:WAVEHDR
    31. local hWaveOut:qword
    32. local type0:qword
    33. mov hWnddlg,rcx
    34. mov lParam,r9
    35. cmp edx,WM_CLOSE
    36. je wmCLOSE
    37. cmp edx,WM_COMMAND
    38. je wmCOMMAND
    39. cmp edx,WM_INITDIALOG
    40. je wmINITDIALOG
    41. xor eax,eax
    42. jmp exit0
    43. wmINITDIALOG:;
    44.         invoke GetDlgItem,,IDC_IMG1
    45. invoke SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    46. jmp wmBYE
    47. wmSEND_TXT:invoke GlobalAlloc,GPTR,256
    48.         mov p,rax;Буфер для передачи данных через канал
    49. invoke  GetDlgItemText,hWnddlg,ID_TXT,eax,256
    50.         or      eax,eax
    51.         jz      wmBYE
    52.         inc     eax
    53. mov FSize,eax
    54. mov type0,WM_USER+1
    55. jmp @f
    56. wmSEND_ICO:mov edx,p1
    57. invoke FindResource,0,,RT_ICON; find the resource
    58. mov hResource,rax
    59. invoke  SizeofResource,0,eax ; get its size
    60. mov FSize,eax
    61. invoke LoadResource,0,hResource ; load the resource
    62. invoke LockResource,eax;pResource
    63.   mov p,rax
    64. ;-------------------------------------------------
    65. and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    66. mov qword ptr[rsp+20h],256
    67. mov qword ptr[rsp+28h],256
    68. mov edx,FSize
    69. invoke  CreateIconFromResourceEx,p,,TRUE,30000h;270376,TRUE,30000h
    70. mov [rsp+20h],rax
    71. invoke  SendDlgItemMessage,hWnddlg,IDC_IMG1,STM_SETIMAGE,IMAGE_ICON
    72. xor p1,11b
    73. mov type0,WM_USER+2
    74. jmp @f
    75. wmSEND_WAV:sub esp,40h
    76. mov ecx,offset wav_file
    77. xor r9d,r9d
    78. mov qword ptr[rsp+30h],r9
    79. mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE
    80. mov qword ptr[rsp+20h],OPEN_EXISTING
    81. invoke CreateFile,,GENERIC_READ or GENERIC_WRITE,\
    82. FILE_SHARE_READ or FILE_SHARE_WRITE
    83.         mov hFile,eax
    84.         invoke GetFileSize,eax,0
    85. mov FSize,eax
    86. invoke GlobalAlloc,GPTR,eax
    87.         mov p,rax
    88. mov type0,WM_USER+3
    89. lea r9d,cbWritten
    90. and qword ptr[rsp+20h],0
    91.         invoke ReadFile,hFile,eax,FSize
    92.         invoke CloseHandle,hFile
    93. @@:; Создаем канал с процессом MSLOTS
    94. mov ecx,offset szMailslotName
    95. xor r9d,r9d
    96. mov qword ptr[rsp+20h],OPEN_EXISTING
    97. mov [rsp+28h],r9
    98. mov [rsp+30h],r9
    99. invoke CreateFile,,GENERIC_WRITE,FILE_SHARE_READ
    100. mov hMailslot,rax
    101. lea r9d,cbWritten
    102. and qword ptr[rsp+20h],0
    103.         invoke WriteFile,hMailslot,p,FSize
    104. ; Найти окно получателя
    105. mov edx,offset szWin
    106.         invoke  FindWindow,NULL
    107.         or      eax,eax
    108.         jz      wmBYE
    109. ; Отправить данные получателю
    110. invoke PostMessage,eax,type0,hWnddlg,FSize
    111. ;Закрываем дескриптор канала
    112. invoke CloseHandle,hMailslot
    113. jmp wmBYE
    114. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + ID_SEND_TXT
    115.         je      wmSEND_TXT
    116.         cmp r8d,BN_CLICKED shl 16 + ID_SEND_ICO
    117.         je      wmSEND_ICO
    118. cmp r8d,BN_CLICKED shl 16 + ID_SEND_WAV
    119.         je      wmSEND_WAV
    120. cmp     r8d,BN_CLICKED shl 16 + IDCANCEL
    121.         jne     wmBYE
    122. wmCLOSE:invoke EndDialog,,0
    123. wmBYE:  mov eax,TRUE
    124. exit0: leave
    125. retn
    126. DialogProc endp
    127. ;---------------------------------------
    128. szWin db 'Mailslot Reciever',0
    129. szMailslotName db "\\.\mailslot\brer_Rabbit",0; Имя создаваемого канала
    130. wav_file db '..\Images\03.wav',0
    131. p1 dd 1
    132. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define ID_TXT 100
    3. #define ID_SEND_TXT 101
    4. #define ID_SEND_ICO 102
    5. #define ID_SEND_WAV 103
    6. #define IDC_DIALOG 200
    7. #define IDC_ICON1 500
    8. #define IDC_IMG1 104
    9. IDC_ICON1 ICON "..\\Images\\icon1.ico"
    10. IDC_ICON2 ICON "..\\Images\\icon2.ico"
    11. IDC_DIALOG DIALOG 0, 0, 212, 140
    12. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    13. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    14. CAPTION "Mailslot Sender"
    15. BEGIN
    16.     CONTROL      "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    17.     CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_ICON,5,23,128,128
    18.     CONTROL "Напишите что-нибудь и нажмите 'Отправить текст'",ID_TXT,"EDIT",WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,5,7,199,13
    19.     DEFPUSHBUTTON "Отправить текст",ID_SEND_TXT,149,27,60,15
    20.     PUSHBUTTON  "Отправить ICO",ID_SEND_ICO,  149,45,60,15
    21.     PUSHBUTTON  "Отправить WAV",ID_SEND_WAV,  149,65,60,15
    22.     PUSHBUTTON "Выход", IDCANCEL,            149,85,60,15
    23. END
    Текст приложения-клиента
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. WM_CLIPBOARDUPDATE equ 31Dh
    4. IDC_DIALOG equ 200
    5. ID_TXT equ 100
    6. ID_ICON equ 102
    7. IDC_ICON1 equ 500
    8. TXT equ 10
    9. ICO equ 11
    10. WAV equ 12
    11. .code
    12. WinMain proc dummy:qword
    13. mov r9d,offset DialogProc
    14. and qword ptr[rsp+20h],0
    15.         invoke  DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    16.         invoke  RtlExitUserProcess,NULL
    17. WinMain endp
    18. DialogProc proc hWnddlg:qword,msg:qword,wParam:qword,lParam:qword
    19. local cbRead:DWORD;Количество байт данных, принятых через канал
    20. local cbMessages:DWORD;Размер сообщения в байтах
    21. local cbMsgNumber:DWORD;Количество сообщений в канале Mailslot
    22. local buffer:QWORD
    23. local lpwiocb:WAVEHDR
    24. local hWaveOut:qword
    25. mov hWnddlg,rcx
    26. mov lParam,r9
    27. cmp edx,WM_CLOSE
    28. je wmCLOSE
    29. cmp edx,WM_INITDIALOG
    30. je wmINITDIALOG
    31. cmp edx,WM_USER+1
    32. je wmUSER_1
    33. cmp edx,WM_USER+2
    34. je wmUSER_2
    35. cmp edx,WM_USER+3
    36. je wmUSER_3
    37. cmp edx,WM_COMMAND
    38.      je wmCOMMAND
    39.      xor eax,eax
    40.      jmp exit0
    41. wmUSER_1:mov type0,CF_TEXT
    42.      jmp @f
    43.      wmUSER_2:mov type0,CF_DIB
    44.      jmp @f
    45. wmUSER_3:mov type0,CF_WAVE
    46. ; Определяем состояние канала Mailslot
    47. @@: lea r8d,cbMessages
    48.      lea r9d,cbMsgNumber
    49.      xor edx,edx
    50.      mov [rsp+20h],rdx
    51.      invoke GetMailslotInfo,hMailslot
    52. ; Выполняем задержку на  500 миллисекунд
    53.      invoke Sleep,500
    54. ; Если в канале есть Mailslot сообщения, читаем первое из них и выводим на экран
    55.      cmp cbMsgNumber,0
    56.      jz wmBYE
    57.      invoke GlobalAlloc,GMEM_FIXED,lParam
    58.      mov buffer,rax
    59.      mov edx,eax
    60.      lea r9d,cbRead
    61.      and qword ptr[rsp+20h],0
    62.      invoke ReadFile,hMailslot,,lParam
    63.      cmp type0,CF_TEXT
    64.      je TEXT
    65.         cmp type0,CF_DIB
    66.      je DIB
    67. WAVE: mov r8,buffer
    68.         add r8d,14h
    69.         lea ecx,hWaveOut
    70.         xor r9,r9
    71.      mov [rsp+20h],r9
    72.      mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
    73.         or edx,WAVE_MAPPER
    74.         invoke waveOutOpen
    75. ; Подготавливаем заголовок для вывода
    76.      lea edx,lpwiocb
    77.      mov edi,edx
    78.      xor eax,eax
    79.      mov ecx,(sizeof WAVEHDR)/8
    80.      rep stosq
    81.      mov rax,buffer
    82.      mov ecx,eax
    83.      add rax,2Ch
    84.      mov [rdx].WAVEHDR.lpData,rax ;адрес блока данных
    85.      mov eax,[rcx+4]
    86.      sub eax,2Ch
    87.      mov [rdx].WAVEHDR.dwBufferLength,eax ;размер блока данных
    88.      invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
    89. ; Запускаем проигрывание блока
    90.      lea edx,lpwiocb
    91.      mov rcx,hWaveOut
    92.      mov r8d,sizeof WAVEHDR
    93.      invoke waveOutWrite
    94. @@: test lpwiocb.dwFlags,WHDR_DONE
    95.      jz @b
    96.      lea edx,lpwiocb
    97.      invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
    98.      invoke waveOutClose,hWaveOut
    99.      invoke GlobalFree,buffer
    100.      jmp wmBYE
    101. TEXT: invoke  SetDlgItemText,hWnddlg,ID_TXT,buffer
    102.      invoke GlobalFree,buffer
    103.      jmp wmBYE
    104. DIB:    and qword ptr[rsp+30h],LR_DEFAULTCOLOR;LR_DEFAULTCOLOR=0
    105.      mov qword ptr[rsp+20h],256
    106.      mov qword ptr[rsp+28h],256
    107.      invoke  CreateIconFromResourceEx,buffer,lParam,TRUE,30000h
    108.      mov [rsp+20h],rax
    109.      invoke  SendDlgItemMessage,hWnddlg,ID_ICON,STM_SETIMAGE,IMAGE_ICON
    110.      invoke GlobalFree,buffer
    111.      jmp wmBYE
    112. wmINITDIALOG:; Создаем канал Mailslot, имеющий имя lpszMailslotName
    113.      mov ecx,offset lpszMailslotName
    114.      invoke CreateMailslot,,0,MAILSLOT_WAIT_FOREVER, NULL
    115.      mov hMailslot,rax
    116.      jmp wmBYE
    117. wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL
    118.      jne wmBYE
    119. wmCLOSE:;Перед завершением приложения закрываем дескриптор канала Mailslot
    120.      invoke CloseHandle,hMailslot
    121.      invoke EndDialog,hWnddlg,0
    122. wmBYE:  mov eax,TRUE
    123. exit0: leave
    124. ret
    125. DialogProc endp
    126. lpszMailslotName db "\\.\mailslot\brer_Rabbit",0;Имя создаваемого канала Mailslot
    127. hMailslot dq ?;дескриптор канала Mailslot
    128. type0 db ?
    129. end
    ресурсы
    Код (C):
    1. #include "resource.h"
    2. #define IDC_DIALOG 200
    3. #define ID_TXT 100
    4. #define ID_ICON 102
    5. IDC_DIALOG DIALOG 0,0,212,140
    6. STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
    7. WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
    8. CAPTION "Mailslot Reciever"
    9. BEGIN
    10.      CONTROL "",-1,"BUTTON",BS_GROUPBOX, 2, -1, 207, 24
    11.      CONTROL "",ID_TXT,"STATIC",WS_BORDER | WS_TABSTOP |     ES_AUTOHSCROLL,5,7,199,13
    12.      DEFPUSHBUTTON  "Выход",IDCANCEL,149,27,60,15
    13.       CONTROL "",ID_ICON,"STATIC",WS_CHILDWINDOW | SS_ICON,5,23,128,128
    14. END
     
    asmlamo нравится это.
  9. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795

    OLE/ActiveX

    Универсальная технология, одно из ее применений ― межпроцессный обмен данными. OLE создавалась на смену DDE. Для обмена данными существует интерфейс IDataObject. Для обмена данными по сети используется DCOM, ее можно рассматривать как объединение ActiveX и RPC.

    Windows Sockets

    Отвечает за обмен данными в глобальной сети. Сокеты используются в локальных сетях. Взаимодействие происходит через так называемые разъемы-"сокеты", которые представляют собой абстракцию конечных точек коммуникационной линии, соединяющей два приложения. С этими объектами программа работает, ждет соединения, посылает данные и так далее.

    Microsoft Message Queue (MSMQ)

    Этот протокол обеспечивает посылку сообщений между приложениями с помощью очереди сообщений. Отличие от стандартной очереди сообщений Windows ― он может работать с удаленными процессами и с процессами, которые на данный момент недоступны (например, не запущены). Доставка сообщения по адресу гарантируется. Оно ставится в специальную очередь сообщений и находится там до тех пор, пока не появляется возможность его доставить.

    Удаленный вызов процедур (Remote Procedure Call, RPC)

    С помощью этой технологии общение через сеть прозрачно как для сервера, так и для клиента. И серверу, и клиенту кажется, что "собеседник" расположен локально по отношению к ним.

    Distributed Component Object Model (DCOM)

    Программная архитектура, разработанная компанией Microsoft для распределения приложений между несколькими компьютерами в сети. Программный компонент на одной из машин может использовать DCOM для передачи сообщения (его называют удаленным вызовом процедуры) к компоненту на другой машине. DCOM автоматически устанавливает соединение, передает сообщение и возвращает ответ удаленного компонента.

    Remote Method Invocation (RMI)

    Механизм, который позволяет вызывать метод удаленного объекта. Все операции по подготовке и передаче данных инкапсулируются в вызываемом методе клиентского объекта-заглушки (stub). Вызов метода не отличается от вызова метода обычного локального объекта, за небольшим исключением:
    • локальные объекты передаются по значению (копии)
    • при передаче удаленного (Remote) объекта, если он экспортирован, передается stub этого объекта
    • передаваемые объекты должны быть Serializable
    • при вызове удаленного метода может возбуждаться исключение RemoteException (ошибки маршализации/демаршализации, передачи данных и другие возможные ошибки протокола)
    При вызове метода работают с удаленным интерфейсом, а не с удаленным классом.

    Common Object Request Broker Architecture (CORBA)

    Общая архитектура брокера объектных запросов; типовая архитектура опосредованных запросов к объектам) — технологический стандарт написания распределенных приложений, продвигаемый консорциумом (рабочей группой) OMG и соответствующая ему информационная технология. CORBA обеспечивает взаимодействие между системами, работающих под разными операционными системами, написанными на разных языках программирования и запущенных на разном вычислительном оборудовании. CORBA использует объектно-ориентированную модель, системы, использующие CORBA, не обязательно должны быть объектно-ориентированными. CORBA — пример парадигмы распределенной объектной системы.

    DLL

    Важной особенностью использования динамических библиотек является возможность одновременного использования одной библиотеки несколькими модулями. Динамическая библиотека становится продолжением запустившего ее приложения, загружаясь в адресное пространство процесса. Данные процесса доступны из динамической библиотеки и данные динамической библиотеки доступны для процесса. При компоновке динамической библиотеки сегмент данных объявлен как секция с общим доступом. При запуске приложения, которое будет загружать динамическую библиотеку, эта область памяти будет общей для всех приложений.
     
  10. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Код (C):
    1. static void SendString (LPCSTR string)
    2. {
    3.     HANDLE handles[257];
    4.     char name[32];
    5.     int i, length;
    6.  
    7.     for (i=0; i<257; i++)
    8.     {
    9.         sprintf (name, "Mutex#u", i);
    10.         handles[i] = CreateMutex (NULL, TRUE, name);
    11.     }
    12.  
    13.     length = lstrlen (string);
    14.     for (i=0; i<length; i++)
    15.     {
    16.         ReleaseMutex (handles[string[i]]);
    17.         WaitForSingleObject (handles[string[i]], INFINITE);
    18.     }
    19.  
    20.     ReleaseMutex (handles[256]);
    21.  
    22.     for (i=0; i<257; i++)
    23.         CloseHandle (handles[i]);
    24. }
    25. static LPSTR ReceiveString ()
    26. {
    27.     LPSTR string;
    28.     HANDLE handles[257];
    29.     char name[32];
    30.     int i, length, result;
    31.     string = malloc (1024);
    32.     length = 0;
    33.  
    34.     for (i=0; i<257; i++)
    35.     {
    36.         sprintf (name, "Mutex#u", i);
    37.         handles[i] = CreateMutex (NULL, FALSE, name);
    38.     }
    39.  
    40.     while (TRUE)
    41.     {
    42.         result = WaitForMultipleObjects (257, handles, FALSE, INFINITE);
    43.         if (result < 0 || result > 255)
    44.             break;
    45.      
    46.         string[length++] = (char)result;
    47.         ReleaseMutex (handles[result]);
    48.     }
    49.     string[length] = 0;
    50.  
    51.     for (i=0; i<257; i++)
    52.         CloseHandle (handles[i]);
    53.  
    54.     return string;
    55. }
    56.  
     
    Mikl___ и youneuoy нравится это.
  11. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795
    rmn,
    спасибо огромное! А разве у WaitForMultipleObjects может быть больше объектов, чем 64?
     
  12. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Не может. Это надо на потоках разруливать. Основной поток записывает в массив хендлов MAX-1 дескрипторов, а последним ― хендл вспомогательного потока, который ждет на следующих MAX-1 дескрипторах и опционально дополнительном вспомогательном потоке.
     
  13. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.795
    Объекты синхронизации

    08. Evet Pipes

    Windows позволяет создавать объекты синхронизации, которые называются событиями (event object). Объекты-события могут находиться в signaled состоянии или nonsignaled состоянии. Сигнальное состояние объекта (signaled) соответствует моменту времени, когда объект не принадлежит ни одному потоку и его можно "захватить". Состояние "сброшен" (nonsignaled) соответствует моменту, когда какой-либо поток уже владеет этим объектом. Доступ к объекту разрешается, когда поток, владеющий объектом, освободит его.
    Установка состояния выполняется вызовом соответствующей функции.
    Одна из задач создает объект-событие, вызывая для этого функцию CreateEvent. У события есть имя, которое доступно всем задачам активных процессов. В процессе создания или позже эта задача устанавливает событие в исходное состояние (signaled или nonsignaled).
    Вызывая функции WaitForSingleObject или WaitForMultipleObjects, задача ожидает момент, когда событие перейдет в signaled состояние.
    Другая задача, принадлежащая тому же самому или другому процессу, получает дескриптор события по его имени с помощью функции OpenEvent. Дальше используя функции SetEvent, ResetEvent или PulseEvent, приложение изменяет состояние события.
    После создания nonsignaled/неотмеченного события первая задача переходит в состояние ожидания, пока вторая задача не подготовит для нее данные. Как только это произойдет, вторая задача отмечает и затем сбрасывает событие, что приводит к завершению ожидания первой задачей.
    Отобразив подготовленные данные, первая задача опять входит в состояние ожидания, пока вторая задача не подготовит данные и не отметит событие. С помощью объекта-события две задачи синхронизируют свою работу.

    Создание события

    Для создания события приложение вызывает функцию CreateEvent
    Код (C):
    1. HANDLE CreateEvent(
    2.   LPSECURITY_ATTRIBUTES lpEventAttributes, // атрибуты защиты
    3.   BOOL    bManualReset,  // флаг ручного сброса события
    4.   BOOL    bInitialState, // флаг начального состояния события
    5.   LPCTSTR lpName       // адрес имени объекта-события
    6. );
    Параметр lpEventAttributes задает атрибуты защиты и в большинстве случаев может быть указан как NULL.
    Параметр bManualReset выбирает один из двух режимов работы объекта-события: ручной или автоматический. Если bManualReset=TRUE, событие нужно сбрасывать вручную при помощи функции ResetEvent. Если bManualReset=FALSE, событие будет сброшено (переведено в nonsignaled состояние) автоматически сразу после того как задача завершит ожидание этого события.
    Параметр bInitialState определяет начальное состояние события. Если bInitialState =TRUE, объект-событие создается в signaled/отмеченном состоянии, если bInitialState=FALSE ― в nonsignaled.
    Чтобы событием могли использовать задачи, созданные разными процессами, необходимо с помощью параметра lpName задать имя объекта-события. В качестве имени можно выбрать любое имя размером не более MAX_PATH=260 символов, не содержащее символ “\”.
    Если событие используется задачами, работающими в рамках одного процесса, имя события можно не задавать (lpName=NULL). Будет создано безымянное событие.
    В случае успешного завершения функция CreateEvent возвращает дескриптор события, который используется при выполнении операций над объектом-событием. При ошибке возвращается NULL (код ошибки получают при помощи GetLastError).
    Если при создании события указано имя уже существующего в системе события, созданного другой задачей ― тогда функция GetLastError возвратит значение ERROR_ALREADY_EXISTS=0B7h.

    Открытие события

    Если событие используется задачами, созданными в рамках одного процесса, его не нужно открывать. В качестве параметра функциям, изменяющим состояние объекта-события, можно передавать дескриптор события, полученный при создании от функции CreateEvent.
    Если событие используется для синхронизации задач, принадлежащих разным процессам, нужно при создании события задать его имя. Задача, изменяющая состояние события и принадлежащая другому процессу, должна открыть объект-событие с помощью функции OpenEvent, передав ей имя этого объекта.
    Прототип функции OpenEvent:
    Код (C):
    1. HANDLE OpenEvent(
    2.   DWORD   fdwAccess,      // флаги доступа
    3.   BOOL    fInherit,       // флаг наследования
    4.   LPCTSTR lpszEventName // адрес имени объекта-события
    5. );
    Флаги доступа, передаваемые через параметр fdwAccess, определяют требуемый уровень доступа к объекту-событию. Этот параметр может быть комбинацией следующих значений:
    Значениеhexbin Описание
    EVENT_QUERY_STATE
    SEMAPHORE_QUERY_STATE
    1​
    0.0000.0000.0000.0000.0001Право на запрос состояния объекта события
    EVENT_MODIFY_STATE
    SEMAPHORE_MODIFY_STATE
    2​
    0.0000.0000.0000.0000.0010 Полученный дескриптор можно использовать функциями SetEvent и ResetEvent
    4​
    0.0000.0000.0000.0000.0100
    8​
    0.0000.0000.0000.0000.1000
    DELETE
    10000​
    0.0001.0000.0000.0000.0000Право на удаление объекта
    READ_CONTROL
    20000​
    0.0010.0000.0000.0000.0000Право на чтение информации в дескрипторе безопасности для объекта, не включая информацию в SACL. Для чтения или записи SACL необходимо запросить право доступа ACCESS_SYSTEM_SECURITY
    WRITE_DAC
    40000​
    0.0100.0000.0000.0000.0000Право на изменение DACL в дескрипторе безопасности для объекта. Право доступа на запись к произвольному управляющему списку доступа объекта access control list (ACL)
    WRITE_OWNER
    80000​
    0.1000.0000.0000.0000.0000Право на изменение владельца в дескрипторе безопасности объекта.
    SYNCHRONIZE1000001.0000.0000.0000.0000.0000 Полученный дескриптор можно использовать в любых функциях ожидания события
    MUTEX_ALL_ACCESS1F00011.1111.0000.0000.0000.0001Указаны все возможные для Mutex флаги доступа
    EVENT_ALL_ACCESS
    SEMAPHORE_ALL_ACCESS
    1F00031.1111.0000.0000.0000.0011Указаны все возможные для Event и Semaphore флаги доступа
    Параметр fInherit определяет возможность наследования полученного дескриптора. Если fInherit=TRUE, дескриптор может наследоваться дочерними процессами. Если fInherit=FALSE, наследование не допускается.
    Через параметр lpszEventName передают имени объекта-события.
    С помощью OpenEvent несколько задач могут открыть один и тот же объект-событие и выполнять одновременное ожидание этого объекта.

    Установка события

    Для установки объекта-события в отмеченное состояние используется функция SetEvent:
    Код (C):
    1. BOOL SetEvent(HANDLE hEvent);
    В качестве параметра функции необходимо передать дескриптор объекта-события, полученного от CreateEvent или OpenEvent. При успешном завершении возвращается TRUE, при ошибке ― FALSE. Код ошибки получают через GetLastError.

    Cброс события

    Сброс события (установка в неотмеченное состояние) выполняется функцией ResetEvent:
    Код (C):
    1. BOOL ResetEvent(HANDLE hEvent);
    Если задача создала событие, работающее в автоматическом режиме, оно будет сбрасываться без помощи ResetEvent, если какая-либо задача выполняла ожидание этого события и событие произошло.

    Функция PulseEvent

    Функция PulseEvent выполняет установку объекта-события в signaled состояние с последующим сбросом события в nonsignaled состояние:
    Код (C):
    1. BOOL PulseEvent(HANDLE hEvent);
    Если эта функция вызвана для события, работающего в ручном режиме, то все задачи, ожидающие это событие, завершат ожидание и продолжат свою работу. Событие при этом будет установлено в nonsignaled состояние.
    Для автоматических объектов-событий выполняются аналогичные действия, но функция возвращает управление сразу как только одна из ожидающих задач перейдет в активное состояние.


    Текст приложения-сервера (08s.asm)
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. ID_TXT        equ 100
    4. ID_SEND_TXT    equ 101
    5. ID_SEND_ICO    equ 102
    6. ID_SEND_WAV    equ 103
    7. IDC_DIALOG    equ 200
    8. IDC_ICON1    equ 500
    9. IDC_IMG1     equ 104
    10. EVENT_DATA_COUNT = 16
    11. size_of_buffer     = 96
    12. time_interval    = 10
    13. EventPipeObjectStruct struct
    14.     hEventDataHigh    dq EVENT_DATA_COUNT dup(?)
    15.     hEventDataLow    dq EVENT_DATA_COUNT dup(?)
    16.     hEventAck    dq ?
    17. EventPipeObjectStruct ends
    18. .code
    19. WinMain proc
    20.     enter    30h,0
    21.     mov    r9d,256;cx
    22.     mov    [rbp-10h],r9
    23.     mov    qword ptr [rbp-8],LR_DEFAULTCOLOR
    24.     invoke    LoadImage,IMAGE_BASE,IDC_ICON1,IMAGE_ICON;,256,256,LR_DEFAULTCOLOR
    25.     mov    r9d,offset DialogProc
    26.     mov    qword ptr[rbp-10h],rax;30h-10h=+20h
    27.     invoke    DialogBoxParam,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP
    28.     invoke    RtlExitUserProcess,NULL
    29. WinMain endp
    30.  
    31. DialogProc proc hWnddlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
    32. local    hFile:qword
    33. local    szEventName[32]:byte
    34. local    szReadWrite:qword    ;number of bytes actually read or write
    35. local    hResource:qword
    36. local    pResource:qword
    37.  
    38.     mov    hWnddlg,rcx
    39.     mov    lParam,r9
    40.  
    41.     cmp    edx,WM_INITDIALOG
    42.     je    wmINITDIALOG
    43.     cmp    edx,WM_CLOSE
    44.     je    wmCLOSE
    45.     cmp    edx,WM_COMMAND
    46.     je    wmCOMMAND
    47.  
    48.     xor    eax,eax
    49.     jmp    exit0
    50. wmINITDIALOG:invoke GetDlgItem,,IDC_IMG1
    51.     invoke    SendMessage,eax,STM_SETIMAGE,IMAGE_ICON,lParam
    52.     xor    edi,edi;for(DWORD i = 0; i < 16; i++)
    53. @@:; set current event name
    54.     invoke    sprintf,&szEventName,&Format1,edi
    55. ; create new object
    56.     invoke    CreateEvent,0,0,0,&szEventName
    57.     mov    EventPipeObject.hEventDataHigh[rdi*8],rax
    58. ; check for errors
    59.     or    eax,eax;if(EventPipeObject.hEventDataHigh[i] == NULL)
    60.     jz    wmBYE;exit0;
    61. ; create "low" data event handles
    62. ; set current event name
    63.     invoke    sprintf,&szEventName,&Format2,edi
    64. ; create new object
    65.     invoke    CreateEvent,0,0,0,&szEventName
    66.     mov    EventPipeObject.hEventDataLow[rdi*8],rax
    67. ; check for errors
    68.     or    eax,eax;if(EventPipeObject.hEventDataLow[i] == NULL)
    69.     jz    wmBYE;exit0
    70.     inc    edi
    71.     cmp    edi,EVENT_DATA_COUNT
    72.     jb    @b
    73. ; create acknowledgement event
    74. ; create new object
    75.     invoke    CreateEvent,0,0,0,&Format3
    76.     mov    EventPipeObject.hEventAck,rax
    77.     jmp    wmBYE
    78. wmSEND_TXT:invoke GlobalAlloc,GPTR,size_of_buffer
    79.     mov    p,rax
    80.     invoke  GetDlgItemText,hWnddlg,ID_TXT,eax,size_of_buffer
    81.         or      eax,eax
    82.         jz      wmBYE
    83.     mov    dwLength,eax
    84.     mov    edx,offset szWin
    85.         invoke  FindWindow,NULL
    86.         or      eax,eax
    87.         jz      wmBYE
    88.     mov    edx,WM_USER+