reactos/drivers/sac/driver/sacdrv.h
Thomas Faber 4be3bc682d
[SACDRV] Fix uninitialized variable usage.
Powered by clang-cl.
2021-10-27 19:27:32 -04:00

1519 lines
29 KiB
C

/*
* PROJECT: ReactOS Drivers
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: drivers/sac/driver/sacdrv.h
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
* PROGRAMMERS: ReactOS Portable Systems Group
*/
#ifndef _SACDRV_H_
#define _SACDRV_H_
/* INCLUDES *******************************************************************/
#include <ntifs.h>
#include <stdio.h>
#include <ntoskrnl/include/internal/hdl.h>
#include <sacmsg.h>
/* DEFINES ********************************************************************/
//
// SAC Heap Allocator Macros
//
#define SacAllocatePool(Length, Tag) \
MyAllocatePool(Length, Tag, __FILE__, __LINE__)
#define SacFreePool(Pointer) \
MyFreePool((PVOID*)(&Pointer))
//
// SAC Debugging Macro and Constants
//
#define SAC_DBG_ENTRY_EXIT 0x01
#define SAC_DBG_UTIL 0x02
#define SAC_DBG_INIT 0x04
#define SAC_DBG_MM 0x1000
#define SAC_DBG_MACHINE 0x2000
#define SAC_DBG(x, ...) \
if (SACDebug & x) \
{ \
DbgPrint("SAC %s: ", __FUNCTION__); \
DbgPrint(__VA_ARGS__); \
}
//
// SAC Parameter Checking Macros
//
#define CHECK_PARAMETER_WITH_STATUS(Condition, Status) \
{ \
if (!NT_VERIFY(Condition)) \
{ \
return Status; \
} \
}
#define CHECK_PARAMETER(x) \
CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER)
#define CHECK_PARAMETER1(x) \
CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_1)
#define CHECK_PARAMETER2(x) \
CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_2)
#define CHECK_PARAMETER3(x) \
CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_3)
#define CHECK_PARAMETER4(x) \
CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_4)
#define CHECK_ALLOCATION(x) \
CHECK_PARAMETER_WITH_STATUS(x, STATUS_NO_MEMORY)
//
// SAC Channel Event Macros
//
#define ChannelInitializeEvent(Channel, Attributes, x) \
{ \
PVOID Object, WaitObject; \
if (Attributes->x) \
{ \
if (!VerifyEventWaitable(Attributes->x, &Object, &WaitObject)) \
{ \
Status = STATUS_INVALID_HANDLE; \
goto FailChannel; \
} \
Channel->x = Attributes->x; \
Channel->x##ObjectBody = Object; \
Channel->x##WaitObjectBody = WaitObject; \
} \
}
#define ChannelUninitializeEvent(Channel, x, f) \
{ \
ASSERT(ChannelGetFlags(Channel) & (f)); \
ASSERT(Channel->x##ObjectBody); \
ASSERT(Channel->x##WaitObjectBody); \
if (Channel->x##ObjectBody) \
{ \
ObDereferenceObject(Channel->x##ObjectBody); \
Channel->Flags &= ~(f); \
Channel->x = NULL; \
Channel->x##ObjectBody = NULL; \
Channel->x##WaitObjectBody = NULL; \
} \
}
#define ChannelSetEvent(Channel, x) \
{ \
ASSERT(Channel->x); \
ASSERT(Channel->x##ObjectBody); \
ASSERT(Channel->x##WaitObjectBody); \
if (Channel->x##WaitObjectBody) \
{ \
KeSetEvent(Channel->x##WaitObjectBody, EVENT_INCREMENT, FALSE); \
Status = STATUS_SUCCESS; \
} \
else \
{ \
Status = STATUS_UNSUCCESSFUL; \
} \
}
#define ChannelClearEvent(Channel, x) \
{ \
ASSERT(Channel->x); \
ASSERT(Channel->x##ObjectBody); \
ASSERT(Channel->x##WaitObjectBody); \
if (Channel->x##WaitObjectBody) \
{ \
KeClearEvent(Channel->x##WaitObjectBody); \
Status = STATUS_SUCCESS; \
} \
else \
{ \
Status = STATUS_UNSUCCESSFUL; \
} \
}
//
// SAC Pool Tags, taken from pooltag.txt:
//
// Rcp? - sacdrv.sys - SAC Driver (Headless)
// RcpA - sacdrv.sys - Internal memory mgr alloc block
// RcpI - sacdrv.sys - Internal memory mgr initial heap block
// RcpS - sacdrv.sys - Security related block
#define GENERIC_TAG '?pcR'
#define ALLOC_BLOCK_TAG 'ApcR'
#define INITIAL_BLOCK_TAG 'IpcR'
#define SECURITY_BLOCK_TAG 'SpcR'
#define FREE_POOL_TAG 'FpcR'
#define GLOBAL_BLOCK_TAG 'GpcR'
#define CHANNEL_BLOCK_TAG 'CpcR'
#define LOCAL_MEMORY_SIGNATURE 'SSEL'
#define GLOBAL_MEMORY_SIGNATURE 'DAEH'
//
// Size Definitions
//
#define SAC_MEMORY_LIST_SIZE (1 * 1024 * 1024) // 1MB
#define SAC_OBUFFER_SIZE (2 * 1024) // 2KB
#define SAC_CHANNEL_NAME_SIZE 64
#define SAC_CHANNEL_DESCRIPTION_SIZE 256
#define SAC_MAX_CHANNELS 10
#define SAC_SERIAL_PORT_BUFFER_SIZE 1024 // 1KB
#define SAC_MAX_MESSAGES 200
#define SAC_VTUTF8_COL_WIDTH 80
#define SAC_VTUTF8_COL_HEIGHT 25
#define SAC_VTUTF8_ROW_HEIGHT 24
#define MAX_UTF8_ENCODE_BLOCK_LENGTH (Utf8ConversionBufferSize / 3 - 1)
#define SAC_VTUTF8_OBUFFER_SIZE 0x2D00
#define SAC_VTUTF8_IBUFFER_SIZE 0x2000
#define SAC_RAW_OBUFFER_SIZE 0x2000
#define SAC_RAW_IBUFFER_SIZE 0x2000
//
// Channel flags
//
#define SAC_CHANNEL_FLAG_INTERNAL 0x1
#define SAC_CHANNEL_FLAG_CLOSE_EVENT 0x2
#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT 0x4
#define SAC_CHANNEL_FLAG_LOCK_EVENT 0x8
#define SAC_CHANNEL_FLAG_REDRAW_EVENT 0x10
#define SAC_CHANNEL_FLAG_APPLICATION 0x20
//
// Cell Flags
//
#define SAC_CELL_FLAG_BLINK 1
#define SAC_CELL_FLAG_BOLD 2
#define SAC_CELL_FLAG_INVERTED 4
//
// Forward definitions
//
struct _SAC_CHANNEL;
//
// Structures used by the SAC Heap Allocator
//
typedef struct _SAC_MEMORY_ENTRY
{
ULONG Signature;
ULONG Tag;
ULONG Size;
} SAC_MEMORY_ENTRY, *PSAC_MEMORY_ENTRY;
typedef struct _SAC_MEMORY_LIST
{
ULONG Signature;
PSAC_MEMORY_ENTRY LocalDescriptor;
ULONG Size;
struct _SAC_MEMORY_LIST* Next;
} SAC_MEMORY_LIST, *PSAC_MEMORY_LIST;
typedef struct _SAC_MESSAGE_ENTRY
{
ULONG Index;
PWCHAR Buffer;
} SAC_MESSAGE_ENTRY, *PSAC_MESSAGE_ENTRY;
//
// These are the VT-100/220/ANSI Escape Codes supported by SAC as input
//
typedef enum _SAC_ANSI_COMMANDS
{
SacCursorUp,
SacCursorDown,
SacCursorRight,
SacCursorLeft,
SacFontNormal,
SacFontBlink,
SacFontBlinkOff,
SacFontBold,
SacFontBoldOff,
SacFontInverse,
SacFontInverseOff,
SacBackTab,
SacEraseEndOfLine,
SacEraseStartOfLine,
SacEraseLine,
SacEraseEndOfScreen,
SacEraseStartOfScreen,
SacEraseScreen,
SacSetCursorPosition,
SacSetScrollRegion,
SacSetColors,
SacSetBackgroundColor,
SacSetFontColor,
SacSetColorsAndAttributes
} SAC_ANSI_COMMANDS;
//
// These are the VT-100/220/ANSI Escape Codes send by SAC as output
//
typedef enum _SAC_ANSI_DISPATCH
{
SacAnsiClearScreen,
SacAnsiClearEndOfScreen,
SacAnsiClearEndOfLine,
SacAnsiSetColors,
SacAnsiSetPosition,
SacAnsiClearAttributes,
SacAnsiSetInverseAttribute,
SacAnsiClearInverseAttribute,
SacAnsiSetBlinkAttribute,
SacAnsiClearBlinkAttribute,
SacAnsiSetBoldAttribute,
SacAnsiClearBoldAttribute
} SAC_ANSI_DISPATCH;
//
// Commands that the consumer and producer share
//
typedef enum _SAC_POST_COMMANDS
{
Nothing,
Shutdown,
Close,
Restart
} SAC_POST_COMMANDS;
//
// SAC supports 3 different channel output types
//
typedef enum _SAC_CHANNEL_TYPE
{
VtUtf8,
Cmd,
Raw
} SAC_CHANNEL_TYPE;
//
// A SAC channel can be active or inactive
//
typedef enum _SAC_CHANNEL_STATUS
{
Inactive,
Active
} SAC_CHANNEL_STATUS, *PSAC_CHANNEL_STATUS;
//
// A SAC channel identifier
//
typedef struct _SAC_CHANNEL_ID
{
GUID ChannelGuid;
ULONG ChannelId;
} SAC_CHANNEL_ID, *PSAC_CHANNEL_ID;
//
// Reference-counted SAC channel semaphore lock
//
typedef struct _SAC_CHANNEL_LOCK
{
LONG RefCount;
KSEMAPHORE Lock;
} SAC_CHANNEL_LOCK, *PSAC_CHANNEL_LOCK;
//
// Structure of the cell-buffer when in VT-UTF8 Mode
//
typedef struct _SAC_CELL_DATA
{
UCHAR CellBackColor;
UCHAR CellForeColor;
UCHAR CellFlags;
WCHAR Char;
} SAC_CELL_DATA, *PSAC_CELL_DATA;
C_ASSERT(sizeof(SAC_CELL_DATA) == 6);
//
// Screen buffer when in VT-UTF8 Mode
//
typedef struct _SAC_VTUTF8_SCREEN
{
SAC_CELL_DATA Cell[SAC_VTUTF8_ROW_HEIGHT][SAC_VTUTF8_COL_WIDTH];
} SAC_VTUTF8_SCREEN, *PSAC_VTUTF8_SCREEN;
//
// Small optimization to easily recognize the most common VT-100/ANSI codes
//
typedef struct _SAC_STATIC_ESCAPE_STRING
{
WCHAR Sequence[10];
ULONG Size;
ULONG Action;
} SAC_STATIC_ESCAPE_STRING, *PSAC_STATIC_ESCAPE_STRING;
//
// Channel callbacks
//
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_CREATE)(
IN struct _SAC_CHANNEL* Channel
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_DESTROY)(
IN struct _SAC_CHANNEL* Channel
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_OREAD)(
IN struct _SAC_CHANNEL* Channel,
IN PCHAR Buffer,
IN ULONG BufferSize,
OUT PULONG ByteCount
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_OECHO)(
IN struct _SAC_CHANNEL* Channel,
IN PCHAR String,
IN ULONG Length
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_OFLUSH)(
IN struct _SAC_CHANNEL* Channel
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_OWRITE)(
IN struct _SAC_CHANNEL* Channel,
IN PCHAR String,
IN ULONG Length
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_IREAD)(
IN struct _SAC_CHANNEL* Channel,
IN PCHAR Buffer,
IN ULONG BufferSize,
IN PULONG ReturnBufferSize
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_IBUFFER_FULL)(
IN struct _SAC_CHANNEL* Channel,
OUT PBOOLEAN BufferStatus
);
typedef
ULONG
(NTAPI *PSAC_CHANNEL_IBUFFER_LENGTH)(
IN struct _SAC_CHANNEL* Channel
);
typedef
WCHAR
(NTAPI *PSAC_CHANNEL_IREAD_LAST)(
IN struct _SAC_CHANNEL* Channel
);
typedef
NTSTATUS
(NTAPI *PSAC_CHANNEL_IWRITE)(
IN struct _SAC_CHANNEL* Channel,
IN PCHAR Buffer,
IN ULONG BufferSize
);
//
// A channel and its attributes
//
typedef struct _SAC_CHANNEL
{
LONG Index;
SAC_CHANNEL_ID ChannelId;
HANDLE CloseEvent;
PVOID CloseEventObjectBody;
PKEVENT CloseEventWaitObjectBody;
HANDLE HasNewDataEvent;
PVOID HasNewDataEventObjectBody;
PKEVENT HasNewDataEventWaitObjectBody;
HANDLE LockEvent;
PVOID LockEventObjectBody;
PKEVENT LockEventWaitObjectBody;
HANDLE RedrawEvent;
PVOID RedrawEventObjectBody;
PKEVENT RedrawEventWaitObjectBody;
PFILE_OBJECT FileObject;
SAC_CHANNEL_TYPE ChannelType;
SAC_CHANNEL_STATUS ChannelStatus;
WCHAR NameBuffer[SAC_CHANNEL_NAME_SIZE + 1];
WCHAR DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE + 1];
ULONG Flags;
GUID ApplicationType;
LONG WriteEnabled;
ULONG IBufferIndex;
PCHAR IBuffer;
LONG ChannelHasNewIBufferData;
UCHAR CursorRow;
UCHAR CursorCol;
UCHAR CellForeColor;
UCHAR CellBackColor;
UCHAR CellFlags;
PCHAR OBuffer;
ULONG OBufferIndex;
ULONG OBufferFirstGoodIndex;
LONG ChannelHasNewOBufferData;
PSAC_CHANNEL_CREATE ChannelCreate;
PSAC_CHANNEL_DESTROY ChannelDestroy;
PSAC_CHANNEL_OFLUSH ChannelOutputFlush;
PSAC_CHANNEL_OECHO ChannelOutputEcho;
PSAC_CHANNEL_OWRITE ChannelOutputWrite;
PSAC_CHANNEL_OREAD ChannelOutputRead;
PSAC_CHANNEL_IWRITE ChannelInputWrite;
PSAC_CHANNEL_IREAD ChannelInputRead;
PSAC_CHANNEL_IREAD_LAST ChannelInputReadLast;
PSAC_CHANNEL_IBUFFER_FULL ChannelInputBufferIsFull;
PSAC_CHANNEL_IBUFFER_LENGTH ChannelInputBufferLength;
SAC_CHANNEL_LOCK ChannelAttributeLock;
SAC_CHANNEL_LOCK ChannelOBufferLock;
SAC_CHANNEL_LOCK ChannelIBufferLock;
} SAC_CHANNEL, *PSAC_CHANNEL;
typedef struct _SAC_CHANNEL_ATTRIBUTES
{
SAC_CHANNEL_TYPE ChannelType;
WCHAR NameBuffer[SAC_CHANNEL_NAME_SIZE + 1];
WCHAR DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE + 1];
ULONG Flag;
HANDLE CloseEvent;
HANDLE HasNewDataEvent;
HANDLE LockEvent;
HANDLE RedrawEvent;
GUID ChannelId;
} SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES;
//
// Cached Machine Information
//
typedef struct _SAC_MACHINE_INFO
{
PWCHAR MachineName;
PWCHAR MachineGuid;
PWCHAR ProcessorArchitecture;
PWCHAR MajorVersion;
PWCHAR BuildNumber;
PWCHAR ProductType;
PWCHAR ServicePack;
} SAC_MACHINE_INFO, *PSAC_MACHINE_INFO;
//
// The device extension for the SAC
//
typedef struct _SAC_DEVICE_EXTENSION
{
PDEVICE_OBJECT DeviceObject;
BOOLEAN Initialized;
BOOLEAN Rundown;
BOOLEAN PriorityFail;
BOOLEAN RundownInProgress;
KPRIORITY PriorityBoost;
PEPROCESS Process;
KSPIN_LOCK Lock;
KEVENT RundownEvent;
KEVENT Event;
HANDLE WorkerThreadHandle;
KEVENT WorkerThreadEvent;
KTIMER Timer;
KDPC Dpc;
LIST_ENTRY List;
} SAC_DEVICE_EXTENSION, *PSAC_DEVICE_EXTENSION;
//
// Dispatch Routines
//
NTSTATUS
NTAPI
Dispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
NTAPI
DispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
NTAPI
DispatchShutdownControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
NTAPI
UnloadHandler(
IN PDRIVER_OBJECT DriverObject
);
//
// Initialization and shutdown routines
//
VOID
NTAPI
FreeGlobalData(
VOID
);
VOID
NTAPI
FreeDeviceData(
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
InitializeDeviceData(
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
InitializeGlobalData(
IN PUNICODE_STRING RegistryPath,
IN PDRIVER_OBJECT DriverObject
);
BOOLEAN
NTAPI
InitializeMemoryManagement(
VOID
);
VOID
NTAPI
FreeMemoryManagement(
VOID
);
VOID
NTAPI
InitializeCmdEventInfo(
VOID
);
VOID
NTAPI
InitializeMachineInformation(
VOID
);
NTSTATUS
NTAPI
PreloadGlobalMessageTable(
IN PVOID ImageBase
);
NTSTATUS
NTAPI
TearDownGlobalMessageTable(
VOID
);
NTSTATUS
NTAPI
GetCommandConsoleLaunchingPermission(
OUT PBOOLEAN Permission
);
NTSTATUS
NTAPI
ImposeSacCmdServiceStartTypePolicy(
VOID
);
NTSTATUS
NTAPI
RegisterBlueScreenMachineInformation(
VOID
);
VOID
NTAPI
FreeMachineInformation(
VOID
);
//
// DPC, Timer, Thread Callbacks
//
VOID
NTAPI
TimerDpcRoutine(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
//
// Custom SAC Heap Allocator Routines
//
PVOID
NTAPI
MyAllocatePool(
IN SIZE_T PoolSize,
IN ULONG Tag,
IN PCHAR File,
IN ULONG Line
);
VOID
NTAPI
MyFreePool(
IN PVOID *Block
);
//
// Connection Manager Routines
//
NTSTATUS
NTAPI
ConMgrInitialize(
VOID
);
VOID
NTAPI
ConMgrWorkerProcessEvents(
IN PSAC_DEVICE_EXTENSION DeviceExtension
);
NTSTATUS
NTAPI
ConMgrShutdown(
VOID
);
BOOLEAN
NTAPI
ConMgrSimpleEventMessage(
IN ULONG MessageIndex,
IN BOOLEAN LockHeld
);
BOOLEAN
NTAPI
SacPutSimpleMessage(
IN ULONG MessageIndex
);
VOID
NTAPI
SacPutString(
IN PWCHAR String
);
NTSTATUS
NTAPI
ConMgrWriteData(
IN PSAC_CHANNEL Channel,
IN PVOID Buffer,
IN ULONG BufferLength
);
NTSTATUS
NTAPI
ConMgrFlushData(
IN PSAC_CHANNEL Channel
);
BOOLEAN
NTAPI
ConMgrIsWriteEnabled(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ConMgrHandleEvent(
IN ULONG EventCode,
IN PSAC_CHANNEL Channel,
OUT PVOID Data
);
//
// Channel Manager Routines
//
NTSTATUS
NTAPI
ChanMgrInitialize(
VOID
);
NTSTATUS
NTAPI
ChanMgrShutdown(
VOID
);
NTSTATUS
NTAPI
ChanMgrCreateChannel(
OUT PSAC_CHANNEL *Channel,
IN PSAC_CHANNEL_ATTRIBUTES Attributes
);
NTSTATUS
NTAPI
ChanMgrGetByHandle(
IN SAC_CHANNEL_ID ChannelId,
OUT PSAC_CHANNEL* TargetChannel
);
NTSTATUS
NTAPI
ChanMgrReleaseChannel(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ChanMgrGetNextActiveChannel(
IN PSAC_CHANNEL CurrentChannel,
IN PULONG TargetIndex,
OUT PSAC_CHANNEL *TargetChannel
);
NTSTATUS
NTAPI
ChanMgrCloseChannel(
IN PSAC_CHANNEL Channel
);
//
// Channel Routines
//
NTSTATUS
NTAPI
ChannelClose(
IN PSAC_CHANNEL Channel
);
BOOLEAN
NTAPI
ChannelIsEqual(
IN PSAC_CHANNEL Channel,
IN PSAC_CHANNEL_ID ChannelId
);
NTSTATUS
NTAPI
ChannelOWrite(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize
);
NTSTATUS
NTAPI
ChannelOFlush(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ChannelSetRedrawEvent(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ChannelClearRedrawEvent(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ChannelHasRedrawEvent(
IN PSAC_CHANNEL Channel,
OUT PBOOLEAN Present
);
BOOLEAN
NTAPI
ChannelIsActive(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ChannelGetName(
IN PSAC_CHANNEL Channel,
OUT PWCHAR *Name
);
BOOLEAN
NTAPI
ChannelIsEqual(
IN PSAC_CHANNEL Channel,
IN PSAC_CHANNEL_ID ChannelId
);
NTSTATUS
NTAPI
ChannelCreate(
IN PSAC_CHANNEL Channel,
IN PSAC_CHANNEL_ATTRIBUTES Attributes,
IN SAC_CHANNEL_ID ChannelId
);
NTSTATUS
NTAPI
ChannelDestroy(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ChannelIWrite(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize
);
WCHAR
NTAPI
ChannelIReadLast(
IN PSAC_CHANNEL Channel
);
ULONG
NTAPI
ChannelIBufferLength(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
ChannelIRead(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize,
IN OUT PULONG ResultBufferSize
);
//
// RAW Channel Table
//
NTSTATUS
NTAPI
RawChannelCreate(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
RawChannelDestroy(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
RawChannelORead(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize,
OUT PULONG ByteCount
);
NTSTATUS
NTAPI
RawChannelOEcho(
IN PSAC_CHANNEL Channel,
IN PCHAR String,
IN ULONG Length
);
NTSTATUS
NTAPI
RawChannelOFlush(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
RawChannelOWrite(
IN PSAC_CHANNEL Channel,
IN PCHAR String,
IN ULONG Length
);
NTSTATUS
NTAPI
RawChannelIRead(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize,
IN PULONG ReturnBufferSize
);
NTSTATUS
NTAPI
RawChannelIBufferIsFull(
IN PSAC_CHANNEL Channel,
OUT PBOOLEAN BufferStatus
);
ULONG
NTAPI
RawChannelIBufferLength(
IN PSAC_CHANNEL Channel
);
WCHAR
NTAPI
RawChannelIReadLast(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
RawChannelIWrite(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize
);
//
// VT-UTF8 Channel Table
//
NTSTATUS
NTAPI
VTUTF8ChannelCreate(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
VTUTF8ChannelDestroy(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
VTUTF8ChannelORead(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize,
OUT PULONG ByteCount
);
NTSTATUS
NTAPI
VTUTF8ChannelOEcho(
IN PSAC_CHANNEL Channel,
IN PCHAR String,
IN ULONG Length
);
NTSTATUS
NTAPI
VTUTF8ChannelOFlush(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
VTUTF8ChannelOWrite(
IN PSAC_CHANNEL Channel,
IN PCHAR String,
IN ULONG Length
);
NTSTATUS
NTAPI
VTUTF8ChannelIRead(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize,
IN PULONG ReturnBufferSize
);
NTSTATUS
NTAPI
VTUTF8ChannelIBufferIsFull(
IN PSAC_CHANNEL Channel,
OUT PBOOLEAN BufferStatus
);
ULONG
NTAPI
VTUTF8ChannelIBufferLength(
IN PSAC_CHANNEL Channel
);
WCHAR
NTAPI
VTUTF8ChannelIReadLast(
IN PSAC_CHANNEL Channel
);
NTSTATUS
NTAPI
VTUTF8ChannelIWrite(
IN PSAC_CHANNEL Channel,
IN PCHAR Buffer,
IN ULONG BufferSize
);
//
// Helper Routines
//
BOOLEAN
NTAPI
SacTranslateUtf8ToUnicode(
IN CHAR Utf8Char,
IN PCHAR Utf8Buffer,
OUT PWCHAR Utf8Value
);
ULONG
NTAPI
GetMessageLineCount(
IN ULONG MessageIndex
);
NTSTATUS
NTAPI
SerialBufferGetChar(
OUT PCHAR Char
);
NTSTATUS
NTAPI
UTF8EncodeAndSend(
IN PWCHAR String
);
NTSTATUS
NTAPI
TranslateMachineInformationXML(
IN PWCHAR *Buffer,
IN PWCHAR ExtraData
);
PWCHAR
NTAPI
GetMessage(
IN ULONG MessageIndex
);
BOOLEAN
NTAPI
VerifyEventWaitable(
IN HANDLE Handle,
OUT PVOID *WaitObject,
OUT PVOID *ActualWaitObject
);
BOOLEAN
NTAPI
SacTranslateUnicodeToUtf8(
IN PWCHAR SourceBuffer,
IN ULONG SourceBufferLength,
OUT PCHAR DestinationBuffer,
IN ULONG DestinationBufferSize,
OUT PULONG UTF8Count,
OUT PULONG ProcessedCount
);
//
// SAC Command Functions
//
VOID
NTAPI
DoRebootCommand(
IN BOOLEAN Reboot
);
VOID
NTAPI
DoFullInfoCommand(
VOID
);
VOID
NTAPI
DoPagingCommand(
VOID
);
VOID
NTAPI
DoSetTimeCommand(
IN PCHAR InputTime
);
VOID
NTAPI
DoKillCommand(
IN PCHAR KillString
);
VOID
NTAPI
DoLowerPriorityCommand(
IN PCHAR PrioString
);
VOID
NTAPI
DoRaisePriorityCommand(
IN PCHAR PrioString
);
VOID
NTAPI
DoLimitMemoryCommand(
IN PCHAR LimitString
);
VOID
NTAPI
DoCrashCommand(
VOID
);
VOID
NTAPI
DoMachineInformationCommand(
VOID
);
VOID
NTAPI
DoChannelCommand(
IN PCHAR ChannelString
);
VOID
NTAPI
DoCmdCommand(
IN PCHAR InputString
);
VOID
NTAPI
DoLockCommand(
VOID
);
VOID
NTAPI
DoHelpCommand(
VOID
);
VOID
NTAPI
DoGetNetInfo(
IN BOOLEAN DoPrint
);
VOID
NTAPI
DoSetIpAddressCommand(
IN PCHAR IpString
);
VOID
NTAPI
DoTlistCommand(
VOID
);
//
// External data
//
extern ULONG SACDebug;
extern PSAC_MESSAGE_ENTRY GlobalMessageTable;
extern KMUTEX CurrentChannelLock;
extern LONG CurrentChannelRefCount;
extern PCHAR SerialPortBuffer;
extern LONG SerialPortConsumerIndex, SerialPortProducerIndex;
extern PCHAR Utf8ConversionBuffer;
extern BOOLEAN GlobalPagingNeeded, GlobalDoThreads;
extern ULONG Utf8ConversionBufferSize;
extern BOOLEAN CommandConsoleLaunchingEnabled;
//
// Function to initialize a SAC Semaphore Lock
//
FORCEINLINE
VOID
SacInitializeLock(IN PSAC_CHANNEL_LOCK Lock)
{
KeInitializeSemaphore(&Lock->Lock, 1, 1);
}
//
// Function to acquire a SAC Semaphore Lock
//
FORCEINLINE
VOID
SacAcquireLock(IN PSAC_CHANNEL_LOCK Lock)
{
KeWaitForSingleObject(&Lock->Lock, Executive, KernelMode, FALSE, NULL);
ASSERT(Lock->RefCount == 0);
_InterlockedIncrement(&Lock->RefCount);
}
//
// Function to release a SAC Semaphore Lock
//
FORCEINLINE
VOID
SacReleaseLock(IN PSAC_CHANNEL_LOCK Lock)
{
ASSERT(Lock->RefCount == 1);
_InterlockedDecrement(&Lock->RefCount);
KeReleaseSemaphore(&Lock->Lock, SEMAPHORE_INCREMENT, 1, FALSE);
}
//
// Function to check if the SAC Mutex Lock is held
//
FORCEINLINE
VOID
SacAssertMutexLockHeld(VOID)
{
ASSERT(CurrentChannelRefCount == 1);
ASSERT(KeReadStateMutex(&CurrentChannelLock) == 0);
}
//
// Function to check if the SAC Mutex Lock is held
//
FORCEINLINE
VOID
SacInitializeMutexLock(VOID)
{
KeInitializeMutex(&CurrentChannelLock, 0);
CurrentChannelRefCount = 0;
}
//
// Function to acquire the SAC Mutex Lock
//
FORCEINLINE
VOID
SacAcquireMutexLock(VOID)
{
KeWaitForSingleObject(&CurrentChannelLock, Executive, KernelMode, FALSE, NULL);
ASSERT(CurrentChannelRefCount == 0);
_InterlockedIncrement(&CurrentChannelRefCount);
}
//
// Function to release the SAC Mutex Lock
//
FORCEINLINE
VOID
SacReleaseMutexLock(VOID)
{
ASSERT(CurrentChannelRefCount == 1);
_InterlockedDecrement(&CurrentChannelRefCount);
KeReleaseMutex(&CurrentChannelLock, FALSE);
}
//
// Locking Macros
//
#define ChannelLockCreates() SacAcquireLock(&ChannelCreateLock);
#define ChannelUnlockCreates() SacReleaseLock(&ChannelCreateLock);
#define ChannelLockOBuffer(x) SacAcquireLock(&x->ChannelOBufferLock);
#define ChannelUnlockOBuffer(x) SacReleaseLock(&x->ChannelOBufferLock);
#define ChannelLockIBuffer(x) SacAcquireLock(&x->ChannelIBufferLock);
#define ChannelUnlockIBuffer(x) SacReleaseLock(&x->ChannelIBufferLock);
#define ChannelLockAttributes(x) SacAcquireLock(&x->ChannelAttributeLock);
#define ChannelUnlockAttributes(x) SacReleaseLock(&x->ChannelAttributeLock);
#define ChannelSlotLock(x) SacAcquireLock(&ChannelSlotLock[x]);
#define ChannelSlotUnlock(x) SacReleaseLock(&ChannelSlotLock[x]);
//
// Channel Accessors
//
FORCEINLINE
ULONG
ChannelGetFlags(IN PSAC_CHANNEL Channel)
{
return Channel->Flags;
}
FORCEINLINE
LONG
ChannelGetIndex(IN PSAC_CHANNEL Channel)
{
/* Return the index of the channel */
return Channel->Index;
}
FORCEINLINE
BOOLEAN
ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel)
{
/* Return if there's any new data in the input buffer */
return Channel->ChannelHasNewIBufferData;
}
//
// FIXME: ANSI.H
//
//
// Source: http://en.wikipedia.org/wiki/ANSI_escape_code
//
typedef enum _VT_ANSI_ATTRIBUTES
{
//
// Attribute modifiers (mostly supported)
//
Normal,
Bold,
Faint,
Italic,
Underline,
SlowBlink,
FastBlink,
Inverse,
Conceal,
Strikethrough,
//
// Font selectors (not supported)
//
PrimaryFont,
AlternateFont1,
AlternateFont2,
AlternateFont3,
Alternatefont4,
AlternateFont5,
AlternateFont6,
AlternateFont7,
AlternateFont8,
AlternateFont9,
//
// Additional attributes (not supported)
//
Fraktur,
DoubleUnderline,
//
// Attribute Un-modifiers (mostly supported)
//
BoldOff,
ItalicOff,
UnderlineOff,
BlinkOff,
Reserved,
InverseOff,
ConcealOff,
StrikethroughOff,
//
// Standard Text Color
//
SetColorStart,
SetColorBlack = SetColorStart,
SetColorRed,
SetColorGreen,
SetColorYellow,
SetColorBlue,
SetcolorMAgent,
SetColorCyan,
SetColorWhite,
SetColorMax = SetColorWhite,
//
// Extended Text Color (not supported)
//
SetColor256,
SeTextColorDefault,
//
// Standard Background Color
//
SetBackColorStart,
SetBackColorBlack = SetBackColorStart,
SetBackColorRed,
SetBackColorGreen,
SetBackColorYellow,
SetBackColorBlue,
SetBackcolorMAgent,
SetBackColorCyan,
SetBackColorWhite,
SetBackColorMax = SetBackColorWhite,
//
// Extended Background Color (not supported)
//
SetBackColor256,
SetBackColorDefault,
//
// Extra Attributes (not supported)
//
Reserved1,
Framed,
Encircled,
Overlined,
FramedOff,
OverlinedOff,
Reserved2,
Reserved3,
Reserved4,
Reserved5
//
// Ideograms (not supported)
//
} VT_ANSI_ATTRIBUTES;
//
// The following site is a good reference on VT100/ANSI escape codes
// http://www.termsys.demon.co.uk/vtansi.htm
//
#define VT_ANSI_ESCAPE L'\x1B'
#define VT_ANSI_COMMAND L'['
#define VT_ANSI_CURSOR_UP_CHAR L'A'
#define VT_ANSI_CURSOR_UP L"[A"
#define VT_ANSI_CURSOR_DOWN_CHAR L'B'
#define VT_ANSI_CURSOR_DOWN L"[B"
#define VT_ANSI_CURSOR_RIGHT_CHAR L'C'
#define VT_ANSI_CURSOR_RIGHT L"[C"
#define VT_ANSI_CURSOR_LEFT_CHAR L'D'
#define VT_ANSI_CURSOR_LEFT L"[D"
#define VT_ANSI_ERASE_LINE_CHAR L'K'
#define VT_ANSI_ERASE_END_LINE L"[K"
#define VT_ANSI_ERASE_START_LINE L"[1K"
#define VT_ANSI_ERASE_ENTIRE_LINE L"[2K"
#define VT_ANSI_ERASE_SCREEN_CHAR L'J'
#define VT_ANSI_ERASE_DOWN_SCREEN L"[J"
#define VT_ANSI_ERASE_UP_SCREEN L"[1J"
#define VT_ANSI_ERASE_ENTIRE_SCREEN L"[2J"
#define VT_ANSI_BACKTAB_CHAR L'Z'
#define VT_220_BACKTAB L"[0Z"
#define VT_ANSI_SET_ATTRIBUTE_CHAR L'm'
#define VT_ANSI_SEPARATOR_CHAR L';'
#define VT_ANSI_HVP_CURSOR_CHAR L'f'
#define VT_ANSI_CUP_CURSOR_CHAR L'H'
#define VT_ANSI_SCROLL_CHAR L'r'
#endif /* _SACDRV_H_ */