winapi - ¿Qué hace CreateFile("CONIN $"..)?
input pipe (1)
Estaba pirateando el código fuente de plink para que sea compatible con Unison.
Si no lo sabe, el unísono es una herramienta de sincronización de archivos, ejecuta un comando "ssh" para conectarse a un servidor remoto, pero no hay ssh.exe para Windows; hay plink, que está muy cerca pero no lo suficientemente cerca (no se comporta como espera unísono), por lo que la gente suele hacer envoltorios alrededor, como este .
uno de los problemas es que el unísono espera que la solicitud de contraseña se imprima en stderr (pero la imprime en stdout, y hace que el unísono se confunda), así que pensé, bueno, debería ser lo suficientemente simple, piratear mi código de trama y hacerlo imprime el mensaje para stdout. así que me abrí paso y lo hice.
Siguiente problema: ¡No puedo responder al aviso! no importa lo que escriba, no tiene ningún efecto.
el código para obtener entrada es más o menos así:
hin = GetStdHandle(STD_INPUT_HANDLE);
....
r = ReadFile(hin, .....);
No estoy seguro de por qué se hace de esta manera, pero no soy un experto en el diseño de herramientas de línea de comandos para Windows, entonces, ¿qué sé yo? Pero creo que falta algo en la configuración del control de entrada.
Miré el código fuente de la herramienta contenedora anterior y veo esto: hconin=CreateFile("CONIN$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0)
y lo intento (solo por el gusto de hacerlo)
hin=CreateFile("CONIN$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
....
r = ReadFile( hin ...... )
¡y sorprendentemente funciona! ¡Ahora puedo responder al aviso!
¿Por qué es esto? ¿Qué es "CONIN $"? y por qué es diferente de STD_INPUT_HANDLE
?
Puedo "adivinar" que FILE_SHARE_READ
y OPEN_EXISTING
están desempeñando un papel en esto (ya que ssh se está ejecutando desde otro proceso), pero quiero entender lo que está sucediendo aquí, y me aseguro de que este código no tenga algunos efectos secundarios no deseados o agujeros de seguridad o algo de miedo como ese!
CONIN$
es el dispositivo de entrada de la consola. Normalmente, stdin es un archivo abierto maneja esto, pero si stdin es redireccionado por alguna razón, entonces usar CONIN$
le permitirá obtener acceso a la consola a pesar de la redirección. Referencia.