📄 usbfx2lk_devctrl.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2005 OSR Open Systems Resources, Inc.
// All Rights Reserved
//
// This sofware is supplied for instructional purposes only.
//
// OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
// for this software. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
// THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE. THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
// WITH YOU. OSR's entire liability and your exclusive remedy shall not
// exceed the price paid for this material. In no event shall OSR or its
// suppliers be liable for any damages whatsoever (including, without
// limitation, damages for loss of business profit, business interruption,
// loss of business information, or any other pecuniary loss) arising out
// of the use or inability to use this software, even if OSR has been
// advised of the possibility of such damages. Because some states/
// jurisdictions do not allow the exclusion or limitation of liability for
// consequential or incidental damages, the above limitation may not apply
// to you.
//
// OSR Open Systems Resources, Inc.
// 105 Route 101A Suite 19
// Amherst, NH 03031 (603) 595-6500 FAX: (603) 595-6503
// email bugs to: bugs@osr.com
//
//
// MODULE:
//
// USBFx2LK_DevCtrl.cpp
//
// ABSTRACT:
//
// This file contains the routines that handle IRP_MJ_DEVICE_CONTROL processing for the
// OSR USB FX2 Learning Kit Device
//
// AUTHOR(S):
//
// OSR Open Systems Resources, Inc.
//
///////////////////////////////////////////////////////////////////////////////
#include "usbfx2lk.h"
#ifdef WPP_TRACING
//
// Include the necessary tmh file - this is
// just a matter of course if you're using WPP tracing.
//
extern "C" {
#include "usbfx2lk_devctrl.tmh"
}
#endif
//
// Forward declarations
//
static LPCSTR IoctlToString(ULONG Ioctl);
///////////////////////////////////////////////////////////////////////////////
//
// UsbFx2LkDeviceControl
//
// This routine is called by the IO Manager to process a IRP_MJ_DEVICE_CONTROL
// Irp.
//
//
// INPUTS:
//
// DeviceObject - One of our Device Objects.
// Irp - The Irp to process.
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// User Context
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS UsbFx2LkDeviceControl(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);
PUSBFX2LK_EXT devExt = (PUSBFX2LK_EXT)DeviceObject->DeviceExtension;
ULONG ioctl;
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG inputBufferLength;
ULONG outputBufferLength;
ULONG bytesReturned;
KIRQL oldIrql;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_IOCTL_INFO,("UsbFx2LkDeviceControl: Entered\n"));
//
// We treat this routine as pageable
//
PAGED_CODE();
//
// Increment the count of outstanding IOs.
//
OsrIncrementOutstandingIoCount(devExt,__FILE__,__LINE__);
//
// See what sort of state we're in.
//
KeAcquireSpinLock(&devExt->IoStateLock,&oldIrql);
if (devExt->DevicePnPState < STATE_ALL_BELOW_FAIL) {
KeReleaseSpinLock(&devExt->IoStateLock,oldIrql);
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: Failing request due to Pnp State! Current PnP state - %s\n",
OsrPrintState(devExt)));
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// We're done with this request
//
OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
return STATUS_INVALID_DEVICE_STATE;
}
KeReleaseSpinLock(&devExt->IoStateLock,oldIrql);
//
// See which IOCTL the caller has sent us
//
ioctl = ioStack->Parameters.DeviceIoControl.IoControlCode;
//
// And get the buffer lengths.
//
inputBufferLength = ioStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength;
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_IOCTL_INFO, ("UsbFx2LkDeviceControl: Entered with IRP: 0x%p, IOCTL: 0x%x (%s)\n",
Irp, ioctl, IoctlToString(ioctl)));
switch (ioctl) {
case IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY: {
//
// This IOCTL doesn't use an input
// buffer. Make sure that the caller knows that
// and is playing by the rules.
//
if (inputBufferLength) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User passed an input buffer - Incorrect usage for this IOCTL\n"));
status = STATUS_INVALID_PARAMETER;
bytesReturned = 0;
break;
}
//
// Make sure the caller's output buffer is large enough
// to hold the state of the bar graph
//
if (outputBufferLength < sizeof(BAR_GRAPH_STATE)) {
//
// Let the user know how big the buffer was
// supposed to be
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User's output buffer is too small for this IOCTL, expecting an BAR_GRAPH_STATE\n"));
status = STATUS_BUFFER_TOO_SMALL;
bytesReturned = sizeof(BAR_GRAPH_STATE);
break;
}
//
// Post the IRP off to the get bar graph code.
// This request may pend while the device powers up,
// so just return whatever SubmitGetBarGraphState
// returns to us and don't touch the IRP
//
status = SubmitGetBarGraphState(devExt, Irp);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_SELECTIVE_SUSPEND,
("UsbFx2LkDeviceControl: SubmitGetBarGraphState returned "\
"0x%x (%s). Exiting...\n",
status,OsrNtStatusToString(status)));
return status;
}
case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: {
//
// This IOCTL doesn't use an output
// buffer. Make sure that the caller knows that
// and is playing by the rules.
//
if (outputBufferLength) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User passed an output buffer - Incorrect usage for this IOCTL\n"));
status = STATUS_INVALID_PARAMETER;
bytesReturned = 0;
break;
}
//
// Make sure the caller's input buffer is of the right size
//
if (inputBufferLength < sizeof(BAR_GRAPH_STATE)) {
//
// Let the user know how big the buffer was
// supposed to be
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User's input buffer is too small for this IOCTL, expecting an BAR_GRAPH_STATE\n"));
status = STATUS_BUFFER_TOO_SMALL;
bytesReturned = sizeof(BAR_GRAPH_STATE);
break;
}
//
// Post the IRP off to the set bar graph code.
// This request may pend while the device powers up,
// so just return whatever SubmitSetBarGraphState
// returns to us and don't touch the IRP
//
status = SubmitSetBarGraphState(devExt, Irp);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_SELECTIVE_SUSPEND,
("UsbFx2LkDeviceControl: SubmitSetBarGraphState returned "\
"0x%x (%s). Exiting...\n",
status,OsrNtStatusToString(status)));
return status;
}
case IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY: {
//
// This IOCTL doesn't use an input
// buffer. Make sure that the caller knows that
// and is playing by the rules.
//
if (inputBufferLength) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User passed an input buffer - Incorrect usage for this IOCTL\n"));
status = STATUS_INVALID_PARAMETER;
bytesReturned = 0;
break;
}
//
// Make sure the caller's output buffer is large enough
// to hold the state of the 7 segment
//
if (outputBufferLength < sizeof(UCHAR)) {
//
// Let the user know how big the buffer was
// supposed to be
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User's output buffer is too small for this IOCTL, expecting an UCHAR\n"));
status = STATUS_BUFFER_TOO_SMALL;
bytesReturned = sizeof(UCHAR);
break;
}
//
// Post the IRP off to the get seven segment code.
// This request may pend while the device powers up,
// so just return whatever SubmitGetSevenSegmentState
// returns to us and don't touch the IRP
//
status = SubmitGetSevenSegmentState(devExt, Irp);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_SELECTIVE_SUSPEND,
("UsbFx2LkDeviceControl: SubmitGetSevenSegmentState returned "\
"0x%x (%s). Exiting...\n",
status,OsrNtStatusToString(status)));
return status;
}
case IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY: {
//
// This IOCTL doesn't use an output
// buffer. Make sure that the caller knows that
// and is playing by the rules.
//
if (outputBufferLength) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User passed an output buffer - Incorrect usage for this IOCTL\n"));
status = STATUS_INVALID_PARAMETER;
bytesReturned = 0;
break;
}
//
// Make sure the caller's input buffer is of the right size
//
if (inputBufferLength < sizeof(UCHAR)) {
//
// Let the user know how big the buffer was
// supposed to be
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User's input buffer is too small for this IOCTL, expecting an UCHAR\n"));
status = STATUS_BUFFER_TOO_SMALL;
bytesReturned = sizeof(UCHAR);
break;
}
//
// Post the IRP off to the set seven segment code.
// This request may pend while the device powers up,
// so just return whatever SubmitSetSevenSegmentState
// returns to us and don't touch the IRP
//
status = SubmitSetSevenSegmentState(devExt, Irp);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_SELECTIVE_SUSPEND,
("UsbFx2LkDeviceControl: SubmitSetSevenSegmentState returned "\
"0x%x (%s). Exiting...\n",
status,OsrNtStatusToString(status)));
return status;
}
case IOCTL_OSRUSBFX2_READ_SWITCHES: {
//
// This IOCTL doesn't use an input
// buffer. Make sure that the caller knows that
// and is playing by the rules.
//
if (inputBufferLength) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User passed an input buffer - Incorrect usage for this IOCTL\n"));
status = STATUS_INVALID_PARAMETER;
bytesReturned = 0;
break;
}
//
// Make sure the caller's output buffer is large enough
// to hold the state of the switches
//
if (outputBufferLength < sizeof(SWITCH_STATE)) {
//
// Let the user know how big the buffer was
// supposed to be
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User's output buffer is too small for this IOCTL, expecting a SWITCH_STATE\n"));
status = STATUS_BUFFER_TOO_SMALL;
bytesReturned = sizeof(SWITCH_STATE);
break;
}
//
// Post the IRP off to the get switch state code.
// This request may pend while the device powers up,
// so just return whatever SubmitGetSwitchState
// returns to us and don't touch the IRP
//
status = SubmitGetSwitchState(devExt, Irp);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_SELECTIVE_SUSPEND,
("UsbFx2LkDeviceControl: SubmitGetSwitchState returned "\
"0x%x (%s). Exiting...\n",
status,OsrNtStatusToString(status)));
return status;
}
case IOCTL_OSRUSBFX2_RESET_PIPE: {
USBFX2_PIPE_ENUM whichPipe;
//
// This IOCTL uses no output buffer. Make sure
// that the caller knows that and is playing by the rules.
//
if (outputBufferLength) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_IOCTL_INFO,
("UsbFx2LkDeviceControl: User passed an output buffer - Incorrect usage for this IOCTL\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -