/*++ Copyright (c) 2000 Microsoft Corporation Module Name: openclos.c Abstract: This module contains the code that is very specific to initialization and unload operations in the irenum driver Author: Brian Lieuallen, 7-13-2000 Environment: Kernel mode Revision History : --*/ #include "internal.h" #include "ircomm.h" NTSTATUS IrCommCreate( PDEVICE_OBJECT DeviceObject, PIRP Irp ) { NTSTATUS Status=STATUS_SUCCESS; IRDA_HANDLE Handle; PFDO_DEVICE_EXTENSION DeviceExtension=(PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; UCHAR ControlBuffer[4]; IRCOMM_BUS_INFO BusInfo; if (InterlockedIncrement(&DeviceExtension->OpenCount) > 1) { D_ERROR(DbgPrint("IRCOMM: Create already open\n");) InterlockedDecrement(&DeviceExtension->OpenCount); Irp->IoStatus.Status=STATUS_ACCESS_DENIED; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_ACCESS_DENIED; } Status=QueryPdoInformation( DeviceExtension->Pdo, IRENUM_CONFIG_SPACE_INFO, &BusInfo, sizeof(BusInfo) ); if (NT_SUCCESS(Status)) { DeviceExtension->DeviceAddress=BusInfo.DeviceAddress; } Status=IrdaConnect( DeviceExtension->DeviceAddress, "IrDA:IrCOMM", BusInfo.OutGoingConnection, &DeviceExtension->ConnectionHandle, DataAvailibleHandler, EventNotification, DeviceExtension ); D_TRACE(DbgPrint("IRCOMM: Create %08lx\n",Status);) if (NT_SUCCESS(Status)) { DeviceExtension->HandFlow.ControlHandShake=SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE; DeviceExtension->HandFlow.FlowReplace=SERIAL_RTS_HANDSHAKE; } else { // // could not creat the connection // goto CleanUp; } Irp->IoStatus.Status=Status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return Status; CleanUp: // // something failed, undo what we did in this function // if (DeviceExtension->ConnectionHandle != NULL) { FreeConnection(DeviceExtension->ConnectionHandle); DeviceExtension->ConnectionHandle=NULL; } InterlockedDecrement(&DeviceExtension->OpenCount); Irp->IoStatus.Status=Status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return Status; } NTSTATUS IrCommClose( PDEVICE_OBJECT DeviceObject, PIRP Irp ) { PFDO_DEVICE_EXTENSION DeviceExtension=(PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS Status=STATUS_SUCCESS; FreeConnection(DeviceExtension->ConnectionHandle); DeviceExtension->ConnectionHandle=NULL; InterlockedDecrement(&DeviceExtension->OpenCount); Irp->IoStatus.Status=Status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return Status; } VOID CleanupIoRequests( PFDO_DEVICE_EXTENSION DeviceExtension ) { KIRQL OldIrql; PIRP WaitIrp=NULL; FlushQueuedPackets(&DeviceExtension->Write.Queue,FLUSH_ALL_IRPS); FlushQueuedPackets(&DeviceExtension->Read.Queue,FLUSH_ALL_IRPS); ReadPurge(DeviceExtension,0); FlushQueuedPackets(&DeviceExtension->Mask.Queue,FLUSH_ALL_IRPS); FlushQueuedPackets(&DeviceExtension->Uart.Queue,FLUSH_ALL_IRPS); KeAcquireSpinLock(&DeviceExtension->Mask.Lock,&OldIrql); WaitIrp=DeviceExtension->Mask.CurrentWaitMaskIrp; DeviceExtension->Mask.CurrentWaitMaskIrp=NULL; KeReleaseSpinLock(&DeviceExtension->Mask.Lock,OldIrql); if (WaitIrp != NULL) { WaitIrp->IoStatus.Status=STATUS_CANCELLED; WaitIrp->IoStatus.Information=0; IoCompleteRequest(WaitIrp,IO_NO_INCREMENT); } return; } NTSTATUS IrCommCleanup( PDEVICE_OBJECT DeviceObject, PIRP Irp ) { PFDO_DEVICE_EXTENSION DeviceExtension=(PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS Status=STATUS_SUCCESS; D_TRACE(DbgPrint("IRCOMM: Cleanup\n");) CleanupIoRequests(DeviceExtension); Irp->IoStatus.Status=Status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return Status; } NTSTATUS IrCommQueryInformation( PDEVICE_OBJECT DeviceObject, PIRP Irp ) { PFDO_DEVICE_EXTENSION DeviceExtension=(PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS Status=STATUS_SUCCESS; Irp->IoStatus.Status=Status; Irp->IoStatus.Information=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return Status; }