230 lines
4.5 KiB
C
230 lines
4.5 KiB
C
/*++
|
|
|
|
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;
|
|
|
|
}
|