diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 15761d38f..ff8ff2646 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -194,6 +194,7 @@ static void serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) { + int status; UINT32 Length; UINT64 Offset; SERIAL_TTY* tty = serial->tty; @@ -208,22 +209,30 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) Length = 0; DEBUG_WARN("tty not valid."); + + Stream_Write_UINT32(irp->output, Length); /* Length (4 bytes) */ + Stream_Write_UINT8(irp->output, 0); /* Padding (1 byte) */ + irp->Complete(irp); + return; } - else if (!serial_tty_write(tty, Stream_Pointer(irp->input), Length)) + + status = serial_tty_write(tty, Stream_Pointer(irp->input), Length); + + if (status < 0) { irp->IoStatus = STATUS_UNSUCCESSFUL; Length = 0; - DEBUG_WARN("write %s(%d) failed.", serial->path, tty->id); - } - else - { - DEBUG_SVC("write %llu-%llu to %s(%d).", Offset, Offset + Length, serial->path, tty->id); + printf("serial_tty_write failure: status: %d, errno: %d\n", status, errno); + + Stream_Write_UINT32(irp->output, Length); /* Length (4 bytes) */ + Stream_Write_UINT8(irp->output, 0); /* Padding (1 byte) */ + irp->Complete(irp); + return; } Stream_Write_UINT32(irp->output, Length); /* Length (4 bytes) */ Stream_Write_UINT8(irp->output, 0); /* Padding (1 byte) */ - irp->Complete(irp); } diff --git a/channels/serial/client/serial_tty.c b/channels/serial/client/serial_tty.c index a9d0a9092..a17db526a 100644 --- a/channels/serial/client/serial_tty.c +++ b/channels/serial/client/serial_tty.c @@ -91,8 +91,29 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, UINT32 begPos, endPos; UINT32 OutputBufferLength; UINT32 status = STATUS_SUCCESS; + UINT32 IoCtlDeviceType; + UINT32 IoCtlFunction; + UINT32 IoCtlMethod; + UINT32 IoCtlAccess; - DEBUG_SVC("in"); + IoCtlMethod = (IoControlCode & 0x3); + IoCtlFunction = ((IoControlCode >> 2) & 0xFFF); + IoCtlAccess = ((IoControlCode >> 14) & 0x3); + IoCtlDeviceType = ((IoControlCode >> 16) & 0xFFFF); + + /** + * FILE_DEVICE_SERIAL_PORT 0x0000001B + * FILE_DEVICE_UNKNOWN 0x00000022 + */ + + printf("IoControlCode: DeviceType: 0x%04X Access: 0x%02X Function: 0x%04X Method: 0x%02X\n", + IoCtlDeviceType, IoCtlAccess, IoCtlFunction, IoCtlMethod); + + if (IoCtlDeviceType == 0x00000022) + { + IoControlCode &= 0xFFFF; + IoControlCode |= (0x0000001B << 16); + } Stream_Seek_UINT32(output); /* OutputBufferLength (4 bytes) */ begPos = (UINT32) Stream_GetPosition(output); @@ -389,8 +410,6 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length) ssize_t status; long timeout = 90; - DEBUG_SVC("in"); - /* Set timeouts kind of like the windows serial timeout parameters. Multiply timeout with requested read size */ if (tty->read_total_timeout_multiplier | tty->read_total_timeout_constant) @@ -451,20 +470,21 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length) return TRUE; } -BOOL serial_tty_write(SERIAL_TTY* tty, BYTE* buffer, UINT32 Length) +int serial_tty_write(SERIAL_TTY* tty, BYTE* buffer, UINT32 Length) { - ssize_t status; + ssize_t status = 0; UINT32 event_txempty = Length; - DEBUG_SVC("in"); - while (Length > 0) { status = write(tty->fd, buffer, Length); if (status < 0) { - return FALSE; + if (errno == EAGAIN) + status = 0; + else + return status; } Length -= status; @@ -473,7 +493,7 @@ BOOL serial_tty_write(SERIAL_TTY* tty, BYTE* buffer, UINT32 Length) tty->event_txempty = event_txempty; - return TRUE; + return status; } /** @@ -485,8 +505,6 @@ BOOL serial_tty_write(SERIAL_TTY* tty, BYTE* buffer, UINT32 Length) */ void serial_tty_free(SERIAL_TTY* tty) { - DEBUG_SVC("in"); - if (!tty) return; @@ -588,8 +606,6 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result) int bytes; BOOL status = FALSE; - DEBUG_SVC("in"); - *result = 0; #ifdef TIOCINQ @@ -840,8 +856,8 @@ static void tty_set_termios(SERIAL_TTY* tty) speed_t speed; struct termios* ptermios; - DEBUG_SVC("in"); ptermios = tty->ptermios; + switch (tty->baud_rate) { #ifdef B75 @@ -1033,8 +1049,6 @@ static UINT32 tty_write_data(SERIAL_TTY* tty, BYTE* data, int len) { ssize_t status; - DEBUG_SVC("in"); - status = write(tty->fd, data, len); if (status < 0) @@ -1047,8 +1061,6 @@ static UINT32 tty_write_data(SERIAL_TTY* tty, BYTE* data, int len) static int tty_get_error_status() { - DEBUG_SVC("in errno %d", errno); - switch (errno) { case EACCES: diff --git a/channels/serial/client/serial_tty.h b/channels/serial/client/serial_tty.h index 20a7bec54..840c448ec 100644 --- a/channels/serial/client/serial_tty.h +++ b/channels/serial/client/serial_tty.h @@ -72,7 +72,7 @@ SERIAL_TTY* serial_tty_new(const char* path, UINT32 id); void serial_tty_free(SERIAL_TTY* tty); BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length); -BOOL serial_tty_write(SERIAL_TTY* tty, BYTE* buffer, UINT32 Length); +int serial_tty_write(SERIAL_TTY* tty, BYTE* buffer, UINT32 Length); UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, wStream* output, UINT32* abort_io); BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result);