www.pudn.com > usbboot-v1.2.rar.zip > Usb_Boot_Driver_Device.cpp, change:2007-09-05,size:43975b
// Jz4740_usbDevice.cpp
// Implementation of Jz4740_usbDevice device class
//
// Generated by DriverWizard version DriverStudio 3.1.0 (Build 1722)
// Requires Compuware's DriverWorks classes
//
#pragma warning(disable:4065) // Allow switch statement with no cases
#include <vdw.h>
#include <kusb.h>
#include <stdio.h>
#include <stdlib.h>
#include "Usb_Boot_Interface.h"
#include "Usb_Boot_Driver.h"
#include "Usb_Boot_Driver_Device.h"
#include "Usb_Boot_Ioctl.h"
#pragma hdrstop("Usb_Boot_Driver.pch")
extern KDebugOnlyTrace t; // Global driver trace object
UCHAR Jz4740_usbDevice::dev_n = 0;
GUID Jz4740_usbDevice_Guid = Jz4740_usbDevice_CLASS_GUID;
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::Jz4740_usbDevice
//
// Routine Description:
// This is the constructor for the Functional Device Object, or FDO.
// It is derived from KPnpDevice, which builds in automatic
// dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP to
// virtual member functions.
//
// Parameters:
// Pdo - Physical Device Object - this is a pointer to a system
// device object that represents the physical device.
//
// Unit - Unit number. This is a number to append to the device's
// base device name to form the Logical Device Object's name
//
// Return Value:
// None
//
// Comments:
// The object being constructed contains a data member (m_Lower) of type
// KPnpLowerDevice. By initializing it, the driver binds the FDO to the
// PDO and creates an interface to the upper edge of the system class driver.
//
Jz4740_usbDevice::Jz4740_usbDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KPnpDevice(Pdo, &Jz4740_usbDevice_Guid)
{
t << "Entering Jz4740_usbDevice::Jz4740_usbDevice (constructor)\n";
// Check constructor status
if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
return;
}
// Remember our unit number
m_Unit = Unit;
if (dev_n<16) dev_n ++;
// Initialize the lower device
m_Lower.Initialize(this, Pdo);
// Initialize the interface object. The wizard generates code
// to support a single interface. You may create and add additional
// interfaces. By default, the wizard uses InterfaceNumber 0 (the
// first interface descriptor), ConfigurationValue 1 (the first
// configuration descriptor), and initial interface alternate
// setting of 0. If your device has multiple interfaces or alternate
// settings for an interface, you can add additional KUsbInterface
// objects or adjust the parameters passed to this function.
m_Interface.Initialize(
m_Lower, //KUsbLowerDevice
0, //InterfaceNumber
1, //ConfigurationValue
0 //Initial Interface Alternate Setting
);
// Initialize each Pipe object
//m_Endpoint1OUT.Initialize(m_Lower, 0x1, 1048576);
//m_Endpoint1IN.Initialize(m_Lower, 0x81, 1048576);
m_Endpoint1OUT.Initialize(m_Lower, 0x1, 0x400000);
m_Endpoint1IN.Initialize(m_Lower, 0x81, 0x400000);
// Inform the base class of the lower edge device object
SetLowerDevice(&m_Lower);
// Initialize the PnP Policy settings to the "standard" policy
SetPnpPolicy();
// TODO: Customize the PnP Policy for this device by setting
// flags in m_Policies.
// Initialize the Power Policy settings to the "standard" policy
SetPowerPolicy();
// TODO: Customize the Power Policy for this device by setting
// flags in m_PowerPolicies.
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::~Jz4740_usbDevice
//
// Routine Description:
// This is the destructor for the Functional Device Object, or FDO.
//
// Parameters:
// None
//
// Return Value:
// None
//
// Comments:
// None
//
Jz4740_usbDevice::~Jz4740_usbDevice()
{
t << "Entering Jz4740_usbDevice::~Jz4740_usbDevice() (destructor)\n";
if (dev_n>0) Jz4740_usbDevice::dev_n -- ;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::DefaultPnp
//
// Routine Description:
// Default handler for IRP_MJ_PNP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_PNP. IRPs that correspond to
// any virtual members of KpnpDevice that handle minor functions of
// IRP_MJ_PNP and that are not overridden get passed to this routine.
//
NTSTATUS Jz4740_usbDevice::DefaultPnp(KIrp I)
{
ULONG Fun;
PIO_STACK_LOCATION IS;
t << "Entering Jz4740_usbDevice::DefaultPnp\n" << I << EOL;
I.ForceReuseOfCurrentStackLocationInCalldown();
IS = IoGetCurrentIrpStackLocation(I);
Fun = IS->MajorFunction;
switch (Fun)
{
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
return this->OnRemoveDevice(I);
//case IRP_
break;
default:
return m_Lower.PnpCall(this, I);
}
return m_Lower.PnpCall(this, I);
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::DefaultPower
//
// Routine Description:
// Default handler for IRP_MJ_POWER
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_POWER.
//
NTSTATUS Jz4740_usbDevice::DefaultPower(KIrp I)
{
t << "Entering Jz4740_usbDevice::DefaultPower\n" << I << EOL;
I.IndicatePowerIrpProcessed();
I.CopyParametersDown();
return m_Lower.PnpPowerCall(this, I);
}
////////////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::SystemControl
//
// Routine Description:
// Default handler for IRP_MJ_SYSTEM_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the next device since this driver
// is not a WMI provider.
//
NTSTATUS Jz4740_usbDevice::SystemControl(KIrp I)
{
t << "Entering Jz4740_usbDevice::SystemControl\n";
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::OnStartDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// Typically, the driver sends a SET CONFIGURATION request for the
// USB device by using KUsbLowerDevice::ActivateConfiguration with
// the ConfigurationValue to activate. The wizard generates code to
// support a single configuration. You may create and add additional
// configurations.
//
NTSTATUS Jz4740_usbDevice::OnStartDevice(KIrp I)
{
t << "Entering Jz4740_usbDevice::OnStartDevice\n";
NTSTATUS status = STATUS_UNSUCCESSFUL;
AC_STATUS acStatus = AC_SUCCESS;
I.Information() = 0;
// The default Pnp policy has already cleared the IRP with the lower device
//By default, the wizard passes a ConfigurationValue of 1 to
//ActivateConfiguration(). This corresponds to the first configuration
//that the device reports in its configuration descriptor. If the device
//supports multiple configurations, pass the appropriate
//ConfigurationValue of the configuration to activate here.
acStatus = m_Lower.ActivateConfiguration(
1 // ConfigurationValue 1 (the first configuration)
);
switch (acStatus)
{
case AC_SUCCESS:
t << "USB Configuration OK\n";
status = STATUS_SUCCESS;
break;
case AC_COULD_NOT_LOCATE_INTERFACE:
t << "Could not locate interface\n";
break;
case AC_COULD_NOT_PRECONFIGURE_INTERFACE:
t << "Could not get configuration descriptor\n";
break;
case AC_CONFIGURATION_REQUEST_FAILED:
t << "Board did not accept configuration URB\n";
break;
case AC_FAILED_TO_INITIALIZE_INTERFACE_OBJECT:
t << "Failed to initialize interface object\n";
break;
case AC_FAILED_TO_GET_DESCRIPTOR:
t << "Failed to get device descriptor\n";
break;
case AC_FAILED_TO_OPEN_PIPE_OBJECT:
//NOTE: this may not be an error. It could mean that
//the device has an endpoint for which a KUsbPipe object has
//not been instanced. If the intention is to not use this endpoint,
//then it's likely not a problem.
status = STATUS_SUCCESS;
t << "Failed to open pipe object\n";
break;
default:
t << "Unexpected error activating USB configuration\n";
break;
}
return status; // base class completes the IRP
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::OnStopDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is stopped.
// The driver should release any hardware resources
// in this routine.
//
// The base class passes the irp to the lower device.
//
NTSTATUS Jz4740_usbDevice::OnStopDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering Jz4740_usbDevice::OnStopDevice\n";
//if (dev_n>0) Jz4740_usbDevice::dev_n -- ;
m_Lower.DeActivateConfiguration();
// TODO: Add device-specific code to stop your device
return status;
// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::OnRemoveDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is removed.
// Our PnP policy will take care of
// (1) giving the IRP to the lower device
// (2) detaching the PDO
// (3) deleting the device object
//
NTSTATUS Jz4740_usbDevice::OnRemoveDevice(KIrp I)
{
t << "Entering Jz4740_usbDevice::OnRemoveDevice\n";
if (dev_n>0) Jz4740_usbDevice::dev_n -- ;
// Device removed, release the system resources used by the USB lower device.
m_Lower.ReleaseResources();
// TODO: Add device-specific code to remove your device
return STATUS_SUCCESS;
// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::OnDevicePowerUp
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to power on state from low power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDevicePowerUp function.
// This function was called by the framework from the completion
// routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
// The bus driver has completed the IRP and this driver can now
// access the hardware device.
// This routine runs at dispatch level.
//
NTSTATUS Jz4740_usbDevice::OnDevicePowerUp(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering Jz4740_usbDevice::OnDevicePowerUp\n";
// TODO: Service the device.
// Restore any context to the hardware device that
// was saved during the handling of a power down request.
// See the OnDeviceSleep function.
// Do NOT complete this IRP.
//
return status;
// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::OnDeviceSleep
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to a low power state from a high power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDeviceSleep function.
// This function was called by the framework from the IRP_MJ_POWER
// dispatch handler in KPnpDevice prior to forwarding to the PDO.
// The hardware has yet to be powered down and this driver can now
// access the hardware device.
// This routine runs at passive level.
//
NTSTATUS Jz4740_usbDevice::OnDeviceSleep(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering Jz4740_usbDevice::OnDeviceSleep\n";
// TODO: Service the device.
// Save any context to the hardware device that will be required
// during a power up request. See the OnDevicePowerUp function.
// Do NOT complete this IRP. The base class handles forwarding
// this IRP to the PDO.
//
return status;
// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::Create
//
// Routine Description:
// Handler for IRP_MJ_CREATE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS Jz4740_usbDevice::Create(KIrp I)
{
NTSTATUS status;
t << "Entering Jz4740_usbDevice::Create, " << I << EOL;
// TODO: Add driver specific create handling code here
// Generally a create IRP is targeted at our FDO, so we don't need
// to pass it down to the PDO. We have found for some devices, the
// PDO is not expecting this Irp and returns an error code.
// The default wizard code, therefore completes the Irp here using
// PnpComplete(). The following commented code could be used instead
// of PnpComplete() to pass the Irp to the PDO, which would complete it.
//
// I.ForceReuseOfCurrentStackLocationInCalldown();
// status = m_Lower.PnpCall(this, I);
status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
t << "Jz4740_usbDevice::Create Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS Jz4740_usbDevice::Close(KIrp I)
{
NTSTATUS status;
t << "Entering Jz4740_usbDevice::Close, " << I << EOL;
// TODO: Add driver specific close handling code here
// Generally a close IRP is targeted at our FDO, so we don't need
// to pass it down to the PDO. We have found for some devices, the
// PDO is not expecting this Irp and returns an error code.
// The default wizard code, therefore completes the Irp here using
// PnpComplete(). The following commented code could be used instead
// of PnpComplete() to pass the Irp to the PDO, which would complete it.
//
// I.ForceReuseOfCurrentStackLocationInCalldown();
// status = m_Lower.PnpCall(this, I);
status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
t << "Jz4740_usbDevice::Close Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::Cleanup
//
// Routine Description:
// Handler for IRP_MJ_CLEANUP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS Jz4740_usbDevice::CleanUp(KIrp I)
{
t << "Entering CleanUp, " << I << EOL;
// TODO: Insert your code to respond to the CLEANUP message.
return I.PnpComplete(this, STATUS_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::Read
//
// Routine Description:
// Handler for IRP_MJ_READ
//
// Parameters:
// I Current IRP
//
// Return Value:
// NTSTATUS Result code
//
// Comments:
// This routine handles read requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS Jz4740_usbDevice::Read(KIrp I)
{
t << "Entering Jz4740_usbDevice::Read, " << I << EOL;
// TODO: Check the incoming request. Replace "FALSE" in the following
// line with a check that returns TRUE if the request is not valid.
if (FALSE) // If (Request is invalid)
{
// Invalid parameter in the Read request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}
// Always ok to read 0 elements.
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Declare a memory object
KMemory Mem(I.Mdl());
ULONG dwTotalSize = I.ReadSize(CURRENT);
ULONG dwMaxSize = m_Endpoint1IN.MaximumTransferSize();
// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}
// Allocate a new context structure for Irp completion
USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
if (pCompInfo == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// TODO: Select the correct pipe to read from
// Create an URB to do actual Bulk read from the pipe
PURB pUrb = m_Endpoint1IN.BuildBulkTransfer(
Mem, // Where is data coming from?
dwTotalSize, // How much data to read?
TRUE, // direction (TRUE = IN)
NULL, // Link to next URB
TRUE // Allow a short transfer
);
if (pUrb == NULL)
{
delete pCompInfo;
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// Initialize context structure
pCompInfo->m_pClass = this;
pCompInfo->m_pUrb = pUrb;
// Submit the URB to our USB device
NTSTATUS status;
status = m_Endpoint1IN.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::ReadComplete
//
// Routine Description:
// Completion Handler for IRP_MJ_READ
//
// Parameters:
// I - IRP just completed by USB
// pContext - Context structure containing pointer to Urb
//
// Parameters:
// NTSTATUS - STATUS_SUCCESS
//
// Comments:
// This routine is called when USBD completes the read request
//
NTSTATUS Jz4740_usbDevice::ReadComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
// Normal completion routine code to propagate pending flag
if (I->PendingReturned)
{
I.MarkPending();
}
NTSTATUS status = I.Status();
PURB pUrb = pContext->m_pUrb;
ULONG nBytesRead = 0;
if ( NT_SUCCESS(status) )
{
nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (nBytesRead > 0)
t << "Read() got " << nBytesRead<< " bytes from USB\n";
}
// Deallocate Urb and context structure
delete pUrb;
delete pContext;
// set returned count
I.Information() = nBytesRead;
// Plug and Play accounting
DecrementOutstandingRequestCount();
// allow IRP completion processing
return STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::Write
//
// Routine Description:
// Handler for IRP_MJ_WRITE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// This routine handles write requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS Jz4740_usbDevice::Write(KIrp I)
{
t << "Entering Jz4740_usbDevice::Write, " << I << EOL;
// TODO: Check the incoming request. Replace "FALSE" in the following
// line with a check that returns TRUE if the request is not valid.
if (FALSE)
{
// Invalid parameter in the Write request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}
// Always ok to write 0 elements.
if (I.WriteSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
ULONG dwTotalSize = I.WriteSize(CURRENT);
ULONG dwMaxSize = m_Endpoint1OUT.MaximumTransferSize();
// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}
// Declare a memory object
KMemory Mem(I.Mdl());
// Allocate a new context structure for Irp completion
USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
if (pCompInfo == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// TODO: Select the correct pipe to write to
// Create an URB to do actual Bulk write to the pipe
PURB pUrb = m_Endpoint1OUT.BuildBulkTransfer(
Mem, // Where is data coming from?
dwTotalSize, // How much data to read?
FALSE, // direction (FALSE = OUT)
NULL // Link to next URB
);
if (pUrb == NULL)
{
delete pCompInfo;
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// Initialize context structure
pCompInfo->m_pClass = this;
pCompInfo->m_pUrb = pUrb;
// Submit the URB to our USB device
NTSTATUS status;
status = m_Endpoint1OUT.SubmitUrb(I, pUrb, LinkTo(WriteComplete), pCompInfo, 0);
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::WriteComplete
//
// Routine Description:
// Completion Handler for IRP_MJ_WRITE
//
// Parameters:
// I - IRP just completed by USB
// pContext - Context structure containing pointer to Urb
//
// Return Value:
// NTSTATUS STATUS_SUCCESS
//
// Comments:
// This routine is called when USBD completes the write request
//
NTSTATUS Jz4740_usbDevice::WriteComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
// Normal completion routine code to propagate pending flag
if (I->PendingReturned)
{
I.MarkPending();
}
NTSTATUS status = I.Status();
PURB pUrb = pContext->m_pUrb;
ULONG nBytesWritten = 0;
if ( NT_SUCCESS(status) )
{
nBytesWritten = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (nBytesWritten > 0)
t << "Wrote " << nBytesWritten << " bytes to USB\n";
}
// Deallocate Urb and context structure
delete pUrb;
delete pContext;
// set returned count
I.Information() = nBytesWritten;
// Plug and Play accounting
DecrementOutstandingRequestCount();
// allow IRP completion processing
return STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::DeviceControl
//
// Routine Description:
// Handler for IRP_MJ_DEVICE_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is the first handler for Device Control requests.
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS Jz4740_usbDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering Jz4740_usbDevice::Device Control, " << I << EOL;
switch (I.IoctlCode())
{
case JZ4740_USB_IOCTL_GET_CPU_INFO:
status = JZ4740_USB_IOCTL_GET_CPU_INFO_Handler(I);
break;
case JZ4740_USB_IOCTL_SET_DATA_ADDRESS:
status = JZ4740_USB_IOCTL_SET_DATA_ADDRESS_Handler(I);
break;
case JZ4740_USB_IOCTL_SET_DATA_LENGTH:
status = JZ4740_USB_IOCTL_SET_DATA_LENGTH_Handler(I);
break;
case JZ4740_USB_IOCTL_FLUSH_CACHES:
status = JZ4740_USB_IOCTL_FLUSH_CACHES_Handler(I);
break;
case JZ4740_USB_IOCTL_PROG_START1:
status = JZ4740_USB_IOCTL_PROG_START1_Handler(I);
break;
case JZ4740_USB_IOCTL_PROG_START2:
status = JZ4740_USB_IOCTL_PROG_START2_Handler(I);
break;
case JZ4740_USB_IOCTL_NOR_OPS:
status = JZ4740_USB_IOCTL_NOR_OPS_Handler(I);
break;
case JZ4740_USB_IOCTL_NAND_OPS:
status = JZ4740_USB_IOCTL_NAND_OPS_Handler(I);
break;
case JZ4740_USB_IOCTL_CONFIGRATION:
status = JZ4740_USB_IOCTL_CONFIGRATION_Handler(I);
break;
case JZ4740_USB_IOCTL_GET_NUM:
status = JZ4740_USB_IOCTL_GET_NUM_Handler(I);
break;
case JZ4740_USB_IOCTL_SDRAM_OPS:
status = JZ4740_USB_IOCTL_SDRAM_OPS_Handler(I);
break;
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}
// If the IRP's IOCTL handler deferred processing using some driver
// specific scheme, the status variable is set to STATUS_PENDING.
// In this case we simply return that status, and the IRP will be
// completed later. Otherwise, complete the IRP using the status
// returned by the IOCTL handler.
if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::JZ4740_USB_IOCTL_GET_CPU_INFO_Handler
//
// Routine Description:
// Handler for IO Control Code JZ4740_USB_IOCTL_GET_CPU_INFO
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the JZ4740_USB_IOCTL_GET_CPU_INFO function.
// This routine runs at passive level.
//
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_GET_CPU_INFO_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwOutputBufferSize = I.IoctlOutputBufferSize();
PUCHAR OutputBuf = reinterpret_cast<PUCHAR>(pBuffer);
ULONG ret;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_GET_CPU_INFO_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_GET_CPU_INFO request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
PURB pUrb = m_Lower.BuildVendorRequest(
OutputBuf, //TransferBuffer
8, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_GET_CPU_INFO, //Request
0, //Value
TRUE, //bIn
FALSE, //bShortOk
NULL, //Link
0, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 8;
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::JZ4740_USB_IOCTL_SET_DATA_ADDRESS_Handler
//
// Routine Description:
// Handler for IO Control Code JZ4740_USB_IOCTL_SET_DATA_ADDRESS
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the JZ4740_USB_IOCTL_SET_DATA_ADDRESS function.
// This routine runs at passive level.
//
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_SET_DATA_ADDRESS_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
ULONG ret;
unsigned int addr;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_SET_DATA_ADDRESS_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
t << "InputBufferSize: " << dwInputBufferSize << EOL;
t << "InputBuf: " << InputBuf[0] << InputBuf[1] << InputBuf[2] << InputBuf[3] << EOL;
// TODO: Handle the the JZ4740_USB_IOCTL_SET_DATA_ADDRESS request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
addr = *(unsigned int *)InputBuf;
t << "ADDR: " << addr << EOL;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_SET_DATA_ADDRESS, //Request
addr >> 16, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
addr & 0xffff, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::JZ4740_USB_IOCTL_SET_DATA_LENGTH_Handler
//
// Routine Description:
// Handler for IO Control Code JZ4740_USB_IOCTL_SET_DATA_LENGTH
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the JZ4740_USB_IOCTL_SET_DATA_LENGTH function.
// This routine runs at passive level.
//
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_SET_DATA_LENGTH_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
ULONG ret;
unsigned int len;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_SET_DATA_LENGTH_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
t << "InputBufferSize: " << dwInputBufferSize << EOL;
t << "InputBuf: " << InputBuf[0] << InputBuf[1] << InputBuf[2] << InputBuf[3] << EOL;
// TODO: Handle the the JZ4740_USB_IOCTL_SET_DATA_LENGTH request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
len = *(unsigned int *)InputBuf;
t << "LEN: " << len << EOL;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_SET_DATA_LENGTH, //Request
len >> 16, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
len & 0xffff, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::JZ4740_USB_IOCTL_FLUSH_CACHES_Handler
//
// Routine Description:
// Handler for IO Control Code JZ4740_USB_IOCTL_FLUSH_CACHES
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the JZ4740_USB_IOCTL_FLUSH_CACHES function.
// This routine runs at passive level.
//
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_FLUSH_CACHES_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_FLUSH_CACHES_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_FLUSH_CACHES request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_FLUSH_CACHES, //Request
0, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
0, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::JZ4740_USB_IOCTL_PROG_START1_Handler
//
// Routine Description:
// Handler for IO Control Code JZ4740_USB_IOCTL_PROG_START1
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the JZ4740_USB_IOCTL_PROG_START1 function.
// This routine runs at passive level.
//
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_PROG_START1_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
ULONG ret;
unsigned int addr;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_PROG_START1_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_PROG_START1 request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
addr= *(unsigned int *)InputBuf;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_PROG_START1, //Request
addr>>16, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
addr, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
////////////////////////////////////////////////////////////////////////
// Jz4740_usbDevice::JZ4740_USB_IOCTL_PROG_START2_Handler
//
// Routine Description:
// Handler for IO Control Code JZ4740_USB_IOCTL_PROG_START2
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the JZ4740_USB_IOCTL_PROG_START2 function.
// This routine runs at passive level.
//
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_PROG_START2_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
ULONG ret;
unsigned int addr;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_PROG_START2_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_PROG_START2 request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
addr= *(unsigned int *)InputBuf;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_PROG_START2, //Request
addr>>16, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
addr, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_NOR_OPS_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
PUCHAR OutputBuf = reinterpret_cast<PUCHAR>(pBuffer);
unsigned int ops;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_NOR_OPS_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_PROG_START2 request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
ops = *(unsigned int *)InputBuf;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_NOR_OPS, //Request
ops, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
0, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_NAND_OPS_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
PUCHAR OutputBuf = reinterpret_cast<PUCHAR>(pBuffer);
unsigned int ops;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_NAND_OPS_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_PROG_START2 request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
ops = *(unsigned int *)InputBuf;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_NAND_OPS, //Request
ops&0xffff, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
0, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
//printf("\n HERE!!");
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_CONFIGRATION_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
PUCHAR OutputBuf = reinterpret_cast<PUCHAR>(pBuffer);
unsigned int ops;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_CONFIGRATION_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_PROG_START2 request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
ops = *(unsigned int *)InputBuf;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_CONFIGRATION, //Request
ops, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
0, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_GET_NUM_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwOutputBufferSize = I.IoctlOutputBufferSize();
PUCHAR OutputBuf = reinterpret_cast<PUCHAR>(pBuffer);
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_GET_CPU_INFO_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_GET_CPU_INFO request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
OutputBuf[0] = Jz4740_usbDevice::dev_n;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 1;
return status;
}
NTSTATUS Jz4740_usbDevice::JZ4740_USB_IOCTL_SDRAM_OPS_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwOutputBufferSize = I.IoctlOutputBufferSize();
PUCHAR InputBuf = reinterpret_cast<PUCHAR>(pBuffer);
PUCHAR OutputBuf = reinterpret_cast<PUCHAR>(pBuffer);
unsigned int ops;
t << "Entering Jz4740_usbDevice::JZ4740_USB_IOCTL_GET_CPU_INFO_Handler, " << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER
// TODO: Handle the the JZ4740_USB_IOCTL_GET_CPU_INFO request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.
ops = *(unsigned int *)InputBuf;
PURB pUrb = m_Lower.BuildVendorRequest(
0, //TransferBuffer
0, //TransferBufferLength
0, //RequestTypeReservedBits
JZ4740_VR_SDRAM_OPS, //Request
ops&0xffff, //Value
FALSE, //bIn
FALSE, //bShortOk
NULL, //Link
0, //Index
URB_FUNCTION_VENDOR_DEVICE //Function
);
//printf("\n HERE!!");
if (pUrb == NULL)
return STATUS_NO_MEMORY;
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
I.Information() = 0;
return status;
}