2 * PROJECT: ReactOS Drivers
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/sac/driver/rawchan.c
5 * PURPOSE: Driver for the Server Administration Console (SAC) for EMS
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES ******************************************************************/
13 /* GLOBALS *******************************************************************/
15 /* FUNCTIONS *****************************************************************/
17 #define SAC_RAW_OBUFFER_SIZE 0x2000
18 #define SAC_RAW_IBUFFER_SIZE 0x2000
22 RawChannelCreate(IN PSAC_CHANNEL Channel
)
24 CHECK_PARAMETER(Channel
);
26 Channel
->OBuffer
= SacAllocatePool(SAC_RAW_OBUFFER_SIZE
, GLOBAL_BLOCK_TAG
);
27 CHECK_ALLOCATION(Channel
->OBuffer
);
29 Channel
->IBuffer
= SacAllocatePool(SAC_RAW_IBUFFER_SIZE
, GLOBAL_BLOCK_TAG
);
30 CHECK_ALLOCATION(Channel
->IBuffer
);
32 Channel
->OBufferIndex
= 0;
33 Channel
->OBufferFirstGoodIndex
= 0;
34 Channel
->ChannelHasNewIBufferData
= FALSE
;
35 Channel
->ChannelHasNewOBufferData
= FALSE
;
37 return STATUS_SUCCESS
;
42 RawChannelDestroy(IN PSAC_CHANNEL Channel
)
44 CHECK_PARAMETER(Channel
);
48 SacFreePool(Channel
->OBuffer
);
53 SacFreePool(Channel
->IBuffer
);
56 return ChannelDestroy(Channel
);
61 ChannelHasNewOBufferData(IN PSAC_CHANNEL Channel
)
63 return Channel
->ChannelHasNewOBufferData
;
68 ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel
)
70 return Channel
->ChannelHasNewIBufferData
;
75 RawChannelORead(IN PSAC_CHANNEL Channel
,
83 CHECK_PARAMETER1(Channel
);
84 CHECK_PARAMETER2(Buffer
);
85 CHECK_PARAMETER3(BufferSize
> 0);
86 CHECK_PARAMETER4(ByteCount
);
90 if (ChannelHasNewOBufferData(Channel
))
92 Status
= STATUS_SUCCESS
;
96 Buffer
[(*ByteCount
)++] = Channel
->OBuffer
[Channel
->OBufferFirstGoodIndex
];
98 NextIndex
= (Channel
->OBufferFirstGoodIndex
+ 1) & (SAC_OBUFFER_SIZE
- 1);
99 Channel
->OBufferFirstGoodIndex
= NextIndex
;
101 if (NextIndex
== Channel
->OBufferIndex
)
103 _InterlockedExchange(&Channel
->ChannelHasNewOBufferData
, 0);
107 ASSERT(*ByteCount
> 0);
109 if (*ByteCount
>= BufferSize
) break;
114 Status
= STATUS_NO_DATA_DETECTED
;
117 if (Channel
->OBufferFirstGoodIndex
== Channel
->OBufferIndex
)
119 ASSERT(ChannelHasNewOBufferData(Channel
) == FALSE
);
122 if (ChannelHasNewOBufferData(Channel
) == FALSE
)
124 ASSERT(Channel
->OBufferFirstGoodIndex
== Channel
->OBufferIndex
);
132 RawChannelOEcho(IN PSAC_CHANNEL Channel
,
136 NTSTATUS Status
= STATUS_SUCCESS
;
138 CHECK_PARAMETER1(Channel
);
139 CHECK_PARAMETER2(String
);
143 Status
= ConMgrWriteData(Channel
, String
, Length
);
144 if (NT_SUCCESS(Status
)) ConMgrFlushData(Channel
);
152 RawChannelOWrite2(IN PSAC_CHANNEL Channel
,
159 CHECK_PARAMETER1(Channel
);
160 CHECK_PARAMETER2(String
);
164 for (i
= 0; i
< Size
; i
++)
166 if ((Channel
->OBufferIndex
== Channel
->OBufferFirstGoodIndex
) &&
167 ((i
) || (ChannelHasNewOBufferData(Channel
))))
172 ASSERT(Channel
->OBufferIndex
< SAC_RAW_OBUFFER_SIZE
);
174 Channel
->OBuffer
[Channel
->OBufferIndex
] = String
[i
];
176 NextIndex
= (Channel
->OBufferIndex
+ 1) & (SAC_RAW_OBUFFER_SIZE
- 1);
177 Channel
->OBufferIndex
= NextIndex
;
179 if (Overflow
) Channel
->OBufferFirstGoodIndex
= NextIndex
;
182 _InterlockedExchange(&Channel
->ChannelHasNewOBufferData
, 1);
184 return STATUS_SUCCESS
;
189 RawChannelOFlush(IN PSAC_CHANNEL Channel
)
194 CHECK_PARAMETER1(Channel
);
196 while (ChannelHasNewOBufferData(Channel
))
198 Status
= RawChannelORead(Channel
, &Dummy
, sizeof(Dummy
), &ByteCount
);
199 if (!NT_SUCCESS(Status
)) return Status
;
201 CHECK_PARAMETER_WITH_STATUS(ByteCount
== 1, STATUS_UNSUCCESSFUL
);
203 Status
= ConMgrWriteData(Channel
, &Dummy
, sizeof(Dummy
));
204 if (!NT_SUCCESS(Status
)) return Status
;
207 return ConMgrFlushData(Channel
);
212 RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel
)
215 ASSERT(Channel
->IBufferIndex
< SAC_RAW_IBUFFER_SIZE
);
217 return Channel
->IBufferIndex
;
222 RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel
,
223 IN ULONG BufferIndex
)
227 ASSERT(Channel
->IBufferIndex
< SAC_RAW_IBUFFER_SIZE
);
229 Channel
->IBufferIndex
= BufferIndex
;
230 Channel
->ChannelHasNewIBufferData
= BufferIndex
!= 0;
232 if (!Channel
->IBufferIndex
)
234 if (Channel
->Flags
& SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT
)
236 ChannelClearEvent(Channel
, HasNewDataEvent
);
237 UNREFERENCED_PARAMETER(Status
);
244 RawChannelOWrite(IN PSAC_CHANNEL Channel
,
248 CHECK_PARAMETER1(Channel
);
249 CHECK_PARAMETER2(String
);
251 if ((ConMgrIsWriteEnabled(Channel
)) && (Channel
->WriteEnabled
))
253 return RawChannelOEcho(Channel
, String
, Length
);
256 return RawChannelOWrite2(Channel
, String
, Length
);
261 RawChannelIRead(IN PSAC_CHANNEL Channel
,
264 IN PULONG ReturnBufferSize
)
268 CHECK_PARAMETER1(Channel
);
269 CHECK_PARAMETER2(Buffer
);
270 CHECK_PARAMETER_WITH_STATUS(BufferSize
> 0, STATUS_INVALID_BUFFER_SIZE
);
272 *ReturnBufferSize
= 0;
274 if (Channel
->ChannelInputBufferLength(Channel
) == 0)
276 ASSERT(ChannelHasNewIBufferData(Channel
) == FALSE
);
280 CopyChars
= Channel
->ChannelInputBufferLength(Channel
);
281 if (CopyChars
> BufferSize
) CopyChars
= BufferSize
;
282 ASSERT(CopyChars
<= Channel
->ChannelInputBufferLength(Channel
));
284 RtlCopyMemory(Buffer
, Channel
->IBuffer
, CopyChars
);
286 RawChannelSetIBufferIndex(Channel
,
287 RawChannelGetIBufferIndex(Channel
) - CopyChars
);
289 if (Channel
->ChannelInputBufferLength(Channel
))
291 RtlMoveMemory(Channel
->IBuffer
,
292 &Channel
->IBuffer
[CopyChars
],
293 Channel
->ChannelInputBufferLength(Channel
));
296 *ReturnBufferSize
= CopyChars
;
299 return STATUS_SUCCESS
;
304 RawChannelIBufferIsFull(IN PSAC_CHANNEL Channel
,
305 OUT PBOOLEAN BufferStatus
)
307 CHECK_PARAMETER1(Channel
);
308 CHECK_PARAMETER2(BufferStatus
);
310 *BufferStatus
= RawChannelGetIBufferIndex(Channel
) > SAC_RAW_IBUFFER_SIZE
;
311 return STATUS_SUCCESS
;
316 RawChannelIBufferLength(IN PSAC_CHANNEL Channel
)
319 return RawChannelGetIBufferIndex(Channel
);
324 RawChannelIReadLast(IN PSAC_CHANNEL Channel
)
330 if (Channel
->ChannelInputBufferLength(Channel
))
332 RawChannelSetIBufferIndex(Channel
, RawChannelGetIBufferIndex(Channel
) - 1);
334 LastChar
= Channel
->IBuffer
[RawChannelGetIBufferIndex(Channel
)];
335 Channel
->IBuffer
[RawChannelGetIBufferIndex(Channel
)] = 0;
343 RawChannelIWrite(IN PSAC_CHANNEL Channel
,
351 CHECK_PARAMETER1(Channel
);
352 CHECK_PARAMETER2(Buffer
);
353 CHECK_PARAMETER_WITH_STATUS(BufferSize
> 0, STATUS_INVALID_BUFFER_SIZE
);
355 Status
= RawChannelIBufferIsFull(Channel
, &IsFull
);
356 if (!NT_SUCCESS(Status
)) return Status
;
358 if (IsFull
) return STATUS_UNSUCCESSFUL
;
360 Index
= RawChannelGetIBufferIndex(Channel
);
361 if ((SAC_RAW_IBUFFER_SIZE
- Index
) >= BufferSize
) return STATUS_INSUFFICIENT_RESOURCES
;
363 RtlCopyMemory(&Channel
->IBuffer
[Index
], Buffer
, BufferSize
);
365 RawChannelSetIBufferIndex(Channel
, BufferSize
+ Index
);
367 if (Channel
->Flags
& SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT
)
369 ChannelSetEvent(Channel
, HasNewDataEvent
);
372 return STATUS_SUCCESS
;