windows-nt/Source/XPSP1/NT/net/unimodem/sample/sys/open.c
2020-09-26 16:20:57 +08:00

152 lines
3.1 KiB
C

/*
* UNIMODEM "Fakemodem" controllerless driver illustrative example
*
* (C) 2000 Microsoft Corporation
* All Rights Reserved
*
*/
#include "fakemodem.h"
NTSTATUS
FakeModemOpen(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
NTSTATUS status=STATUS_UNSUCCESSFUL;
KIRQL OldIrql;
// make sure the device is ready for irp's
status=CheckStateAndAddReference( DeviceObject, Irp);
if (STATUS_SUCCESS != status) {
// not accepting irp's. The irp has already been complted
return status;
}
KeAcquireSpinLock(&deviceExtension->SpinLock, &OldIrql);
deviceExtension->OpenCount++;
if (deviceExtension->OpenCount != 1) {
//
// serial devices are exclusive
//
status=STATUS_ACCESS_DENIED;
deviceExtension->OpenCount--;
} else {
//
// ok to open, init some stuff
//
deviceExtension->ReadBufferBegin=0;
deviceExtension->ReadBufferEnd=0;
deviceExtension->BytesInReadBuffer=0;
deviceExtension->CommandMatchState=COMMAND_MATCH_STATE_IDLE;
deviceExtension->ModemStatus=SERIAL_DTR_STATE | SERIAL_DSR_STATE;
deviceExtension->CurrentlyConnected=FALSE;
deviceExtension->ConnectionStateChanged=FALSE;
}
KeReleaseSpinLock( &deviceExtension->SpinLock, OldIrql);
Irp->IoStatus.Information = 0;
RemoveReferenceAndCompleteRequest( DeviceObject, Irp, status);
RemoveReferenceForDispatch(DeviceObject);
return status;
}
NTSTATUS
FakeModemClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
NTSTATUS status=STATUS_SUCCESS;
KIRQL OldIrql;
KeAcquireSpinLock(&deviceExtension->SpinLock, &OldIrql);
deviceExtension->OpenCount--;
KeReleaseSpinLock(&deviceExtension->SpinLock, OldIrql);
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_SERIAL_INCREMENT);
return status;
}
NTSTATUS
FakeModemCleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
NTSTATUS status=STATUS_SUCCESS;
FakeModemKillPendingIrps(DeviceObject);
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_SERIAL_INCREMENT);
return status;
}
void
FakeModemKillPendingIrps(
PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION pDeviceExtension = DeviceObject->DeviceExtension;
KIRQL oldIrql;
// Kill all reads
FakeModemKillAllReadsOrWrites(DeviceObject,
&pDeviceExtension->ReadQueue, &pDeviceExtension->CurrentReadIrp);
// Kill all writes
FakeModemKillAllReadsOrWrites(DeviceObject,
&pDeviceExtension->WriteQueue, &pDeviceExtension->CurrentWriteIrp);
// Remove any mask operations
FakeModemKillAllReadsOrWrites(DeviceObject,
&pDeviceExtension->MaskQueue, &pDeviceExtension->CurrentMaskIrp);
}