Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

363 lines
9.8 KiB

/*++
Copyright (c) Microsoft Corporation
Module Name:
OCRW.C
Abstract:
This source file contains the dispatch routines which handle
opening, closing, reading, and writing to the device, i.e.:
IRP_MJ_CREATE
IRP_MJ_CLOSE
IRP_MJ_READ
IRP_MJ_WRITE
Environment:
kernel mode
Revision History:
Sept 01 : KenRay
--*/
//*****************************************************************************
// I N C L U D E S
//*****************************************************************************
#include "genusb.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, GenUSB_Create)
#pragma alloc_text(PAGE, GenUSB_Close)
#pragma alloc_text(PAGE, GenUSB_Read)
#pragma alloc_text(PAGE, GenUSB_Write)
#endif
//******************************************************************************
//
// GenUSB_Create()
//
// Dispatch routine which handles IRP_MJ_CREATE
//
//******************************************************************************
NTSTATUS
GenUSB_Create (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS status;
DBGPRINT(2, ("enter: GenUSB_Create\n"));
DBGFBRK(DBGF_BRK_CREATE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
LOGENTRY(deviceExtension, 'CREA', DeviceObject, Irp, 0);
status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
if (!NT_SUCCESS(status)) {
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
// While there are several readers of the IsStarted state, it is only
// set at the end of GenUSB_StartDevice.
if (!deviceExtension->IsStarted)
{
LOGENTRY(deviceExtension, 'IOns', DeviceObject, Irp, 0);
status = STATUS_DEVICE_NOT_CONNECTED;
}
else if (1 != InterlockedIncrement (&deviceExtension->OpenedCount))
{
InterlockedDecrement (&deviceExtension->OpenedCount);
status = STATUS_SHARING_VIOLATION;
}
else
{
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
}
IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DBGPRINT(2, ("exit: GenUSB_Create\n"));
LOGENTRY(deviceExtension, 'crea', 0, 0, 0);
return status;
}
//******************************************************************************
//
// GenUSB_Close()
//
// Dispatch routine which handles IRP_MJ_CLOSE
//
//******************************************************************************
NTSTATUS
GenUSB_Close (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension;
//
// Never check the remove lock, or started for close.
//
DBGPRINT(2, ("enter: GenUSB_Close\n"));
DBGFBRK(DBGF_BRK_CLOSE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
LOGENTRY(deviceExtension, 'CLOS', DeviceObject, Irp, 0);
GenUSB_DeselectConfiguration (deviceExtension, TRUE);
InterlockedDecrement (&deviceExtension->OpenedCount);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DBGPRINT(2, ("exit: GenUSB_Close\n"));
LOGENTRY(deviceExtension, 'clos', 0, 0, 0);
return STATUS_SUCCESS;
}
//******************************************************************************
//
// GenUSB_ReadWrite()
//
// Dispatch routine which handles IRP_MJ_READ and IRP_MJ_WRITE
//
//******************************************************************************
NTSTATUS
GenUSB_ReadComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Unused,
IN USBD_STATUS UrbStatus,
IN ULONG Length
)
{
PDEVICE_EXTENSION deviceExtension;
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
LOGENTRY(deviceExtension, 'RedC', Irp, Length, UrbStatus);
IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
Irp->IoStatus.Information = Length;
return Irp->IoStatus.Status;
}
NTSTATUS
GenUSB_Read (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION irpSp;
DBGPRINT(2, ("enter: GenUSB_Read\n"));
DBGFBRK(DBGF_BRK_READWRITE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
LOGENTRY(deviceExtension, 'R ', DeviceObject, Irp, 0);
status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
if (!NT_SUCCESS(status)) {
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
// While there are several readers of the IsStarted state, it is only
// set at the end of GenUSB_StartDevice.
if (!deviceExtension->IsStarted)
{
LOGENTRY(deviceExtension, 'IOns', DeviceObject, Irp, 0);
status = STATUS_DEVICE_NOT_CONNECTED;
goto GenUSB_ReadReject;
}
irpSp = IoGetCurrentIrpStackLocation (Irp);
if (0 != irpSp->Parameters.Read.ByteOffset.QuadPart)
{
status = STATUS_NOT_IMPLEMENTED;
goto GenUSB_ReadReject;
}
//
// After talking extensively with JD, he tells me that I do not need
// to queue requests for power downs or query stop. If that is the
// case then even if the device power state isn't PowerDeviceD0 we
// can still allow trasfers. This, of course, is a property of the
// brand new port driver that went into XP.
//
// if (DeviceExtension->DevicePowerState != PowerDeviceD0)
// {
// }
//
//
// BUGBUG if we ever implement IDLE, we need to turn the device
// back on here.
//
return GenUSB_TransmitReceive (
deviceExtension,
Irp,
deviceExtension->ReadInterface,
deviceExtension->ReadPipe,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL,
Irp->MdlAddress,
irpSp->Parameters.Read.Length,
NULL,
GenUSB_ReadComplete);
GenUSB_ReadReject:
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
DBGPRINT(2, ("exit: GenUSB_Read %08X\n", status));
LOGENTRY(deviceExtension, 'r ', status, 0, 0);
return status;
}
NTSTATUS
GenUSB_WriteComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Unused,
IN USBD_STATUS UrbStatus,
IN ULONG Length
)
{
PDEVICE_EXTENSION deviceExtension;
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
LOGENTRY(deviceExtension, 'WrtC', Irp, Length, UrbStatus);
IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
Irp->IoStatus.Information = Length;
return Irp->IoStatus.Status;
}
NTSTATUS
GenUSB_Write (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION irpSp;
DBGPRINT(2, ("enter: GenUSB_Write\n"));
DBGFBRK(DBGF_BRK_READWRITE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
LOGENTRY(deviceExtension, 'W ', DeviceObject, Irp, 0);
status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
if (!NT_SUCCESS(status)) {
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
// While there are several readers of the IsStarted state, it is only
// set at the end of GenUSB_StartDevice.
if (!deviceExtension->IsStarted)
{
LOGENTRY(deviceExtension, 'IOns', DeviceObject, Irp, 0);
status = STATUS_DEVICE_NOT_CONNECTED;
goto GenUSB_WriteReject;
}
irpSp = IoGetCurrentIrpStackLocation (Irp);
if (0 != irpSp->Parameters.Write.ByteOffset.QuadPart)
{
status = STATUS_NOT_IMPLEMENTED;
goto GenUSB_WriteReject;
}
//
// After talking extensively with JD, he tells me that I do not need
// to queue requests for power downs or query stop. If that is the
// case then even if the device power state isn't PowerDeviceD0 we
// can still allow trasfers. This, of course, is a property of the
// brand new port driver that went into XP.
//
// if (DeviceExtension->DevicePowerState != PowerDeviceD0)
// {
// }
//
//
// BUGBUG if we ever implement IDLE, we need to turn the device
// back on here.
//
return GenUSB_TransmitReceive (
deviceExtension,
Irp,
deviceExtension->WriteInterface,
deviceExtension->WritePipe,
USBD_TRANSFER_DIRECTION_OUT,
NULL,
Irp->MdlAddress,
irpSp->Parameters.Read.Length,
NULL,
GenUSB_WriteComplete);
GenUSB_WriteReject:
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
DBGPRINT(2, ("exit: GenUSB_Write %08X\n", status));
LOGENTRY(deviceExtension, 'w ', status, 0, 0);
return status;
}