nt services issue

Hi guys,
I have a problem with the nt service issue. If I run as a console
application, everything seem to work probably, but when I convert the code
to run as a service, I got the Call cmd :C:\WINDOWS\system32\cmd.exe

Call opts :/C set
CreateChildProcess
child read pipe
ReadFromPipe
Read data from child
ReadFile Failed:109
child Done
// CallCmd.cpp: implementation of the CCallCmd class.
//
//////////////////////////////////////////////////////////////////////

#include “CallCmd.h”
#include <stdio.h>
#include <windows.h>
#include <winerror.h>

#define BUFSIZE 256

#include “…/service/PipeClient.h”
#ifdef debug
extern CPipeClient m_clientPipe;
#endif

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hSaveStdin, hSaveStdout;

BOOL CreateChildProcess(char *cmdline, char *options);
long WriteToPipe(VOID);
long ReadFromPipe(VOID);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);

//#define pInputFile “parentInput”
#define pInputFile NULL

long CallCmd(char *cmdLine, char *options)
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;

DEBUG_OUT1(“Call cmd :%s”, cmdLine);
DEBUG_OUT1(“Call opts :%s”, options);

// Set the bInheritHandle flag so pipe handles are inherited.

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;

// The steps for redirecting child process’s STDOUT:
// 1. Save current STDOUT, to be restored later.
// 2. Create anonymous pipe to be STDOUT for child process.
// 3. Set STDOUT of the parent process to be write handle to
// the pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the read handle and
// close the inheritable read handle.

// Save the handle to the current STDOUT.

hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Create a pipe for the child process’s STDOUT.

if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
{
ErrorExit(“Stdout pipe creation failed\n”);
return 1;
}

// Set a write handle to the pipe to be STDOUT.

if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
ErrorExit(“Redirecting STDOUT failed”);

// Create noninheritable read handle and close the inheritable read
// handle.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if( !fSuccess )
{
ErrorExit(“DuplicateHandle failed”);
return 1;
}
CloseHandle(hChildStdoutRd);

// The steps for redirecting child process’s STDIN:
// 1. Save current STDIN, to be restored later.
// 2. Create anonymous pipe to be STDIN for child process.
// 3. Set STDIN of the parent to be the read handle to the
// pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the write handle,
// and close the inheritable write handle.

// Save the handle to the current STDIN.

hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

// Create a pipe for the child process’s STDIN.

if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
{
ErrorExit(“Stdin pipe creation failed\n”);
return 1;
}

// Set a read handle to the pipe to be STDIN.

if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
{
ErrorExit(“Redirecting Stdin failed”);
return 1;
}

// Duplicate the write handle to the pipe so it is not inherited.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE, // not inherited
DUPLICATE_SAME_ACCESS);
if (! fSuccess)
{
ErrorExit(“DuplicateHandle failed”);
return 1;
}

CloseHandle(hChildStdinWr);

// Now create the child process.

if (! CreateChildProcess(cmdLine, options))
{
ErrorExit(“Create process failed”);
return 1;
}

// After process creation, restore the saved STDIN and STDOUT.

if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
{
ErrorExit(“Re-redirecting Stdin failed\n”);
return 1;
}

if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
{
ErrorExit(“Re-redirecting Stdout failed\n”);
return 1;
}

// Get a handle to the parent’s input file.

if (pInputFile)
hInputFile = CreateFile(pInputFile, GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
else
hInputFile = hSaveStdin;

if (hInputFile == INVALID_HANDLE_VALUE)
{
ErrorExit(“no input file\n”);
return 1;
}

// Write to pipe that is the standard input for a child process.

// WriteToPipe();

// Read from pipe that is the standard output for child process.

DEBUG_OUT(“child read pipe”);
ReadFromPipe();

DEBUG_OUT(“child Done”);
return 0;
}

BOOL CreateChildProcess(char *cmdline, char *options)
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
int status = 1;

DEBUG_OUT(“CreateChildProcess”);
// Set up members of the PROCESS_INFORMATION structure.

ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

// Set up members of the STARTUPINFO structure.

ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);

// Create the child process.

if (!(status = CreateProcess(
cmdline, // program
options, // command line options
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
CREATE_NEW_CONSOLE, // creation flags
NULL, // use parent’s environment
NULL, // use parent’s current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo))) // receives PROCESS_INFORMATION
{
DEBUG_OUT1(“CreateProcess failed. Error:%d\n”, GetLastError());
}

return status;
}

long WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];

// Read from a file and write its contents to a pipe.

for (;:wink:
{
if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0) break;
if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
&dwWritten, NULL)) break;
}

// Close the pipe handle so the child process stops reading.

if (! CloseHandle(hChildStdinWrDup))
{
ErrorExit(“Close pipe failed\n”);
return 1;
}
return 0;
}

long ReadFromPipe(VOID)
{
DWORD dwRead;
CHAR chBuf[BUFSIZE];
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Close the write end of the pipe before reading from the
// read end of the pipe.
DEBUG_OUT(“ReadFromPipe”);

if (!CloseHandle(hChildStdoutWr))
{
ErrorExit(“Closing handle failed”);
return 1;
}

// Read output from the child process, and write to parent’s STDOUT.

Sleep(500);
for (;:wink:
{
DEBUG_OUT(“Read data from child”);
if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0)
{
DEBUG_OUT1(“ReadFile Failed:%d”, GetLastError());
break;
}

DEBUG_OUT(“Got data from child”);
chBuf[dwRead] = 0;
DEBUG_OUT1(“child out: %s\n”, chBuf);
}
return 0;
}

VOID ErrorExit (LPTSTR lpszMessage)
{
DEBUG_OUT1(“child Error: %s”, lpszMessage);
}</winerror.h></windows.h></stdio.h>

Services have closed stdin/stdout. Closed at all. These handles are just
not valid.

Maybe this is your problem.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Friday, December 17, 2004 5:57 AM
Subject: [ntdev] nt services issue

>
>
>
> Hi guys,
> I have a problem with the nt service issue. If I run as a console
> application, everything seem to work probably, but when I convert the code
> to run as a service, I got the Call cmd :C:\WINDOWS\system32\cmd.exe
> >Call opts :/C set
> >CreateChildProcess
> >child read pipe
> >ReadFromPipe
> >Read data from child
> >ReadFile Failed:109
> >child Done
> // CallCmd.cpp: implementation of the CCallCmd class.
> //
> //////////////////////////////////////////////////////////////////////
>
> #include “CallCmd.h”
> #include <stdio.h>
> #include <windows.h>
> #include <winerror.h>
>
> #define BUFSIZE 256
>
> #include “…/service/PipeClient.h”
> #ifdef debug
> extern CPipeClient m_clientPipe;
> #endif
>
>
> HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
> hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
> hInputFile, hSaveStdin, hSaveStdout;
>
> BOOL CreateChildProcess(char *cmdline, char *options);
> long WriteToPipe(VOID);
> long ReadFromPipe(VOID);
> VOID ErrorExit(LPTSTR);
> VOID ErrMsg(LPTSTR, BOOL);
>
> //#define pInputFile “parentInput”
> #define pInputFile NULL
>
>
> long CallCmd(char *cmdLine, char *options)
> {
> SECURITY_ATTRIBUTES saAttr;
> BOOL fSuccess;
>
> DEBUG_OUT1(“Call cmd :%s”, cmdLine);
> DEBUG_OUT1(“Call opts :%s”, options);
>
> // Set the bInheritHandle flag so pipe handles are inherited.
>
> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
> saAttr.bInheritHandle = TRUE;
> saAttr.lpSecurityDescriptor = NULL;
>
> // The steps for redirecting child process’s STDOUT:
> // 1. Save current STDOUT, to be restored later.
> // 2. Create anonymous pipe to be STDOUT for child process.
> // 3. Set STDOUT of the parent process to be write handle to
> // the pipe, so it is inherited by the child process.
> // 4. Create a noninheritable duplicate of the read handle and
> // close the inheritable read handle.
>
> // Save the handle to the current STDOUT.
>
> hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>
> // Create a pipe for the child process’s STDOUT.
>
> if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
> {
> ErrorExit(“Stdout pipe creation failed\n”);
> return 1;
> }
>
> // Set a write handle to the pipe to be STDOUT.
>
> if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
> ErrorExit(“Redirecting STDOUT failed”);
>
> // Create noninheritable read handle and close the inheritable read
> // handle.
>
> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
> GetCurrentProcess(), &hChildStdoutRdDup , 0,
> FALSE,
> DUPLICATE_SAME_ACCESS);
> if( !fSuccess )
> {
> ErrorExit(“DuplicateHandle failed”);
> return 1;
> }
> CloseHandle(hChildStdoutRd);
>
> // The steps for redirecting child process’s STDIN:
> // 1. Save current STDIN, to be restored later.
> // 2. Create anonymous pipe to be STDIN for child process.
> // 3. Set STDIN of the parent to be the read handle to the
> // pipe, so it is inherited by the child process.
> // 4. Create a noninheritable duplicate of the write handle,
> // and close the inheritable write handle.
>
> // Save the handle to the current STDIN.
>
> hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
>
> // Create a pipe for the child process’s STDIN.
>
> if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
> {
> ErrorExit(“Stdin pipe creation failed\n”);
> return 1;
> }
>
> // Set a read handle to the pipe to be STDIN.
>
> if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
> {
> ErrorExit(“Redirecting Stdin failed”);
> return 1;
> }
>
> // Duplicate the write handle to the pipe so it is not inherited.
>
> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
> GetCurrentProcess(), &hChildStdinWrDup, 0,
> FALSE, // not inherited
> DUPLICATE_SAME_ACCESS);
> if (! fSuccess)
> {
> ErrorExit(“DuplicateHandle failed”);
> return 1;
> }
>
> CloseHandle(hChildStdinWr);
>
> // Now create the child process.
>
> if (! CreateChildProcess(cmdLine, options))
> {
> ErrorExit(“Create process failed”);
> return 1;
> }
>
> // After process creation, restore the saved STDIN and STDOUT.
>
> if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
> {
> ErrorExit(“Re-redirecting Stdin failed\n”);
> return 1;
> }
>
> if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
> {
> ErrorExit(“Re-redirecting Stdout failed\n”);
> return 1;
> }
>
> // Get a handle to the parent’s input file.
>
> if (pInputFile)
> hInputFile = CreateFile(pInputFile, GENERIC_READ, 0, NULL,
> OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
> else
> hInputFile = hSaveStdin;
>
> if (hInputFile == INVALID_HANDLE_VALUE)
> {
> ErrorExit(“no input file\n”);
> return 1;
> }
>
> // Write to pipe that is the standard input for a child process.
>
> // WriteToPipe();
>
> // Read from pipe that is the standard output for child process.
>
> DEBUG_OUT(“child read pipe”);
> ReadFromPipe();
>
> DEBUG_OUT(“child Done”);
> return 0;
> }
>
>
>
>
>
> BOOL CreateChildProcess(char *cmdline, char *options)
> {
> PROCESS_INFORMATION piProcInfo;
> STARTUPINFO siStartInfo;
> int status = 1;
>
> DEBUG_OUT(“CreateChildProcess”);
> // Set up members of the PROCESS_INFORMATION structure.
>
> ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
>
> // Set up members of the STARTUPINFO structure.
>
> ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
> siStartInfo.cb = sizeof(STARTUPINFO);
>
> // Create the child process.
>
> if (!(status = CreateProcess(
> cmdline, // program
> options, // command line options
> NULL, // process security attributes
> NULL, // primary thread security attributes
> TRUE, // handles are inherited
> CREATE_NEW_CONSOLE, // creation flags
> NULL, // use parent’s environment
> NULL, // use parent’s current directory
> &siStartInfo, // STARTUPINFO pointer
> &piProcInfo))) // receives PROCESS_INFORMATION
> {
> DEBUG_OUT1(“CreateProcess failed. Error:%d\n”, GetLastError());
> }
>
> return status;
> }
>
>
>
> long WriteToPipe(VOID)
> {
> DWORD dwRead, dwWritten;
> CHAR chBuf[BUFSIZE];
>
> // Read from a file and write its contents to a pipe.
>
> for (;:wink:
> {
> if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
> dwRead == 0) break;
> if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
> &dwWritten, NULL)) break;
> }
>
> // Close the pipe handle so the child process stops reading.
>
> if (! CloseHandle(hChildStdinWrDup))
> {
> ErrorExit(“Close pipe failed\n”);
> return 1;
> }
> return 0;
> }
>
>
>
> long ReadFromPipe(VOID)
> {
> DWORD dwRead;
> CHAR chBuf[BUFSIZE];
> HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>
> // Close the write end of the pipe before reading from the
> // read end of the pipe.
> DEBUG_OUT(“ReadFromPipe”);
>
> if (!CloseHandle(hChildStdoutWr))
> {
> ErrorExit(“Closing handle failed”);
> return 1;
> }
>
> // Read output from the child process, and write to parent’s STDOUT.
>
> Sleep(500);
> for (;:wink:
> {
> DEBUG_OUT(“Read data from child”);
> if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL) ||
> dwRead == 0)
> {
> DEBUG_OUT1(“ReadFile Failed:%d”, GetLastError());
> break;
> }
>
> DEBUG_OUT(“Got data from child”);
> chBuf[dwRead] = 0;
> DEBUG_OUT1(“child out: %s\n”, chBuf);
> }
> return 0;
> }
>
>
>
> VOID ErrorExit (LPTSTR lpszMessage)
> {
> DEBUG_OUT1(“child Error: %s”, lpszMessage);
> }
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
></winerror.h></windows.h></stdio.h>

thnx so much,
huy

Maxim S. Shatskih

Services have closed stdin/stdout. Closed at all. These handles are
just
not valid.

Maybe this is your problem.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
> To: “Windows System Software Devs Interest List”
> Sent: Friday, December 17, 2004 5:57 AM
> Subject: [ntdev] nt services issue
>
>
>>
>>
>>
>> Hi guys,
>> I have a problem with the nt service issue. If I run as a console
>> application, everything seem to work probably, but when I convert the
>> code
>> to run as a service, I got the Call cmd :C:\WINDOWS\system32\cmd.exe
>> >Call opts :/C set
>> >CreateChildProcess
>> >child read pipe
>> >ReadFromPipe
>> >Read data from child
>> >ReadFile Failed:109
>> >child Done
>> // CallCmd.cpp: implementation of the CCallCmd class.
>> //
>> //////////////////////////////////////////////////////////////////////
>>
>> #include “CallCmd.h”
>> #include <stdio.h>
>> #include <windows.h>
>> #include <winerror.h>
>>
>> #define BUFSIZE 256
>>
>> #include “…/service/PipeClient.h”
>> #ifdef debug
>> extern CPipeClient m_clientPipe;
>> #endif
>>
>>
>> HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
>> hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
>> hInputFile, hSaveStdin, hSaveStdout;
>>
>> BOOL CreateChildProcess(char *cmdline, char *options);
>> long WriteToPipe(VOID);
>> long ReadFromPipe(VOID);
>> VOID ErrorExit(LPTSTR);
>> VOID ErrMsg(LPTSTR, BOOL);
>>
>> //#define pInputFile “parentInput”
>> #define pInputFile NULL
>>
>>
>> long CallCmd(char *cmdLine, char *options)
>> {
>> SECURITY_ATTRIBUTES saAttr;
>> BOOL fSuccess;
>>
>> DEBUG_OUT1(“Call cmd :%s”, cmdLine);
>> DEBUG_OUT1(“Call opts :%s”, options);
>>
>> // Set the bInheritHandle flag so pipe handles are inherited.
>>
>> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
>> saAttr.bInheritHandle = TRUE;
>> saAttr.lpSecurityDescriptor = NULL;
>>
>> // The steps for redirecting child process’s STDOUT:
>> // 1. Save current STDOUT, to be restored later.
>> // 2. Create anonymous pipe to be STDOUT for child process.
>> // 3. Set STDOUT of the parent process to be write handle to
>> // the pipe, so it is inherited by the child process.
>> // 4. Create a noninheritable duplicate of the read handle and
>> // close the inheritable read handle.
>>
>> // Save the handle to the current STDOUT.
>>
>> hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>>
>> // Create a pipe for the child process’s STDOUT.
>>
>> if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
>> {
>> ErrorExit(“Stdout pipe creation failed\n”);
>> return 1;
>> }
>>
>> // Set a write handle to the pipe to be STDOUT.
>>
>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
>> ErrorExit(“Redirecting STDOUT failed”);
>>
>> // Create noninheritable read handle and close the inheritable read
>> // handle.
>>
>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
>> GetCurrentProcess(), &hChildStdoutRdDup ,
>> 0,
>> FALSE,
>> DUPLICATE_SAME_ACCESS);
>> if( !fSuccess )
>> {
>> ErrorExit(“DuplicateHandle failed”);
>> return 1;
>> }
>> CloseHandle(hChildStdoutRd);
>>
>> // The steps for redirecting child process’s STDIN:
>> // 1. Save current STDIN, to be restored later.
>> // 2. Create anonymous pipe to be STDIN for child process.
>> // 3. Set STDIN of the parent to be the read handle to the
>> // pipe, so it is inherited by the child process.
>> // 4. Create a noninheritable duplicate of the write handle,
>> // and close the inheritable write handle.
>>
>> // Save the handle to the current STDIN.
>>
>> hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
>>
>> // Create a pipe for the child process’s STDIN.
>>
>> if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
>> {
>> ErrorExit(“Stdin pipe creation failed\n”);
>> return 1;
>> }
>>
>> // Set a read handle to the pipe to be STDIN.
>>
>> if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
>> {
>> ErrorExit(“Redirecting Stdin failed”);
>> return 1;
>> }
>>
>> // Duplicate the write handle to the pipe so it is not inherited.
>>
>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
>> GetCurrentProcess(), &hChildStdinWrDup, 0,
>> FALSE, // not inherited
>> DUPLICATE_SAME_ACCESS);
>> if (! fSuccess)
>> {
>> ErrorExit(“DuplicateHandle failed”);
>> return 1;
>> }
>>
>> CloseHandle(hChildStdinWr);
>>
>> // Now create the child process.
>>
>> if (! CreateChildProcess(cmdLine, options))
>> {
>> ErrorExit(“Create process failed”);
>> return 1;
>> }
>>
>> // After process creation, restore the saved STDIN and STDOUT.
>>
>> if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
>> {
>> ErrorExit(“Re-redirecting Stdin failed\n”);
>> return 1;
>> }
>>
>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
>> {
>> ErrorExit(“Re-redirecting Stdout failed\n”);
>> return 1;
>> }
>>
>> // Get a handle to the parent’s input file.
>>
>> if (pInputFile)
>> hInputFile = CreateFile(pInputFile, GENERIC_READ, 0, NULL,
>> OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
>> else
>> hInputFile = hSaveStdin;
>>
>> if (hInputFile == INVALID_HANDLE_VALUE)
>> {
>> ErrorExit(“no input file\n”);
>> return 1;
>> }
>>
>> // Write to pipe that is the standard input for a child process.
>>
>> // WriteToPipe();
>>
>> // Read from pipe that is the standard output for child process.
>>
>> DEBUG_OUT(“child read pipe”);
>> ReadFromPipe();
>>
>> DEBUG_OUT(“child Done”);
>> return 0;
>> }
>>
>>
>>
>>
>>
>> BOOL CreateChildProcess(char *cmdline, char *options)
>> {
>> PROCESS_INFORMATION piProcInfo;
>> STARTUPINFO siStartInfo;
>> int status = 1;
>>
>> DEBUG_OUT(“CreateChildProcess”);
>> // Set up members of the PROCESS_INFORMATION structure.
>>
>> ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
>>
>> // Set up members of the STARTUPINFO structure.
>>
>> ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
>> siStartInfo.cb = sizeof(STARTUPINFO);
>>
>> // Create the child process.
>>
>> if (!(status = CreateProcess(
>> cmdline, // program
>> options, // command line options
>> NULL, // process security attributes
>> NULL, // primary thread security attributes
>> TRUE, // handles are inherited
>> CREATE_NEW_CONSOLE, // creation flags
>> NULL, // use parent’s environment
>> NULL, // use parent’s current directory
>> &siStartInfo, // STARTUPINFO pointer
>> &piProcInfo))) // receives PROCESS_INFORMATION
>> {
>> DEBUG_OUT1(“CreateProcess failed. Error:%d\n”, GetLastError());
>> }
>>
>> return status;
>> }
>>
>>
>>
>> long WriteToPipe(VOID)
>> {
>> DWORD dwRead, dwWritten;
>> CHAR chBuf[BUFSIZE];
>>
>> // Read from a file and write its contents to a pipe.
>>
>> for (;:wink:
>> {
>> if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
>> dwRead == 0) break;
>> if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
>> &dwWritten, NULL)) break;
>> }
>>
>> // Close the pipe handle so the child process stops reading.
>>
>> if (! CloseHandle(hChildStdinWrDup))
>> {
>> ErrorExit(“Close pipe failed\n”);
>> return 1;
>> }
>> return 0;
>> }
>>
>>
>>
>> long ReadFromPipe(VOID)
>> {
>> DWORD dwRead;
>> CHAR chBuf[BUFSIZE];
>> HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>>
>> // Close the write end of the pipe before reading from the
>> // read end of the pipe.
>> DEBUG_OUT(“ReadFromPipe”);
>>
>> if (!CloseHandle(hChildStdoutWr))
>> {
>> ErrorExit(“Closing handle failed”);
>> return 1;
>> }
>>
>> // Read output from the child process, and write to parent’s STDOUT.
>>
>> Sleep(500);
>> for (;:wink:
>> {
>> DEBUG_OUT(“Read data from child”);
>> if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL)
>> ||
>> dwRead == 0)
>> {
>> DEBUG_OUT1(“ReadFile Failed:%d”, GetLastError());
>> break;
>> }
>>
>> DEBUG_OUT(“Got data from child”);
>> chBuf[dwRead] = 0;
>> DEBUG_OUT1(“child out: %s\n”, chBuf);
>> }
>> return 0;
>> }
>>
>>
>>
>> VOID ErrorExit (LPTSTR lpszMessage)
>> {
>> DEBUG_OUT1(“child Error: %s”, lpszMessage);
>> }
>>
>>
>> —
>> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>>
>> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
>> To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@dslextreme.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
></winerror.h></windows.h></stdio.h>

Hi Maxim,
Do you know why services close all the stdin, stdout? what can I do to
prevent service from doing it?
thnx,
Huy

xxxxx@dslextreme.com

thnx so much,
huy

Maxim S. Shatskih
> Services have closed stdin/stdout. Closed at all. These handles are
> just
> not valid.
>
> Maybe this is your problem.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
> ----- Original Message -----
> From:
>> To: “Windows System Software Devs Interest List”
>> Sent: Friday, December 17, 2004 5:57 AM
>> Subject: [ntdev] nt services issue
>>
>>
>>>
>>>
>>>
>>> Hi guys,
>>> I have a problem with the nt service issue. If I run as a console
>>> application, everything seem to work probably, but when I convert the
>>> code
>>> to run as a service, I got the Call cmd :C:\WINDOWS\system32\cmd.exe
>>> >Call opts :/C set
>>> >CreateChildProcess
>>> >child read pipe
>>> >ReadFromPipe
>>> >Read data from child
>>> >ReadFile Failed:109
>>> >child Done
>>> // CallCmd.cpp: implementation of the CCallCmd class.
>>> //
>>> //////////////////////////////////////////////////////////////////////
>>>
>>> #include “CallCmd.h”
>>> #include <stdio.h>
>>> #include <windows.h>
>>> #include <winerror.h>
>>>
>>> #define BUFSIZE 256
>>>
>>> #include “…/service/PipeClient.h”
>>> #ifdef debug
>>> extern CPipeClient m_clientPipe;
>>> #endif
>>>
>>>
>>> HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
>>> hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
>>> hInputFile, hSaveStdin, hSaveStdout;
>>>
>>> BOOL CreateChildProcess(char *cmdline, char *options);
>>> long WriteToPipe(VOID);
>>> long ReadFromPipe(VOID);
>>> VOID ErrorExit(LPTSTR);
>>> VOID ErrMsg(LPTSTR, BOOL);
>>>
>>> //#define pInputFile “parentInput”
>>> #define pInputFile NULL
>>>
>>>
>>> long CallCmd(char *cmdLine, char *options)
>>> {
>>> SECURITY_ATTRIBUTES saAttr;
>>> BOOL fSuccess;
>>>
>>> DEBUG_OUT1(“Call cmd :%s”, cmdLine);
>>> DEBUG_OUT1(“Call opts :%s”, options);
>>>
>>> // Set the bInheritHandle flag so pipe handles are inherited.
>>>
>>> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
>>> saAttr.bInheritHandle = TRUE;
>>> saAttr.lpSecurityDescriptor = NULL;
>>>
>>> // The steps for redirecting child process’s STDOUT:
>>> // 1. Save current STDOUT, to be restored later.
>>> // 2. Create anonymous pipe to be STDOUT for child process.
>>> // 3. Set STDOUT of the parent process to be write handle to
>>> // the pipe, so it is inherited by the child process.
>>> // 4. Create a noninheritable duplicate of the read handle and
>>> // close the inheritable read handle.
>>>
>>> // Save the handle to the current STDOUT.
>>>
>>> hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>>>
>>> // Create a pipe for the child process’s STDOUT.
>>>
>>> if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
>>> {
>>> ErrorExit(“Stdout pipe creation failed\n”);
>>> return 1;
>>> }
>>>
>>> // Set a write handle to the pipe to be STDOUT.
>>>
>>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
>>> ErrorExit(“Redirecting STDOUT failed”);
>>>
>>> // Create noninheritable read handle and close the inheritable read
>>> // handle.
>>>
>>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
>>> GetCurrentProcess(), &hChildStdoutRdDup
>>> ,
>>> 0,
>>> FALSE,
>>> DUPLICATE_SAME_ACCESS);
>>> if( !fSuccess )
>>> {
>>> ErrorExit(“DuplicateHandle failed”);
>>> return 1;
>>> }
>>> CloseHandle(hChildStdoutRd);
>>>
>>> // The steps for redirecting child process’s STDIN:
>>> // 1. Save current STDIN, to be restored later.
>>> // 2. Create anonymous pipe to be STDIN for child process.
>>> // 3. Set STDIN of the parent to be the read handle to the
>>> // pipe, so it is inherited by the child process.
>>> // 4. Create a noninheritable duplicate of the write handle,
>>> // and close the inheritable write handle.
>>>
>>> // Save the handle to the current STDIN.
>>>
>>> hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
>>>
>>> // Create a pipe for the child process’s STDIN.
>>>
>>> if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
>>> {
>>> ErrorExit(“Stdin pipe creation failed\n”);
>>> return 1;
>>> }
>>>
>>> // Set a read handle to the pipe to be STDIN.
>>>
>>> if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
>>> {
>>> ErrorExit(“Redirecting Stdin failed”);
>>> return 1;
>>> }
>>>
>>> // Duplicate the write handle to the pipe so it is not inherited.
>>>
>>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
>>> GetCurrentProcess(), &hChildStdinWrDup, 0,
>>> FALSE, // not inherited
>>> DUPLICATE_SAME_ACCESS);
>>> if (! fSuccess)
>>> {
>>> ErrorExit(“DuplicateHandle failed”);
>>> return 1;
>>> }
>>>
>>> CloseHandle(hChildStdinWr);
>>>
>>> // Now create the child process.
>>>
>>> if (! CreateChildProcess(cmdLine, options))
>>> {
>>> ErrorExit(“Create process failed”);
>>> return 1;
>>> }
>>>
>>> // After process creation, restore the saved STDIN and STDOUT.
>>>
>>> if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
>>> {
>>> ErrorExit(“Re-redirecting Stdin failed\n”);
>>> return 1;
>>> }
>>>
>>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
>>> {
>>> ErrorExit(“Re-redirecting Stdout failed\n”);
>>> return 1;
>>> }
>>>
>>> // Get a handle to the parent’s input file.
>>>
>>> if (pInputFile)
>>> hInputFile = CreateFile(pInputFile, GENERIC_READ, 0, NULL,
>>> OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
>>> else
>>> hInputFile = hSaveStdin;
>>>
>>> if (hInputFile == INVALID_HANDLE_VALUE)
>>> {
>>> ErrorExit(“no input file\n”);
>>> return 1;
>>> }
>>>
>>> // Write to pipe that is the standard input for a child process.
>>>
>>> // WriteToPipe();
>>>
>>> // Read from pipe that is the standard output for child process.
>>>
>>> DEBUG_OUT(“child read pipe”);
>>> ReadFromPipe();
>>>
>>> DEBUG_OUT(“child Done”);
>>> return 0;
>>> }
>>>
>>>
>>>
>>>
>>>
>>> BOOL CreateChildProcess(char *cmdline, char *options)
>>> {
>>> PROCESS_INFORMATION piProcInfo;
>>> STARTUPINFO siStartInfo;
>>> int status = 1;
>>>
>>> DEBUG_OUT(“CreateChildProcess”);
>>> // Set up members of the PROCESS_INFORMATION structure.
>>>
>>> ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
>>>
>>> // Set up members of the STARTUPINFO structure.
>>>
>>> ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
>>> siStartInfo.cb = sizeof(STARTUPINFO);
>>>
>>> // Create the child process.
>>>
>>> if (!(status = CreateProcess(
>>> cmdline, // program
>>> options, // command line options
>>> NULL, // process security attributes
>>> NULL, // primary thread security attributes
>>> TRUE, // handles are inherited
>>> CREATE_NEW_CONSOLE, // creation flags
>>> NULL, // use parent’s environment
>>> NULL, // use parent’s current directory
>>> &siStartInfo, // STARTUPINFO pointer
>>> &piProcInfo))) // receives PROCESS_INFORMATION
>>> {
>>> DEBUG_OUT1(“CreateProcess failed. Error:%d\n”, GetLastError());
>>> }
>>>
>>> return status;
>>> }
>>>
>>>
>>>
>>> long WriteToPipe(VOID)
>>> {
>>> DWORD dwRead, dwWritten;
>>> CHAR chBuf[BUFSIZE];
>>>
>>> // Read from a file and write its contents to a pipe.
>>>
>>> for (;:wink:
>>> {
>>> if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
>>> dwRead == 0) break;
>>> if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
>>> &dwWritten, NULL)) break;
>>> }
>>>
>>> // Close the pipe handle so the child process stops reading.
>>>
>>> if (! CloseHandle(hChildStdinWrDup))
>>> {
>>> ErrorExit(“Close pipe failed\n”);
>>> return 1;
>>> }
>>> return 0;
>>> }
>>>
>>>
>>>
>>> long ReadFromPipe(VOID)
>>> {
>>> DWORD dwRead;
>>> CHAR chBuf[BUFSIZE];
>>> HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>>>
>>> // Close the write end of the pipe before reading from the
>>> // read end of the pipe.
>>> DEBUG_OUT(“ReadFromPipe”);
>>>
>>> if (!CloseHandle(hChildStdoutWr))
>>> {
>>> ErrorExit(“Closing handle failed”);
>>> return 1;
>>> }
>>>
>>> // Read output from the child process, and write to parent’s STDOUT.
>>>
>>> Sleep(500);
>>> for (;:wink:
>>> {
>>> DEBUG_OUT(“Read data from child”);
>>> if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL)
>>> ||
>>> dwRead == 0)
>>> {
>>> DEBUG_OUT1(“ReadFile Failed:%d”, GetLastError());
>>> break;
>>> }
>>>
>>> DEBUG_OUT(“Got data from child”);
>>> chBuf[dwRead] = 0;
>>> DEBUG_OUT1(“child out: %s\n”, chBuf);
>>> }
>>> return 0;
>>> }
>>>
>>>
>>>
>>> VOID ErrorExit (LPTSTR lpszMessage)
>>> {
>>> DEBUG_OUT1(“child Error: %s”, lpszMessage);
>>> }
>>>
>>>
>>> —
>>> Questions? First check the Kernel Driver FAQ at
>> http://www.osronline.com/article.cfm?id=256
>>>
>>> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
>>> To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>
>>
>>
>> —
>> Questions? First check the Kernel Driver FAQ at
>> http://www.osronline.com/article.cfm?id=256
>>
>> You are currently subscribed to ntdev as: xxxxx@dslextreme.com
>> To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@dslextreme.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
></winerror.h></windows.h></stdio.h>

They do not close them.
They do not have stdin/stdout open at all, from the very beginning.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Friday, December 17, 2004 9:11 AM
Subject: Re: [ntdev] nt services issue

> Hi Maxim,
> Do you know why services close all the stdin, stdout? what can I do to
> prevent service from doing it?
> thnx,
> Huy
>
>
> xxxxx@dslextreme.com
> > thnx so much,
> > huy
> >
> >
> > Maxim S. Shatskih
> >> Services have closed stdin/stdout. Closed at all. These handles are
> >> just
> >> not valid.
> >>
> >> Maybe this is your problem.
> >>
> >> Maxim Shatskih, Windows DDK MVP
> >> StorageCraft Corporation
> >> xxxxx@storagecraft.com
> >> http://www.storagecraft.com
> >>
> >> ----- Original Message -----
> >> From:
> >> To: “Windows System Software Devs Interest List”
> >> Sent: Friday, December 17, 2004 5:57 AM
> >> Subject: [ntdev] nt services issue
> >>
> >>
> >>>
> >>>
> >>>
> >>> Hi guys,
> >>> I have a problem with the nt service issue. If I run as a console
> >>> application, everything seem to work probably, but when I convert the
> >>> code
> >>> to run as a service, I got the Call cmd :C:\WINDOWS\system32\cmd.exe
> >>> >Call opts :/C set
> >>> >CreateChildProcess
> >>> >child read pipe
> >>> >ReadFromPipe
> >>> >Read data from child
> >>> >ReadFile Failed:109
> >>> >child Done
> >>> // CallCmd.cpp: implementation of the CCallCmd class.
> >>> //
> >>> //////////////////////////////////////////////////////////////////////
> >>>
> >>> #include “CallCmd.h”
> >>> #include <stdio.h>
> >>> #include <windows.h>
> >>> #include <winerror.h>
> >>>
> >>> #define BUFSIZE 256
> >>>
> >>> #include “…/service/PipeClient.h”
> >>> #ifdef debug
> >>> extern CPipeClient m_clientPipe;
> >>> #endif
> >>>
> >>>
> >>> HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
> >>> hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
> >>> hInputFile, hSaveStdin, hSaveStdout;
> >>>
> >>> BOOL CreateChildProcess(char *cmdline, char *options);
> >>> long WriteToPipe(VOID);
> >>> long ReadFromPipe(VOID);
> >>> VOID ErrorExit(LPTSTR);
> >>> VOID ErrMsg(LPTSTR, BOOL);
> >>>
> >>> //#define pInputFile “parentInput”
> >>> #define pInputFile NULL
> >>>
> >>>
> >>> long CallCmd(char *cmdLine, char *options)
> >>> {
> >>> SECURITY_ATTRIBUTES saAttr;
> >>> BOOL fSuccess;
> >>>
> >>> DEBUG_OUT1(“Call cmd :%s”, cmdLine);
> >>> DEBUG_OUT1(“Call opts :%s”, options);
> >>>
> >>> // Set the bInheritHandle flag so pipe handles are inherited.
> >>>
> >>> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
> >>> saAttr.bInheritHandle = TRUE;
> >>> saAttr.lpSecurityDescriptor = NULL;
> >>>
> >>> // The steps for redirecting child process’s STDOUT:
> >>> // 1. Save current STDOUT, to be restored later.
> >>> // 2. Create anonymous pipe to be STDOUT for child process.
> >>> // 3. Set STDOUT of the parent process to be write handle to
> >>> // the pipe, so it is inherited by the child process.
> >>> // 4. Create a noninheritable duplicate of the read handle and
> >>> // close the inheritable read handle.
> >>>
> >>> // Save the handle to the current STDOUT.
> >>>
> >>> hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
> >>>
> >>> // Create a pipe for the child process’s STDOUT.
> >>>
> >>> if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
> >>> {
> >>> ErrorExit(“Stdout pipe creation failed\n”);
> >>> return 1;
> >>> }
> >>>
> >>> // Set a write handle to the pipe to be STDOUT.
> >>>
> >>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
> >>> ErrorExit(“Redirecting STDOUT failed”);
> >>>
> >>> // Create noninheritable read handle and close the inheritable read
> >>> // handle.
> >>>
> >>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
> >>> GetCurrentProcess(), &hChildStdoutRdDup
> >>> ,
> >>> 0,
> >>> FALSE,
> >>> DUPLICATE_SAME_ACCESS);
> >>> if( !fSuccess )
> >>> {
> >>> ErrorExit(“DuplicateHandle failed”);
> >>> return 1;
> >>> }
> >>> CloseHandle(hChildStdoutRd);
> >>>
> >>> // The steps for redirecting child process’s STDIN:
> >>> // 1. Save current STDIN, to be restored later.
> >>> // 2. Create anonymous pipe to be STDIN for child process.
> >>> // 3. Set STDIN of the parent to be the read handle to the
> >>> // pipe, so it is inherited by the child process.
> >>> // 4. Create a noninheritable duplicate of the write handle,
> >>> // and close the inheritable write handle.
> >>>
> >>> // Save the handle to the current STDIN.
> >>>
> >>> hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
> >>>
> >>> // Create a pipe for the child process’s STDIN.
> >>>
> >>> if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
> >>> {
> >>> ErrorExit(“Stdin pipe creation failed\n”);
> >>> return 1;
> >>> }
> >>>
> >>> // Set a read handle to the pipe to be STDIN.
> >>>
> >>> if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
> >>> {
> >>> ErrorExit(“Redirecting Stdin failed”);
> >>> return 1;
> >>> }
> >>>
> >>> // Duplicate the write handle to the pipe so it is not inherited.
> >>>
> >>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
> >>> GetCurrentProcess(), &hChildStdinWrDup, 0,
> >>> FALSE, // not inherited
> >>> DUPLICATE_SAME_ACCESS);
> >>> if (! fSuccess)
> >>> {
> >>> ErrorExit(“DuplicateHandle failed”);
> >>> return 1;
> >>> }
> >>>
> >>> CloseHandle(hChildStdinWr);
> >>>
> >>> // Now create the child process.
> >>>
> >>> if (! CreateChildProcess(cmdLine, options))
> >>> {
> >>> ErrorExit(“Create process failed”);
> >>> return 1;
> >>> }
> >>>
> >>> // After process creation, restore the saved STDIN and STDOUT.
> >>>
> >>> if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
> >>> {
> >>> ErrorExit(“Re-redirecting Stdin failed\n”);
> >>> return 1;
> >>> }
> >>>
> >>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
> >>> {
> >>> ErrorExit(“Re-redirecting Stdout failed\n”);
> >>> return 1;
> >>> }
> >>>
> >>> // Get a handle to the parent’s input file.
> >>>
> >>> if (pInputFile)
> >>> hInputFile = CreateFile(pInputFile, GENERIC_READ, 0, NULL,
> >>> OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
> >>> else
> >>> hInputFile = hSaveStdin;
> >>>
> >>> if (hInputFile == INVALID_HANDLE_VALUE)
> >>> {
> >>> ErrorExit(“no input file\n”);
> >>> return 1;
> >>> }
> >>>
> >>> // Write to pipe that is the standard input for a child process.
> >>>
> >>> // WriteToPipe();
> >>>
> >>> // Read from pipe that is the standard output for child process.
> >>>
> >>> DEBUG_OUT(“child read pipe”);
> >>> ReadFromPipe();
> >>>
> >>> DEBUG_OUT(“child Done”);
> >>> return 0;
> >>> }
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> BOOL CreateChildProcess(char *cmdline, char *options)
> >>> {
> >>> PROCESS_INFORMATION piProcInfo;
> >>> STARTUPINFO siStartInfo;
> >>> int status = 1;
> >>>
> >>> DEBUG_OUT(“CreateChildProcess”);
> >>> // Set up members of the PROCESS_INFORMATION structure.
> >>>
> >>> ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
> >>>
> >>> // Set up members of the STARTUPINFO structure.
> >>>
> >>> ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
> >>> siStartInfo.cb = sizeof(STARTUPINFO);
> >>>
> >>> // Create the child process.
> >>>
> >>> if (!(status = CreateProcess(
> >>> cmdline, // program
> >>> options, // command line options
> >>> NULL, // process security attributes
> >>> NULL, // primary thread security attributes
> >>> TRUE, // handles are inherited
> >>> CREATE_NEW_CONSOLE, // creation flags
> >>> NULL, // use parent’s environment
> >>> NULL, // use parent’s current directory
> >>> &siStartInfo, // STARTUPINFO pointer
> >>> &piProcInfo))) // receives PROCESS_INFORMATION
> >>> {
> >>> DEBUG_OUT1(“CreateProcess failed. Error:%d\n”, GetLastError());
> >>> }
> >>>
> >>> return status;
> >>> }
> >>>
> >>>
> >>>
> >>> long WriteToPipe(VOID)
> >>> {
> >>> DWORD dwRead, dwWritten;
> >>> CHAR chBuf[BUFSIZE];
> >>>
> >>> // Read from a file and write its contents to a pipe.
> >>>
> >>> for (;:wink:
> >>> {
> >>> if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
> >>> dwRead == 0) break;
> >>> if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
> >>> &dwWritten, NULL)) break;
> >>> }
> >>>
> >>> // Close the pipe handle so the child process stops reading.
> >>>
> >>> if (! CloseHandle(hChildStdinWrDup))
> >>> {
> >>> ErrorExit(“Close pipe failed\n”);
> >>> return 1;
> >>> }
> >>> return 0;
> >>> }
> >>>
> >>>
> >>>
> >>> long ReadFromPipe(VOID)
> >>> {
> >>> DWORD dwRead;
> >>> CHAR chBuf[BUFSIZE];
> >>> HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
> >>>
> >>> // Close the write end of the pipe before reading from the
> >>> // read end of the pipe.
> >>> DEBUG_OUT(“ReadFromPipe”);
> >>>
> >>> if (!CloseHandle(hChildStdoutWr))
> >>> {
> >>> ErrorExit(“Closing handle failed”);
> >>> return 1;
> >>> }
> >>>
> >>> // Read output from the child process, and write to parent’s STDOUT.
> >>>
> >>> Sleep(500);
> >>> for (;:wink:
> >>> {
> >>> DEBUG_OUT(“Read data from child”);
> >>> if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL)
> >>> ||
> >>> dwRead == 0)
> >>> {
> >>> DEBUG_OUT1(“ReadFile Failed:%d”, GetLastError());
> >>> break;
> >>> }
> >>>
> >>> DEBUG_OUT(“Got data from child”);
> >>> chBuf[dwRead] = 0;
> >>> DEBUG_OUT1(“child out: %s\n”, chBuf);
> >>> }
> >>> return 0;
> >>> }
> >>>
> >>>
> >>>
> >>> VOID ErrorExit (LPTSTR lpszMessage)
> >>> {
> >>> DEBUG_OUT1(“child Error: %s”, lpszMessage);
> >>> }
> >>>
> >>>
> >>> —
> >>> Questions? First check the Kernel Driver FAQ at
> >> http://www.osronline.com/article.cfm?id=256
> >>>
> >>> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> >>> To unsubscribe send a blank email to xxxxx@lists.osr.com
> >>>
> >>
> >>
> >> —
> >> Questions? First check the Kernel Driver FAQ at
> >> http://www.osronline.com/article.cfm?id=256
> >>
> >> You are currently subscribed to ntdev as: xxxxx@dslextreme.com
> >> To unsubscribe send a blank email to xxxxx@lists.osr.com
> >>
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@dslextreme.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
></winerror.h></windows.h></stdio.h>

If you think about it for a moment, it becomes
obvious why there isn’t a STDIN or STDOUT for
a service. A service runs even when no user
is logged on, after the user logs off, or when
a different users logs on.

There is no possible way a command window could
span all those environments.

Best practice, don’t use stdin, stdout or stderr
in a service. In fact, don’t do anything that
displays any kind of UI, period. Services
are UI-less programs. That is the whole point
of a service.

That said, you could open STDIN and STDOUT
handles by opening CONIN$ (I think) and CONOUT$
(see CreateFile documentation.) You might
also need to do an AllocConsole(), I don’t
remember. With the handles returned from
CreateFile() you can do a SetStdHandle().

The console window created through this technique
will be in a hidden window station on a hidden
desktop. It will never be seen by the user.
There will never be any input. There is no
make the window station, desktop, or command
window visible.

Just say “NO” to UI in services. UI in a
service is a very bad idea.

Thanks,

Joseph

Maxim S. Shatskih wrote:

They do not close them.
They do not have stdin/stdout open at all, from the very beginning.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
> To: “Windows System Software Devs Interest List”
> Sent: Friday, December 17, 2004 9:11 AM
> Subject: Re: [ntdev] nt services issue
>
>
>
>>Hi Maxim,
>>Do you know why services close all the stdin, stdout? what can I do to
>>prevent service from doing it?
>>thnx,
>>Huy
>>
>>
>>xxxxx@dslextreme.com
>>
>>>thnx so much,
>>>huy
>>>
>>>
>>>Maxim S. Shatskih
>>>
>>>> Services have closed stdin/stdout. Closed at all. These handles are
>>>>just
>>>>not valid.
>>>>
>>>> Maybe this is your problem.
>>>>
>>>>Maxim Shatskih, Windows DDK MVP
>>>>StorageCraft Corporation
>>>>xxxxx@storagecraft.com
>>>>http://www.storagecraft.com
>>>>
>>>>----- Original Message -----
>>>>From:
>>>>To: “Windows System Software Devs Interest List”
>>>>Sent: Friday, December 17, 2004 5:57 AM
>>>>Subject: [ntdev] nt services issue
>>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>>Hi guys,
>>>>>I have a problem with the nt service issue. If I run as a console
>>>>>application, everything seem to work probably, but when I convert the
>>>>>code
>>>>>to run as a service, I got the Call cmd :C:\WINDOWS\system32\cmd.exe
>>>>>
>>>>>>Call opts :/C set
>>>>>>CreateChildProcess
>>>>>>child read pipe
>>>>>>ReadFromPipe
>>>>>>Read data from child
>>>>>>ReadFile Failed:109
>>>>>>child Done
>>>>>
>>>>>// CallCmd.cpp: implementation of the CCallCmd class.
>>>>>//
>>>>>//////////////////////////////////////////////////////////////////////
>>>>>
>>>>>#include “CallCmd.h”
>>>>>#include <stdio.h>
>>>>>#include <windows.h>
>>>>>#include <winerror.h>
>>>>>
>>>>>#define BUFSIZE 256
>>>>>
>>>>>#include “…/service/PipeClient.h”
>>>>>#ifdef debug
>>>>>extern CPipeClient m_clientPipe;
>>>>>#endif
>>>>>
>>>>>
>>>>>HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
>>>>> hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
>>>>> hInputFile, hSaveStdin, hSaveStdout;
>>>>>
>>>>>BOOL CreateChildProcess(char *cmdline, char *options);
>>>>>long WriteToPipe(VOID);
>>>>>long ReadFromPipe(VOID);
>>>>>VOID ErrorExit(LPTSTR);
>>>>>VOID ErrMsg(LPTSTR, BOOL);
>>>>>
>>>>>//#define pInputFile “parentInput”
>>>>>#define pInputFile NULL
>>>>>
>>>>>
>>>>>long CallCmd(char *cmdLine, char *options)
>>>>>{
>>>>> SECURITY_ATTRIBUTES saAttr;
>>>>> BOOL fSuccess;
>>>>>
>>>>> DEBUG_OUT1(“Call cmd :%s”, cmdLine);
>>>>> DEBUG_OUT1(“Call opts :%s”, options);
>>>>>
>>>>>// Set the bInheritHandle flag so pipe handles are inherited.
>>>>>
>>>>> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
>>>>> saAttr.bInheritHandle = TRUE;
>>>>> saAttr.lpSecurityDescriptor = NULL;
>>>>>
>>>>> // The steps for redirecting child process’s STDOUT:
>>>>> // 1. Save current STDOUT, to be restored later.
>>>>> // 2. Create anonymous pipe to be STDOUT for child process.
>>>>> // 3. Set STDOUT of the parent process to be write handle to
>>>>> // the pipe, so it is inherited by the child process.
>>>>> // 4. Create a noninheritable duplicate of the read handle and
>>>>> // close the inheritable read handle.
>>>>>
>>>>>// Save the handle to the current STDOUT.
>>>>>
>>>>> hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>>>>>
>>>>>// Create a pipe for the child process’s STDOUT.
>>>>>
>>>>> if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
>>>>> {
>>>>> ErrorExit(“Stdout pipe creation failed\n”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>>// Set a write handle to the pipe to be STDOUT.
>>>>>
>>>>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
>>>>> ErrorExit(“Redirecting STDOUT failed”);
>>>>>
>>>>>// Create noninheritable read handle and close the inheritable read
>>>>>// handle.
>>>>>
>>>>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
>>>>> GetCurrentProcess(), &hChildStdoutRdDup
>>>>>,
>>>>>0,
>>>>> FALSE,
>>>>> DUPLICATE_SAME_ACCESS);
>>>>> if( !fSuccess )
>>>>> {
>>>>> ErrorExit(“DuplicateHandle failed”);
>>>>> return 1;
>>>>> }
>>>>> CloseHandle(hChildStdoutRd);
>>>>>
>>>>> // The steps for redirecting child process’s STDIN:
>>>>> // 1. Save current STDIN, to be restored later.
>>>>> // 2. Create anonymous pipe to be STDIN for child process.
>>>>> // 3. Set STDIN of the parent to be the read handle to the
>>>>> // pipe, so it is inherited by the child process.
>>>>> // 4. Create a noninheritable duplicate of the write handle,
>>>>> // and close the inheritable write handle.
>>>>>
>>>>>// Save the handle to the current STDIN.
>>>>>
>>>>> hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
>>>>>
>>>>>// Create a pipe for the child process’s STDIN.
>>>>>
>>>>> if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
>>>>> {
>>>>> ErrorExit(“Stdin pipe creation failed\n”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>>// Set a read handle to the pipe to be STDIN.
>>>>>
>>>>> if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
>>>>> {
>>>>> ErrorExit(“Redirecting Stdin failed”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>>// Duplicate the write handle to the pipe so it is not inherited.
>>>>>
>>>>> fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
>>>>> GetCurrentProcess(), &hChildStdinWrDup, 0,
>>>>> FALSE, // not inherited
>>>>> DUPLICATE_SAME_ACCESS);
>>>>> if (! fSuccess)
>>>>> {
>>>>> ErrorExit(“DuplicateHandle failed”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>> CloseHandle(hChildStdinWr);
>>>>>
>>>>>// Now create the child process.
>>>>>
>>>>> if (! CreateChildProcess(cmdLine, options))
>>>>> {
>>>>> ErrorExit(“Create process failed”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>>// After process creation, restore the saved STDIN and STDOUT.
>>>>>
>>>>> if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
>>>>> {
>>>>> ErrorExit(“Re-redirecting Stdin failed\n”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>> if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
>>>>> {
>>>>> ErrorExit(“Re-redirecting Stdout failed\n”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>>// Get a handle to the parent’s input file.
>>>>>
>>>>> if (pInputFile)
>>>>> hInputFile = CreateFile(pInputFile, GENERIC_READ, 0, NULL,
>>>>> OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
>>>>> else
>>>>> hInputFile = hSaveStdin;
>>>>>
>>>>> if (hInputFile == INVALID_HANDLE_VALUE)
>>>>> {
>>>>> ErrorExit(“no input file\n”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>>// Write to pipe that is the standard input for a child process.
>>>>>
>>>>>// WriteToPipe();
>>>>>
>>>>>// Read from pipe that is the standard output for child process.
>>>>>
>>>>> DEBUG_OUT(“child read pipe”);
>>>>> ReadFromPipe();
>>>>>
>>>>> DEBUG_OUT(“child Done”);
>>>>> return 0;
>>>>>}
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>BOOL CreateChildProcess(char *cmdline, char *options)
>>>>>{
>>>>> PROCESS_INFORMATION piProcInfo;
>>>>> STARTUPINFO siStartInfo;
>>>>> int status = 1;
>>>>>
>>>>> DEBUG_OUT(“CreateChildProcess”);
>>>>>// Set up members of the PROCESS_INFORMATION structure.
>>>>>
>>>>> ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
>>>>>
>>>>>// Set up members of the STARTUPINFO structure.
>>>>>
>>>>> ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
>>>>> siStartInfo.cb = sizeof(STARTUPINFO);
>>>>>
>>>>>// Create the child process.
>>>>>
>>>>> if (!(status = CreateProcess(
>>>>> cmdline, // program
>>>>> options, // command line options
>>>>> NULL, // process security attributes
>>>>> NULL, // primary thread security attributes
>>>>> TRUE, // handles are inherited
>>>>> CREATE_NEW_CONSOLE, // creation flags
>>>>> NULL, // use parent’s environment
>>>>> NULL, // use parent’s current directory
>>>>> &siStartInfo, // STARTUPINFO pointer
>>>>> &piProcInfo))) // receives PROCESS_INFORMATION
>>>>> {
>>>>> DEBUG_OUT1(“CreateProcess failed. Error:%d\n”, GetLastError());
>>>>> }
>>>>>
>>>>> return status;
>>>>>}
>>>>>
>>>>>
>>>>>
>>>>>long WriteToPipe(VOID)
>>>>>{
>>>>> DWORD dwRead, dwWritten;
>>>>> CHAR chBuf[BUFSIZE];
>>>>>
>>>>>// Read from a file and write its contents to a pipe.
>>>>>
>>>>> for (;:wink:
>>>>> {
>>>>> if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
>>>>> dwRead == 0) break;
>>>>> if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
>>>>> &dwWritten, NULL)) break;
>>>>> }
>>>>>
>>>>>// Close the pipe handle so the child process stops reading.
>>>>>
>>>>> if (! CloseHandle(hChildStdinWrDup))
>>>>> {
>>>>> ErrorExit(“Close pipe failed\n”);
>>>>> return 1;
>>>>> }
>>>>> return 0;
>>>>>}
>>>>>
>>>>>
>>>>>
>>>>>long ReadFromPipe(VOID)
>>>>>{
>>>>> DWORD dwRead;
>>>>> CHAR chBuf[BUFSIZE];
>>>>> HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
>>>>>
>>>>>// Close the write end of the pipe before reading from the
>>>>>// read end of the pipe.
>>>>> DEBUG_OUT(“ReadFromPipe”);
>>>>>
>>>>> if (!CloseHandle(hChildStdoutWr))
>>>>> {
>>>>> ErrorExit(“Closing handle failed”);
>>>>> return 1;
>>>>> }
>>>>>
>>>>>// Read output from the child process, and write to parent’s STDOUT.
>>>>>
>>>>> Sleep(500);
>>>>> for (;:wink:
>>>>> {
>>>>> DEBUG_OUT(“Read data from child”);
>>>>> if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL)
>>>>>||
>>>>>dwRead == 0)
>>>>> {
>>>>> DEBUG_OUT1(“ReadFile Failed:%d”, GetLastError());
>>>>> break;
>>>>> }
>>>>>
>>>>> DEBUG_OUT(“Got data from child”);
>>>>> chBuf[dwRead] = 0;
>>>>> DEBUG_OUT1(“child out: %s\n”, chBuf);
>>>>> }
>>>>> return 0;
>>>>>}
>>>>>
>>>>>
>>>>>
>>>>>VOID ErrorExit (LPTSTR lpszMessage)
>>>>>{
>>>>> DEBUG_OUT1(“child Error: %s”, lpszMessage);
>>>>>}
>>>>>
>>>>>
>>>>>—
>>>>>Questions? First check the Kernel Driver FAQ at
>>>>
>>>>http://www.osronline.com/article.cfm?id=256
>>>>
>>>>>You are currently subscribed to ntdev as: xxxxx@storagecraft.com
>>>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>>>
>>>>
>>>>
>>>>—
>>>>Questions? First check the Kernel Driver FAQ at
>>>>http://www.osronline.com/article.cfm?id=256
>>>>
>>>>You are currently subscribed to ntdev as: xxxxx@dslextreme.com
>>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>>
>>>
>>>
>>>—
>>>Questions? First check the Kernel Driver FAQ at
>>>http://www.osronline.com/article.cfm?id=256
>>>
>>>You are currently subscribed to ntdev as: xxxxx@dslextreme.com
>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>
> http://www.osronline.com/article.cfm?id=256
>
>>You are currently subscribed to ntdev as: xxxxx@storagecraft.com
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@vandyke.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
></winerror.h></windows.h></stdio.h>