为啥 BluetoothSetLocalServiceInfo 会抛出错误 1314?

Posted

技术标签:

【中文标题】为啥 BluetoothSetLocalServiceInfo 会抛出错误 1314?【英文标题】:why does BluetoothSetLocalServiceInfo throw error 1314?为什么 BluetoothSetLocalServiceInfo 会抛出错误 1314? 【发布时间】:2021-06-17 02:59:20 【问题描述】:

我正在尝试构建一个 BT 应用程序。我想使用 BluetoothSetLocalServiceInfo,但收到错误 1314(客户端不持有所需的权限)。 我使用 Windows 驱动程序中的 echo 蓝牙示例。这是我修改后的代码:

DEFINE_GUID(BTHECHOSAMPLE_SVC_GUID, 0xc07508f2, 0xb970, 0x43ca, 0xb5, 0xdd, 0xcc, 0x4f, 0x23, 0x91, 0xbe, 0xf4);
wchar_t name[17] = L"BthEchoSampleSrv";
extern __declspec(selectany) const PWSTR BthEchoSampleSvcName = name;
/* fc71b33d-d528-4763-a86c-78777c7bcd7b */
DEFINE_GUID(BTHECHOSAMPLE_DEVICE_INTERFACE, 0xfc71b33d, 0xd528, 0x4763, 0xa8, 0x6c, 0x78, 0x77, 0x7c, 0x7b, 0xcd, 0x7b);

int main()

  DWORD err = ERROR_SUCCESS;
  BLUETOOTH_LOCAL_SERVICE_INFO SvcInfo =  0 ;
  SvcInfo.Enabled = true;

  if (FAILED(StringCbCopyW(SvcInfo.szName, sizeof(SvcInfo.szName), BthEchoSampleSvcName)))
  
    printf("Copying svc name failed\n");
    goto exit;
  

  std::cout<<"Name of the device: "<< SvcInfo.szName<<std::endl;

  if (ERROR_SUCCESS != (err = BluetoothSetLocalServiceInfo(
    NULL, //callee would select the first found radio
    &BTHECHOSAMPLE_SVC_GUID,
    0,
    &SvcInfo
  )))
  
    printf("BluetoothSetLocalServiceInfo failed, err = %d\n", err);
    goto exit;
  
exit:
  return err;

我在命令行中运行代码(以管理员身份打开),并更改了应用程序的属性以使用管理员权限运行。我错过了什么?

【问题讨论】:

【参考方案1】:

错误 1314 是 ERROR_PRIVILEGE_NOT_HELD。根据BluetoothSetLocalServiceInfo() 文档:

BluetoothSetLocalServiceInfo 函数返回以下值:

...

STATUS_PRIVILEGE_NOT_HELD 调用者没有所需的权限。有关如何提升权限的信息,请参阅备注部分。

并且备注说:

警告调用BluetoothSetLocalServiceInfo的进程必须具有SE_LOAD_DRIVER_NAME权限。在系统或管理员上下文中运行的进程可以使用SDK LookupPrivilegeValue提升其权限和AdjustTokenPrivileges 函数。有关这方面的更多信息,请参阅Installing a Bluetooth Device。

所以,这意味着:

运行您的应用程序的用户帐户根本没有该权限 您的应用未通过AdjustTokenPrivileges() 启用该权限。

Installing a Bluetooth Device 文档提供了启用SE_LOAD_DRIVER_NAME 权限的示例:

安装应用程序必须调用用户模式 ​​API BluetoothSetLocalServiceInfo。但是,在应用程序可以调用此 API 之前,应用程序必须具有SE_LOAD_DRIVER_NAME 安全权限。以下代码示例演示了如何获取此权限。请注意,该示例不演示错误处理。

HANDLE procToken;
LUID luid;
TOKEN_PRIVILEGES tp;

OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &procToken);

LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &luid);

Tp.PrivilegeCount = 1;
Tp.privileges[0].Luid = luid;
Tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(procToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD)NULL)

有关详细信息,请参阅 MSDN 上的 Changing Privileges in a Token 和 Enabling and Disabling Privileges in C++。

【讨论】:

当你是新手时很容易错过。我必须更加小心。伟大的!谢谢!这解决了一切!

以上是关于为啥 BluetoothSetLocalServiceInfo 会抛出错误 1314?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?