Windows2003-3790/drivers/parallel/parport2/pdoclose.c
2020-09-30 16:53:55 +02:00

95 lines
2.3 KiB
C

#include "pch.h"
NTSTATUS
PptPdoClose(
IN PDEVICE_OBJECT Pdo,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch for a close requests.
Arguments:
DeviceObject - Supplies the device object.
Irp - Supplies the I/O request packet.
Return Value:
STATUS_SUCCESS - Success.
--*/
{
PPDO_EXTENSION pdx = Pdo->DeviceExtension;
BOOLEAN haveShadowBuffer;
PVOID threadObject;
DD((PCE)pdx,DDT,"PptPdoClose\n");
// immediately stop signalling any dot4 event
pdx->P12843DL.bEventActive = FALSE;
//
// Protect against two threads calling us concurrently
//
ExAcquireFastMutex( &pdx->OpenCloseMutex );
haveShadowBuffer = pdx->bShadowBuffer;
pdx->bShadowBuffer = FALSE;
threadObject = pdx->ThreadObjectPointer;
pdx->ThreadObjectPointer = NULL;
ExReleaseFastMutex( &pdx->OpenCloseMutex );
//
// clean up Bounded ECP shadow buffer
//
if( haveShadowBuffer ) {
Queue_Delete( &(pdx->ShadowBuffer) );
}
//
// if we still have a worker thread, kill it
//
if( threadObject ) {
if (!pdx->TimeToTerminateThread)
{
// set the flag for the worker thread to kill itself
pdx->TimeToTerminateThread = TRUE;
// wake up the thread so it can kill itself
KeReleaseSemaphore(&pdx->RequestSemaphore, 0, 1, FALSE );
}
// allow thread to get past PauseEvent so it can kill self
KeSetEvent( &pdx->PauseEvent, 0, TRUE );
// wait for the thread to die
KeWaitForSingleObject( threadObject, UserRequest, KernelMode, FALSE, NULL );
// allow the system to release the thread object
ObDereferenceObject( threadObject );
}
//
// update open handle count
//
{
ExAcquireFastMutex( &pdx->OpenCloseMutex );
InterlockedDecrement( &pdx->OpenCloseRefCount );
if( pdx->OpenCloseRefCount < 0) {
// catch possible underflow
pdx->OpenCloseRefCount = 0;
}
ExReleaseFastMutex(&pdx->OpenCloseMutex);
}
return P4CompleteRequest( Irp, STATUS_SUCCESS, 0 );
}