|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
ioctl.c
Abstract:
USB device driver for Intel/Microsoft diagnostic apps
Environment:
kernel mode only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
Revision History:
5-4-96 : created 7-21-97 : Added Chapter 11 IOCTL's (t-toddca)
--*/
#define DRIVER
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
// Enable 1-byte alignment in structs
#pragma pack (push,1)
#include "usb100.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "usbioctl.h"
#pragma pack (pop) //disable 1-byte alignment
#include "opaque.h"
// Enable 1-byte alignment in structs
#pragma pack (push,1)
#include "ioctl.h"
#include "chap9drv.h"
#include "USBDIAG.h"
#pragma pack (pop) //disable 1-byte alignment
extern USBD_VERSION_INFORMATION gVersionInformation;
NTSTATUS USBDIAG_ProcessIOCTL( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++
Routine Description:
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930 devcice.
Return Value:
NT status code
--*/ { PIO_STACK_LOCATION irpStack; PVOID ioBuffer; ULONG inputBufferLength; ULONG outputBufferLength; PDEVICE_EXTENSION deviceExtension; ULONG ioControlCode; NTSTATUS ntStatus = STATUS_SUCCESS; USBDIAG_KdPrint(("USBDIAG.SYS: IRP_MJ_DEVICE_CONTROL\n")); //
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0;
//
// Get a pointer to the device extension
//
deviceExtension = DeviceObject->DeviceExtension;
//USBDIAG_KdPrint(("USBDIAG.SYS: DeviceObj: %X | DeviceExt: %X\n",DeviceObject, DeviceObject->DeviceExtension));
ioBuffer = Irp->AssociatedIrp.SystemBuffer; inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; USBDIAG_KdPrint(("USBDIAG.SYS: IOControlCode: %X\n", ioControlCode));
//
// Handle Ioctls from User mode
//
switch (ioControlCode) {
case IOCTL_USBDIAG_GET_USBDI_VERSION: { PULONG pulUSBDIVersion = (PULONG)ioBuffer;
*pulUSBDIVersion = gVersionInformation.USBDI_Version; Irp->IoStatus.Status = ntStatus = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(ULONG); } break;
case IOCTL_USBDIAG_CHAP9_GET_DEVHANDLE:
{ //
// inputs - ptr to _REQ_DEVICE_HANDLES structure
// with devicehandle set to the last handle
// returned or NULL.
// outputs -
//
struct _REQ_DEVICE_HANDLES *reqDeviceHandles; PDEVICE_LIST_ENTRY device; PDEVICE_EXTENSION localDeviceExtension; PDEVICE_OBJECT deviceObject;
//USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_CHAP9_GET_DEVHANDLE\n"));
// walk our list of PDOs and find the current one
// if cuurent is NULL return the first PDO in our list
// if current can not be found then return NULL for next_device
reqDeviceHandles = ioBuffer;
//
// Check that the buffer length is of the appropriate size
//
if (inputBufferLength < sizeof(struct _REQ_DEVICE_HANDLES) || outputBufferLength < sizeof(struct _REQ_DEVICE_HANDLES)) {
Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE; break; }
device = deviceExtension->DeviceList;
// should always have at least one
if (device != NULL) { if (reqDeviceHandles->DeviceHandle != NULL) { //
// Searching for the next device in the list
//
while (device != NULL && device != reqDeviceHandles->DeviceHandle) { device = device->Next; }
//
// Make device point to the next possible device in our list,
// if we haven't reached the end of the list
//
if (NULL != device) { device = device -> Next; } }
//
// At this point, device is either NULL or points to a usbdiag
// device. However, the diag device may not yet be started and
// if so, should not be reported in this query so we must skip
// over it. We will skip over all such devices in our list.
// Do that here.
//
while (device != NULL) { deviceObject = FDO_FROM_DEVICE_HANDLE(device);
localDeviceExtension = deviceObject -> DeviceExtension;
if (!(localDeviceExtension -> Stopped)) { //
// Found a legit started device, break out of this loop
//
break; }
//
// Oops, we've got a device but it hasn't been started yet,
// don't return it in the query. Try the next one in the list.
//
device = device -> Next; }
//
// At this point, device is either NULL or points to a device that
// can be legitimately returned to the calling app. If a legit
// device, then create a device string for it.
//
if (NULL != device) { sprintf(reqDeviceHandles->DeviceString, "%2.2d Vid (0x%4.4x) Pid (0x%4.4x)", device->DeviceNumber, localDeviceExtension->pDeviceDescriptor->idVendor, localDeviceExtension->pDeviceDescriptor->idProduct); } } reqDeviceHandles -> NextDeviceHandle = device; Irp->IoStatus.Information = sizeof(struct _REQ_DEVICE_HANDLES); Irp->IoStatus.Status = STATUS_SUCCESS; } break;
case IOCTL_USBDIAG_CHAP9_CONTROL:
//
// inputs -
// outputs -
//
//USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_CHAP9_CONTROL\n"));
ntStatus = USBDIAG_Chap9Control(DeviceObject, Irp); //USBDIAG_KdPrint(("USBDIAG.SYS: Done w/ IOCTL_USBDIAG_CHAP9_CONTROL\n"));
goto USBDIAG_ProcessIOCTL_Done; break;
case IOCTL_USBDIAG_HIDP_GETCOLLECTION: /*
// calls thru to the HID Parser
// NOTE: The function called will complete the IRP since it will
// free the buffers created by the HID parser immediately
// thereafter, and since BUFFERED method is used, the IOS
// needs the buffers to be present while it's copying it
// back to the user space. So, we jump to the end to avoid this.
*/ //USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_HIDP_GETCOLLECTION\n"));
ntStatus = USBDIAG_HIDP_GetCollection (DeviceObject, Irp); break;
case IOCTL_USBDIAG_CONFIGURE_DEVICE:
/*
// Configures a given device in the given configuration
// Input: IOCTL block indicating what configuration to put
// device into
// Output: Success/error code
//
*/ //USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_CONFIGURE_DEVICE\n"));
ntStatus = USBDIAG_Configure_Device (DeviceObject, Irp);
break;
default: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; }
//USBDIAG_KdPrint(("USBDIAG.SYS: Chap9Ctrl Compltng Irp w/ IoStatus.Status=%X | .Inf = %X | ntSt=%X\n",
//Irp->IoStatus.Status, Irp->IoStatus.Information, ntStatus));
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
USBDIAG_ProcessIOCTL_Done:
return ntStatus; }
|