windows-nt/Source/XPSP1/NT/net/netbios/sys/nb.h
2020-09-26 16:20:57 +08:00

373 lines
15 KiB
C

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
nb.h
Abstract:
Private include file for the NB (NetBIOS) component of the NTOS project.
Author:
Colin Watson (ColinW) 13-Mar-1991
Revision History:
--*/
#ifndef _NB_
#define _NB_
#include <ntifs.h>
//#include <ntos.h>
#include <windef.h>
#include <status.h>
#include <tdikrnl.h> // Transport Driver Interface.
#include <nb30.h>
#include <nb30p.h>
#include <netpnp.h>
#include "nbconst.h" // private NETBEUI constants.
#include "nbtypes.h" // private NETBEUI types.
#include "nbdebug.h" // private NETBEUI debug defines.
#include "nbprocs.h" // private NETBEUI function prototypes.
#ifdef MEMPRINT
#include "memprint.h" // drt's memory debug print
#endif
extern PEPROCESS NbFspProcess;
extern ULONG g_ulMaxLana;
extern LANA_ENUM g_leLanaEnum;
extern PUNICODE_STRING g_pusActiveDeviceList;
extern HANDLE g_hBindHandle;
extern UNICODE_STRING g_usRegistryPath;
extern LIST_ENTRY g_leFCBList;
extern ERESOURCE g_erGlobalLock;
#if DBG
#define PAGED_DBG 1
#endif
#ifdef PAGED_DBG
#undef PAGED_CODE
#define PAGED_CODE() \
struct { ULONG bogus; } ThisCodeCantBePaged; \
ThisCodeCantBePaged; \
if (KeGetCurrentIrql() > APC_LEVEL) { \
KdPrint(( "NETBIOS: Pageable code called at IRQL %d. File %s, Line %d\n", KeGetCurrentIrql(), __FILE__, __LINE__ )); \
ASSERT(FALSE); \
}
#define PAGED_CODE_CHECK() if (ThisCodeCantBePaged) ;
extern ULONG ThisCodeCantBePaged;
#else
#define PAGED_CODE_CHECK()
#endif
#if PAGED_DBG
#define ACQUIRE_SPIN_LOCK(a, b) { \
PAGED_CODE_CHECK(); \
KeAcquireSpinLock(a, b); \
}
#define RELEASE_SPIN_LOCK(a, b) { \
PAGED_CODE_CHECK(); \
KeReleaseSpinLock(a, b); \
}
#else
#define ACQUIRE_SPIN_LOCK(a, b) KeAcquireSpinLock(a, b)
#define RELEASE_SPIN_LOCK(a, b) KeReleaseSpinLock(a, b)
#endif
//
// Macro for filling in the status for an NCB.
//
#define NCB_COMPLETE( _pdncb, _code ) { \
UCHAR _internal_copy = _code; \
IF_NBDBG (NB_DEBUG_COMPLETE) { \
NbPrint (("%s %d NCB_COMPLETE: %lx, %lx\n" , \
__FILE__, __LINE__, _pdncb, _internal_copy )); \
} \
if (((PDNCB)_pdncb)->ncb_retcode == NRC_PENDING) { \
((PDNCB)_pdncb)->ncb_retcode = _internal_copy; \
} else { \
IF_NBDBG (NB_DEBUG_NCBS) { \
NbPrint((" Status already set!!!!!!!!\n")); \
IF_NBDBG (NB_DEBUG_NCBSBRK) { \
DbgBreakPoint(); \
} \
} \
} \
IF_NBDBG (NB_DEBUG_NCBS) { \
NbDisplayNcb( (PDNCB)_pdncb ); \
} \
IF_NBDBG (NB_DEBUG_COMPLETE) \
{ \
if ( ( (_code) == NRC_BRIDGE ) || \
( (_code) == NRC_ENVNOTDEF ) ) \
{ \
DbgPrint("\n[NETBIOS]: NCB_COMPLETE : File %s," \
" line %d\n", __FILE__, __LINE__); \
DbgPrint("LANA %x, Command %x ", \
((PDNCB)_pdncb)->ncb_lana_num, \
((PDNCB)_pdncb)->ncb_command ); \
DbgPrint("Return %x, Cmplt %x\n", \
((PDNCB)_pdncb)->ncb_retcode, \
((PDNCB)_pdncb)->ncb_cmd_cplt ); \
NbFormattedDump( ((PDNCB)_pdncb)->ncb_name, 16 ); \
NbFormattedDump( ((PDNCB)_pdncb)->ncb_callname, 16 ); \
} \
else if ( ( ( (_code) == NRC_DUPNAME ) || \
( (_code) == NRC_INUSE ) ) && \
( ((PDNCB)_pdncb)-> ncb_command != NCBADDGRNAME ) ) \
{ \
DbgPrint("\n[NETBIOS]: NCB_COMPLETE : DUPNAME : File %s," \
"line %d\n", __FILE__, __LINE__); \
DbgPrint("LANA %x, Command %x ", \
((PDNCB)_pdncb)->ncb_lana_num, \
((PDNCB)_pdncb)->ncb_command ); \
DbgPrint("Return %x, Cmplt %x\n", \
((PDNCB)_pdncb)->ncb_retcode, \
((PDNCB)_pdncb)->ncb_cmd_cplt ); \
NbFormattedDump( ((PDNCB)_pdncb)->ncb_name, 16 ); \
if ( ((PDNCB)_pdncb)->ncb_name[15] == 0x3) \
{ \
DbgPrint("Messenger Name, dup ok\n"); \
} \
else \
{ \
IF_NBDBG(NB_DEBUG_NCBSBRK) DbgBreakPoint(); \
} \
} \
} \
}
//++
//
// VOID
// NbCompleteRequest (
// IN PIRP Irp,
// IN NTSTATUS Status
// );
//
// Routine Description:
//
// This routine is used to complete an IRP with the indicated
// status. It does the necessary raise and lower of IRQL.
//
// Arguments:
//
// Irp - Supplies a pointer to the Irp to complete
//
// Status - Supplies the completion status for the Irp
//
// Return Value:
//
// None.
//
//--
#define NbCompleteRequest(IRP,STATUS) { \
(IRP)->IoStatus.Status = (STATUS); \
IoCompleteRequest( (IRP), IO_NETWORK_INCREMENT ); \
}
#if defined(_WIN64)
#define NbCheckAndCompleteIrp32(Irp) \
{ \
if (IoIs32bitProcess(Irp) == TRUE) \
{ \
NbCompleteIrp32(Irp); \
} \
}
#else
#define NbCheckAndCompleteIrp32(Irp)
#endif
//
// Normally the driver wants to prohibit other threads making
// requests (using a resource) and also prevent indication routines
// being called (using a spinlock).
//
// To do this LOCK and UNLOCK are used. IO system calls cannot
// be called with a spinlock held so sometimes the ordering becomes
// LOCK, UNLOCK_SPINLOCK <do IO calls> UNLOCK_RESOURCE.
//
#define LOCK(PFCB, OLDIRQL) { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint (("%s %d LOCK: %lx %lx %lx\n" , \
__FILE__, __LINE__, (PFCB) )); \
} \
KeEnterCriticalRegion(); \
ExAcquireResourceExclusiveLite( &(PFCB)->Resource, TRUE); \
ACQUIRE_SPIN_LOCK( &(PFCB)->SpinLock, &(OLDIRQL)); \
}
#define LOCK_RESOURCE(PFCB) { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint(("%s %d LOCK_RESOURCE: %lx, %lx %lx\n" , \
__FILE__, __LINE__, (PFCB))); \
} \
KeEnterCriticalRegion(); \
ExAcquireResourceExclusiveLite( &(PFCB)->Resource, TRUE); \
}
#define LOCK_GLOBAL() { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint(("%s %d LOCK_GLOBAL: %lx, %lx\n" , \
__FILE__, __LINE__)); \
} \
KeEnterCriticalRegion(); \
ExAcquireResourceExclusiveLite( &g_erGlobalLock, TRUE); \
}
#define LOCK_STOP() { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint(("%s %d LOCK_STOP: %lx, %lx\n" , \
__FILE__, __LINE__)); \
} \
KeEnterCriticalRegion(); \
ExAcquireResourceExclusiveLite( &g_erStopLock, TRUE); \
}
#define LOCK_SPINLOCK(PFCB, OLDIRQL) { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint( ("%s %d LOCK_SPINLOCK: %lx %lx %lx\n" , \
__FILE__, __LINE__, (PFCB))); \
} \
ACQUIRE_SPIN_LOCK( &(PFCB)->SpinLock, &(OLDIRQL)); \
}
#define UNLOCK(PFCB, OLDIRQL) { \
UNLOCK_SPINLOCK( PFCB, OLDIRQL ); \
UNLOCK_RESOURCE( PFCB ); \
}
#define UNLOCK_GLOBAL() { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint(("%s %d UNLOCK_GLOBAL: %lx, %lx\n" , \
__FILE__, __LINE__)); \
} \
ExReleaseResourceLite( &g_erGlobalLock ); \
KeLeaveCriticalRegion(); \
}
#define UNLOCK_STOP() { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint(("%s %d UNLOCK_STOP: %lx, %lx\n" , \
__FILE__, __LINE__)); \
} \
ExReleaseResourceLite( &g_erStopLock ); \
KeLeaveCriticalRegion(); \
}
#define UNLOCK_RESOURCE(PFCB) { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint( ("%s %d RESOURCE: %lx, %lx %lx\n" , \
__FILE__, __LINE__, (PFCB) )); \
} \
ExReleaseResourceLite( &(PFCB)->Resource ); \
KeLeaveCriticalRegion(); \
}
#define UNLOCK_SPINLOCK(PFCB, OLDIRQL) { \
IF_NBDBG (NB_DEBUG_LOCKS) { \
NbPrint( ("%s %d SPINLOCK: %lx, %lx %lx %lx\n" , \
__FILE__, __LINE__, (PFCB), (OLDIRQL))); \
} \
RELEASE_SPIN_LOCK( &(PFCB)->SpinLock, (OLDIRQL) ); \
}
// Assume resource held when modifying CurrentUsers
#define REFERENCE_AB(PAB) { \
(PAB)->CurrentUsers++; \
IF_NBDBG (NB_DEBUG_ADDRESS) { \
NbPrint( ("ReferenceAb %s %d: %lx, NewCount:%lx\n", \
__FILE__, __LINE__, \
PAB, \
(PAB)->CurrentUsers)); \
NbFormattedDump( (PUCHAR)&(PAB)->Name, sizeof(NAME) ); \
} \
}
// Resource must be held before dereferencing the address block
#define DEREFERENCE_AB(PPAB) { \
IF_NBDBG (NB_DEBUG_ADDRESS) { \
NbPrint( ("DereferenceAb %s %d: %lx, OldCount:%lx\n", \
__FILE__, __LINE__, *PPAB, (*PPAB)->CurrentUsers)); \
NbFormattedDump( (PUCHAR)&(*PPAB)->Name, sizeof(NAME) );\
} \
(*PPAB)->CurrentUsers--; \
if ( (*PPAB)->CurrentUsers == 0 ) { \
if ( (*PPAB)->AddressHandle != NULL ) { \
IF_NBDBG (NB_DEBUG_ADDRESS) { \
NbPrint( ("DereferenceAb: Closing: %lx\n", \
(*PPAB)->AddressHandle)); \
} \
NbAddressClose( (*PPAB)->AddressHandle, \
(*PPAB)->AddressObject ); \
(*PPAB)->AddressHandle = NULL; \
} \
(*PPAB)->pLana->AddressCount--; \
ExFreePool( *PPAB ); \
*PPAB = NULL; \
} \
}
//
// The following macros are used to establish the semantics needed
// to do a return from within a try-finally clause. As a rule every
// try clause must end with a label call try_exit. For example,
//
// try {
// :
// :
//
// try_exit: NOTHING;
// } finally {
//
// :
// :
// }
//
// Every return statement executed inside of a try clause should use the
// try_return macro. If the compiler fully supports the try-finally construct
// then the macro should be
//
// #define try_return(S) { return(S); }
//
// If the compiler does not support the try-finally construct then the macro
// should be
//
#define try_return(S) { S; goto try_exit; }
#define NETBIOS_STOPPING 1
#define NETBIOS_RUNNING 2;
#endif // def _NB_