📄 isp1581device_buf.cpp
字号:
UNREFERENCED_PARAMETER(I);
}
////////////////////////////////////////////////////////////////////////
// GnganfgDevice::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 GnganfgDevice::OnDeviceSleep(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering GnganfgDevice::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);
}
////////////////////////////////////////////////////////////////////////
// GnganfgDevice::Create
//
// Routine Description:
// Handler for IRP_MJ_CREATE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS GnganfgDevice::Create(KIrp I)
{
NTSTATUS status=STATUS_SUCCESS;
t << "Entering GnganfgDevice::Create, " << I << EOL;
if( (m_HasBeenCreated == FALSE) || (m_AdapterNotificationEvent==NULL) )
{
m_HasBeenCreated = TRUE;
KUnitizedName EventName;
NotificationEventHandle = NULL;
EventName.Initialize(L"\\BaseNamedObjects\\KINGF_ReadOperationCompEvent", m_Unit);
m_AdapterNotificationEvent = IoCreateSynchronizationEvent(PUNICODE_STRING(EventName), &NotificationEventHandle);
// m_AdapterNotificationEvent = IoCreateNotificationEvent(PUNICODE_STRING(EventName), &NotificationEventHandle);
if (m_AdapterNotificationEvent == NULL)
{
t << "Create Event Error!\n";
status = STATUS_NO_EVENT_PAIR;
return status;
}
KeClearEvent(m_AdapterNotificationEvent);
}
if (!m_FPGAConfigSuccessful)
{
m_FPGAConfigSuccessful = TRUE;
status = ConfigFpga();
}
// 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, IO_NO_INCREMENT);
t << "GnganfgDevice::Create Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// GnganfgDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS GnganfgDevice::Close(KIrp I)
{
NTSTATUS status;
t << "Entering GnganfgDevice::Close, " << I << EOL;
// TODO: Add driver specific close handling code here
m_HasBeenCreated = FALSE;
if (NotificationEventHandle != NULL)
ZwClose (NotificationEventHandle);
// 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 << "GnganfgDevice::Close Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// GnganfgDevice::Cleanup
//
// Routine Description:
// Handler for IRP_MJ_CLEANUP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS GnganfgDevice::CleanUp(KIrp I)
{
t << "Entering CleanUp, " << I << EOL;
// TODO: Insert your code to respond to the CLEANUP message.
return I.PnpComplete(this, STATUS_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
// Read (member of GnganfgDevice) Handler for IRP_MJ_READ
// Input I Current IRP
// Output NTSTATUS Result code
// Note This routine handles read requests.
// The KPnpDevice class handles restricting IRP flow if the device is stopping or being removed.
NTSTATUS GnganfgDevice::Read(KIrp I)
{
t << "Entering GnganfgDevice::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);
}
ULONG dwTotalSize = I.ReadSize(CURRENT); // dwTotalSize = 400k-Byte;
ULONG dwMaxSize = m_Endpoint5.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 != 640*640) || (dwTotalSize > dwMaxSize) )
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_BUFFER_SIZE);
}
// 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);
}
// Create an URB to do actual Bulk read from the pipe
PURB pUrb = m_Endpoint5.BuildBulkTransfer(
m_lpBufferToRead, // Where is data coming from?
dwMaxSize, // How much data to read? 405k_Bytes;
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_Endpoint5.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
return status;
}
////////////////////////////////////////////////////////////////////////
// GnganfgDevice::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 GnganfgDevice::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;
// Declare a memory object
KMemory Mem(I.Mdl());
PUCHAR pIrpBuffer = (PUCHAR) Mem.MapToSystemSpace();
CHAR* pBuffer;
ULONG dOffset = 5*1024;
if ( NT_SUCCESS(status) )
{
nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
pBuffer = (CHAR*)pUrb->UrbBulkOrInterruptTransfer.TransferBuffer;
pBuffer += dOffset; // Offset 5k;
if (nBytesRead == m_dwFrameLengthInByte )
{
nBytesRead -= dOffset;
RtlCopyMemory( pIrpBuffer, //IN VOID UNALIGNED *Destination,
pBuffer, //IN CONST VOID UNALIGNED *Source,
nBytesRead ); //IN ULONG Length
}
else
nBytesRead = 0;
}
// Deallocate Urb and context structure
delete pUrb;
delete pContext;
// set returned count
I.Information() = nBytesRead;
// Plug and Play accounting
DecrementOutstandingRequestCount();
if(m_AdapterNotificationEvent!=NULL)
KeSetEvent(m_AdapterNotificationEvent,0,FALSE) ;
// allow IRP completion processing
return STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////
// Write (member of GnganfgDevice) Handler for IRP_MJ_WRITE
// Input I Current IRP
// Output NTSTATUS Result code
// Note This routine handles write requests.
// The KPnpDevice class handles restricting IRP flow if the device is stopping or being removed.
NTSTATUS GnganfgDevice::Write(KIrp I)
{
NTSTATUS status;
ULONG dwBytesWritten = 0;
ULONG dwWriteTimes = 0;
ULONG i;
t << "Entering GnganfgDevice::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);
}
ULONG dwMaxTransferSize = m_Endpoint4.MaximumTransferSize();
ULONG dwTotalSize = I.WriteSize(CURRENT);
// Always ok to write 0 elements.
if (dwTotalSize == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Declare a memory object
KMemory Mem(I.Mdl());
PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
// calculate the Write times needed to complete this read request
dwWriteTimes = dwTotalSize/dwMaxTransferSize;
if( dwTotalSize%dwMaxTransferSize )
dwWriteTimes++;
for( i = 0; i < dwWriteTimes; i ++ )
{
// Create an URB to do actual Bulk read from the pipe
ULONG tempWriteSize = dwMaxTransferSize;
if( (i == (dwWriteTimes - 1 )) && (dwTotalSize%dwMaxTransferSize) ) // last read and read length less than dwMaxTransferSize
{
tempWriteSize = dwTotalSize%dwMaxTransferSize;
}
PURB pUrb = NULL;
pUrb = m_Endpoint4.BuildBulkTransfer(
pBuffer, // Where is data coming from?
tempWriteSize, // How much data to write.
FALSE, // direction (TRUE = IN)
NULL, // Link to next URB
FALSE);
if (pUrb == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}
// Allow a short transfer
pUrb->UrbBulkOrInterruptTransfer.TransferFlags =
(USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK);
// Submit the URB to our USB device
status = m_Endpoint4.SubmitUrb( pUrb, NULL, NULL, 1000);
// if successful then calculate the amount of the read bytes
if ( NT_SUCCESS(status) )
{
dwBytesWritten = dwBytesWritten +
pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
delete pUrb;
// adjust the buffer pointer
pBuffer = pBuffer + tempWriteSize;
}
else
{
break;
}
}
I.Information() = dwBytesWritten;
return I.PnpComplete(this, status);
}
////////////////////////////////////////////////////////////////////////
// WriteComplete (member of GnganfgDevice) Completion Handler for IRP_MJ_WRITE
// Input I IRP just completed by USB
// pContext Context structure containing pointer to Urb
// Output NTSTATUS STATUS_SUCCESS
// Note This routine is called when USBD completes the write request
NTSTATUS GnganfgDevice::WriteComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
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;
}
////////////////////////////////////////////////////////////////////////
// DeviceControl (member of GnganfgDevice)
//
// Handler for IRP_MJ_DEVICE_CONTROL
//
// Input
// I Current IRP
//
// Output
// None
//
// Notes:
// 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 GnganfgDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering GnganfgDevice::Device Control, " << I << EOL;
switch (I.IoctlCode())
{
// Vendor request.
case FzGdi_IOCTL_SetDeviceCommands:
status = KBUSBDEV_IOCTL_SetDeviceCommands_Handler(I);
break;
// Vendor request.
case FzGdi_IOCTL_GetDeviceStatus:
status = KBUSBDEV_IOCTL_GetDeviceStatus_Handler(I);
break;
// Calss request.
case FzGdi_IOCTL_GetDeviceID:
status = KBUSBDEV_IOCTL_GetDeviceID_Handler(I);
break;
// Calss request.
case FzGdi_IOCTL_GetPortStatus:
status = KBUSBDEV_IOCTL_GetPortStatus_Handler(I);
break;
// Calss request.
case FzGdi_IOCTL_SoftReset:
status = KBUSBDEV_IOCTL_SoftReset_Handler(I);
break;
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -