Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

801 lines
18 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
clusnet.h
Abstract:
Top-level, common header file for the Cluster Network Driver.
Defines common driver structures.
Author:
Mike Massa (mikemas) January 3, 1997
Revision History:
Who When What
-------- -------- ----------------------------------------------
mikemas 01-03-97 created
Notes:
--*/
#ifndef _CLUSNET_INCLUDED_
#define _CLUSNET_INCLUDED_
#define _NTDDK_ // [HACKHACK] to make ProbeForRead work. Better to include ntddk instead of ntos //
#define WMI_TRACING 1
#include <ntos.h>
#include <zwapi.h>
#include <clusdef.h>
#include <ntddcnet.h>
#include <cnettest.h>
#include <ntemgmt.h>
#include <nbtmgmt.h>
#include <memlog.h>
#if defined(WMI_TRACING)
# include "cnwmi.h"
#endif
//
// Constants
//
#define CN_POOL_TAG 'tnSC'
#define CDP_DEFAULT_IRP_STACK_SIZE 4
#define CN_DEFAULT_IRP_STACK_SIZE 4
//
// Pool Macros
//
#define CnAllocatePool(_bufsize) \
ExAllocatePoolWithTag(NonPagedPool, (_bufsize), CN_POOL_TAG);
#define CnAllocatePoolWithQuota(_bufsize) \
ExAllocatePoolWithQuotaTag(NonPagedPool, (_bufsize), CN_POOL_TAG);
#define CnFreePool(_ptr) \
ExFreePool((_ptr))
#define ROUND32(_value) ( ((_value) + 3) & ~(0x3) )
//
// Init/Cleanup synchronization
//
typedef enum {
CnStateShutdown = 0,
CnStateShutdownPending = 1,
CnStateInitializePending = 2,
CnStateInitialized = 3
} CN_STATE;
// Clusnet Heart Beat Period definintion Removed from clusnet\xport\Chbeat.c
// This is it's proper place.
//
// heart beat period in millisecs
//
#define HEART_BEAT_PERIOD 600
//
// Node ID validation macro
//
#define CnIsValidNodeId(_id) ( ((_id) >= CnMinValidNodeId) && \
((_id) <= CnMaxValidNodeId) )
//
// Lock acquisition ranking. Locks must be acquired in this order to
// prevent deadlocks. Components really should avoid calling outside
// of themselves while holding locks.
//
#define CN_IOCANCEL_LOCK 0x00000001
#define CN_IOCANCEL_LOCK_MAX 0x00000001
// MM locks
#define MM_RGP_LOCK 0x00000010
#define MM_CALLBACK_LOCK 0x00000020
// CX Locks
#define CX_PRECEEDING_LOCK_RANGE 0x0000FFFF
#define CX_LOCK_RANGE 0xFFFF0000
#define CX_ADDROBJ_TABLE_LOCK 0x00010000
#define CX_ADDROBJ_TABLE_LOCK_MAX 0x0001FFFF
#define CX_ADDROBJ_LOCK 0x00020000
#define CX_ADDROBJ_LOCK_MAX 0x0003FFFF
#define CNP_PRECEEDING_LOCK_RANGE 0x00FFFFFF
#define CNP_LOCK_RANGE 0xFF000000
#define CNP_NODE_TABLE_LOCK 0x01000000
#define CNP_NODE_TABLE_LOCK_MAX 0x01FFFFFF
#define CNP_NODE_OBJECT_LOCK 0x02000000
#define CNP_NODE_OBJECT_LOCK_MAX 0x03FFFFFF
#define CNP_NETWORK_LIST_LOCK 0x04000000
#define CNP_NETWORK_LIST_LOCK_MAX 0x07FFFFFF
#define CNP_NETWORK_OBJECT_LOCK 0x08000000
#define CNP_NETWORK_OBJECT_LOCK_MAX 0x0FFFFFFF
#define CNP_HBEAT_LOCK 0x10000000
#define CNP_EVENT_LOCK_PRECEEDING 0x1FFFFFFF
#define CNP_EVENT_LOCK 0x20000000
#define CNP_EVENT_LOCK_MAX 0x3FFFFFFF
#define CNP_SEC_CTXT_LOCK 0x20000000
//
// Debugging Definitions
//
#if DBG
#define CNPRINT(many_args) DbgPrint many_args
extern ULONG CnDebug;
#define CN_DEBUG_INIT 0x00000001
#define CN_DEBUG_OPEN 0x00000002
#define CN_DEBUG_CLEANUP 0x00000004
#define CN_DEBUG_CLOSE 0x00000008
#define CN_DEBUG_IRP 0x00000010
#define CN_DEBUG_NODEOBJ 0x00000020
#define CN_DEBUG_NETOBJ 0x00000040
#define CN_DEBUG_IFOBJ 0x00000080
#define CN_DEBUG_CONFIG 0x00000100
#define CN_DEBUG_CNPSEND 0x00000200
#define CN_DEBUG_CNPRECV 0x00000400
#define CN_DEBUG_CNPREF 0x00000800
#define CN_DEBUG_EVENT 0x00001000
#define CN_DEBUG_MMSTATE 0x00002000
#define CN_DEBUG_HBEATS 0x00004000
#define CN_DEBUG_POISON 0x00008000
#define CN_DEBUG_CDPSEND 0x00010000
#define CN_DEBUG_CDPRECV 0x00020000
#define CN_DEBUG_CCMPSEND 0x00040000
#define CN_DEBUG_CCMPRECV 0x00080000
#define CN_DEBUG_ADDROBJ 0x00100000
#define CN_DEBUG_INFO 0x00200000
#define CN_DEBUG_NTE 0x00400000
#define CN_DEBUG_NDIS 0x00800000
#define CN_DEBUG_RGP 0x10000000
#define CN_DEBUG_CMM 0x20000000
#define CN_DEBUG_CMMMSG 0x40000000
#define CN_DEBUG_CMMTIMERQ 0x80000000
#define IF_CNDBG(flag) if (CnDebug & flag)
VOID
CnAssertBreak(
PCHAR FailedStatement,
PCHAR FileName,
ULONG LineNumber
);
#define CnAssert(_statement) \
if (!(_statement)) CnAssertBreak(#_statement, __FILE__, __LINE__)
#define CN_SIGNATURE_FIELD ULONG Signature;
#define CN_INIT_SIGNATURE(pstruct, sig) ((pstruct)->Signature = (sig))
#define CN_ASSERT_SIGNATURE(pstruct, sig) CnAssert( (pstruct)->Signature == \
(sig) )
#define CN_DBGCHECK DbgBreakPoint()
typedef struct {
KSPIN_LOCK SpinLock;
ULONG Rank;
} CN_LOCK, *PCN_LOCK;
typedef KIRQL CN_IRQL, *PCN_IRQL;
ULONG
CnGetCpuLockMask(
VOID
);
VOID
CnVerifyCpuLockMask(
IN ULONG RequiredLockMask,
IN ULONG ForbiddenLockMask,
IN ULONG MaximumLockMask
);
VOID
CnInitializeLock(
PCN_LOCK Lock,
ULONG Rank
);
VOID
CnAcquireLock(
IN PCN_LOCK Lock,
OUT PCN_IRQL Irql
);
VOID
CnReleaseLock(
IN PCN_LOCK Lock,
IN CN_IRQL Irql
);
VOID
CnAcquireLockAtDpc(
IN PCN_LOCK Lock
);
VOID
CnReleaseLockFromDpc(
IN PCN_LOCK Lock
);
VOID
CnMarkIoCancelLockAcquired(
VOID
);
VOID
CnAcquireCancelSpinLock(
OUT PCN_IRQL Irql
);
VOID
CnReleaseCancelSpinLock(
IN CN_IRQL Irql
);
#else // DBG
#define CNPRINT(many_args)
#define IF_CNDBG(flag) if (0)
#define CnAssert(_statement)
#define CN_SIGNATURE_FIELD
#define CN_INIT_SIGNATURE(pstruct, sig)
#define CN_ASSERT_SIGNATURE(pstruct, sig)
#define CN_DBGCHECK
typedef KSPIN_LOCK CN_LOCK, *PCN_LOCK;
typedef KIRQL CN_IRQL, *PCN_IRQL;
#define CnVerifyCpuLockMask(p1, p2, p3)
#define CnInitializeLock(_plock, _rank) KeInitializeSpinLock((_plock))
#define CnAcquireLock(_plock, _pirql) KeAcquireSpinLock((_plock), (_pirql))
#define CnReleaseLock(_plock, _irql) KeReleaseSpinLock((_plock), (_irql))
#define CnAcquireLockAtDpc(_plock) KeAcquireSpinLockAtDpcLevel((_plock))
#define CnReleaseLockFromDpc(_plock) KeReleaseSpinLockFromDpcLevel((_plock))
#define CnMarkIoCancelLockAcquired()
#define CnAcquireCancelSpinLock(_pirql) IoAcquireCancelSpinLock((_pirql))
#define CnReleaseCancelSpinLock(_irql) IoReleaseCancelSpinLock((_irql))
#endif // DBG
//
// File Object Context Structure
//
// A pointer to this structure is stored in FileObject->FsContext.
// It maintains context information about open file objects.
//
typedef struct {
//
// used by event mechanism to find interested consumers when a new event
// is posted.
//
LIST_ENTRY Linkage;
CN_SIGNATURE_FIELD
PFILE_OBJECT FileObject;
LONG ReferenceCount;
UCHAR CancelIrps;
UCHAR ShutdownOnClose;
UCHAR Pad[2];
KEVENT CleanupEvent;
//
// list of event context blocks representing events to be delivered to
// consumer
//
LIST_ENTRY EventList;
//
// pending IRP that is completed when a new event is issued
//
PIRP EventIrp;
//
// event types in which this consumer is interested
//
ULONG EventMask;
//
// routine used to notify kernel consumers of new events
//
CLUSNET_EVENT_CALLBACK_ROUTINE KmodeEventCallback;
} CN_FSCONTEXT, *PCN_FSCONTEXT;
#define CN_CONTROL_CHANNEL_SIG 'lrtc'
//
// Generic Resource Management Package
//
//
// Forward Declarations
//
typedef struct _CN_RESOURCE *PCN_RESOURCE;
typedef struct _CN_RESOURCE_POOL *PCN_RESOURCE_POOL;
/*++
PCN_RESOURCE
CnCreateResourceRoutine(
IN PVOID Context
);
Routine Description:
Creates a new instance of a resource to be managed by a resource pool.
Arguments:
Context - The context value specified when the pool was initialized.
Return Value:
A pointer to the newly created resource if successful.
NULL if unsuccessful.
--*/
typedef
PCN_RESOURCE
(*PCN_CREATE_RESOURCE_ROUTINE)(
IN PVOID PoolContext
);
/*++
PCN_RESOURCE
CnDeleteResourceRoutine(
IN PCN_RESOURCE Resource
);
Routine Description:
Destroys an instance of a resource allocated by
CnCreateResourceRoutine().
Arguments:
Resource - A pointer to the resource to destroy.
Return Value:
None.
--*/
typedef
VOID
(*PCN_DELETE_RESOURCE_ROUTINE) (
IN PCN_RESOURCE Resource
);
//
// Resource Pool Structure
//
typedef struct _CN_RESOURCE_POOL {
CN_SIGNATURE_FIELD
SLIST_HEADER ResourceList;
KSPIN_LOCK ResourceListLock;
USHORT Depth;
USHORT Pad;
PCN_CREATE_RESOURCE_ROUTINE CreateRoutine;
PVOID CreateContext;
PCN_DELETE_RESOURCE_ROUTINE DeleteRoutine;
} CN_RESOURCE_POOL;
#define CN_RESOURCE_POOL_SIG 'lpnc'
//
// Resource Structure
//
typedef struct _CN_RESOURCE {
SLIST_ENTRY Linkage;
CN_SIGNATURE_FIELD
PCN_RESOURCE_POOL Pool;
PVOID Context;
} CN_RESOURCE;
#define CN_RESOURCE_SIG 'ernc'
//
// Routines for operating on Resource Pools
//
/*++
VOID
CnInitializeResourcePool(
IN PCN_RESOURCE_POOL Pool,
IN USHORT Depth,
IN PCN_CREATE_RESOURCE_ROUTINE CreateRoutine,
IN PVOID CreateContext,
IN PCN_DELETE_RESOURCE_ROUTINE DeleteRoutine,
);
Routine Description:
Initializes a resource pool structure.
Arguments:
Pool - A pointer to the pool structure to initialize.
Depth - The maximum number of items to cache in the pool.
CreateRoutine - A pointer to the routine to call to create a new
instance of a resource.
CreateContext - A context value to pass as an argument to
the CreateRoutine.
DeleteRoutine - A pointer to the routine to call to destroy an instance
of a resource created by CreateRoutine.
Return Value
None.
--*/
#define CnInitializeResourcePool(_pool, _depth, _creatertn, _createctx, _deletertn) \
{ \
CN_INIT_SIGNATURE(_pool, CN_RESOURCE_POOL_SIG); \
ExInitializeSListHead(&((_pool)->ResourceList)); \
KeInitializeSpinLock(&((_pool)->ResourceListLock)); \
(_pool)->Depth = _depth; \
(_pool)->CreateRoutine = _creatertn; \
(_pool)->CreateContext = _createctx; \
(_pool)->DeleteRoutine = _deletertn; \
}
VOID
CnDrainResourcePool(
IN PCN_RESOURCE_POOL Pool
);
PCN_RESOURCE
CnAllocateResource(
IN PCN_RESOURCE_POOL Pool
);
VOID
CnFreeResource(
PCN_RESOURCE Resource
);
/*++
VOID
CnSetResourceContext(
IN PCN_RESOURCE Resource,
IN PVOID ContextValue
);
Routine Description:
Sets the context value for a Resource.
Arguments:
Resource - A pointer to the resource on which to operate.
Return Value:
A pointer to the context value associated with the resource.
--*/
#define CnSetResourceContext(_res, _value) ((_res)->Context = (_value))
/*++
PVOID
CnGetResourceContext(
IN PCN_RESOURCE Resource
);
Routine Description:
Retrieves the context value from a Resource.
Arguments:
Resource - A pointer to the resource on which to operate.
Return Value:
A pointer to the context value associated with the resource.
--*/
#define CnGetResourceContext(_res) ((_res)->Context)
//
// Init/Cleanup Function Prototypes
//
NTSTATUS
CnInitialize(
IN CL_NODE_ID LocalNodeId,
IN ULONG MaxNodes
);
NTSTATUS
CnShutdown(
VOID
);
BOOLEAN
CnHaltOperation(
IN PKEVENT ShutdownEvent OPTIONAL
);
NTSTATUS
CnCloseProcessHandle(
HANDLE Handle
);
VOID
CnEnableHaltProcessing(
VOID
);
//
// Irp Handling Routines
//
NTSTATUS
CnDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
CnDispatchInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
CnDispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
#if DBG
#define CnReferenceFsContext(_fsc) \
{ \
LONG newValue = InterlockedIncrement(&((_fsc)->ReferenceCount)); \
CnAssert(newValue > 1); \
}
#else // DBG
#define CnReferenceFsContext(_fsc) \
(VOID) InterlockedIncrement( &((_fsc)->ReferenceCount) )
#endif // DBG
VOID
CnDereferenceFsContext(
PCN_FSCONTEXT FsContext
);
NTSTATUS
CnMarkRequestPending(
PIRP Irp,
PIO_STACK_LOCATION IrpSp,
PDRIVER_CANCEL CancelRoutine
);
VOID
CnCompletePendingRequest(
IN PIRP Irp,
IN NTSTATUS Status,
IN ULONG BytesReturned
);
PFILE_OBJECT
CnBeginCancelRoutine(
IN PIRP Irp
);
VOID
CnEndCancelRoutine(
PFILE_OBJECT FileObject
);
VOID
CnAdjustDeviceObjectStackSize(
PDEVICE_OBJECT ClusnetDeviceObject,
PDEVICE_OBJECT TargetDeviceObject
);
//
// ExResource wrappers
//
BOOLEAN
CnAcquireResourceExclusive(
IN PERESOURCE Resource,
IN BOOLEAN Wait
);
BOOLEAN
CnAcquireResourceShared(
IN PERESOURCE Resource,
IN BOOLEAN Wait
);
VOID
CnReleaseResourceForThread(
IN PERESOURCE Resource,
IN ERESOURCE_THREAD ResourceThreadId
);
//
// routines for in-memory logging facility
//
#ifdef MEMLOGGING
VOID
CnInitializeMemoryLog(
VOID
);
VOID
CnFreeMemoryLog(
VOID
);
#endif // MEMLOGGING
NTSTATUS
CnSetMemLogging(
PCLUSNET_SET_MEM_LOGGING_REQUEST request
);
#if 0
//
// NDIS related stuff
//
NDIS_STATUS
CnRegisterNDISProtocolHandlers(
VOID
);
NDIS_STATUS
CnDeregisterNDISProtocolHandlers(
VOID
);
VOID
CnOpenAdapterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus
);
VOID
CnCloseAdapterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
);
VOID
CnStatusIndication(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
);
VOID
CnStatusIndicationComplete(
IN NDIS_HANDLE ProtocolBindingContext
);
#endif
//
// error logging support
//
VOID _cdecl
CnWriteErrorLogEntry(
IN ULONG UniqueErrorCode,
IN NTSTATUS NtStatusCode,
IN PVOID ExtraInformationBuffer,
IN USHORT ExtraInformationLength,
IN USHORT NumberOfInsertionStrings,
...
);
//
// Global Data
//
extern PDRIVER_OBJECT CnDriverObject;
extern PDEVICE_OBJECT CnDeviceObject;;
extern PDEVICE_OBJECT CdpDeviceObject;
extern PKPROCESS CnSystemProcess;
extern CN_STATE CnState;
extern PERESOURCE CnResource;
extern CL_NODE_ID CnMinValidNodeId;
extern CL_NODE_ID CnMaxValidNodeId;
extern CL_NODE_ID CnLocalNodeId;
extern HANDLE ClussvcProcessHandle;
//
// vars for managing Events. The lookaside list generates Event data structs
// that are used to carry the event data back to user mode. EventLock is
// acquired when ANY Event operation takes place. Events are not generated
// at a high rate, hence the gross level of locking. EventFileHandles is a list
// of CN_FSCONTEXT blocks. These contain the acutal list of Events to be delivered
// to that file handle when clussvc makes an IRP available.
//
extern PNPAGED_LOOKASIDE_LIST EventLookasideList;
extern CN_LOCK EventLock;
extern LIST_ENTRY EventFileHandles;
extern ULONG EventEpoch;
extern LONG EventDeliveryInProgress;
extern KEVENT EventDeliveryComplete;
extern BOOLEAN EventRevisitRequired;
//
// Exports for Clussvc to Clusnet Heartbeating.
//
extern ULONG ClussvcClusnetHbTimeoutTicks;
extern ClussvcHangAction ClussvcClusnetHbTimeoutAction;
extern ULONG ClussvcClusnetHbTickCount;
extern PEPROCESS ClussvcProcessObject;
extern ULONG ClussvcClusnetHbTimeoutSeconds;
//
// ClusNet security descriptor
//
extern PSECURITY_DESCRIPTOR CdpAdminSecurityDescriptor;
#include <cluxport.h>
#include <event.h>
#ifdef MM_IN_CLUSNET
#include <clusmem.h>
#endif // MM_IN_CLUSNET
#endif // ifndef _CLUSNET_INCLUDED_