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

📄 tuple.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 3 页
字号:
        pParms->uLinkOffset /= 2;
        DEBUGMSG(ZONE_TUPLE,
            (TEXT("I_CheckNextLink: processing CISTPL_LONGLINK_TO_A\r\n")));
    } else {
        return CERR_NO_MORE_ITEMS;
    }
    pParms->fFlags &= ~(TUPLE_FLAG_LINK_TO_A|TUPLE_FLAG_LINK_TO_C);

    DEBUGMSG(ZONE_TUPLE,
        (TEXT("I_CheckNextLink: CISOffset changing from 0x%x to 0x%x\r\n"),
        pParms->uCISOffset, pParms->uLinkOffset));

    //
    // Point to correct memory space on PC card (attribute vs common)
    //
    DEBUGMSG(ZONE_TUPLE,
        (TEXT("I_CheckNextLink: *pAttr changing from 0x%x"), *pAttr));
    *pAttr = I_TupleGetWindow(pParms);
    DEBUGMSG(ZONE_TUPLE,(TEXT(" to 0x%x\r\n"), *pAttr));

    //
    // Check that the link destination looks correct.
    //
    pParms->uCISOffset = pParms->uLinkOffset;
    if (pParms->uCISOffset > TUPLE_WINDOW_SIZE/2) {
        DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("I_CheckNextLink: Link target larger than window!\r\n")));
        return CERR_NO_MORE_ITEMS;
    }

    status = I_ReadAttrByte(pAttr, pParms, 0, &tuple);
    if (status != CERR_SUCCESS) {
        DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("I_CheckNextLink: Read tuple code failed %d\r\n"), status));
        return status;
    }

    if (tuple != CISTPL_LINKTARGET) {
        DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("I_CheckNextLink: Invalid link target tuple!(0x%x s/b 0x%x)\r\n"),
            tuple, CISTPL_LINKTARGET));
        return CERR_NO_MORE_ITEMS;
    }

    status = I_ReadAttrWord(pAttr, pParms, 1, &uSig);
    if (status != CERR_SUCCESS) {
        DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("I_CheckNextLink: Read signature failed %d\r\n"), status));
        return status;
    }

    uSig >>= 8; // ignore the link byte.
    if (uSig != LINK_TARGET_SIG) {
        DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("I_CheckNextLink: Invalid link target signature!(0x%x s/b 0x%x)\r\n"),
            uSig, LINK_TARGET_SIG));
        return CERR_NO_MORE_ITEMS;
    }

    pParms->fFlags &= TUPLE_FLAG_COMMON;    // Clear all but mem mode.
    return CERR_SUCCESS;
}   // I_CheckNextLink


//
// Get the next tuple's code and link info.
//
// pAttr may get changed to a pointer to common memory if the CIS is in common
// memory.
//
STATUS
I_GetNextTuple(
    PCHAR * pAttr,
    PCARD_TUPLE_PARMS pParms
    )
{
    STATUS status;

    if (I_CheckNextTuple(pAttr, pParms)) {
        status = I_CheckNextLink(pAttr, pParms);
        if (status) {
            return status;
        }
    }

    pParms->uTupleLink = 0;
    status = I_ReadAttrByte(pAttr, pParms, 0, &(pParms->uTupleCode));
    if ((status == CERR_SUCCESS) && (pParms->uTupleCode != CISTPL_END)) {
        status = I_ReadAttrByte(pAttr, pParms, 1, &(pParms->uTupleLink));
    }
    if (status != CERR_SUCCESS) {
        return status;
    }
    I_ReadLink(pAttr, pParms);    // Remember info from link tuples.
    return CERR_SUCCESS;
}   // I_GetNextTuple


//
// Find the next requested tuple
//
STATUS
I_GetDesiredTuple(
    PCHAR * pAttr,
    PCARD_TUPLE_PARMS pParms
    )
{
    STATUS status;
    int iMisses;

    //
    // Continue down this tuple chain until we find a match or hit the end.
    //
    for (iMisses = 0; iMisses < MAX_TUPLE_MISSES; iMisses++) {
        //
        // Only CISTPL_END and CISTPL_NO_LINK can have a 0 link field.
        //
        if (pParms->uTupleLink == 0) {
            if ((pParms->uTupleCode != CISTPL_END) &&
                (pParms->uTupleCode != CISTPL_NO_LINK)) {
                goto igdt_next;
            }
        }

        //
        // See if this tuple matches what the caller requested.
        //
        if ((pParms->uDesiredTuple == pParms->uTupleCode) ||
            (pParms->uDesiredTuple == 0xff)) {
            if (pParms->fAttributes & TUPLE_RETURN_LINKS) {
                return CERR_SUCCESS;
            }
            if ((pParms->uTupleCode != CISTPL_LONGLINK_A) &&
                (pParms->uTupleCode != CISTPL_LONGLINK_C) &&
                (pParms->uTupleCode != CISTPL_LONGLINK_MFC) &&
                (pParms->uTupleCode != CISTPL_LINKTARGET) &&
                (pParms->uTupleCode != CISTPL_NO_LINK)) {
                return CERR_SUCCESS;
            }
        }

igdt_next:
        status = I_GetNextTuple(pAttr, pParms);
        if (status) {
            return status;
        }
    }
    return CERR_NO_MORE_ITEMS;
}   // I_GetDesiredTuple


//
// CardGetNextTuple
//
// @doc DRIVERS
//
// @func    STATUS | CardGetNextTuple | Finds the next desired tuple in the CIS.
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_ARGS, CERR_BAD_SOCKET, CERR_READ_FAILURE,
//          CERR_OUT_OF_RESOURCE or CERR_NO_MORE_ITEMS.
//
// @comm    Follows the CIS tuple chain specified by the uLinkOffset, uCISOffset and
//          fFlags fields of the <t CARD_TUPLE_PARMS> structure.  These fields were set
//          by a previous call to <f CardGetFirstTuple> or CardGetNextTuple.
//          The result fields, uTupleCode and uTupleLink, should be ignored when
//          the return code is not CERR_SUCCESS.
// @xref    <t CARD_DATA_PARMS>
//
STATUS
CardGetNextTuple(
    PCARD_TUPLE_PARMS pParms    // @parm Pointer to a <t CARD_TUPLE_PARMS> structure.
    )
{
    PLOG_SOCKET pSock;
    PCHAR pAttr;
    STATUS status;

    DEBUGMSG(ZONE_FUNCTION|ZONE_TUPLE,
        (TEXT("CardGetNextTuple entered\r\n")));

    if (pParms == NULL) {
        status = CERR_BAD_ARGS;
        goto next_exit;
    }

    pSock = I_FindSocket(pParms->hSocket);
    if (pSock == NULL) {
        status = CERR_BAD_SOCKET;
        goto next_exit;
    }

    if (!IsCardInserted(pParms->hSocket.uSocket)) {
        status = CERR_READ_FAILURE;
        goto next_exit;
    }

    pAttr = (PCHAR)I_TupleGetWindow(pParms);
    if (pAttr == NULL) {
        status = CERR_OUT_OF_RESOURCE;
        goto next_exit;
    }

    status = I_GetNextTuple(&pAttr, pParms);
    if (status) {
        goto next_exit;
    }

    status = I_GetDesiredTuple(&pAttr, pParms);

next_exit:
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR|ZONE_TUPLE,
            (TEXT("CardGetNextTuple failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION|ZONE_TUPLE,
            (TEXT("CardGetNextTuple succeeded\r\n")));
    }
#endif
    return status;
}   // CardGetNextTuple


//
// CardGetFirstTuple
//
// @func    STATUS | CardGetFirstTuple | Finds the desired tuple in the CIS.
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_ARGS, CERR_BAD_SOCKET, CERR_READ_FAILURE,
//          CERR_OUT_OF_RESOURCE or CERR_NO_MORE_ITEMS.
//
// @comm    Follows the CIS tuple chain searching for the desired tuple.
//          On return, the uLinkOffset, uCISOffset and fFlags fields of the
//          <t CARD_TUPLE_PARMS> structure are set so that subsequent calls to
//          <f CardGetNextTuple> or <f CardGetTupleData> can follow the tuple chain.
//          The result fields, uTupleCode and uTupleLink, should be ignored when
//          the return code is not CERR_SUCCESS.
// @xref    <t CARD_DATA_PARMS>
//
STATUS
CardGetFirstTuple(
    PCARD_TUPLE_PARMS pParms    // @parm Pointer to a <t CARD_TUPLE_PARMS> structure.
    )
{
    PLOG_SOCKET pSock;
    PCHAR pAttr;
    UINT8 uByte;
    STATUS status;

    DEBUGMSG(ZONE_FUNCTION|ZONE_TUPLE,
        (TEXT("CardGetFirstTuple entered %d\r\n"), pParms->uDesiredTuple));

    if (pParms == NULL) {
        status = CERR_BAD_ARGS;
        goto first_exit;
    }

    pSock = I_FindSocket(pParms->hSocket);
    if (pSock == NULL) {
        status = CERR_BAD_SOCKET;
        goto first_exit;
    }

    if (!IsCardInserted(pParms->hSocket.uSocket)) {
        status = CERR_READ_FAILURE;
        goto first_exit;
    }

    //
    // Check if a window has already been mapped to attribute space on this
    // socket.  Map a window if not and set it to attribute space mode.
    //
    pParms->fFlags = 0;
    pAttr = (PCHAR)I_TupleGetWindow(pParms);
    if (pAttr == NULL) {
        status = CERR_OUT_OF_RESOURCE;
        goto first_exit;
    }

    PcmciaPowerOn(pParms->hSocket.uSocket);

    //
    // Fill in where to start the tuple search
    //
    pParms->uLinkOffset = 0;
    pParms->uCISOffset = 0;
    pParms->fFlags = 0;
    status = I_ReadAttrByte(&pAttr, pParms, 0, &uByte);
    if (status) {
        goto first_exit;
    }
    if (uByte == 0xFF) {
        DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("CardGetFirstTuple: CIS is in common memory\r\n")));
        // The CIS is in common memory.
        pParms->fFlags = TUPLE_FLAG_COMMON;
        pAttr = (PCHAR)I_TupleGetWindow(pParms);
        if (pAttr == NULL) {
            status = CERR_OUT_OF_RESOURCE;
            goto first_exit;
        }
    }

    status = I_ReadAttrByte(&pAttr, pParms, 0, &(pParms->uTupleCode));
    if (status == CERR_SUCCESS) {
        status = I_ReadAttrByte(&pAttr, pParms, 1, &(pParms->uTupleLink));
    }
    if (status) {
        goto first_exit;
    }

    //
    // Find the requested tuple type
    //
    status = I_GetDesiredTuple(&pAttr, pParms);

first_exit:
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR|ZONE_TUPLE,
            (TEXT("CardGetFirstTuple failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION|ZONE_TUPLE,
            (TEXT("CardGetFirstTuple succeeded\r\n")));
    }
#endif
    return status;
}   // CardGetFirstTuple


