📄 portemu.cxx
字号:
pIO = pIO->pNext;
}
SVSUTIL_ASSERT (cHaveBytes == cTotalBytes);
pContext->iSendQuotaUsed += cTotalBytes;
if (pContext->credit_fc) {
--pContext->iHaveCredits;
pContext->iGaveCredits += cGiveCredits;
}
SVSUTIL_ASSERT (pContext->iHaveCredits >= 0);
// Send the buffer down...
HANDLE h = pContext->hRFCOMM;
HANDLE hConn = pContext->hConnection;
RFCOMM_DataDown_In pCallback = pContext->rfcomm_if.rfcomm_DataDown_In;
pContext->fSending = TRUE;
gpPORTEMU->Unlock ();
int iRes = ERROR_INTERNAL_ERROR;
__try {
iRes = pCallback (h, pCall, hConn, pBuffer, cGiveCredits);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] SendData : exception in rfcomm_DataDown_In\n"));
}
gpPORTEMU->Lock ();
if (! (gpPORTEMU->fInitialized &&
(pContext == GetContext ((DWORD)pContext)) &&
(pContext->hConnection == hConn))) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] Going through (connection?) shutdown in the middle of send...\n"));
return ERROR_OPERATION_ABORTED;
}
pContext->fSending = FALSE;
if (iRes != ERROR_SUCCESS) { // Close the connection
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] SendData : rfcomm_DataDown_In returned %d\n", iRes));
RegisterCommEvent (pContext, EV_ERR, CE_FRAME);
CloseConnection (pContext, iRes, TRUE);
return iRes;
}
}
}
static int SendMSC (PORTEMU_CONTEXT *pContext) {
HANDLE h = pContext->hRFCOMM;
HANDLE hConnection = pContext->hConnection;
RFCOMM_MSC_In pCallback = pContext->rfcomm_if.rfcomm_MSC_In;
unsigned char v24 = EA_BIT | pContext->ucv24out;
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"SendMSC : (%s %s %s %s %s)\n",
v24 & MSC_DV_BIT ? L"MS_RLSD_ON" : L"",
v24 & MSC_IC_BIT ? L"MS_RING_ON" : L"",
v24 & MSC_RTR_BIT ? L"MS_CTS_ON" : L"",
v24 & MSC_RTC_BIT ? L"MS_DSR_ON" : L"",
v24 & MSC_FC_BIT ? L"Flow_Off" : L""));
gpPORTEMU->Unlock ();
__try {
pCallback (h, NULL, hConnection, v24, 0xff);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] SendMSC Exception in rfcomm_MSC_In\n"));
}
gpPORTEMU->Lock ();
return ERROR_SUCCESS;
}
static DWORD WINAPI AuthenticateThread (LPVOID pUserContext) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] AuthenticateThread 0x%08x\n", pUserContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] AuthenticateThread 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] AuthenticateThread 0x%08x: not initialized!\n", pUserContext));
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] AuthenticateThread 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
int fAuthenticate = pContext->freq_auth;
int fEncrypt = pContext->freq_encrypt;
BT_ADDR bt = SET_NAP_SAP (pContext->b.NAP, pContext->b.SAP);
HANDLE hConnection = pContext->hConnection;
SVSUTIL_ASSERT (fAuthenticate || fEncrypt);
SVSUTIL_ASSERT (hConnection);
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] AuthenticateThread 0x%08x : doing authentication/encryption\n", pUserContext));
gpPORTEMU->Unlock ();
int iRes = ERROR_SUCCESS;
if (fAuthenticate)
iRes = BthAuthenticate (&bt);
if ((iRes == ERROR_SUCCESS) && fEncrypt)
iRes = BthSetEncryption (&bt, TRUE);
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] AuthenticateThread 0x%08x : RE_ENTERING THE LOCK\n", pUserContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] AuthenticateThread 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] AuthenticateThread 0x%08x: not initialized!\n", pUserContext));
gpPORTEMU->Unlock ();
return 0;
}
pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] AuthenticateThread 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
int fAllow = FALSE;
if ((iRes == ERROR_SUCCESS) && pContext->fLocal && pContext->fLocalOpen && pContext->hConnection) {
fAllow = TRUE;
RegisterCommEvent (pContext, EV_RLSD, 0);
} else
ReinitClosedConnection (pContext);
HANDLE hRFCOMM = pContext->hRFCOMM;
RFCOMM_ConnectResponse_In pCallback = pContext->rfcomm_if.rfcomm_ConnectResponse_In;
gpPORTEMU->Unlock ();
__try {
iRes = pCallback (hRFCOMM, NULL, hConnection, fAllow);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] AuthenticateThread 0x%08x : exception in rfcomm_ConnectResponse_In\n", pUserContext));
}
if (fAllow && (iRes == ERROR_SUCCESS) && gpPORTEMU) {
gpPORTEMU->Lock ();
if ((pContext == GetContext ((DWORD)pUserContext)) && pContext->hConnection) {
pContext->ucv24out &= ~MSC_FC_BIT;
SendMSC (pContext);
}
gpPORTEMU->Unlock ();
}
return iRes;
}
static void PORTEMU_ProcessExited (HANDLE hProc) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] PORTEMU_ProcessExited 0x%08x\n", hProc));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] PORTEMU_ProcessExited 0x%08x : not initialized!\n", hProc));
return;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] PORTEMU_ProcessExited 0x%08x: not initialized!\n", hProc));
gpPORTEMU->Unlock ();
return;
}
while (gpPORTEMU->fInitialized) {
PORTEMU_CONTEXT *pContext = gpPORTEMU->pPorts;
int iPort = 0;
while (pContext) {
for (iPort = 0 ; iPort < PORTEMU_OPEN_MAX ; ++iPort) {
if (pContext->hOwnerProc[iPort] == hProc)
break;
}
if (iPort < PORTEMU_OPEN_MAX)
break;
pContext = pContext->pNext;
}
if (! pContext)
break;
SVSUTIL_ASSERT (iPort < PORTEMU_OPEN_MAX);
pContext->hOwnerProc[iPort] = NULL;
gpPORTEMU->AddRef ();
gpPORTEMU->Unlock ();
COM_Close (((DWORD)pContext) | iPort);
gpPORTEMU->Lock ();
gpPORTEMU->DelRef ();
}
gpPORTEMU->Unlock ();
}
static DWORD WINAPI StackDisconnect (LPVOID pArg) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"Disconnect stack\n"));
rfcomm_CloseDriverInstance ();
return ERROR_SUCCESS;
}
static DWORD WINAPI StackDown (LPVOID pArg) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"stack down\n"));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] StackDown 0x%08x : not initialized!\n", pArg));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] StackDown 0x%08x: not initialized!\n", pArg));
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pArg);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] StackDown 0x%08x : context not found\n", pArg));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
if (pContext->hConnection) {
pContext->hConnection = NULL;
pContext->fc_aggregate = 0;
CloseConnection (pContext, ERROR_GRACEFUL_DISCONNECT, TRUE);
}
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int rfcommsdp_disconnect_out(void *pCallContext, unsigned long status) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"+rfcommsdp_disconnect_out\n"));
return ERROR_SUCCESS;
}
static void rfcommsdp_disconnect (void *pCallContext, int iErr) {
SVSUTIL_ASSERT(gpPORTEMU && gpPORTEMU->IsLocked());
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] rfcommsdp_disconnect 0x%08x : context does not exist\n", pCallContext));
return;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
DeleteCall (pCall);
PendingIO *pParent = NULL;
PendingIO *pIO = pContext->pops;
while (pIO) {
if (pIO->op == COMM_OPEN) {
PendingIO *pNext = pIO->pNext;
pIO->pNext = NULL;
pIO->dwEvent = 0;
pIO->iIoResult = iErr;
SetEvent (pIO->hEvent);
if (pParent)
pParent->pNext = pNext;
else
pContext->pops = pNext;
break;
}
pParent = pIO;
pIO = pIO->pNext;
}
SVSUTIL_ASSERT (pContext->pops == NULL);
if (pContext->sdpCid) {
HANDLE h = gpPORTEMU->hSDP;
SDP_Disconnect_In pCallback = gpPORTEMU->sdp_if.sdp_Disconnect_In;
unsigned short cid = pContext->sdpCid;
pContext->sdpCid = 0;
SVSUTIL_ASSERT(h && pCallback && cid);
gpPORTEMU->AddRef ();
gpPORTEMU->Unlock ();
__try {
pCallback (h,NULL,cid);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] : exception in sdp_disconnect_in!\n"));
}
gpPORTEMU->Lock ();
gpPORTEMU->DelRef ();
}
}
static int rfcommsdp_connect_out (void *pCallContext, unsigned long status, unsigned short cid) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"+rfcommsdp_connect_out \n"));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] rfcommsdp_connect_out 0x%08x : not initialized!\n", pCallContext));
return ERROR_SUCCESS;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] rfcommsdp_connect_out 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] rfcommsdp_connect_out 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
SVSUTIL_ASSERT (pContext->channel == 0);
SVSUTIL_ASSERT (pContext->sdpCid == 0);
SdpQueryUuid uuid[2];
SdpAttributeRange attribRange;
int iErr = ERROR_PORT_UNREACHABLE;
if (status == ERROR_SUCCESS) {
SVSUTIL_ASSERT(cid);
pContext->sdpCid = cid;
// Call ServiceAttribSearch to get protocol headers.
SDP_ServiceAttributeSearch_In pCallback = gpPORTEMU->sdp_if.sdp_ServiceAttributeSearch_In;
HANDLE h = gpPORTEMU->hSDP;
SVSUTIL_ASSERT(h && pCallback);
uuid[0].uuidType = SDP_ST_UUID128;
memcpy(&uuid[0].u.uuid128, &pContext->uuidService, sizeof(GUID));
memset(&uuid[1],0,sizeof(uuid[1]));
attribRange.minAttribute = attribRange.maxAttribute = SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST;
gpPORTEMU->AddRef ();
gpPORTEMU->Unlock ();
iErr = ERROR_INTERNAL_ERROR;
__try {
iErr = pCallback (h, pCallContext, cid, uuid, &attribRange,1);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] : exception in sdp_ServiceAttributeSearch_In!\n"));
}
gpPORTEMU->Lock ();
gpPORTEMU->DelRef ();
IFDBG(DebugOut(DEBUG_ERROR,L"rfcommsdp_connect_out: returns 0x%08x\r\n",iErr));
}
SVSUTIL_ASSERT(gpPORTEMU->IsLocked());
if (iErr != ERROR_SUCCESS)
rfcommsdp_disconnect (pCallContext, iErr);
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int rfcommsdp_service_attribute_search_out(void *pCallContext, unsigned long status, unsigned char *pOutBuf, unsigned long cOutBuf) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"+rfcommsdp_service_attribute_search_out\n"));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] rfcommsdp_service_attribute_search_out 0x%08x : not initialized!\n", pCallContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] rfcommsdp_service_attribute_search_out 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return 0;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] rfcommsdp_service_attribute_search_out 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
SVSUTIL_ASSERT (pContext->channel == 0);
SVSUTIL_ASSERT (pContext->sdpCid != 0);
if ((status == ERROR_SUCCESS) && ((! pOutBuf) || (cOutBuf == 0)))
status = ERROR_INVALID_DATA;
unsigned long ch = 0;
if (status == ERROR_SUCCESS)
status = GetProtocolCidFromResponse (pOutBuf, cOutBuf, &RFCOMM_PROTOCOL_UUID, &ch);
if (status == ERROR_SUCCESS)
pContext->channel = ch;
IFDBG(DebugOut(DEBUG_RFCOMM_TRACE,L"rfcommsdp_service_attribute_search_out returns %d channel=%d\r\n", status, pContext->channel));
if (pOutBuf)
g_funcFree(pOutBuf,g_pvAllocData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -