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

📄 tlv.c

📁 Vista 核心Rally技术之-LLTD 实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * LICENSE NOTICE.
 *
 * Use of the Microsoft Windows Rally Development Kit is covered under
 * the Microsoft Windows Rally Development Kit License Agreement,
 * which is provided within the Microsoft Windows Rally Development
 * Kit or at http://www.microsoft.com/whdc/rally/rallykit.mspx. If you
 * want a license from Microsoft to use the software in the Microsoft
 * Windows Rally Development Kit, you must (1) complete the designated
 * "licensee" information in the Windows Rally Development Kit License
 * Agreement, and (2) sign and return the Agreement AS IS to Microsoft
 * at the address provided in the Agreement.
 */

/*
 * Copyright (c) Microsoft Corporation 2005.  All rights reserved.
 * This software is provided with NO WARRANTY.
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include "globals.h"

#include "tlv.h"

/************************* E X T E R N A L S   f o r   T L V _ G E T _ F N s ***************************/
#define TLVDEF(_type, _name, _repeat, _number, _access, _inHello) \
extern int get_ ## _name ();
#include "tlvdef.h"
#undef TLVDEF

static int
write_lg_icon_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    lg_icon_t* icon = (lg_icon_t*) data;
    int          num_read;
    off_t        curOffset;
    int          remaining;

    IF_TRACED(TRC_TLVINFO)
        printf("write-lg_icon: tlvnum:%d  isHello:%s  isLarge:%s  offset:" FMT_SIZET "\n",
               number, isHello==TRUE?"true":"false", isLarge==TRUE?"true":"false", offset);
    END_TRACE

    if (icon->fd_icon < 0)
    {
        DEBUG({printf("write-lg_icon: No icon FD, nothing written\n");})
	return 0;	// No jumbo icon was correctly declared.
    }

    if (isHello==TRUE)
    {
        /* Jumbo icon - always force to a large-TLV */
        /* write header in Hello's small-TLV format */
        *buf++ = (uint8_t)number;
        *buf   = (uint8_t)0;
        close(icon->fd_icon);
        icon->fd_icon = -1;
        return 2;
    }
    
    /* try to read as much as will fit in the buffer, allowing 2 bytes for the header */
    curOffset = lseek(icon->fd_icon, (off_t) offset, SEEK_SET);
    if (curOffset != (off_t)offset)
    {
        /* the seek on the icon file failed... whine and cleanup the buffer */
        warn("write_lg_icon_t: lseek to byte " FMT_SIZET " on the iconfile FAILED, errno: %s",
             offset, strerror(errno));
        close(icon->fd_icon);
        icon->fd_icon = -1;
        return 0;
    }
    num_read = read(icon->fd_icon, buf+2, bytes_free-2);
    if (num_read < 0)
    {
        /* the read of the icon failed... whine and cleanup the buffer */
        warn("write_lg_icon_t: read of the jumbo iconfile FAILED, errno: %s", strerror(errno));
        close(icon->fd_icon);
        icon->fd_icon = -1;
        return 0;
    }
    /* adjust the number, length and/or the flag appropriately */
    /* write header in QueryLargeTlvResp large-TLV format */
    remaining = read(icon->fd_icon, buf, 1);	// Check for more...

    IF_TRACED(TRC_TLVINFO)
        printf("writing jumbo-tlv of %d bytes, with %s remaining\n",
                num_read+2, remaining<=0?"none":"some");
    END_TRACE

    if (remaining <= 0)
    {
        /* EOF or error - no more to read, so more -flag is 0 */
        /* replace: *(uint16_t*)buf = htons((uint16_t)num_read); with: */
        g_short_reorder_buffer = htons((uint16_t)num_read);
        memcpy(buf, &g_short_reorder_buffer, 2);
    } else {
        /* found at least one more byte... set the more-flag */
        /* replace: *(uint16_t*)buf = htons((uint16_t)(0x8000) | (uint16_t)num_read); with: */
        g_short_reorder_buffer = htons((uint16_t)(0x8000) | (uint16_t)num_read);
        memcpy(buf, &g_short_reorder_buffer, 2);
    }
    IF_TRACED(TRC_TLVINFO)
        printf("txbuf: %02X, %02X, %02X, %02X\n",buf[0],buf[1],buf[2],buf[3]);
    END_TRACE
    close(icon->fd_icon);
    icon->fd_icon = -1;
    return num_read + 2;
}


