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

📄 wshirda.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -