News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

issue with redirecting of StdIn & StdOut for child process.

Started by RastaMag, January 19, 2014, 07:09:42 AM

Previous topic - Next topic

RastaMag

I have read this post on msdn about Creating a child process with redirected StdIn & StdOut. (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx) I converted  The C++ to asm to better understand how the program was working.  The issue is my asm code only kind of works

#####

Code below.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
    include \masm32\include\debug.inc
    includelib \masm32\lib\debug.lib
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    .const
   
    .data
    BytesTowrite dd 0
    BytesWritten dd 0
Process db "C:\Windows\system32\cmd.exe",0
CmdR db "dir"
TestM db "A test message"
    .data?
     Written dd ?
    hChildStd_In_Rd dd ?
    hChildStd_In_Wr dd ?
    hChildStd_Out_Rd dd ?
    hChildStd_Out_Wr dd ?
    hParentStd_Out dd ?
   
security_attrib  SECURITY_ATTRIBUTES <>
stinfo STARTUPINFO <>
pinfo PROCESS_INFORMATION <>

CBuff db ?

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

mov security_attrib.lpSecurityDescriptor,0
mov security_attrib.bInheritHandle,TRUE
mov security_attrib.nLength,sizeof SECURITY_ATTRIBUTES

invoke CreatePipe,offset hChildStd_Out_Rd ,offset hChildStd_Out_Wr,offset security_attrib,0
or eax,eax
jz EX
invoke CreatePipe,offset hChildStd_In_Rd ,offset hChildStd_In_Wr,offset security_attrib,0
or eax,eax
jz EX
invoke SetHandleInformation,hChildStd_Out_Rd,HANDLE_FLAG_INHERIT, 0
or eax,eax
jz EX
invoke SetHandleInformation,hChildStd_In_Wr,HANDLE_FLAG_INHERIT, 0
or eax,eax
jz EX
mov stinfo.cb,sizeof STARTUPINFO
mov eax,hChildStd_Out_Wr
mov stinfo.hStdError,eax
mov stinfo.hStdOutput,eax
mov eax,hChildStd_In_Rd
mov stinfo.hStdInput,eax
mov stinfo.dwFlags,STARTF_USESTDHANDLES
;mov stinfo.wShowWindow,SW_SHOW ; Set to SW_SHOW to show window or SW_HIDE to hide window STARTF_USESHOWWINDOW+

invoke CreateProcess,offset Process,0,0,0,TRUE,CREATE_NEW_CONSOLE,0,0,offset stinfo,offset pinfo
or eax,eax
jz EX
mov eax,LENGTHOF CmdR
mov BytesTowrite,eax
invoke WriteFile,hChildStd_In_Wr,offset CmdR,1024,addr BytesWritten,0
invoke CloseHandle, offset hChildStd_In_Wr
invoke ReadFile,hChildStd_Out_Rd,addr CBuff,1024,addr BytesWritten,0
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov hParentStd_Out,eax
;invoke WriteFile,eax,ADDR TestM,LENGTHOF TestM,ADDR Written,0
invoke WriteFile,eax,ADDR CBuff,1024,Addr BytesWritten,0
PrintDec BytesTowrite
PrintString CBuff
invoke MessageBox, NULL, addr CBuff, addr CBuff, MB_OK
mov eax,LENGTHOF CBuff
PrintDec eax
; Never ending loop to try and see whats going on.
;L2:
;mov ecx,0
;cmp ecx,0
;je L2
EX:
    ret

main endp


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

the above program, does not work as expected, when run the std handles are redirected, but the  call to write file to child sdtin_wr, when i try to get the out put from child stdOut. instead of getting out put from my cmd pushed to child process   through stdin write pipe. i get from child stdOut-Rd pipe, the  1st line of cmd.exe prompt launching.  "Microsoft Windows [Version 6.1.7601]". instead of Output  from pushed cmd to cmd.exe = "dir"

ragdog

Hi

You can look in EzPrompt from Akyprain i hope it help you ;)
http://www.winasm.net/forum/index.php?showtopic=385

