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

📄 btd.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
	}

	if (pCall == VerifyCall (pCall)) {
		if (iRes == ERROR_SUCCESS) {
			if (pCall->fComplete)
				iRes = pCall->iResult;
			else
				iRes = ERROR_INTERNAL_ERROR;
		}

		if (iRes == ERROR_SUCCESS)
			gpState->b = pCall->baResult;

		DeleteCall (pCall);
	} else if (iRes == ERROR_SUCCESS)
		iRes = ERROR_INTERNAL_ERROR;

	if (iRes != ERROR_SUCCESS) {
		gpState->Unlock ();
		return iRes;
	}

	WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
	DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
	unsigned char aComputerName[BD_MAXNAME];
	memset (aComputerName, 0, sizeof(aComputerName));

	if (gpState->fIsRunning && gpState->fConnected && GetComputerName (szComputerName, &dwSize) &&
		(WideCharToMultiByte (CP_UTF8, 0, szComputerName, -1, (char *)aComputerName, sizeof(aComputerName), NULL, NULL) ||
		WideCharToMultiByte (CP_ACP, 0, szComputerName, -1, (char *)aComputerName, sizeof(aComputerName), NULL, NULL))) {

		HCI_ChangeLocalName_In pCallback = gpState->hci_if.hci_ChangeLocalName_In;
		pCall = AllocCall (CALL_HCI_CHANGE_LOCAL_NAME);
		if (! pCall) {
			gpState->Unlock ();
			return ERROR_OUTOFMEMORY;
		}

		pCall->hProcOwner = NULL;

		HANDLE hEvent = pCall->hEvent;

		gpState->AddRef ();
		gpState->Unlock ();
		int iRes = ERROR_INTERNAL_ERROR;
		__try {
			iRes = pCallback (hHCI, pCall, aComputerName);
		} __except (1) {
		}

		if (iRes == ERROR_SUCCESS)
			WaitForSingleObject (hEvent, 5000);

		gpState->Lock ();
		gpState->DelRef ();

		if (! gpState->fIsRunning) {
			gpState->Unlock ();
			return ERROR_CANCELLED;
		}

		if (pCall == VerifyCall (pCall)) {
			if (iRes == ERROR_SUCCESS) {
				if (pCall->fComplete)
					iRes = pCall->iResult;
				else
					iRes = ERROR_INTERNAL_ERROR;
			}

			DeleteCall (pCall);
		} else if (iRes == ERROR_SUCCESS)
			iRes = ERROR_INTERNAL_ERROR;

		if (iRes != ERROR_SUCCESS) {
			gpState->Unlock ();
			return iRes;
		}
	}

	HANDLE hSignal = gpState->hNamedEvents[BTD_EVENT_HARDWARE_CHANGED];

	int fHaveCOD = FALSE;
	unsigned int cod = 0;

	gpState->fNoSuspend = FALSE;

	HKEY hk;
	if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_BASE, L"software\\microsoft\\bluetooth\\sys", 0, KEY_READ, &hk)) {
		DWORD dwSize = sizeof(cod);
		DWORD dwType;

		if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"COD", NULL, &dwType, (BYTE *)&cod, &dwSize)) &&
			(dwType == REG_DWORD) && (dwSize == sizeof(cod)))
			fHaveCOD = TRUE;

		DWORD dw = 0;
		dwSize = sizeof(dw);

		if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"DisableAutoSuspend", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
			(dwType == REG_DWORD) && (dwSize == sizeof(dw)) && dw)
			gpState->fNoSuspend = TRUE;

		RegCloseKey (hk);
	}

	gpState->Unlock ();

	if (fHaveCOD)
		BthWriteCOD (cod);

	SetEvent (hSignal);
	ResetEvent (hSignal);

	return ERROR_SUCCESS;
}

static void ProcessExited (HANDLE hProc) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: ProcessExited 0x%08x\n", hProc));

	if (! gpState)
		return;

	gpState->Lock ();

	if (gpState->hSecurityUIProc == hProc)
		CleanUpSecurityUIHandler ();

	if (! gpState->fIsRunning) {
		gpState->Unlock ();
		return;
	}

	SCall *pCall = gpState->pCalls;
	while (pCall) {
		if ((pCall->hProcOwner == hProc) && (! pCall->fComplete)) {
			pCall->fComplete = TRUE;
			pCall->iResult = ERROR_SHUTDOWN_IN_PROGRESS;
			SetEvent (pCall->hEvent);
		}

		pCall = pCall->pNext;
	}

	Link *pLink = gpState->pLinks;
	Link *pParent = NULL;
	
	while (pLink) {		
		if (pLink->hProcOwner == hProc) {
			if (pParent)
				pParent->pNext = pLink->pNext;
			else
				gpState->pLinks = pLink->pNext;

			unsigned short h = pLink->h;
			svsutil_FreeFixed (pLink, gpState->pfmdLinks);

			HCI_Disconnect_In pCallback = gpState->hci_if.hci_Disconnect_In;
			HANDLE hHCI = gpState->hHCI;
			
			gpState->AddRef ();
			gpState->Unlock ();

			__try {
				pCallback (hHCI, NULL, h, 0x13);
			} __except (1) {
				IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"BTSHELL :: Process exited :: exception in hci_Disconnect_In\n"));
			}

			gpState->Lock ();
			gpState->DelRef ();

			pLink = gpState->pLinks;
			pParent = NULL;
		} else {
			pParent = pLink;
			pLink = pLink->pNext;
		}
	}

	gpState->Unlock ();

	SdpRemoveRecordsOnProcessExit(hProc);
}

