ReactOS  0.4.14-dev-815-ge410a12
rawchan.c
Go to the documentation of this file.
1 /*
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
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "sacdrv.h"
12 
13 /* FUNCTIONS ******************************************************************/
14 
16 NTAPI
18 {
19  CHECK_PARAMETER(Channel);
20 
21  /* Allocate the output buffer */
23  CHECK_ALLOCATION(Channel->OBuffer);
24 
25  /* Allocate the input buffer */
27  CHECK_ALLOCATION(Channel->IBuffer);
28 
29  /* Reset all flags and return success */
30  Channel->OBufferIndex = 0;
31  Channel->OBufferFirstGoodIndex = 0;
32  Channel->ChannelHasNewIBufferData = FALSE;
33  Channel->ChannelHasNewOBufferData = FALSE;
34  return STATUS_SUCCESS;
35 }
36 
38 NTAPI
40 {
41  CHECK_PARAMETER(Channel);
42 
43  /* Free the buffer and then destroy the channel */
44  if (Channel->OBuffer) SacFreePool(Channel->OBuffer);
45  if (Channel->IBuffer) SacFreePool(Channel->IBuffer);
46  return ChannelDestroy(Channel);
47 }
48 
50 BOOLEAN
52 {
53  return Channel->ChannelHasNewOBufferData;
54 }
55 
57 NTAPI
59  IN PCHAR Buffer,
62 {
64  ULONG NextIndex;
65 
66  CHECK_PARAMETER1(Channel);
70 
71  *ByteCount = 0;
72 
73  if (ChannelHasNewOBufferData(Channel))
74  {
76 
77  while (TRUE)
78  {
79  Buffer[(*ByteCount)++] = Channel->OBuffer[Channel->OBufferFirstGoodIndex];
80 
81  NextIndex = (Channel->OBufferFirstGoodIndex + 1) & (SAC_OBUFFER_SIZE - 1);
82  Channel->OBufferFirstGoodIndex = NextIndex;
83 
84  if (NextIndex == Channel->OBufferIndex)
85  {
86  _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0);
87  break;
88  }
89 
90  ASSERT(*ByteCount > 0);
91 
92  if (*ByteCount >= BufferSize) break;
93  }
94  }
95  else
96  {
98  }
99 
100  if (Channel->OBufferFirstGoodIndex == Channel->OBufferIndex)
101  {
103  }
104 
105  if (ChannelHasNewOBufferData(Channel) == FALSE)
106  {
107  ASSERT(Channel->OBufferFirstGoodIndex == Channel->OBufferIndex);
108  }
109 
110  return Status;
111 }
112 
113 NTSTATUS
114 NTAPI
116  IN PCHAR String,
117  IN ULONG Length)
118 {
120 
121  CHECK_PARAMETER1(Channel);
123 
124  if (Length)
125  {
126  Status = ConMgrWriteData(Channel, String, Length);
127  if (NT_SUCCESS(Status)) ConMgrFlushData(Channel);
128  }
129 
130  return Status;
131 }
132 
133 NTSTATUS
134 NTAPI
136  IN PCHAR String,
137  IN ULONG Size)
138 {
139  BOOLEAN Overflow;
140  ULONG i, NextIndex;
141 
142  CHECK_PARAMETER1(Channel);
144 
145  Overflow = FALSE;
146 
147  for (i = 0; i < Size; i++)
148  {
149  if ((Channel->OBufferIndex == Channel->OBufferFirstGoodIndex) &&
150  ((i) || (ChannelHasNewOBufferData(Channel))))
151  {
152  Overflow = TRUE;
153  }
154 
155  ASSERT(Channel->OBufferIndex < SAC_RAW_OBUFFER_SIZE);
156 
157  Channel->OBuffer[Channel->OBufferIndex] = String[i];
158 
159  NextIndex = (Channel->OBufferIndex + 1) & (SAC_RAW_OBUFFER_SIZE - 1);
160  Channel->OBufferIndex = NextIndex;
161 
162  if (Overflow) Channel->OBufferFirstGoodIndex = NextIndex;
163  }
164 
165  _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 1);
166 
167  return STATUS_SUCCESS;
168 }
169 
170 NTSTATUS
171 NTAPI
173 {
176  CHAR Dummy;
177  CHECK_PARAMETER1(Channel);
178 
179  while (ChannelHasNewOBufferData(Channel))
180  {
181  Status = RawChannelORead(Channel, &Dummy, sizeof(Dummy), &ByteCount);
182  if (!NT_SUCCESS(Status)) return Status;
183 
185 
186  Status = ConMgrWriteData(Channel, &Dummy, sizeof(Dummy));
187  if (!NT_SUCCESS(Status)) return Status;
188  }
189 
190  return ConMgrFlushData(Channel);
191 }
192 
193 NTSTATUS
194 NTAPI
196  IN PCHAR String,
197  IN ULONG Length)
198 {
199  CHECK_PARAMETER1(Channel);
201 
202  if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled))
203  {
204  return RawChannelOEcho(Channel, String, Length);
205  }
206 
207  return RawChannelOWrite2(Channel, String, Length);
208 }
209 
210 ULONG
211 NTAPI
213 {
214  ASSERT(Channel);
215  ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
216 
217  /* Return the current buffer index */
218  return Channel->IBufferIndex;
219 }
220 
221 VOID
222 NTAPI
224  IN ULONG BufferIndex)
225 {
227  ASSERT(Channel);
228  ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
229 
230  /* Set the new index, and if it's not zero, it means we have data */
231  Channel->IBufferIndex = BufferIndex;
232  _InterlockedExchange(&Channel->ChannelHasNewIBufferData, BufferIndex != 0);
233 
234  /* If we have new data, and an event has been registered... */
235  if (!(Channel->IBufferIndex) &&
236  (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT))
237  {
238  /* Go ahead and signal it */
239  ChannelClearEvent(Channel, HasNewDataEvent);
241  }
242 }
243 
244 NTSTATUS
245 NTAPI
247  IN PCHAR Buffer,
250 {
251  ULONG CopyChars;
252  CHECK_PARAMETER1(Channel);
255 
256  /* Assume failure */
257  *ReturnBufferSize = 0;
258 
259  /* Check how many bytes are in the buffer */
260  if (Channel->ChannelInputBufferLength(Channel) == 0)
261  {
262  /* Apparently nothing. Make sure the flag indicates so too */
264  }
265  else
266  {
267  /* Use the smallest number of bytes either in the buffer or requested */
268  CopyChars = min(Channel->ChannelInputBufferLength(Channel), BufferSize);
269  ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel));
270 
271  /* Copy them into the caller's buffer */
272  RtlCopyMemory(Buffer, Channel->IBuffer, CopyChars);
273 
274  /* Update the channel's index past the copied (read) bytes */
276  RawChannelGetIBufferIndex(Channel) - CopyChars);
277 
278  /* Are there still bytes that haven't been read yet? */
279  if (Channel->ChannelInputBufferLength(Channel))
280  {
281  /* Shift them up in the buffer */
282  RtlMoveMemory(Channel->IBuffer,
283  &Channel->IBuffer[CopyChars],
284  Channel->ChannelInputBufferLength(Channel));
285  }
286 
287  /* Return the number of bytes we actually copied */
288  *ReturnBufferSize = CopyChars;
289  }
290 
291  /* Return success */
292  return STATUS_SUCCESS;
293 }
294 
295 NTSTATUS
296 NTAPI
298  OUT PBOOLEAN BufferStatus)
299 {
300  CHECK_PARAMETER1(Channel);
301  CHECK_PARAMETER2(BufferStatus);
302 
303  /* If the index is beyond the length, the buffer must be full */
304  *BufferStatus = RawChannelGetIBufferIndex(Channel) > SAC_RAW_IBUFFER_SIZE;
305  return STATUS_SUCCESS;
306 }
307 
308 ULONG
309 NTAPI
311 {
312  ASSERT(Channel);
313 
314  /* The index is the current length (since we're 0-based) */
315  return RawChannelGetIBufferIndex(Channel);
316 }
317 
318 WCHAR
319 NTAPI
321 {
322  UCHAR LastChar = 0;
323  ASSERT(Channel);
324 
325  /* Check if there's anything to read in the buffer */
326  if (Channel->ChannelInputBufferLength(Channel))
327  {
328  /* Go back one character */
330  RawChannelGetIBufferIndex(Channel) - 1);
331 
332  /* Read it, and clear its current value */
333  LastChar = Channel->IBuffer[RawChannelGetIBufferIndex(Channel)];
334  Channel->IBuffer[RawChannelGetIBufferIndex(Channel)] = ANSI_NULL;
335  }
336 
337  /* Return the last character */
338  return LastChar;
339 }
340 
341 NTSTATUS
342 NTAPI
344  IN PCHAR Buffer,
346 {
348  BOOLEAN IsFull;
349  ULONG Index;
350  CHECK_PARAMETER1(Channel);
353 
354  /* First, check if the input buffer still has space */
355  Status = RawChannelIBufferIsFull(Channel, &IsFull);
356  if (!NT_SUCCESS(Status)) return Status;
357  if (IsFull) return STATUS_UNSUCCESSFUL;
358 
359  /* Get the current buffer index */
360  Index = RawChannelGetIBufferIndex(Channel);
362  {
364  }
365 
366  /* Copy the new data */
367  RtlCopyMemory(&Channel->IBuffer[Index], Buffer, BufferSize);
368 
369  /* Update the index */
371 
372  /* Signal the event, if one was set */
373  if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
374  {
375  ChannelSetEvent(Channel, HasNewDataEvent);
376  }
377 
378  /* All done */
379  return STATUS_SUCCESS;
380 }
signed char * PCHAR
Definition: retypes.h:7
#define IN
Definition: typedefs.h:38
BOOLEAN NTAPI ConMgrIsWriteEnabled(IN PSAC_CHANNEL Channel)
Definition: conmgr.c:155
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define CHECK_ALLOCATION(x)
Definition: sacdrv.h:64
WCHAR NTAPI RawChannelIReadLast(IN PSAC_CHANNEL Channel)
Definition: rawchan.c:320
#define SAC_RAW_OBUFFER_SIZE
Definition: sacdrv.h:162
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define SAC_RAW_IBUFFER_SIZE
Definition: sacdrv.h:163
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1892
ULONG NTAPI RawChannelIBufferLength(IN PSAC_CHANNEL Channel)
Definition: rawchan.c:310
static WCHAR String[]
Definition: stringtable.c:55
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define GLOBAL_BLOCK_TAG
Definition: sacdrv.h:141
ULONG NTAPI RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel)
Definition: rawchan.c:212
NTSTATUS NTAPI ChannelDestroy(IN PSAC_CHANNEL Channel)
Definition: channel.c:77
FORCEINLINE BOOLEAN ChannelHasNewOBufferData(IN PSAC_CHANNEL Channel)
Definition: rawchan.c:51
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define ANSI_NULL
NTSTATUS NTAPI RawChannelOWrite2(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Size)
Definition: rawchan.c:135
unsigned char BOOLEAN
#define FORCEINLINE
Definition: ntbasedef.h:221
Definition: bufpool.h:45
NTSTATUS NTAPI RawChannelOEcho(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Length)
Definition: rawchan.c:115
#define CHECK_PARAMETER(x)
Definition: sacdrv.h:54
#define SacAllocatePool(Length, Tag)
Definition: sacdrv.h:24
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
NTSTATUS NTAPI ConMgrFlushData(IN PSAC_CHANNEL Channel)
Definition: conmgr.c:139
FORCEINLINE BOOLEAN ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel)
Definition: sacdrv.h:1360
#define ChannelSetEvent(Channel, x)
Definition: sacdrv.h:98
NTSTATUS NTAPI RawChannelORead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount)
Definition: rawchan.c:58
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT
Definition: sacdrv.h:170
NTSTATUS NTAPI RawChannelDestroy(IN PSAC_CHANNEL Channel)
Definition: rawchan.c:39
NTSTATUS NTAPI RawChannelIRead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, IN PULONG ReturnBufferSize)
Definition: rawchan.c:246
static const UCHAR Index[8]
Definition: usbohci.c:18
#define BufferSize
Definition: classpnp.h:419
#define SacFreePool(Pointer)
Definition: sacdrv.h:26
#define CHECK_PARAMETER1(x)
Definition: sacdrv.h:56
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
VOID NTAPI RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel, IN ULONG BufferIndex)
Definition: rawchan.c:223
#define STATUS_NO_DATA_DETECTED
Definition: udferr_usr.h:131
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define ChannelClearEvent(Channel, x)
Definition: sacdrv.h:113
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
Status
Definition: gdiplustypes.h:24
#define CHECK_PARAMETER3(x)
Definition: sacdrv.h:60
NTSTATUS NTAPI ConMgrWriteData(IN PSAC_CHANNEL Channel, IN PVOID Buffer, IN ULONG BufferLength)
Definition: conmgr.c:111
#define CHECK_PARAMETER4(x)
Definition: sacdrv.h:62
NTSTATUS NTAPI RawChannelOWrite(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Length)
Definition: rawchan.c:195
NTSTATUS NTAPI RawChannelOFlush(IN PSAC_CHANNEL Channel)
Definition: rawchan.c:172
#define CHECK_PARAMETER_WITH_STATUS(Condition, Status)
Definition: sacdrv.h:47
#define SAC_OBUFFER_SIZE
Definition: sacdrv.h:150
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define CHECK_PARAMETER2(x)
Definition: sacdrv.h:58
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI RawChannelIWrite(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize)
Definition: rawchan.c:343
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSTATUS NTAPI RawChannelCreate(IN PSAC_CHANNEL Channel)
Definition: rawchan.c:17
NTSTATUS NTAPI RawChannelIBufferIsFull(IN PSAC_CHANNEL Channel, OUT PBOOLEAN BufferStatus)
Definition: rawchan.c:297