static int
write_icon_file_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    icon_file_t* icon = (icon_file_t*) data;
    int          num_read;
    off_t        curOffset;

    IF_TRACED(TRC_TLVINFO)
        printf("write-icon-file: tlvnum:%d  isHello:%s  isLarge:%s  offset:" FMT_SIZET "\n",
               number, isHello==TRUE?"true":"false", isLarge==TRUE?"true":"false", offset);
    END_TRACE

    if (icon->fd_icon < 0)
    {
        DEBUG({printf("write-icon-file: No icon FD, nothing written\n");})
	return 0;	// No iconfile was correctly declared.
    }

    if (isHello==TRUE)
    {
        if ((icon->sz_iconfile > (size_t)255) || (bytes_free < 2 + (int)icon->sz_iconfile) || isLarge==TRUE)
        {
            IF_TRACED(TRC_TLVINFO)
                printf("write_icon_file: not enuff room - bytes_free=%d, and icon_sz=" FMT_SIZET "\n",
                       bytes_free, icon->sz_iconfile);
                printf("writing small-tlv of 0 bytes to notify of large-tlv value\n");
            END_TRACE
            /* Not enough room - force to a large-TLV */
            /* write header in Hello's small-TLV format */
            *buf++ = (uint8_t)number;
            *buf   = (uint8_t)0;
            close(icon->fd_icon);
            icon->fd_icon = -1;
            return 2;
        }
    }

    /* try to read as much as will fit in the buffer, allowing 2 bytes for the header, small or large */
    curOffset = lseek(icon->fd_icon, (off_t) offset, SEEK_SET);
    if (curOffset != (off_t)offset)
    {
        /* the seek on the icon file failed... whine and cleanup the buffer */
        warn("write_icon_file_t: lseek to byte " FMT_SIZET " on the iconfile FAILED, errno: %s",
             offset, strerror(errno));
        close(icon->fd_icon);
        icon->fd_icon = -1;
        return 0;
    }
    num_read = read(icon->fd_icon, buf+2, bytes_free-2);
    if (num_read < 0)
    {
        /* the read of the icon failed... whine and cleanup the buffer */
        warn("write_icon_file_t: read of the iconfile FAILED, errno: %s", strerror(errno));
        close(icon->fd_icon);
        icon->fd_icon = -1;
        return 0;
    }
    /* adjust the number, length and/or the flag appropriately */
    if (isHello==TRUE)
    {
        /* write header in Hello's small-TLV format */
        IF_TRACED(TRC_TLVINFO)
            printf("writing small-tlv of %d bytes\n",num_read+2);
        END_TRACE
        *buf++ = (uint8_t)number;
        *buf-- = (uint8_t)num_read;
    } else {
        /* write header in QueryLargeTlvResp large-TLV format */
        int remaining = read(icon->fd_icon, buf, 1);	// Check for more...

        IF_TRACED(TRC_TLVINFO)
            printf("writing large-tlv of %d bytes, with %s remaining\n",
                    num_read+2, remaining<=0?"none":"some");
        END_TRACE

        if (remaining <= 0)
        {
            /* EOF or error - no more to read, so more -flag is 0 */
            /* replace: *(uint16_t*)buf = htons((uint16_t)num_read); with: */
            g_short_reorder_buffer = htons((uint16_t)num_read);
            memcpy(buf, &g_short_reorder_buffer, 2);
        } else {
            /* found at least one more byte... set the more-flag */
            /* replace: *(uint16_t*)buf = htons((uint16_t)(0x8000) | (uint16_t)num_read); with: */
            g_short_reorder_buffer = htons((uint16_t)(0x8000) | (uint16_t)num_read);
            memcpy(buf, &g_short_reorder_buffer, 2);
        }
    }
    IF_TRACED(TRC_TLVINFO)
        printf("txbuf: %02X, %02X, %02X, %02X\n",buf[0],buf[1],buf[2],buf[3]);
    END_TRACE
    close(icon->fd_icon);
    icon->fd_icon = -1;
    return num_read + 2;
}