static int CleanUpL2CAP (SCall *pCall) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: CleanUpL2CAP : ensuring that skies are clear\n"));

	BT_LAYER_IO_CONTROL pCallback = gpState->l2cap_if.l2ca_ioctl;
	int iRes = ERROR_INTERNAL_ERROR;

	int fWait = FALSE;
	int cRet = 0;

	HANDLE hL2CAP = gpState->hL2CAP;
	HANDLE hEvent = pCall->hEvent;

	gpState->AddRef ();
	gpState->Unlock ();

	__try {
		iRes = pCallback (hL2CAP, BTH_L2CAP_IOCTL_DROP_IDLE, sizeof(pCall), (char *)&pCall, sizeof(fWait), (char *)&fWait, &cRet);
	} __except (1) {
		IFDBG(DebugOut (DEBUG_ERROR, L"Shell: CleanUpL2CAP : excepted in l2ca_ioctl\n"));
	}

	if ((iRes == ERROR_SUCCESS) && fWait) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: CleanUpL2CAP : have connection to clean up, waiting...\n"));
		WaitForSingleObject (hEvent, 15000);
	}

	gpState->Lock ();
	gpState->DelRef ();

	if (iRes != ERROR_SUCCESS) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: CleanUpL2CAP : %d\n", iRes));
		return iRes;
	}

	if (pCall != VerifyCall (pCall)) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: CleanUpL2CAP : ERROR_INTERNAL_ERROR\n"));
		return ERROR_INTERNAL_ERROR;
	}

	iRes = pCall->iResult;

	if (iRes != ERROR_SUCCESS) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: CleanUpL2CAP : aborted, %d\n", iRes));
		return iRes;
	}

	pCall->fComplete = FALSE;

	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: CleanUpL2CAP : ERROR_SUCCESS\n"));
	return ERROR_SUCCESS;
}

static int GetHandleForBA
(
BD_ADDR *pba,
unsigned short	*phandle
) {
	// First, get the connection handle 
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"GetHandleForBA : %04x%08x : getting connection handle\n", pba->NAP, pba->SAP));

	union {
		BD_ADDR b;
		unsigned char data[sizeof(BD_ADDR) + 1];
	} in_buff;

	memset (&in_buff, 0, sizeof(in_buff));
	in_buff.b = *pba;

	HANDLE hHCI = gpState->hHCI;
	BT_LAYER_IO_CONTROL pCallbackIOCTL = gpState->hci_if.hci_ioctl;
	gpState->AddRef ();
	gpState->Unlock ();
	int iRes = ERROR_INTERNAL_ERROR;
	__try {
		int dwData = 0;
		iRes = pCallbackIOCTL (hHCI, BTH_HCI_IOCTL_GET_HANDLE_FOR_BD, sizeof(in_buff), (char *)&in_buff, sizeof(*phandle), (char *)phandle, &dwData);
		if ((iRes == ERROR_SUCCESS) && (dwData != sizeof(*phandle))) {
			IFDBG(DebugOut (DEBUG_ERROR, L"[SHELL] GetHandleForBA : %04x%08x : incorrect return buffer in hci_ioctl\n", pba->NAP, pba->SAP));
			iRes = ERROR_INTERNAL_ERROR;
		}
	} __except (1) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[SHELL] GetHandleForBA : %04x%08x : exception in hci_ioctl\n", pba->NAP, pba->SAP));
	}
	gpState->Lock ();
	gpState->DelRef ();

	if ((iRes == ERROR_SUCCESS) && (! gpState->fConnected)) {
		iRes = ERROR_SERVICE_NOT_ACTIVE;
		IFDBG(DebugOut (DEBUG_WARN, L"[SHELL] GetHandleForBA : %04x%08x (rare event!) disconnected while in ioctl\n", pba->NAP, pba->SAP));
	}

	return iRes;
}