//
// CardGetTupleData
//
// @func    STATUS | CardGetTupleData | Reads the data from the current tuple.
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_ARGS, CERR_BAD_SOCKET, CERR_READ_FAILURE,
//          CERR_OUT_OF_RESOURCE, CERR_NO_MORE_ITEMS or CERR_BAD_ARG_LENGTH.
//
// @comm    Reads the CIS data from the specified PC card at the location specified by
//          the uCISOffset and uTupleOffset fields.  The uCISOffset field should be the
//          value set by a previous call to <f CardGetFirstTuple> or <f CardGetNextTuple>.
// @xref    <t CARD_TUPLE_PARMS>
//
STATUS
CardGetTupleData(
    PCARD_DATA_PARMS pData  // @parm Pointer to a <t CARD_DATA_PARMS> structure.
    )
{
    PLOG_SOCKET pSock;
    PCHAR pAttr;
    PCHAR pBuf;
    UINT uNumBytes, uOffset;
    STATUS status;
    UINT8 tuple;

    DEBUGMSG(ZONE_FUNCTION|ZONE_TUPLE,
        (TEXT("CardGetTupleData entered\r\n")));

    if (pData == NULL) {
        status = CERR_BAD_ARGS;
        goto data_exit;
    }

    pSock = I_FindSocket(pData->hSocket);
    if (pSock == NULL) {
        status = CERR_BAD_SOCKET;
        goto data_exit;
    }

    if (!IsCardInserted(pData->hSocket.uSocket)) {
        status = CERR_READ_FAILURE;
        goto data_exit;
    }

    pAttr = (PCHAR)I_TupleGetWindow((PCARD_TUPLE_PARMS)pData);
    if (pAttr == NULL) {
        status = CERR_OUT_OF_RESOURCE;
        goto data_exit;
    }

    DEBUGMSG(ZONE_TUPLE,
        (TEXT("CardGetTupleData: uCISOffset = 0x%x\r\n"), pData->uCISOffset));

    //
    // There is no data for CISTPL_END
    //
    pData->uDataLen = 0;
    status = I_ReadAttrByte(
                &pAttr,
                (PCARD_TUPLE_PARMS)pData,
                0,
                &tuple);
    if ((status != CERR_SUCCESS) || (tuple == CISTPL_END)) {
        goto data_exit;
    }

    //
    // Get length from link field.
    //
    status = I_ReadAttrByte(
                &pAttr,
                (PCARD_TUPLE_PARMS)pData,
                1,
                (PCHAR)(&(pData->uDataLen)));
    if (status) {
        goto data_exit;
    }

    //
    // Check if they want more than is there.
    //
    if (pData->uDataLen < pData->uTupleOffset) {
        status = CERR_NO_MORE_ITEMS;
        goto data_exit;
    }

    //
    // See if user buffer has enough room
    //
    pData->uDataLen -= pData->uTupleOffset;
    if (pData->uDataLen > pData->uBufLen) {
        status = CERR_BAD_ARG_LENGTH;
        goto data_exit;
    }

    pBuf = (PCHAR)pData;
    pBuf += sizeof(CARD_DATA_PARMS);    // point to user's buffer.
    uNumBytes = pData->uDataLen;
    uOffset = pData->uTupleOffset + 2;    // skip code and link

    while (uNumBytes) {
        status = I_ReadAttrByte(
                    &pAttr,
                    (PCARD_TUPLE_PARMS)pData,
                    uOffset,
                    pBuf);
        if (status != CERR_SUCCESS) {
            goto data_exit;
        }

        pBuf++;
        uNumBytes--;
        uOffset++;
    }

data_exit:
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR|ZONE_TUPLE,
            (TEXT("CardGetTupleData failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION|ZONE_TUPLE,
            (TEXT("CardGetTupleData succeeded\r\n")));
    }
#endif
    return status;
}   // CardGetTupleData


//
// VarToFixed - convert the bytes of a variable length field into a UINT32
//              and return fixed length value.
//
UINT32
VarToFixed(
    UINT32 VarSize,
    PUCHAR pBytes
    )
{
    UINT32 Fixed = 0;

    //
    // Parse the bytes starting from the MSB and shift them into place.
    //
    while (VarSize) {
        VarSize--;
        Fixed <<= 8;
        Fixed |= (UINT32) pBytes[VarSize];
    }
    return Fixed;
}


//
// ParseConfig - Read the CISTPL_CONFIG tuple from the CIS and format it into a
// PARSED_CONFIG structure.
//
STATUS
ParseConfig(
    CARD_SOCKET_HANDLE hSocket,
    PVOID   pBuf,
    PUINT   pnItems
    )
{
    STATUS status;
    PPARSED_CONFIG pCfg = (PPARSED_CONFIG)pBuf;
    UCHAR buf[BUFFER_SIZE + sizeof(CARD_DATA_PARMS)];
    PCARD_DATA_PARMS pData;
    PCARD_TUPLE_PARMS pTuple;
    PUCHAR pCIS;
    UINT   AddrSz;


    //
    // Find and read the second CISTPL_CONFIG tuple if possible.
    // (Some MFC cards contain a CISTPL_CONFIG in the CISTPL_LONGLINK_MFC chain)
    //
    pTuple = (PCARD_TUPLE_PARMS)buf;
    pTuple->hSocket = hSocket;
    pTuple->uDesiredTuple = CISTPL_CONFIG;

⌨️ 快捷键说明

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