📄 dpnp.c
字号:
if (NT_SUCCESS(ntStatus)) {
/*
// Put a ptr to the device descriptor in the device extension for easy
// access (like a "cached" copy). We will free this memory when the
// device is removed. See the "Ezusb_RemoveDevice" code.
*/
pdx->DeviceDescriptor = deviceDescriptor;
pdx->Stopped = FALSE;
} else if (deviceDescriptor) {
/*
// If the bus transaction failed, then free up the memory created to hold
// the device descriptor, since the device is probably non-functional
*/
ExFreePool(deviceDescriptor);
pdx->DeviceDescriptor = NULL;
}
ExFreePool(urb);
} else {
// Failed getting memory for the Urb
ntStatus = STATUS_NO_MEMORY;
}
// If the Get_Descriptor call was successful, then configure the device.
if (NT_SUCCESS(ntStatus)) {
ntStatus = d_ConfigureDevice(fdo);
}
return ntStatus;
}
NTSTATUS d_ConfigureDevice(
IN PDEVICE_OBJECT fdo
)
/*++
Routine Description:
Configures the USB device via USB-specific device requests and interaction
with the USB software subsystem.
Arguments:
fdo - pointer to the device object for this instance of the Ezusb Device
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION pdx;
NTSTATUS ntStatus;
PURB urb = NULL;
ULONG siz;
PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;
Ezusb_KdPrint (("enter Ezusb_ConfigureDevice\n"));
pdx = fdo->DeviceExtension;
//
// Get memory for the USB Request Block (urb).
//
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (urb != NULL)
{
//
// Set size of the data buffer. Note we add padding to cover hardware faults
// that may cause the device to go past the end of the data buffer
//
siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) + 16;
// Get the nonpaged pool memory for the data buffer
configurationDescriptor = ExAllocatePool(NonPagedPool, siz);
if (configurationDescriptor != NULL) {
UsbBuildGetDescriptorRequest(urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
configurationDescriptor,
NULL,
sizeof (USB_CONFIGURATION_DESCRIPTOR),/* Get only the configuration descriptor */
NULL);
ntStatus = Ezusb_CallUSBD(fdo, urb);
if (NT_SUCCESS(ntStatus)) {
Ezusb_KdPrint (("Configuration Descriptor is at %x, bytes txferred: %d\n\
Configuration Descriptor Actual Length: %d\n",
configurationDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength,
configurationDescriptor->wTotalLength));
}//if
} else {
ntStatus = STATUS_NO_MEMORY;
goto Exit_EzusbConfigureDevice;
}//if-else
// Determine how much data is in the entire configuration descriptor
// and add extra room to protect against accidental overrun
siz = configurationDescriptor->wTotalLength + 16;
// Free up the data buffer memory just used
ExFreePool(configurationDescriptor);
configurationDescriptor = NULL;
// Get nonpaged pool memory for the data buffer
configurationDescriptor = ExAllocatePool(NonPagedPool, siz);
// Now get the entire Configuration Descriptor
if (configurationDescriptor != NULL) {
UsbBuildGetDescriptorRequest(urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
configurationDescriptor,
NULL,
siz, // Get all the descriptor data
NULL);
ntStatus = Ezusb_CallUSBD(fdo, urb);
if (NT_SUCCESS(ntStatus)) {
Ezusb_KdPrint (("Entire Configuration Descriptor is at %x, bytes txferred: %d\n",
configurationDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength));
} else {
//Error in getting configuration descriptor
goto Exit_EzusbConfigureDevice;
}//else
} else {
// Failed getting data buffer (configurationDescriptor) memory
ntStatus = STATUS_NO_MEMORY;
goto Exit_EzusbConfigureDevice;
}//if-else
} else {
// failed getting urb memory
ntStatus = STATUS_NO_MEMORY;
goto Exit_EzusbConfigureDevice;
}//if-else
/*
// We have the configuration descriptor for the configuration
// we want.
//
// Now we issue the SelectConfiguration command to get
// the pipes associated with this configuration.
*/
if (configurationDescriptor) {
// Get our pipes
ntStatus = d_SelectInterfaces(fdo,
configurationDescriptor,
NULL // Device not yet configured
);
} //if
Exit_EzusbConfigureDevice:
// Clean up and exit this routine
if (urb != NULL) {
ExFreePool(urb); // Free urb memory
}//if
if (configurationDescriptor != NULL) {
ExFreePool(configurationDescriptor);// Free data buffer
}//if
Ezusb_KdPrint (("exit Ezusb_ConfigureDevice (%x)\n", ntStatus));
return ntStatus;
}//Ezusb_ConfigureDevice
NTSTATUS d_RemoveDevice(
IN PDEVICE_OBJECT fdo
)
/*++
Routine Description:
Removes a given instance of a Ezusb Device device on the USB.
Arguments:
fdo - pointer to the device object for this instance of a Ezusb Device
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION pdx;
NTSTATUS ntStatus = STATUS_SUCCESS;
Ezusb_KdPrint (("enter Ezusb_RemoveDevice\n"));
pdx = fdo->DeviceExtension;
if (pdx->DeviceDescriptor)
{
ExFreePool(pdx->DeviceDescriptor);
}
//
// Free up any interface structures in our device extension
//
if (pdx->Interface != NULL)
{
ExFreePool(pdx->Interface);
}
//
// remove the device object's symbolic link
//
if (pdx->NeedCleanup)
{
UNICODE_STRING deviceLinkUnicodeString;
pdx->NeedCleanup = FALSE;
RtlInitUnicodeString (&deviceLinkUnicodeString,
pdx->DeviceLinkNameBuffer);
IoDeleteSymbolicLink(&deviceLinkUnicodeString);
}
IoDetachDevice(pdx->StackDeviceObject);
IoDeleteDevice (fdo);
Ezusb_KdPrint (("exit Ezusb_RemoveDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
d_SelectInterfaces(
IN PDEVICE_OBJECT fdo,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
IN PUSBD_INTERFACE_INFORMATION Interface
)
/*++
Routine Description:
Initializes an Ezusb Device with multiple interfaces
Arguments:
fdo - pointer to the device object for this instance of the Ezusb Device
ConfigurationDescriptor - pointer to the USB configuration descriptor containing the interface and endpoint
descriptors.
Interface - pointer to a USBD Interface Information Object
- If this is NULL, then this driver must choose its interface based on driver-specific
criteria, and the driver must also CONFIGURE the device.
- If it is NOT NULL, then the driver has already been given an interface and
the device has already been configured by the parent of this device driver.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION pdx;
NTSTATUS ntStatus;
PURB urb;
ULONG j;
UCHAR alternateSetting, MyInterfaceNumber;
PUSBD_INTERFACE_INFORMATION interfaceObject;
USBD_INTERFACE_LIST_ENTRY interfaceList[2];
Ezusb_KdPrint (("enter Ezusb_SelectInterfaces\n"));
pdx = fdo->DeviceExtension;
MyInterfaceNumber = SAMPLE_INTERFACE_NBR;
// Search the configuration descriptor for the first interface/alternate setting
interfaceList[0].InterfaceDescriptor =
USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
ConfigurationDescriptor,
-1, // Interface - don't care
-1, // Alternate Setting - don't care
-1, // Class - don't care
-1, // SubClass - don't care
-1); // Protocol - don't care
ASSERT(interfaceList[0].InterfaceDescriptor != NULL);
interfaceList[1].InterfaceDescriptor = NULL;
interfaceList[1].Interface = NULL;
urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor,&interfaceList[0]);
if (!urb)
{
Ezusb_KdPrint ((" USBD_CreateConfigurationRequestEx failed\n"));
}
d_DumpBuffer(urb, urb->UrbHeader.Length);
interfaceObject = (PUSBD_INTERFACE_INFORMATION) (&(urb->UrbSelectConfiguration.Interface));
/*
// We set up a default max transfer size for the endpoints. Your driver will
// need to change this to reflect the capabilities of your device's endpoints.
*/
for (j=0; j<interfaceList[0].InterfaceDescriptor->bNumEndpoints; j++)
interfaceObject->Pipes[j].MaximumTransferSize = (64 * 1024) - 1;
ntStatus = Ezusb_CallUSBD(fdo, urb);
d_DumpBuffer(urb, urb->UrbHeader.Length);
if (NT_SUCCESS(ntStatus) && USBD_SUCCESS(urb->UrbHeader.Status))
{
// Save the configuration handle for this device
pdx->ConfigurationHandle =
urb->UrbSelectConfiguration.ConfigurationHandle;
pdx->Interface = ExAllocatePool(NonPagedPool,
interfaceObject->Length);
// save a copy of the interfaceObject information returned
RtlCopyMemory(pdx->Interface, interfaceObject, interfaceObject->Length);
// Dump the interfaceObject to the debugger
Ezusb_KdPrint (("---------\n"));
Ezusb_KdPrint (("NumberOfPipes 0x%x\n", pdx->Interface->NumberOfPipes));
Ezusb_KdPrint (("Length 0x%x\n", pdx->Interface->Length));
Ezusb_KdPrint (("Alt Setting 0x%x\n", pdx->Interface->AlternateSetting));
Ezusb_KdPrint (("Interface Number 0x%x\n", pdx->Interface->InterfaceNumber));
// Dump the pipe info
for (j=0; j<interfaceObject->NumberOfPipes; j++)
{
PUSBD_PIPE_INFORMATION pipeInformation;
pipeInformation = &pdx->Interface->Pipes[j];
Ezusb_KdPrint (("---------\n"));
Ezusb_KdPrint (("PipeType 0x%x\n", pipeInformation->PipeType));
Ezusb_KdPrint (("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
Ezusb_KdPrint (("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
Ezusb_KdPrint (("Interval 0x%x\n", pipeInformation->Interval));
Ezusb_KdPrint (("Handle 0x%x\n", pipeInformation->PipeHandle));
Ezusb_KdPrint (("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
}
Ezusb_KdPrint (("---------\n"));
}
Ezusb_KdPrint (("exit Ezusb_SelectInterfaces (%x)\n", ntStatus));
return ntStatus;
}/* Ezusb_SelectInterfaces */
#define BYTES_PER_LINE 0x10
void d_DumpBuffer(
PVOID pvBuffer, ULONG length)
{
int nItems = 0;
char temp[64] = "";
char temp2[64] = "";
ULONG i;
ULONG j;
PUCHAR ptr;
ptr = (PUCHAR) pvBuffer;
for (i = 0; i < ((length + BYTES_PER_LINE - 1) / BYTES_PER_LINE); i++)
{
sprintf(temp,"%04X ",(i*BYTES_PER_LINE));
for (j = 0; j < BYTES_PER_LINE; j++)
{
if (((i * BYTES_PER_LINE) + j) < length)
{
sprintf(temp2,"%02X ",*ptr++);
strcat(temp,temp2);
}
}
// SendMessage (hOutputBox, LB_ADDSTRING, 0, (LPARAM)temp);
Ezusb_KdPrint (("%s\n",temp));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -