xref: /reactos/drivers/sac/driver/sacdrv.h (revision 23373acb)
1 /*
2  * PROJECT:     ReactOS Drivers
3  * LICENSE:     BSD - See COPYING.ARM in the top level directory
4  * FILE:        drivers/sac/driver/sacdrv.h
5  * PURPOSE:     Driver for the Server Administration Console (SAC) for EMS
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 #ifndef _SACDRV_H_
10 #define _SACDRV_H_
11 
12 /* INCLUDES *******************************************************************/
13 
14 #include <ntifs.h>
15 #include <stdio.h>
16 #include <ntoskrnl/include/internal/hdl.h>
17 #include <sacmsg.h>
18 
19 /* DEFINES ********************************************************************/
20 
21 //
22 // SAC Heap Allocator Macros
23 //
24 #define SacAllocatePool(Length, Tag)    \
25     MyAllocatePool(Length, Tag, __FILE__, __LINE__)
26 #define SacFreePool(Pointer)            \
27     MyFreePool((PVOID*)(&Pointer))
28 
29 //
30 // SAC Debugging Macro and Constants
31 //
32 #define SAC_DBG_ENTRY_EXIT                  0x01
33 #define SAC_DBG_UTIL                        0x02
34 #define SAC_DBG_INIT                        0x04
35 #define SAC_DBG_MM                          0x1000
36 #define SAC_DBG_MACHINE                     0x2000
37 #define SAC_DBG(x, ...)                     \
38     if (SACDebug & x)                       \
39     {                                       \
40         DbgPrint("SAC %s: ", __FUNCTION__); \
41         DbgPrint(__VA_ARGS__);              \
42     }
43 
44 //
45 // SAC Parameter Checking Macros
46 //
47 #define CHECK_PARAMETER_WITH_STATUS(Condition, Status)  \
48 {                                                       \
49     if (!NT_VERIFY(Condition))                          \
50     {                                                   \
51         return Status;                                  \
52     }                                                   \
53 }
54 #define CHECK_PARAMETER(x)      \
55     CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER)
56 #define CHECK_PARAMETER1(x)     \
57     CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_1)
58 #define CHECK_PARAMETER2(x)     \
59     CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_2)
60 #define CHECK_PARAMETER3(x)     \
61     CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_3)
62 #define CHECK_PARAMETER4(x)     \
63     CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_4)
64 #define CHECK_ALLOCATION(x)     \
65     CHECK_PARAMETER_WITH_STATUS(x, STATUS_NO_MEMORY)
66 
67 //
68 // SAC Channel Event Macros
69 //
70 #define ChannelInitializeEvent(Channel, Attributes, x)                  \
71 {                                                                       \
72     PVOID Object, WaitObject;                                           \
73     if (Attributes->x)                                                  \
74     {                                                                   \
75         if (!VerifyEventWaitable(Attributes->x, &Object, &WaitObject))  \
76         {                                                               \
77             goto FailChannel;                                           \
78         }                                                               \
79         Channel->x = Attributes->x;                                     \
80         Channel->x##ObjectBody = Object;                                \
81         Channel->x##WaitObjectBody = WaitObject;                        \
82     }                                                                   \
83 }
84 #define ChannelUninitializeEvent(Channel, x, f)         \
85 {                                                       \
86     ASSERT(ChannelGetFlags(Channel) & (f));             \
87     ASSERT(Channel->x##ObjectBody);                     \
88     ASSERT(Channel->x##WaitObjectBody);                 \
89     if (Channel->x##ObjectBody)                         \
90     {                                                   \
91         ObDereferenceObject(Channel->x##ObjectBody);    \
92         Channel->Flags &= ~(f);                         \
93         Channel->x = NULL;                              \
94         Channel->x##ObjectBody = NULL;                  \
95         Channel->x##WaitObjectBody = NULL;              \
96     }                                                   \
97 }
98 #define ChannelSetEvent(Channel, x)                                     \
99 {                                                                       \
100     ASSERT(Channel->x);                                                 \
101     ASSERT(Channel->x##ObjectBody);                                     \
102     ASSERT(Channel->x##WaitObjectBody);                                 \
103     if (Channel->x##WaitObjectBody)                                     \
104     {                                                                   \
105         KeSetEvent(Channel->x##WaitObjectBody, EVENT_INCREMENT, FALSE); \
106         Status = STATUS_SUCCESS;                                        \
107     }                                                                   \
108     else                                                                \
109     {                                                                   \
110         Status = STATUS_UNSUCCESSFUL;                                   \
111     }                                                                   \
112 }
113 #define ChannelClearEvent(Channel, x)               \
114 {                                                   \
115     ASSERT(Channel->x);                             \
116     ASSERT(Channel->x##ObjectBody);                 \
117     ASSERT(Channel->x##WaitObjectBody);             \
118     if (Channel->x##WaitObjectBody)                 \
119     {                                               \
120         KeClearEvent(Channel->x##WaitObjectBody);   \
121         Status = STATUS_SUCCESS;                    \
122     }                                               \
123     else                                            \
124     {                                               \
125         Status = STATUS_UNSUCCESSFUL;               \
126     }                                               \
127 }
128 
129 //
130 // SAC Pool Tags, taken from pooltag.txt:
131 //
132 //  Rcp? - sacdrv.sys - SAC Driver (Headless)
133 //  RcpA - sacdrv.sys -     Internal memory mgr alloc block
134 //  RcpI - sacdrv.sys -     Internal memory mgr initial heap block
135 //  RcpS - sacdrv.sys -     Security related block
136 #define GENERIC_TAG                         '?pcR'
137 #define ALLOC_BLOCK_TAG                     'ApcR'
138 #define INITIAL_BLOCK_TAG                   'IpcR'
139 #define SECURITY_BLOCK_TAG                  'SpcR'
140 #define FREE_POOL_TAG                       'FpcR'
141 #define GLOBAL_BLOCK_TAG                    'GpcR'
142 #define CHANNEL_BLOCK_TAG                   'CpcR'
143 #define LOCAL_MEMORY_SIGNATURE              'SSEL'
144 #define GLOBAL_MEMORY_SIGNATURE             'DAEH'
145 
146 //
147 // Size Definitions
148 //
149 #define SAC_MEMORY_LIST_SIZE                (1 * 1024 * 1024)   // 1MB
150 #define SAC_OBUFFER_SIZE                    (2 * 1024)          // 2KB
151 #define SAC_CHANNEL_NAME_SIZE               64
152 #define SAC_CHANNEL_DESCRIPTION_SIZE        256
153 #define SAC_MAX_CHANNELS                    10
154 #define SAC_SERIAL_PORT_BUFFER_SIZE         1024                // 1KB
155 #define SAC_MAX_MESSAGES                    200
156 #define SAC_VTUTF8_COL_WIDTH                80
157 #define SAC_VTUTF8_COL_HEIGHT               25
158 #define SAC_VTUTF8_ROW_HEIGHT               24
159 #define MAX_UTF8_ENCODE_BLOCK_LENGTH        (Utf8ConversionBufferSize / 3 - 1)
160 #define SAC_VTUTF8_OBUFFER_SIZE             0x2D00
161 #define SAC_VTUTF8_IBUFFER_SIZE             0x2000
162 #define SAC_RAW_OBUFFER_SIZE                0x2000
163 #define SAC_RAW_IBUFFER_SIZE                0x2000
164 
165 //
166 // Channel flags
167 //
168 #define SAC_CHANNEL_FLAG_INTERNAL           0x1
169 #define SAC_CHANNEL_FLAG_CLOSE_EVENT        0x2
170 #define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT 0x4
171 #define SAC_CHANNEL_FLAG_LOCK_EVENT         0x8
172 #define SAC_CHANNEL_FLAG_REDRAW_EVENT       0x10
173 #define SAC_CHANNEL_FLAG_APPLICATION        0x20
174 
175 //
176 // Cell Flags
177 //
178 #define SAC_CELL_FLAG_BLINK                 1
179 #define SAC_CELL_FLAG_BOLD                  2
180 #define SAC_CELL_FLAG_INVERTED              4
181 
182 //
183 // Forward definitions
184 //
185 struct _SAC_CHANNEL;
186 
187 //
188 // Structures used by the SAC Heap Allocator
189 //
190 typedef struct _SAC_MEMORY_ENTRY
191 {
192     ULONG Signature;
193     ULONG Tag;
194     ULONG Size;
195 } SAC_MEMORY_ENTRY, *PSAC_MEMORY_ENTRY;
196 typedef struct _SAC_MEMORY_LIST
197 {
198     ULONG Signature;
199     PSAC_MEMORY_ENTRY LocalDescriptor;
200     ULONG Size;
201     struct _SAC_MEMORY_LIST* Next;
202 } SAC_MEMORY_LIST, *PSAC_MEMORY_LIST;
203 
204 typedef struct _SAC_MESSAGE_ENTRY
205 {
206     ULONG Index;
207     PWCHAR Buffer;
208 } SAC_MESSAGE_ENTRY, *PSAC_MESSAGE_ENTRY;
209 
210 //
211 // These are the VT-100/220/ANSI Escape Codes supported by SAC as input
212 //
213 typedef enum _SAC_ANSI_COMMANDS
214 {
215     SacCursorUp,
216     SacCursorDown,
217     SacCursorRight,
218     SacCursorLeft,
219     SacFontNormal,
220     SacFontBlink,
221     SacFontBlinkOff,
222     SacFontBold,
223     SacFontBoldOff,
224     SacFontInverse,
225     SacFontInverseOff,
226     SacBackTab,
227     SacEraseEndOfLine,
228     SacEraseStartOfLine,
229     SacEraseLine,
230     SacEraseEndOfScreen,
231     SacEraseStartOfScreen,
232     SacEraseScreen,
233     SacSetCursorPosition,
234     SacSetScrollRegion,
235     SacSetColors,
236     SacSetBackgroundColor,
237     SacSetFontColor,
238     SacSetColorsAndAttributes
239 } SAC_ANSI_COMMANDS;
240 
241 //
242 // These are the VT-100/220/ANSI Escape Codes send by SAC as output
243 //
244 typedef enum _SAC_ANSI_DISPATCH
245 {
246     SacAnsiClearScreen,
247     SacAnsiClearEndOfScreen,
248     SacAnsiClearEndOfLine,
249     SacAnsiSetColors,
250     SacAnsiSetPosition,
251     SacAnsiClearAttributes,
252     SacAnsiSetInverseAttribute,
253     SacAnsiClearInverseAttribute,
254     SacAnsiSetBlinkAttribute,
255     SacAnsiClearBlinkAttribute,
256     SacAnsiSetBoldAttribute,
257     SacAnsiClearBoldAttribute
258 } SAC_ANSI_DISPATCH;
259 
260 //
261 // Commands that the consumer and producer share
262 //
263 typedef enum _SAC_POST_COMMANDS
264 {
265     Nothing,
266     Shutdown,
267     Close,
268     Restart
269 } SAC_POST_COMMANDS;
270 
271 //
272 // SAC supports 3 different channel output types
273 //
274 typedef enum _SAC_CHANNEL_TYPE
275 {
276     VtUtf8,
277     Cmd,
278     Raw
279 } SAC_CHANNEL_TYPE;
280 
281 //
282 // A SAC channel can be active or inactive
283 //
284 typedef enum _SAC_CHANNEL_STATUS
285 {
286     Inactive,
287     Active
288 } SAC_CHANNEL_STATUS, *PSAC_CHANNEL_STATUS;
289 
290 //
291 // A SAC channel identifier
292 //
293 typedef struct _SAC_CHANNEL_ID
294 {
295     GUID ChannelGuid;
296     ULONG ChannelId;
297 } SAC_CHANNEL_ID, *PSAC_CHANNEL_ID;
298 
299 //
300 // Reference-counted SAC channel semaphore lock
301 //
302 typedef struct _SAC_CHANNEL_LOCK
303 {
304     LONG RefCount;
305     KSEMAPHORE Lock;
306 } SAC_CHANNEL_LOCK, *PSAC_CHANNEL_LOCK;
307 
308 //
309 // Structure of the cell-buffer when in VT-UTF8 Mode
310 //
311 typedef struct _SAC_CELL_DATA
312 {
313     UCHAR CellBackColor;
314     UCHAR CellForeColor;
315     UCHAR CellFlags;
316     WCHAR Char;
317 } SAC_CELL_DATA, *PSAC_CELL_DATA;
318 C_ASSERT(sizeof(SAC_CELL_DATA) == 6);
319 
320 //
321 // Screen buffer when in VT-UTF8 Mode
322 //
323 typedef struct _SAC_VTUTF8_SCREEN
324 {
325     SAC_CELL_DATA Cell[SAC_VTUTF8_ROW_HEIGHT][SAC_VTUTF8_COL_WIDTH];
326 } SAC_VTUTF8_SCREEN, *PSAC_VTUTF8_SCREEN;
327 
328 //
329 // Small optimization to easily recognize the most common VT-100/ANSI codes
330 //
331 typedef struct _SAC_STATIC_ESCAPE_STRING
332 {
333     WCHAR Sequence[10];
334     ULONG Size;
335     ULONG Action;
336 } SAC_STATIC_ESCAPE_STRING, *PSAC_STATIC_ESCAPE_STRING;
337 
338 //
339 // Channel callbacks
340 //
341 typedef
342 NTSTATUS
343 (NTAPI *PSAC_CHANNEL_CREATE)(
344     IN struct _SAC_CHANNEL* Channel
345 );
346 
347 typedef
348 NTSTATUS
349 (NTAPI *PSAC_CHANNEL_DESTROY)(
350     IN struct _SAC_CHANNEL* Channel
351 );
352 
353 typedef
354 NTSTATUS
355 (NTAPI *PSAC_CHANNEL_OREAD)(
356     IN struct _SAC_CHANNEL* Channel,
357     IN PCHAR Buffer,
358     IN ULONG BufferSize,
359     OUT PULONG ByteCount
360 );
361 
362 typedef
363 NTSTATUS
364 (NTAPI *PSAC_CHANNEL_OECHO)(
365     IN struct _SAC_CHANNEL* Channel,
366     IN PCHAR String,
367     IN ULONG Length
368 );
369 
370 typedef
371 NTSTATUS
372 (NTAPI *PSAC_CHANNEL_OFLUSH)(
373     IN struct _SAC_CHANNEL* Channel
374 );
375 
376 typedef
377 NTSTATUS
378 (NTAPI *PSAC_CHANNEL_OWRITE)(
379     IN struct _SAC_CHANNEL* Channel,
380     IN PCHAR String,
381     IN ULONG Length
382 );
383 
384 typedef
385 NTSTATUS
386 (NTAPI *PSAC_CHANNEL_IREAD)(
387     IN struct _SAC_CHANNEL* Channel,
388     IN PCHAR Buffer,
389     IN ULONG BufferSize,
390     IN PULONG ReturnBufferSize
391 );
392 
393 typedef
394 NTSTATUS
395 (NTAPI *PSAC_CHANNEL_IBUFFER_FULL)(
396     IN struct _SAC_CHANNEL* Channel,
397     OUT PBOOLEAN BufferStatus
398 );
399 
400 typedef
401 ULONG
402 (NTAPI *PSAC_CHANNEL_IBUFFER_LENGTH)(
403     IN struct _SAC_CHANNEL* Channel
404 );
405 
406 typedef
407 WCHAR
408 (NTAPI *PSAC_CHANNEL_IREAD_LAST)(
409     IN struct _SAC_CHANNEL* Channel
410 );
411 
412 typedef
413 NTSTATUS
414 (NTAPI *PSAC_CHANNEL_IWRITE)(
415     IN struct _SAC_CHANNEL* Channel,
416     IN PCHAR Buffer,
417     IN ULONG BufferSize
418 );
419 
420 //
421 // A channel and its attributes
422 //
423 typedef struct _SAC_CHANNEL
424 {
425     LONG Index;
426     SAC_CHANNEL_ID ChannelId;
427     HANDLE CloseEvent;
428     PVOID CloseEventObjectBody;
429     PKEVENT CloseEventWaitObjectBody;
430     HANDLE HasNewDataEvent;
431     PVOID HasNewDataEventObjectBody;
432     PKEVENT HasNewDataEventWaitObjectBody;
433     HANDLE LockEvent;
434     PVOID LockEventObjectBody;
435     PKEVENT LockEventWaitObjectBody;
436     HANDLE RedrawEvent;
437     PVOID RedrawEventObjectBody;
438     PKEVENT RedrawEventWaitObjectBody;
439     PFILE_OBJECT FileObject;
440     SAC_CHANNEL_TYPE ChannelType;
441     SAC_CHANNEL_STATUS ChannelStatus;
442     WCHAR NameBuffer[SAC_CHANNEL_NAME_SIZE + 1];
443     WCHAR DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE + 1];
444     ULONG Flags;
445     GUID ApplicationType;
446     LONG WriteEnabled;
447     ULONG IBufferIndex;
448     PCHAR IBuffer;
449     LONG ChannelHasNewIBufferData;
450     UCHAR CursorRow;
451     UCHAR CursorCol;
452     UCHAR CellForeColor;
453     UCHAR CellBackColor;
454     UCHAR CellFlags;
455     PCHAR OBuffer;
456     ULONG OBufferIndex;
457     ULONG OBufferFirstGoodIndex;
458     LONG ChannelHasNewOBufferData;
459     PSAC_CHANNEL_CREATE ChannelCreate;
460     PSAC_CHANNEL_DESTROY ChannelDestroy;
461     PSAC_CHANNEL_OFLUSH ChannelOutputFlush;
462     PSAC_CHANNEL_OECHO ChannelOutputEcho;
463     PSAC_CHANNEL_OWRITE ChannelOutputWrite;
464     PSAC_CHANNEL_OREAD ChannelOutputRead;
465     PSAC_CHANNEL_IWRITE ChannelInputWrite;
466     PSAC_CHANNEL_IREAD ChannelInputRead;
467     PSAC_CHANNEL_IREAD_LAST ChannelInputReadLast;
468     PSAC_CHANNEL_IBUFFER_FULL ChannelInputBufferIsFull;
469     PSAC_CHANNEL_IBUFFER_LENGTH ChannelInputBufferLength;
470     SAC_CHANNEL_LOCK ChannelAttributeLock;
471     SAC_CHANNEL_LOCK ChannelOBufferLock;
472     SAC_CHANNEL_LOCK ChannelIBufferLock;
473 } SAC_CHANNEL, *PSAC_CHANNEL;
474 
475 typedef struct _SAC_CHANNEL_ATTRIBUTES
476 {
477     SAC_CHANNEL_TYPE ChannelType;
478     WCHAR NameBuffer[SAC_CHANNEL_NAME_SIZE + 1];
479     WCHAR DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE + 1];
480     ULONG Flag;
481     HANDLE CloseEvent;
482     HANDLE HasNewDataEvent;
483     HANDLE LockEvent;
484     HANDLE RedrawEvent;
485     GUID ChannelId;
486 } SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES;
487 
488 //
489 // Cached Machine Information
490 //
491 typedef struct _SAC_MACHINE_INFO
492 {
493     PWCHAR MachineName;
494     PWCHAR MachineGuid;
495     PWCHAR ProcessorArchitecture;
496     PWCHAR MajorVersion;
497     PWCHAR BuildNumber;
498     PWCHAR ProductType;
499     PWCHAR ServicePack;
500 } SAC_MACHINE_INFO, *PSAC_MACHINE_INFO;
501 
502 //
503 // The device extension for the SAC
504 //
505 typedef struct _SAC_DEVICE_EXTENSION
506 {
507     PDEVICE_OBJECT DeviceObject;
508     BOOLEAN Initialized;
509     BOOLEAN Rundown;
510     BOOLEAN PriorityFail;
511     BOOLEAN RundownInProgress;
512     KPRIORITY PriorityBoost;
513     PEPROCESS Process;
514     KSPIN_LOCK Lock;
515     KEVENT RundownEvent;
516     KEVENT Event;
517     HANDLE WorkerThreadHandle;
518     KEVENT WorkerThreadEvent;
519     KTIMER Timer;
520     KDPC Dpc;
521     LIST_ENTRY List;
522 } SAC_DEVICE_EXTENSION, *PSAC_DEVICE_EXTENSION;
523 
524 //
525 // Dispatch Routines
526 //
527 NTSTATUS
528 NTAPI
529 Dispatch(
530     IN PDEVICE_OBJECT DeviceObject,
531     IN PIRP Irp
532 );
533 
534 NTSTATUS
535 NTAPI
536 DispatchDeviceControl(
537     IN PDEVICE_OBJECT DeviceObject,
538     IN PIRP Irp
539 );
540 
541 NTSTATUS
542 NTAPI
543 DispatchShutdownControl(
544     IN PDEVICE_OBJECT DeviceObject,
545     IN PIRP Irp
546 );
547 
548 VOID
549 NTAPI
550 UnloadHandler(
551     IN PDRIVER_OBJECT DriverObject
552 );
553 
554 //
555 // Initialization and shutdown routines
556 //
557 VOID
558 NTAPI
559 FreeGlobalData(
560     VOID
561 );
562 
563 VOID
564 NTAPI
565 FreeDeviceData(
566     IN PDEVICE_OBJECT DeviceObject
567 );
568 
569 BOOLEAN
570 NTAPI
571 InitializeDeviceData(
572     IN PDEVICE_OBJECT DeviceObject
573 );
574 
575 BOOLEAN
576 NTAPI
577 InitializeGlobalData(
578     IN PUNICODE_STRING RegistryPath,
579     IN PDRIVER_OBJECT DriverObject
580 );
581 
582 BOOLEAN
583 NTAPI
584 InitializeMemoryManagement(
585     VOID
586 );
587 
588 VOID
589 NTAPI
590 FreeMemoryManagement(
591     VOID
592 );
593 
594 VOID
595 NTAPI
596 InitializeCmdEventInfo(
597     VOID
598 );
599 
600 VOID
601 NTAPI
602 InitializeMachineInformation(
603     VOID
604 );
605 
606 NTSTATUS
607 NTAPI
608 PreloadGlobalMessageTable(
609     IN PVOID ImageBase
610 );
611 
612 NTSTATUS
613 NTAPI
614 TearDownGlobalMessageTable(
615     VOID
616 );
617 
618 NTSTATUS
619 NTAPI
620 GetCommandConsoleLaunchingPermission(
621     OUT PBOOLEAN Permission
622 );
623 
624 NTSTATUS
625 NTAPI
626 ImposeSacCmdServiceStartTypePolicy(
627     VOID
628 );
629 
630 NTSTATUS
631 NTAPI
632 RegisterBlueScreenMachineInformation(
633     VOID
634 );
635 
636 VOID
637 NTAPI
638 FreeMachineInformation(
639     VOID
640 );
641 
642 //
643 // DPC, Timer, Thread Callbacks
644 //
645 VOID
646 NTAPI
647 TimerDpcRoutine(
648     IN PKDPC Dpc,
649     IN PVOID DeferredContext,
650     IN PVOID SystemArgument1,
651     IN PVOID SystemArgument2
652 );
653 
654 //
655 // Custom SAC Heap Allocator Routines
656 //
657 PVOID
658 NTAPI
659 MyAllocatePool(
660     IN SIZE_T PoolSize,
661     IN ULONG Tag,
662     IN PCHAR File,
663     IN ULONG Line
664 );
665 
666 VOID
667 NTAPI
668 MyFreePool(
669     IN PVOID *Block
670 );
671 
672 //
673 // Connection Manager Routines
674 //
675 NTSTATUS
676 NTAPI
677 ConMgrInitialize(
678     VOID
679 );
680 
681 VOID
682 NTAPI
683 ConMgrWorkerProcessEvents(
684     IN PSAC_DEVICE_EXTENSION DeviceExtension
685 );
686 
687 NTSTATUS
688 NTAPI
689 ConMgrShutdown(
690     VOID
691 );
692 
693 BOOLEAN
694 NTAPI
695 ConMgrSimpleEventMessage(
696     IN ULONG MessageIndex,
697     IN BOOLEAN LockHeld
698 );
699 
700 BOOLEAN
701 NTAPI
702 SacPutSimpleMessage(
703     IN ULONG MessageIndex
704 );
705 
706 VOID
707 NTAPI
708 SacPutString(
709     IN PWCHAR String
710 );
711 
712 NTSTATUS
713 NTAPI
714 ConMgrWriteData(
715     IN PSAC_CHANNEL Channel,
716     IN PVOID Buffer,
717     IN ULONG BufferLength
718 );
719 
720 NTSTATUS
721 NTAPI
722 ConMgrFlushData(
723     IN PSAC_CHANNEL Channel
724 );
725 
726 BOOLEAN
727 NTAPI
728 ConMgrIsWriteEnabled(
729     IN PSAC_CHANNEL Channel
730 );
731 
732 NTSTATUS
733 NTAPI
734 ConMgrHandleEvent(
735     IN ULONG EventCode,
736     IN PSAC_CHANNEL Channel,
737     OUT PVOID Data
738 );
739 
740 //
741 // Channel Manager Routines
742 //
743 NTSTATUS
744 NTAPI
745 ChanMgrInitialize(
746     VOID
747 );
748 
749 NTSTATUS
750 NTAPI
751 ChanMgrShutdown(
752     VOID
753 );
754 
755 NTSTATUS
756 NTAPI
757 ChanMgrCreateChannel(
758     OUT PSAC_CHANNEL *Channel,
759     IN PSAC_CHANNEL_ATTRIBUTES Attributes
760 );
761 
762 NTSTATUS
763 NTAPI
764 ChanMgrGetByHandle(
765     IN SAC_CHANNEL_ID ChannelId,
766     OUT PSAC_CHANNEL* TargetChannel
767 );
768 
769 NTSTATUS
770 NTAPI
771 ChanMgrReleaseChannel(
772     IN PSAC_CHANNEL Channel
773 );
774 
775 NTSTATUS
776 NTAPI
777 ChanMgrGetNextActiveChannel(
778     IN PSAC_CHANNEL CurrentChannel,
779     IN PULONG TargetIndex,
780     OUT PSAC_CHANNEL *TargetChannel
781 );
782 
783 NTSTATUS
784 NTAPI
785 ChanMgrCloseChannel(
786     IN PSAC_CHANNEL Channel
787 );
788 
789 //
790 // Channel Routines
791 //
792 NTSTATUS
793 NTAPI
794 ChannelClose(
795     IN PSAC_CHANNEL Channel
796 );
797 
798 BOOLEAN
799 NTAPI
800 ChannelIsEqual(
801     IN PSAC_CHANNEL Channel,
802     IN PSAC_CHANNEL_ID ChannelId
803 );
804 
805 NTSTATUS
806 NTAPI
807 ChannelOWrite(
808     IN PSAC_CHANNEL Channel,
809     IN PCHAR Buffer,
810     IN ULONG BufferSize
811 );
812 
813 NTSTATUS
814 NTAPI
815 ChannelOFlush(
816     IN PSAC_CHANNEL Channel
817 );
818 
819 NTSTATUS
820 NTAPI
821 ChannelSetRedrawEvent(
822     IN PSAC_CHANNEL Channel
823 );
824 
825 NTSTATUS
826 NTAPI
827 ChannelClearRedrawEvent(
828     IN PSAC_CHANNEL Channel
829 );
830 
831 NTSTATUS
832 NTAPI
833 ChannelHasRedrawEvent(
834     IN PSAC_CHANNEL Channel,
835     OUT PBOOLEAN Present
836 );
837 
838 BOOLEAN
839 NTAPI
840 ChannelIsActive(
841     IN PSAC_CHANNEL Channel
842 );
843 
844 NTSTATUS
845 NTAPI
846 ChannelGetName(
847     IN PSAC_CHANNEL Channel,
848     OUT PWCHAR *Name
849 );
850 
851 BOOLEAN
852 NTAPI
853 ChannelIsEqual(
854     IN PSAC_CHANNEL Channel,
855     IN PSAC_CHANNEL_ID ChannelId
856 );
857 
858 NTSTATUS
859 NTAPI
860 ChannelCreate(
861     IN PSAC_CHANNEL Channel,
862     IN PSAC_CHANNEL_ATTRIBUTES Attributes,
863     IN SAC_CHANNEL_ID ChannelId
864 );
865 
866 NTSTATUS
867 NTAPI
868 ChannelDestroy(
869     IN PSAC_CHANNEL Channel
870 );
871 
872 NTSTATUS
873 NTAPI
874 ChannelIWrite(
875     IN PSAC_CHANNEL Channel,
876     IN PCHAR Buffer,
877     IN ULONG BufferSize
878 );
879 
880 WCHAR
881 NTAPI
882 ChannelIReadLast(
883     IN PSAC_CHANNEL Channel
884 );
885 
886 ULONG
887 NTAPI
888 ChannelIBufferLength(
889     IN PSAC_CHANNEL Channel
890 );
891 
892 NTSTATUS
893 NTAPI
894 ChannelIRead(
895     IN PSAC_CHANNEL Channel,
896     IN PCHAR Buffer,
897     IN ULONG BufferSize,
898     IN OUT PULONG ResultBufferSize
899 );
900 
901 //
902 // RAW Channel Table
903 //
904 NTSTATUS
905 NTAPI
906 RawChannelCreate(
907     IN PSAC_CHANNEL Channel
908 );
909 
910 NTSTATUS
911 NTAPI
912 RawChannelDestroy(
913     IN PSAC_CHANNEL Channel
914 );
915 
916 NTSTATUS
917 NTAPI
918 RawChannelORead(
919     IN PSAC_CHANNEL Channel,
920     IN PCHAR Buffer,
921     IN ULONG BufferSize,
922     OUT PULONG ByteCount
923 );
924 
925 NTSTATUS
926 NTAPI
927 RawChannelOEcho(
928     IN PSAC_CHANNEL Channel,
929     IN PCHAR String,
930     IN ULONG Length
931 );
932 
933 NTSTATUS
934 NTAPI
935 RawChannelOFlush(
936     IN PSAC_CHANNEL Channel
937 );
938 
939 NTSTATUS
940 NTAPI
941 RawChannelOWrite(
942     IN PSAC_CHANNEL Channel,
943     IN PCHAR String,
944     IN ULONG Length
945 );
946 
947 NTSTATUS
948 NTAPI
949 RawChannelIRead(
950     IN PSAC_CHANNEL Channel,
951     IN PCHAR Buffer,
952     IN ULONG BufferSize,
953     IN PULONG ReturnBufferSize
954 );
955 
956 NTSTATUS
957 NTAPI
958 RawChannelIBufferIsFull(
959     IN PSAC_CHANNEL Channel,
960     OUT PBOOLEAN BufferStatus
961 );
962 
963 ULONG
964 NTAPI
965 RawChannelIBufferLength(
966     IN PSAC_CHANNEL Channel
967 );
968 
969 WCHAR
970 NTAPI
971 RawChannelIReadLast(
972     IN PSAC_CHANNEL Channel
973 );
974 
975 NTSTATUS
976 NTAPI
977 RawChannelIWrite(
978     IN PSAC_CHANNEL Channel,
979     IN PCHAR Buffer,
980     IN ULONG BufferSize
981 );
982 
983 //
984 // VT-UTF8 Channel Table
985 //
986 NTSTATUS
987 NTAPI
988 VTUTF8ChannelCreate(
989     IN PSAC_CHANNEL Channel
990 );
991 
992 NTSTATUS
993 NTAPI
994 VTUTF8ChannelDestroy(
995     IN PSAC_CHANNEL Channel
996 );
997 
998 NTSTATUS
999 NTAPI
1000 VTUTF8ChannelORead(
1001     IN PSAC_CHANNEL Channel,
1002     IN PCHAR Buffer,
1003     IN ULONG BufferSize,
1004     OUT PULONG ByteCount
1005 );
1006 
1007 NTSTATUS
1008 NTAPI
1009 VTUTF8ChannelOEcho(
1010     IN PSAC_CHANNEL Channel,
1011     IN PCHAR String,
1012     IN ULONG Length
1013 );
1014 
1015 NTSTATUS
1016 NTAPI
1017 VTUTF8ChannelOFlush(
1018     IN PSAC_CHANNEL Channel
1019 );
1020 
1021 NTSTATUS
1022 NTAPI
1023 VTUTF8ChannelOWrite(
1024     IN PSAC_CHANNEL Channel,
1025     IN PCHAR String,
1026     IN ULONG Length
1027 );
1028 
1029 NTSTATUS
1030 NTAPI
1031 VTUTF8ChannelIRead(
1032     IN PSAC_CHANNEL Channel,
1033     IN PCHAR Buffer,
1034     IN ULONG BufferSize,
1035     IN PULONG ReturnBufferSize
1036 );
1037 
1038 NTSTATUS
1039 NTAPI
1040 VTUTF8ChannelIBufferIsFull(
1041     IN PSAC_CHANNEL Channel,
1042     OUT PBOOLEAN BufferStatus
1043 );
1044 
1045 ULONG
1046 NTAPI
1047 VTUTF8ChannelIBufferLength(
1048     IN PSAC_CHANNEL Channel
1049 );
1050 
1051 WCHAR
1052 NTAPI
1053 VTUTF8ChannelIReadLast(
1054     IN PSAC_CHANNEL Channel
1055 );
1056 
1057 NTSTATUS
1058 NTAPI
1059 VTUTF8ChannelIWrite(
1060     IN PSAC_CHANNEL Channel,
1061     IN PCHAR Buffer,
1062     IN ULONG BufferSize
1063 );
1064 
1065 
1066 //
1067 // Helper Routines
1068 //
1069 BOOLEAN
1070 NTAPI
1071 SacTranslateUtf8ToUnicode(
1072     IN CHAR Utf8Char,
1073     IN PCHAR Utf8Buffer,
1074     OUT PWCHAR Utf8Value
1075 );
1076 
1077 ULONG
1078 NTAPI
1079 GetMessageLineCount(
1080     IN ULONG MessageIndex
1081 );
1082 
1083 NTSTATUS
1084 NTAPI
1085 SerialBufferGetChar(
1086     OUT PCHAR Char
1087 );
1088 
1089 NTSTATUS
1090 NTAPI
1091 UTF8EncodeAndSend(
1092     IN PWCHAR String
1093 );
1094 
1095 NTSTATUS
1096 NTAPI
1097 TranslateMachineInformationXML(
1098     IN PWCHAR *Buffer,
1099     IN PWCHAR ExtraData
1100 );
1101 
1102 PWCHAR
1103 NTAPI
1104 GetMessage(
1105     IN ULONG MessageIndex
1106 );
1107 
1108 BOOLEAN
1109 NTAPI
1110 VerifyEventWaitable(
1111     IN HANDLE Handle,
1112     OUT PVOID *WaitObject,
1113     OUT PVOID *ActualWaitObject
1114 );
1115 
1116 BOOLEAN
1117 NTAPI
1118 SacTranslateUnicodeToUtf8(
1119     IN PWCHAR SourceBuffer,
1120     IN ULONG SourceBufferLength,
1121     OUT PCHAR DestinationBuffer,
1122     IN ULONG DestinationBufferSize,
1123     OUT PULONG UTF8Count,
1124     OUT PULONG ProcessedCount
1125 );
1126 
1127 //
1128 // SAC Command Functions
1129 //
1130 VOID
1131 NTAPI
1132 DoRebootCommand(
1133     IN BOOLEAN Reboot
1134 );
1135 
1136 VOID
1137 NTAPI
1138 DoFullInfoCommand(
1139     VOID
1140 );
1141 
1142 VOID
1143 NTAPI
1144 DoPagingCommand(
1145     VOID
1146 );
1147 
1148 VOID
1149 NTAPI
1150 DoSetTimeCommand(
1151     IN PCHAR InputTime
1152 );
1153 
1154 VOID
1155 NTAPI
1156 DoKillCommand(
1157     IN PCHAR KillString
1158 );
1159 
1160 VOID
1161 NTAPI
1162 DoLowerPriorityCommand(
1163     IN PCHAR PrioString
1164 );
1165 
1166 VOID
1167 NTAPI
1168 DoRaisePriorityCommand(
1169     IN PCHAR PrioString
1170 );
1171 
1172 VOID
1173 NTAPI
1174 DoLimitMemoryCommand(
1175     IN PCHAR LimitString
1176 );
1177 
1178 VOID
1179 NTAPI
1180 DoCrashCommand(
1181     VOID
1182 );
1183 
1184 VOID
1185 NTAPI
1186 DoMachineInformationCommand(
1187     VOID
1188 );
1189 
1190 VOID
1191 NTAPI
1192 DoChannelCommand(
1193     IN PCHAR ChannelString
1194 );
1195 
1196 VOID
1197 NTAPI
1198 DoCmdCommand(
1199     IN PCHAR InputString
1200 );
1201 
1202 VOID
1203 NTAPI
1204 DoLockCommand(
1205     VOID
1206 );
1207 
1208 VOID
1209 NTAPI
1210 DoHelpCommand(
1211     VOID
1212 );
1213 
1214 VOID
1215 NTAPI
1216 DoGetNetInfo(
1217     IN BOOLEAN DoPrint
1218 );
1219 
1220 VOID
1221 NTAPI
1222 DoSetIpAddressCommand(
1223     IN PCHAR IpString
1224 );
1225 
1226 VOID
1227 NTAPI
1228 DoTlistCommand(
1229     VOID
1230 );
1231 
1232 //
1233 // External data
1234 //
1235 extern ULONG SACDebug;
1236 extern PSAC_MESSAGE_ENTRY GlobalMessageTable;
1237 extern KMUTEX CurrentChannelLock;
1238 extern LONG CurrentChannelRefCount;
1239 extern PCHAR SerialPortBuffer;
1240 extern LONG SerialPortConsumerIndex, SerialPortProducerIndex;
1241 extern PCHAR Utf8ConversionBuffer;
1242 extern BOOLEAN GlobalPagingNeeded, GlobalDoThreads;
1243 extern ULONG Utf8ConversionBufferSize;
1244 extern BOOLEAN CommandConsoleLaunchingEnabled;
1245 
1246 //
1247 // Function to initialize a SAC Semaphore Lock
1248 //
1249 FORCEINLINE
1250 VOID
1251 SacInitializeLock(IN PSAC_CHANNEL_LOCK Lock)
1252 {
1253     KeInitializeSemaphore(&Lock->Lock, 1, 1);
1254 }
1255 
1256 //
1257 // Function to acquire a SAC Semaphore Lock
1258 //
1259 FORCEINLINE
1260 VOID
1261 SacAcquireLock(IN PSAC_CHANNEL_LOCK Lock)
1262 {
1263     KeWaitForSingleObject(&Lock->Lock, Executive, KernelMode, FALSE, NULL);
1264     ASSERT(Lock->RefCount == 0);
1265     _InterlockedIncrement(&Lock->RefCount);
1266 }
1267 
1268 //
1269 // Function to release a SAC Semaphore Lock
1270 //
1271 FORCEINLINE
1272 VOID
1273 SacReleaseLock(IN PSAC_CHANNEL_LOCK Lock)
1274 {
1275     ASSERT(Lock->RefCount == 1);
1276     _InterlockedDecrement(&Lock->RefCount);
1277     KeReleaseSemaphore(&Lock->Lock, SEMAPHORE_INCREMENT, 1, FALSE);
1278 }
1279 
1280 //
1281 // Function to check if the SAC Mutex Lock is held
1282 //
1283 FORCEINLINE
1284 VOID
1285 SacAssertMutexLockHeld(VOID)
1286 {
1287     ASSERT(CurrentChannelRefCount == 1);
1288     ASSERT(KeReadStateMutex(&CurrentChannelLock) == 0);
1289 }
1290 
1291 //
1292 // Function to check if the SAC Mutex Lock is held
1293 //
1294 FORCEINLINE
1295 VOID
1296 SacInitializeMutexLock(VOID)
1297 {
1298     KeInitializeMutex(&CurrentChannelLock, 0);
1299     CurrentChannelRefCount = 0;
1300 }
1301 
1302 //
1303 // Function to acquire the SAC Mutex Lock
1304 //
1305 FORCEINLINE
1306 VOID
1307 SacAcquireMutexLock(VOID)
1308 {
1309     KeWaitForSingleObject(&CurrentChannelLock, Executive, KernelMode, FALSE, NULL);
1310     ASSERT(CurrentChannelRefCount == 0);
1311     _InterlockedIncrement(&CurrentChannelRefCount);
1312 }
1313 
1314 //
1315 // Function to release the SAC Mutex Lock
1316 //
1317 FORCEINLINE
1318 VOID
1319 SacReleaseMutexLock(VOID)
1320 {
1321     ASSERT(CurrentChannelRefCount == 1);
1322     _InterlockedDecrement(&CurrentChannelRefCount);
1323     KeReleaseMutex(&CurrentChannelLock, FALSE);
1324 }
1325 
1326 //
1327 // Locking Macros
1328 //
1329 #define ChannelLockCreates()            SacAcquireLock(&ChannelCreateLock);
1330 #define ChannelUnlockCreates()          SacReleaseLock(&ChannelCreateLock);
1331 #define ChannelLockOBuffer(x)           SacAcquireLock(&x->ChannelOBufferLock);
1332 #define ChannelUnlockOBuffer(x)         SacReleaseLock(&x->ChannelOBufferLock);
1333 #define ChannelLockIBuffer(x)           SacAcquireLock(&x->ChannelIBufferLock);
1334 #define ChannelUnlockIBuffer(x)         SacReleaseLock(&x->ChannelIBufferLock);
1335 #define ChannelLockAttributes(x)        SacAcquireLock(&x->ChannelAttributeLock);
1336 #define ChannelUnlockAttributes(x)      SacReleaseLock(&x->ChannelAttributeLock);
1337 #define ChannelSlotLock(x)              SacAcquireLock(&ChannelSlotLock[x]);
1338 #define ChannelSlotUnlock(x)            SacReleaseLock(&ChannelSlotLock[x]);
1339 
1340 //
1341 // Channel Accessors
1342 //
1343 FORCEINLINE
1344 ULONG
1345 ChannelGetFlags(IN PSAC_CHANNEL Channel)
1346 {
1347     return Channel->Flags;
1348 }
1349 
1350 FORCEINLINE
1351 LONG
1352 ChannelGetIndex(IN PSAC_CHANNEL Channel)
1353 {
1354     /* Return the index of the channel */
1355     return Channel->Index;
1356 }
1357 
1358 FORCEINLINE
1359 BOOLEAN
1360 ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel)
1361 {
1362     /* Return if there's any new data in the input buffer */
1363     return Channel->ChannelHasNewIBufferData;
1364 }
1365 
1366 //
1367 // FIXME: ANSI.H
1368 //
1369 //
1370 // Source: http://en.wikipedia.org/wiki/ANSI_escape_code
1371 //
1372 typedef enum _VT_ANSI_ATTRIBUTES
1373 {
1374     //
1375     // Attribute modifiers (mostly supported)
1376     //
1377     Normal,
1378     Bold,
1379     Faint,
1380     Italic,
1381     Underline,
1382     SlowBlink,
1383     FastBlink,
1384     Inverse,
1385     Conceal,
1386     Strikethrough,
1387 
1388     //
1389     // Font selectors (not supported)
1390     //
1391     PrimaryFont,
1392     AlternateFont1,
1393     AlternateFont2,
1394     AlternateFont3,
1395     Alternatefont4,
1396     AlternateFont5,
1397     AlternateFont6,
1398     AlternateFont7,
1399     AlternateFont8,
1400     AlternateFont9,
1401 
1402     //
1403     // Additional attributes (not supported)
1404     //
1405     Fraktur,
1406     DoubleUnderline,
1407 
1408     //
1409     // Attribute Un-modifiers (mostly supported)
1410     //
1411     BoldOff,
1412     ItalicOff,
1413     UnderlineOff,
1414     BlinkOff,
1415     Reserved,
1416     InverseOff,
1417     ConcealOff,
1418     StrikethroughOff,
1419 
1420     //
1421     // Standard Text Color
1422     //
1423     SetColorStart,
1424     SetColorBlack = SetColorStart,
1425     SetColorRed,
1426     SetColorGreen,
1427     SetColorYellow,
1428     SetColorBlue,
1429     SetcolorMAgent,
1430     SetColorCyan,
1431     SetColorWhite,
1432     SetColorMax = SetColorWhite,
1433 
1434     //
1435     // Extended Text Color (not supported)
1436     //
1437     SetColor256,
1438     SeTextColorDefault,
1439 
1440     //
1441     // Standard Background Color
1442     //
1443     SetBackColorStart,
1444     SetBackColorBlack = SetBackColorStart,
1445     SetBackColorRed,
1446     SetBackColorGreen,
1447     SetBackColorYellow,
1448     SetBackColorBlue,
1449     SetBackcolorMAgent,
1450     SetBackColorCyan,
1451     SetBackColorWhite,
1452     SetBackColorMax = SetBackColorWhite,
1453 
1454     //
1455     // Extended Background Color (not supported)
1456     //
1457     SetBackColor256,
1458     SetBackColorDefault,
1459 
1460     //
1461     // Extra Attributes (not supported)
1462     //
1463     Reserved1,
1464     Framed,
1465     Encircled,
1466     Overlined,
1467     FramedOff,
1468     OverlinedOff,
1469     Reserved2,
1470     Reserved3,
1471     Reserved4,
1472     Reserved5
1473 
1474     //
1475     // Ideograms (not supported)
1476     //
1477 } VT_ANSI_ATTRIBUTES;
1478 
1479 //
1480 // The following site is a good reference on VT100/ANSI escape codes
1481 // http://www.termsys.demon.co.uk/vtansi.htm
1482 //
1483 #define VT_ANSI_ESCAPE              L'\x1B'
1484 #define VT_ANSI_COMMAND             L'['
1485 
1486 #define VT_ANSI_CURSOR_UP_CHAR      L'A'
1487 #define VT_ANSI_CURSOR_UP           L"[A"
1488 
1489 #define VT_ANSI_CURSOR_DOWN_CHAR    L'B'
1490 #define VT_ANSI_CURSOR_DOWN         L"[B"
1491 
1492 #define VT_ANSI_CURSOR_RIGHT_CHAR   L'C'
1493 #define VT_ANSI_CURSOR_RIGHT        L"[C"
1494 
1495 #define VT_ANSI_CURSOR_LEFT_CHAR    L'D'
1496 #define VT_ANSI_CURSOR_LEFT         L"[D"
1497 
1498 #define VT_ANSI_ERASE_LINE_CHAR     L'K'
1499 #define VT_ANSI_ERASE_END_LINE      L"[K"
1500 #define VT_ANSI_ERASE_START_LINE    L"[1K"
1501 #define VT_ANSI_ERASE_ENTIRE_LINE   L"[2K"
1502 
1503 #define VT_ANSI_ERASE_SCREEN_CHAR   L'J'
1504 #define VT_ANSI_ERASE_DOWN_SCREEN   L"[J"
1505 #define VT_ANSI_ERASE_UP_SCREEN     L"[1J"
1506 #define VT_ANSI_ERASE_ENTIRE_SCREEN L"[2J"
1507 
1508 #define VT_ANSI_BACKTAB_CHAR        L'Z'
1509 #define VT_220_BACKTAB              L"[0Z"
1510 
1511 #define VT_ANSI_SET_ATTRIBUTE_CHAR  L'm'
1512 #define VT_ANSI_SEPARATOR_CHAR      L';'
1513 #define VT_ANSI_HVP_CURSOR_CHAR     L'f'
1514 #define VT_ANSI_CUP_CURSOR_CHAR     L'H'
1515 #define VT_ANSI_SCROLL_CHAR         L'r'
1516 
1517 #endif /* _SACDRV_H_ */
1518