telnet.exe über STD-input/output handler "fernsteuer"
-
hallo zusammen,
ich versuche momentan ein einfaches Kommando aus einem Programm heraus auf einer entfernten Maschine aufzurufen. Auf dem Gerät läuft leider nur ein Telnet server deshalb bin ich drauf angwiesen den Befehl auf diese Art und Weise abzusetzten.
Ein neues Telnet-Fenster lässt sich problemlos öffnen, deshalb habe ich zuerst gedacht es ist möglich direkt auf die entsprechende console zuzugreifen. Da ich so aber keinen Zugriff auf den STD-Input von Telnet.exe habe komme ich an der Stelle nicht richtig weiter.
Nun hatte ich die Idee für STD-Handler von telnet.exe selbst erstellte Pipes zu verwenden.
Siehe:
http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx
http://support.microsoft.com/?scid=kb%3Ben-us%3B190351&x=9&y=8
Soweit sieht auch alles ganz gut aus, nur wird der Befehl nicht ausgeführt und ich weiss nicht genau was überhaupt in telnet.exe abgeht.
Das Lesen von der Input-Pipe (hInputRead) blockiert leider immer. Selbst ein einzelnes byte kann ich nicht auslesen.PROCESS_INFORMATION cProcessInfo = {0}; STARTUPINFO cStartupInfo = {0}; DWORD dwIpAddr = 0; HANDLE hOutputReadTmp,hOutputRead,hOutputWrite; HANDLE hInputWriteTmp,hInputRead,hInputWrite; HANDLE hErrorWrite; HANDLE hStdIn = NULL; // Handle to parents std input. char lpTelnetCmd[255] = {0}; DWORD dwLastError = 0; BOOL bSuccess = FALSE; CHAR szCommand[] = "deploy\r\n"; SECURITY_ATTRIBUTES sa; // get ip-address m_ipaddr.GetAddress(dwIpAddr); if(0 == dwIpAddr) return; // Set up the security attributes struct. sa.nLength= sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; // Create the child output pipe. if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0)) AfxMessageBox("CreatePipe"); // Create a duplicate of the output write handle for the std error // write handle. This is necessary in case the child application // closes one of its std output handles. if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite, GetCurrentProcess(),&hErrorWrite,0, TRUE,DUPLICATE_SAME_ACCESS)) AfxMessageBox("DuplicateHandle"); // Create the child input pipe. if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0)) AfxMessageBox("CreatePipe"); // Create new output read handle and the input write handles. Set // the Properties to FALSE. Otherwise, the child inherits the // properties and, as a result, non-closeable handles to the pipes // are created. if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp, GetCurrentProcess(), &hOutputRead, // Address of new handle. 0,FALSE, // Make it uninheritable. DUPLICATE_SAME_ACCESS)) AfxMessageBox("DupliateHandle"); if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp, GetCurrentProcess(), &hInputWrite, // Address of new handle. 0,FALSE, // Make it uninheritable. DUPLICATE_SAME_ACCESS)) AfxMessageBox("DupliateHandle"); // Close inheritable copies of the handles you do not want to be // inherited. if (!CloseHandle(hOutputReadTmp)) AfxMessageBox("CloseHandle"); if (!CloseHandle(hInputWriteTmp)) AfxMessageBox("CloseHandle"); // Get std input handle so you can close it and force the ReadFile to // fail when you want the input thread to exit. if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE ) AfxMessageBox("GetStdHandle"); // preare telnet command StringCbPrintf(lpTelnetCmd, 255, "telnet.exe %d.%d.%d.%d mode stream", (dwIpAddr&(0xFF<<24))>>24, (dwIpAddr&(0xFF<<16))>>16, (dwIpAddr&(0xFF<<8))>>8, dwIpAddr&(0xFF<<0)); // initliaze startup information ZeroMemory( &cStartupInfo, sizeof(cStartupInfo) ); cStartupInfo.cb = sizeof(STARTUPINFO); // DWORD cb cStartupInfo.dwFlags = STARTF_USESTDHANDLES; cStartupInfo.dwFlags = STARTF_USEPOSITION | STARTF_USESHOWWINDOW; cStartupInfo.hStdError = hErrorWrite; cStartupInfo.hStdOutput = hOutputWrite; cStartupInfo.hStdInput = hInputRead; // Start telnet connection if( !CreateProcess( NULL, lpTelnetCmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &cStartupInfo, &cProcessInfo ) ) { AfxMessageBox("Connection failed!"); } bSuccess = WriteFile(hInputWrite, szCommand, strlen(szCommand), &dwPipeBytes, NULL); if (!bSuccess) dwLastError = GetLastError(); CloseHandle(hOutputReadTmp); CloseHandle(hOutputRead); CloseHandle(hOutputWrite); CloseHandle(hInputWriteTmp); CloseHandle(hInputRead); CloseHandle(hInputWrite);Hat jemand noch ne idee an was das liegen könnte? Muss der Befehl mit irgend einem magischen Zeichen abgeschlossen/bestätigt werden?
Muss ich beim lesen aus der STD-Out pipe etwas beachten?Danke schonmal im voraus!
-
Niemand ne Idee?
Oder hab ich mein Anliegen zu kompliziert erklärt?
-
Ich würde es einfach mit Sockets machen. telnet.exe sendet im Normalfall einfach roh die Daten rüber.