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

📄 ircomm.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        SocketsCreated = FALSE;
    
        // make Rx/TxThread exit

        SetEvent(hRxEvent);
        SetEvent(hTxEvent);

        if (bClose) {
            CloseHandle(hTxEvent);
            CloseHandle(hRxEvent);
            VirtualFree(pMemBase, 0, MEM_RELEASE);
        } else {
            CreateSockets();
        }
    } else {
		DEBUGMSG (1, (TEXT("IRCOMM:Shutdown called and State == IRCOMM_CLOSED\r\n")));
		DEBUGMSG (1, (TEXT("IRCOMM:ListenSock=%d\r\n"), ListenSock));
		DEBUGMSG (1, (TEXT("IRCOMM:ConnectSock=%d\r\n"), ConnectSock));
		DEBUGMSG (1, (TEXT("IRCOMM:DataSock=%d\r\n"), DataSock));
	}

    LeaveCriticalSection(&IrcommCs);
}

// -----------------------------------------------------------------------------
// Function to read the thread priority from the registry.
// If it is not in the registry then a default value is returned.
// -----------------------------------------------------------------------------
static DWORD
GetRegistryThreadPriority(
	LPWSTR lpszActiveKey
	)
{
    HKEY hDevKey;
    DWORD dwValType;
    DWORD dwValLen;
    DWORD dwPrio;

    dwPrio = DEFAULT_THREAD_PRIORITY;

    hDevKey = OpenDeviceKey(lpszActiveKey);
    
    if (hDevKey) {
        dwValLen = sizeof(DWORD);
        RegQueryValueEx(
        	hDevKey,
            REGISTRY_PRIORITY_VALUE,
            NULL,
            &dwValType,
            (PUCHAR)&dwPrio,
            &dwValLen);
        RegCloseKey(hDevKey);
    }

    return dwPrio;
}

//  @func PVOID | ttt_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.  "ttt" is the string passed
//          in as lpszType in RegisterDevice

DWORD
COM_Init(DWORD Index)
{
    DWORD i;
    WORD    WsaVer = WINSOCK_VERSION;
    WSADATA WsaData;

    DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:+COM_Init(%d)\r\n"), Index));

    i = WSAStartup(WsaVer, &WsaData);
    if (i) {
        DEBUGMSG(1, (L"IRCOMM:-COM_Init:WSAStartup failed %d!!\n", i));
        return 0;
    }

    // Retrieve higher thread priority from registry
    g_dwHighThreadPrio = GetRegistryThreadPriority((LPWSTR)Index);

    InitializeCriticalSection(&IrcommCs);
    for (i = 0; i < MAX_OPENS; i++) {
        g_Opens[i] = NULL;
    }

    SocketsCreated = FALSE;
    DataSock = INVALID_SOCKET;
    vAccessOwner = NULL;

    NewState(IRCOMM_CLOSED);
    DEBUGMSG (ZONE_INTERFACE, (TEXT("IRCOMM:-COM_Init: return 1\r\n")));
    return 1;
}

//  @func PVOID | ttt_Deinit | Device deinitialization routine
//  @parm DWORD | dwData | value returned from ttt_Init call
//  @rdesc  Returns TRUE for success, FALSE for failure.
//  @remark Routine exported by a device driver.  "ttt" is the string
//          passed in as lpszType in RegisterDevice

