📄 wshirda.c
字号:
Level,
OptionName,
pOptionValue,
OptionLen));
DUMP_WSHOBJECTS(ZONE_WSHIRDA);
if (Level == SOL_INTERNAL && OptionName == SO_CONTEXT)
{
PIRLMP_SOCKET_CONTEXT pSocketContext = pHelperDllSocketContext;
if (OptionLen < (int)sizeof(IRLMP_SOCKET_CONTEXT))
return(WSAEINVAL);
if (pHelperDllSocketContext == NULL)
{
// Socket was inherited or duped, create a new context.
pSocketContext = IrdaAlloc(sizeof(IRLMP_SOCKET_CONTEXT),
MT_WSH_SOCKET_CTXT);
if (pSocketContext == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("IRLMP_SetSocketInformation() CTEAllocMem() failed\r\n")));
return(WSAENOBUFS);
}
// Copy the parent's context into the child's context.
memcpy(pSocketContext, pOptionValue, sizeof(IRLMP_SOCKET_CONTEXT));
pSocketContext->pIasAttribs = NULL;
// Return the address of the new context in pOptionVal.
*(PIRLMP_SOCKET_CONTEXT *) pOptionValue = pSocketContext;
EnterCriticalSection(&g_csWshIrda);
InsertHeadList(&g_SocketList, &pSocketContext->Linkage);
LeaveCriticalSection(&g_csWshIrda);
}
else
{
// The socket was accept()'ed and it needs to have the same
// properties as it's parent. The OptionValue buffer
// contains the context information of this socket's parent.
//memcpy(pSocketContext, pOptionValue,
// sizeof(IRLMP_SOCKET_CONTEXT));
// sh - don't memcpy - there is a link list entry in there!
// Also, we don't copy the attributes.
pSocketContext->UseExclusiveMode = ((PIRLMP_SOCKET_CONTEXT)pOptionValue)->UseExclusiveMode;
pSocketContext->UseIrLPTMode = ((PIRLMP_SOCKET_CONTEXT)pOptionValue)->UseIrLPTMode;
pSocketContext->Use9WireMode = ((PIRLMP_SOCKET_CONTEXT)pOptionValue)->Use9WireMode;
pSocketContext->UseSharpMode = ((PIRLMP_SOCKET_CONTEXT)pOptionValue)->UseSharpMode;
}
DUMP_WSHOBJECTS(ZONE_WSHIRDA);
return(NO_ERROR);
}
if (Level == SOL_IRLMP && OptionName == IRLMP_EXCLUSIVE_MODE)
{
if (OptionLen < (int)sizeof(int))
return(WSAEINVAL);
pContext->UseExclusiveMode = *(int *) pOptionValue;
return(NO_ERROR);
}
if (Level == SOL_IRLMP && OptionName == IRLMP_IRLPT_MODE)
{
if (OptionLen < (int)sizeof(int))
return(WSAEINVAL);
pContext->UseIrLPTMode = *(int *) pOptionValue;
return(NO_ERROR);
}
if (Level == SOL_IRLMP && OptionName == IRLMP_9WIRE_MODE)
{
if (OptionLen < (int)sizeof(int))
return(WSAEINVAL);
pContext->Use9WireMode = *(int *) pOptionValue;
return(NO_ERROR);
}
if (Level == SOL_IRLMP && OptionName == IRLMP_SHARP_MODE)
{
if (OptionLen < (int)sizeof(int))
return(WSAEINVAL);
pContext->UseSharpMode = *(int *) pOptionValue;
return(NO_ERROR);
}
/* wmz clear the IAS sometime maybe */
if (Level == SOL_IRLMP && OptionName == IRLMP_IAS_SET)
{
PVOID AttribHandle;
PWSHIRDA_IAS_ATTRIB pIasAttrib;
if (OptionLen < (int)(sizeof(IAS_SET) - 4))
return(WSAEFAULT);
if (pIASSet->irdaClassName[0] == 0)
{
return (WSAEINVAL);
}
pIASSet->irdaClassName[60] = 0;
pIASSet->irdaAttribName[60] = 0;
switch(pIASSet->irdaAttribType)
{
case IAS_ATTRIB_INT:
break;
case IAS_ATTRIB_OCTETSEQ:
if (OptionLen -
offsetof(IAS_SET, irdaAttribute.irdaAttribOctetSeq.OctetSeq) <
(unsigned) pIASSet->irdaAttribute.irdaAttribOctetSeq.Len)
{
return(WSAEFAULT);
}
if (pIASSet->irdaAttribute.irdaAttribOctetSeq.Len > 1024 ||
pIASSet->irdaAttribute.irdaAttribOctetSeq.Len < 0)
{
return (WSAEINVAL);
}
break;
case IAS_ATTRIB_STR:
if (OptionLen -
offsetof(IAS_SET, irdaAttribute.irdaAttribUsrStr.UsrStr) <
(unsigned) pIASSet->irdaAttribute.irdaAttribUsrStr.Len)
{
return(WSAEFAULT);
}
if (pIASSet->irdaAttribute.irdaAttribUsrStr.Len > 255 ||
pIASSet->irdaAttribute.irdaAttribUsrStr.Len < 0)
{
return (WSAEINVAL);
}
pIASSet->irdaAttribute.irdaAttribUsrStr.UsrStr[
pIASSet->irdaAttribute.irdaAttribUsrStr.Len] = 0;
break;
default:
return(WSAEFAULT);
break;
}
pIasAttrib = IrdaAlloc(sizeof(WSHIRDA_IAS_ATTRIB), 0);
if (pIasAttrib == NULL)
{
return (WSAENOBUFS);
}
IrDAMsg.Prim = IRLMP_ADDATTRIBUTE_REQ;
IrDAMsg.IRDA_MSG_pIasSet = pIASSet;
IrDAMsg.IRDA_MSG_pAttribHandle = &AttribHandle;
rc = IrlmpDown(NULL, &IrDAMsg);
if (rc == IRLMP_IAS_ATTRIB_ALREADY_EXISTS ||
rc == IRLMP_IAS_MAX_ATTRIBS_REACHED)
{
IrdaFree(pIasAttrib);
return (WSAEINVAL);
}
else if (rc != SUCCESS)
{
IrdaFree(pIasAttrib);
return (WSAENOBUFS);
}
ASSERT(AttribHandle != NULL);
pIasAttrib->AttributeHandle = AttribHandle;
EnterCriticalSection(&g_csWshIrda);
DEBUGMSG(ZONE_WSHIRDA, (TEXT("Added attrib %x to socket %x\r\n"),
AttribHandle, pContext));
pIasAttrib->pNext = pContext->pIasAttribs;
pContext->pIasAttribs = pIasAttrib;
LeaveCriticalSection(&g_csWshIrda);
return(NO_ERROR);
}
return(WSAENOPROTOOPT);
}
/*****************************************************************************
*
* @func INT | IRLMP_Notify |
* Called after the socket event(s) specified in IRLMP_OpenSocket()
* occur.
*
* @rdesc
* NO_ERROR (winerror.h) on success, or (winsock.h)
* @errors
* @ecode WSAEINVAL | Invalid NotifyEvent.
*
* @parm PVOID | pHelperDllSocketContext |
* Pointer to the IRLMP_SOCKET_CONTEXT returned by IRLMP_OpenSocket().
* @parm SOCKET | SocketHandle | Socket handle.
* @parm HANDLE | TdiAddressObjectHandle |
* TDI Address Object handle if the socket is bound, otherwise NULL.
* @parm HANDLE | TdiConnectionObjectHandle |
* TDI Connection Object handle if socket is connected,
* otherwise NULL.
* @parm DWORD | NotifyEvent |
* (tdice.h) One of
* <nl> WSH_NOTIFY_BIND
* <nl> WSH_NOTIFY_LISTEN
* <nl> WSH_NOTIFY_CONNECT
* <nl> WSH_NOTIFY_ACCEPT
* <nl> WSH_NOTIFY_SHUTDOWN_RECEIVE
* <nl> WSH_NOTIFY_SHUTDOWN_SEND
* <nl> WSH_NOTIFY_SHUTDOWN_ALL
* <nl> WSH_NOTIFY_CLOSE
* <nl> WSH_NOTIFY_CONNECT_ERROR
*
* @xref <f IRLMP_OpenSocket>
*/
INT
IRLMP_Notify(IN PVOID pHelperDllSocketContext,
IN SOCKET SocketHandle,
IN HANDLE TdiAddressObjectHandle,
IN HANDLE TdiConnectionObjectHandle,
IN DWORD NotifyEvent)
{
PIRLMP_SOCKET_CONTEXT pContext =
(PIRLMP_SOCKET_CONTEXT) pHelperDllSocketContext;
IRDA_MSG IrDAMsg;
int rc;
IAS_SET IASSet;
int i;
DEBUGMSG(ZONE_FUNCTION || ZONE_WSHIRDA,
(TEXT("IRLMP_Notify(0x%X,0x%X,0x%X,0x%X,%s - 0x%x)\r\n"),
pHelperDllSocketContext,
(unsigned) SocketHandle,
(unsigned) TdiAddressObjectHandle,
(unsigned) TdiConnectionObjectHandle,
NotifyEvent == WSH_NOTIFY_BIND ? TEXT("WSH_NOTIFY_BIND") :
NotifyEvent == WSH_NOTIFY_LISTEN ? TEXT("WSH_NOTIFY_LISTEN") :
NotifyEvent == WSH_NOTIFY_CLOSE ? TEXT("WSH_NOTIFY_CLOSE") :
TEXT("unexpected WSH_NOTIFY"),
NotifyEvent));
DUMP_WSHOBJECTS(ZONE_WSHIRDA);
if (NotifyEvent == WSH_NOTIFY_BIND)
{
PIRLMP_ADDR_OBJ pAddrObj;
pAddrObj = GETADDR(TdiAddressObjectHandle);
if (pAddrObj == NULL)
{
return (WSAEFAULT);
}
pAddrObj->UseExclusiveMode = pContext->UseExclusiveMode;
pAddrObj->UseIrLPTMode = pContext->UseIrLPTMode;
pAddrObj->Use9WireMode = pContext->Use9WireMode;
pAddrObj->UseSharpMode = pContext->UseSharpMode;
REFDELADDR(pAddrObj);
}
if (NotifyEvent == WSH_NOTIFY_LISTEN)
{
PIRLMP_ADDR_OBJ pAddrObj;
pAddrObj = GETADDR(TdiAddressObjectHandle);
if (pAddrObj == NULL)
{
return (WSAEFAULT);
}
pAddrObj->IsServer = TRUE;
IrDAMsg.Prim = IRLMP_REGISTERLSAP_REQ;
IrDAMsg.IRDA_MSG_LocalLsapSel = pAddrObj->LSAPSelLocal;
if (pAddrObj->UseIrLPTMode || pAddrObj->UseExclusiveMode)
IrDAMsg.IRDA_MSG_UseTtp = FALSE;
else
IrDAMsg.IRDA_MSG_UseTtp = TRUE;
rc = IrlmpDown(NULL, &IrDAMsg);
ASSERT(rc == 0);
i = 0;
// irdaServiceName is 25 chars, but will truncate with 24 + 1 NULL.
while (pAddrObj->SockAddrLocal.irdaServiceName[i] && i < 25)
{
IASSet.irdaClassName[i] =
pAddrObj->SockAddrLocal.irdaServiceName[i];
i++;
}
IASSet.irdaClassName[i] = 0;
i = 0;
while (IasAttribName_TTPLsapSel[i])
{
IASSet.irdaAttribName[i] = IasAttribName_TTPLsapSel[i];
i++;
}
IASSet.irdaAttribName[i] = 0;
IASSet.irdaAttribType = IAS_ATTRIB_INT;
IASSet.irdaAttribute.irdaAttribInt = pAddrObj->LSAPSelLocal;
IrDAMsg.Prim = IRLMP_ADDATTRIBUTE_REQ;
IrDAMsg.IRDA_MSG_pIasSet = &IASSet;
IrDAMsg.IRDA_MSG_pAttribHandle = &pAddrObj->IasAttribHandle;
rc = IrlmpDown(NULL, &IrDAMsg);
ASSERT(rc == 0);
REFDELADDR(pAddrObj);
}
if (NotifyEvent == WSH_NOTIFY_CLOSE)
{
PIRLMP_SOCKET_CONTEXT pSocket = (PIRLMP_SOCKET_CONTEXT)pHelperDllSocketContext;
EnterCriticalSection(&g_csWshIrda);
DeleteSocketAttribs(pSocket);
RemoveEntryList(&pSocket->Linkage);
LeaveCriticalSection(&g_csWshIrda);
IrdaFree(pSocket);
EnterCriticalSection(&g_csWshIrda);
OpenSocketCnt--;
DEBUGMSG(ZONE_SOCKETCNT, (TEXT("IrDA: Open sockets = %d -> %d.\r\n"),
OpenSocketCnt + 1, OpenSocketCnt));
ASSERT((int)OpenSocketCnt >= 0);
if (OpenSocketCnt == 0) {
if (g_IrdaLinkState == IRDALINKSTATE_OPENED) {
g_IrdaLinkState = IRDALINKSTATE_CLOSING;
ResetEvent(g_hEvWaitToRelLink);
if (CTEScheduleEvent(&g_evReleaseLink, NULL) == 0)
{
ASSERT(FALSE);
LeaveCriticalSection(&g_csWshIrda);
// Fail to release link resources.
return (WSAEBADF);
}
}
}
LeaveCriticalSection(&g_csWshIrda);
}
return(NO_ERROR);
}
/*****************************************************************************
*
* @func DWORD | IRLMP_GetWinsockMapping |
* Called at stack load time. Returns a WINSOCK_MAPPING (tdice.h)
* struct containing the AddressFamily, SocketType and Protocol
* triple socket() parms supported by this stack.
*
* @rdesc
* Required WINSOCK_MAPPING struct size. The function is called again
* with a larger buffer if needed.
*
* @parm PWINSOCK_MAPPING | pMapping |
* Pointer to output WINSOCK_MAPPING struct. IrLMP will copy
* IRLMP_Mapping to this address.
* @parm DWORD | MappingLength |
* sizeof() output WINSOCK_MAPPING structure. If this value is too
* small, GetWinsockMapping() will return the required buffer size.
*/
DWORD
IRLMP_GetWinsockMapping(OUT PWINSOCK_MAPPING pMapping,
IN DWORD MappingLength)
{
DEBUGMSG(ZONE_FUNCTION,
(TEXT("IRLMP_GetWinsockMapping(0x%X,0x%X)\r\n"),
pMapping, MappingLength));
if (MappingLength >= sizeof(IRLMP_Mapping))
memcpy(pMapping, &IRLMP_Mapping, sizeof(WINSOCK_MAPPING));
return(sizeof(WINSOCK_MAPPING));
}
/*****************************************************************************
*
* @func INT | IRLMP_EnumProtocols | Called at stack load time.
*/
INT
IRLMP_EnumProtocols(IN LPINT lpiProtocols,
IN LPTSTR lpTransportKeyName,
IN OUT LPVOID lpProtocolBuffer,
IN OUT LPDWORD lpdwBufferLength)
{
int i;
BOOL useIR = FALSE;
PPROTOCOL_INFO pProtocolInfo;
DWORD bytesRequired;
DEBUGMSG(ZONE_FUNCTION,
(TEXT("IRLMP_EnumProtocols(0x%X,0x%X,0x%X,0x%X)\r\n"),
lpiProtocols,
lpTransportKeyName,
lpProtocolBuffer,
lpdwBufferLength));
// Should we check for correct procotol in lpiProtocols????
if (lpiProtocols != NULL)
{
for (i = 0; lpiProtocols[i] != 0; i++)
{
if (lpiProtocols[i] == AF_IRDA)
{
useIR = TRUE;
}
}
}
else
{
// If no proto's specified then Set true.
useIR = TRUE;
}
// Did they specify a valid protocol?
if (!useIR)
{
*lpdwBufferLength = 0;
return 0;
}
// This only supports UNICODE.....
bytesRequired = sizeof(PROTOCOL_INFO) +
(wcslen (IRLMP_TRANSPORT_NAME) + 1) *sizeof(WCHAR);
// Did they give us enough room?
if (bytesRequired > *lpdwBufferLength)
{
*lpdwBufferLength = bytesRequired;
return -1;
}
pProtocolInfo = lpProtocolBuffer;
pProtocolInfo->dwServiceFlags =
XP_GUARANTEED_DELIVERY |
XP_GUARANTEED_ORDER;
pProtocolInfo->iAddressFamily = AF_IRDA;
pProtocolInfo->iMaxSockAddr = sizeof(SOCKADDR_IRDA);
pProtocolInfo->iMinSockAddr = sizeof(SOCKADDR_IRDA);
pProtocolInfo->iSocketType = SOCK_STREAM;
pProtocolInfo->iProtocol = AF_IRDA;
pProtocolInfo->dwMessageSize = 0; //?? what does this mean?
// Use the end of the passed in buffer to store the name
pProtocolInfo->lpProtocol =
(LPWSTR) ((LPBYTE)pProtocolInfo + sizeof(PROTOCOL_INFO));
// Copy the name
wcscpy (pProtocolInfo->lpProtocol, IRLMP_TRANSPORT_NAME);
// Set return buffer length
*lpdwBufferLength = bytesRequired;
// Indicate one protocol info structure returned.
return 1;
}
/*****************************************************************************
*
* @func INT | IRLMP_OpenSocket |
* Called after socket(). Validates socket() parms and allocates a
* new IRLMP_SOCKET_CONTEXT.
*
* @rdesc
* NO_ERROR (winerror.h) on success, or (winsock.h)
* @errors
* @ecode WSAEINVAL | Invalid socket() parameters.
* @ecode WSAENOBUFS | No memory to allocate socket context.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -