📄 bthuniv.cxx
字号:
return FALSE;
ghNotifyThread = CreateThread(NULL, 0, HciUnivNotifyThread, NULL, 0, NULL);
if (NULL == ghNotifyThread)
return FALSE;
gfInitialized = TRUE;
IFDBG(DebugOut(DEBUG_HCI_INIT, L"[HCIUNIV] -Initialize...\n"));
return TRUE;
}
/*
This function is called when the universal transport manager is being shut down.
*/
static void UnInitialize()
{
SVSUTIL_ASSERT(gpSynch->IsLocked());
if (!gfInitialized)
return;
SetEvent(ghStopNotifyThread);
WaitForSingleObject(ghNotifyThread, INFINITE);
CloseHandle(ghStopNotifyThread);
CloseHandle(ghNotifyThread);
if (ghCurDriver)
DeInitPointers();
SVSUTIL_ASSERT(gpSynch->IsLocked());
gfInitialized = FALSE;
}
/*
This funtion is called by HCI_OpenConnection to get the driver name for the current
PnP device (if one exists) and copy over the registry settings for the driver.
*/
static BOOL GetPnPDriver(LPWSTR pszName)
{
BOOL fRetVal = TRUE;
HKEY hkTrans = NULL;
HKEY hkHCI = NULL;
DWORD dwEnum = 0;
WCHAR wszKey[MAX_PATH];
DWORD dwType;
DWORD dwSize = sizeof(WCHAR)*MAX_PATH;
GUID ZeroGuid;
memset(&ZeroGuid, 0, sizeof(GUID));
if (0 == memcmp(&gIClassGuid, &ZeroGuid, sizeof(GUID))) {
return FALSE;
}
swprintf(wszKey, L"Software\\Microsoft\\Bluetooth\\Transports\\PnP\\{" SVSUTIL_GUID_FORMAT_W L"}" , SVSUTIL_RGUID_ELEMENTS(gIClassGuid));
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_BASE, wszKey, 0, 0, &hkTrans)) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"[HCIUNIV] Could not get PnP device for specified IClass\n"));
ASSERT(0);
fRetVal = FALSE;
goto exit;
}
if ((ERROR_SUCCESS != RegQueryValueEx(hkTrans, L"driver", NULL, &dwType, (LPBYTE)pszName, &dwSize)) && (dwType == REG_SZ)) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"[HCIUNIV] Could not get transport driver for PnP device\n"));
ASSERT(0);
fRetVal = FALSE;
goto exit;
}
IFDBG(DebugOut (DEBUG_HCI_INIT, L"[HCIUNIV] PnP device found. Using driver %s.\n", pszName));
WCHAR wszHCI[] = L"Software\\Microsoft\\Bluetooth\\HCI";
CopyRegistryEntry(wszHCI, wszKey, HKEY_BASE, TRUE);
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_BASE, wszHCI, 0, 0, &hkHCI)) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"[HCIUNIV] Could not open HCI registry key\n"));
ASSERT(0);
fRetVal = FALSE;
goto exit;
}
if (ERROR_SUCCESS != RegSetValueEx(hkHCI, L"Name", 0, REG_SZ, (LPBYTE)gwszDevName, (wcslen(gwszDevName)+1)*sizeof(WCHAR))) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"[HCIUNIV] Could not set device name in HCI registry key\n"));
ASSERT(0);
fRetVal = FALSE;
goto exit;
}
exit:
if (hkTrans) {
RegCloseKey(hkTrans);
}
if (hkHCI) {
RegCloseKey(hkHCI);
}
return fRetVal;
}
/*
This function is called by HCI to set the callback function to indicate device
insertion/removal notifications.
*/
int HCI_SetCallback (HCI_TransportCallback pfCallback)
{
int nRet = FALSE;
gpSynch->Lock();
if (pfCallback)
{
if (!pfnCallback)
DebugInit();
nRet = Initialize();
if (!nRet)
UnInitialize();
}
else
{
UnInitialize();
if (pfnCallback)
DebugDeInit();
}
pfnCallback = pfCallback;
gpSynch->Unlock();
return nRet;
}
/*
This function is called by HCI to start the hardware. In this case we indicate a
device up notification so HCI will proceed with a call to HCI_OpenConnection.
*/
int HCI_StartHardware (void)
{
HCI_TransportCallback pfn = NULL;
gpSynch->Lock();
BOOL fInit = gfInitialized;
pfn = pfnCallback;
gfStopHardware = FALSE;
gpSynch->AddRef();
gpSynch->Unlock();
int fRet = ((fInit) && (pfn) && (ERROR_SUCCESS == pfn(DEVICE_UP, NULL)));
gpSynch->Lock();
gpSynch->DelRef();
gpSynch->Unlock();
return fRet;
}
/*
This function is called by HCI to stop the hardware. In this case we indicate a
device up notification so HCI will proceed with a call to HCI_CloseConnection.
*/
int HCI_StopHardware (void)
{
HCI_TransportCallback pfn = NULL;
gpSynch->Lock();
BOOL fInit = gfInitialized;
pfn = pfnCallback;
gfStopHardware = TRUE;
gpSynch->AddRef();
gpSynch->Unlock();
int fRet = ((fInit) && (pfn) && (ERROR_SUCCESS == pfn(DEVICE_DOWN, NULL)));
gpSynch->Lock();
gpSynch->DelRef();
gpSynch->Unlock();
return fRet;
}
/*
This function is called by HCI to read the current transport driver parameters.
*/
int HCI_ReadHciParameters (HCI_PARAMETERS *pParms)
{
HCI_READHCIPARAMETERS pfn = NULL;
int nRet = FALSE;
gpSynch->Lock();
BOOL fInit = gfInitialized;
pfn = pfnReadHciParameters;
gpSynch->AddRef();
gpSynch->Unlock();
if (fInit && pfn)
nRet = (*pfn)(pParms);
if (!nRet)
{
IFDBG(DebugOut(DEBUG_ERROR, L"[HCIUNIV] HCI_ReadHciParameters failed.\n"));
}
gpSynch->Lock();
gpSynch->DelRef();
gpSynch->Unlock();
return nRet;
}
/*
This function is called by HCI to open a connection to a transport driver. This function first sees
if there is a PnP device present and if not tries to open a built-in driver.
*/
int HCI_OpenConnection (void)
{
int nRet = FALSE;
HCI_OPENCONNECTION pfn = NULL;
HCI_SETCALLBACK pfncb = NULL;
HINSTANCE hLib = NULL;
int nCurrent = -1;
WCHAR szDriver[MAX_PATH];
DWORD dwDriver = sizeof(szDriver);
HKEY hk;
gpSynch->Lock();
while(geInCall != eOther)
{
gpSynch->Unlock();
Sleep(2000);
gpSynch->Lock();
}
if (!gfInitialized || ghCurDriver)
{
gpSynch->Unlock();
return FALSE;
}
geInCall = eOpen;
//
// Try opening PnP device
//
if (GetPnPDriver(szDriver))
{
if ((NULL != (hLib = LoadLibrary(szDriver))) &&
(NULL != (pfn = (HCI_OPENCONNECTION )GetProcAddress(hLib, L"HCI_OpenConnection"))) &&
(NULL != (pfncb = (HCI_SETCALLBACK )GetProcAddress(hLib, L"HCI_SetCallback"))))
{
gpSynch->AddRef();
gpSynch->Unlock();
if (ERROR_SUCCESS == (*pfncb)(TransportCallback))
nRet = (*pfn)();
if (!nRet)
(*pfncb)(NULL);
else
ghCurDriver = hLib;
gpSynch->Lock();
gpSynch->DelRef();
}
}
if (nRet)
goto Done;
else if (hLib)
{
FreeLibrary(hLib);
hLib = NULL;
}
//
// No PnP devices present. Try built-in devices.
//
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_BASE, L"Software\\Microsoft\\Bluetooth\\Transports\\Builtin", 0, 0, &hk))
{
//MAX_PATH is way too much for numbers. This is in case somebody decides they dont like numbers...
WCHAR szId[MAX_PATH];
DWORD dwId = MAX_PATH;
DWORD dwIndex = 0;
while((ERROR_SUCCESS == RegEnumKeyEx(hk, dwIndex++, szId, &dwId, NULL, NULL, NULL, NULL)) && (dwId < MAX_PATH))
{
HKEY hk1;
DWORD dwType;
if ((ERROR_SUCCESS == RegOpenKeyEx(hk, szId, 0, 0, &hk1)) && (hk1) &&
(ERROR_SUCCESS == RegQueryValueEx(hk1, L"driver", NULL, &dwType, (LPBYTE )szDriver, &dwDriver)) &&
(dwDriver < sizeof(szDriver)) && (dwType == REG_SZ) &&
(NULL != (hLib = LoadLibrary(szDriver))) &&
(NULL != (pfn = (HCI_OPENCONNECTION )GetProcAddress(hLib, L"HCI_OpenConnection"))) &&
(NULL != (pfncb = (HCI_SETCALLBACK )GetProcAddress(hLib, L"HCI_SetCallback"))) )
{
WCHAR szKey[MAX_PATH];
WCHAR szHCI[] = L"Software\\Microsoft\\Bluetooth\\HCI";
wcscpy(szKey, L"Software\\Microsoft\\Bluetooth\\Transports\\Builtin\\");
wcsncat(szKey, szId, MAX_PATH - wcslen(szKey) - 1);
CopyRegistryEntry(szHCI, szKey, HKEY_BASE, TRUE);
gpSynch->AddRef();
gpSynch->Unlock();
if (ERROR_SUCCESS == (*pfncb)(TransportCallback))
nRet = (*pfn)();
if (!nRet)
(*pfncb)(NULL);
gpSynch->Lock();
gpSynch->DelRef();
if (!nRet)
{
HKEY hk2;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_BASE, szHCI, 0, 0, &hk2))
{
SVSUTIL_ASSERT(hk2);
DeleteValues(hk2);
RegCloseKey(hk2);
}
}
else
{
IFDBG(DebugOut(DEBUG_HCI_INIT, L"[HCIUNIV] HCI_OpenConnection using driver %s(Id=%s).\n", szDriver, szId));
ghCurDriver = hLib;
RegCloseKey(hk1);
break;
}
}
if (hk1)
RegCloseKey(hk1);
if (hLib)
{
FreeLibrary(hLib);
hLib = NULL;
}
dwId = MAX_PATH;
dwDriver = sizeof(szDriver);
}
RegCloseKey(hk);
}
Done:
SVSUTIL_ASSERT(gpSynch->IsLocked());
if (nRet)
nRet = InitPointers();
else
IFDBG(DebugOut(DEBUG_ERROR, L"[HCIUNIV] HCI_OpenConnection failed.\n"));
geInCall = eOther;
gpSynch->Unlock();
return nRet;
}
/*
This function is called by HCI to close a connection to a transport driver.
*/
void HCI_CloseConnection (void)
{
HCI_CLOSECONNECTION pfn = NULL;
HCI_SETCALLBACK pfncb = NULL;
gpSynch->Lock();
while(geInCall != eOther)
{
gpSynch->Unlock();
Sleep(2000);
gpSynch->Lock();
}
geInCall = eClose;
BOOL fInit = gfInitialized;
pfn = pfnCloseConnection;
pfncb = pfnSetCallback;
gpSynch->AddRef();
gpSynch->Unlock();
if (fInit && pfn)
{
(*pfn)();
(*pfncb)(NULL);
}
gpSynch->Lock();
gpSynch->DelRef();
if (fInit && pfn)
{
DeInitPointers();
}
SVSUTIL_ASSERT(gpSynch->IsLocked());
geInCall = eOther;
gpSynch->Unlock();
}
/*
This function is called by HCI to write a packet. This function calls directly into
the active transport driver.
*/
int HCI_WritePacket (HCI_TYPE eType, BD_BUFFER *pBuff)
{
int nRet = FALSE;
HCI_WRITEPACKET pfn = NULL;
gpSynch->Lock();
BOOL fInit = gfInitialized;
pfn = pfnWritePacket;
gpSynch->AddRef();
gpSynch->Unlock();
if (fInit && pfn)
nRet = (*pfn)(eType, pBuff);
if (!nRet)
{
IFDBG(DebugOut(DEBUG_ERROR, L"[HCIUNIV] HCI_WritePacket failed.\n"));
}
gpSynch->Lock();
gpSynch->DelRef();
gpSynch->Unlock();
return nRet;
}
/*
This function is called by HCI to read a packet. This function calls directly into
the active transport driver.
*/
int HCI_ReadPacket (HCI_TYPE *peType, BD_BUFFER *pBuff)
{
int nRet = FALSE;
HCI_READPACKET pfn = NULL;
gpSynch->Lock();
BOOL fInit = gfInitialized;
pfn = pfnReadPacket;
gpSynch->AddRef();
gpSynch->Unlock();
if (fInit && pfn)
nRet = (*pfn)(peType, pBuff);
if (!nRet)
{
IFDBG(DebugOut(DEBUG_ERROR, L"[HCIUNIV] HCI_ReadPacket failed.\n"));
}
gpSynch->Lock();
gpSynch->DelRef();
gpSynch->Unlock();
return nRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -