Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Get the std output of a console process - Windows API

windows api process stdout

This topic has been archived. This means that you cannot reply to this topic.
15 replies to this topic

#1 FrancoAti

FrancoAti

    CC Regular

  • Member
  • PipPipPip
  • 32 posts

Posted 19 October 2014 - 09:35 PM

(First of all,sorry for my poor english)

Hy guys,what i want is simple but i can't do.
I want to create a process using the Windows API and get the output of this process.
For example,i start the ipconfig.exe process with my code and get the output of this process.

Like this:

 

c:\>ipconfig.exe

 

/*THE OUTPUT OF THE PROCESS
Wireless LAN adapter Wi-Fi:

   Connection-specific DNS Suffix  . :
   IPv4 Address. . . . . . . . . . . : 192.168.0.105
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.0.1

*/

I can do this but with workarounds. :(

 

My code

#include <windows.h>
#include <stdio.h>

int main(){

	SECURITY_ATTRIBUTES saAttr; 
	PROCESS_INFORMATION piProcInfo; 
	STARTUPINFO siStartInfo,si;
	HANDLE hsdtError = NULL,hstdOut = NULL,hstdIn = NULL;
	BOOL bSuccess = FALSE;   //NON SEI ONDE ENTRA ESSA PORRA
	unsigned char buffer[1000]; 

	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);  //DEFINE AQUI SASPORRA
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL;

	//ZERA PROCESS INFORMATION
	//ISSO SÓ É PREENCHIDO DEPOIS DO PROCESSO EXECUTADO
	ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

	// Set up members of the STARTUPINFO structure. 
	// This structure specifies the STDIN and STDOUT handles for redirection.
	ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );  //START INFOS

	siStartInfo.cb = sizeof(STARTUPINFO); 
	siStartInfo.hStdError = hsdtError;
	siStartInfo.hStdOutput = hstdOut;
	siStartInfo.hStdInput = hstdIn;
	siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
	

	if(!CreateProcess("c:\\windows\\system32\\ipconfig.exe", 
      NULL,     // command line 
      &saAttr,    //process security attributes 
      NULL,     // primary thread security attributes 
      TRUE,     // handles are inherited 
      0,        // creation flags 
      NULL,     // use parent's environment 
      NULL,     // use parent's current directory 
      &siStartInfo,  // STARTUPINFO pointer 
      &piProcInfo)  // receives PROCESS_INFORMATION 

	){


		printf("Seh fodeo %d\n",GetLastError());
		return -1;
	}

	printf("%d\n",siStartInfo.hStdOutput);
	printf("%d\n",siStartInfo.hStdInput);
	printf("%d\n",siStartInfo.hStdError);

	return 0;
}

I guide me with this links of windows api:

http://msdn.microsof...9(v=vs.85).aspx

http://msdn.microsof...5(v=vs.85).aspx

http://msdn.microsof...6(v=vs.85).aspx

P.S: I don't understand very well this in the windows API,i'am confuse,someone cant help me?



#2 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts

Posted 20 October 2014 - 07:36 AM

You're almost there! You're just missing the part where you create the I/O handles.

HANDLE hChildOut = INVALID_HANDLE_VALUE;
HANDLE hChildIn = INVALID_HANDLE_VALUE;

/* Do other stuff over here */

// Create a pipe for the child process's STDOUT.
if ( !CreatePipe(&hChildIn, &hChildOut, &saAttr, 0) ) 
    ErrorExit(TEXT("Failed to create a pipe")); 

// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( !SetHandleInformation(hChildOut, HANDLE_FLAG_INHERIT, 0) )
    ErrorExit(TEXT("Failed to set handle information"));

/* Call CreateProcess and other stuff here.

You can now use ReadFile using hChildOut as the file handle to get the output
of your child process.
*/

CloseHandle(hChildIn);
CloseHandle(hChildOut);

sudo rm -rf / && echo $'Sanitize your inputs!'


#3 FrancoAti

FrancoAti

    CC Regular

  • Member
  • PipPipPip
  • 32 posts

Posted 20 October 2014 - 05:34 PM

(First of all,sorry for my poor english)

 

Ok,it still confuse to me,i had problems to understand this,but  work more or less.
Now i can see the real value of the stdout handle but i cannot read the file.
This program return the ERROR_ACCESS_DENIED in GetLastError();
Sorry for dont solve this problem,but help me again.

#include <windows.h>
#include <stdio.h>

int main(){

    HANDLE hChildOut = INVALID_HANDLE_VALUE;
    HANDLE hChildIn = INVALID_HANDLE_VALUE;
    SECURITY_ATTRIBUTES saAttr;
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo,si;
    HANDLE hsdtError = NULL,hstdOut = NULL,hstdIn = NULL;
    BOOL bSuccess = FALSE;   //NON SEI ONDE ENTRA ESSA PORRA
    unsigned char buffer[1000];

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);  //DEFINE AQUI SASPORRA
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    //ZERA PROCESS INFORMATION
    //ISSO SÓ É PREENCHIDO DEPOIS DO PROCESSO EXECUTADO
    ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

    // Set up members of the STARTUPINFO structure.
    // This structure specifies the STDIN and STDOUT handles for redirection.
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );  //START INFOS

    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.hStdError = hsdtError;
    siStartInfo.hStdOutput = hstdOut;
    siStartInfo.hStdInput = hstdIn;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    // Create a pipe for the child process's STDOUT.
    if ( !CreatePipe(&hChildIn, &hChildOut, &saAttr, 0) ) {
            printf("Failed to create a pipe");
    }

    // Ensure the read handle to the pipe for STDOUT is not inherited.
    if ( !SetHandleInformation(hChildOut,HANDLE_FLAG_INHERIT, 0) ){
            printf("Failed to set handle information %d",GetLastError());
    }

    //
    if(!CreateProcess("c:\\windows\\system32\\ipconfig.exe",
      "more",     //command line
      NULL,    //process security attributes
      NULL,     //primary thread security attributes
      TRUE,     //handles are inherited
      0,  //creation flags
      NULL,     //use parent's environment
      NULL,     //use parent's current directory
      &siStartInfo,  //STARTUPINFO pointer
      &piProcInfo)  //receives PROCESS_INFORMATION

    ){

        printf("Seh fodeo %d\n",GetLastError());
        return -1;
    }

    if( !ReadFile(hChildOut,buffer,998,NULL,NULL) ){
            printf("Failed to coisar the file %d",GetLastError());
    }else{

        printf("%s\n",buffer);
    }

    CloseHandle(hChildIn);
    CloseHandle(hChildOut);

    return 0;
}

Edited by FrancoAti, 20 October 2014 - 05:35 PM.


#4 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts

Posted 21 October 2014 - 12:13 PM

Change

siStartInfo.hStdOutput = hstdOut;
siStartInfo.hStdInput = hstdIn;

to

siStartInfo.hStdOutput = hChildOut;
siStartInfo.hStdInput = hChildIn;

sudo rm -rf / && echo $'Sanitize your inputs!'


#5 FrancoAti

FrancoAti

    CC Regular

  • Member
  • PipPipPip
  • 32 posts

Posted 21 October 2014 - 01:05 PM

Same error, :(
 The error:

 

hChildOut handle -> 448
Error 5

#include <windows.h>
#include <stdio.h>

int main(){

	HANDLE hChildOut = INVALID_HANDLE_VALUE;
	HANDLE hChildIn = INVALID_HANDLE_VALUE;
	HANDLE hChildErr = INVALID_HANDLE_VALUE;
	
	SECURITY_ATTRIBUTES saAttr; 
	PROCESS_INFORMATION piProcInfo; 
	STARTUPINFO siStartInfo,si;
	BOOL bSuccess = FALSE;   //NON SEI ONDE ENTRA ESSA PORRA
	unsigned char buffer[1000]; 

	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);  //DEFINE AQUI SASPORRA
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL;

	//ZERA PROCESS INFORMATION
	//ISSO SÓ É PREENCHIDO DEPOIS DO PROCESSO EXECUTADO
	ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

	// Set up members of the STARTUPINFO structure. 
	// This structure specifies the STDIN and STDOUT handles for redirection.
	ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );  //START INFOS

	siStartInfo.cb = sizeof(STARTUPINFO); 
	siStartInfo.hStdError = hChildErr;
	siStartInfo.hStdOutput = hChildOut;
	siStartInfo.hStdInput = hChildIn;
	siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

	// Create a pipe for the child process's STDOUT.
	if ( !CreatePipe(&hChildIn, &hChildOut, &saAttr, 0) ) {
			printf("Failed to create a pipe"); 
	}

	// Ensure the read handle to the pipe for STDOUT is not inherited.
	if ( !SetHandleInformation(hChildOut, HANDLE_FLAG_INHERIT, 0) ){
			printf("Failed to set handle information");
	}

	if(!CreateProcess("c:\\windows\\system32\\ipconfig.exe", 
      NULL,     // command line 
      &saAttr,    //process security attributes 
      NULL,     // primary thread security attributes 
      TRUE,     // handles are inherited 
      0,        // creation flags 
      NULL,     // use parent's environment 
      NULL,     // use parent's current directory 
      &siStartInfo,  // STARTUPINFO pointer 
      &piProcInfo)  // receives PROCESS_INFORMATION 

	){

		printf("Seh fodeo %d\n",GetLastError());
		return -1;
	}

	printf("%d\n",hChildOut);

	if( !ReadFile(hChildOut,buffer,500,NULL,NULL) ){

		printf("Error %d\n",GetLastError());
		return -10;
	}

	printf("Saida do processo:\n%s\n",&buffer);

	return 0;
}


#6 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts

Posted 21 October 2014 - 02:55 PM

You're not setting siStartInfo.bInheritHandles to TRUE. You need to do that when you're setting the other process flags.

 

http://msdn.microsof...6(v=vs.85).aspx


sudo rm -rf / && echo $'Sanitize your inputs!'


#7 FrancoAti

FrancoAti

    CC Regular

  • Member
  • PipPipPip
  • 32 posts

Posted 21 October 2014 - 06:11 PM

(First of all,sorry for my poor english)
There's no siStartInfo.bInheritHandles field in the STARTUPINFO struct,i do just like in the link.
The saAttr.bInheritHandle field is set to true and in the parameter of the CreateProcess function.
That is i understand...



#8 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts

Posted 21 October 2014 - 06:20 PM

Whoops, sorry. Anyway, I found your problem. You need to put your call to CreatePipe before you initialize all the values in siStartValue. Because those handles haven't been initialized when you set them in siStartValue, you're setting the process' input/output handles to NULL. Just move that code up and it should work. :)


sudo rm -rf / && echo $'Sanitize your inputs!'


#9 FrancoAti

FrancoAti

    CC Regular

  • Member
  • PipPipPip
  • 32 posts

Posted 21 October 2014 - 06:29 PM

Don't work like i charm... :crying:

#include <windows.h>
#include <stdio.h>

int main(){

	HANDLE hChildOut = INVALID_HANDLE_VALUE;
	HANDLE hChildIn = INVALID_HANDLE_VALUE;
	HANDLE hChildErr = INVALID_HANDLE_VALUE;
	
	SECURITY_ATTRIBUTES saAttr; 
	PROCESS_INFORMATION piProcInfo; 
	STARTUPINFO siStartInfo,si;
	BOOL bSuccess = FALSE;   //NON SEI ONDE ENTRA ESSA PORRA
	unsigned char buffer[1000]; 

	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);  //DEFINE AQUI SASPORRA
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL;

	// Create a pipe for the child process's STDOUT.
	if ( !CreatePipe(&hChildIn, &hChildOut, &saAttr, 0) ) {
			printf("Failed to create a pipe"); 
	}

	// Ensure the read handle to the pipe for STDOUT is not inherited.
	if ( !SetHandleInformation(hChildOut, HANDLE_FLAG_INHERIT, 0) ){
			printf("Failed to set handle information");
	}

	//ZERA PROCESS INFORMATION
	//ISSO SÓ É PREENCHIDO DEPOIS DO PROCESSO EXECUTADO
	ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

	// Set up members of the STARTUPINFO structure. 
	// This structure specifies the STDIN and STDOUT handles for redirection.
	ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );  //START INFOS

	siStartInfo.cb = sizeof(STARTUPINFO); 
	siStartInfo.hStdError = hChildErr;
	siStartInfo.hStdOutput = hChildOut;
	siStartInfo.hStdInput = hChildIn;
	siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

	if(!CreateProcess("c:\\windows\\system32\\ipconfig.exe", 
      NULL,     //command line 
      &saAttr,    //process security attributes 
      NULL,     // primary thread security attributes 
      TRUE,     // handles are inherited 
      0,        // creation flags 
      NULL,     // use parent's environment 
      NULL,     // use parent's current directory 
      &siStartInfo,  // STARTUPINFO pointer 
      &piProcInfo)  // receives PROCESS_INFORMATION 

	){

		printf("Seh fodeo %d\n",GetLastError());
		return -1;
	}

	printf("hChildOut handle -> %d\n",hChildOut);

	if( !ReadFile(hChildOut,buffer,500,NULL,NULL) ){

		printf("Error %d\n",GetLastError());
		return -10;
	}

	printf("Saida do processo:\n%s\n",&buffer);

	return 0;
}

I'am doing just like you show to me and just like this post.

http://forum.codecal...ure-its-output/

But isn't working for me...sad.

Edited by dargueta, 22 October 2014 - 10:33 AM.


#10 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts

Posted 22 October 2014 - 10:54 AM

Oh wow, I never noticed this before! You have the order of the first two arguments to CreateProcess wrong. Swap the first two arguments - the second should be your command line, the first should be NULL.

 

A few other things:

1) You never initialize hChildErr so you're passing an invalid handle. Do siStartInfo.hStdError = hChildOut instead.

 

2) Your command line must be enclosed in the TEXT() macro. I can go into the details of why but they're irrelevant at the moment. Use TEXT("C:\\Windows\\System32\\ipconfig.exe") instead.

 

3) At the end of main(), do printf("Saida do processo:\n%s\n", buffer) (notice there's no & there).


sudo rm -rf / && echo $'Sanitize your inputs!'


#11 FrancoAti

FrancoAti

    CC Regular

  • Member
  • PipPipPip
  • 32 posts

Posted 22 October 2014 - 04:18 PM

Hey man,bad ** news!
Still with the same error.

-----------------------------
hChildOut handle -> 452
Error 5
-----------------------------

The problem is not in executing the process,i can se with tasklist command the process that i create running.
The ** problem is to get your stdout.

I really dont know what is wrong.

:crying:

#12 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts

Posted 25 October 2014 - 05:04 PM

Whoops, just saw this. To be honest, I have absolutely no idea.


sudo rm -rf / && echo $'Sanitize your inputs!'





Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download