windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/infocomm/spuddrv/misc.c
2020-09-26 16:20:57 +08:00

387 lines
6.1 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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