if(!CreateProcess(NULL,line_count,NULL,NULL,FALSE,0,NULL,NULL,&sinfo,&pinfo)) {
printf("ERROR: Cannot launch child process\n");
    exit(1);
}
WaitForSingleObject(&pinfo.hProcess,INFINITE);
TerminateProcess(&pinfo,0);
GetExitCodeProcess(pinfo.hProcess,&exit_status);
while(exit_status==STILL_ACTIVE){
            if(GetExitCodeProcess(pinfo.hProcess,&exit_status)) {
              if(exit_status!=STILL_ACTIVE)printf("%d",exit_status);
            }
            else printf("GetExitCodeProcess() failed\n");
    }

This will get me the return() from another program.  So I'm trying to do this in MASM.

Begin_ proc
LOCAL sinfo:STARTUPINFO
LOCAL pinfo:PROCESS_INFORMATION
LOCAL sattr:SECURITY_ATTRIBUTES

mov sattr.nLength,sizeof SECURITY_ATTRIBUTES
mov sattr.lpSecurityDescriptor,NULL
mov sattr.bInheritHandle,FALSE


invoke CreateProcess,NULL,addr line_count,NULL,NULL,FALSE,0,NULL,ADDR DLPart2,ADDR sinfo,ADDR pinfo
invoke WaitForSingleObject,addr pinfo.hProcess,INFINITE
;invoke TerminateProcess,addr pinfo,0
jmp @GetIt
@GetIt:
invoke GetExitCodeProcess,addr pinfo.hProcess,addr exit_status
          cmp exit_status, STILL_ACTIVE ;while(exit_status==STILL_ACTIVE)
          je @GetIt
          jne @GotIt ;if(exit_status!=STILL_ACTIVE)
@GotIt:
invoke  CloseHandle, pinfo.hProcess
    invoke  CloseHandle, pinfo.hThread
    push exit_status
    push offset buffer
    call lstrcpy
;invoke MessageBox,NULL,offset buffer,offset AppName,MB_OK
            ret
Begin_ endp

when I referance it (here or elsewhere in my program) All I get is a blank MessageBox.  HELP! What am I missing?

-#2pencil-
http://www.akroncdnr.com
Posted on 2005-08-09 13:33:57 by number2pencil

szFormat BYTE "%d", 0

invoke wsprintf, addr buffer, addr szFormat, exit_status

Posted on 2005-08-09 13:52:58 by f0dder
You can rub it in my face...
http://www.asmcommunity.net/board/index.php?topic=1123
I should have looked 1st.  But I thank you =-D

Except it's returning zero, I'll keep poking at it though, at least it isn't NULL anymore.

Thanks again!
-#2pencil-
Posted on 2005-08-09 13:57:37 by number2pencil
:-)

most programs will be returning zero for exitcode.

Btw, there's no reason for TerminateProcess as the process is done executing when your WaitForSingleObject returns (also, read the PlatformSDK on TerminateProcess - it's a last-resort thing). And again, since the process is terminated, there's no reason to loop GetExitCodeProcess.

Good to see that you're using WaitForSingleObject and are closing your handles :)
Posted on 2005-08-09 14:02:40 by f0dder
I do have the terminate process commented out.

Also, I realize that it will return zero, but the point of this is to get the return() status from another program.

The one I wrote in C works.  Basicly, program A counts the lines in a file, any line starting with a comment "#" the total number is subtracted by one.  Then the program exits with return (number);  The calling program, program B, retrieves this value & then spits that value out.  Now I want to put this into my Masm program. 

-#2pencil-
Posted on 2005-08-09 14:06:33 by number2pencil

invoke  GetExitCodeProcess,addr pinfo.hProcess,addr exit_status


Bug highlighted :)
Posted on 2005-08-09 14:10:57 by f0dder
Either way, with or without the addr it still returns zero.

So do you _really_ like Front Line Assembly, or is it just catchy because this is an asm messageboard?
Didn't they open up for Skinny Puppy?

-#2pencil-
Posted on 2005-08-09 14:17:23 by number2pencil
hmm, you do

invoke GetExitCodeProcess, pinfo.hProcess, addr exit_status


