NTSTATUS NTAPI VTUTF8ChannelIRead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, IN PULONG ReturnBufferSize) { ULONG CopyChars, ReadLength; CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(Buffer); CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); /* Assume failure */ *ReturnBufferSize = 0; /* Check how many bytes are in the buffer */ if (Channel->ChannelInputBufferLength(Channel) == 0) { /* Apparently nothing. Make sure the flag indicates so too */ ASSERT(ChannelHasNewIBufferData(Channel) == FALSE); } else { /* Use the smallest number of bytes either in the buffer or requested */ ReadLength = min(Channel->ChannelInputBufferLength(Channel) * sizeof(WCHAR), BufferSize); /* Do some cheezy buffer alignment */ CopyChars = ReadLength / sizeof(WCHAR); ReadLength = CopyChars * sizeof(WCHAR); ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel)); /* Copy them into the caller's buffer */ RtlCopyMemory(Buffer, Channel->IBuffer, ReadLength); /* Update the channel's index past the copied (read) bytes */ VTUTF8ChannelSetIBufferIndex(Channel, VTUTF8ChannelGetIBufferIndex(Channel) - ReadLength); /* Are there still bytes that haven't been read yet? */ if (Channel->ChannelInputBufferLength(Channel)) { /* Shift them up in the buffer */ RtlMoveMemory(Channel->IBuffer, &Channel->IBuffer[ReadLength], Channel->ChannelInputBufferLength(Channel) * sizeof(WCHAR)); } /* Return the number of bytes we actually copied */ *ReturnBufferSize = ReadLength; } /* Return success */ return STATUS_SUCCESS; }
NTSTATUS NTAPI VTUTF8ChannelIWrite(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize) { NTSTATUS Status; BOOLEAN IsFull; ULONG Index, i; CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(Buffer); CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); /* First, check if the input buffer still has space */ Status = VTUTF8ChannelIBufferIsFull(Channel, &IsFull); if (!NT_SUCCESS(Status)) return Status; if (IsFull) return STATUS_UNSUCCESSFUL; /* Get the current buffer index */ Index = VTUTF8ChannelGetIBufferIndex(Channel); if ((SAC_VTUTF8_IBUFFER_SIZE - Index) < BufferSize) { return STATUS_INSUFFICIENT_RESOURCES; } /* Copy the new data */ for (i = 0; i < BufferSize; i++) { /* Convert the character */ if (SacTranslateUtf8ToUnicode(Buffer[i], IncomingUtf8ConversionBuffer, &IncomingUnicodeValue)) { /* Write it into the buffer */ *(PWCHAR)&Channel->IBuffer[VTUTF8ChannelGetIBufferIndex(Channel)] = IncomingUnicodeValue; /* Update the index */ Index = VTUTF8ChannelGetIBufferIndex(Channel); VTUTF8ChannelSetIBufferIndex(Channel, Index + sizeof(WCHAR)); } } /* Signal the event, if one was set */ if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) { ChannelSetEvent(Channel, HasNewDataEvent); } /* All done */ return STATUS_SUCCESS; }
NTSTATUS NTAPI RawChannelIWrite(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize) { NTSTATUS Status; BOOLEAN IsFull; ULONG Index; CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(Buffer); CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); /* First, check if the input buffer still has space */ Status = RawChannelIBufferIsFull(Channel, &IsFull); if (!NT_SUCCESS(Status)) return Status; if (IsFull) return STATUS_UNSUCCESSFUL; /* Get the current buffer index */ Index = RawChannelGetIBufferIndex(Channel); if ((SAC_RAW_IBUFFER_SIZE - Index) < BufferSize) { return STATUS_INSUFFICIENT_RESOURCES; } /* Copy the new data */ RtlCopyMemory(&Channel->IBuffer[Index], Buffer, BufferSize); /* Update the index */ RawChannelSetIBufferIndex(Channel, BufferSize + Index); /* Signal the event, if one was set */ if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) { ChannelSetEvent(Channel, HasNewDataEvent); } /* All done */ return STATUS_SUCCESS; }
NTSTATUS NTAPI RawChannelOFlush(IN PSAC_CHANNEL Channel) { NTSTATUS Status; ULONG ByteCount; CHAR Dummy; CHECK_PARAMETER1(Channel); while (ChannelHasNewOBufferData(Channel)) { Status = RawChannelORead(Channel, &Dummy, sizeof(Dummy), &ByteCount); if (!NT_SUCCESS(Status)) return Status; CHECK_PARAMETER_WITH_STATUS(ByteCount == 1, STATUS_UNSUCCESSFUL); Status = ConMgrWriteData(Channel, &Dummy, sizeof(Dummy)); if (!NT_SUCCESS(Status)) return Status; } return ConMgrFlushData(Channel); }