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

📄 wshirda.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
*
*   @parm   PINT    |   pAddressFamily              |   
*           From socket(AF_IRDA, , ). IrLMP will return this value unchanged.
*   @parm   PINT    |   pSocketType                 | 
*           From socket( , SOCK_SEQPACKET, ). IrLMP will return this value 
*           unchanged.
*   @parm   PINT    |   pProtocol                   | 
*           From socket( , , 0). IrLMP will return this value unchanged.
*   @parm   PWSTR   |   pTransportDeviceName        |
*           IrLMP will copy IRLMP_TRANSPORT_NAME to this address.
*   @parm   PVOID * |   ppHelperDllSocketContext    |
*           Returns the address of a new IRLMP_SOCKET_CONTEXT. This context
*           will be returned by IRLMP_Notify(), IRLMP_OpenConnection(), 
*           IRLMP_GetWildcardSockaddr(), and IRLMP_SetSocketInformation(),
*           and IRLMP_GetSocketInformation(). 
*   @parm   PDWORD  |   pNotificationEvents         |
*           (tdice.h) Bitmask indicating which Winsock events should result
*           in a call to IRLMP_Notify(). IrLMP will set this value to 0.
*		    <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_Notify>               <f IRLMP_OpenConnection>
*           <f IRLMP_GetWildcardSockaddr>  <f IRLMP_SetSocketInformation>
*/

