Create Process + Pipe
-
Hi,
kann mir bitte jemand sagen warum das erstellen eines prozesses und das senden an die command line nicht funktioniert?
ich starte openvpn und nach dem connected muss ich den private key eingeben, möchte das automatisieren und die eingabe über eine pipe an den command line senden...lg
int main() { HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Wr = NULL; SECURITY_ATTRIBUTES saAttr; STARTUPINFO siStartupInfo; PROCESS_INFORMATION piProcessInfo; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Create a pipe for the child process's STDOUT. if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) cout << "StdoutRd CreatePipe" << endl; // Create a pipe for the child process's STDIN. if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) cout << "Stdin CreatePipe" << endl; memset(&piProcessInfo, 0, sizeof(piProcessInfo)); siStartupInfo.cb = sizeof(siStartupInfo); //STARTUPINFO startInfo; memset(&siStartupInfo, 0, sizeof(STARTUPINFO)); siStartupInfo.cb = sizeof(STARTUPINFO); siStartupInfo.dwFlags = STARTF_USESHOWWINDOW; siStartupInfo.hStdInput = g_hChildStd_IN_Rd; siStartupInfo.hStdOutput = g_hChildStd_OUT_Wr; siStartupInfo.wShowWindow = SW_SHOW; // PROGRA~1 if(CreateProcess(L"C:\\Program Files\\OpenVPN\\bin\\openvpn.exe", // Application name L"--config C:\\openvpn\\xxxx.ovpn", // Application arguments 0, 0, FALSE, CREATE_DEFAULT_ERROR_MODE, 0, 0, // Working directory &siStartupInfo, &piProcessInfo) == FALSE) { unsigned int BUFSIZE = 100; char chBuf[100]; DWORD dwWritten = 0; DWORD dwRead = 0; BOOL bSuccess = FALSE; string data = "password"; strcpy(chBuf, data.c_str()); Sleep(2000); bSuccess = WriteFile(g_hChildStd_IN_Rd, chBuf, data.length(), &dwWritten, NULL); cout << dwWritten << endl; if ( ! CloseHandle(g_hChildStd_IN_Wr) ) cout << "StdInWr CloseHandle" << endl; return 0; }
-
GetLastError()?
ERROR_EVELATION_REQUIRED?
-
hi,
mit folgendem code bekomme ich bei WriteFile 1 zurück und er sagt mir auch das 8 zeichen geschrieben wurden! somit bekomme ich also keinen fehler...folgende ausgabe: http://www.upload-pictures.de/bild.php/656,pic1WECO5.png
wenn ich das programm manuell starte und dann das password eingebe, versucht er sich zu verbinden: http://www.upload-pictures.de/bild.php/657,pic2Y4PAZ.png
lg
HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Wr = NULL; SECURITY_ATTRIBUTES saAttr; STARTUPINFO siStartupInfo; PROCESS_INFORMATION piProcessInfo; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Create a pipe for the child process's STDOUT. if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) { cout << "Error: StdoutRd CreatePipe" << endl; } // Create a pipe for the child process's STDIN. if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) { cout << "Error: Stdin CreatePipe" << endl; } // Set up members of the PROCESS_INFORMATION structure. memset(&piProcessInfo, 0, sizeof(piProcessInfo)); // Set up members of the STARTUPINFO structure. // This structure specifies the STDIN and STDOUT handles for redirection. memset(&siStartupInfo, 0, sizeof(STARTUPINFO)); siStartupInfo.cb = sizeof(STARTUPINFO); siStartupInfo.dwFlags = STARTF_USESHOWWINDOW; siStartupInfo.hStdOutput = g_hChildStd_OUT_Wr; siStartupInfo.hStdInput = g_hChildStd_IN_Rd; siStartupInfo.wShowWindow = SW_SHOW; if(CreateProcess(L"C:\\Program Files\\OpenVPN\\bin\\openvpn.exe", // Application name L"--config C:\\openvpn\\xxxx.ovpn", // Application arguments 0, 0, FALSE, // handles are inherited CREATE_DEFAULT_ERROR_MODE, //CREATE_NO_WINDOW, // creation flags 0, 0, // Working directory &siStartupInfo, &piProcessInfo) == FALSE) { cout << getLastError() << endl; return -1; } const unsigned int BUFSIZE = 100; char chBuf[BUFSIZE]; DWORD dwWritten = 0; DWORD dwRead = 0; BOOL bSuccess = FALSE; string data = "password"; strcpy(chBuf, data.c_str()); Sleep(2000); bSuccess = WriteFile(g_hChildStd_OUT_Wr, chBuf, data.length(), &dwWritten, NULL); cout << dwWritten << endl; if (!CloseHandle(g_hChildStd_IN_Rd)) { cout << "StdInWr CloseHandle" << endl; } if (!CloseHandle(g_hChildStd_IN_Wr)) { cout << "StdInWr CloseHandle" << endl; }
-
Evtl. liest das Programm nicht von stdin!
Wenn das so wäre könntest Du auch durch Umleitung einer datei, das Kennwort eingeben! Geht das:
MeinProgramm.exe < DateiMitKennwort.txt
-
Hi
Wen man ein befehl oder ein Programm mit Parameter aufrufen will, und dazu eine unnamed-pipe verwendet. Sollte dies hier bestens funktionieren.
/* StartupInfo struktur definieren für Process */ ZeroMemory(&sInfo,sizeof(sInfo)); ZeroMemory(&pInfo,sizeof(pInfo)); sInfo.cb = sizeof(sInfo); sInfo.dwFlags = STARTF_USESTDHANDLES; sInfo.hStdInput = NULL; // Stdin = muss null sein sInfo.hStdOutput= wPipe; // Stdout = muss write-pipe sein sInfo.hStdError = wPipe; // Stderror = muss/darf write-pipe sein
danach ...
/* Create Process */ CreateProcess( 0 ,command ,0 ,0 ,TRUE ,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW ,0 ,0 ,&sInfo ,&pInfo ); /* Nach schreiben des Output in wPipe, Pipe schliessen */ CloseHandle(wPipe);
und jetz kannst du den output von der readpipe lesen wen du willst !
/* Read von der pipe */ res = ReadFile(rPipe,buf ,READBUFSIZE ,&reDword ,0);
Wichtig ist der erste schritt. Das du schaust das die (stdin) und (stdout) richtig gesetzt hast. Wen du den Prozess dan aufrufst mit CreateProcess, dan musst du die write-pipe schliessen das du auch daraus lesen kannst.
Am schluss solltest du noch alle Handles closen .
CloseHandle(rPipe); /* Close process-handles */ CloseHandle(pInfo.hProcess); CloseHandle(pInfo.hThread);
lowbyte
-
@lowbyte_
ich will aber schon den openvpn prozess starten? das geht doch wohl? warum hast du da mit CreateProcess( 0 ,command , ... ersetzt?
vor dem close handle von wpipe kann ich das password an die console senden via WriteFile?
bye
-
@Martin Richter: Dein Vorschlag mit "MeinProgramm.exe < DateiMitKennwort.txt" klappt;) gar nicht gewusst das sowas überhaupt geht ^^
lg
-
hi,
wenn ich von der pipe lese bekomme ich folgende ausgabe;/ obwohl der übergebene passwort richtig ist!Wed May 05 21:31:24 2010 OpenVPN 2.1_rc4 Win32-MinGW [SSL] [LZO2] built on Apr 2
5 2007
Enter Privat╠╠╠╠╠╠╠╠d
e Key Password:
Wed May 05 21:31:24 2010 ERROR: could not not read Private Key password from std
╠╠╠╠╠╠╠╠d
-
meicko schrieb:
@Martin Richter: Dein Vorschlag mit "MeinProgramm.exe < DateiMitKennwort.txt" klappt;) gar nicht gewusst das sowas überhaupt geht ^^
lg
Das ist doch normale redirection der CMD:XE oder der entsprechenden Shell..
-
Hi
Nichts mit Writefile ! Wen du die pipes erstellt hast musst du am besten das Programm xxx.exe mit CreateProcess aufrufen inklusive mit deinem password als parameter.
Dan sollte es etwa so aussehen in dem vector command:
char command[]={"xxx.exe password"};
Danach kannst du das programm + passowrd parameter mit createprocess starten !
CreateProcess( 0 ,command ,0 ,0 ,TRUE ,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW ,0 ,0 ,&sInfo ,&pInfo );
Du musst schauen das du die starupinfo struct richtig. bzw. mit den richtigen werten versehst. Die stdin und stdout und stderror müssen so wie ich hier schreibe sein.
ZeroMemory(&sInfo,sizeof(sInfo)); ZeroMemory(&pInfo,sizeof(pInfo)); sInfo.cb = sizeof(sInfo); sInfo.dwFlags = STARTF_USESTDHANDLES; sInfo.hStdInput = NULL; --->// Stdin = muss null sein sInfo.hStdOutput = wPipe; --->// Stdout = muss write-pipe sein sInfo.hStdError = wPipe; --->// Stderror = muss/darf write-pipe sein
bei dir ist es so:
siStartupInfo.hStdOutput = g_hChildStd_OUT_Wr; siStartupInfo.hStdInput = g_hChildStd_IN_Rd;
das ist falsch !
lowbyte
-
Hi
@martin richter
Wen man es so macht wie du geschrieben hast. Dan musst du die ganze zeit die UAC bestätigen !Und in einem C Program hat so ein aufruf mit zbsp. system("xxx.exe<pass.txt"); nichts verloren, meiner meinung nach !
So wie ichs beschrieben habe funktioniert es ohne das dir die UAC dazwischenfunkt!
lowbyte
-
1. Was hat UAC hier zu tun. Warum solltehier ein UAC Prompt kommen, wenn das Programm keinen verlangt?
2. Habe ich dieses Sample nur gegeben, damit der OP testen kann ob stdin verwendet wird für die Password Abfrage.
3. Ist dieser Weg nichts anderss als bei CreateProcess die file Handles zu verbiegen.
-
Hi
Auf manchen OS Versionen musst du mit entsprechender berechtigung sogar für cmd.exe die UAC bestätigen.
lowbyte
-
Hi
Aber hast schon recht, das war nicht die Frage.
Soll er's machen wie er will.
-
lowbyte_ schrieb:
Auf manchen OS Versionen musst du mit entsprechender berechtigung sogar für cmd.exe die UAC bestätigen.
Das kannst du falten. CMD.EXE hat in keiner der aktuellen ausgelieferten Windows Version ein Manifest mit requireAdministrator!
-
Hi
Sorry habe mich da vertan. Meinte eigentlich was anderes, ein Problem das ich mal hatte mit Vista und "pipen ala. system("cmd.exe >> r.txt");.
Das mit der cmd.exe ist klar. War wohl nicht bei der Sache. Mein Ringpuffer den ich gestern unter anderem geschriben habe,hat mich wohl durch den Wind gezogen. Hatte richtige Probleme, Zeiger krieg. Und siehe da, nach 5min Pause und einer kippe ,habe ich's plötzlich wieder gesehen
Unter dem Strich: Pause ist immer gut !lowbyte
-
@lowbyte_
das klappt so nicht, wie du das vorgeschlagen hast:
C:\Documents and Settings\meiko>openvpn --config C:\\openvpn\\xxxx.ovpn passwort Wed May 12 01:30:19 2010 OpenVPN 2.1_rc4 Win32-MinGW [SSL] [LZO2] built on Apr 2 5 2007 Enter Private Key Password:
-
@lowbyte_: mit meiner alten openvpn version kann man das passwort nicht direkt übergeben;/
warum funktioniert das mit der pipe und writefile nicht???
lg