|
|
/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
channel.h
Abstract:
Common Channel routines.
Author:
Brian Guarraci (briangu) March, 2001.
Revision History:
--*/
#ifndef CHANNEL_H
#define CHANNEL_H
//
// The maximum buffer size an EMS app may write to it's channel
//
#define CHANNEL_MAX_OWRITE_BUFFER_SIZE 0x8000
//
// Channel function types
//
struct _SAC_CHANNEL;
typedef NTSTATUS (*CHANNEL_FUNC_CREATE)( IN struct _SAC_CHANNEL* Channel );
typedef NTSTATUS (*CHANNEL_FUNC_DESTROY)( IN struct _SAC_CHANNEL* Channel );
typedef NTSTATUS (*CHANNEL_FUNC_OFLUSH)( IN struct _SAC_CHANNEL* Channel );
typedef NTSTATUS (*CHANNEL_FUNC_OECHO)( IN struct _SAC_CHANNEL* Channel, IN PCUCHAR Buffer, IN ULONG BufferSize );
typedef NTSTATUS (*CHANNEL_FUNC_OWRITE)( IN struct _SAC_CHANNEL* Channel, IN PCUCHAR Buffer, IN ULONG BufferSize );
typedef NTSTATUS (*CHANNEL_FUNC_OREAD)( IN struct _SAC_CHANNEL* Channel, IN PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount );
typedef NTSTATUS (*CHANNEL_FUNC_IWRITE)( IN struct _SAC_CHANNEL* Channel, IN PCUCHAR Buffer, IN ULONG BufferSize );
typedef NTSTATUS (*CHANNEL_FUNC_IREAD)( IN struct _SAC_CHANNEL* Channel, IN PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount );
typedef WCHAR (*CHANNEL_FUNC_IREADLAST)( IN struct _SAC_CHANNEL* Channel );
typedef NTSTATUS (*CHANNEL_FUNC_IBUFFERISFULL)( IN struct _SAC_CHANNEL* Channel, OUT BOOLEAN* BufferStatus );
typedef ULONG (*CHANNEL_FUNC_IBUFFERLENGTH)( IN struct _SAC_CHANNEL* Channel );
//
// This struct is all the information necessary to maintian a single channel.
//
typedef struct _SAC_CHANNEL {
/////////////////////////////////////////
// BEGIN: ATTRIBUTES SET UPON CREATION
/////////////////////////////////////////
//
// Index of the channel in the channel manager's channel array
//
ULONG Index;
//
// Handle for use by Channel applications
//
SAC_CHANNEL_HANDLE Handle; //
// Events specified by the channel application
//
HANDLE CloseEvent; PVOID CloseEventObjectBody; PVOID CloseEventWaitObjectBody; HANDLE HasNewDataEvent; PVOID HasNewDataEventObjectBody; PVOID HasNewDataEventWaitObjectBody; #if ENABLE_CHANNEL_LOCKING
HANDLE LockEvent; PVOID LockEventObjectBody; PVOID LockEventWaitObjectBody; #endif
HANDLE RedrawEvent; PVOID RedrawEventObjectBody; PVOID RedrawEventWaitObjectBody; /////////////////////////////////////////
// END: ATTRIBUTES SET UPON CREATION
/////////////////////////////////////////
/////////////////////////////////////////
// BEGIN: REQUIRES CHANNEL_ACCESS_ATTRIBUTES
/////////////////////////////////////////
//
// General channel attributes
//
//
// The pointer to the file object used to reference
// the SAC driver for the process that created
// the channel. We use this file object to make
// sure no other process operates on a channel they
// didnt create.
//
PFILE_OBJECT FileObject;
//
// Channel Type
//
// Determines the channel implementation
//
SAC_CHANNEL_TYPE Type;
//
// Channel Status (Active/Inactive)
//
// Active - the channel may send/receive data
// Inactive - channel may not receive data
// if the preserve flag is set, the channel
// will not be reaped until the data is sent
// otherwise the channel is reapable
//
SAC_CHANNEL_STATUS Status; //
// Channel Name
//
WCHAR Name[SAC_MAX_CHANNEL_NAME_LENGTH+1]; //
// Channel Description
//
WCHAR Description[SAC_MAX_CHANNEL_DESCRIPTION_LENGTH+1]; //
// Channel behavior attribute flags
//
// Example:
//
// SAC_CHANNEL_FLAG_PRESERVE - don't reap the channel until the data
// in the obuffer has been sent
//
SAC_CHANNEL_FLAG Flags; //
// Channel Attribute type
//
// Application determined identifier that is used primarily
// by the remote management app to determine how to handle
// the channel data
//
GUID ApplicationType;
//
// Status of OBuffer
//
// TRUE when the OBuffer has been flushed
// Otherwise FALSE
//
// This is primarily intended for use with an IOMGR like the console
// manager. For instance, this flag gets set to FALSE when we
// fast-channel-switch to another channel, and set to TRUE when we
// select a channel and flush it's contents to the current channel.
//
// Note: we use ULONG for this so we can use InterlockedExchange
//
ULONG SentToScreen; /////////////////////////////////////////
// END: REQUIRES CHANNEL_ACCESS_ATTRIBUTES
/////////////////////////////////////////
/////////////////////////////////////////
// BEGIN: REQUIRES CHANNEL_ACCESS_IBUFFER
/////////////////////////////////////////
//
// Common Input Buffer
//
ULONG IBufferIndex; PUCHAR IBuffer; ULONG IBufferHasNewData;
/////////////////////////////////////////
// END: REQUIRES CHANNEL_ACCESS_IBUFFER
/////////////////////////////////////////
/////////////////////////////////////////
// BEGIN: REQUIRES CHANNEL_ACCESS_OBUFFER
/////////////////////////////////////////
//
// VTUTF8 Channel Screen details
//
UCHAR CursorRow; UCHAR CursorCol; UCHAR CurrentFg; UCHAR CurrentBg; UCHAR CurrentAttr;
//
// Output Buffer
PVOID OBuffer; //
// OBuffer management vars for RawChannels
//
ULONG OBufferIndex; ULONG OBufferFirstGoodIndex; //
// This gets set when new data is inserted into OBuffer
//
ULONG OBufferHasNewData;
/////////////////////////////////////////
// END: REQUIRES CHANNEL_ACCESS_OBUFFER
/////////////////////////////////////////
//
// Channel Function VTABLE
//
CHANNEL_FUNC_CREATE Create; CHANNEL_FUNC_DESTROY Destroy; CHANNEL_FUNC_OFLUSH OFlush; CHANNEL_FUNC_OECHO OEcho; CHANNEL_FUNC_OWRITE OWrite; CHANNEL_FUNC_OREAD ORead; CHANNEL_FUNC_IWRITE IWrite; CHANNEL_FUNC_IREAD IRead; CHANNEL_FUNC_IREADLAST IReadLast; CHANNEL_FUNC_IBUFFERISFULL IBufferIsFull; CHANNEL_FUNC_IBUFFERLENGTH IBufferLength;
//
// Channel access locks
//
SAC_LOCK ChannelAttributeLock; SAC_LOCK ChannelOBufferLock; SAC_LOCK ChannelIBufferLock;
} SAC_CHANNEL, *PSAC_CHANNEL;
//
// Macros for managing channel locks
//
#define INIT_CHANNEL_LOCKS(_Channel) \
INITIALIZE_LOCK(_Channel->ChannelAttributeLock); \ INITIALIZE_LOCK(_Channel->ChannelOBufferLock); \ INITIALIZE_LOCK(_Channel->ChannelIBufferLock);
#define ASSERT_CHANNEL_LOCKS_SIGNALED(_Channel) \
ASSERT(LOCK_IS_SIGNALED(_Channel->ChannelAttributeLock)); \ ASSERT(LOCK_HAS_ZERO_REF_COUNT(_Channel->ChannelAttributeLock)); \ ASSERT(LOCK_IS_SIGNALED(_Channel->ChannelOBufferLock)); \ ASSERT(LOCK_HAS_ZERO_REF_COUNT(_Channel->ChannelOBufferLock)); \ ASSERT(LOCK_IS_SIGNALED(_Channel->ChannelIBufferLock)); \ ASSERT(LOCK_HAS_ZERO_REF_COUNT(_Channel->ChannelIBufferLock));
#define LOCK_CHANNEL_ATTRIBUTES(_Channel) \
ACQUIRE_LOCK(_Channel->ChannelAttributeLock) #define UNLOCK_CHANNEL_ATTRIBUTES(_Channel) \
RELEASE_LOCK(_Channel->ChannelAttributeLock)
#define LOCK_CHANNEL_OBUFFER(_Channel) \
ACQUIRE_LOCK(_Channel->ChannelOBufferLock) #define UNLOCK_CHANNEL_OBUFFER(_Channel) \
RELEASE_LOCK(_Channel->ChannelOBufferLock)
#define LOCK_CHANNEL_IBUFFER(_Channel) \
ACQUIRE_LOCK(_Channel->ChannelIBufferLock) #define UNLOCK_CHANNEL_IBUFFER(_Channel) \
RELEASE_LOCK(_Channel->ChannelIBufferLock)
//
// Macros for get/set operations on most of the channel's attributes
//
// Note: If the operation can be done use InterlockedXXX,
// then it should be done here.
//
#define ChannelGetHandle(_Channel) (_Channel->Handle)
#define ChannelGetType(_Channel) (_Channel->Type)
#define ChannelSetType(_Channel, _v) (InterlockedExchange((volatile long *)&(_Channel->Status), _v))
#define ChannelSentToScreen(_Channel) ((BOOLEAN)_Channel->SentToScreen)
#define ChannelSetSentToScreen(_Channel, _f) (InterlockedExchange((volatile long *)&(_Channel->SentToScreen), _f))
#define ChannelHasNewOBufferData(_Channel) ((BOOLEAN)_Channel->OBufferHasNewData)
#define ChannelSetOBufferHasNewData(_Channel, _f) (InterlockedExchange((volatile long *)&(_Channel->OBufferHasNewData), _f))
#define ChannelHasNewIBufferData(_Channel) ((BOOLEAN)_Channel->IBufferHasNewData)
#define ChannelSetIBufferHasNewData(_Channel, _f) (InterlockedExchange((volatile long *)&(_Channel->IBufferHasNewData), _f))
#define ChannelGetFlags(_Channel) (_Channel->Flags)
#define ChannelSetFlags(_Channel, _f) (InterlockedExchange((volatile long *)&(_Channel->Flags), _f))
#define ChannelGetIndex(_Channel) (_Channel->Index)
#define ChannelSetIndex(_Channel, _v) (InterlockedExchange((volatile long *)&(_Channel->Index), _v))
#define ChannelGetFileObject(_Channel) (_Channel->FileObject)
#define ChannelSetFileObject(_Channel, _v) (InterlockedExchangePointer(&(_Channel->FileObject), _v))
#if ENABLE_CHANNEL_LOCKING
#define ChannelHasLockEvent(_Channel) (_Channel->LockEvent ? TRUE : FALSE)
#endif
//
// Prototypes
//
BOOLEAN ChannelIsValidType( SAC_CHANNEL_TYPE ChannelType );
BOOLEAN ChannelIsActive( IN PSAC_CHANNEL Channel );
BOOLEAN ChannelIsEqual( IN PSAC_CHANNEL Channel, IN PSAC_CHANNEL_HANDLE ChannelHandle );
BOOLEAN ChannelIsClosed( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelCreate( OUT PSAC_CHANNEL Channel, IN PSAC_CHANNEL_OPEN_ATTRIBUTES Attributes, IN SAC_CHANNEL_HANDLE ChannelHandle );
NTSTATUS ChannelClose( PSAC_CHANNEL Channel );
NTSTATUS ChannelDestroy( IN PSAC_CHANNEL Channel );
WCHAR ChannelIReadLast( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelInitializeVTable( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelOWrite( IN PSAC_CHANNEL Channel, IN PCUCHAR Buffer, IN ULONG BufferSize );
NTSTATUS ChannelOFlush( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelOEcho( IN PSAC_CHANNEL Channel, IN PCUCHAR Buffer, IN ULONG BufferSize );
NTSTATUS ChannelORead( IN PSAC_CHANNEL Channel, IN PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount );
NTSTATUS ChannelIWrite( IN PSAC_CHANNEL Channel, IN PCUCHAR Buffer, IN ULONG BufferSize ); NTSTATUS ChannelIRead( IN PSAC_CHANNEL Channel, IN PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount );
WCHAR ChannelIReadLast( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelIBufferIsFull( IN PSAC_CHANNEL Channel, OUT BOOLEAN* BufferStatus );
ULONG ChannelIBufferLength( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelGetName( IN PSAC_CHANNEL Channel, OUT PWSTR* Name );
NTSTATUS ChannelSetName( IN PSAC_CHANNEL Channel, IN PCWSTR Name );
NTSTATUS ChannelGetDescription( IN PSAC_CHANNEL Channel, OUT PWSTR* Name );
NTSTATUS ChannelSetDescription( IN PSAC_CHANNEL Channel, IN PCWSTR Name );
NTSTATUS ChannelSetStatus( IN PSAC_CHANNEL Channel, IN SAC_CHANNEL_STATUS Status );
NTSTATUS ChannelGetStatus( IN PSAC_CHANNEL Channel, OUT SAC_CHANNEL_STATUS* Status );
NTSTATUS ChannelSetApplicationType( IN PSAC_CHANNEL Channel, IN GUID ApplicationType );
NTSTATUS ChannelGetApplicationType( IN PSAC_CHANNEL Channel, IN GUID* ApplicationType );
#if ENABLE_CHANNEL_LOCKING
NTSTATUS ChannelSetLockEvent( IN PSAC_CHANNEL Channel ); #endif
NTSTATUS ChannelSetRedrawEvent( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelClearRedrawEvent( IN PSAC_CHANNEL Channel );
NTSTATUS ChannelHasRedrawEvent( IN PSAC_CHANNEL Channel, OUT PBOOLEAN Present );
#endif
|