INT
IRLMP_OpenSocket(IN  OUT PINT    pAddressFamily,
                 IN  OUT PINT    pSocketType,
                 IN  OUT PINT    pProtocol,
                 OUT     PWSTR   pTransportDeviceName,
                 OUT     PVOID * ppHelperDllSocketContext,
                 OUT     PDWORD  pNotificationEvents)
{
    PIRLMP_SOCKET_CONTEXT pSocket;
    UINT rc;

    DEBUGMSG(ZONE_FUNCTION,
        (TEXT("IRLMP_OpenSocket(0x%X,0x%X,0x%X,0x%X,0x%X,0x%X)\r\n"),
        pAddressFamily, 
        pSocketType, 
        pProtocol, 
        pTransportDeviceName,
        ppHelperDllSocketContext, 
        pNotificationEvents));

    DUMP_WSHOBJECTS(ZONE_WSHIRDA);

    if (*pAddressFamily != (int) IRLMP_Mapping.Mapping[0].AddressFamily)
        return(WSAEINVAL);

    if (*pSocketType    != (int) IRLMP_Mapping.Mapping[0].SocketType)
        return(WSAEINVAL);

    if (*pProtocol      != (int) IRLMP_Mapping.Mapping[0].Protocol)
        return(WSAEINVAL);

	wcscpy(pTransportDeviceName, IRLMP_TRANSPORT_NAME);

    pSocket = IrdaAlloc(sizeof(IRLMP_SOCKET_CONTEXT), MT_WSH_SOCKET_CTXT);

    if (pSocket == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("IRLMP_OpenSocket() CTEAllocMem() failed\r\n")));

        return(WSAENOBUFS);
    }

    EnterCriticalSection(&g_csWshIrda);

    while (g_IrdaLinkState == IRDALINKSTATE_CLOSING)
    {
        LeaveCriticalSection(&g_csWshIrda);

        DEBUGMSG(ZONE_WARN, (TEXT("IRLMP_OpenSocket(0x%x): Wait for IrDA to release link before open...\r\n"), pSocket));
        // If we are in the midst of releasing the link, wait until done - then
        // we will need to reacquire the link.
        rc = WaitForSingleObject(g_hEvWaitToRelLink, IRLMP_OPENSOCKET_MAX_WAIT);
        if (rc != WAIT_OBJECT_0) {
            //
            // Either IRDA has been deinit'd or the process this thread belongs to has been terminated
            //
            DEBUGMSG(ZONE_ERROR, (TEXT("IRLMP_OpenSocket:WaitForSingleObject returned error %d\r\n"), rc));
            IrdaFree(pSocket);
            return (WSASYSNOTREADY);
        }
        EnterCriticalSection(&g_csWshIrda);        
    }


    *ppHelperDllSocketContext = pSocket;

    OpenSocketCnt++;
    DEBUGMSG(ZONE_SOCKETCNT, (TEXT("IrDA: Open sockets = %d -> %d.\r\n"), 
        OpenSocketCnt - 1, OpenSocketCnt));

    pSocket->UseExclusiveMode = FALSE;
    pSocket->UseIrLPTMode     = FALSE;
    pSocket->Use9WireMode     = FALSE;
    pSocket->UseSharpMode     = FALSE;
    pSocket->pIasAttribs      = NULL;

    InsertHeadList(&g_SocketList, &pSocket->Linkage);
	
    *pNotificationEvents = 
        WSH_NOTIFY_CLOSE    | 
        WSH_NOTIFY_BIND     | 
        WSH_NOTIFY_LISTEN;

    if (g_IrdaLinkState == IRDALINKSTATE_CLOSED)
    {
        IRDA_MSG IMsg;

        g_IrdaLinkState = IRDALINKSTATE_OPENING;

        DEBUGMSG(ZONE_SOCKETCNT, (TEXT("IrDA: Acquire link resources.\r\n")));
        IMsg.Prim = IRLMP_LINKCONTROL_REQ;
        IMsg.IRDA_MSG_AcquireResources = TRUE;
        rc = IrlmpDown(NULL, &IMsg);

        if (rc == SUCCESS)
        {
            g_IrdaLinkState = IRDALINKSTATE_OPENED;
        }
        else if (rc == IRMAC_ALREADY_INIT)
        {
            // This happens if a previous process got terminated in the middle of
            // calling IRLMP_OpenSocket
            DEBUGMSG(ZONE_WARN, (TEXT("IRDASTK:IRLMP_OpenSocket Link already up!\r\n")));
            g_IrdaLinkState = IRDALINKSTATE_OPENED;
            rc = SUCCESS;
        }
        else
        {
            g_IrdaLinkState  = IRDALINKSTATE_CLOSED;
            // Need to dec. socket count since new AFD will not call 
            // Notify CLOSE.
            OpenSocketCnt--;

            DEBUGMSG(ZONE_SOCKETCNT, 
               (TEXT("IrDA: Acquire resource failure - ")
                TEXT("Open sockets = %d -> %d.\r\n"), 
                OpenSocketCnt + 1, OpenSocketCnt));
        }

        if (rc == IRMAC_OPEN_PORT_FAILED)
        {
            DEBUGMSG(ZONE_WARN, (TEXT("IrTdi: Could not open serial port!\r\n")));
            rc = WSAEBADF;
        }
        else if (rc == IRMAC_MALLOC_FAILED)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("IrTdi: WSAENOBUFS!\r\n")));
            rc = WSAENOBUFS;
        }
        else if (rc != SUCCESS)
        {
            ASSERT(FALSE);
            DEBUGMSG(ZONE_ERROR, (TEXT("IrTdi: got unexpected error.\r\n")));
            rc = WSAEBADF;
        }

        if (rc != SUCCESS) {
            RemoveEntryList(&pSocket->Linkage);
            LeaveCriticalSection(&g_csWshIrda);
            IrdaFree(pSocket);
            return (INT) rc;
        }

        LeaveCriticalSection(&g_csWshIrda);
    }
    else
    {
        ASSERT(g_IrdaLinkState == IRDALINKSTATE_OPENED);
        LeaveCriticalSection(&g_csWshIrda);
    }

    return(NO_ERROR);
}

INT
TdiIasQuery(
    PIAS_QUERY pIasQuery,
    DWORD      cbIasQuery
    )
{
    INT        Status = NO_ERROR;
    INT        rc;
    IRDA_MSG   IrDAMsg;
    PIAS_QUERY pLocalIasQuery = NULL;

    EnterCriticalSection(&csIasQuery);

    if (IASQueryInProgress)
    {
        Status = WSAEINPROGRESS;
        goto done;
    }

    pIASQuery = pIasQuery;

    // Need to get around this damn thing for proc permissions.
    pLocalIasQuery = IrdaAlloc(cbIasQuery, 0);

    if (pLocalIasQuery == NULL)
    {
        Status = WSAENOBUFS;
        goto done;
    }
    else 
    {
        memcpy(pLocalIasQuery, pIasQuery, cbIasQuery);
    }

    IrDAMsg.Prim                   = IRLMP_GETVALUEBYCLASS_REQ;
    IrDAMsg.IRDA_MSG_pIasQuery     = pLocalIasQuery;
    IrDAMsg.IRDA_MSG_AttribLen     = 
        cbIasQuery - offsetof(IAS_QUERY, irdaAttribute.irdaAttribUsrStr.UsrStr);

    if (IrDAMsg.IRDA_MSG_AttribLen <= 0)
    {
        Status = WSAEFAULT;
        goto done;
    }
    
    IASQueryInProgress = TRUE;

    LeaveCriticalSection(&csIasQuery);

    rc = IrlmpDown(NULL, &IrDAMsg);

    EnterCriticalSection(&csIasQuery);

    if (rc != 0)
    {
        if (rc == IRLMP_LINK_IN_USE)
        {
            Status = WSAEADDRINUSE;
            IASQueryInProgress = FALSE;
            goto done;
        }
        else if (rc == IRLMP_IN_EXCLUSIVE_MODE)
        {
            Status = WSAEISCONN;
            IASQueryInProgress = FALSE;
            goto done;
        }
        else 
        {
            DEBUGMSG (ZONE_ERROR, (TEXT("!IRLMP_GetSocketInfo: Error from IRLMP_DOWN %d\r\n"), rc));
            Status = WSAEFAULT;
            IASQueryInProgress = FALSE;
            goto done;
        }
    }

    LeaveCriticalSection(&csIasQuery);

    WaitForSingleObject(IASQueryConfEvent, INFINITE);

    EnterCriticalSection(&csIasQuery);

    IASQueryInProgress = FALSE;

    switch(IASQueryStatus)
    {
    case IRLMP_IAS_SUCCESS:
        Status = NO_ERROR;
        break;

    case IRLMP_MAC_MEDIA_BUSY:
        /* wmz retry the query */
        DEBUGMSG (1, (TEXT("TDI:IRLMP_GetSocketinformation, Got IRLMP_MAC_MEDIA_BUSY, returning WSAENETDOWN\r\n")));
        Status = WSAENETDOWN;
        break;

    case IRLMP_IRLAP_REMOTE_DISCOVERY_IN_PROGRESS:
        /* wmz retry the query after DISCOVERY_IND */
        DEBUGMSG (1, (TEXT("GOT IRLMP_IRLAP_REMOTE_DISCOVERY_IN_PROGRESS in TDI:IRLMP_GetSocketinformation\r\n")));
        Status = WSAENETDOWN;
        break;
    
    case IRLMP_DISC_LSAP:
        Status = WSAECONNREFUSED;
        break;

    case IRLMP_NO_RESPONSE_LSAP:
        Status = WSAETIMEDOUT;
        break;

    case IRLMP_IAS_NO_SUCH_OBJECT:
        pLocalIasQuery->irdaAttribType = IAS_ATTRIB_NO_CLASS;
        Status = NO_ERROR;
        break;
    
    case IRLMP_IAS_NO_SUCH_ATTRIB:
        pLocalIasQuery->irdaAttribType = IAS_ATTRIB_NO_ATTRIB;
        Status = NO_ERROR;
        break;
    
    default:
        Status = WSAECONNABORTED;
        break;
    }

done:

    if (pLocalIasQuery != NULL)
    {
        memcpy(pIasQuery, pLocalIasQuery, cbIasQuery);
        IrdaFree(pLocalIasQuery);
    }

    LeaveCriticalSection(&csIasQuery);

    return (Status);
}

#define MAX_ENUM_WAIT_TIME 20000

INT
TdiEnumDevices(
    PDEVICELIST pDeviceList,
    DWORD       cDevices
    )
{
    INT      Status = NO_ERROR;
    INT      rc;
    IRDA_MSG IrDAMsg;

    EnterCriticalSection(&csDscv);

    if (DscvInProgress)
    {
        Status = WSAEINPROGRESS;
        goto done;
    }

    DscvInProgress          = TRUE;
    DscvCallersPermissions  = GetCurrentPermissions();
    pDscvDevList            = pDeviceList;
    DscvNumDevices          = cDevices;
    DscvRepeats             = 0;
    pDscvDevList->numDevice = 0;
        
    if (DscvNumDevices < 1)
    {
        DscvInProgress = FALSE;
        Status = WSAEFAULT;
        goto done;
    }

    IrDAMsg.Prim                = IRLMP_DISCOVERY_REQ;
    IrDAMsg.IRDA_MSG_SenseMedia = TRUE;

    LeaveCriticalSection(&csDscv);

    rc = IrlmpDown(NULL, &IrDAMsg);
    ASSERT(rc == 0);
    
    rc = WaitForSingleObject(DscvConfEvent, MAX_ENUM_WAIT_TIME);

    EnterCriticalSection(&csDscv);

    if (WAIT_TIMEOUT == rc) {
        Status = WSAETIMEDOUT;
    }

    DscvInProgress = FALSE;

done:

    LeaveCriticalSection(&csDscv);
    
    return (Status);
}

/*++

 Function:       DeleteSocketAttribs

 Description:    Deletes all IAS attributes associated with this socket context.

 Arguments:

    pSocket - Socket context.

 Returns:

    None.

 Comments:

    Assumes g_csWshIrda is held.

--*/

VOID
DeleteSocketAttribs(PIRLMP_SOCKET_CONTEXT pSocket)
{
    IRDA_MSG            IMsg;
    PWSHIRDA_IAS_ATTRIB pIasAttrib;

#ifdef DEBUG
    DWORD cAttribs = 0;
#endif 

    DEBUGMSG(ZONE_WSHIRDA, (TEXT("+DeleteSocketAttributes(%x)\r\n"), pSocket));
    
    while (pSocket->pIasAttribs)
    {
    #ifdef DEBUG
        cAttribs++;
    #endif 

        pIasAttrib           = pSocket->pIasAttribs;
        pSocket->pIasAttribs = pIasAttrib->pNext;
                
        DEBUGMSG(ZONE_WSHIRDA, (TEXT("Delete attrib %x socket %x\r\n"), 
                 pIasAttrib->AttributeHandle, pSocket));
                
        IMsg.Prim                  = IRLMP_DELATTRIBUTE_REQ;
        IMsg.IRDA_MSG_AttribHandle = pIasAttrib->AttributeHandle;
        IrlmpDown(NULL, &IMsg);

        IrdaFree(pIasAttrib);
    }

    DEBUGMSG(ZONE_WSHIRDA, (TEXT("-DeleteSocketAttributes ")
        TEXT("[%d IAS attributes deleted]\r\n"), cAttribs));
}

/*++

 Function:       TdiReleaseLink

 Description:    Release the link. Called by g_evReleaseLink.

 Arguments:

 Returns:

 Comments:

    If we really did correct book-keeping, we know that this function
    is thread safe.
    1) all sockets are closed, that is why we are releasing the link
    2) we won't create any more sockets until g_hEvWaitToRelLink is signalled.

--*/

INT
TdiReleaseLink(
    struct CTEEvent *pEvent,
    VOID *pvNULL
    )
{
    IRDA_MSG IMsg;
    INT      rc;

    DEBUGMSG(ZONE_FUNCTION|ZONE_WARN, (TEXT("IRDA:+TdiReleaseLink\r\n")));
    EnterCriticalSection(&g_csWshIrda);

    if (g_IrdaLinkState == IRDALINKSTATE_CLOSING) {
        DEBUGMSG(ZONE_SOCKETCNT, (TEXT("IRDA:TdiReleaseLink releasing link resources\r\n")));
        IMsg.Prim = IRLMP_LINKCONTROL_REQ;
        IMsg.IRDA_MSG_AcquireResources = FALSE;
    
        LeaveCriticalSection(&g_csWshIrda);
        rc = IrlmpDown(NULL, &IMsg);
        EnterCriticalSection(&g_csWshIrda);
        switch (rc) {
        case SUCCESS:
        case IRMAC_NOT_INITIALIZED:
            g_IrdaLinkState  = IRDALINKSTATE_CLOSED;
            SetEvent(g_hEvWaitToRelLink);
            break;

        case IRMAC_MALLOC_FAILED:
            // Try again later.
            CTEStartTimer(&g_evReleaseLink,
                          1000,
                          TdiReleaseLink,
                          NULL);
            break;

        default:
            ASSERT(FALSE);
        }
    } else {
        ASSERT(FALSE);  // Should be at IRDALINKSTATE_CLOSING
    }
    
    LeaveCriticalSection(&g_csWshIrda);

    DEBUGMSG(ZONE_FUNCTION|ZONE_WARN, (TEXT("IRDA:-TdiReleaseLink\r\n")));
    return 0;
}


⌨️ 快捷键说明

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