jj2007

Unfortunately, pipes are really messy animals. It can be done, see attachment - 70 lines only, but under the hood (i.e. in the library) there is a relatively complex procedure, inter alia with an extra thread for reading the input. Have a look at the SubEdit proc, and put an int 3 in front of Launch in WM_CREATE...

@ragdog: Does ezprompt's prog work for you? Not for my Win XP SP3, I can see the Windows prompt but then it just hangs :(

EDIT: Version 2 has a bugfix in line 50 - EM_LIMITTEXT instead of EM_EXLIMITTEXT

ragdog

I have it testet on Xp sp2 for years and it works
And now have i not Xp installed but it a good Idea from AkyPrain

Now have i tested under Win7 Sp1 and it works fine  :t

You must put this commands in the Combobox


Jochen your example works fine but look i in the source find i Macros or define this uses
by your MasmBasic

"WritePipe" :(


GoneFishing

I made a few minor changes in your code and it worked as expected ( under WinDbg only)
Quote
CmdR db "dir",0
...
CBuff  db 1024 dup (?)


vkdebug has DumpMem macro for viewing memory:

invoke ReadFile,hChildStd_Out_Rd,addr CBuff,1024, addr BytesWritten,0
DumpMem offset CBuff,512

When under WinDbg CBuff is filled with DIR's output .
Is the child console supposed to know something about current working directory?


jj2007

Quote from: ragdog on January 19, 2014, 07:19:46 PM
You must put this commands in the Combobox

Oops, I had overlooked this feature ;-)
My example tries to emulate a real DOS prompt, i.e. you can insert commands right in the output window, then hit Return.

EDIT: Attached a more advanced example, inter alia with history (can be saved, too). For this app, a new macro LaunchEndPos() had to be added, see line 908. The updated library can be downloaded here. LaunchEndPos() returns the position inside the edit control where the last pipe read ended. Thus, the new portion of text entered by the user can be identified and sent to the pipe.

QuoteJochen your example works fine but look i in the source find i Macros or define this uses by your MasmBasic

"WritePipe" :(

Yes, WritePipe and Launch are macros, of course.

GoneFishing

I've managed to make your code run :
Quote
CmdR db "dir",0Dh,0Ah,0
...
CBuff db ?     ; CBuff db 1024 dup (?) not needed here 

Quote
invoke CloseHandle, hChildStd_Out_Wr  ; without "offset"

invoke Sleep,500                                  ; guessed , don't even ask me why it works
                                                           ; even 50 ms worked for me (10 didn't work)

RastaMag

yes thank you all who have helped Me try to figure this issue out.

so the above code works kind off but its getting better So with the input from  vertograd , Line :  invoke CloseHandle, hChildStd_Out_Wr  ; without "offset

was the big error  thanks. vertograd, And all who help me. thanks guys you are awesome.   

for anybody who is going to use or improve above code, its not fully functional .

stdin & out are correctly redirected to child process. you can send cmds to child process and thy willl exec but getting back output from said cmds and printing to ParentsStdOut is not working correct.

GoneFishing

Did you try to invoke Sleep right after closing hChildStd_Out_Wr  handle ?
In the attachment compiled working executable ( tested on W8.1 64)

jj2007

I've used Sleep in earlier phases of Launch, together with WaitForSingleObject. It's a hack, and the tricky point is the order of events: When the child process closes, it does not mean that the pipe is finished, too (see also "PeekNamedPipe better than WaitForSingleObject?").

GoneFishing

Jochen , this subject is very interesting  :t
Seems that now it's my turn to do some research  ;)

First, I decided to determine when the child is closed . The child's console disappears after closing hChildStd_Out_Wr handle but the process itself keeps being alive till the parent's termination .

MSDN says:
Quote
To free resources used by a pipe, the application should always close handles when they are no longer needed, which is accomplished either by calling the CloseHandle function or when the process associated with the instance handles ends.

What exactly in this case is "the process associated with the instance handles " ? The child or the parent?
If I terminate the child the pipes associated with it will still exist , right?