⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bthuniv.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CXX
📖 第 1 页 / 共 2 页
字号:
		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 + -