Кормим notepad пайпами

Тема в разделе "WASM.BEGINNERS", создана пользователем ltshck, 19 ноя 2010.

  1. ltshck

    ltshck New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2007
    Сообщения:
    195
    Стоит следующая задача.
    Надо скормить блокноту файл из пайпа.

    Т.е. чтобы блокнот, имеющий последовательность вызовов CreateFile + ReadFile прочитал данные из подсунутого пайпа вместо обычного файла.
    Запуск блокнота осуществляется так: notepad.exe //./pipe/mynamepipe2
    Ниже приведен код, который функционирует следующим образом.
    При запуске создается пайм и в Месте Б программа ждет подключения к пайпу.
    Запускаем нотепад с указанием имени файла - наш пайп.
    Нотепад открыл пайп, увидел его, все оки.
    Программа пошла дальнейшее выполнение и в месте В я делаю WriteFile в пайп строку "77777777" и жду ее в нотепаде.
    Ее там естественно нет, так как нотепад уже сделал ReadFile до вызова мною WriteFile.

    Отсюда вывод что запись в пайп должна быть до соединения его клиентом. То есть в месте А.
    Причем при создании пайпа было указано что буфер на чтение 512 байт и на запись тоже 512 байт.

    Но как только я не ипался с WriteFile в месте А - вылетали всяческие ошибки вида ERROR_PIPE_CONNECTED
    и так далее, не позволяя мне писать в неоткрытый клиентом пайп.

    Все. Требуется помощь гуру по решению указанной задачи.


    Текст исходной программы для экспериментов:
    Код (C):
    1. #include <windows.h>
    2. #include <cstdio>
    3.  
    4. int main() {
    5. char buf100 = "notepad.exe ";
    6.  
    7. LPTSTR pipe = TEXT("\\\\.\\pipe\\mynamedpipe2");
    8.  
    9. HANDLE hPipe = CreateNamedPipe(pipe, PIPE_ACCESS_DUPLEX,
    10.     PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
    11.     1 /*PIPE_UNLIMITED_INSTANCES*/,
    12.     512, 512, 0, NULL);
    13.  
    14. if (hPipe == INVALID_HANDLE_VALUE)
    15. {
    16.           printf(TEXT("CreateNamedPipe failed, GLE=%d.\n"), GetLastError());
    17.           return -1;
    18.     }
    19.  
    20. //Место А
    21.  
    22.  
    23. //Место Б
    24. // Ожидаем соединения со стороны клиента
    25.     bool fConnected = ConnectNamedPipe(hPipe, NULL);
    26.  
    27. // При возникновении ошибки выводим ее код
    28.   if(!fConnected)
    29. {
    30.     switch(GetLastError())
    31.   {
    32.       case ERROR_NO_DATA:
    33.         fprintf(stdout,"ConnectNamedPipe: ERROR_NO_DATA");
    34.         CloseHandle(hPipe);
    35.         return 0;
    36.       break;
    37.  
    38. case ERROR_PIPE_CONNECTED:
    39.         printf("ConnectNamedPipe: ERROR_PIPE_CONNECTED");
    40.         CloseHandle(hPipe);
    41.         return 0;
    42.       break;
    43.  
    44. case ERROR_PIPE_LISTENING:
    45.         printf("ConnectNamedPipe: ERROR_PIPE_LISTENING");
    46.         CloseHandle(hPipe);
    47.         return 0;
    48.       break;
    49.  
    50. case ERROR_CALL_NOT_IMPLEMENTED:
    51.         printf("ConnectNamedPipe: ERROR_CALL_NOT_IMPLEMENTED");
    52.         CloseHandle(hPipe);
    53.         return 0;
    54.       break;
    55.  
    56. default:
    57.         printf("ConnectNamedPipe: Error %ld\n",GetLastError());
    58.         CloseHandle(hPipe);
    59.         return 0;
    60.       break;
    61.  
    62. }
    63.  
    64. CloseHandle(hPipe);
    65.     return 0;
    66.   }
    67.  
    68. char bufw[20] = "777777777777";
    69.     DWORD dw;
    70.  
    71. //Место В
    72. if (!WriteFile(
    73.         hPipe,
    74.         bufw,
    75.         10,
    76.         &dw,
    77.         0)) {
    78.         printf( "WriteFile failed (%d).\n", GetLastError() );
    79.         return -3;
    80.     }
    81.  
    82. /*if (!CreateProcess( NULL,   // No module name (use command line)
    83.         buf,        // Command line
    84.         NULL,           // Process handle not inheritable
    85.         NULL,           // Thread handle not inheritable
    86.         FALSE,          // Set handle inheritance to FALSE
    87.         0,              // No creation flags
    88.         NULL,           // Use parent's environment block
    89.         NULL,           // Use parent's starting directory
    90.         0,            // Pointer to STARTUPINFO structure
    91.         0 ))           // Pointer to PROCESS_INFORMATION structure
    92. {
    93.         printf( "CreateProcess failed (%d).\n", GetLastError() );
    94.         return -2;
    95.     }*/
    96.  
    97. CloseHandle(hPipe);
    98.  
    99. return 0;
    100. }
     
  2. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    ltshck,

    То, что notepad.exe не дочитывает исходный файл регулярно, не смущает? Он при старте вычитает пайп, засандалит его в EDIT и будет думать что больше там ничего нет. Остальное — WM_CHAR и проч.
     
  3. ltshck

    ltshck New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2007
    Сообщения:
    195
    baldr,
    не смущает. потому как задача другая.
    не требуется чтобы в нотепаде появлялись буквы по мере их появления в пайпе.
    естественно в нотепаде нет цикла чтения данных с пайпа.
    там один раз читается само собой.

    требуется чтобы при первом открытии пайпа нотепадом появилась строка "77777777", которая была в пайпе до открытия еще, в буфере, который 512 байт...

    т.е:
    1. создаем пайп
    2. пишем ему в буфер строку "777777"
    3. октрываем пайп нотепадом
    4. хочется увидеть в нотепаде строку "77777" которую он прочитал один раз после открытия пайпа, а ее нет.

    как такое сделать? сабж открыт.
    baldr просьба не беспокоиться, нужна дельная помощь.
     
  4. ltshck

    ltshck New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2007
    Сообщения:
    195
    ап. нид хелп.
     
  5. _Nickel

    _Nickel New Member

    Публикаций:
    0
    Регистрация:
    15 июн 2009
    Сообщения:
    37
    То, что notepad не кушает пайпы, это известная фича. Дело в том, что он использует CreateFileMapping, а не ReadFile.
     
  6. ltshck

    ltshck New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2007
    Сообщения:
    195
    Истина была где-то рядом!.. :)

    Спасибо! TRUE
     
  7. Babyshamble

    Babyshamble New Member

    Публикаций:
    0
    Регистрация:
    2 май 2010
    Сообщения:
    67
    Так где она была то ?
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Babyshamble
    дык CreateFileMapping же
     
  9. Babyshamble

    Babyshamble New Member

    Публикаций:
    0
    Регистрация:
    2 май 2010
    Сообщения:
    67
    Я думал истиной было какое-то решение проблеммы :)
     
  10. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Попытка номер 2. Извиняюсь за паскаль
    Код (Text):
    1. uses
    2.   Windows;
    3.  
    4. type
    5.   TBuf=array[0..1023] of AnsiChar;
    6.  
    7. var
    8.   map,pipe,pipefile:  THandle;
    9.   PBuf:               ^tbuf;
    10.   i:                  Cardinal;
    11.   overlapped:         _OVERLAPPED;
    12.   startupinfo:        _STARTUPINFOA=(cb: sizeof(_STARTUPINFOA));
    13.   ProcInfo:           _PROCESS_INFORMATION;
    14.  
    15.  
    16. begin
    17.   map :=CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READWRITE,0,sizeof(TBuf),'Global\buf.txt');
    18.   PBuf:=MapViewOfFile(map,FILE_MAP_ALL_ACCESS,0,0,sizeof(TBuf));
    19.   PBuf^:='qwerty';
    20.   CreateProcessA(0,'notepad \\.\Global\buf.txt',0,0,false,0,0,0,startupinfo,ProcInfo);
    21.  
    22.   pipe:=CreateNamedPipeW('\\.\pipe\buf.txt',PIPE_ACCESS_DUPLEX+FILE_FLAG_OVERLAPPED,PIPE_TYPE_BYTE+PIPE_NOWAIT,PIPE_UNLIMITED_INSTANCES,sizeof(TBuf),sizeof(TBuf),0,0);
    23.   pipefile:=CreateFileW('\\.\pipe\buf.txt',GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
    24.   WriteFile(pipefile,PBuf^,sizeof(TBuf),i,@overlapped);
    25.   CreateProcessA(0,'notepad \\.\pipe\buf.txt',0,0,false,0,0,0,startupinfo,ProcInfo);
    26.  
    27.   MessageBoxW(0,0,0,0);
    28. end.
    Вначале подсовываю именованную область памяти и получаю это (если нажать да ничего не происходит)
    1.png

    Далее подсовываю асинхронный именованный канал и вот
    2.png
    То есть нотепад всё-таки понимает, что это пайп. Кто что думает?
     
  11. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.966
    Блокнот после открытия файла в обязательном порядке кастует на него CreateFileMappingW и MapViewOfFile, что-то мне подсказывает, что это не очень сочетается с пайпами. (windows 8.1 x64)

    ЗЫ: гораздо проще ворд или IE накормить через ole-автоматизацию.
     
    Последнее редактирование: 4 мар 2019
  12. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Технически не вижу препятствий. При создании пайпа мы ведь указываем размер входного и выходного буферов. Теоретически система может смапить буфер. Или не?
     
  13. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.966
    Дай собранный бинарник, который файл в пайп вываливает, скажу точней что нотпеду не нравится.
     
  14. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Всё по минимуму - проверок на ошибки нет.
     

    Вложения:

    • pipe.7z
      Размер файла:
      984 байт
      Просмотров:
      262
  15. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.966
    Для открытия файла (8.1 x64) блокнот создает COM-объект DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7 (IFileOpenDialog) и где-то в методе Show (+0x18) этот объект обламывает все пытаясь найти через RPC сетевой путь "\\.\pipe\buf.txt", до CreateFileW даже не доходит. Больше с этим делать нечего, тупик, по крайней мере для более-менее актуальных версий Windows (если конечно кое-кто не хочет реализовать альтернативный IFileOpenDialog подменив им оригинал).

    ЗЫ: точку в имени файла я не забыл, он сам ее убрал.
    --- Сообщение объединено, 5 мар 2019 ---
    Вобщем я идиот и ничего не понял.
    Код (Text):
    1. notepad \\.\pipe\buf.txt
    Код (ASM):
    1. format pe console 4.0
    2. include 'win32ax.inc'
    3. entry main
    4.  
    5. section '.code' code data readable executable
    6.  
    7. proc main
    8.             locals
    9.                 hPipe    dd ?
    10.                 nCount    dd ?
    11.             endl
    12.             .next:
    13.             invoke CreateNamedPipe,pipename,PIPE_ACCESS_OUTBOUND,PIPE_TYPE_BYTE + PIPE_READMODE_BYTE ,PIPE_UNLIMITED_INSTANCES,1024,1024,0,0
    14.             .if eax <> INVALID_HANDLE_VALUE
    15.                 mov [hPipe],eax
    16.                 @@:
    17.                 invoke WriteFile,[hPipe],pipename,sizeof.pipename,addr nCount,0
    18.                 test eax,eax
    19.                 .if ZERO?
    20.                     jmp @B
    21.                 .endif
    22.                 invoke CloseHandle,[hPipe]
    23.                 jmp .next
    24.             .endif
    25.             ret
    26. endp
    27.  
    28. pipename     db '\\.\pipe\buf.txt',0
    29. sizeof.pipename = $ - pipename
    30.  
    31. section '.data' data readable writable
    32. data import
    33.     library kernel32,'kernel32.dll',user32,'user32.dll'
    34.     include 'api\kernel32.inc'
    35.     include 'api\user32.inc'
    36. end data
    Удается создать пайп, дождаться когда блокнот его откроет (иначе WriteFile вернет ERROR_PIPE_LISTENING, возможно есть способ лучше, пофиг), но как я и предупреждал:
    Код (Text):
    1. 00007FF62E1A1E4F   | 45 33 C9                            | xor r9d,r9d                                                            |
    2. 00007FF62E1A1E52   | 33 D2                               | xor edx,edx                                                            |
    3. 00007FF62E1A1E54   | 45 8D 41 02                         | lea r8d,[r9+0x2]                                                       |
    4. 00007FF62E1A1E58   | 48 8B 0D 69 82 01 00                | mov rcx,[0x7FF62E1BA0C8]                                               |
    5. 00007FF62E1A1E5F   | FF 15 3B C2 01 00                   | call [<&CreateFileMappingW>]                                           |
    6. 00007FF62E1A1E65   | 48 8B C8                            | mov rcx,rax                                                            |
    7. 00007FF62E1A1E68   | 48 89 44 24 58                      | mov [rsp+0x58],rax                                                     |
    8. 00007FF62E1A1E6D   | 48 85 C0                            | test rax,rax                                                           |
    9. 00007FF62E1A1E70   | 74 2B                               | je notepad.7FF62E1A1E9D                                                |
    10. 00007FF62E1A1E72   | 4C 89 64 24 20                      | mov [rsp+0x20],r12                                                     |
    11. 00007FF62E1A1E77   | 45 33 C9                            | xor r9d,r9d                                                            |
    12. 00007FF62E1A1E7A   | 45 33 C0                            | xor r8d,r8d                                                            |
    13. 00007FF62E1A1E7D   | 41 8D 51 04                         | lea edx,[r9+0x4]                                                       |
    14. 00007FF62E1A1E81   | FF 15 11 C2 01 00                   | call [<&MapViewOfFile>]                                                |
    15. 00007FF62E1A1E87   | 48 8B F0                            | mov rsi,rax                                                            |
    16. 00007FF62E1A1E8A   | 48 89 44 24 78                      | mov [rsp+0x78],rax                                                     |
    17. 00007FF62E1A1E8F   | 48 8B 4C 24 58                      | mov rcx,[rsp+0x58]                                                     |
    18. 00007FF62E1A1E94   | FF 15 26 C3 01 00                   | call [<&CloseHandle>]                                                  |
    19. 00007FF62E1A1E9A   | EB 01                               | jmp notepad.7FF62E1A1E9D                                               |
    CreateFileMappingW возвращает 0.
     

    Вложения:

    • 234.png
      234.png
      Размер файла:
      8,1 КБ
      Просмотров:
      557
    Последнее редактирование: 5 мар 2019
  16. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Надо попробовать так: "\\?\\\.\pipe\buf.txt". Всё, что после префикса "\\?\" должно остаться без изменений.
     
  17. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.966
    "Недопустимое имя файла". Ну через открытие файла скорей всего точно не выйдет, через аргумент вон получилось хотя бы CreateFileW чтоб прошло (с твоим примером INVALID_HANDLE_VALUE на выходе).