2010-09-21 100 views
1

我有问题,我无法解决一段时间。 对于我的一个C++项目,我必须编写函数来更改蓝牙无线电本地名称。 它使用微软蓝牙堆栈。如果打开任何蓝牙适配器设备属性并导航到高级属性,则可以找到该名称。 我需要这个没有任何第三方库,只有WinApi功能。需要以Windows设备管理器的方式执行此操作。问题是,我没有弄清楚它是如何做到的。 BluetoothAPI和Setupapi在这里似乎没用。具有SPDRP_FRIENDLYNAME参数的SetupDiSetDeviceRegistryProperty不是我所需要的。在注册表中更改本地名称也无济于事。也许我应该以某种方式在那之后重新启动蓝牙堆栈。我不知道。那么,我如何以编程方式更改设备高级属性?提前致谢。蓝牙设备本地名称

回答

0

我找到了自己的解决方案:

#include <windows.h> 
#include <Setupapi.h> 
#include <stdio.h> 
#include <tchar.h> 
#include <cfgmgr32.h> 
#include <devguid.h> 
#include <string> 
#pragma comment(lib,"setupapi.lib") 
using namespace std; 

#define WIN32_LEAN_AND_MEAN 

typedef basic_string<TCHAR> tstring; 
DEFINE_GUID(GUID_DEVCLASS_BLUETOOTH, {0xe0cbf06cL, 0xcd8b, 0x4647, {0xbb, 0x8a, 0x26, 0x3b, 0x43, 0xf0, 0xf9, 0x74}}); 


LPTSTR GetGenericBluetoothAdapterInstanceID(void) 
{ 
     unsigned i;  
     CONFIGRET r; 
     HDEVINFO hDevInfo; 
     SP_DEVINFO_DATA DeviceInfoData; 
     PTSTR deviceInstanceID = new TCHAR[MAX_DEVICE_ID_LEN]; 

     // Find all bluetooth radio modules 
     hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_BLUETOOTH, NULL, NULL, DIGCF_PRESENT); 

     if (hDevInfo == INVALID_HANDLE_VALUE) 
       return NULL; 

     // Get first Generic Bluetooth Adapter InstanceID 
     for (i = 0; ; i++) 
     {    
       DeviceInfoData.cbSize = sizeof (DeviceInfoData); 

       if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData)) 
         break; 

       r = CM_Get_Device_ID(DeviceInfoData.DevInst, deviceInstanceID , MAX_PATH, 0); 

       if (r != CR_SUCCESS) 
         continue; 

       if (_tcsncmp(_TEXT("USB"), deviceInstanceID, 3) == 0) 
       {      
         return deviceInstanceID; 
       } 
     } 

     return NULL; 
} 

void find_and_replace(LPTSTR source, LPCTSTR strFind, LPCTSTR strReplace) 
{ 
     tstring s = tstring(source); 
     tstring f = tstring(strFind); 
     tstring r = tstring(strReplace);  
     size_t j; 

     for (; (j = s.find(f)) != string::npos ;) 
     { 
       s.replace(j, f.length(), r); 
     } 

     _tcscpy(source, s.c_str()); 
} 

int _tmain(int argc, TCHAR *argv[]) 
{ 
     if (argc != 2) 
     { 
       _tprintf(TEXT("Invalid parameters number. " 
         TEXT("Usage: Bthrmmodifier.exe <radio module local name>\n"))); 
       return 1; 
     } 

     LPTSTR instanceID = GetGenericBluetoothAdapterInstanceID(); 

     if (instanceID == NULL) 
     { 
       _tprintf(_TEXT("Failed to get Generic Bluetooth Adapter InstanceID\n")); 
       return 1; 
     } 

     LPTSTR instanceIDModified = new TCHAR[_tcslen(instanceID)]; 
     _tcscpy(instanceIDModified, instanceID); 
     find_and_replace(instanceIDModified, _TEXT("\\"), _TEXT("#")); 

     HANDLE hDevice; 
     TCHAR fileName[1024] = { 0 }; 
     _tcscpy(fileName, _TEXT("\\\\.\\")); 
     _tcscat(fileName, instanceIDModified); 
     _tcscat(fileName, _TEXT("#{a5dcbf10-6530-11d2-901f-00c04fb951ed}")); 

     hDevice = CreateFile(fileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 

     if (hDevice == INVALID_HANDLE_VALUE) 
     { 
       _tprintf(_TEXT("Failed to open device. Error code: %d\n"), GetLastError());    
       return EXIT_FAILURE; 
     } 

     //Change radio module local name in registry 
     LPTSTR RMLocalName = argv[1]; 
     CHAR bufRMLocalName[256]; 

     int nLength = WideCharToMultiByte(CP_UTF8, 0, RMLocalName, 
       -1, NULL, 0, NULL, NULL); 
     WideCharToMultiByte(CP_UTF8, 0, RMLocalName, 
       -1, bufRMLocalName, nLength, NULL, NULL); 

     HKEY hKey; 
     TCHAR rmLocalNameKey[1024] = { 0 }; 
     LSTATUS ret; 
     _tcscpy(rmLocalNameKey, _TEXT("SYSTEM\\ControlSet001\\Enum\\"));  
     _tcscat(rmLocalNameKey, instanceID); 
     _tcscat(rmLocalNameKey, _TEXT("\\Device Parameters")); 

     ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, rmLocalNameKey, 
       0L, KEY_SET_VALUE , &hKey); 

     if(ret != ERROR_SUCCESS) 
     { 
       _tprintf(TEXT("Failed to open registry key. Error code: %d\n"), ret); 
       return EXIT_FAILURE; 
     } 

     ret = RegSetValueEx(hKey, _TEXT("Local Name"), 0, REG_BINARY, 
       (LPBYTE)bufRMLocalName, nLength); 

     if (ret != ERROR_SUCCESS) 
     { 
       _tprintf(TEXT("Failed to set registry key. Error code: %d\n"), ret); 
       return EXIT_FAILURE; 
     } 

     RegCloseKey(hKey); 

     // This check decides what IO control code to use based on if we're in XP or Vista (and later). 
     OSVERSIONINFO osver; 
     osver.dwOSVersionInfoSize = sizeof(osver); 
     GetVersionEx(&osver); 

     UINT ctlCode = (UINT)(6 > osver.dwMajorVersion ? 0x220fd4 : 0x411008); 
     long reload = 4; // tells the control function to reset or reload or similar... 
     DWORD bytes = 0; // merely a placeholder 

     // Send radio module driver command to update device information 
     if (!DeviceIoControl(hDevice, ctlCode, &reload, 4, NULL, 0, &bytes, NULL)) 
     { 
       _tprintf(TEXT("Failed to update radio module local name. Error code: %d\n"), GetLastError()); 
       return EXIT_FAILURE; 
     } 

     _tprintf(TEXT("Done\n")); 

     return EXIT_SUCCESS; 
} 
+0

你能后你是如何解决这个问题呢? – Nightfirecat 2011-07-18 18:07:33