?? d12xp.c
字號:
ntStatus = BulkUsb_SymbolicLink( PhysicalDeviceObject, &deviceLinkUnicodeString );
if (NT_SUCCESS(ntStatus)) {
ntStatus = IoCreateDevice (DriverObject,
sizeof (DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
FILE_AUTOGENERATED_DEVICE_NAME,
FALSE,
DeviceObject);
if (!NT_SUCCESS(ntStatus)) {
return ntStatus;
}
// Name buffer for our named Functional device object link
// The name is generated based on the driver's class GUID
deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);
RtlCopyMemory(deviceExtension->DeviceLinkNameBuffer,
deviceLinkUnicodeString.Buffer,
deviceLinkUnicodeString.Length);
deviceExtension->DeviceDescriptor = NULL;
deviceExtension->Interface = NULL;
deviceExtension->ConfigurationHandle = NULL;
deviceExtension->AcceptingRequests = TRUE;
deviceExtension->PendingIoCount = 0;
deviceExtension->UserEvent = NULL;
KeInitializeEvent(&deviceExtension->RemoveEvent, NotificationEvent, FALSE);
for (i=0; i<D12_MAX_PIPES; i++) {
deviceExtension->PipeList[i].PipeInfo = NULL;
}
RtlFreeUnicodeString( &deviceLinkUnicodeString );
}
return ntStatus;
}
NTSTATUS
D12_CallUSBD(
IN PDEVICE_OBJECT DeviceObject,
IN PURB Urb
)
/*++
Routine Description:
Passes a URB to the USBD class driver
Arguments:
DeviceObject - pointer to the device object for this instance of an 82930
Urb - pointer to Urb request block
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus, status = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension;
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;
D12_KdPrint (("D12TEST.SYS: enter D12_CallUSBD\n"));
deviceExtension = DeviceObject->DeviceExtension;
//
// issue a synchronous request
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_SUBMIT_URB,
deviceExtension->TopOfStackDeviceObject,
NULL,
0,
NULL,
0,
TRUE, /* INTERNAL */
&event,
&ioStatus);
//
// Call the class driver to perform the operation. If the returned status
// is PENDING, wait for the request to complete.
//
nextStack = IoGetNextIrpStackLocation(irp);
ASSERT(nextStack != NULL);
//
// pass the URB to the USB driver stack
//
nextStack->Parameters.Others.Argument1 = Urb;
D12_KdPrint (("D12TEST.SYS: calling USBD\n"));
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
irp);
D12_KdPrint (("D12TEST.SYS: return from IoCallDriver USBD %x\n", ntStatus));
if (ntStatus == STATUS_PENDING) {
D12_KdPrint (("D12TEST.SYS: Wait for single object\n"));
status = KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
D12_KdPrint (("D12TEST.SYS: Wait for single object, returned %x\n", status));
} else {
ioStatus.Status = ntStatus;
}
D12_KdPrint (("D12TEST.SYS: URB status = %x status = %x irp status %x\n",
Urb->UrbHeader.Status, status, ioStatus.Status));
//
// USBD maps the error code for us
//
ntStatus = ioStatus.Status;
D12_KdPrint (("D12TEST.SYS: exit D12_CallUSBD (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
D12_ConfigureDevice(
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;
PURB urb;
ULONG siz;
PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;
D12_KdPrint (("D12TEST.SYS: enter D12_ConfigureDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
//
// first configure the device
//
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (urb) {
// BUGBUG 82930 chokes if on the next command if you don't get
// the entire descriptor on the first try
siz = sizeof(USB_CONFIGURATION_DESCRIPTOR)+256;
get_config_descriptor_retry:
configurationDescriptor = ExAllocatePool(NonPagedPool,
siz);
if (configurationDescriptor) {
UsbBuildGetDescriptorRequest(urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
configurationDescriptor,
NULL,
siz,
NULL);
ntStatus = D12_CallUSBD(DeviceObject, urb);
D12_KdPrint (("D12TEST.SYS: Configuration Descriptor = %x, len %x\n",
configurationDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength));
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
//
// if we got some data see if it was enough.
//
// NOTE: we may get an error in URB because of buffer overrun
if (urb->UrbControlDescriptorRequest.TransferBufferLength>0 &&
configurationDescriptor->wTotalLength > siz) {
siz = configurationDescriptor->wTotalLength;
ExFreePool(configurationDescriptor);
configurationDescriptor = NULL;
goto get_config_descriptor_retry;
}
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (configurationDescriptor) {
//
// We have the configuration descriptor for the configuration
// we want.
//
// Now we issue the select configuration command to get
// the pipes associated with this configuration.
//
ntStatus = D12_SelectInterface(DeviceObject,
configurationDescriptor, NULL);
ExFreePool(configurationDescriptor);
}
D12_KdPrint (("D12TEST.SYS: exit D12_ConfigureDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
D12_SelectInterface(
IN PDEVICE_OBJECT DeviceObject,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
PUSBD_INTERFACE_INFORMATION Interface
)
/*++
Routine Description:
Initializes an 82930 with multiple interfaces
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
devcice.
ConfigurationDescriptor - pointer to the USB configuration
descriptor containing the interface and endpoint
descriptors.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus;
PURB urb = NULL;
ULONG i;
UCHAR alternateSetting, interfaceNumber;
PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
USHORT siz;
D12_KdPrint (("D12TEST.SYS: enter D12_SelectInterface\n"));
deviceExtension = DeviceObject->DeviceExtension;
if (Interface == NULL) {
//
// D12 driver only supports one interface, we must search
// the configuration descriptor for the interface we want
// and remember the pipes.
//
urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, &siz);
if (urb) {
//
// search thru all the interfaces
// and find any we are interested in
//
interfaceNumber = 0;
alternateSetting = 0;
// alternateSetting = 3;
/* interfaceDescriptor =
USBD_ParseConfigurationDescriptor(ConfigurationDescriptor,
interfaceNumber,
alternateSetting);
*/
interfaceDescriptor =
USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
ConfigurationDescriptor, //search from start of config descriptro
-1, // interface number not a criteria; we only support one interface
-1, // not interested in alternate setting here either
-1, // interface class not a criteria
-1, // interface subclass not a criteria
-1 // interface protocol not a criteria
);
Interface = &urb->UrbSelectConfiguration.Interface;
for (i=0; i< Interface->NumberOfPipes; i++) {
//
// perform any pipe initialization here
//
Interface->Pipes[i].MaximumTransferSize = 64*1024-1;
}
UsbBuildSelectConfigurationRequest(urb,
(USHORT) siz,
ConfigurationDescriptor);
// Interface->AlternateSetting = 3;
ntStatus = D12_CallUSBD(DeviceObject, urb);
deviceExtension->ConfigurationHandle =
urb->UrbSelectConfiguration.ConfigurationHandle;
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
} else {
//
// we were give an interface already set up
//
// do a selectinterface here if we want to change any of the
// pipe parameters.
//
TRAP();
}
ASSERT(Interface != NULL);
if (NT_SUCCESS(ntStatus)) {
//
// Save the configuration handle for this device
//
deviceExtension->ConfigurationHandle =
urb->UrbSelectConfiguration.ConfigurationHandle;
deviceExtension->Interface = ExAllocatePool(NonPagedPool,
Interface->Length);
if (deviceExtension->Interface) {
ULONG j;
//
// save a copy of the interface information returned
//
RtlCopyMemory(deviceExtension->Interface, Interface, Interface->Length);
//
// Dump the interface to the debugger
//
D12_KdPrint (("D12TEST.SYS: ---------\n"));
D12_KdPrint (("D12TEST.SYS: NumberOfPipes 0x%x\n", deviceExtension->Interface->NumberOfPipes));
D12_KdPrint (("D12TEST.SYS: Length 0x%x\n", deviceExtension->Interface->Length));
D12_KdPrint (("D12TEST.SYS: Alt Setting 0x%x\n", deviceExtension->Interface->AlternateSetting));
D12_KdPrint (("D12TEST.SYS: Interface Number 0x%x\n", deviceExtension->Interface->InterfaceNumber));
D12_KdPrint (("D12TEST.SYS: Class, subclass, protocol 0x%x 0x%x 0x%x\n",
deviceExtension->Interface->Class,
deviceExtension->Interface->SubClass,
deviceExtension->Interface->Protocol));
// Dump the pipe info
for (j=0; j<Interface->NumberOfPipes; j++) {
PUSBD_PIPE_INFORMATION pipeInformation;
pipeInformation = &deviceExtension->Interface->Pipes[j];
D12_KdPrint (("D12TEST.SYS: ---------\n"));
D12_KdPrint (("D12TEST.SYS: PipeType 0x%x\n", pipeInformation->PipeType));
D12_KdPrint (("D12TEST.SYS: EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
D12_KdPrint (("D12TEST.SYS: MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
D12_KdPrint (("D12TEST.SYS: Interval 0x%x\n", pipeInformation->Interval));
D12_KdPrint (("D12TEST.SYS: Handle 0x%x\n", pipeInformation->PipeHandle));
D12_KdPrint (("D12TEST.SYS: MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
}
D12_KdPrint (("D12TEST.SYS: ---------\n"));
}
}
if (urb) {
ExFreePool(urb);
urb = NULL;
}
// Retrieve the selected Configuration and Interface setting from the
// device. (The only purpose of doing this here is to exercise the
// URB_FUNCTION_GET_CONFIGURATION and URB_FUNCTION_GET_INTERFACE
// requests).
//
if (NT_SUCCESS(ntStatus)) {
urb = ExAllocatePool(
NonPagedPool,
sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST) + 1);
if (urb)
{
PUCHAR configuration;
configuration = (PUCHAR)urb + sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST);
*configuration = 0xFF;
urb->UrbHeader.Function = URB_FUNCTION_GET_CONFIGURATION;
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST);
urb->UrbControlGetConfigurationRequest.TransferBufferLength = 1;
urb->UrbControlGetConfigurationRequest.TransferBuffer = configuration;
urb->UrbControlGetConfigurationRequest.TransferBufferMDL = NULL;
urb->UrbControlGetConfigurationRequest.UrbLink = NULL;
ntStatus = D12_CallUSBD(DeviceObject, urb);
D12_KdPrint (("D12TEST.SYS: Configuration %d (%x)\n",
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -