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

📄 wshirda.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++


 Module Name:    wshirda.c

 Abstract:       Contains winsock helper functions.

 Contents:

--*/

#include "irdatdi.h"

//
// Globals.
//

const WINSOCK_MAPPING IRLMP_Mapping = { 1, 3, AF_IRDA, SOCK_STREAM, 0 };

LIST_ENTRY       g_SocketList;
CRITICAL_SECTION g_csWshIrda;
INT              g_IrdaLinkState;
HANDLE           g_hEvWaitToRelLink;
CTEEvent         g_evReleaseLink;


///
// IrdaLinkStates
//
#define IRDALINKSTATE_CLOSED  1
#define IRDALINKSTATE_CLOSING 2
#define IRDALINKSTATE_OPENED  3
#define IRDALINKSTATE_OPENING 4
#define IRLMP_OPENSOCKET_MAX_WAIT 10000

// 
// Prototypes.
//

static INT
TdiEnumDevices(
    PDEVICELIST pDeviceList,
    DWORD       cDevices
    );

static INT
TdiIasQuery(
    PIAS_QUERY pIasQuery,
    DWORD      cbAttrib
    );

static INT
TdiReleaseLink(
    struct CTEEvent *pEvent,
    VOID *pvNULL
    );

static VOID
DeleteSocketAttribs(
    PIRLMP_SOCKET_CONTEXT pSocket
    );

#ifdef DEBUG

#define DUMP_WSHOBJECTS(zone) if (zone) DumpWshObjects()

VOID
DumpWshObjects()
{
    PLIST_ENTRY             pEntry;
    PIRLMP_SOCKET_CONTEXT   pContext;
    PWSHIRDA_IAS_ATTRIB     pAttrib;

    EnterCriticalSection(&g_csWshIrda);

    DEBUGMSG(1,
        (TEXT("*** WSHIRDA Objects : %hs\r\n"), 
         IsListEmpty(&g_SocketList) ? "EMPTY" : ""));
    
    for (pEntry = g_SocketList.Flink;
         pEntry != &g_SocketList;
         pEntry = pEntry->Flink)
    {
        pContext = (PIRLMP_SOCKET_CONTEXT)pEntry;

        DEBUGMSG(1,
            (TEXT("SockContext:%#x, Excl:%hs LPT:%hs, 9Wire:%hs, Sharp:%hs, Next:%#x\r\n"),
             pContext, 
             pContext->UseExclusiveMode == TRUE ? "T" : "F",
             pContext->UseIrLPTMode     == TRUE ? "T" : "F",
             pContext->Use9WireMode     == TRUE ? "T" : "F",
             pContext->UseSharpMode     == TRUE ? "T" : "F",
             pEntry->Flink != &g_SocketList ? pEntry->Flink : NULL));
        
        for (pAttrib = pContext->pIasAttribs;
             pAttrib != NULL;
             pAttrib = pAttrib->pNext)
        {
            DEBUGMSG(1, (TEXT("    Socket attribute handle:%#x, Next:%#x\r\n"), 
                 pAttrib->AttributeHandle,
                 pAttrib->pNext));
        }
    }

    LeaveCriticalSection(&g_csWshIrda);
}

#else // DEBUG

#define DUMP_WSHOBJECTS(zone) ((void)0)

#endif // !DEBUG

/*++

 Function:       WshIrdaInit

 Description:    Initializes the WinSock Helper code.

 Arguments:

    None.

 Returns:

    STATUS_SUCCESS.

 Comments:

--*/

DWORD WshIrdaInit()
{
    DEBUGMSG(ZONE_WSHIRDA | ZONE_INIT, (TEXT("WshIrdaInit\r\n")));
    
    g_hEvWaitToRelLink = CreateEvent(
        NULL,  // security attribs.
        TRUE,  // manual reset event.
        TRUE,  // initial state is signalled.
        NULL); // no name.

    if (g_hEvWaitToRelLink == NULL)
    {
        return (STATUS_INSUFFICIENT_RESOURCES);
    }

    InitializeCriticalSection(&g_csWshIrda);
    InitializeListHead(&g_SocketList);

    CTEInitEvent(&g_evReleaseLink, TdiReleaseLink);

    // WinCE miniports start without resources acquired.
    g_IrdaLinkState  = IRDALINKSTATE_CLOSED;

    return (STATUS_SUCCESS);
}

/*++

 Function:       WshIrdaDeinit

 Description:    Deinitalizes the WinSock Helper code.

 Arguments:

    None.

 Returns:

    STATUS_SUCCESS.

 Comments:

--*/

DWORD WshIrdaDeinit()
{
    PIRLMP_SOCKET_CONTEXT pSocket;
    
    DEBUGMSG(ZONE_WSHIRDA | ZONE_INIT, (TEXT("WshIrdaDeinit\r\n")));

    DUMP_WSHOBJECTS(ZONE_WSHIRDA);

    EnterCriticalSection(&g_csWshIrda);

    for (pSocket = (PIRLMP_SOCKET_CONTEXT) g_SocketList.Flink;
         pSocket != (PIRLMP_SOCKET_CONTEXT) &g_SocketList;
         pSocket = (PIRLMP_SOCKET_CONTEXT) pSocket->Linkage.Flink)
    {
        DeleteSocketAttribs(pSocket);
    }     

    CloseHandle(g_hEvWaitToRelLink);
    g_hEvWaitToRelLink = NULL;
    
    LeaveCriticalSection(&g_csWshIrda);

    DeleteCriticalSection(&g_csWshIrda);

    return (STATUS_SUCCESS);
}


/*****************************************************************************
*
*   @func   INT |   IRLMP_GetSockaddrType |
*           Called after bind(). Returns address information. 
*
*	@rdesc
*           NO_ERROR (winerror.h) on success, or (winsock.h)
*   @errors
*           @ecode WSAEAFNOSUPPORT  | AddressFamily != AF_IRDA.
*           @ecode WSAEFAULT        | SockaddrLen != sizeof(SOCKADDR_IRDA).
*
*   @parm   PSOCKADDR       | pSockaddr     |
*           Pointer to input SOCKADDR (winsock.h) struct.
*   @parm   DWORD           | SockaddrLen   |
*           Length of input SOCKADDR struct.
*   @parm   PSOCKADDR_INFO  | pSockaddrInfo |
*           Pointer to output SOCKADDR_INFO (tdice.h) struct.
*           <nl>pSockaddrInfo.AddressInfo can return
*           <nl>    SockaddrAddressInfoNormal
*           <nl>    SockaddrAddressInfoWildcard
*           <nl>    SockaddrAddressInfoBroadcast
*           <nl>    SockaddrAddressInfoLoopback
*           <nl>pSockaddrInfo.EndPointInfo can return
*           <nl>    SockaddrEndpointInfoNormal
*           <nl>    SockaddrEndpointInfoWildcard
*           <nl>    SockaddrEndpointInfoReserved
*           <nl>IrLmp will return SockaddrAddressInfoNormal and
*           SockaddrEndpointInfoNormal.
*/

INT 
IRLMP_GetSockaddrType(IN  PSOCKADDR      pSockaddr,
                      IN  DWORD          SockaddrLen,
                      OUT PSOCKADDR_INFO pSockaddrInfo)
{
	DEBUGMSG(ZONE_FUNCTION,
        (TEXT("IRLMP_GetSockaddrType(0x%X,0x%X,0x%X)\r\n"),
        pSockaddr, SockaddrLen, pSockaddrInfo));

    if (SockaddrLen < sizeof(SOCKADDR_IRDA))
        return(WSAEFAULT);

    if (pSockaddr->sa_family != AF_IRDA)
        return WSAEAFNOSUPPORT;

    if (((SOCKADDR_IRDA *) pSockaddr)->irdaServiceName[0] == 0)
    {
        pSockaddrInfo->AddressInfo  = SockaddrAddressInfoWildcard;
        pSockaddrInfo->EndpointInfo = SockaddrEndpointInfoWildcard;
    }
    else
    {
        pSockaddrInfo->AddressInfo  = SockaddrAddressInfoNormal;
        pSockaddrInfo->EndpointInfo = SockaddrEndpointInfoNormal;
    }
    
    return(NO_ERROR);
}

/*****************************************************************************
*
*   @func   INT |   IRLMP_GetWildCardSockaddr           |
*           Called after connect() without previous bind(). Returns a 
*           SOCKADDR_IRDA suitable for an implicit bind().
*
*	@rdesc
*           NO_ERROR (winerror.h) on success, or (winsock.h)
*   @errors
*           @ecode WSAEFAULT    | SockaddrLen != sizeof(SOCKADDR_IRDA).
*
*   @parm   PVOID       |   pHelperDllSocketContext     |
*           Pointer to the IRLMP_SOCKET_CONTEXT returned by IRLMP_OpenSocket().
*   @parm   PSOCKADDR   | pSockaddr                     |
*           Pointer to output SOCKADDR (winsock.h) struct.
*   @parm   PINT        | pSockaddrLen                  |
*           Pointer to input and output PSOCKADDR struct length.
*/

INT
IRLMP_GetWildcardSockaddr(IN  PVOID     pHelperDllSocketContext,
                          OUT PSOCKADDR pSockaddr,
                          OUT PINT      pSockaddrLen)
{
	DEBUGMSG(ZONE_FUNCTION, 
        (TEXT("IRLMP_GetWildcardSockaddr(0x%X,0x%X,0x%X)\r\n"),
        pHelperDllSocketContext, pSockaddr, pSockaddrLen));

    if (*pSockaddrLen < (int)sizeof(SOCKADDR_IRDA))
    {
		DEBUGMSG(ZONE_ERROR,
            (TEXT("IRLMP_GetWildcardSockaddr *pSockaddrLen < sizeof(SOCKADDR_IRDA) %d\r\n")));

        return(WSAEFAULT);
    }

    *pSockaddrLen = sizeof(SOCKADDR_IRDA);

    memset(pSockaddr, sizeof(SOCKADDR_IRDA), 0);
    ((SOCKADDR_IRDA *) pSockaddr)->irdaAddressFamily = AF_IRDA;

    return(NO_ERROR);
}

/*****************************************************************************
*
*   @func   INT |   IRLMP_GetSocketInformation          |
*           Called by the Winsock DLL when a level/option name combination
*           is passed to getsockopt() that the winsock DLL does not understand.
*
*	@rdesc
*           NO_ERROR (winerror.h) on success, or (winsock.h)
*   @errors
*           @ecode WSAEINVAL        | Unsupported level.
*           @ecode WSAEFAULT        | pOptionLen in invalid.
*           @ecode WSAENOPROTOOPT   | Unsupported option.  
*
*   @parm   PVOID   | pHelperDllSocketContext   |
*           Pointer to the IRLMP_SOCKET_CONTEXT returned by IRLMP_OpenSocket().
*   @parm   SOCKET  | SocketHandle              |
*           Handle of the socket for which we're getting information.
*   @parm   HANDLE  | TdiAddressObjectHandle    |
*           TDI address object of the socket, or NULL.
*   @parm   HANDLE  | TdiConnectionObjectHandle |
*           TDI connection object of the socket, or NULL.
*   @parm   INT     | Level                     |
*           level, from getsockopt().           
*   @parm   INT     | OptionName                |
*           optname, from getsockopt().
*   @parm   PCHAR   | pOptionValue              |
*           optval, from getsockopt().
*   @parm   PINT    | pOptionLen                |
*           optlen, from getsockopt().
*/

INT
IRLMP_GetSocketInformation(IN  PVOID  pHelperDllSocketContext,
                           IN  SOCKET SocketHandle,
                           IN  HANDLE TdiAddressObjectHandle,
                           IN  HANDLE TdiConnectionObjectHandle,
                           IN  INT    Level,
                           IN  INT    OptionName,
                           OUT PCHAR  pOptionValue,
                           OUT PINT   pOptionLen)
{
    int                   Status = WSAENOPROTOOPT;

	DEBUGMSG(ZONE_FUNCTION,
        (TEXT("IRLMP_GetSocketInformation(0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X)\r\n"),
        pHelperDllSocketContext, 
        (unsigned) SocketHandle, 
        (unsigned) TdiAddressObjectHandle, 
        (unsigned) TdiConnectionObjectHandle,
        Level, 
        OptionName, 
        pOptionValue, 
        pOptionLen));

    if (Level == SOL_INTERNAL && OptionName == SO_CONTEXT)
    {
        // Copy pHelperDllSocketContext to pOptionValue
        if ((*pOptionLen = sizeof(IRLMP_SOCKET_CONTEXT)) < 
            (int)sizeof(IRLMP_SOCKET_CONTEXT))
        {
            Status = WSAEFAULT;
            goto done;
        }
        
        if (pOptionValue != NULL)
        {
            memcpy(pOptionValue, pHelperDllSocketContext, 
                   sizeof(IRLMP_SOCKET_CONTEXT));
            ((PIRLMP_SOCKET_CONTEXT)pOptionValue)->Linkage.Flink = NULL;
            ((PIRLMP_SOCKET_CONTEXT)pOptionValue)->Linkage.Blink = NULL;
            ((PIRLMP_SOCKET_CONTEXT)pOptionValue)->pIasAttribs   = NULL;
        }

        Status = NO_ERROR;
    }

    if (Level == SOL_IRLMP && OptionName == IRLMP_SEND_PDU_LEN)
    {
        PIRLMP_CONNECTION     pConn;
        
        if (*pOptionLen < (int)sizeof(DWORD))
        {
            Status = WSAEFAULT;
            goto done;
        }

        pConn = GETCONN(TdiConnectionObjectHandle);
    
        if (pConn == NULL)
        {
            Status = WSAEFAULT;
            goto done;
        }

        VALIDCONN(pConn);
    
        GET_CONN_LOCK(pConn);

        if (pConn->Use9WireMode)
            *(int *) pOptionValue = pConn->SendMaxPDU - 1;
        else
            *(int *) pOptionValue = pConn->SendMaxPDU;

        FREE_CONN_LOCK(pConn);

        REFDELCONN(pConn);
        Status = NO_ERROR;
    }

    if (Level == SOL_IRLMP && OptionName == IRLMP_ENUMDEVICES)
    {
        if (*pOptionLen < (int)sizeof(DWORD))
        {
            Status = WSAEFAULT;
            goto done;
        }
    
        Status = TdiEnumDevices(
            (PDEVICELIST)pOptionValue,
            (*pOptionLen - sizeof(DWORD))/sizeof(IRDA_DEVICE_INFO)
            );
    }

    if (Level == SOL_IRLMP && OptionName == IRLMP_IAS_QUERY)
    {
        if (*pOptionLen < (int)(sizeof(IAS_QUERY) - 4))
        {
            Status = WSAEFAULT;
            goto done;
        }

        Status = TdiIasQuery(
            (PIAS_QUERY)pOptionValue,
            *pOptionLen);
    }

done:


    return(Status);
}

/*****************************************************************************
*
*   @func   INT |   IRLMP_SetSocketInformation          |
*           Called by the Winsock DLL when a level/option name combination
*           is passed to setsockopt() that the winsock DLL does not understand.
*
*	@rdesc
*           NO_ERROR (winerror.h) on success, or (winsock.h)
*   @errors
*           @ecode WSAEINVAL        | Unsupported level.
*           @ecode WSAEFAULT        | pOptionLen in invalid.
*           @ecode WSAENOBUFS       | No memory.
*           @ecode WSAENOPROTOOPT   | Unsupported option.  
*
*   @parm   PVOID   | pHelperDllSocketContext   |
*           Pointer to the IRLMP_SOCKET_CONTEXT returned by IRLMP_OpenSocket().
*   @parm   SOCKET  | SocketHandle              |
*           Handle of the socket for which we're getting information.
*   @parm   HANDLE  | TdiAddressObjectHandle    |
*           TDI address object of the socket, or NULL.
*   @parm   HANDLE  | TdiConnectionObjectHandle |
*           TDI connection object of the socket, or NULL.
*   @parm   INT     | Level                     |
*           level, from setsockopt().           
*   @parm   INT     | OptionName                |
*           optname, from setsockopt().
*   @parm   PCHAR   | pOptionValue              |
*           optval, from setsockopt().
*   @parm   INT     | OptionLen                 |
*           optlen, from setsockopt().
*/
	
INT
IRLMP_SetSocketInformation(IN PVOID  pHelperDllSocketContext,
                           IN SOCKET SocketHandle,
                           IN HANDLE TdiAddressObjectHandle,
                           IN HANDLE TdiConnectionObjectHandle,
                           IN INT    Level,
                           IN INT    OptionName,
                           IN PCHAR  pOptionValue,
                           IN INT    OptionLen)
{
    PIRLMP_SOCKET_CONTEXT pContext = 
        (PIRLMP_SOCKET_CONTEXT) pHelperDllSocketContext;
    PIAS_SET              pIASSet  = (PIAS_SET) pOptionValue;
    IRDA_MSG              IrDAMsg;
    int                   rc;

	DEBUGMSG(ZONE_FUNCTION,
        (TEXT("IRLMP_SetSocketInformation(0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X)\r\n"),
        pHelperDllSocketContext, 
        (unsigned) SocketHandle, 
        (unsigned) TdiAddressObjectHandle,
        (unsigned) TdiConnectionObjectHandle, 

⌨️ 快捷键说明

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