Blog. Just Blog

Обмен данными между процессами с помощью WM_COPYDATA

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Обмен данными между процессами с помощью WM_COPYDATA
Обмен данными между процессами с помощью WM_COPYDATA

Обмен данными между процессами приложений может выполняться различными способами. Это может быть shared-память, буфер обмена, COM-объекты и другие высокоуровневые способы. Но наиболее простым и понятным способом является передача данных с использованием сообщения WM_COPYDATA. В этом случае обмен происходит через ядро системы с выделением памяти в принимающем процессе. Таким образом, например, выполняется взаимодействие с окном плеера JetAudio.

Взаимодействие выполняется через структуру COPYDATASTRUCT. В ней всего три поля - идентификатор типа передаваемых данных, размер данных и указатель на данные. Вот так это делается:
  1. ; Сегмент данных
  2. cdata    COPYDATASTRUCT
  3. szStr    db 'Hello!',0
  4. szWindow db 'Reciever Window',0
  5. ...
  6. ...
  7. ; Сегмент кода
  8. ...
  9. ...
  10.         ; Тип передаваемых данных
  11.         mov     [cdata.dwData],0
  12.         ; Длина строки
  13.         invoke  lstrlen,szStr
  14.         ; Учитываем финальный символ 0x00 в строке
  15.         inc     eax
  16.         mov     [cdata.cbData],eax
  17.         ; Указатель на строку
  18.         mov     [cdata.lpData],szStr
  19.  
  20.         ; Найти окно приемника
  21.         invoke  FindWindow,NULL,szWindow
  22.         or      eax,eax
  23.         jz      .processed
  24.  
  25.         ; Отправить данные получателю
  26.         invoke  SendMessage,eax,WM_COPYDATA,[hwnddlg],cdata
  27.         jmp     .processed
Обратите внимание, что для передачи данных должна использоваться только функция синхронной отправки сообщения SendMessage, а не PostMessage, которая передает сообщение асинхронным образом. Память под передаваемые данные резервируется и удерживается до тех пор, пока приложение-приемник не обработает сообщение и не оповестит об этом систему. До этого момента приложение-отправитель переходит в режим ожидания. Если нужно ограничивать время ожидания, например, когда целевое приложение по какой-то причине может не ответить на сообщение, то пользуйтесь функцией SendMessageTimeout.

При передаче текстовых данных нужно учитывать завершающий нулевой символ и включать его в длину строки. То есть при передаче пустой строки длина передаваемых данных все равно будет 1 символ.

В окне приложения-получателя отслеживается сообщение WM_COPYDATA, его обработка выполняется примерно так:
  1.         ; Пришло сообщение WM_COPYDATA?
  2.         cmp     [msg],WM_COPYDATA
  3.         je      .wmcopydata
  4.         ...
  5.         ...
  6. .wmcopydata:
  7.         ; В lparam приходит указатель на структуру COPYDATASTRUCT
  8.         mov     ebx,[lparam]
  9.         ; Это нужный тип данных?
  10.         cmp     [ebx+COPYDATASTRUCT.dwData],0
  11.         ; Нет, пропускаем
  12.         jne     .processed
  13.         ; Размер данных нулевой?
  14.         cmp     [ebx+COPYDATASTRUCT.cbData],0
  15.         ; Да, тоже пропускаем
  16.         je      .processed
  17.         ; Скопировать полученные данные в наше приложение
  18.         mov     esi,[ebx+COPYDATASTRUCT.lpData]
  19.         mov     edi,myOwnBuff
  20.         mov     ecx,[ebx+COPYDATASTRUCT.cbData]
  21.         rep     movsb
Важно понимать, что целевое приложение в принципе не в состоянии достоверно определить, от какого именно окна и от какого приложения пришли данные через WM_COPYDATA, а также тип, размер и реальное содержимое этих данных. Поэтому обеспечение безопасности и взаимной идентификации возлагается на плечи разработчиков, а не на систему.

Примеры программ с исходными текстами в приложении. Одна из программ передает другой текстовую строку и затем получает от нее изображение.

Примеры программ с исходными текстами (FASM)Примеры программ с исходными текстами (FASM)

WM_COPYDATA.Demo.zip (5,591 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 2593 | Комментариев: 2

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Mikl___ (11.08.2022 в 02:06):
Привет, manhunter! Развиваю вашу фразу "Обмен данными между процессами приложений может выполняться различными способами. Это может быть shared-память, буфер обмена, COM-объекты и другие высокоуровневые способы..." на сайте wasm.in топик "Межпроцессное взаимодействие" рассмотрены передача данных (текст, картинки, WAV-данные) через: 1. WM_COPYDATA
2. Буфер обмена
3. Memory_Mapped_File
4. страничный файл
5. Mailslot
6. Named_Pipe
7. DDE
8. Evet_Pipes
9. Mutex
10. Semaphore
11. Sockets
Хотелось бы побольше узнать об обмене данными между COM-сервером и COM-клиентом
Grey (01.03.2018 в 13:13):
Прикольно

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2023
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.005 сек.) / Память: 4.5 Mb
Наверх