static int LockL2CAPConnection
(
BD_ADDR *pba,
int fLock
) {
	// First, get the connection handle 
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"LockL2CAPConnection : %04x%08x : %s l2cap connection\n", pba->NAP, pba->SAP, fLock ? L"locking" : L"unlocking"));

	HANDLE hL2CAP = gpState->hL2CAP;
	BT_LAYER_IO_CONTROL pCallbackIOCTL = gpState->l2cap_if.l2ca_ioctl;
	gpState->AddRef ();
	gpState->Unlock ();
	int iRes = ERROR_INTERNAL_ERROR;
	__try {
		int dwData = 0;
		iRes = pCallbackIOCTL (hL2CAP, fLock ? BTH_L2CAP_IOCTL_LOCK_BASEBAND : BTH_L2CAP_IOCTL_UNLOCK_BASEBAND, sizeof(*pba), (char *)pba, 0, NULL, &dwData);
		if ((iRes == ERROR_SUCCESS) && (dwData != 0)) {
			IFDBG(DebugOut (DEBUG_ERROR, L"[SHELL] GetHandleForBA : %04x%08x : incorrect return buffer in l2cap_ioctl\n", pba->NAP, pba->SAP));
			iRes = ERROR_INTERNAL_ERROR;
		}
	} __except (1) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[SHELL] GetHandleForBA : %04x%08x : exception in l2cap_ioctl\n", pba->NAP, pba->SAP));
	}
	gpState->Lock ();
	gpState->DelRef ();

	if ((iRes == ERROR_SUCCESS) && (! gpState->fConnected)) {
		iRes = ERROR_SERVICE_NOT_ACTIVE;
		IFDBG(DebugOut (DEBUG_WARN, L"[SHELL] GetHandleForBA : %04x%08x (rare event!) disconnected while in ioctl\n", pba->NAP, pba->SAP));
	}

	return iRes == ERROR_SUCCESS ? TRUE : FALSE;
}

static int WaitForCommandCompletion (HANDLE hEvent, BD_ADDR *pba, unsigned short h) {
	for ( ; ; ) {
		int iRes = WaitForSingleObject (hEvent, COMMAND_PERIODIC_TIMEOUT);
		if (iRes == WAIT_OBJECT_0)
			return ERROR_SUCCESS;

		if (iRes == WAIT_TIMEOUT) {
			unsigned short h2 = 0;

			gpState->Lock ();
			iRes = GetHandleForBA (pba, &h2);
			gpState->Unlock ();

			if (iRes != ERROR_SUCCESS)
				return iRes;

			if (h2 != h)
				return ERROR_CONNECTION_INVALID;

			continue;
		}

		return ERROR_OPERATION_ABORTED;
	}
}

static BOOL RouteSCOControl (void) {
	BOOL fSCOControl = TRUE;
	HKEY hk;
	
	if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Bluetooth\\AudioGateway", 0, 0, &hk)) {
		DWORD dwData;
    	DWORD cbAudioRoute = sizeof(DWORD);
	    if ((ERROR_SUCCESS == RegQueryValueEx(hk, _T("MapAudioToPcmMode"), 0, NULL, (PBYTE)&dwData, &cbAudioRoute)) && (0 == dwData)) {
	        fSCOControl = FALSE;
	    }
	}

	return fSCOControl;
}


//
//	Callbacks
//
static int btshell_CallAborted (void *pCallContext, int iError) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: SCall aborted for call 0x%08x error %d\n", pCallContext, iError));

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();

	if (! gpState->fIsRunning) {
		gpState->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	SCall *pCall = VerifyCall ((SCall *)pCallContext);
	if (! pCall) {
		gpState->Unlock ();
		return ERROR_NOT_FOUND;
	}

	pCall->fComplete = TRUE;
	pCall->iResult = iError;
	SetEvent (pCall->hEvent);

	gpState->Unlock ();

	return ERROR_SUCCESS;
}

static int btshell_LocalNameDone (void *pCallContext, unsigned char status) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: local name done status %d\n", pCallContext, status));

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();

	if (! gpState->fIsRunning) {
		gpState->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	SCall *pCall = VerifyCall ((SCall *)pCallContext);
	if (! pCall) {
		gpState->Unlock ();
		return ERROR_NOT_FOUND;
	}

	pCall->fComplete = TRUE;
	pCall->iResult = StatusToError (status, ERROR_INTERNAL_ERROR);
	SetEvent (pCall->hEvent);

	gpState->Unlock ();

	return ERROR_SUCCESS;
}

static int btshell_Inquiry_Out (void *pCallContext, unsigned char status) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: Inquiry out status %d\n", status));

	if (status != 0)
		return btshell_CallAborted (pCallContext, StatusToError (status, ERROR_INTERNAL_ERROR));

	return ERROR_SUCCESS;
}

static int btshell_BDADDR_Out (void *pCallContext, unsigned char status, BD_ADDR *pba) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: BD READ out status %d, address %04x%08x\n", status, pba->NAP, pba->SAP));

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();

	if (! gpState->fIsRunning) {
		gpState->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -