Что делает CreateFile(“CONIN$” ..)?
Вопрос
Я взламывал исходный код для плинк чтобы сделать его совместимым с unison.
Если вы не знаете, unison - это инструмент синхронизации файлов, он запускает команду "ssh" для подключения к удаленному серверу, но ее нет ssh.exe для Windows;есть plink, который находится очень близко, но недостаточно близко (он ведет себя не так, как ожидает unison), поэтому люди обычно делают обертки вокруг него, как этот.
одна из проблем заключается в том, что unison ожидает, что запрос пароля будет напечатан в stderr (но plink печатает его в stdout и приводит к путанице в unison), поэтому я подумал, что это должно быть достаточно просто, взломать мой код через plink и заставить его печатать запрос в stdout.так что я прорубил себе путь и сделал это.
Следующая проблема:Я не могу ответить на запрос!!независимо от того, что я печатаю, это не имеет никакого эффекта.
код для получения входных данных примерно такой:
hin = GetStdHandle(STD_INPUT_HANDLE);
....
r = ReadFile(hin, .....);
Я не уверен, почему это сделано таким образом, но я не эксперт в разработке инструментов командной строки для Windows, так что что я знаю!Но я полагаю, что чего-то не хватает в настройке дескриптора ввода.
Я просмотрел исходный код для приведенный выше инструмент для обертывания и я вижу это:hconin=CreateFile("CONIN$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0)
и я пробую это (просто так, ради интереса).
hin=CreateFile("CONIN$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
....
r = ReadFile( hin ...... )
и на удивление это работает!Теперь я могу ответить на запрос!
Почему это происходит?что такое "CONIN$"?и почему это отличается от STD_INPUT_HANDLE
?
Я могу как бы "догадаться", что FILE_SHARE_READ
и OPEN_EXISTING
играют определенную роль в этом (поскольку ssh запускается из другого процесса), но я хочу понять, что здесь происходит, и убедиться, что этот код не имеет каких-либо нежелательных побочных эффектов, дыр в безопасности или чего-то страшного в этом роде!
Решение
CONIN$
является консольным устройством ввода.Обычно stdin является дескриптором открытого файла для этого, но если stdin по какой-то причине перенаправляется, то с помощью CONIN$
позволит вам получить доступ к консоли, несмотря на перенаправление. Ссылка.