and exit_status is still 0? What does GetExitCodeProcess return? Have you tried running it through a debugger (http://www.ollydbg.de/) ?

Yeah, I like FLA, dunno if they opened for Skinny Puppy though. And it's a nice catchy phrase :)
Posted on 2005-08-09 14:20:42 by f0dder
invoke GetExitCodeProcess,pinfo.hProcess,addr exit_status
invoke wsprintf,addr buffer,addr szDwordFormat,eax
.if buffer!=NULL  
invoke MessageBox,NULL,offset buffer,offset AppName,MB_OK
.endif

Prints a zero.

I'm guessing eax is the return of GetExitCodeProcess, yes?
Posted on 2005-08-09 14:33:15 by number2pencil
Doesn't MASM give a warning when you assemble that code? Using ADDR for local variables trashes EAX, so you'll need to save this variable somewhere temporarily (in a register, for instance).

And really, if you haven't familiarized yourself with debuggers yet, by all means do so - it makes debugging a LOT easier :)

GetExitCodeProcess returns TRUE or FALSE. What you want to display is the contents of the exit_status variable (after checking GECP for success, of course).
Posted on 2005-08-09 14:38:11 by f0dder
C:\Documents and Settings\jasong\asm>make program_2p3c

C:\Documents and Settings\jasong\asm>ml /c /coff /Cx program_2p3c.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

Assembling: program_2p3c.asm

C:\Documents and Settings\jasong\asm>C:\masm32\bin\rc program_2p3c.rc

C:\Documents and Settings\jasong\asm>C:\masm32\bin\link.exe /SUBSYSTEM:WINDOWS
LIBPATH:c:\masm32\lib program_2p3c.obj program_2p3c.res
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Nope, no errors.  No complaints, nothing.  It assembles clean.  I've not used debuggers before.  I'll check out the link you sent me.

-#2pencil-
Posted on 2005-08-09 14:41:45 by number2pencil

Using ADDR for local variables trashes EAX, so you'll need to save this variable somewhere temporarily (in a register, for instance).


Ok, now you are over my head.  Can you show me what you mean?

If you havn't noticed, I'm not (real) clear on the differances between addr & offset.

-#2pencil-
Posted on 2005-08-09 14:44:28 by number2pencil
Can you zip up your entire current .asm file and attach it here? I wonder if older versions of masm don't warn on clobbering EAX?

Btw, when posting code snippets, add it in code tags - <code>code goes here</code> (but replacing angle brackets with square brackets).
Posted on 2005-08-09 14:44:59 by f0dder

If you havn't noticed, I'm not (real) clear on the differances between addr & offset.

ADDR can only be used in INVOKE statements, OFFSET works everywhere.

OFFSET only works for static addresses - which means it will work for global data, but not LOCAL variables. When ADDR is used for static addresses, it has the same effect as OFFSET. When ADDR is used with a LOCAL variable, it will generate code like the following:

lea eax,


This is necessary because "" really means ""
Posted on 2005-08-09 14:47:33 by f0dder
i'm quite sure that create process fails.

about addr:

addr with local variables
lea eax,localVAR ;; load effective address, example: lea eax,? ;; 
push eax

address is calculated from data between []

addr with global variables
push offset globalVAR
;; offset is numeric position in memory


? ? ; puts string in data section
? ? T macro __qstr:VARARG
LOCAL __sym
.data
align 4
__sym db __qstr,0
.code
exitm <offset __sym>
endm


? ? Begin_ proc
? ? LOCAL sinfo:STARTUPINFO,pinfo:PROCESS_INFORMATION,exit_status:DWORD
? ? LOCAL bufy[10h]:byte
? ? .data
? ? line_count db "yourexe.exe /commandline_here",0 ;;; remove the commandline if not needed
? ? .code
? ? invoke CreateProcess,0,addr line_count,0,0,FALSE,0,0,0,addr sinfo,addr pinfo
? ? .if !eax
? ? invoke MessageBox,0,T("ERROR: Cannot launch child process"),0,0
? ? mov eax,1
? ? ret
? ? .endif
invoke WaitForSingleObject,pinfo.hProcess,INFINITE;
invoke GetExitCodeProcess,pinfo.hProcess,addr exit_status;
.while(exit_status==STILL_ACTIVE)
invoke GetExitCodeProcess,pinfo.hProcess,addr exit_status
.if eax
.if (exit_status!=STILL_ACTIVE)
invoke wsprintf,addr bufy,T("%d"),exit_status
invoke MessageBox,0,addr bufy,0,0
.endif
.else
invoke MessageBox,0,T("GetExitCodeProcess() failed"),0,0
.endif
.endw
invoke CloseHandle,pinfo.hProcess
invoke CloseHandle,pinfo.hThread
? ? mov eax,0
? ? ret
? ? Begin_ endp

this was written in notepad and not checked!
Posted on 2005-08-09 15:51:57 by drizz
Thank you both very much!!!


Begin_ proc
LOCAL sinfo:STARTUPINFO,pinfo:PROCESS_INFORMATION,exit_status:DWORD,sattr:SECURITY_ATTRIBUTES

.data
line_count db "linecount.exe",0

.code
mov esi,sizeof sinfo
invoke RtlZeroMemory,addr sinfo,esi  ; this is what I was missing!
mov sinfo.cb,esi
mov sattr.nLength,sizeof SECURITY_ATTRIBUTES
mov sattr.lpSecurityDescriptor,NULL
mov sattr.bInheritHandle,FALSE

invoke CreateProcess,NULL,addr line_count,NULL,NULL,FALSE,0,NULL,ADDR DLPart2,ADDR sinfo,ADDR pinfo
invoke WaitForSingleObject,addr pinfo.hProcess,INFINITE
jmp @GetIt
@GetIt:
invoke GetExitCodeProcess,pinfo.hProcess,addr exit_status
          cmp exit_status, STILL_ACTIVE ;while(exit_status==STILL_ACTIVE)
          je @GetIt
          jne @GotIt ;if(exit_status!=STILL_ACTIVE)
@GotIt:
    invoke wsprintf,addr buffer,offset szDwordFormat,exit_status
    invoke MessageBox,NULL,addr buffer,offset AppName,MB_OK
invoke  CloseHandle,pinfo.hProcess
    invoke  CloseHandle,pinfo.hThread
    mov eax,0
ret
Begin_ endp
Posted on 2005-08-10 09:06:22 by number2pencil
#2pencil, use the brackets, not the <angle> ones :)
Posted on 2005-08-10 09:34:55 by f0dder
upss i forgot to put sizeof sinfo in cb thats true.

#2pencil you are still not checking if CreateProcess returns nonzero value.

invoke CreateProcess...
test eax,eax
jz @Error
Posted on 2005-08-10 12:17:15 by drizz
I have brought this post back from the dead because I'm having issues again.  This method works, but service pack 2 causes faulty results.  Any ideas?

The results are altered in that 24 is returned, when it should be 0

Just for error checking purposes I added
printf("%i",lc);

to the end of the c program, & it returns the correct (expected) count.  So I'm guessing that the value is miss-represented by my asm program when it is recieved.

Has anyone had this kind of problem before?

-#2pencil-
Posted on 2005-09-16 11:02:36 by number2pencil
Your code had a couple of problems - like using ESI without preserving it, and using "addr" on the WaitForSingleObject invocation. Here's a fixed and hopefully working :) routine:


Begin_ proc
LOCAL sinfo:STARTUPINFO, pinfo:PROCESS_INFORMATION, exit_status:DWORD

.data
line_countdb "linecount.exe",0

.code
invoke RtlZeroMemory, addr sinfo, sizeof sinfo
mov sinfo.cb, sizeof sinfo

invoke CreateProcess, 0, addr line_count, 0, 0, FALSE, 0, 0, ADDR DLPart2, ADDR sinfo, ADDR pinfo
test eax, eax
jz @@out

invoke WaitForSingleObject, pinfo.hProcess, INFINITE ; DON'T use "addr" here!

invoke GetExitCodeProcess, pinfo.hProcess, addr exit_status

invoke CloseHandle, pinfo.hProcess
invoke CloseHandle, pinfo.hThread

    invoke wsprintf, addr buffer, offset szDwordFormat, exit_status
    invoke MessageBox, 0, addr buffer, offset AppName, MB_OK

@@out:
ret

Begin_ endp

Posted on 2005-09-17 06:07:07 by f0dder