📄 l2capdev.cxx
字号:
}
int L2CAPCloseCID (unsigned short usCID) {
if (! gpState)
return ERROR_SERVICE_NOT_ACTIVE;
gpState->Lock ();
if (! gpState->fIsRunning) {
gpState->Unlock ();
return ERROR_SERVICE_NOT_ACTIVE;
}
Link *pLink = FindLink (usCID);
if (! pLink) {
gpState->Unlock ();
return ERROR_NOT_FOUND;
}
unsigned short cid = pLink->cid;
DeleteLink (pLink);
HANDLE hL2CAP = gpState->hL2CAP;
L2CA_Disconnect_In pCallback = gpState->l2cap_if.l2ca_Disconnect_In;
gpState->Unlock ();
__try {
pCallback (hL2CAP, NULL, cid);
} __except (1) {
}
return ERROR_SUCCESS;
}
int L2CAPRead
(
unsigned short usCID,
unsigned int cBuffer,
unsigned int *pRequired,
unsigned char *pBuffer
) {
if (! gpState)
return ERROR_SERVICE_NOT_ACTIVE;
gpState->Lock ();
if (! gpState->fIsRunning) {
gpState->Unlock ();
return ERROR_SERVICE_NOT_ACTIVE;
}
Link *pLink = FindLink (usCID);
if (! pLink) {
gpState->Unlock ();
return ERROR_NOT_FOUND;
}
if (pLink->fStage & LINK_ERROR) {
gpState->Unlock ();
return ERROR_CONNECTION_UNAVAIL;
}
SCall *pCall = gpState->pCalls;
while (pCall && ((pCall->pLink != pLink) || (pCall->fWhat != CALL_L2CAP_DATA_READ) || (! pCall->fAutoClean)))
pCall = pCall->pNext;
for (int i = 0 ; ; ++i) {
if (pCall) {
SVSUTIL_ASSERT (pCall->fComplete);
int iRes = pCall->iResult;
if (iRes == ERROR_SUCCESS) {
SVSUTIL_ASSERT (pCall->pBuffer);
unsigned int cSize = BufferTotal (pCall->pBuffer);
*pRequired = cSize;
if (cSize <= cBuffer) {
BufferGetChunk (pCall->pBuffer, cSize, pBuffer);
DeleteCall (pCall);
}
}
gpState->Unlock ();
return iRes;
}
if (i == 1) {
gpState->Unlock ();
return ERROR_CANCELLED;
}
if (pLink->fStage != UP) {
gpState->Unlock ();
return ERROR_CONNECTION_UNAVAIL;
}
pCall = AllocCall (CALL_L2CAP_DATA_READ, pLink, GetOwnerProcess ());
if (! pCall) {
gpState->Unlock ();
return ERROR_OUTOFMEMORY;
}
HANDLE hEvent = pCall->hEvent;
gpState->Unlock ();
WaitForSingleObject (hEvent, INFINITE);
if (! gpState)
return ERROR_CANCELLED;
gpState->Lock ();
if (! gpState->fIsRunning) {
gpState->Unlock ();
return ERROR_CANCELLED;
}
pCall = VerifyCall (pCall);
}
}
int L2CAPWrite
(
unsigned short usCID,
unsigned int cBuffer,
unsigned char *pBuffer
) {
if (! gpState)
return ERROR_SERVICE_NOT_ACTIVE;
gpState->Lock ();
if (! gpState->fIsRunning) {
gpState->Unlock ();
return ERROR_SERVICE_NOT_ACTIVE;
}
Link *pLink = FindLink (usCID);
if ((! pLink) || (pLink->fStage != UP)) {
gpState->Unlock ();
return ERROR_NOT_FOUND;
}
BD_BUFFER *pB = L2CAP_BufferAlloc (cBuffer + gpState->cHeaders + gpState->cTrailers);
pB->cStart = gpState->cHeaders;
pB->cEnd = pB->cSize - gpState->cTrailers;
memcpy (pB->pBuffer + pB->cStart, pBuffer, cBuffer);
SCall *pCall = AllocCall (CALL_L2CAP_DATA_WRITE, pLink, GetOwnerProcess ());
if (! pCall) {
gpState->Unlock ();
return ERROR_OUTOFMEMORY;
}
HANDLE hEvent = pCall->hEvent;
HANDLE hL2CAP = gpState->hL2CAP;
L2CA_DataDown_In pCallback = gpState->l2cap_if.l2ca_DataDown_In;
gpState->Unlock ();
int iRes = ERROR_INTERNAL_ERROR;
__try {
iRes = pCallback (hL2CAP, pCall, usCID, pB);
} __except (1) {
}
if (iRes == ERROR_SUCCESS)
WaitForSingleObject (hEvent, INFINITE);
if (! gpState)
return ERROR_SERVICE_NOT_ACTIVE;
gpState->Lock ();
SVSUTIL_ASSERT ((iRes != ERROR_SUCCESS) || pCall->fComplete);
if (iRes == ERROR_SUCCESS)
iRes = pCall->iResult;
else
L2CAP_BufferFree (pB);
DeleteCall (pCall);
gpState->Unlock ();
return iRes;
}
int L2CAPPing
(
BT_ADDR *pbt,
unsigned int cBufferIn,
unsigned char *pBufferIn,
unsigned int *pcBufferOut,
unsigned char *pBufferOut
) {
BD_ADDR ba = *(BD_ADDR *)pbt;
unsigned int cBuffer = *pcBufferOut;
*pcBufferOut = 0;
if (! gpState)
return ERROR_SERVICE_NOT_ACTIVE;
gpState->Lock ();
if (! gpState->fIsRunning) {
gpState->Unlock ();
return ERROR_SERVICE_NOT_ACTIVE;
}
SCall *pCall = AllocCall (CALL_L2CAP_PING, NULL, GetOwnerProcess ());
if (! pCall) {
gpState->Unlock ();
return ERROR_OUTOFMEMORY;
}
HANDLE hEvent = pCall->hEvent;
HANDLE hL2CAP = gpState->hL2CAP;
L2CA_Ping_In pCallback = gpState->l2cap_if.l2ca_Ping_In;
gpState->Unlock ();
int iRes = ERROR_INTERNAL_ERROR;
__try {
iRes = pCallback (hL2CAP, pCall, &ba, pBufferIn, cBufferIn);
} __except (1) {
}
if (iRes == ERROR_SUCCESS)
WaitForSingleObject (hEvent, INFINITE);
if (! gpState)
return ERROR_SERVICE_NOT_ACTIVE;
gpState->Lock ();
SVSUTIL_ASSERT ((iRes != ERROR_SUCCESS) || pCall->fComplete);
if (iRes == ERROR_SUCCESS) {
iRes = pCall->iResult;
if ((iRes == ERROR_SUCCESS) && (pCall->pBuffer)) {
unsigned int cSize = BufferTotal (pCall->pBuffer);
*pcBufferOut = cSize;
if (cSize <= cBuffer)
BufferGetChunk (pCall->pBuffer, cSize, pBufferOut);
}
}
DeleteCall (pCall);
gpState->Unlock ();
return iRes;
}
#if defined (UNDER_CE)
//
// Driver service funcs...
//
extern "C" BOOL WINAPI DllMain( HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved) {
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls ((HMODULE)hInstDll);
svsutil_Initialize ();
break;
case DLL_PROCESS_DETACH:
svsutil_DeInitialize ();
break;
}
return TRUE;
}
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// EXECUTION THREAD: Client-application!
// These functions are only executed on the caller's thread
// i.e. the thread belongs to the client application
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// @func PVOID | L2C_Init | Device initialization routine
// @parm DWORD | dwInfo | Info passed to RegisterDevice
// @rdesc Returns a DWORD which will be passed to Open & Deinit or NULL if
// unable to initialize the device.
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" DWORD L2C_Init (DWORD Index) {
DebugInit();
return (DWORD)(l2capdev_CreateDriverInstance () == ERROR_SUCCESS);
}
// @func PVOID | L2C_Deinit | Device deinitialization routine
// @parm DWORD | dwData | value returned from L2C_Init call
// @rdesc Returns TRUE for success, FALSE for failure.
// @remark Routine exported by a device driver. "PRF" is the string
// passed in as lpszType in RegisterDevice
extern "C" BOOL L2C_Deinit(DWORD dwData) {
l2capdev_CloseDriverInstance ();
DebugDeInit();
return TRUE;
}
// @func PVOID | L2C_Open | Device open routine
// @parm DWORD | dwData | value returned from L2C_Init call
// @parm DWORD | dwAccess | requested access (combination of GENERIC_READ
// and GENERIC_WRITE)
// @parm DWORD | dwShareMode | requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE)
// @rdesc Returns a DWORD which will be passed to Read, Write, etc or NULL if
// unable to open device.
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" DWORD L2C_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
HANDLE *ph = (HANDLE *)g_funcAlloc (sizeof(HANDLE), g_pvAllocData);
ph[0] = NULL;
return (DWORD)ph;
}
// @func BOOL | L2C_Close | Device close routine
// @parm DWORD | dwOpenData | value returned from L2C_Open call
// @rdesc Returns TRUE for success, FALSE for failure
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" BOOL L2C_Close (DWORD dwData) {
HANDLE *ph = (HANDLE *)dwData;
if (ph && ph[0])
ProcessExited (ph[0]);
if (ph)
g_funcFree (ph, g_pvFreeData);
return TRUE;
}
// @func DWORD | L2C_Write | Device write routine
// @parm DWORD | dwOpenData | value returned from L2C_Open call
// @parm LPCVOID | pBuf | buffer containing data
// @parm DWORD | len | maximum length to write [IN BYTES, NOT WORDS!!!]
// @rdesc Returns -1 for error, otherwise the number of bytes written. The
// length returned is guaranteed to be the length requested unless an
// error condition occurs.
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
//
extern "C" DWORD L2C_Write (DWORD dwData, LPCVOID pInBuf, DWORD dwInLen) {
return -1;
}
// @func DWORD | L2C_Read | Device read routine
// @parm DWORD | dwOpenData | value returned from L2C_Open call
// @parm LPVOID | pBuf | buffer to receive data
// @parm DWORD | len | maximum length to read [IN BYTES, not WORDS!!]
// @rdesc Returns 0 for end of file, -1 for error, otherwise the number of
// bytes read. The length returned is guaranteed to be the length
// requested unless end of file or an error condition occurs.
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
//
extern "C" DWORD L2C_Read (DWORD dwData, LPVOID pBuf, DWORD Len) {
return -1;
}
// @func DWORD | L2C_Seek | Device seek routine
// @parm DWORD | dwOpenData | value returned from L2C_Open call
// @parm long | pos | position to seek to (relative to type)
// @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END
// @rdesc Returns current position relative to start of file, or -1 on error
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" DWORD L2C_Seek (DWORD dwData, long pos, DWORD type) {
return (DWORD)-1;
}
// @func void | L2C_PowerUp | Device powerup routine
// @comm Called to restore device from suspend mode. You cannot call any
// routines aside from those in your dll in this call.
extern "C" void L2C_PowerUp (void) {
return;
}
// @func void | L2C_PowerDown | Device powerdown routine
// @comm Called to suspend device. You cannot call any routines aside from
// those in your dll in this call.
extern "C" void L2C_PowerDown (void) {
return;
}
// @func BOOL | L2C_IOControl | Device IO control routine
// @parm DWORD | dwOpenData | value returned from L2C_Open call
// @parm DWORD | dwCode | io control code to be performed
// @parm PBYTE | pBufIn | input data to the device
// @parm DWORD | dwLenIn | number of bytes being passed in
// @parm PBYTE | pBufOut | output data from the device
// @parm DWORD | dwLenOut |maximum number of bytes to receive from device
// @parm PDWORD | pdwActualOut | actual number of bytes received from device
// @rdesc Returns TRUE for success, FALSE for failure
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" BOOL L2C_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
#if ! defined (SDK_BUILD)
if (dwCode == IOCTL_PSL_NOTIFY) {
PDEVICE_PSL_NOTIFY pPslPacket = (PDEVICE_PSL_NOTIFY)pBufIn;
if ((pPslPacket->dwSize == sizeof(DEVICE_PSL_NOTIFY)) && (pPslPacket->dwFlags == DLL_PROCESS_EXITING)){
SVSUTIL_ASSERT (*(HANDLE *)dwData == pPslPacket->hProc);
ProcessExited ((HANDLE)pPslPacket->hProc);
}
return TRUE;
}
#endif
HANDLE *ph = (HANDLE *)dwData;
SVSUTIL_ASSERT (ph);
if (! ph[0])
ph[0] = GetCallerProcess ();
SVSUTIL_ASSERT (ph[0] == GetCallerProcess());
int iError = ERROR_SUCCESS;
L2CAPDEVAPICALL *pbapi = (L2CAPDEVAPICALL *)pBufIn;
if (dwLenIn != sizeof(L2CAPDEVAPICALL)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch (dwCode) {
case L2CAPDEV_IOCTL_L2CAPConnect:
iError = L2CAPConnect (&pbapi->L2CAPConnect_p.ba,
pbapi->L2CAPConnect_p.usPSM,
pbapi->L2CAPConnect_p.usInMTU,
&pbapi->L2CAPConnect_p.usCID,
&pbapi->L2CAPConnect_p.usOutMTU);
break;
case L2CAPDEV_IOCTL_L2CAPListen:
iError = L2CAPListen (pbapi->L2CAPListen_p.usPSM, pbapi->L2CAPListen_p.usInMTU);
break;
case L2CAPDEV_IOCTL_L2CAPAccept:
iError = L2CAPAccept (pbapi->L2CAPAccept_p.usPSM,
&pbapi->L2CAPAccept_p.ba,
&pbapi->L2CAPAccept_p.usCID,
&pbapi->L2CAPAccept_p.usOutMTU);
break;
case L2CAPDEV_IOCTL_L2CAPWrite:
iError = L2CAPWrite (pbapi->L2CAPReadWrite_p.usCID,
pbapi->L2CAPReadWrite_p.cBuffer,
(unsigned char *)MapCallerPtr (pbapi->L2CAPReadWrite_p.pBuffer, pbapi->L2CAPReadWrite_p.cBuffer));
break;
case L2CAPDEV_IOCTL_L2CAPRead:
iError = L2CAPRead (pbapi->L2CAPReadWrite_p.usCID,
pbapi->L2CAPReadWrite_p.cBuffer,
&pbapi->L2CAPReadWrite_p.cRequired,
(unsigned char *)MapCallerPtr (pbapi->L2CAPReadWrite_p.pBuffer, pbapi->L2CAPReadWrite_p.cBuffer));
break;
case L2CAPDEV_IOCTL_L2CAPCloseCID:
iError = L2CAPCloseCID (pbapi->L2CAPClose_p.us);
break;
case L2CAPDEV_IOCTL_L2CAPClosePSM:
iError = L2CAPClosePSM (pbapi->L2CAPClose_p.us);
break;
case L2CAPDEV_IOCTL_L2CAPPing:
iError = L2CAPPing (&pbapi->L2CAPPing_p.ba, pbapi->L2CAPPing_p.cBufferIn,
(unsigned char *)MapCallerPtr (pbapi->L2CAPPing_p.pBufferIn, pbapi->L2CAPPing_p.cBufferIn),
&pbapi->L2CAPPing_p.cBufferOut,
(unsigned char *)MapCallerPtr (pbapi->L2CAPPing_p.pBufferOut, pbapi->L2CAPPing_p.cBufferOut));
break;
default:
IFDBG(DebugOut (DEBUG_WARN, L"Unknown control code %d\n", dwCode));
iError = ERROR_CALL_NOT_IMPLEMENTED;
}
if (iError != ERROR_SUCCESS) {
SetLastError(iError);
return FALSE;
}
return TRUE;
}
#if defined(UNDER_CE) && CE_MAJOR_VER < 0x0003
extern "C" int _isctype(int c, int mask) {
if ((c < 0) || (c > 0xff))
return 0;
return iswctype((wchar_t)c,(wctype_t)mask);
}
#endif //defined(UNDER_CE) && CE_MAJOR_VER < 0x0003
#endif // UNDER_CE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -