|
|
||
|
|
||
|
|
||
Q. Are there
I have already described various methods of synchronization and using the shared memory. There is another interesting approach implemented in
Listing 18.3: Communications with console process through an anonymous pipe
|
|
// The PIPE.RC file
// Constant definitions
#define WS_SYSMENU 0x00080000L
#define WS_VISIBLE 0x100000000L
#define WS_TABSTOP 0x00010000L
#define WS_VSCROLL 0x00200000L
#define DS_3DLOOK 0x0004L
#define ES_LEFT 0x0000L
#define WS_CHILD 0x40000000L
#define WS_BORDER 0x00800000L
#define ES_MULTILINE 0x0004L
#define WS_VSCROLL 0x00200000L
#define WS_HSCROLL 0x00100000L
MENUP MENU
{
POPUP "&Start the program"
{
MENUITEM "S&tart", 200
MENUITEM "E&xit the program", 300
}
}
// Dialog box definition
DIAL1 DIALOG 0, 0, 200, 140
STYLE WS_SYSMENU DS_3DLOOK
CAPTION "Example of PIPE use"
FONT 8, "Arial"
{
CONTROL "", 101, "edit", ES_LEFT ES_MULTILINE
WS_VISIBLE WS_BORDER WS_VSCROLL
WS_HSCROLL, 24, 20, 128, 70
}
; The PIPE.INC file
; Constants
SW_HIDE equ 0
SW_SHOWNORMAL equ 1
STARTFJJSESHOWWINDOW equ 1h
STARTF_USESTDHANDLES equ 100h
STARTF_ADD = STARTFUSESHOWWINDOW + STARTF_USESTDHANDLES
; This message arrives when the window is closed
WM_CLOSE equ 10h
WM_INITDIALOG equ 110h
WM_COMMAND equ 111h
EM_REPLACESEL equ 0C2h
; Prototypes of external procedures
IFDEF MASM
EXTERN ReadFile@20:NEAR
EXTERN CloseHandle@4:NEAR
EXTERN CreatePipe@16:NEAR
EXTERN SetMenu@8:NEAR
EXTERN LoadMenuA@8:NEAR
EXTERN CreateProcessA@40:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN GetModuleHandleA@4:NEAR
EXTERN DialogBoxParamA@20:NEAR
EXTERN EndDialog@8:NEAR
EXTERN SendDlgItemMessageA@20:NEAR
ELSE
EXTERN ReadFile:NEAR
EXTERN CloseHandle:NEAR
EXTERN CreatePipe:NEAR
EXTERN TerminateProcess: NEAR
EXTERN WaitForSingleObject:NEAR
EXTERN SetMenu:NEAR
EXTERN LoadMenuA:NEAR
EXTERN CreateProcessA:NEAR
EXTERN ExitProcess:NEAR
EXTERN GetModuleHandleA:NEAR
EXTERN DialogBoxParamA:NEAR
EXTERN EndDialog:NEAR
EXTERN SendDlgItemMessageA:NEAR
ReadFile@20 = ReadFile
CloseHandle@4 = CloseHandle
CreatePipe@16 = CreatePipe
TerminateProcess@8 = TerminateProcess
WaitForSingleObject@8 = WaitForSingleObject
SetMenu@8 = SetMenu
LoadMenuA@8 = LoadMenuA
CreateProcessA@40 = CreateProcessA
ExitProcess@4 = ExitProcess
GetModuleHandleA@4 = GetModuleHandleA
DialogBoxParamA@20 = DialogBoxParamA
EndDialog@8 = EndDialog
SendDlgItemMessageA@20 = SendDlgItemMessageA
ENDIF
; Structures
; Message structure
MSGSTRUCT STRUC
MSHWND DD ?
MSMESSAGE DD ?
MSWPARAM DD ?
MSLPARAM DD ?
MSTIME DD ?
MSPT DD ?
MSGSTRUCT ENDS
; Structure for CreateProcess
STARTUP STRUC
cb DD 0
lpReserved DD 0
lpDesktop DD 0
lpTitle DD 0
dwX DD 0
dwY DD 0
dwXSize DD 0
dwYSize DD 0
dwXCountChars DD 0
dwYCountChars DD 0
dwFillAttribute DD 0
dwFlags DD 0
wShowWindow DW 0
cbReserved2 DW 0
lpReserved2 DD 0
hStdInput DD 0
hStdOutput DD 0
hStdError DD 0
STARTUP ENDS
; Structure - Information about the process
PROCINF STRUC
hProcess DD ?
hThread DD ?
Idproc DD ?
idThr DD ?
PROCINF ENDS
; The PIPE.ASM file
.586P
; Flat memory model
.MODEL FLAT, stdcall
include pipe.inc
; INCLUDELIB directives for the linker
IFDEF MASM
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
includelib c:\tasm32\lib\import32.lib
ENDIF
;---------------------------------------------
; Data segment
_DATA SEGMENT
STRUP STARTUP <?>
INF PROCINF <?>
MSG MSGSTRUCT <?>
HINST DD 0 ; Application descriptor
PA DB "DIAL1", 0
CMD DB "c:\tasm32\bin\tlink32.exe", 0
PMENU DB "MENUP", 0
HW DD ?
HR DD ?
BUFER DB 3000 DUP(0)
BYT DD ?
_DATA ENDS
; Code segment
_TEXT SEGMENT
START:
; Get the application handle
PUSH 0
CALL GetModuleHandleA@4
MOV [HINST], EAX
;--------------------------------
PUSH 0
PUSH OFFSET WNDPROC
PUSH 0
PUSH OFFSET PA
PUSH [HINST]
CALL DialogBoxParamA@20
CMP EAX, -1
JNE KOL
; Error message
KOL:
;-------------------------------
PUSH 0
CALL ExitProcess@4
;-------------------------------
; Window procedure
; Position of parameters in the stack
; [BP+014H] ; LPARAM
; [BP+10H] ; WAPARAM
; [BP+0CH] ; MES
; [BP+8] ; HWND
WNDPROC PROC
PUSH EBP
MOV EBP, ESP
PUSH EBX
PUSH ESI
PUSH EDI
-----------------
CMP DWORD PTR [EBP+0CH], WM_CLOSE
JNE L1
L3:
PUSH 0
PUSH DWORD PTR [EBP+08H]
CALL EndDialog@8
JMP FINISH
L1:
CMP DWORD PTR [EBP+0CH], WM_INITDIALOG
JNE L2
; Load the menu
PUSH OFFSET PMENU
PUSH [HINST]
CALL LoadMenuA@8
; Set the menu
PUSH EAX
PUSH DWORD PTR [EBP+08H]
CALL SetMenu@8
JMP FINISH
L2:
CMP DWORD PTR [EBP+0CH], WM_COMMAND
JNE FINISH
CMP WORD PTR [EBP+10H], 300
JE L3
CMP WORD PTR [EBP+10H], 200
JNE FINISH
; Startup here
; PIPE in the beginning
PUSH 0
PUSH 0
PUSH OFFSET HW
PUSH OFFSET HR
CALL CreatePipe@16
MOV EAX, HW
; Console application starts here
MOV STRUP.cb, 68
MOV STRUP.lpReserved, 0
MOV STRUP.lpDesktop, 0
MOV STRUP.lpTitle, 0
MOV STRUP.dwFlags, STARTF_ADD
MOV STRUP.cbReserved2, 0
MOV STRUP.lpReserved2, 0
MOV STRUP.wShowWindow, SW_HIDE ; Process window is invisible
MOV STRUP.hStdOutput, EAX
MOV STRUP.hStdError, EAX
;------------------------------
PUSH OFFSET INF
PUSH OFFSET STRUP
PUSH 0
PUSH 0
PUSH 0
PUSH 1 ; Inherit descriptors
PUSH 0
PUSH 0
PUSH OFFSET CMD
PUSH 0
CALL CreateProcessA@40
; Read information
PUSH 0
PUSH OFFSET BYT
PUSH 3000
PUSH OFFSET BUFER
PUSH HR
CALL ReadFile@20
PUSH OFFSET BUFER
PUSH 0
PUSH EM_REPLACESEL
PUSH 101
PUSH DWORD PTR [EBP+08H]
CALL SendDlgItemMessageA@20
; Close the handle for writing
PUSH HW
CALL CloseHandle@4
; Close the handle for reading
PUSH HR
CALL CloseHandle@4
FINISH:
MOV EAX, 0
POP EDI
POP ESI
POP EBX
POP EBP
RET 16
WNDPROC ENDP
_TEXT ENDS
END START
|
|
The underlying idea of pipes is easy. When creating a process, it is possible to assign it the appropriate pipe descriptor as the input or the output descriptor. After that, it will be possible to organize information exchange between two processes using the WriteFile and ReadFile functions.
To translate the program presented in Listing 18.3, issue the following commands using MASM32:
ml /c /coff /DMASM pipe.asm
rc pipe.rc
link /subsystem:windows pipe.obj pipe.res
Issue the following commands using TASM32:
tasm32 /ml pipe.asm
brcc32 pipe.rc
tlink32 -aa pipe.obj,,,,,pipe.res
The program that you just
Starting a console application is a complicated task. Therefore, I won't dive into details. In the program in Listing 18.3, this procedure is practically no different from the one used in Chapter 15 for starting the WINWORD.EXE application. Consider, however, new features implemented in this program. Note that the EditBox control plays an interesting role here. This window element plays the role of the output console. To achieve this, set the ES_MULTILINE property, which displays the entire text sent to the window using the EM_REPLACESEL message. To read the information, a large buffer is used. Principally, it is possible to read the data in smaller portions, checking the number of read bytes as with files.
[i] So-called named pipes are implemented in Windows NT.
|
|
||
|
|
||
|
|
||