static int
write_etheraddr_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    if (bytes_free < (int)(2 + sizeof(etheraddr_t)))
	return 0;

    IF_TRACED(TRC_TLVINFO)
        dbgprintf("write_etheraddr_t(%s): addr=" ETHERADDR_FMT "\n", isLarge?"LTLV":"TLV",
                  ETHERADDR_PRINT(((etheraddr_t*)data)));
    END_TRACE

    if (isHello)
    {
        /* write hdr in Hello-tlv format */
        *buf = (uint8_t)number;
        if (isLarge)
        {
            *(buf+1) = 0;
            return 2;
        } else {
            *(buf+1) = sizeof(etheraddr_t);
        }
    } else {
        /* write in QueryLargeTlvResp LTLV format */
        /* replace: *(uint16_t*)buf = htons(sizeof(etheraddr_t)); with: */
        g_short_reorder_buffer = htons(sizeof(etheraddr_t));
        memcpy(buf, &g_short_reorder_buffer, 2);
    }
    /* replace: *((etheraddr_t*)(buf+2)) = *(etheraddr_t*)data; with: */
    memcpy(buf+2, data, sizeof(etheraddr_t));
    return sizeof(etheraddr_t) + 2;
}

static int
write_uint8_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    if (bytes_free < (int)(2 + sizeof(uint8_t)))
	return 0;

    if (isHello)
    {
        /* write hdr in Hello-tlv format */
        *buf = (uint8_t)number;
        if (isLarge)
        {
            *(buf+1) = 0;
            return 2;
        } else {
            *(buf+1) = sizeof(uint8_t);
        }
    } else {
        /* write in QueryLargeTlvResp LTLV format */
        /* replace: *(uint16_t*)buf = htons(sizeof(etheraddr_t)); with: */
        g_short_reorder_buffer = htons(sizeof(uint8_t));
        memcpy(buf, &g_short_reorder_buffer, 2);
    }
    *(buf+2) = *(uint8_t*)data;
    return sizeof(uint8_t) + 2;
}

static int
write_uint16_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    if (bytes_free < (int)(2 + sizeof(uint16_t)))
	return 0;

    if (isHello)
    {
        /* write hdr in Hello-tlv format */
        *buf = (uint8_t)number;
        if (isLarge)
        {
            *(buf+1) = 0;
            return 2;
        } else {
            *(buf+1) = sizeof(uint16_t);
        }
    } else {
        /* write in QueryLargeTlvResp LTLV format */
        /* replace: *(uint16_t*)buf = htons(sizeof(uint16_t)); with: */
        g_short_reorder_buffer = htons(sizeof(uint16_t));
        memcpy(buf, &g_short_reorder_buffer, 2);
    }
    /* replace: *((uint16_t*)(buf+2)) = *(uint16_t*)data; with: */
    memcpy(buf+2, data, sizeof(uint16_t));
    return sizeof(uint16_t) + 2;
}

static int
write_uint32_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    if (bytes_free < (int)(2 + sizeof(uint32_t)))
	return 0;

    if (isHello)
    {
        /* write hdr in Hello-tlv format */
        *buf = (uint8_t)number;
        if (isLarge)
        {
            *(buf+1) = 0;
            return 2;
        } else {
            *(buf+1) = sizeof(uint32_t);
        }
    } else {
        /* write in QueryLargeTlvResp LTLV format */
        /* replace: *(uint16_t*)buf = htons(sizeof(uint32_t)); with: */
        g_short_reorder_buffer = htons(sizeof(uint32_t));
        memcpy(buf, &g_short_reorder_buffer, 2);
    }
    /* replace: *((uint32_t*)(buf+2)) = *(uint32_t*)data; with: */
    memcpy(buf+2, data, sizeof(uint32_t));
    return sizeof(uint32_t) + 2;
}

static int
write_uint64_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    if (bytes_free < (int)(2 + sizeof(uint64_t)))
	return 0;

    if (isHello)
    {
        /* write hdr in Hello-tlv format */
        *buf = (uint8_t)number;
        if (isLarge)
        {
            *(buf+1) = 0;
            return 2;
        } else {
            *(buf+1) = sizeof(uint64_t);
        }
    } else {
        /* write in QueryLargeTlvResp LTLV format */
        /* replace: *(uint16_t*)buf = htons(sizeof(uint64_t)); with: */
        g_short_reorder_buffer = htons(sizeof(uint64_t));
        memcpy(buf, &g_short_reorder_buffer, 2);

⌨️ 快捷键说明

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