551 lines
13 KiB
C
551 lines
13 KiB
C
/*++
|
||
|
||
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
|
||
|