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