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

📄 deviceid.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  

    deviceid.c

Abstract:  

    This file implements the PCMCIA card unique identifier (PNP id) functions.
    This is provided as a sample to platform writers and is
    expected to be able to be used without modification on most (if not
    all) hardware platforms.

Functions:

    GetCardCRC()
    CisToChar()
    itoah()
    CreateDeviceID()

Notes:


--*/

#include <windows.h>
#include <types.h>
#include <cardserv.h>
#include <sockserv.h>
#include <pcmcia.h>
#include <tuple.h>
#include <tchar.h>
#include <extern.h>

#define BUFFER_SIZE 300

// Defines for deviceID generation
#define PROD_LEN    64
#define MANFNAME_END (DEVID_LEN - 12)
#define PRODNAME_END (DEVID_LEN - 8)
#define MAX_INSTANCE 10
#define MAX_TUPLES    2048
#define STR_UNKNOWN_MANID    (TEXT("UNKNOWN_MANUFACTURER"))

//
// List of tuples used to generate a card's CRC
//
const UCHAR TplList[] = {
    CISTPL_DEVICE,
    CISTPL_VERS_1,
    CISTPL_CONFIG,
    CISTPL_CFTABLE_ENTRY,
    CISTPL_MANFID,
    CISTPL_END
};

const unsigned short crc16a[] = {
    0000000,  0140301,  0140601,  0000500,
    0141401,  0001700,  0001200,  0141101,
    0143001,  0003300,  0003600,  0143501,
    0002400,  0142701,  0142201,  0002100,
};
const unsigned short crc16b[] = {
    0000000,  0146001,  0154001,  0012000,
    0170001,  0036000,  0024000,  0162001,
    0120001,  0066000,  0074000,  0132001,
    0050000,  0116001,  0104001,  0043000,
};


//
// Using the same algorithm as Windows 95, calculate the CRC value
// to be appended with the manufacturer name and device name to
// obtain the unique identifier for the PCCARD.
//
// Return: USHORT CRC.
//
USHORT
GetCardCRC(
    UINT uSocket,
    PUCHAR buffer
    )
{
    int i;
    USHORT  crc = 0;
    USHORT  index;
    USHORT  length;
    PUCHAR  tupleData;
    PUCHAR  cp;
    UCHAR   tupleCode;
    UCHAR   tmp;
    PCARD_TUPLE_PARMS pTuple;
    PCARD_DATA_PARMS pData;
    STATUS status;

    //
    // Calculate CRC
    //

    DEBUGMSG(ZONE_TUPLE, (TEXT("GetCardCRC: Calculating CRC\r\n")));

    pTuple = (PCARD_TUPLE_PARMS) buffer;
    pData = (PCARD_DATA_PARMS) buffer;
    tupleData = (PUCHAR)pData;
    tupleData += sizeof(CARD_DATA_PARMS);

    pTuple->hSocket.uSocket = (UINT8)uSocket;
    pTuple->hSocket.uFunction = 0;
    pTuple->fAttributes = 0;         // Not interested in links
    pTuple->uDesiredTuple = 0xff;    // Interested in all tuples.
    status = CardGetFirstTuple(pTuple);
    if (status) {
        DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("GetCardCRC: CardGetFirstTuple returned %d\r\n"), status));
        goto crc_done;
    }

    //
    // Walk the whole CIS, processing only those tuples that are used in CRC
    // generation.
    //
    for (i = 0; i < MAX_TUPLES; i++) {
        tupleCode = pTuple->uTupleCode;

        for (index = 0; TplList[index] != CISTPL_END; index++) {
            if (tupleCode != TplList[index]) {
                continue;
            }

            pData->uBufLen = BUFFER_SIZE;
            pData->uTupleOffset = 0;
            status = CardGetTupleData(pData);
            if (status) {
                DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
                (TEXT("GetCardCRC: CardGetTupleData returned %d\r\n"), status));
                goto crc_done;
            }

            length = (USHORT)pData->uDataLen;


            //
            // This one is included in the CRC calculation
            //
            if (tupleCode == CISTPL_VERS_1) {
                cp = tupleData + 2;

                //
                // Include all of the manufacturer name.
                //
                while (*cp) {
                    cp++;
                }

                cp++;        // Include the product string

                while (*cp) {
                    cp++;
                }
                cp++;

                length = cp - tupleData;
            }
           
            for (cp = tupleData; length; length--, cp++) {
                tmp = *cp ^ (UCHAR)crc;
                crc = (crc >> 8) ^ crc16a[tmp & 0x0f] ^ crc16b[tmp >> 4];
            }
            break;

        }    // for (all CRC tuples)

        status = CardGetNextTuple(pTuple);
        if (status) {
            DEBUGMSG(ZONE_TUPLE|ZONE_WARNING,
            (TEXT("GetCardCRC: CardGetNextTuple returned %d\r\n"), status));
            break;
        }
        
    }    // for MAX_TUPLES

crc_done:
    DEBUGMSG(ZONE_TUPLE,(TEXT("GetCardCRC: CRC = %x\r\n"), crc));
    return crc;
}    // GetCardCRC



//
// Convert a single byte character string from a PCMCIA CIS tuple to
// a TCHAR string limiting the range to 0x20-0x7F and changing space and
// comma to underscore.
//
// Returns number of bytes of source that where used.
//
UINT
CisToChar(
    LPCSTR pcstr,   // source
    LPTSTR ptstr    // destination
    )
{
    UCHAR c;
    UINT i = 0;

    while (c = *pcstr) {
        if ((c > 0x20) && (c < 0x7f)) {
            *ptstr = (TCHAR) c;
            ptstr++;
        } else if ((c == ' ') || (c == ',')) {
            *ptstr = (TCHAR) '_';
            ptstr++;
        }
        pcstr++;
        i++;
    }
    *ptstr = (TCHAR) *pcstr;    // NULL terminator
    return i;
}



const TCHAR HexDigit[] = {
    (TCHAR) '0', (TCHAR) '1', (TCHAR) '2', (TCHAR) '3', (TCHAR) '4',
    (TCHAR) '5', (TCHAR) '6', (TCHAR) '7', (TCHAR) '8', (TCHAR) '9',
    (TCHAR) 'A', (TCHAR) 'B', (TCHAR) 'C', (TCHAR) 'D', (TCHAR) 'E',
    (TCHAR) 'F'};

//
// Convert USHORT value to ascii using hex radix
//
// Returns pointer to end of converted string.
//
TCHAR *
itoah(TCHAR * ptr, USHORT val)
{
    int i;

    for (i = 0; i < 4; i++) {
        *ptr = HexDigit[val >> 12];
        ptr++;
        val <<= 4;
    }
    *ptr = (TCHAR) 0;
    return ptr;
}    // itoah



/********************************************************************
 *
 *    CreateDeviceID - Create the DeviceID for the PC Card.
 *
 *    The device ID is created from tuple information on the PC Card and saved
 *    in the CIC socket data.  The goal is to create a unique ID for each
 *    card.  The device ID is created from the manufacturer name string,
 *    the product name string, and a 16-bit CRC of a set of tuples.
 *
 *    The ID is created by concatenating the PCMCIA" prefix, the manufacturer
 *    name string, the product name string, a 16-bit CRC, and the instance
 *    value for the card.
 *
 *        PCMCIA\<manuf_name>-<prod_name>-<crc>\<instance>
 *
 *    If the CISTPL_VERS_1 tuple is not available or the manufacturer name is
 *    NULL, the string "UNKNOWN_MANUFACTURER" will be included in its place.
 *
 *        PCMCIA\UNKNOWN_MANUFACTURER-<crc>\<instance>
 *
 *    The CRC will be created from the following tuple data.
 *
 *        CISTPL_DEVICE
 *        CISTPL_VERS_1
 *        CISTPL_CONFIG
 *        CISTPL_CFTABLE_ENTRY
 *        CISTPL_MANFID
 *
 *    The total length of the device ID string is limited to 128 characters,
 *    including the null terminator.    The manufacturer and product name will
 *    be truncated to maintain this length restriction in the ID string.
 *
 *    The characters in the manufacturer and product name strings that are
 *    greater than or equal to a space (0x20) or less than (0x7F) will be
 *    copied into the name string.  Any other characters outside this range
 *    will be skipped.  This makes it easier to include these characters in
 *    the .INF files for the device.
 *
 *    Note the Configuration Manager converts spaces (' ') and commas (',')
 *    in the device ID that is passed during devnode creation to
 *    underscores ('_') and converts all characters to upper case.
 *
 ********************************************************************/

STATUS
CreateDeviceID(
    UINT uSocket,
    BOOL instance
    )
{
    int  i;
    TCHAR *ps;
    TCHAR *pd;
    TCHAR product_name[PROD_LEN];
    TCHAR manf_name[MANFNAME_END];
    TCHAR dev_id[DEVID_LEN+1];
    UCHAR buffer[BUFFER_SIZE+sizeof(CARD_DATA_PARMS)];
    PCARD_TUPLE_PARMS pTuple;
    PCARD_DATA_PARMS pData;
    STATUS status;
    PUCHAR tupleData;

    DEBUGMSG(ZONE_TUPLE,(TEXT("CreateDeviceID entered\r\n")));

    product_name[0] = 0;      // Initialize product name string
    pd = dev_id;
    ps = STR_UNKNOWN_MANID;   // UNKNOWN_MANUFACTURER string


    //
    // Try to get the manufacturer name and product name strings from
    // the Level 1 Version tuple
    //
    pTuple = (PCARD_TUPLE_PARMS) buffer;
    pTuple->hSocket.uSocket = uSocket;
    pTuple->hSocket.uFunction = 0;
    pTuple->fAttributes = 0;        // Not interested in links
    pTuple->uDesiredTuple = CISTPL_VERS_1;
    if ((status = CardGetFirstTuple(pTuple)) == CERR_SUCCESS) {
        pData = (PCARD_DATA_PARMS) buffer;
        pData->uBufLen = BUFFER_SIZE;
        pData->uTupleOffset = 0;
        if ((status = CardGetTupleData(pData)) == CERR_SUCCESS) {
            tupleData = (PUCHAR)pData;
            tupleData += sizeof(CARD_DATA_PARMS);    // point at returned data
            if ((pData->uDataLen > 4) &&
                (tupleData[2] != 0)) {

                //
                // Have a valid manufacturer name string.
                //
                // Force a null terminator at the end of the data, just in case
                // the string is not properly terminated.
                //
                tupleData[pData->uDataLen] = 0;
                tupleData = &tupleData[2];
                i = CisToChar(tupleData, manf_name) + 1;
                ps = manf_name;
                tupleData += i;
                DEBUGMSG(ZONE_TUPLE,(TEXT("Manufacturer = %s\r\n"), manf_name));

                //
                // Copy product name if manufacturer name is not too long
                //
                if (i < pData->uDataLen-2) {
                    CisToChar(tupleData, product_name);
                    DEBUGMSG(ZONE_TUPLE,(TEXT("Product Name = %s\r\n"), product_name));
                } else {
                    product_name[0] = (TCHAR)0;
                }
            } 
#ifdef DEBUG
            else {
                if (pData->uDataLen > 2) {
                    for (i = 0; i < pData->uDataLen; i++) {
                        if ((i) && ((i & 0x0F) == 0)) {
                            DEBUGMSG(ZONE_TUPLE,(TEXT("\r\n")));
                        }
                        DEBUGMSG(ZONE_TUPLE,(TEXT(" %2x"), tupleData[i]));
                    }
                    DEBUGMSG(ZONE_TUPLE,(TEXT("\r\n")));
                }
            }
#endif
        }
    }

    //
    // Copy manufacturer name into the device ID.
    //
    i = _tcslen(ps);
    if (i > MANFNAME_END) {
        i = MANFNAME_END;
    }
    _tcsncpy(pd, ps, i);
    pd[i] = 0;
    pd += i;                    // advance destination pointer
    *pd++ = (TCHAR)'-';         // Append '-' to device ID

    //
    // If product name is valid, copy it into the device ID.
    //
    if (product_name[0] != (TCHAR)0) {
        // Append product name to device ID.
        _tcsncpy(pd, product_name, PROD_LEN);
        i = _tcslen(pd);
        if (i > PROD_LEN) {
            i = PROD_LEN;
        }
        pd += i;                    // advance destination pointer
        *pd++ = (TCHAR)'-';         // Append '-' to device ID
    }

    //
    // Compute CRC for desired tuples and
    // convert to ascii and append to device ID.
    //
    pd = itoah(pd, GetCardCRC(uSocket, buffer));

    if (instance) {
        *pd++ = (TCHAR)'\\';        // Append '\' to device ID
        pd[1] = (TCHAR)0;           // Null terminate device ID string
    }

    //
    // Install the device id string for the current card
    //
    i = _tcslen(dev_id) + 1;
    v_Sockets[uSocket].pDevId = alloc(i*sizeof(TCHAR));
    if (v_Sockets[uSocket].pDevId == NULL) {
        DEBUGMSG(ZONE_TUPLE,(TEXT("CreateDeviceID failed\r\n")));
        return CERR_OUT_OF_RESOURCE;
    }
#ifdef MYMEMTRACKING
    v_TrackPNPId++;
    v_TrackPNPIdBytes += i*sizeof(TCHAR);
#endif
#ifdef MEMTRACKING
    AddTrackedItem( v_TrackPNPId, v_Sockets[uSocket].pDevId, NULL,
        GetCurrentProcessId(), i*sizeof(TCHAR), 0, 0);
#endif

    _tcscpy(v_Sockets[uSocket].pDevId, dev_id);

    DEBUGMSG(ZONE_TUPLE,(TEXT("CreateDeviceID done\r\n")));
    return CERR_SUCCESS;

}   // CreateDeviceID

⌨️ 快捷键说明

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