取得 HF 裝置的藍牙位址
取得 HF 裝置的藍牙位址主題示範音訊驅動程式如何取得配對無手部 (HF) 裝置的藍牙位址。
位址字串可用於唯一識別特定配對 HF 裝置。 例如,位址字串可作為傳遞至 IoRegisterDeviceInterface 的 ReferenceString 參數、傳遞至 KsCreateFilterFactory 的 RefString 參數,或傳遞至 PcRegisterSubdevice 的 Name 參數。
請注意,GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS裝置介面符號連結對於每個配對的 HF 裝置而言也是唯一的,但此字串對於某些用途而言可能太長。
下列程式碼範例所示的 IoHelperGetDevicePdo 常式是 IoHelperGetDeviceBluetoothAddress 所使用的公用程式函式。 當音訊驅動程式正在處理 PnP 介面抵達通知時,可以呼叫這類函式。 音訊驅動程式會從 IoGetDeviceObjectPointer 取得裝置物件,並將它傳遞給 IoHelperGetDeviceBluetoothAddress。
_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS
IoHelperGetDevicePdo(
_In_ PDEVICE_OBJECT DeviceObject,
_Out_ PDEVICE_OBJECT *PhysicalDeviceObject
)
/*++
Routine description:
Returns a pointer to the physical device object in a driver stack and
increments the reference count on that object.
Parameters:
DeviceObject
Pointer to the device object for which the physical device object is
retrieved.
PhysicalDeviceObject
Returns a pointer to the physical device object in a stack of device
objects after incrementing the reference count on the object.
Return value:
A status code.
Remarks:
This routine uses IRP_MN_QUERY_DEVICE_RELATIONS TargetDeviceRelation to
get the physical device object from the device stack.
Requirements:
IRQL = PASSIVE_LEVEL
--*/
{
NTSTATUS status;
PIRP irp = NULL;
PDEVICE_RELATIONS deviceRelations = NULL;
PIO_STACK_LOCATION ioStack;
KEVENT completionEvent;
PAGED_CODE();
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
ioStack = IoGetNextIrpStackLocation(irp);
ioStack->MajorFunction = IRP_MJ_PNP;
ioStack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
ioStack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
KeInitializeEvent(&completionEvent, SynchronizationEvent, FALSE);
IoSetCompletionRoutine(irp, OnRequestComplete, &completionEvent, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING) {
// wait for irp to complete
KeWaitForSingleObject(
&completionEvent,
Suspended,
KernelMode,
FALSE,
NULL);
status = irp->IoStatus.Status;
}
if (NT_SUCCESS(status))
{
deviceRelations = (PDEVICE_RELATIONS)irp->IoStatus.Information;
*PhysicalDeviceObject = deviceRelations->Objects[0];
}
Exit:
if (deviceRelations != NULL)
{
ExFreePool(deviceRelations);
}
if (irp != NULL)
{
IoFreeIrp(irp);
}
return status;
}
_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS IoHelperGetDeviceBluetoothAddress(
_In_ PDEVICE_OBJECT DeviceObject,
_Outptr_ PWSTR *BluetoothAddress,
_In_ ULONG Tag
)
/*++
Routine description:
Returns the Bluetooth address string for the physical device object in the
device stack.
Parameters:
DeviceObject
Pointer to a device object in a device stack whose physical object has
a Bluetooth address property.
BluetoothAddress
Returns a string allocated from NonPagedPoolNx pool.
Tag
Return value:
A status code.
Remarks:
This routine retrieves the DEVPKEY_Bluetooth_DeviceAddress property from
the physical device object in the device stack containing the specified
device object.
Requirements:
IRQL = PASSIVE_LEVEL
--*/
{
NTSTATUS status;
PDEVICE_OBJECT physicalDeviceObject = NULL;
PWSTR bluetoothAddress = NULL;
ULONG requiredSize;
DEVPROPTYPE devPropType;
PAGED_CODE();
status = IoHelperGetDevicePdo(DeviceObject, &physicalDeviceObject);
if (!NT_SUCCESS(status))
{
goto Exit;
}
status = IoGetDevicePropertyData(physicalDeviceObject, &DEVPKEY_Bluetooth_DeviceAddress, LOCALE_NEUTRAL, 0, 0, NULL, &requiredSize, &devPropType);
if (NT_SUCCESS(status) || devPropType != DEVPROP_TYPE_STRING)
{
status = STATUS_UNSUCCESSFUL;
goto Exit;
}
if (status != STATUS_BUFFER_TOO_SMALL)
{
goto Exit;
}
bluetoothAddress = (PWCH)ExAllocatePoolWithTag(NonPagedPoolNx, requiredSize, Tag);
if (bluetoothAddress == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
status = IoGetDevicePropertyData(physicalDeviceObject, &DEVPKEY_Bluetooth_DeviceAddress, LOCALE_NEUTRAL, 0, requiredSize, bluetoothAddress, &requiredSize, &devPropType);
if (!NT_SUCCESS(status))
{
goto Exit;
}
*BluetoothAddress = bluetoothAddress;
bluetoothAddress = NULL;
status = STATUS_SUCCESS;
Exit:
if (bluetoothAddress != NULL)
{
ExFreePoolWithTag(bluetoothAddress, Tag);
}
if (physicalDeviceObject != NULL)
{
ObDereferenceObject(physicalDeviceObject);
}
return status;
}