Board index » cppbuilder » CreateProcess and piping. Trying to spoon feed TELNET

CreateProcess and piping. Trying to spoon feed TELNET


2006-10-20 12:43:20 PM
cppbuilder100
OK standing on the back of giants I have learned a lot but alas I am
still wanting.
You will no doubt recognize this as code that has been presented here
before.
I got it straight from this user group and it performed as indicated.
However I don't understand why if I change the CreateProcess so it
starts TELNET instead of CMD that it blows up with a bad handle?
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if(!CreatePipe(&hStdInRead, &hStdInWrite, &sa, 0)) {
CloseHandles();
RaiseLastWin32Error();
}
if(!CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0)) {
CloseHandles();
RaiseLastWin32Error();
}
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput = hStdInRead;
si.hStdOutput = hStdOutWrite;
si.hStdError = hStdOutWrite;
// --->>change from cmd.exe to telnet.exe
if(!CreateProcess("c:\\WINNT\\system32\\cmd.exe", NULL, NULL, NULL,
TRUE,
0,
NULL, NULL, &si, &pi)) {
CloseHandles();
RaiseLastWin32Error();
}
CloseHandle(pi.hThread);
hProcess = pi.hProcess;
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(!hStdInWrite) return;
AnsiString Data = "dir\n";
// -->>Change to "display\n" a valid command for telnet
char *ptr = Data.c_str();
DWORD TotalBytes = Data.Length();
DWORD BytesSent = 0;
while(TotalBytes) {
if(!WriteFile(hStdInWrite, ptr, TotalBytes, &BytesSent, NULL))
RaiseLastWin32Error();
ptr += BytesSent;
TotalBytes -= BytesSent;
}
}
//---------------------------------------------------------------------------
The error is win32 error code :6 handle is invalid
 
 

Re:CreateProcess and piping. Trying to spoon feed TELNET

< XXXX@XXXXX.COM >wrote in message
Quote
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
That is the wrong way to set up a descriptor that allows all access. You
need to use SetSecurityDescriptorDacl() as well:
SECURITY_DESCRIPTOR sd = {0};
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = &sd;
Quote
The error is win32 error code :6 handle is invalid
At which point exactly?
Gambit
 

Re:CreateProcess and piping. Trying to spoon feed TELNET

On Fri, 20 Oct 2006 00:02:02 -0700, "Remy Lebeau \(TeamB\)"
< XXXX@XXXXX.COM >wrote:
Quote
That is the wrong way to set up a descriptor that allows all access. You
need to use SetSecurityDescriptorDacl() as well:
>The error is win32 error code :6 handle is invalid
Thanks for the heads up on the SECURITY DESCRIPTOR.

At which point exactly?
Gambit
I now have a little better idea of what is happening but don't know
why. Somehow Telnet is not starting.
Assuming I have the spawned process set to cmd.exe
I put a breakpoint just before the CreateProcess() and stepped through
it. Then I bring up the task manager and there is CMD in the list of
processes as it should be.
But it doesn't show up there if I spawn telnet.exe
Apparently CreateProcess() does return a non zero result but it still
isn't right. The end result is that when the timer is triggered it
peeks at the pipe and the total bytes are 0. That being the case it
calls CloseHandles() and so the subsequent timer trigger is invalid.
But that is a red herring.
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
DWORD TotalBytes = 0;
if(!PeekNamedPipe(hStdOutRead, NULL, 0, NULL, &TotalBytes, NULL))
RaiseLastWin32Error();
if(TotalBytes) {
char Data[1024];
DWORD BytesRead = 0;
while(TotalBytes) {
if(!ReadFile(hStdOutRead, Data, sizeof(Data)-1, &BytesRead, NULL))
RaiseLastWin32Error();
Memo1->SelStart = Memo1->GetTextLen();
Memo1->SelText = AnsiString(Data, BytesRead);
TotalBytes -= BytesRead;
}
} else if(WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0) ;
CloseHandles();
}
//-----------------------
void __fastcall TForm1::CloseHandles()
{
if(hProcess) {
CloseHandle(hProcess);
hProcess = NULL;
}
if(hStdInRead) {
CloseHandle(hStdInRead);
hStdInRead = NULL;
}
if(hStdInWrite) {
CloseHandle(hStdInWrite);
hStdInWrite = NULL;
}
if(hStdOutRead) {
CloseHandle(hStdOutRead);
hStdOutRead = NULL;
}
if(hStdInWrite) {
CloseHandle(hStdOutWrite);
hStdOutWrite = NULL;
}
}
//------------------------
 

{smallsort}

Re:CreateProcess and piping. Trying to spoon feed TELNET

XXXX@XXXXX.COM wrote:
Quote
Assuming I have the spawned process set to cmd.exe
I put a breakpoint just before the CreateProcess() and stepped through
it. Then I bring up the task manager and there is CMD in the list of
processes as it should be.

But it doesn't show up there if I spawn telnet.exe
Yes, I try with my own code:
www.leunen.com/cbuilder/redirect.html
and it exhibits the same behaviour. Telnet is launched because
CreateProcess() doesn't report any error and besides, a valid handle and
process ID is returned. But effectively, it doesn't show up in the task
manager. And using my code snippet, I can see that nothing is sent
through the pipe.
Note that it doesn't work with ftp.exe either. However, it works for all
the other applications I've tried. I first thought it was a network
issue but if it doesn't work with ftp, it works with tftp. I now think
it's due to the fact that telnet and ftp all two open some sort of a
shell to let you enter command.
Michel
--
----------------------------------------
Michel Leunen
mailto: see my homepage.
C++Builder, BCC5.5.1 Web site:
www.leunen.com/
----------------------------------------
 

Re:CreateProcess and piping. Trying to spoon feed TELNET

OK at least I see it is strange behavior.
But check this out.
If you start telnet manually and then check the task manager
It is there. not only that,
I can using an entirely different program to
EnumWindows((WNDENUMPROC)ewp, 0);
and then direct keystrokes to it via
keybd_event( VkKeyScan(*character), 0, 0, 0 );
SO how is CreateProcess starting telnet?
Quote
On Fri, 20 Oct 2006 17:12:21 +0200, Michel Leunen < XXXX@XXXXX.COM >>
Yes, I try with my own code:
www.leunen.com/cbuilder/redirect.html
and it exhibits the same behaviour. Telnet is launched because
CreateProcess() doesn't report any error and besides, a valid handle and
process ID is returned. But effectively, it doesn't show up in the task
manager. And using my code snippet, I can see that nothing is sent
through the pipe.
Note that it doesn't work with ftp.exe either. However, it works for all
the other applications I've tried. I first thought it was a network
issue but if it doesn't work with ftp, it works with tftp. I now think
it's due to the fact that telnet and ftp all two open some sort of a
shell to let you enter command.

Michel
 

Re:CreateProcess and piping. Trying to spoon feed TELNET

XXXX@XXXXX.COM wrote:
Quote
I can using an entirely different program to
EnumWindows((WNDENUMPROC)ewp, 0);
and then direct keystrokes to it via
keybd_event( VkKeyScan(*character), 0, 0, 0 );
The text printed on a console by Telnet is written through a console
buffer and not stdout. That's why I didn't see anything when reading my
pipe. But it doesn't explain why tenet isn't appearing in the task
manager. No idea.
Michel
--
----------------------------------------
Michel Leunen
mailto: see my homepage.
C++Builder, BCC5.5.1 Web site:
www.leunen.com/
----------------------------------------
 

Re:CreateProcess and piping. Trying to spoon feed TELNET

< XXXX@XXXXX.COM >wrote in message
Quote
But it doesn't show up there if I spawn telnet.exe
Are you passing any parameters for telnet.exe? If not, then it might be
exiting immediately. Or CreateProcess() may be failing. Please show the
actual code that is spawning telnet.
Alternatively, you might consider using your own telnet socket. Then you
don't need to spawn the OS's telnet executable at all.
Quote
else if(WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0) ;
CloseHandles();
You have an extra semicolon in there that you need to take out.
Gambit
 

Re:CreateProcess and piping. Trying to spoon feed TELNET

On Fri, 20 Oct 2006 10:42:13 -0700, "Remy Lebeau \(TeamB\)"
< XXXX@XXXXX.COM >wrote:
Quote

< XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>But it doesn't show up there if I spawn telnet.exe

Are you passing any parameters for telnet.exe? If not, then it might be
exiting immediately. Or CreateProcess() may be failing. Please show the
actual code that is spawning telnet.
Not passing any parameters but then I don't pass any when I start it
manually.
In the past two post I have pretty much included all code I think.
I added your suggestion as well.
Quote
Alternatively, you might consider using your own telnet socket. Then you
don't need to spawn the OS's telnet executable at all.

Sounds great any hints on where to start?
Quote
>else if(WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0) ;
>CloseHandles();
Yea; I just added it for debugging and remarked out the closeHandles()
back then
Quote

You have an extra semicolon in there that you need to take out.


Gambit

 

Re:CreateProcess and piping. Trying to spoon feed TELNET

< XXXX@XXXXX.COM >wrote in message
Quote
Sounds great any hints on where to start?
Look at the WinSock API. Specifically, at the WSAStartup/Cleanup(),
socket(), bind(), send(), recv(), and select() functions.
Gambit