BOOL
COM_Deinit(DWORD dwData)
{
    DEBUGMSG(ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:COM_Deinit(0x%X)\r\n"), dwData));

    DeleteCriticalSection(&IrcommCs);
    WSACleanup();
    return TRUE;
}

//  @func PVOID | ttt_Open      | Device open routine
//  @parm DWORD | dwData        | value returned from ttt_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.  "ttt" is the string passed
//          in as lpszType in RegisterDevice
DWORD
COM_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
    DWORD dwThisOpen;
    DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:+COM_Open(0x%X, 0x%X, 0x%X)\r\n"),
              dwData, dwAccess, dwShareMode));

    EnterCriticalSection(&IrcommCs);
    if ((dwAccess & (GENERIC_READ|GENERIC_WRITE)) && vAccessOwner) {
        LeaveCriticalSection(&IrcommCs);
        SetLastError(ERROR_INVALID_ACCESS);        
        return 0;
    }

    if ((dwThisOpen = NewOpen(dwAccess)) == MAX_OPENS+1) {
        LeaveCriticalSection(&IrcommCs);
        SetLastError(ERROR_OPEN_FAILED);
        return 0;
    }
    
    if (State != IRCOMM_CLOSED)
    {
        LeaveCriticalSection(&IrcommCs);
        return dwThisOpen;
    }
    
    hTxEvent        = CreateEvent(NULL, FALSE, FALSE, NULL);
    hRxEvent        = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (!hTxEvent || !hRxEvent)
    {
        DEBUGMSG(ZONE_INTERFACE|ZONE_ERROR, (TEXT("IRCOMM:-COM_Open failed to create event\r\n")));        
        if (hTxEvent) {
            CloseHandle(hTxEvent);
        }
        if (hRxEvent) {
            CloseHandle(hRxEvent);
        }
        DerefOpen(dwThisOpen);
        LeaveCriticalSection(&IrcommCs);
        SetLastError(ERROR_OPEN_FAILED);
        return 0;        
    }

    pMemBase = (BYTE *) VirtualAlloc(NULL,
                           IRCOMM_TX_RING_SIZE +
                           IRCOMM_RX_RING_SIZE +
                           IRCOMM_TX_BUF_SIZE,
                           MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (pMemBase == NULL)
    {
        DEBUGMSG(ZONE_INTERFACE|ZONE_ERROR, (TEXT("IRCOMM:-COM_Open failed to create event\r\n")));        
        CloseHandle(hTxEvent);
        CloseHandle(hRxEvent);
        DerefOpen(dwThisOpen);
        LeaveCriticalSection(&IrcommCs);        
        SetLastError(ERROR_OPEN_FAILED);
        return 0;
    }

    TxRing  = pMemBase;
    RxRing  = pMemBase + IRCOMM_TX_RING_SIZE;
    TxBuf   = RxRing + IRCOMM_RX_RING_SIZE;

    pTxRingRead = pTxRingWrite = TxRing;
    pTxRingMax  = TxRing + IRCOMM_TX_RING_SIZE;
    
    pRxRingRead = pRxRingWrite = RxRing;
    pRxRingMax  = RxRing + IRCOMM_RX_RING_SIZE;    

    vEventMask = 0;

    NewState(IRCOMM_OPENED);

    LeaveCriticalSection(&IrcommCs);
    
    DEBUGMSG(ZONE_INTERFACE, (TEXT("IRCOMM:-COM_Open: Success\r\n")));        
    return dwThisOpen;
}


//  @func BOOL | ttt_Close | Device close routine
//  @parm DWORD | dwOpenData | value returned from ttt_Open call
//  @rdesc  Returns TRUE for success, FALSE for failure
//  @remark Routine exported by a device driver.  "ttt" is the string passed
//          in as lpszType in RegisterDevice
BOOL
COM_Close(DWORD dwData) 
{
    BOOL bShutdown;
    PIRCOMM_OPEN pOpen;
    DWORD i;

    DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:+COM_Close(0x%X)\r\n"), dwData));

    EnterCriticalSection(&IrcommCs);

    if (NULL == (pOpen = IsValidOpen(dwData))) {
        SetLastError(ERROR_INVALID_HANDLE);
        LeaveCriticalSection(&IrcommCs);
        return FALSE;

    }

    for (i = pOpen->dwRefCnt; i; i--) {
        SetEvent(pOpen->hCommEvent);
    }
    LeaveCriticalSection(&IrcommCs);

    DerefOpen(dwData);  // once for IsValidOpen
    DerefOpen(dwData);  // once to delete

    EnterCriticalSection(&IrcommCs);
    //
    // If there are no open handles, then we need to shutdown
    //
    bShutdown = TRUE;
    for (dwData = 0; dwData < MAX_OPENS; dwData++) {
        if (g_Opens[dwData]) {
            bShutdown = FALSE;
            break;
        }
    }
    if (bShutdown) {
        Shutdown(TRUE); // TRUE => Close
    } else {
        ComputeEventMaskOR();
    }
    LeaveCriticalSection(&IrcommCs);
    
    DEBUGMSG(ZONE_INTERFACE, (TEXT("IRCOMM:-COM_Close: Success\r\n")));

    return TRUE;
}

#define BIND_RETRIES 5
#define BIND_RETRY_SLEEP 500

BOOL
CreateSockets()
{
    // max attribute size 6
    BYTE        IASSetBuff[sizeof(IAS_SET) - 3 + 6];
    int         IASSetLen  = sizeof(IASSetBuff);
    PIAS_SET    pIASSet    = (PIAS_SET) &IASSetBuff;
    HANDLE      hAcceptThread;
    int         Enable9WireMode  = 1;
    BOOL        Status = FALSE;
    int         cBindRetry;
    
    DEBUGMSG(ZONE_FUNCTION|ZONE_CONN, (TEXT("IRCOMM:+CreateSockets\r\n")));

    EnterCriticalSection(&IrcommCs);

    if (SocketsCreated)
    {
        Status = TRUE;
        goto done;
    }

    if (State == IRCOMM_CLOSED)
        goto done;
    
    if ((ConnectSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets ConnectSock=socket() failed %s\n\r"), GetLastErrorText()));
        goto done;
    }

    if ((ListenSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets ListenSock=socket() failed %s\n\r"), GetLastErrorText()));
        goto done;
    }

    if (setsockopt(ListenSock, SOL_IRLMP, IRLMP_9WIRE_MODE, 
                   (const char *) &Enable9WireMode, sizeof(int)) 
        == SOCKET_ERROR)
    {
        goto done;
    }

    cBindRetry = BIND_RETRIES;
    while (cBindRetry) {
        if (bind(ListenSock, (const struct sockaddr *) &SockAddr, sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR) {
            if (GetLastError() == WSAEADDRINUSE) {
                Sleep(BIND_RETRY_SLEEP);
            } else {
                DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets bind(ListenSock) failed %s\n\r"), GetLastErrorText()));
                goto done;
            }
        } else {
            break;
        }
        cBindRetry--;
    }

    ASSERT(cBindRetry);
    if (0 == cBindRetry) {
        DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets bind(ListenSock) failed %s\n\r"), GetLastErrorText()));
        goto done;
    }

    if (listen(ListenSock, 1) == SOCKET_ERROR)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets listen() failed %s\n\r"), GetLastErrorText()));
        goto done;
    }

/*
    memset ((char *) CommTimeouts, 0, sizeof(COMMTIMEOUTS));
*/
    // add IrCOMM IAS attributes
    memcpy(&pIASSet->irdaClassName[0],  "IrDA:IrCOMM", 12);
    memcpy(&pIASSet->irdaAttribName[0], "Parameters",  11);
    
    pIASSet->irdaAttribType                       = IAS_ATTRIB_OCTETSEQ;
    pIASSet->irdaAttribute.irdaAttribOctetSeq.Len = 6;

    memcpy(&pIASSet->irdaAttribute.irdaAttribOctetSeq.OctetSeq[0],
           "\000\001\006\001\001\001", 6);

    if (setsockopt(ListenSock, SOL_IRLMP, IRLMP_IAS_SET, 
                   (const char *) pIASSet, IASSetLen) == SOCKET_ERROR)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets setsockopt(,,IRLMP_IAS_SET,,) %s\n\r"), GetLastErrorText()));

        goto done;
    }

    if ((hAcceptThread = CreateThread(NULL, 0, AcceptThread, (PVOID)g_dwListenInstance, 0, NULL))
        == 0)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets CreateThread() failed\r\n")));
        goto done;
    }

    CloseHandle(hAcceptThread);

    SocketsCreated = TRUE;

    NewState(IRCOMM_DISCOVERY_PENDING);

    Status = TRUE;
    
done:

    if (!SocketsCreated) {
        if (ListenSock != INVALID_SOCKET) {
            closesocket(ListenSock);
            ListenSock = INVALID_SOCKET;
        }
        if (ConnectSock != INVALID_SOCKET) {
            closesocket(ConnectSock);
            ConnectSock = INVALID_SOCKET;
        }
    }
    
    LeaveCriticalSection(&IrcommCs);
    
    DEBUGMSG(ZONE_FUNCTION|ZONE_CONN, (TEXT("IRCOMM:-CreateSockets %s\r\n"), Status ? L"TRUE" : L"FALSE"));
    return Status;
}

//  @func DWORD | ttt_Read | Device read routine
//  @parm DWORD | dwOpenData | value returned from ttt_Open call
//  @parm LPVOID | pBuf | buffer to receive data

⌨️ 快捷键说明

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