📄 buspdo.c
字号:
// Adjust the caps to what your device supports.
// Our device just supports D0 and D3.
//
deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
if(deviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0)
deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
if(deviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0)
deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
if(deviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0)
deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
// We cannot wake the system.
deviceCapabilities->SystemWake = PowerSystemUnspecified;
deviceCapabilities->DeviceWake = PowerDeviceUnspecified;
//
// Specifies whether the device hardware supports the D1 and D2
// power state. Set these bits explicitly.
//
deviceCapabilities->DeviceD1 = FALSE;
deviceCapabilities->DeviceD2 = FALSE;
//
// Specifies whether the device can respond to an external wake
// signal while in the D0, D1, D2, and D3 state.
// Set these bits explicitly.
//
deviceCapabilities->WakeFromD0 = FALSE;
deviceCapabilities->WakeFromD1 = FALSE;
deviceCapabilities->WakeFromD2 = FALSE;
deviceCapabilities->WakeFromD3 = FALSE;
// We have no latencies
deviceCapabilities->D1Latency = 0;
deviceCapabilities->D2Latency = 0;
deviceCapabilities->D3Latency = 0;
// Ejection supported
deviceCapabilities->EjectSupported = TRUE;
//
// This flag specifies whether the device's hardware is disabled.
// The PnP Manager only checks this bit right after the device is
// enumerated. Once the device is started, this bit is ignored.
//
deviceCapabilities->HardwareDisabled = FALSE;
//
// Out simulated device can be physically removed.
//
deviceCapabilities->Removable = TRUE;
//
// Setting it to TURE prevents the warning dialog from appearing
// whenever the device is surprise removed.
//
deviceCapabilities->SurpriseRemovalOK = TRUE;
// We don't support system-wide unique IDs.
deviceCapabilities->UniqueID = FALSE;
//
// Specify whether the Device Manager should suppress all
// installation pop-ups except required pop-ups such as
// "no compatible drivers found."
//
deviceCapabilities->SilentInstall = FALSE;
//
// Specifies an address indicating where the device is located
// on its underlying bus. The interpretation of this number is
// bus-specific. If the address is unknown or the bus driver
// does not support an address, the bus driver leaves this
// member at its default value of 0xFFFFFFFF. In this example
// the location address is same as instance id.
//
deviceCapabilities->Address = DeviceData->SerialNo;
//
// UINumber specifies a number associated with the device that can
// be displayed in the user interface.
//
deviceCapabilities->UINumber = DeviceData->SerialNo;
return STATUS_SUCCESS;
}
NTSTATUS
Bus_PDO_QueryDeviceId(
IN PPDO_DEVICE_DATA DeviceData,
IN PIRP Irp )
/*++
Routine Description:
Bus drivers must handle BusQueryDeviceID requests for their
child devices (child PDOs). Bus drivers can handle requests
BusQueryHardwareIDs, BusQueryCompatibleIDs, and BusQueryInstanceID
for their child devices.
When returning more than one ID for hardware IDs or compatible IDs,
a driver should list the IDs in the order of most specific to most
general to facilitate choosing the best driver match for the device.
Bus drivers should be prepared to handle this IRP for a child device
immediately after the device is enumerated.
Arguments:
DeviceData - Pointer to the PDO's device extension.
Irp - Pointer to the irp.
Return Value:
NT STATUS
--*/
{
PIO_STACK_LOCATION stack;
PWCHAR buffer;
ULONG length;
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE ();
stack = IoGetCurrentIrpStackLocation (Irp);
switch (stack->Parameters.QueryId.IdType) {
case BusQueryDeviceID:
//
// DeviceID is unique string to identify a device.
// This can be the same as the hardware ids (which requires a multi
// sz).
//
buffer = DeviceData->HardwareIDs;
while (*(buffer++)) {
while (*(buffer++)) {
;
}
}
length = (ULONG)(buffer - DeviceData->HardwareIDs) * sizeof (WCHAR);
buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);
if (!buffer) {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlCopyMemory (buffer, DeviceData->HardwareIDs, length);
Irp->IoStatus.Information = (ULONG_PTR) buffer;
break;
case BusQueryInstanceID:
//
// total length = number (5 digits to be safe) + null wide char
//
length = 6 * sizeof(WCHAR);
buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);
if (!buffer) {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
swprintf(buffer, L"%02d", DeviceData->SerialNo);
Bus_KdPrint_Cont (DeviceData, BUS_DBG_PNP_INFO,
("\tInstanceID: %ws\n", buffer));
Irp->IoStatus.Information = (ULONG_PTR) buffer;
break;
case BusQueryHardwareIDs:
//
// A device has at least one hardware id.
// In a list of hardware IDs (multi_sz string) for a device,
// DeviceId is the most specific and should be first in the list.
//
buffer = DeviceData->HardwareIDs;
while (*(buffer++)) {
while (*(buffer++)) {
;
}
}
length = (ULONG)(buffer - DeviceData->HardwareIDs) * sizeof (WCHAR);
buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);
if (!buffer) {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlCopyMemory (buffer, DeviceData->HardwareIDs, length);
Irp->IoStatus.Information = (ULONG_PTR) buffer;
break;
case BusQueryCompatibleIDs:
//
// The generic ids for installation of this pdo.
//
length = (BUSENUM_COMPATIBLE_IDS_LENGTH + 1) * sizeof (WCHAR);
buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);
if (!buffer) {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlCopyMemory (buffer, BUSENUM_COMPATIBLE_IDS, length);
Irp->IoStatus.Information = (ULONG_PTR) buffer;
break;
default:
status = Irp->IoStatus.Status;
}
return status;
}
NTSTATUS
Bus_PDO_QueryDeviceText(
IN PPDO_DEVICE_DATA DeviceData,
IN PIRP Irp )
/*++
Routine Description:
The PnP Manager uses this IRP to get a device's
description or location information. This string
is displayed in the "found new hardware" pop-up
window if no INF match is found for the device.
Bus drivers are also encouraged to return location
information for their child devices, but this information
is optional.
Arguments:
DeviceData - Pointer to the PDO's device extension.
Irp - Pointer to the irp.
Return Value:
NT STATUS
--*/
{
PWCHAR buffer;
USHORT length;
PIO_STACK_LOCATION stack;
NTSTATUS status;
PAGED_CODE ();
stack = IoGetCurrentIrpStackLocation (Irp);
switch (stack->Parameters.QueryDeviceText.DeviceTextType) {
case DeviceTextDescription:
//
// Check to see if any filter driver has set any information.
// If so then remain silent otherwise add your description.
// This string must be localized to support various languages.
//
switch (stack->Parameters.QueryDeviceText.LocaleId) {
case 0x00000407 : // German
// Localize the device text.
// Until we implement let us fallthru to English
default: // for all other languages, fallthru to English
case 0x00000409 : // English
if(!Irp->IoStatus.Information) {
length = (USHORT) \
(wcslen(VENDORNAME) + wcslen(MODEL) + 8) * sizeof(WCHAR);
buffer = ExAllocatePoolWithTag (PagedPool,
length, BUSENUM_POOL_TAG);
if (buffer == NULL ) {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
swprintf(buffer, L"%ws%ws%02d", VENDORNAME, MODEL,
DeviceData->SerialNo);
Bus_KdPrint_Cont (DeviceData, BUS_DBG_PNP_TRACE,
("\tDeviceTextDescription :%ws\n", buffer));
Irp->IoStatus.Information = (ULONG_PTR) buffer;
}
status = STATUS_SUCCESS;
break;
} // end of LocalID switch
break;
case DeviceTextLocationInformation:
Bus_KdPrint_Cont (DeviceData, BUS_DBG_PNP_TRACE,
("\tDeviceTextLocationInformation: Unknown\n"));
default:
status = Irp->IoStatus.Status;
break;
}
return status;
}
NTSTATUS
Bus_PDO_QueryResources(
IN PPDO_DEVICE_DATA DeviceData,
IN PIRP Irp )
/*++
Routine Description:
The PnP Manager uses this IRP to get a device's
boot configuration resources. The bus driver returns
a resource list in response to this IRP, it allocates
a CM_RESOURCE_LIST from paged memory. The PnP Manager
frees the buffer when it is no longer needed.
Arguments:
DeviceData - Pointer to the PDO's device extension.
Irp - Pointer to the irp.
Return Value:
NT STATUS
--*/
{
#if 0
PCM_RESOURCE_LIST resourceList;
PCM_FULL_RESOURCE_DESCRIPTOR frd;
PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
ULONG resourceListSize;
#endif
PAGED_CODE ();
return Irp->IoStatus.Status;
//
// Following code shows how to provide
// boot I/O port resource to a device.
//
#if 0
resourceListSize = sizeof(CM_RESOURCE_LIST);
resourceList = ExAllocatePoolWithTag (PagedPool,
resourceListSize, BUSENUM_POOL_TAG);
if (resourceList == NULL ) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory( resourceList, resourceListSize );
resourceList->Count = 1;
frd = &resourceList->List[0];
frd->InterfaceType = InterfaceTypeUndefined;
frd->BusNumber = 0;
//
// Set the number of Partial Resource
// Descriptors in this FRD.
//
frd->PartialResourceList.Count = 1;
//
// Get pointer to first Partial Resource
// Descriptor in this FRD.
//
prd = &frd->PartialResourceList.PartialDescriptors[0];
prd->Type = CmResourceTypePort;
prd->ShareDisposition = CmResourceShareShared;
prd->Flags = CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE;
prd->u.Port.Start.QuadPart = 0xBAD; // some random port number
prd->u.Port.Length = 1;
Irp->IoStatus.Information = (ULONG_PTR)resourceList;
return STATUS_SUCCESS;
#endif
}
NTSTATUS
Bus_PDO_QueryResourceRequirements(
IN PPDO_DEVICE_DATA DeviceData,
IN PIRP Irp )
/*++
Routine Description:
The PnP Manager uses this IRP to get a device's alternate
resource requirements list. The bus driver returns a resource
requirements list in response to this IRP, it allocates an
IO_RESOURCE_REQUIREMENTS_LIST from paged memory. The PnP
Manager frees the buffer when it is no longer needed.
Arguments:
DeviceData - Pointer to the PDO's device extension.
Irp - Pointer to the irp.
Return Value:
NT STATUS
--*/
{
PIO_RESOURCE_REQUIREMENTS_LIST resourceList;
PIO_RESOURCE_DESCRIPTOR descriptor;
ULONG resourceListSize;
NTSTATUS status;
PAGED_CODE ();
//
// Note the IO_RESOURCE_REQUIREMENTS_LIST structure includes
// IO_RESOURCE_LIST List[1]; if we specify more than one
// resource, we must include IO_RESOURCE_LIST size
// in the resourceListSize calculation.
//
resourceListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
resourceList = ExAllocatePoolWithTag (
PagedPool,
resourceListSize,
BUSENUM_POOL_TAG);
if (resourceList == NULL ) {
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
RtlZeroMemory( resourceList, resourceListSize );
resourceList->ListSize = resourceListSize;
//
// Initialize the list header.
//
resourceList->AlternativeLists = 1;
resourceList->InterfaceType = InterfaceTypeUndefined;
resourceList->BusNumber = 0;
resourceList->List[0].Version = 1;
resourceList->List[0].Revision = 1;
resourceList->List[0].Count = 1;
descriptor = resourceList->List[0].Descriptors;
//
// Fill in the information about the ports your device
// can use.
//
descriptor->Type = CmResourceTypePort;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -