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

Discussion in 'WASM.BEGINNERS' started by ltshck, Nov 19, 2010.

  1. ltshck

    ltshck New Member

    Blog Posts:
    0
    Joined:
    Nov 5, 2007
    Messages:
    195
    Стоит следующая задача.
    Надо скормить блокноту файл из пайпа.

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

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

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

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


    Текст исходной программы для экспериментов:
    Code (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

    Blog Posts:
    0
    Joined:
    Apr 29, 2010
    Messages:
    327
    ltshck,

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

    ltshck New Member

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

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

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

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

    ltshck New Member

    Blog Posts:
    0
    Joined:
    Nov 5, 2007
    Messages:
    195
    ап. нид хелп.
     
  5. _Nickel

    _Nickel New Member

    Blog Posts:
    0
    Joined:
    Jun 15, 2009
    Messages:
    37
    То, что notepad не кушает пайпы, это известная фича. Дело в том, что он использует CreateFileMapping, а не ReadFile.
     
  6. ltshck

    ltshck New Member

    Blog Posts:
    0
    Joined:
    Nov 5, 2007
    Messages:
    195
    Истина была где-то рядом!.. :)

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

    Babyshamble New Member

    Blog Posts:
    0
    Joined:
    May 2, 2010
    Messages:
    67
    Так где она была то ?
     
  8. wasm_test

    wasm_test wasm test user

    Blog Posts:
    0
    Joined:
    Nov 24, 2006
    Messages:
    5,582
    Babyshamble
    дык CreateFileMapping же
     
  9. Babyshamble

    Babyshamble New Member

    Blog Posts:
    0
    Joined:
    May 2, 2010
    Messages:
    67
    Я думал истиной было какое-то решение проблеммы :)
     
  10. murder

    murder Member

    Blog Posts:
    0
    Joined:
    Jun 3, 2007
    Messages:
    628
    Попытка номер 2. Извиняюсь за паскаль
    Code (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

    Blog Posts:
    0
    Joined:
    Jun 22, 2009
    Messages:
    2,020
    Блокнот после открытия файла в обязательном порядке кастует на него CreateFileMappingW и MapViewOfFile, что-то мне подсказывает, что это не очень сочетается с пайпами. (windows 8.1 x64)

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

    murder Member

    Blog Posts:
    0
    Joined:
    Jun 3, 2007
    Messages:
    628
    Технически не вижу препятствий. При создании пайпа мы ведь указываем размер входного и выходного буферов. Теоретически система может смапить буфер. Или не?
     
  13. f13nd

    f13nd Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 22, 2009
    Messages:
    2,020
    Дай собранный бинарник, который файл в пайп вываливает, скажу точней что нотпеду не нравится.
     
  14. murder

    murder Member

    Blog Posts:
    0
    Joined:
    Jun 3, 2007
    Messages:
    628
    Всё по минимуму - проверок на ошибки нет.
     

    Attached Files:

    • pipe.7z
      File size:
      984 bytes
      Views:
      330
  15. f13nd

    f13nd Well-Known Member

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

    ЗЫ: точку в имени файла я не забыл, он сам ее убрал.
    --- Сообщение объединено, Mar 5, 2019 ---
    Вобщем я идиот и ничего не понял.
    Code (Text):
    1. notepad \\.\pipe\buf.txt
    Code (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, возможно есть способ лучше, пофиг), но как я и предупреждал:
    Code (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.
     

    Attached Files:

    • 234.png
      234.png
      File size:
      8.1 KB
      Views:
      603
    Last edited: Mar 5, 2019
  16. murder

    murder Member

    Blog Posts:
    0
    Joined:
    Jun 3, 2007
    Messages:
    628
    Надо попробовать так: "\\?\\\.\pipe\buf.txt". Всё, что после префикса "\\?\" должно остаться без изменений.
     
  17. f13nd

    f13nd Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 22, 2009
    Messages:
    2,020
    "Недопустимое имя файла". Ну через открытие файла скорей всего точно не выйдет, через аргумент вон получилось хотя бы CreateFileW чтоб прошло (с твоим примером INVALID_HANDLE_VALUE на выходе).