|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
misc.c
Abstract:
This module contains the miscellaneous SPUD routines.
Author:
John Ballard (jballard) 21-Oct-1996
Revision History:
Keith Moore (keithmo) 04-Feb-1998 Cleanup, added much needed comments.
--*/
#include "spudp.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, SpudEnterService )
#pragma alloc_text( PAGE, SpudLeaveService )
#pragma alloc_text( PAGE, SpudGetAfdDeviceObject )
#endif
#if 0
NOT PAGEABLE -- SpudAssert NOT PAGEABLE -- SpudReferenceCompletionPort NOT PAGEABLE -- SpudDereferenceCompletionPort #endif
//
// Public funcitons.
//
NTSTATUS SpudEnterService( #if DBG
IN PSTR ServiceName, #endif
IN BOOLEAN InitRequired )
/*++
Routine Description:
Common service entry prologue. This routine ensures that all necessary initialization required by the service has been performed.
Arguments:
ServiceName - Name of the service being invoked (DBG only).
InitRequired - If TRUE, then the driver must have already been fully initialized. This parameter is TRUE for all services *except* SPUDInitialize().
Return Value:
NTSTATUS - Completion status
--*/
{
//
// Sanity check.
//
PAGED_CODE();
#if DBG
UNREFERENCED_PARAMETER( ServiceName ); #endif
//
// If InitRequired is TRUE, then the current process must match the
// one that owns our driver.
//
if( InitRequired && ( SpudOwningProcess != PsGetCurrentProcess() ) ) { return STATUS_INVALID_DEVICE_REQUEST; }
//
// If InitRequired is FALSE, then there must be no owning process.
//
if( !InitRequired && ( SpudOwningProcess != NULL ) ) { return STATUS_INVALID_DEVICE_REQUEST; }
//
// Looks good.
//
return STATUS_SUCCESS;
} // SpudEnterService
VOID SpudLeaveService( #if DBG
IN PSTR ServiceName, IN NTSTATUS Status, #endif
IN BOOLEAN DerefRequired )
/*++
Routine Description:
Common service exit routine.
Arguments:
ServiceName - Name of the service being invoked (DBG only).
Status - Service completion status (DBG only).
DerefRequired - TRUE if the completion port should be dereferenced before returning.
Return Value:
None.
--*/
{
//
// Sanity check.
//
PAGED_CODE();
#if DBG
UNREFERENCED_PARAMETER( ServiceName ); UNREFERENCED_PARAMETER( Status ); #endif
if( DerefRequired ) { SpudDereferenceCompletionPort(); }
} // SpudLeaveService
NTSTATUS SpudGetAfdDeviceObject( IN PFILE_OBJECT AfdFileObject )
/*++
Routine Description:
Retreives AFD's device object & fast IO dispatch table from a socket's file object.
Arguments:
AfdFileObject - The FILE_OBJECT for an open socket.
Return Value:
NTSTATUS - Completion status.
--*/
{
//
// Sanity check.
//
PAGED_CODE();
//
// Chase down the device object associated with the file object, then
// snag the fast I/O dispatch table.
//
SpudAfdDeviceObject = IoGetRelatedDeviceObject( AfdFileObject );
if( !SpudAfdDeviceObject ) { return STATUS_INVALID_DEVICE_REQUEST; }
SpudAfdFastIoDeviceControl = SpudAfdDeviceObject->DriverObject->FastIoDispatch->FastIoDeviceControl;
if( !SpudAfdFastIoDeviceControl ) { SpudAfdDeviceObject = NULL; return STATUS_INVALID_DEVICE_REQUEST; }
return STATUS_SUCCESS;
} // SpudGetAfdDeviceObject
#if DBG
VOID SpudAssert( IN PVOID FailedAssertion, IN PVOID FileName, IN ULONG LineNumber, IN PCHAR Message OPTIONAL )
/*++
Routine Description:
Private assertion failure handler. This is necessary to make ASSERT()s work on free builds. (RtlAssert() is a noop on free builds.)
Arguments:
FailedAssertion - The text of the failed assertion.
FileName - The file name containing the failed assertion.
LineNumber - The line number of the failed assertion.
Message - An optional message to display with the assertion.
Return Value:
None.
--*/
{
//
// If we 're to use our private assert, then do it ourselves.
// Otherwise, let RtlAssert() handle it.
//
if( SpudUsePrivateAssert ) {
DbgPrint( "\n*** Assertion failed: %s%s\n*** Source File: %s, line %ld\n\n", Message ? Message : "", FailedAssertion, FileName, LineNumber );
DbgBreakPoint();
} else {
RtlAssert( FailedAssertion, FileName, LineNumber, Message );
}
} // SpudAssert
#endif // DBG
PVOID SpudReferenceCompletionPort( VOID )
/*++
Routine Description:
Bumps our private reference on the completion port pointer.
Arguments:
None.
Return Value:
PVOID - A pointer to the completion port object if successful, NULL otherwise.
--*/
{
PVOID port; KIRQL oldIrql;
KeAcquireSpinLock( &SpudCompletionPortLock, &oldIrql );
port = SpudCompletionPort;
if( port != NULL ) { SpudCompletionPortRefCount++; ASSERT( SpudCompletionPortRefCount > 0 ); }
KeReleaseSpinLock( &SpudCompletionPortLock, oldIrql );
return port;
} // SpudReferenceCompletionPort
VOID SpudDereferenceCompletionPort( VOID )
/*++
Routine Description:
Removes a private reference from the completion port object.
Arguments:
None.
Return Value:
None.
--*/
{
KIRQL oldIrql;
KeAcquireSpinLock( &SpudCompletionPortLock, &oldIrql );
if( SpudCompletionPort != NULL ) {
ASSERT( SpudCompletionPortRefCount > 0 ); SpudCompletionPortRefCount--;
if( SpudCompletionPortRefCount == 0 ) { TRACE_OB_DEREFERENCE( SpudCompletionPort ); ObDereferenceObject( SpudCompletionPort ); SpudCompletionPort = NULL; }
}
KeReleaseSpinLock( &SpudCompletionPortLock, oldIrql );
} // SpudDereferenceCompletionPort
|