title: Low Level Console Input and Redirection
body: <p>I'm trying to send commands to to the input of a <code>cmd.exe</code> application using the low level read/write console functions. I have no trouble reading the text (scraping) using the <code>ReadConsole...()</code> and <code>WriteConsole()</code> functions after having attached to the process console, but I've not figured out how to write for example <code>"dir"</code> and have the console interpret it as a sent command.</p>
  
  <p>Here's a bit of my code:</p>
  
  <pre><code>CreateProcess(NULL, "cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &amp;si, &amp;pi);
  AttachConsole(pi.dwProcessId);
  
  strcpy(buffer, "dir");
  WriteConsole(GetStdHandle(STD_INPUT_HANDLE), buffer, strlen(buffer), &amp;charRead, NULL);
  </code></pre>
  
  <p><code>STARTUPINFO</code> attributes of the process are all set to zero, except, of course, the <code>.cb</code> attribute.</p>
  
  <p>Nothing changes on the screen, however I'm getting an <code>Error 6: Invalid Handle</code> returned from <code>WriteConsole</code> to <code>STD_INPUT_HANDLE</code>. If I write to <code>(STD_OUTPUT_HANDLE)</code> I do get my <code>dir</code> written on the screen, but nothing of course happens. I'm guessing <code>SetConsoleMode()</code> might be of help, but I've tried many mode combinations, nothing helped. I've also created a quick console application that waits for input (<code>scanf()</code>) and echoes back whatever goes in, didn't work.</p>
  
  <p>I've also tried typing into the <code>scanf()</code> promp and then peek into the input buffer using <code>PeekConsoleInput()</code>, returns 0, but the <code>INPUT_RECORD</code> array is empty.</p>
  
  <p>I'm aware that there is another way around this using <code>WriteConsoleInput()</code> to directly inject INPUT_RECORD structured events into the console, but this would be way too long, I'll have to send each keypress into it.</p>
  
  <p>I hope the question is clear. Please let me know if you need any further information. Thanks for your help.</p>
  
  <p><strong>Update 1:</strong></p>
  
  <p>I am able to send keypresses to a <code>cmd</code> process using <code>WriteConsoleInput()</code> with <code>INPUT_RECORD</code> structs, however, the <code>AttachConsole</code> sometimes throws <code>ERROR_GEN_FAILURE #31: A device attached to the system is not functioning.</code>, and thus the <code>INPUT_RECORD</code> are not sent (<code>Error 6: Invalid Handle</code>). <code>Sleep(1000)</code> after <code>CreateProcess()</code> before <code>AttachConsole()</code> solves this. The characters <code>dir</code> are typed in automatically, but I can't figure out how to send the <code>RETURN</code> key:</p>
  
  <pre><code>ir[0].EventType = KEY_EVENT;
  ir[0].Event.KeyEvent.bKeyDown = TRUE;
  ir[0].Event.KeyEvent.dwControlKeyState = 0;
  ir[0].Event.KeyEvent.uChar.UnicodeChar = '\n';
  ir[0].Event.KeyEvent.wRepeatCount = 1;
  ir[0].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
  ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
  ir[1].EventType = KEY_EVENT;
  ir[1].Event.KeyEvent.bKeyDown = FALSE;
  ir[1].Event.KeyEvent.dwControlKeyState = 0;
  ir[1].Event.KeyEvent.uChar.UnicodeChar = '\n';
  ir[1].Event.KeyEvent.wRepeatCount = 1;
  ir[1].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
  ir[1].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
  
  WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir, 2, &amp;charRead);
  </code></pre>
  
  <p><code>WriteConsoleInput</code> returns <code>0</code>, but nothing happens in the console, I've tried setting <code>SetConsoleMode()</code> to <code>ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT</code> and a combination thereof, with no results, though. If I press enter from the keyboard, however, the automatically-typed <code>dir</code> command executes (unlike the times when I just <code>WriteConsole()</code>), so I guess I'm on the right track.</p>
  
  <p>Doesn't SSH send over the actual keypresses and gets the actual screen buffer (like TAB, and CTRL+C CTRL+D work)? I'm after something of the like.</p>
  
  <p><strong>Update 2:</strong></p>
  
  <p>I found the problem with injecting the return command. Should have been <code>ir[1].Event.KeyEvent.uChar.AsciiChar = '\r';</code> i.e. an <code>\r</code> instead of a <code>\n</code>, super simple.</p>
  
  <p>It seems that there is no way of using <code>WriteConsole()</code> to input commands, one should get by by sending <code>WriteConsoleInput()</code> INPUT_RECORDs or by creating pipes (which are not always perfect, but great for most straight forward applications). One great advantage of using <code>WriteConsoleInput()</code> is that you one can send <code>VK_UP</code> and <code>VK_DOWN</code>, to access console history, (if we're in CMD) and <code>VK_TAB</code> for auto-completion, all CTRL+_ sequences, ESC and FUNCTION keys and even MOUSE CLICKS.</p>
  
  <p>More information here: <a href="http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx</a>
  plus tonnes of examples here: <a href="http://controllingtheinter.net/forums/viewtopic.php?f=116&amp;t=366" rel="nofollow">http://controllingtheinter.net/forums/viewtopic.php?f=116&amp;t=366</a></p>
  
  <p>If anyone has other great ideas feel free to chip in. Thank you to all those who took interest in this. Hope this helps someone in the future.</p>