📄 d12xp.c
字号:
*configuration, ntStatus));
ExFreePool(urb);
urb = NULL;
}
/* urb = ExAllocatePool(
NonPagedPool,
sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST) + 1);
if (urb)
{
PUCHAR interface;
interface = (PUCHAR)urb + sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST);
*interface = 0xFF;
urb->UrbHeader.Function = URB_FUNCTION_GET_INTERFACE;
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST);
urb->UrbControlGetInterfaceRequest.TransferBufferLength = 1;
urb->UrbControlGetInterfaceRequest.TransferBuffer = interface;
urb->UrbControlGetInterfaceRequest.TransferBufferMDL = NULL;
urb->UrbControlGetInterfaceRequest.UrbLink = NULL;
urb->UrbControlGetInterfaceRequest.Interface =
deviceExtension->Interface->InterfaceNumber;
ntStatus = D12_CallUSBD(DeviceObject, urb);
D12_KdPrint (("D12TEST.SYS: Interface %d (%x)\n",
*interface, ntStatus));
ExFreePool(urb);
urb = NULL;
}*/
#ifdef WIN_XP
urb = ExAllocatePool(
NonPagedPool,
sizeof(struct _URB_CONTROL_TRANSFER) + 1);
if (urb)
{
PUCHAR control;
UCHAR SetupToken[8] = {0x81,0x0a,0x00,0x00,0x00,0x00,0x01,0x00};
int i;
control = (PUCHAR)urb + sizeof(struct
_URB_CONTROL_TRANSFER);
*control = 0xFF;
urb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER ;
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_TRANSFER);
urb->UrbControlTransfer.PipeHandle = NULL;
urb->UrbControlTransfer.TransferFlags = USBD_DEFAULT_PIPE_TRANSFER ;//USBD_DEFAULT_PIPE_TRANSFER ;
urb->UrbControlTransfer.TransferBufferLength = 1;
urb->UrbControlTransfer.TransferBuffer = control;
urb->UrbControlTransfer.TransferBufferMDL = NULL;
urb->UrbControlTransfer.UrbLink = NULL;
for(i=0; i<8;i++){
urb->UrbControlTransfer.SetupPacket[i] = SetupToken[i];
}
ntStatus = D12_CallUSBD(DeviceObject, urb);
DbgPrint ("SONYPEO1.SYS: Interface %d (%x)\n",
*control, ntStatus);
ExFreePool(urb);
urb = NULL;
}
#endif
}
D12_KdPrint (("D12TEST.SYS: exit D12_SelectInterface (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
D12_BuildPipeList(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
devcice.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
ULONG i;
WCHAR Name[] = L"\\PIPE00";
PUSBD_INTERFACE_INFORMATION interface;
deviceExtension = DeviceObject->DeviceExtension;
interface = deviceExtension->Interface;
D12_KdPrint (("D12TEST.SYS: enter D12_BuildPipeList\n"));
deviceExtension = DeviceObject->DeviceExtension;
for (i=0; i<D12_MAX_PIPES; i++) {
Name[6] = 'X';
RtlCopyMemory(deviceExtension->PipeList[i].Name,
Name,
sizeof(Name));
}
//
// build a list of pipe names based on the interface
//
for (i=0; i<interface->NumberOfPipes; i++) {
Name[6] = '0' + (USHORT) i;
RtlCopyMemory(deviceExtension->PipeList[i].Name,
Name,
sizeof(Name));
deviceExtension->PipeList[i].PipeInfo =
&interface->Pipes[i];
deviceExtension->PipeList[i].Opened = FALSE;
}
return STATUS_SUCCESS;
}
NTSTATUS
D12_ResetPipe(
IN PDEVICE_OBJECT DeviceObject,
IN PD12_PIPE Pipe,
IN BOOLEAN IsoClearStall
)
/*++
Routine Description:
Reset a given USB pipe.
NOTES:
This will reset the host to Data0 and should also reset the device
to Data0 for Bulk and Interrupt pipes.
For Iso pipes this will set the virgin state of pipe so that ASAP
transfers begin with the current bus frame instead of the next frame
after the last transfer occurred.
Arguments:
Return Value:
--*/
{
NTSTATUS ntStatus;
PURB urb;
D12_KdPrint (("D12TEST.SYS: Reset Pipe %x\n", Pipe));
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_PIPE_REQUEST));
if (urb) {
urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
urb->UrbPipeRequest.PipeHandle =
Pipe->PipeInfo->PipeHandle;
ntStatus = D12_CallUSBD(DeviceObject, urb);
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
//
// Memphis RESET_PIPE will send a Clear-Feature Endpoint Stall to
// reset the data toggle of non-Iso pipes as part of a RESET_PIPE
// request. It does not do this for Iso pipes as Iso pipes do not use
// the data toggle (all Iso packets are Data0). However, we also use
// the Clear-Feature Endpoint Stall request in our device firmware to
// reset data buffer points inside the device so we explicitly send
// this request to the device for Iso pipes if desired.
//
if (NT_SUCCESS(ntStatus) && IsoClearStall &&
(Pipe->PipeInfo->PipeType == UsbdPipeTypeIsochronous)) {
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_FEATURE_REQUEST));
if (urb) {
UsbBuildFeatureRequest(urb,
URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,
USB_FEATURE_ENDPOINT_STALL,
Pipe->PipeInfo->EndpointAddress,
NULL);
ntStatus = D12_CallUSBD(DeviceObject, urb);
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
return ntStatus;
}
LONG
D12_DecrementIoCount(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PDEVICE_EXTENSION deviceExtension;
LONG ioCount;
deviceExtension = DeviceObject->DeviceExtension;
ioCount = InterlockedDecrement(&deviceExtension->PendingIoCount);
D12_KdPrint (("D12TEST.SYS: Pending io count = %x\n", ioCount));
if (ioCount==0) {
KeSetEvent(&deviceExtension->RemoveEvent,
1,
FALSE);
}
return ioCount;
}
VOID
D12_IncrementIoCount(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PDEVICE_EXTENSION deviceExtension;
deviceExtension = DeviceObject->DeviceExtension;
InterlockedIncrement(&deviceExtension->PendingIoCount);
}
NTSTATUS
D12_ReconfigureDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Initializes a given instance of the device on the USB and selects the
configuration.
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
devcice.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
PUSBD_INTERFACE_INFORMATION interface;
ULONG i;
D12_KdPrint (("D12TEST.SYS: enter D12_ReconfigureDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
if (NT_SUCCESS(ntStatus)) {
ntStatus = D12_ConfigureDevice(DeviceObject);
}
//
// new interface structure is now set up
//
interface = deviceExtension->Interface;
//
// set up the pipe handles again
//
for (i=0; i<interface->NumberOfPipes; i++) {
D12_KdPrint (("D12TEST.SYS: pipe list = %x\n", &deviceExtension->PipeList[i]));
deviceExtension->PipeList[i].PipeInfo =
&interface->Pipes[i];
//deviceExtension->PipeList[i].Opened = FALSE;
}
return ntStatus;
}
NTSTATUS
D12_IrpCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Used as a general purpose completion routine so it can signal an event,
passed as the Context, when the next lower driver is done with the input Irp.
This routine is used by both PnP and Power Management logic.
Even though this routine does nothing but set an event, it must be defined and
prototyped as a completetion routine for use as such
Arguments:
DeviceObject - Pointer to the device object for the class device.
Irp - Irp completed.
Context - Driver defined context, in this case a pointer to an event.
Return Value:
The function value is the final status from the operation.
--*/
{
PKEVENT event = Context;
// Set the input event
KeSetEvent(event,
1, // Priority increment for waiting thread.
FALSE); // Flag this call is not immediately followed by wait.
// This routine must return STATUS_MORE_PROCESSING_REQUIRED because we have not yet called
// IoFreeIrp() on this IRP.
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
D12_SelfSuspendOrActivate(
IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN fSuspend
)
/*++
Routine Description:
Called on D12_PnPAddDevice() to power down until needed (i.e., till a pipe is actually opened).
Called on D12_Create() to power up device to D0 before opening 1st pipe.
Called on D12_Close() to power down device if this is the last pipe.
Arguments:
DeviceObject - Pointer to the device object
fSuspend; TRUE to Suspend, FALSE to acivate.
Return Value:
If the operation is not attemtped, SUCCESS is returned.
If the operation is attemtped, the value is the final status from the operation.
????
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
POWER_STATE PowerState;
PDEVICE_EXTENSION deviceExtension;
deviceExtension = DeviceObject->DeviceExtension;
DbgPrint("Enter D12_SelfSuspendOrActivate(),fSuspend = %d\n", fSuspend);
// Can't accept request if:
// 1) device is removed,
// 2) has never been started,
// 3) is stopped,
// 4) has a remove request pending,
// 5) has a stop device pending
if ( !D12_CanAcceptIoRequests( DeviceObject ) ) {
ntStatus = STATUS_DELETE_PENDING;
DbgPrint("D12 D12_SelfSuspendOrActivate()\n");
return ntStatus;
}
// don't do anything if any System-generated Device Pnp irps are pending
if ( NULL != deviceExtension->PowerIrp ) {
DbgPrint("Exit D12_SelfSuspendOrActivate(),refusing on pending deviceExtension->PowerIrp 0x%x\n", deviceExtension->PowerIrp);
return ntStatus;
}
// don't do anything if any self-generated Device Pnp irps are pending
if ( deviceExtension->SelfPowerIrp ) {
DbgPrint("Exit D12_SelfSuspendOrActivate(),refusing on pending deviceExtension->SelfPowerIrp\n" );
return ntStatus;
}
// don't auto-suspend if any pipes are open
if ( fSuspend && ( 0 != deviceExtension->OpenPipeCount ) ) {
DbgPrint("Exit D12_SelfSuspendOrActivate(),refusing to self-suspend on OpenPipeCount %d\n", deviceExtension->OpenPipeCount);
return ntStatus;
}
// don't auto-activate if no pipes are open
if ( !fSuspend && ( 0 == deviceExtension->OpenPipeCount ) ) {
DbgPrint("Exit D12_SelfSuspendOrActivate(),refusing to self-activate, no pipes open\n");
return ntStatus;
}
// dont do anything if registry CurrentControlSet\Services\D12\Parameters\PowerDownLevel
// has been set to zero, PowerDeviceD0 ( 1 ), or a bogus high value
if ( ( deviceExtension->PowerDownLevel == PowerDeviceD0 ) ||
( deviceExtension->PowerDownLevel == PowerDeviceUnspecified) ||
( deviceExtension->PowerDownLevel >= PowerDeviceMaximum ) ) {
DbgPr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -