[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk fo
From: |
Blue Swirl |
Subject: |
Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system |
Date: |
Wed, 9 Jan 2013 21:37:54 +0000 |
On Wed, Jan 9, 2013 at 7:31 AM, 马磊 <address@hidden> wrote:
>
>
>>> Hi,
>>> The final effect is as follows:
>>>
>>>
>>> address@hidden Fri Dec 28 ~/honeypot/xen/xen-4.1.2]$ qemu-img-xen cat
>>> -f /1/boot.ini ~/vm-check.img
>>> [boot loader]
>>> timeout=30
>>> default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
>>> [operating systems]
>>> multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP
>>> Professional" /noexecute=optin /fastdetect
>>>
>>> address@hidden Fri Dec 28 ~/honeypot/xen/xen-4.1.2]$ qemu-img-xen ls
>>> -l -d /1/ ~/vm-check.img
>>> 【name size(bytes) dir? date
>>> create-time】
>>> AUTOEXEC.BAT 0 file 2010-12-22 17:30:37
>>> boot.ini 211 file 2010-12-23 01:24:41
>>> bootfont.bin 322730 file 2004-11-23 20:00:00
>>>
>>>
>>>
>>> As you see above, the patch add two sub-commands for qemu-img-xen:cat and
>>> ls.
>>>
>>> For details in the patch, please check the attachment.
>>>
>>>
>
> Does anyone prefer this feature?!
Nice feature, but this approach would just clutter QEMU and give only
readonly FAT or NTFS support. I think a more generally useful approach
would be to use NBD or iSCSI to export the block device data from the
image file (qemu-nbd already exists) and then make a tool that uses
some combination of NBD/iSCSI client, all GRUB file systems and FUSE
or other user space methods to access the contents of the filesystem.
Probably also UML with a simple guest agent could provide read/write
access to any file system that Linux supports.
>
>
>
> Signed-off-by: Lei Ma (address@hidden)
>
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/debug.c
Patches sent to qemu-devel should be based on qemu.git. Please also
read CODING_STYLE and HACKING files.
> xen-4.1.2-b/tools/ioemu-qemu-xen/debug.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/debug.c 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/debug.c 2012-12-28 16:02:40.999933925
> +0800
> @@ -0,0 +1,182 @@
> +#include<time.h>
> +#include<sys/stat.h>
> +#include<stdarg.h>
> +#include<fcntl.h>
> +#include"debug.h"
> +#include <unistd.h>
> +#include <string.h>
> +
> +#define KB(x) ((x)*1024)
> +
> +static int dbg_term = 0, dbg_file = 0, log_day = 0;
> +static FILE* fp_log = NULL;
> +static char dir[128]={0,}, filename[160];
> +static void init_file_path(void);
> +static char printbuf[1024]={};
> +int mkdir_recursive(char* path);
> +
> +
> +void print_error(char* file, char* function, int line, const char *fmt,
> ...)
> +{
> + va_list args;
> + int i;
> +
> + if( !dbg_term && !dbg_file )
> + return;
> +
> + va_start(args, fmt);
> + i=vsprintf( printbuf, fmt, args );
> + printbuf[i] = 0;
> + va_end(args);
> +
> + if( dbg_term )
> + {
> + printf("[%s]%s(%d):\n%s\n", file, function, line, printbuf);
> + }
> +
> + if( dbg_file )
> + {
> + time_t t = time( NULL );
> + struct tm* tm1 = localtime(&t);
> + if( !tm1 ) return;
> + //if( tm1->tm_mday != log_day )
> + {
> + //init_file_path();
> + }
> + char tmp[16];
> + strftime( tmp, 15, "%X", tm1 );
> + fprintf( fp_log, "%s [%s]%s(%d): %s\n", tmp, file, function, line,
> printbuf);
> + fflush( fp_log );
> + }
> +}
> +
> +static char* hex_str(unsigned char *buf, int len, char* outstr )
> +{
> +
> + const char *set = "0123456789abcdef";
> + char *tmp;
> + unsigned char *end;
> + if (len > 1024)
> + len = 1024;
> + end = buf + len;
> + tmp = &outstr[0];
> + while (buf < end)
> + {
> + *tmp++ = set[ (*buf) >> 4 ];
> + *tmp++ = set[ (*buf) & 0xF ];
> + *tmp++ = ' ';
> + buf ++;
> + }
> + *tmp = '\0';
> + return outstr;
> +}
> +
> +void hex_dump( unsigned char * buf, int len )
> +{
> + char str[KB(4)];
> + if( dbg_term )
> + puts( hex_str( buf, len, str ) );
> + if( dbg_file ){
> + fputs( hex_str( buf, len, str ), fp_log );
> + fprintf( fp_log, "\n" );
> + fflush( fp_log );
> + }
> + //fprintf( stderr, hex_str( buf, len ) );
> +}
> +
> +void debug_term_on()
> +{
> + dbg_term = 1;
> +}
> +
> +void debug_term_off()
> +{
> + dbg_term = 0;
> +}
> +
> +
> +int mkdir_recursive( char* path )
> +{
> + char *p;
> +
> + if( access( path, 0 ) == 0 )
> + return 0;
> +
> + for( p=path; *p; p++ )
> + {
> + if( p>path && *p == '/' )
> + {
> + *p = 0;
> + if( access( path, 0 ) != 0 )
> + {
> +#ifdef __WIN32__
> + mkdir( path );
> +#else
> + if( mkdir( path, S_IRWXU ) != 0 )
> + return -1;
> +#endif
> + }
> + *p = '/';
> + }
> + }
> +#ifdef __WIN32__
> + return mkdir( path );
> +#else
> + return mkdir( path, S_IRWXU );
> +#endif
> +}
> +
> +void init_file_path()
> +{
> + char tmp[64];
> + time_t t = time( NULL );
> + struct tm* tm1 = localtime(&t);
> +
> + if( !tm1 )
> + {
> + perror("debug.c init_file_path: ERROR GETTING SYSTEM TIME.");
> + }
> + log_day = tm1->tm_mday;
> + strftime( tmp, 64, "/%Y-%m-%d.txt", tm1 );
> +
> + if( access( dir, 0 )!=0 )
> + {
> + (mkdir_recursive( dir )<0) ? perror("mkdir_recursive fail!!\n") : 0;
> + }
> + strcpy( filename, dir );
> + strcat( filename, tmp );
> + if( fp_log )
> + fclose( fp_log );
> + fp_log = fopen( filename, "w" );
> + if(fp_log)
> + {
> + fprintf(fp_log,"======================LOG
> START========================\n");
> + fclose(fp_log); fp_log=NULL;
> + fp_log = fopen( filename, "a+" );
> + NULL==fp_log ? printf("init_file_path():fopen(a+) fail\n") : 0;
> + }
> +}
> +
> +void debug_file_on(char *path)
> +{
> + if( dbg_file )
> + return;
> + debug_set_dir(path);
> + init_file_path();
> + dbg_file = 1;
> +}
> +
> +void debug_file_off()
> +{
> + if( !dbg_file )
> + return;
> + dbg_file = 0;
> + if( fp_log )
> + fclose( fp_log );
> +}
> +
> +void debug_set_dir(char* str)
> +{
> + strcpy( dir, str );
> +}
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/debug.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/debug.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/debug.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/debug.h 2012-12-28 16:02:41.000934327
> +0800
> @@ -0,0 +1,34 @@
> +#ifndef _DEBUG_H
> +#define _DEBUG_H
> +
> +#include <stdio.h>
> +#include <errno.h>
> +#include <assert.h>
> +
> +//#define RELEASE
> +
> +#ifndef RELEASE
> +#define DBG(args ...) \
> + print_error( (char*)__FILE__, (char*)__func__, __LINE__, ##args )
> +#else
> +#define DBG(args ...) \
> + do \
> + { \
> +fprintf(logfile,"%s::[%s]::(%d):\n", \
> + (char*)__FILE__, (char*)__func__, __LINE__); \
> +fprintf(logfile, ##args); fprintf(logfile, "\n"); \
> +} \
> +while(0)
> +//#define DBG printf
> +#endif
> +#define MSGprintf
> +void print_error(char* file, char* function, int line, const char *fmt,
> ...);
> +void hex_dump( unsigned char * buf, int len );
> +void debug_term_on(void);
> +void debug_term_off(void);
> +void debug_file_on(char *path);
> +void debug_file_off(void);
> +void debug_set_dir(char* str);
> +
> +#endif //_DEBUG_H
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fat.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/fat.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fat.c 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fat.c 2012-12-28 16:02:41.001934709
> +0800
> @@ -0,0 +1,936 @@
> +/* fat.c - FAT filesystem */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free
> Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include "misc.h"
> +#include "fat.h"
> +#include "debug.h"
> +
> +
> +int g_err = GRUB_ERR_NONE;
> +int64_t s_bpb_bytes_per_sector;
> +int64_t s_part_off_sector;
> +
> +static int bdrv_pread_from_sector_of_volume(BlockDriverState *bs, int64_t
> offset,
> + void *buf1, int count1)
> +{
> + int64_t off = s_bpb_bytes_per_sector * s_part_off_sector + offset;
> + return bdrv_pread(bs, off, buf1, count1);
> +}
> +
> +
> +static int
> +fat_log2 (unsigned x)
> +{
> + int i;
> +
> + if (x == 0)
> + return -1;
> +
> + for (i = 0; (x & 1) == 0; i++)
> + x >>= 1;
> +
> + if (x != 1)
> + return -1;
> +
> + return i;
> +}
> +
> +
> +char *
> +grub_fat_find_dir (BlockDriverState *bs, struct grub_fat_data *data,
> + const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure),
> + void *closure);
> +
> +
> +
> +struct grub_fat_data *
> +grub_fat_mount (BlockDriverState *bs, uint32_t part_off_sector)
> +{
> + struct grub_fat_bpb bpb;
> + struct grub_fat_data *data = 0;
> + grub_uint32_t first_fat, magic;
> + int64_t off_bytes = (int64_t)part_off_sector << GRUB_DISK_SECTOR_BITS;
> +
> + if (! bs)
> + goto fail;
> +
> + data = (struct grub_fat_data *) malloc (sizeof (*data));
> + if (! data)
> + goto fail;
> +
> + /* Read the BPB. */
> + if (bdrv_pread(bs, off_bytes, &bpb, sizeof(bpb)) != sizeof(bpb))
> + {
> + DBG("bdrv_pread fail....");
> + goto fail;
> + }
> +
> + if (grub_strncmp((const char *)
> bpb.version_specific.fat12_or_fat16.fstype,
> + "FAT12", 5)
> + && grub_strncmp((const char *)
> bpb.version_specific.fat12_or_fat16.fstype,
> + "FAT16", 5)
> + && grub_strncmp((const char *) bpb.version_specific.fat32.fstype,
> + "FAT32", 5)
> + )
> + {
> +
> + DBG("fail here-->grub_strncmp......");
> + goto fail;
> + }
> +
> + /* Get the sizes of logical sectors and clusters. */
> + s_bpb_bytes_per_sector = (bpb.bytes_per_sector);
> + s_part_off_sector = part_off_sector;
> + data->logical_sector_bits =
> + fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
> + DBG("bpb.bytes_per_sector=0x%x, le_to_cpu16=0x%x",
> + bpb.bytes_per_sector, grub_le_to_cpu16 (bpb.bytes_per_sector));
> +
> +
> + if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS)
> + {
> + DBG("fail here-->logical_sector_bits");
> + goto fail;
> + }
> + data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
> +
> + DBG("bpb.sectors_per_cluster=%u", bpb.sectors_per_cluster);
> + data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
> + if (data->cluster_bits < 0)
> + {
> + DBG("fail here-->cluster_bits......line[%u]", __LINE__);
> + goto fail;
> + }
> + data->cluster_bits += data->logical_sector_bits;
> +
> + /* Get information about FATs. */
> + DBG("bpb.num_reserved_sectors=%u,"
> + "le_to_cpu16=%u",
> + bpb.num_reserved_sectors,
> + grub_le_to_cpu16 (bpb.num_reserved_sectors));
> + data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors)
> + << data->logical_sector_bits);
> + DBG("data->fat_sector=%u, part_off_sector=%u",
> + data->fat_sector, part_off_sector);
> + if (data->fat_sector == 0)
> + {
> + DBG("fail here-->fat_sector......");
> + goto fail;
> + }
> + data->sectors_per_fat = ((bpb.sectors_per_fat_16
> + ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
> + : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
> + << data->logical_sector_bits);
> + DBG("bpb.version_specific.fat32.sectors_per_fat_32=%u\n"
> + "grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)=%u",
> + bpb.version_specific.fat32.sectors_per_fat_32,
> + grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32));
> + if (data->sectors_per_fat == 0)
> + goto fail;
> +
> + /* Get the number of sectors in this volume. */
> + data->num_sectors = ((bpb.num_total_sectors_16
> + ? grub_le_to_cpu16 (bpb.num_total_sectors_16)
> + : grub_le_to_cpu32 (bpb.num_total_sectors_32))
> + << data->logical_sector_bits);
> + if (data->num_sectors == 0)
> + {
> + DBG("fail here-->num_sectors......");
> + goto fail;
> + }
> + /* Get information about the root directory. */
> + if (bpb.num_fats == 0)
> + {
> + DBG("fail here-->num_fats......");
> + goto fail;
> + }
> + data->root_sector = data->fat_sector + bpb.num_fats *
> data->sectors_per_fat;
> + data->num_root_sectors
> + = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
> + * GRUB_FAT_DIR_ENTRY_SIZE
> + + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
> + >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
> + << (data->logical_sector_bits));
> + //in fat32 : root is not included in file cluster??
> + data->cluster_sector = data->root_sector + data->num_root_sectors;
> + data->num_clusters = (((data->num_sectors - data->cluster_sector)
> + >> (data->cluster_bits + data->logical_sector_bits))
> + + 2);
> +
> + if (data->num_clusters <= 2)
> + {
> + DBG("fail here-->num_clusters......");
> + goto fail;
> + }
> + if (! bpb.sectors_per_fat_16)
> + {
> + /* FAT32. */
> + grub_uint16_t flags = grub_le_to_cpu16
> (bpb.version_specific.fat32.extended_flags);
> +
> + data->root_cluster = grub_le_to_cpu32
> (bpb.version_specific.fat32.root_cluster);
> + data->fat_size = 32;
> + data->cluster_eof_mark = 0x0ffffff8;
> +
> + if (flags & 0x80)
> + {
> + /* Get an active FAT. */
> + unsigned active_fat = flags & 0xf;
> +
> + if (active_fat > bpb.num_fats)
> + goto fail;
> +
> + data->fat_sector += active_fat * data->sectors_per_fat;
> + }
> +
> + if (bpb.num_root_entries != 0 ||
> bpb.version_specific.fat32.fs_version != 0)
> + goto fail;
> + }
> + else
> + {
> + /* FAT12 or FAT16. */
> + data->root_cluster = ~0U;
> +
> + if (data->num_clusters <= 4085 + 2)
> + {
> + /* FAT12. */
> + data->fat_size = 12;
> + data->cluster_eof_mark = 0x0ff8;
> + }
> + else
> + {
> + /* FAT16. */
> + data->fat_size = 16;
> + data->cluster_eof_mark = 0xfff8;
> + }
> + }
> +
> + /* More sanity checks. */
> + if (data->num_sectors <= data->fat_sector)
> + goto fail;
> +
> +
> + DBG("data->fat_sector=%u, data->sectors_per_fat=%u",
> + data->fat_sector, data->sectors_per_fat);
> + if (bdrv_pread_from_sector_of_volume(bs,
> + data->fat_sector << GRUB_DISK_SECTOR_BITS,
> + &first_fat,
> + sizeof (first_fat)) != sizeof(first_fat))
> + {
> + DBG("fail here-->bdrv_pread......");
> + goto fail;
> + }
> +
> + first_fat = grub_le_to_cpu32 (first_fat);
> +
> + if (data->fat_size == 32)
> + {
> + first_fat &= 0x0fffffff;
> + magic = 0x0fffff00;
> + }
> + else if (data->fat_size == 16)
> + {
> + first_fat &= 0x0000ffff;
> + magic = 0xff00;
> + }
> + else
> + {
> + first_fat &= 0x00000fff;
> + magic = 0x0f00;
> + }
> +
> + /* Serial number. */
> + if (bpb.sectors_per_fat_16)
> + data->uuid = grub_le_to_cpu32
> (bpb.version_specific.fat12_or_fat16.num_serial);
> + else
> + data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
> +
> + /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
> + descriptor, even if it is a so-called superfloppy (e.g. an USB key).
> + The check may be too strict for this kind of stupid BIOSes, as
> + they overwrite the media descriptor. */
> + if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
> + {
> + DBG("fail here-->first_fat=0x%x, magic=0x%x",
> + first_fat, magic);
> + goto fail;
> + }
> + /* Start from the root directory. */
> + data->file_cluster = data->root_cluster;
> + data->cur_cluster_num = ~0U;
> + data->attr = GRUB_FAT_ATTR_DIRECTORY;
> + DBG("data->file_cluster=%u \ndata->cur_cluster_num=%u
> \ndata->attr=0x%x\n"
> + "data->logical_sector_bits=%u\n"
> + "data->cluster_bits=%u",
> + data->file_cluster, data->cur_cluster_num, data->attr,
> + data->logical_sector_bits, data->cluster_bits);
> + return data;
> +
> + fail:
> +
> + free (data);
> + printf("not a FAT filesystem!\n");
> + return 0;
> +}
> +
> +
> +
> +//从文件的指定偏移offset字节处读取len字节的数据到buf
> +//文件由data->file_cluster指定
> +//data->file_cluster指定了文件的起始簇号
> +//默认data->file_cluster=2,代表根目录
> +static grub_ssize_t
> +grub_fat_read_data (BlockDriverState *bs, struct grub_fat_data *data,
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset, unsigned length,
> + void *closure),
> + void *closure,
> + grub_off_t offset, grub_size_t len, char *buf)
> +{
> + grub_size_t size;
> + grub_uint32_t logical_cluster;
> + unsigned logical_cluster_bits;
> + grub_ssize_t ret = 0;
> + unsigned long sector;
> + uint64_t off_bytes = 0;
> + /* This is a special case. FAT12 and FAT16 doesn't have the root
> directory
> + in clusters. */
> + if (data->file_cluster == ~0U)
> + {
> + size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
> + if (size > len)
> + size = len;
> +
> + off_bytes = ((uint64_t)data->root_sector << GRUB_DISK_SECTOR_BITS) +
> offset;
> + if(bdrv_pread_from_sector_of_volume(bs, off_bytes, buf, size ) !=
> size)
> + return -1;
> +
> + return size;
> + }
> +
> + /* Calculate the logical cluster number and offset. */
> + logical_cluster_bits = (data->cluster_bits
> + + data->logical_sector_bits
> + + GRUB_DISK_SECTOR_BITS);
> + logical_cluster = offset >> logical_cluster_bits; //which cluster to
> read
> + offset &= (1 << logical_cluster_bits) - 1; //mod
> +
> + if (logical_cluster < data->cur_cluster_num) //
> + {
> + data->cur_cluster_num = 0;
> + data->cur_cluster = data->file_cluster; // 第2个fat表项开始记录目录和文件
> + }
> +
> + while (len)
> + {
> + while (logical_cluster > data->cur_cluster_num)
> + {
> + /* Find next cluster. */
> + grub_uint32_t next_cluster;
> + unsigned long fat_offset;
> +
> + switch (data->fat_size)
> + {
> + case 32:
> + fat_offset = data->cur_cluster << 2;
> + break;
> + case 16:
> + fat_offset = data->cur_cluster << 1;
> + break;
> + default:
> + /* case 12: */
> + fat_offset = data->cur_cluster + (data->cur_cluster >> 1);
> + break;
> + }
> +
> + /* Read the FAT. */
> + int len = (data->fat_size + 7) >> 3;
> + uint64_t off_bytes = ((uint64_t)data->fat_sector <<
> GRUB_DISK_SECTOR_BITS) + fat_offset;
> + if (bdrv_pread_from_sector_of_volume (bs, off_bytes,
> + (char *) &next_cluster,
> + len) != len) //从fat表读取簇号
> + return -1;
> +
> + next_cluster = grub_le_to_cpu32 (next_cluster);
> + switch (data->fat_size)
> + {
> + case 16:
> + next_cluster &= 0xFFFF;
> + break;
> + case 12:
> + if (data->cur_cluster & 1)
> + next_cluster >>= 4;
> +
> + next_cluster &= 0x0FFF;
> + break;
> + }
> +
> + DBG ("fat_size=%d, next_cluster=%u",
> + data->fat_size, next_cluster);
> +
> + /* Check the end. */
> + if (next_cluster >= data->cluster_eof_mark)
> + return ret;
> +
> + if (next_cluster < 2 || next_cluster >= data->num_clusters)
> + {
> + DBG("invalid cluster %u................",
> + next_cluster);
> + return -1;
> + }
> +
> + data->cur_cluster = next_cluster;
> + data->cur_cluster_num++;
> + }
> +
> + /* Read the data here. */
> + //逻辑簇所对应的绝对扇区
> + sector = (data->cluster_sector
> + + ((data->cur_cluster - 2)
> + << (data->cluster_bits + data->logical_sector_bits)));
> + //绝对扇区中去掉偏移后的字节数
> + size = (1 << logical_cluster_bits) - offset;
> + if (size > len)
> + size = len;
> +
> + //disk->read_hook = read_hook;
> + //disk->closure = closure;
> + int64_t off_bytes = ((uint64_t)sector << GRUB_DISK_SECTOR_BITS) +
> offset;
> + //disk->read_hook = 0;
> + if (bdrv_pread_from_sector_of_volume (bs, off_bytes, buf, size) !=
> size)
> + return -1;
> +
> + len -= size;
> + buf += size;
> + ret += size;
> + logical_cluster++;
> + offset = 0; //以后读的都是完整扇区
> + }
> +
> + return ret;
> +}
> +
> +//遍历由data->file_cluster指定的目录
> +static int
> +grub_fat_iterate_dir (BlockDriverState *bs, struct grub_fat_data *data,
> + int (*hook) (const char *filename,
> + struct grub_fat_dir_entry *dir,
> + void *closure),
> + void *closure)
> +{
> + struct grub_fat_dir_entry dir;
> + char *filename, *filep = 0;
> + grub_uint16_t *unibuf;
> + int slot = -1, slots = -1;
> + int checksum = -1;
> + grub_ssize_t offset = -sizeof(dir);
> +
> + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
> + return printf("not a directory......\n");
> +
> + /* Allocate space enough to hold a long name. */
> + filename = (char*)malloc (0x40 * 13 * 4 + 1);
> + unibuf = (grub_uint16_t *) malloc (0x40 * 13 * 2);
> + char *gbname = (char*)malloc(0x40 * 13 * 2);
> + if (! filename || ! unibuf || !gbname)
> + {
> + free(gbname);
> + free (filename);
> + free (unibuf);
> + perror("iterate: malloc failed!...\n");
> + return -1;
> + }
> +
> +
> + int count = 0;
> + while (1)
> + {
> + unsigned i;
> +
> + /* Adjust the offset. */
> + offset += sizeof (dir);
> + DBG("\n[%d]offset=%u,"
> + "data->cur_cluster_num=%u,data->cur_cluster=%u",
> + count+1, offset,
> + data->cur_cluster_num, data->cur_cluster);
> + /* Read a directory entry. */
> + //0x0表示空目录
> + if ((grub_fat_read_data (bs, data, 0, 0,
> + offset, sizeof (dir), (char *) &dir)
> + != sizeof (dir) || dir.name[0] == 0))
> + {
> + DBG("break...dir.name[0]==%d", dir.name[0]);
> + break;
> + }
> + /* Handle long name entries. */
> + if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
> + {
> + DBG("long name...");
> + struct grub_fat_long_name_entry *long_name
> + = (struct grub_fat_long_name_entry *) &dir;
> + grub_uint8_t id = long_name->id;
> +
> + if (id & 0x40) //the last item
> + {
> + id &= 0x3f; //index or ordinal number 1~31
> + slots = slot = id;
> + checksum = long_name->checksum;
> + DBG("the last ordinal num=%d!!!", id);
> + }
> +
> + if (id != slot || slot == 0 || checksum != long_name->checksum)
> + {
> + DBG("not valid ordinal number ,ignore...continue");
> + checksum = -1;
> + continue;
> + }
> +
> + slot--;
> + memcpy (unibuf + slot * 13, long_name->name1, 5 * 2);
> + memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
> + memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
> + DBG("memcpy...continue");
> + continue;
> + }
> +
> +
> + /* Check if this entry is valid. */
> + //oxe5表示已经被删除
> + if (dir.name[0] == 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID))
> + {
> + DBG("dir.name[0]=0x%x, dir.attr=0x%x not valid...continue",
> + dir.name[0], dir.attr);
> + continue;
> + }
> +
> + DBG("checksum=%d, slot=%d", checksum, slot);
> + /* This is a workaround for Japanese. */
> + if (dir.name[0] == 0x05)
> + dir.name[0] = 0xe5;
> +
> + if (checksum != -1 && slot == 0)
> + {
> + DBG("checksuming");
> + grub_uint8_t sum;
> +
> + for (sum = 0, i = 0; i < sizeof (dir.name); i++)
> + sum = ((sum >> 1) | (sum << 7)) + dir.name[i];
> +
> + if (sum == checksum)
> + {//长名表项后面紧接短名表项,验证成功则证明真正是长名字
> + int u;
> +
> + for (u = 0; u < slots * 13; u++)
> + unibuf[u] = grub_le_to_cpu16 (unibuf[u]);
> +
> + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
> + slots * 13) = '\0';
> +
> +
> + checksum = -1;
> + for (i = 0; i < sizeof (dir.name); i++)
> + DBG("0x%x ", dir.name[i]);
> +
> + u2g(filename, strlen(filename), gbname, 0x40 * 13 * 2);
> + DBG("\ndir.name=%s, filename=%s, dir.attr=0x%x,"
> + "sum==checksum...continue",
> + dir.name, gbname, dir.attr);
> +
> + count++;
> +
> + if (hook && hook (gbname, &dir, closure))
> + break;
> +
> + continue;
> + }
> +
> + checksum = -1;
> + }
> +
> + //后面的处理针对非真实长名和真实短名
> + /* Convert the 8.3 file name. */
> + //去掉短名的空格,全改为小写
> + filep = filename;
> + if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
> + {
> + DBG("VOLUME");
> + for (i = 0; i < sizeof (dir.name) && dir.name[i]
> + && ! grub_isspace (dir.name[i]); i++)
> + *filep++ = dir.name[i];
> + }
> + else
> + {
> + for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
> + *filep++ = grub_tolower (dir.name[i]);
> +
> + *filep = '.';
> +
> + for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
> + *++filep = grub_tolower (dir.name[i]);
> +
> + if (*filep != '.')
> + filep++;
> + }
> + *filep = '\0';
> +
> + //for (i = 0; i < sizeof (dir.name); i++)
> + // DBG("0x%x ", dir.name[i]);
> + DBG("\ndir.name=%s, filename=【%s】, dir.attr=0x%x,"
> + "...next while",
> + dir.name, filename, dir.attr);
> + count++;
> + /*if(strcmp(filename, ".") && strcmp(filename, ".."))
> + {
> + DBG("{==============>");
> + struct grub_fat_data *data2 = NULL;
> + data2 = (struct grub_fat_data*)malloc(sizeof(*data));
> + memcpy(data2, data, sizeof(*data));
> + data2->attr = dir.attr;
> + data2->file_size = grub_le_to_cpu32 (dir.file_size);
> + data2->file_cluster = ((grub_le_to_cpu16 (dir.first_cluster_high) << 16)
> + | grub_le_to_cpu16 (dir.first_cluster_low));
> + data2->cur_cluster_num = ~0U;
> + (grub_fat_iterate_dir(bs, data2, NULL, NULL) < 0) ? DBG("error !!!!!!")
> : 0;
> + free(data2);
> + DBG("<===================}");
> + }
> + */
> + if (hook && hook (filename, &dir, closure))
> + break;
> + }
> +
> + free(gbname);
> + free (filename);
> + free (unibuf);
> +
> + return 0;
> +}
> +
> +
> +
> +//传给grub_fat_find_hook的参数closure
> +struct grub_fat_find_dir_closure
> +{
> + struct grub_fat_data *data;
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure);
> + void *closure;
> + char *dirname;
> + int call_hook;
> + int found;
> +};
> +
> +
> +static int
> +grub_fat_find_dir_hook (const char *filename, struct grub_fat_dir_entry
> *dir,
> + void *closure)
> +{
> + struct grub_fat_find_dir_closure *c = closure;
> + struct grub_dirhook_info info;
> + memset (&info, 0, sizeof (info));
> +
> + info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
> + info.case_insensitive = 1;
> + info.mtimeset = (dir->c_date || dir->c_time);
> + info.mtime = (((grub_uint32_t)dir->c_date << 16) | (dir->c_time));
> + info.filesize = dir->file_size;
> +
> + DBG("target file 【%s】======", c->dirname);
> + if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
> + {
> + DBG("volume id , ignore======");
> + return 0;
> + }
> +
> + if (*(c->dirname) == '\0' && (c->call_hook))
> + { //打开的是目录 /x/path1/path2/
> + //返回0,让iterate时只是打印信息,而不退出while
> + c->found = 1;
> + if(!(c->data->attr & GRUB_FAT_ATTR_DIRECTORY))
> + {
> + printf("it's not a directory!\n");
> + }
> + DBG("list the dir 【%s】===========",
> + ((struct ls_ctrl*)c->closure)->dirname);
> + return c->hook (filename, &info, c->closure);
> + }
> +
> +
> + if (grub_strcasecmp (c->dirname, filename) == 0)
> + { //打开的是文件 /x/path1/file
> + DBG("found======");
> + struct grub_fat_data *data = c->data;
> +
> + c->found = 1;
> + data->attr = dir->attr;
> + data->file_size = grub_le_to_cpu32 (dir->file_size);
> + data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) <<
> 16)
> + | grub_le_to_cpu16 (dir->first_cluster_low));
> + data->cur_cluster_num = ~0U;
> +
> + if (c->call_hook)
> + c->hook (filename, &info, c->closure);
> +
> + return 1;
> + }
> + else
> + {
> + DBG("not match======");
> + }
> + return 0;
> +}
> +
> +
> +/* Find the underlying directory or file in PATH and return the
> + next path. If there is no next path or an error occurs, return NULL.
> + If HOOK is specified, call it with each file name. */
> +//在由data指定的目录下查找由path路径指定的文件夹或文件
> +//找到之后交由 grub_fat_find_dir_hook函数处理,其中closure参数是关键
> +char *
> +grub_fat_find_dir (BlockDriverState *bs, struct grub_fat_data *data,
> + const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure),
> + void *closure)
> +{
> + char *dirname, *dirp;
> + struct grub_fat_find_dir_closure c;
> + DBG("to search [%s]...in data->attr=0x%x", path, data->attr);
> + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
> + {
> + printf("not a directory...........\n");
> + return 0;
> + }
> +
> + /* Extract a directory name. */
> + while (*path == '/')
> + path++;
> +
> + dirp = grub_strchr (path, '/');
> + if (dirp)
> + {
> + unsigned len = dirp - path;
> +
> + dirname = (char*)malloc (len + 1);
> + if (! dirname)
> + return 0;
> +
> + memcpy (dirname, path, len);
> + dirname[len] = '\0';
> + }
> + else
> + {
> + /* This is actually a file. */
> + dirname = grub_strdup (path);
> + }
> + DBG("searching \"%s\"======", dirname);
> + c.data = data;
> + c.hook = hook;
> + c.closure = closure;
> + c.dirname =dirname;
> + c.found = 0;
> + c.call_hook = (! dirp && hook); //针对目录的hook
> +
> + int ret = grub_fat_iterate_dir (bs, data, grub_fat_find_dir_hook, &c);
> + if(0 == ret && !c.found)
> + {
> + g_err = GRUB_ERR_NOT_FOUND;
> + printf("file not found..\n");
> + }
> + else if(ret < 0)
> + {
> + g_err = GRUB_ERR_UNKNOWN;
> + printf("iterate error!\n");
> + }
> +
> +
> + free (dirname);
> +
> + return (c.found && 0==ret) ? dirp : 0;
> +}
> +
> +
> +
> +
> +
> +grub_err_t
> +grub_fat_open (grub_file_t file, const char *name)
> +{
> + struct grub_fat_data *data = 0;
> + char *p = (char *) name;
> +
> +
> + data = grub_fat_mount (file->bs, file->part_off_sector);
> + if (! data)
> + {
> + printf("[%s]: mount error!\n", name);
> + goto fail;
> + }
> +
> + int i = 0;
> + do
> + {
> + p = grub_fat_find_dir (file->bs, data, p, 0, 0);
> + DBG("%d cycle past【path=%s】.......", i+1, p);
> + //error judge......
> + }
> + while (p);
> +
> + DBG("exit while======");
> +
> + if ((GRUB_ERR_NONE == g_err)
> + && (data->attr & GRUB_FAT_ATTR_DIRECTORY))
> + {
> + printf ("[%s]: not a file!\n", name);
> + goto fail;
> + }
> +
> + if(GRUB_ERR_NONE == g_err)
> + {
> + DBG("found======");
> + }
> + else
> + {
> + printf("not found or error!\n");
> + goto fail;
> + }
> +
> + DBG("11111111111111111111111");
> + file->data = data;
> + file->size = data->file_size;
> + return 0;
> +
> + fail:
> + free(data);
> + file->data = NULL;
> + DBG("2222222222222222222222");
> + return 1;
> +}
> +
> +
> +#define TIME_BIT 0xFFFF
> +#define TIME_HOUR_BIT 0xF800
> +#define TIME_MINUTE_BIT 0x07E0
> +#define TIME_SECOND_BIT 0x001F
> +#define DATE_BIT 0xFFFF0000
> +#define DATE_YEAR_BIT 0xFE00
> +#define DATE_MONTH_BIT 0x01E0
> +#define DATE_DAY_BIT 0x001F
> +static int find_then_ls_hook(const char *filename,
> + const struct grub_dirhook_info *info, void *closure)
> +{
> + struct ls_ctrl* ctrl = (struct ls_ctrl*)closure;
> + DBG("detail=%d", ctrl->detail);
> + printf("%s", filename);
> + if(!ctrl->detail)
> + {
> + printf("\n");
> + return 0;
> + }
> + else
> + {
> + printf("\t");
> + }
> +
> +
> + printf("%ubytes\t", (info->filesize));
> + printf("%s\t", (info->dir ? "dir" : "file"));
> + grub_uint16_t time = ((info->mtime) & TIME_BIT);
> + grub_uint16_t date = ((info->mtime) & DATE_BIT) >> 16;
> +
> + printf("%04d/%02d/%02d\t",
> + ((date & DATE_YEAR_BIT) >> 9) + 1980,
> + (date & DATE_MONTH_BIT) >> 5,
> + (date & DATE_DAY_BIT));
> + printf("%02d:%02d:%02d\n",
> + (time & TIME_HOUR_BIT) >> 11,
> + (time & TIME_MINUTE_BIT) >> 5,
> + time & TIME_SECOND_BIT) * 2;
> +
> + return 0; // 最终返回给iterate
> +}
> +
> +
> +grub_err_t
> +grub_fat_ls (grub_file_t file, const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info, void *closure),
> + void *closure)
> +{
> + struct grub_fat_data *data = 0;
> + grub_size_t len;
> + char *dirname = 0;
> + char *p;
> +
> + data = grub_fat_mount (file->bs, file->part_off_sector);
> + if (! data)
> + goto fail;
> +
> + file->data = data;
> + /* Make sure that DIRNAME terminates with '/'. */
> + len = strlen(path);
> + dirname = (char*)malloc (len + 1 + 1);
> + if (! dirname)
> + goto fail;
> + memcpy (dirname, path, len);
> + p = dirname + len;
> + if (path[len - 1] != '/')
> + *p++ = '/';
> + *p = '\0';
> + p = dirname;
> +
> + do
> + {
> + p = grub_fat_find_dir (file->bs, data, p, find_then_ls_hook,
> closure);
> + }
> + while (p && g_err == GRUB_ERR_NONE);
> +
> +
> +
> + fail:
> +
> + free (dirname);
> + free (data); file->data = NULL;
> +
> + return g_err;
> +}
> +
> +
> +grub_err_t grub_fat_close(grub_file_t file)
> +{
> + free(file->data);
> + return g_err;
> +}
> +
> +
> +grub_ssize_t grub_fat_read(grub_file_t file, grub_off_t offset,
> + grub_size_t len, char *buf)
> +{
> + return grub_fat_read_data(file->bs, file->data, NULL, NULL, offset, len,
> buf);
> +}
> +
> +
> +
> +
> +
> +
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fat.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/fat.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fat.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fat.h 2012-12-28 16:02:41.002938019
> +0800
> @@ -0,0 +1,160 @@
> +#ifndef FS_FAT_H
> +#define FS_FAT_H
> +
> +
> +#include "fs-types.h"
> +#include "block_int.h"
> +#include "fs-comm.h"
> +#include "grub_err.h"
> +
> +
> +#define GRUB_DISK_SECTOR_BITS 9
> +#define GRUB_FAT_DIR_ENTRY_SIZE 32
> +
> +#define GRUB_FAT_ATTR_READ_ONLY 0x01
> +#define GRUB_FAT_ATTR_HIDDEN 0x02
> +#define GRUB_FAT_ATTR_SYSTEM 0x04
> +#define GRUB_FAT_ATTR_VOLUME_ID 0x08
> +#define GRUB_FAT_ATTR_DIRECTORY 0x10
> +#define GRUB_FAT_ATTR_ARCHIVE 0x20
> +
> +#define GRUB_FAT_MAXFILE 256
> +
> +#define GRUB_FAT_ATTR_LONG_NAME (GRUB_FAT_ATTR_READ_ONLY \
> + | GRUB_FAT_ATTR_HIDDEN \
> + | GRUB_FAT_ATTR_SYSTEM \
> + | GRUB_FAT_ATTR_VOLUME_ID)
> +#define GRUB_FAT_ATTR_VALID (GRUB_FAT_ATTR_READ_ONLY \
> + | GRUB_FAT_ATTR_HIDDEN \
> + | GRUB_FAT_ATTR_SYSTEM \
> + | GRUB_FAT_ATTR_DIRECTORY \
> + | GRUB_FAT_ATTR_ARCHIVE \
> + | GRUB_FAT_ATTR_VOLUME_ID)
> +
> +struct grub_fat_bpb
> +{
> + grub_uint8_t jmp_boot[3];
> + grub_uint8_t oem_name[8];
> + grub_uint16_t bytes_per_sector;
> + grub_uint8_t sectors_per_cluster;
> + grub_uint16_t num_reserved_sectors;
> + grub_uint8_t num_fats;
> + grub_uint16_t num_root_entries;
> + grub_uint16_t num_total_sectors_16;
> + grub_uint8_t media;
> + grub_uint16_t sectors_per_fat_16;
> + grub_uint16_t sectors_per_track;
> + grub_uint16_t num_heads;
> + grub_uint32_t num_hidden_sectors;
> + grub_uint32_t num_total_sectors_32;
> + union
> + {
> + struct
> + {
> + grub_uint8_t num_ph_drive;
> + grub_uint8_t reserved;
> + grub_uint8_t boot_sig;
> + grub_uint32_t num_serial;
> + grub_uint8_t label[11];
> + grub_uint8_t fstype[8];
> + } __attribute__ ((packed)) fat12_or_fat16;
> + struct
> + {
> + grub_uint32_t sectors_per_fat_32;
> + grub_uint16_t extended_flags;
> + grub_uint16_t fs_version;
> + grub_uint32_t root_cluster;
> + grub_uint16_t fs_info;
> + grub_uint16_t backup_boot_sector;
> + grub_uint8_t reserved[12];
> + grub_uint8_t num_ph_drive;
> + grub_uint8_t reserved1;
> + grub_uint8_t boot_sig;
> + grub_uint32_t num_serial;
> + grub_uint8_t label[11];
> + grub_uint8_t fstype[8];
> + } __attribute__ ((packed)) fat32;
> + } __attribute__ ((packed)) version_specific;
> +} __attribute__ ((packed));
> +
> +struct grub_fat_dir_entry
> +{
> + grub_uint8_t name[11];
> + grub_uint8_t attr;
> + grub_uint8_t nt_reserved;
> + grub_uint8_t c_time_tenth;
> + grub_uint16_t c_time;
> + grub_uint16_t c_date;
> + grub_uint16_t a_date;
> + grub_uint16_t first_cluster_high;
> + grub_uint16_t w_time;
> + grub_uint16_t w_date;
> + grub_uint16_t first_cluster_low;
> + grub_uint32_t file_size;
> +} __attribute__ ((packed));
> +
> +struct grub_fat_long_name_entry
> +{
> + grub_uint8_t id;
> + grub_uint16_t name1[5];
> + grub_uint8_t attr;
> + grub_uint8_t reserved;
> + grub_uint8_t checksum;
> + grub_uint16_t name2[6];
> + grub_uint16_t first_cluster;
> + grub_uint16_t name3[2];
> +} __attribute__ ((packed));
> +
> +struct grub_fat_data
> +{
> + int logical_sector_bits;
> + grub_uint32_t num_sectors;
> +
> + grub_uint32_t fat_sector;
> + grub_uint32_t sectors_per_fat;
> + int fat_size;
> +
> + grub_uint32_t root_cluster;
> + grub_uint32_t root_sector;
> + grub_uint32_t num_root_sectors;
> +
> + int cluster_bits;
> + grub_uint32_t cluster_eof_mark;
> + grub_uint32_t cluster_sector;
> + grub_uint32_t num_clusters;
> +
> + grub_uint8_t attr;
> + grub_ssize_t file_size;
> + grub_uint32_t file_cluster;
> + grub_uint32_t cur_cluster_num;
> + grub_uint32_t cur_cluster;
> +
> + grub_uint32_t uuid;
> +};
> +
> +
> +
> +
> +
> +
> +
> +struct grub_fat_data*
> +grub_fat_mount (BlockDriverState *bs, grub_uint32_t part_off_sector);
> +
> +grub_err_t
> +grub_fat_open (grub_file_t file, const char *name);
> +
> +grub_err_t
> +grub_fat_ls (grub_file_t file, const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure),
> + void *closure);
> +
> +grub_err_t grub_fat_close(grub_file_t file);
> +
> +grub_ssize_t grub_fat_read(grub_file_t file, grub_off_t offset,
> + grub_size_t len, char *buf);
> +
> +
> +#endif
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fs-comm.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/fs-comm.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fs-comm.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fs-comm.h 2012-12-28 16:02:41.003846897
> +0800
> @@ -0,0 +1,60 @@
> +#ifndef _FS_COMM_H
> +#define _FS_COMM_H
> +
> +#include "fs-types.h"
> +#include "block_int.h"
> +#include "grub_err.h"
> +#include "debug.h"
> +
> +typedef struct grub_file
> +{
> + void *data;
> + BlockDriverState *bs;
> + uint32_t part_off_sector;
> + grub_size_t size;
> + grub_off_t offset;
> + /* This is called when a sector is read. Used only for a disk device. */
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset, unsigned length, void *closure);
> + void *closure;
> +}*grub_file_t;
> +
> +struct grub_dirhook_info
> +{
> + unsigned dir:1;
> + unsigned mtimeset:1;
> + unsigned case_insensitive:1;
> + grub_uint32_t mtime; //(date | time)
> + grub_uint32_t filesize;
> + grub_uint64_t filesize_ntfs;
> + grub_uint64_t time_ntfs;
> +};
> +
> +struct ls_ctrl
> +{
> + unsigned detail:1;
> + char* dirname;
> +};
> +
> +
> +
> +
> +typedef grub_err_t
> +(*grub_open) (grub_file_t file, const char *name);
> +
> +typedef grub_err_t
> +(*grub_ls) (grub_file_t file, const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure),
> + void *closure);
> +
> +typedef grub_err_t
> +(*grub_close) (grub_file_t file);
> +
> +typedef grub_ssize_t
> +(*grub_read)(grub_file_t file, grub_off_t offset,
> + grub_size_t len, char *buf);
> +
> +
> +#endif
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fshelp.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/fshelp.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fshelp.c 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fshelp.c 2012-12-28 16:02:41.004932457
> +0800
> @@ -0,0 +1,362 @@
> +/* fshelp.c -- Filesystem helper functions */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "err.h"
> +#include "misc.h"
> +#include "block_int.h"
> +#include "fshelp.h"
> +#include "ntfs.h"
> +#include "debug.h"
> +
> +struct grub_fshelp_find_file_closure
> +{
> + grub_fshelp_node_t rootnode;
> + int (*iterate_dir) (grub_fshelp_node_t dir,
> + int (*hook)
> + (const char *filename,
> + enum grub_fshelp_filetype filetype,
> + grub_fshelp_node_t node, void *closure),
> + void *closure);
> + void *closure;
> + char *(*read_symlink) (grub_fshelp_node_t node);
> + int symlinknest;
> + enum grub_fshelp_filetype foundtype;
> + grub_fshelp_node_t currroot;
> +};
> +
> +static void
> +free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_closure
> *c)
> +{
> + if (node != c->rootnode && node != c->currroot)
> + grub_free (node);
> +}
> +
> +struct find_file_closure
> +{
> + char *name;
> + enum grub_fshelp_filetype *type;
> + grub_fshelp_node_t *oldnode;
> + grub_fshelp_node_t *currnode;
> +};
> +
> +static int
> +iterate (const char *filename,
> + enum grub_fshelp_filetype filetype,
> + grub_fshelp_node_t node,
> + void *closure)
> +{
> + struct find_file_closure *c = closure;
> + DBG("list_file hooked by fshelp:iterate(), filename=%s", filename);
> + if (filetype == GRUB_FSHELP_UNKNOWN ||
> + (grub_strcmp (c->name, filename) &&
> + (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) ||
> + grub_strncasecmp (c->name, filename, GRUB_LONG_MAX))))
> + {
> + DBG("not match!!!>>>>>>");
> + grub_free (node);
> + return 0;
> + }
> +
> + /* The node is found, stop iterating over the nodes. */
> + *(c->type) = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
> + *(c->oldnode) = *(c->currnode);
> + *(c->currnode) = node;
> + DBG("found!!>>>>>>");
> + return 1;
> +}
> +
> +static grub_err_t
> +find_file (const char *currpath, grub_fshelp_node_t currroot,
> + grub_fshelp_node_t *currfound,
> + struct grub_fshelp_find_file_closure *c)
> +{
> + char fpath[grub_strlen (currpath) + 1];
> + char *name = fpath;
> + char *next;
> + enum grub_fshelp_filetype type = GRUB_FSHELP_DIR;
> + grub_fshelp_node_t currnode = currroot;
> + grub_fshelp_node_t oldnode = currroot;
> +
> + c->currroot = currroot;
> +
> + grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1);
> +
> + /* Remove all leading slashes. */
> + while (*name == '/')
> + name++;
> +
> + if (! *name)
> + {
> + *currfound = currnode;
> + return 0;
> + }
> +
> + for (;;)
> + {
> + int found;
> + struct find_file_closure cc;
> +
> + /* Extract the actual part from the pathname. */
> + next = grub_strchr (name, '/');
> + if (next)
> + {
> + /* Remove all leading slashes. */
> + while (*next == '/')
> + *(next++) = '\0';
> + }
> +
> + /* At this point it is expected that the current node is a
> + directory, check if this is true. */
> + if (type != GRUB_FSHELP_DIR)
> + {
> + free_node (currnode, c);
> + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
> + }
> +
> + DBG("find_file_closure cc.name=【%s】", name);
> + cc.name = name;
> + cc.type = &type;
> + cc.oldnode = &oldnode;
> + cc.currnode = &currnode;
> + /* Iterate over the directory. */
> + DBG("******fshelp:find_file hooked by \'grub_ntfs_iterate_dir\',"
> + "nested another hook \'fshelp:iterator\'");
> + found = c->iterate_dir (currnode, iterate, &cc);
> + if (! found)
> + {
> + if (grub_errno)
> + return grub_errno;
> +
> + break;
> + }
> +
> + /* Read in the symlink and follow it. */
> + if (type == GRUB_FSHELP_SYMLINK)
> + {
> + char *symlink;
> +
> + /* Test if the symlink does not loop. */
> + if (++(c->symlinknest) == 8)
> + {
> + free_node (currnode, c);
> + free_node (oldnode, c);
> + return grub_error (GRUB_ERR_SYMLINK_LOOP,
> + "too deep nesting of symlinks");
> + }
> +
> + symlink = c->read_symlink (currnode);
> + free_node (currnode, c);
> +
> + if (!symlink)
> + {
> + free_node (oldnode, c);
> + return grub_errno;
> + }
> +
> + /* The symlink is an absolute path, go back to the root inode. */
> + if (symlink[0] == '/')
> + {
> + free_node (oldnode, c);
> + oldnode = c->rootnode;
> + }
> +
> + /* Lookup the node the symlink points to. */
> + find_file (symlink, oldnode, &currnode, c);
> + type = c->foundtype;
> + grub_free (symlink);
> +
> + if (grub_errno)
> + {
> + free_node (oldnode, c);
> + return grub_errno;
> + }
> + }
> +
> + free_node (oldnode, c);
> +
> + /* Found the node! */
> + if (! next || *next == '\0')
> + {
> + *currfound = currnode;
> + c->foundtype = type;
> + return 0;
> + }
> +
> + name = next;
> + }
> +
> + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
> +}
> +
> +/* Lookup the node PATH. The node ROOTNODE describes the root of the
> + directory tree. The node found is returned in FOUNDNODE, which is
> + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
> + iterate over all directory entries in the current node.
> + READ_SYMLINK is used to read the symlink if a node is a symlink.
> + EXPECTTYPE is the type node that is expected by the called, an
> + error is generated if the node is not of the expected type. Make
> + sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
> + because GCC has a nasty bug when using regparm=3. */
> +grub_err_t
> +grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
> + grub_fshelp_node_t *foundnode,
> + int (*iterate_dir) (grub_fshelp_node_t dir,
> + int (*hook)
> + (const char *filename,
> + enum grub_fshelp_filetype filetype,
> + grub_fshelp_node_t node,
> + void *closure),
> + void *closure),
> + void *closure,
> + char *(*read_symlink) (grub_fshelp_node_t node),
> + enum grub_fshelp_filetype expecttype)
> +{
> + grub_err_t err;
> + struct grub_fshelp_find_file_closure c;
> +
> + c.rootnode = rootnode;
> + c.iterate_dir = iterate_dir;
> + c.closure = closure;
> + c.read_symlink = read_symlink;
> + c.symlinknest = 0;
> + c.foundtype = GRUB_FSHELP_DIR;
> +
> + if (!path || path[0] != '/')
> + {
> + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
> + return grub_errno;
> + }
> +
> +
> + DBG("going to find_file\n");
> + err = find_file (path, rootnode, foundnode, &c);
> + if (err)
> + return err;
> +
> + /* Check if the node that was found was of the expected type. */
> + if (expecttype == GRUB_FSHELP_REG && c.foundtype != expecttype)
> + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
> + else if (expecttype == GRUB_FSHELP_DIR && c.foundtype != expecttype)
> + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
> +
> + return 0;
> +}
> +
> +/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
> + beginning with the block POS. READ_HOOK should be set before
> + reading a block from the file. GET_BLOCK is used to translate file
> + blocks to disk blocks. The file is FILESIZE bytes big and the
> + blocks have a size of LOG2BLOCKSIZE (in log2). */
> +grub_ssize_t
> +grub_fshelp_read_file (BlockDriverState* bs, grub_fshelp_node_t node,
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset,
> + unsigned length,
> + void *closure),
> + void *closure,
> + grub_off_t pos, grub_size_t len, char *buf,
> + grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
> + grub_disk_addr_t block),
> + grub_off_t filesize, int log2blocksize)
> +{
> + grub_disk_addr_t i, blockcnt;
> + grub_off_t off_bytes;
> + int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS);
> +
> + /* Adjust LEN so it we can't read past the end of the file. */
> + if (pos + len > filesize)
> + len = filesize - pos;
> +
> + blockcnt = ((len + pos) + blocksize - 1) >>
> + (log2blocksize + GRUB_DISK_SECTOR_BITS);
> +
> + for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt;
> i++)
> + {
> + grub_disk_addr_t blknr;
> + int blockoff = pos & (blocksize - 1);
> + int blockend = blocksize;
> +
> + int skipfirst = 0;
> +
> + blknr = get_block (node, i);
> + if (grub_errno)
> + return -1;
> +
> + blknr = blknr << log2blocksize;
> + off_bytes = blknr << GRUB_DISK_SECTOR_BITS;
> +
> + /* Last block. */
> + if (i == blockcnt - 1)
> + {
> + blockend = (len + pos) & (blocksize - 1);
> +
> + /* The last portion is exactly blocksize. */
> + if (! blockend)
> + blockend = blocksize;
> + }
> +
> + /* First block. */
> + if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS)))
> + {
> + skipfirst = blockoff;
> + blockend -= skipfirst;
> + }
> +
> + /* If the block number is 0 this block is not stored on disk but
> + is zero filled instead. */
> + if (blknr)
> + {
> + //bs->read_hook = read_hook;
> + //bs->closure = closure;
> +
> + bdrv_pread_from_lcn_of_volum(bs, off_bytes + skipfirst,
> + buf, blockend);
> + //bs->read_hook = 0;
> + if (grub_errno)
> + return -1;
> + }
> + else
> + grub_memset (buf, 0, blockend);
> +
> + buf += blocksize - skipfirst;
> + }
> +
> + return len;
> +}
> +
> +unsigned int
> +grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow)
> +{
> + int mod;
> +
> + *pow = 0;
> + while (blksize > 1)
> + {
> + mod = blksize - ((blksize >> 1) << 1);
> + blksize >>= 1;
> +
> + /* Check if it really is a power of two. */
> + if (mod)
> + return grub_error (GRUB_ERR_BAD_NUMBER,
> + "the blocksize is not a power of two");
> + (*pow)++;
> + }
> +
> + return GRUB_ERR_NONE;
> +}
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fshelp.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/fshelp.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fshelp.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fshelp.h 2012-12-28 16:02:41.004932457
> +0800
> @@ -0,0 +1,86 @@
> +/* fshelp.h -- Filesystem helper functions */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_FSHELP_HEADER
> +#define GRUB_FSHELP_HEADER 1
> +
> +#include "fs-types.h"
> +#include "grub_err.h"
> +#include "block_int.h"
> +typedef struct grub_fshelp_node *grub_fshelp_node_t;
> +
> +#define GRUB_FSHELP_CASE_INSENSITIVE 0x100
> +#define GRUB_FSHELP_TYPE_MASK 0xff
> +#define GRUB_FSHELP_FLAGS_MASK 0x100
> +
> +enum grub_fshelp_filetype
> + {
> + GRUB_FSHELP_UNKNOWN,
> + GRUB_FSHELP_REG,
> + GRUB_FSHELP_DIR,
> + GRUB_FSHELP_SYMLINK
> + };
> +
> +/* Lookup the node PATH. The node ROOTNODE describes the root of the
> + directory tree. The node found is returned in FOUNDNODE, which is
> + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
> + iterate over all directory entries in the current node.
> + READ_SYMLINK is used to read the symlink if a node is a symlink.
> + EXPECTTYPE is the type node that is expected by the called, an
> + error is generated if the node is not of the expected type. Make
> + sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
> + because GCC has a nasty bug when using regparm=3. */
> +grub_err_t grub_fshelp_find_file (const char *path,
> + grub_fshelp_node_t rootnode,
> + grub_fshelp_node_t *foundnode,
> + int (*iterate_dir)
> + (grub_fshelp_node_t dir,
> + int (*hook)
> + (const char *filename,
> + enum grub_fshelp_filetype filetype,
> + grub_fshelp_node_t node,
> + void *closure),
> + void *closure),
> + void *closure,
> + char *(*read_symlink) (grub_fshelp_node_t node),
> + enum grub_fshelp_filetype expect);
> +
> +
> +/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
> + beginning with the block POS. READ_HOOK should be set before
> + reading a block from the file. GET_BLOCK is used to translate file
> + blocks to disk blocks. The file is FILESIZE bytes big and the
> + blocks have a size of LOG2BLOCKSIZE (in log2). */
> +grub_ssize_t grub_fshelp_read_file (BlockDriverState* bs,
> grub_fshelp_node_t node,
> + void (*read_hook)
> + (grub_disk_addr_t sector,
> + unsigned offset,
> + unsigned length,
> + void *closure),
> + void *closure,
> + grub_off_t pos, grub_size_t len, char *buf,
> + grub_disk_addr_t (*get_block)
> + (grub_fshelp_node_t node,
> + grub_disk_addr_t block),
> + grub_off_t filesize, int log2blocksize);
> +
> +unsigned int grub_fshelp_log2blksize (unsigned int blksize,
> + unsigned int *pow);
> +
> +#endif /* ! GRUB_FSHELP_HEADER */
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fs-time.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/fs-time.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fs-time.c 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fs-time.c 2012-12-28 16:02:41.005685798
> +0800
> @@ -0,0 +1,77 @@
> +#include "fs-time.h"
> +
> +
> +
> +static uint64_t div64(uint64_t a, uint32_t b, uint32_t c)
> +{
> + union {
> + uint64_t ll;
> + struct {
> +#ifdef WORDS_BIGENDIAN
> + uint32_t high, low;
> +#else
> + uint32_t low, high;
> +#endif
> + } l;
> + } u, res;
> + uint64_t rl, rh;
> +
> + u.ll = a;
> + rl = (uint64_t)u.l.low * (uint64_t)b;
> + rh = (uint64_t)u.l.high * (uint64_t)b;
> + rh += (rl >> 32);
> + res.l.high = rh / c;
> + res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
> + return res.ll;
> +}
> +
> +static uint64_t sub64(uint64_t a, uint64_t b)
> +{
> + struct
> + {
> +#ifdef WORDS_BIGENDIAN
> + uint32_t high, low;
> +#else
> + uint32_t low, high;
> +#endif
> + }a1,b1,c;
> +
> + a1.high = a>>32;
> + a1.low = a&0xffffffff;
> + b1.high = b>>32;
> + b1.low = b&0xffffffff;
> +
> + if(a1.high < b1.high)
> + {
> + c=b1;
> + b1=a1;
> + a1=c;
> + }
> +
> + a1.high -= b1.high;
> + a1.low -= b1.low;
> + if(a1.low & 0x80000000)
> + {
> + a1.low = (~(a1.low & 0x7fffffff))+1;
> + a1.high -= 1;
> + }
> +
> + uint64_t ret = (uint64_t)a1.high<<32 | a1.low;
> + return ret;
> +}
> +
> +struct tm* ntfs_utc2local(grub_uint64_t time, struct tm* ptm)
> +{
> + //time_t time2 = sub64(time, NTFS_TIME_OFFSET);
> + time_t time2 = time - NTFS_TIME_OFFSET;
> + /*DBG("sizeof(int)=%d", sizeof(int));
> + DBG("sizeof(short)=%d", sizeof(short));
> + DBG("sizeof(long)=%d", sizeof(long));
> + DBG("sizeof(long long)=%d", sizeof(unsigned long long));
> + DBG("sizeof(time_t)=%d, time=%zu, time2=%zu", sizeof(time_t), time,
> time2);*/
> + //time2 = div64(time2,1,10000000);
> + time2 = time2 / 10000000;
> + DBG("sizeof(time_t)=%d, time=%zu, time2=%zu", sizeof(time_t), time,
> time2);
> + ////time2 = 0;//time(NULL);
> + return localtime_r(&time2, ptm);
> +}
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fs-time.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/fs-time.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fs-time.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fs-time.h 2012-12-28 16:02:41.005685798
> +0800
> @@ -0,0 +1,12 @@
> +#ifndef FS_TIME_H
> +#define FS_TIME_H
> +
> +#include <time.h>
> +#include "fs-comm.h"
> +#define NTFS_TIME_OFFSET ((grub_uint64_t)(369 * 365 + 89) * 24 * 3600 *
> 10000000)
> +
> +struct tm* ntfs_utc2local(grub_uint64_t time, struct tm* ptm);
> +
> +
> +#endif
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fs-types.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/fs-types.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/fs-types.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/fs-types.h 2012-12-28
> 16:02:41.006932417 +0800
> @@ -0,0 +1,234 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2005,2006,2007,2008,2009 Free Software Foundation,
> Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TYPES_HEADER
> +#define GRUB_TYPES_HEADER 1
> +
> +#include "grub-config.h"
> +#include "x86_64/types.h"
> +
> +#ifdef GRUB_UTIL
> +# define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P
> +# define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG
> +# ifdef WORDS_BIGENDIAN
> +# define GRUB_CPU_WORDS_BIGENDIAN 1
> +# else
> +# undef GRUB_CPU_WORDS_BIGENDIAN
> +# endif
> +#else /* ! GRUB_UTIL */
> +# define GRUB_CPU_SIZEOF_VOID_P GRUB_TARGET_SIZEOF_VOID_P
> +# define GRUB_CPU_SIZEOF_LONG GRUB_TARGET_SIZEOF_LONG
> +# ifdef GRUB_TARGET_WORDS_BIGENDIAN
> +# define GRUB_CPU_WORDS_BIGENDIAN 1
> +# else
> +# undef GRUB_CPU_WORDS_BIGENDIAN
> +# endif
> +#endif /* ! GRUB_UTIL */
> +
> +#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8
> +# error "This architecture is not supported because sizeof(void *) != 4 and
> sizeof(void *) != 8"
> +#endif
> +
> +#ifndef GRUB_TARGET_WORDSIZE
> +# if GRUB_TARGET_SIZEOF_VOID_P == 4
> +# define GRUB_TARGET_WORDSIZE 32
> +# elif GRUB_TARGET_SIZEOF_VOID_P == 8
> +# define GRUB_TARGET_WORDSIZE 64
> +# endif
> +#endif
> +
> +/* Define various wide integers. */
> +typedef signed char grub_int8_t;
> +typedef short grub_int16_t;
> +typedef int grub_int32_t;
> +#if GRUB_CPU_SIZEOF_LONG == 8
> +typedef long grub_int64_t;
> +#else
> +typedef long long grub_int64_t;
> +#endif
> +
> +typedef unsigned char grub_uint8_t;
> +typedef unsigned short grub_uint16_t;
> +typedef unsigned grub_uint32_t;
> +#if GRUB_CPU_SIZEOF_LONG == 8
> +typedef unsigned long grub_uint64_t;
> +#else
> +typedef unsigned long long grub_uint64_t;
> +#endif
> +
> +/* Misc types. */
> +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> +typedef grub_uint64_t grub_target_addr_t;
> +typedef grub_uint64_t grub_target_off_t;
> +typedef grub_uint64_t grub_target_size_t;
> +typedef grub_int64_t grub_target_ssize_t;
> +#else
> +typedef grub_uint32_t grub_target_addr_t;
> +typedef grub_uint32_t grub_target_off_t;
> +typedef grub_uint32_t grub_target_size_t;
> +typedef grub_int32_t grub_target_ssize_t;
> +#endif
> +
> +#if GRUB_CPU_SIZEOF_VOID_P == 8
> +typedef grub_uint64_t grub_addr_t;
> +typedef grub_uint64_t grub_size_t;
> +typedef grub_int64_t grub_ssize_t;
> +#else
> +typedef grub_uint32_t grub_addr_t;
> +typedef grub_uint32_t grub_size_t;
> +typedef grub_int32_t grub_ssize_t;
> +#endif
> +
> +#if GRUB_CPU_SIZEOF_VOID_P == 8
> +# define GRUB_ULONG_MAX 18446744073709551615UL
> +# define GRUB_LONG_MAX 9223372036854775807L
> +# define GRUB_LONG_MIN (-9223372036854775807L - 1)
> +#else
> +# define GRUB_ULONG_MAX 4294967295UL
> +# define GRUB_LONG_MAX 2147483647L
> +# define GRUB_LONG_MIN (-2147483647L - 1)
> +#endif
> +
> +#if GRUB_CPU_SIZEOF_VOID_P == 4
> +#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
> +#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
> +#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
> +#else
> +#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
> +#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
> +#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
> +#endif
> +
> +/* The type for representing a file offset. */
> +typedef grub_uint64_t grub_off_t;
> +
> +/* The type for representing a disk block address. */
> +typedef grub_uint64_t grub_disk_addr_t;
> +
> +/* Byte-orders. */
> +#define grub_swap_bytes16(x) \
> +({ \
> + grub_uint16_t _x = (x); \
> + (grub_uint16_t) ((_x << 8) | (_x >> 8)); \
> +})
> +
> +#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__
>>= 3) && defined(GRUB_TARGET_I386)
> +static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x)
> +{
> + return __builtin_bswap32(x);
> +}
> +
> +static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
> +{
> + return __builtin_bswap64(x);
> +}
> +#else /* not gcc 4.3 or newer */
> +#define grub_swap_bytes32(x) \
> +({ \
> + grub_uint32_t _x = (x); \
> + (grub_uint32_t) ((_x << 24) \
> + | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \
> + | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \
> + | (_x >> 24)); \
> +})
> +
> +#define grub_swap_bytes64(x) \
> +({ \
> + grub_uint64_t _x = (x); \
> + (grub_uint64_t) ((_x << 56) \
> + | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \
> + | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \
> + | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
> + | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \
> + | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \
> + | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \
> + | (_x >> 56)); \
> +})
> +#endif /* not gcc 4.3 or newer */
> +
> +#ifdef GRUB_CPU_WORDS_BIGENDIAN
> +# define grub_cpu_to_le16(x) grub_swap_bytes16(x)
> +# define grub_cpu_to_le32(x) grub_swap_bytes32(x)
> +# define grub_cpu_to_le64(x) grub_swap_bytes64(x)
> +# define grub_le_to_cpu16(x) grub_swap_bytes16(x)
> +# define grub_le_to_cpu32(x) grub_swap_bytes32(x)
> +# define grub_le_to_cpu64(x) grub_swap_bytes64(x)
> +# define grub_cpu_to_be16(x) ((grub_uint16_t) (x))
> +# define grub_cpu_to_be32(x) ((grub_uint32_t) (x))
> +# define grub_cpu_to_be64(x) ((grub_uint64_t) (x))
> +# define grub_be_to_cpu16(x) ((grub_uint16_t) (x))
> +# define grub_be_to_cpu32(x) ((grub_uint32_t) (x))
> +# define grub_be_to_cpu64(x) ((grub_uint64_t) (x))
> +# ifdef GRUB_TARGET_WORDS_BIGENDIAN
> +# define grub_target_to_host16(x) ((grub_uint16_t) (x))
> +# define grub_target_to_host32(x) ((grub_uint32_t) (x))
> +# define grub_target_to_host64(x) ((grub_uint64_t) (x))
> +# define grub_host_to_target16(x) ((grub_uint16_t) (x))
> +# define grub_host_to_target32(x) ((grub_uint32_t) (x))
> +# define grub_host_to_target64(x) ((grub_uint64_t) (x))
> +# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
> +# define grub_target_to_host16(x) grub_swap_bytes16(x)
> +# define grub_target_to_host32(x) grub_swap_bytes32(x)
> +# define grub_target_to_host64(x) grub_swap_bytes64(x)
> +# define grub_host_to_target16(x) grub_swap_bytes16(x)
> +# define grub_host_to_target32(x) grub_swap_bytes32(x)
> +# define grub_host_to_target64(x) grub_swap_bytes64(x)
> +# endif
> +#else /* ! WORDS_BIGENDIAN */
> +# define grub_cpu_to_le16(x) ((grub_uint16_t) (x))
> +# define grub_cpu_to_le32(x) ((grub_uint32_t) (x))
> +# define grub_cpu_to_le64(x) ((grub_uint64_t) (x))
> +# define grub_le_to_cpu16(x) ((grub_uint16_t) (x))
> +# define grub_le_to_cpu32(x) ((grub_uint32_t) (x))
> +# define grub_le_to_cpu64(x) ((grub_uint64_t) (x))
> +# define grub_cpu_to_be16(x) grub_swap_bytes16(x)
> +# define grub_cpu_to_be32(x) grub_swap_bytes32(x)
> +# define grub_cpu_to_be64(x) grub_swap_bytes64(x)
> +# define grub_be_to_cpu16(x) grub_swap_bytes16(x)
> +# define grub_be_to_cpu32(x) grub_swap_bytes32(x)
> +# define grub_be_to_cpu64(x) grub_swap_bytes64(x)
> +# ifdef GRUB_TARGET_WORDS_BIGENDIAN
> +# define grub_target_to_host16(x) grub_swap_bytes16(x)
> +# define grub_target_to_host32(x) grub_swap_bytes32(x)
> +# define grub_target_to_host64(x) grub_swap_bytes64(x)
> +# define grub_host_to_target16(x) grub_swap_bytes16(x)
> +# define grub_host_to_target32(x) grub_swap_bytes32(x)
> +# define grub_host_to_target64(x) grub_swap_bytes64(x)
> +# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
> +# define grub_target_to_host16(x) ((grub_uint16_t) (x))
> +# define grub_target_to_host32(x) ((grub_uint32_t) (x))
> +# define grub_target_to_host64(x) ((grub_uint64_t) (x))
> +# define grub_host_to_target16(x) ((grub_uint16_t) (x))
> +# define grub_host_to_target32(x) ((grub_uint32_t) (x))
> +# define grub_host_to_target64(x) ((grub_uint64_t) (x))
> +# endif
> +#endif /* ! WORDS_BIGENDIAN */
> +
> +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> +# define grub_host_to_target_addr(x) grub_host_to_target64(x)
> +#else
> +# define grub_host_to_target_addr(x) grub_host_to_target32(x)
> +#endif
> +
> +
> +
> +
> +
> +
> +
> +#endif /* ! GRUB_TYPES_HEADER */
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub-config.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-config.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-config.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-config.h 2012-12-28
> 16:02:41.006932417 +0800
> @@ -0,0 +1,251 @@
> +/* config.h. Generated from config.h.in by configure. */
> +/* config.h.in. Generated from configure.ac by autoheader. */
> +
> +/* Define it if GAS requires that absolute indirect calls/jumps are not
> + prefixed with an asterisk */
> +/* #undef ABSOLUTE_WITHOUT_ASTERISK */
> +
> +/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
> +#define ADDR32 addr32
> +
> +/* Define it to \"data32\" or \"data32;\" to make GAS happy */
> +#define DATA32 data32
> +
> +/* Define to 1 if translation of program messages to the user's native
> + language is requested. */
> +#define ENABLE_NLS 1
> +
> +/* Define if C symbols get an underscore after compilation */
> +/* #undef HAVE_ASM_USCORE */
> +
> +/* Define to 1 if you have the `asprintf' function. */
> +#define HAVE_ASPRINTF 1
> +
> +/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
> + CoreFoundation framework. */
> +/* #undef HAVE_CFLOCALECOPYCURRENT */
> +
> +/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue
> in
> + the CoreFoundation framework. */
> +/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
> +
> +/* Define to 1 if you have the <curses.h> header file. */
> +/* #undef HAVE_CURSES_H */
> +
> +/* Define if the GNU dcgettext() function is already present or
> preinstalled.
> + */
> +#define HAVE_DCGETTEXT 1
> +
> +/* Define to 1 if you have the <dirent.h> header file, and it defines
> `DIR'.
> + */
> +#define HAVE_DIRENT_H 1
> +
> +/* Define to 1 if you have the <ft2build.h> header file. */
> +#define HAVE_FT2BUILD_H 1
> +
> +/* Define to 1 if you have the `getgid' function. */
> +#define HAVE_GETGID 1
> +
> +/* Define if getrawpartition() in -lutil can be used */
> +/* #undef HAVE_GETRAWPARTITION */
> +
> +/* Define if the GNU gettext() function is already present or preinstalled.
> */
> +#define HAVE_GETTEXT 1
> +
> +/* Define to 1 if you have the `getuid' function. */
> +#define HAVE_GETUID 1
> +
> +/* Define if you have the iconv() function and it works. */
> +/* #undef HAVE_ICONV */
> +
> +/* Define to 1 if you have the <inttypes.h> header file. */
> +#define HAVE_INTTYPES_H 1
> +
> +/* Define to 1 if you have the <limits.h> header file. */
> +#define HAVE_LIMITS_H 1
> +
> +/* Define to 1 if you have the `lstat' function. */
> +#define HAVE_LSTAT 1
> +
> +/* Define to 1 if you have the <malloc.h> header file. */
> +#define HAVE_MALLOC_H 1
> +
> +/* Define to 1 if you have the `memalign' function. */
> +#define HAVE_MEMALIGN 1
> +
> +/* Define to 1 if you have the `memmove' function. */
> +#define HAVE_MEMMOVE 1
> +
> +/* Define to 1 if you have the <memory.h> header file. */
> +#define HAVE_MEMORY_H 1
> +
> +/* Define to 1 if you have the <ncurses/curses.h> header file. */
> +/* #undef HAVE_NCURSES_CURSES_H */
> +
> +/* Define to 1 if you have the <ncurses.h> header file. */
> +/* #undef HAVE_NCURSES_H */
> +
> +/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'.
> */
> +/* #undef HAVE_NDIR_H */
> +
> +/* Define if opendisk() in -lutil can be used */
> +/* #undef HAVE_OPENDISK */
> +
> +/* Define to 1 if you have the <pci/pci.h> header file. */
> +/* #undef HAVE_PCI_PCI_H */
> +
> +/* Define to 1 if you have the `posix_memalign' function. */
> +#define HAVE_POSIX_MEMALIGN 1
> +
> +/* Define if returns_twice attribute is supported */
> +/* #undef HAVE_RETURNS_TWICE */
> +
> +/* Define to 1 if you have the `sbrk' function. */
> +#define HAVE_SBRK 1
> +
> +/* Define to 1 if you have the <SDL/SDL.h> header file. */
> +/* #undef HAVE_SDL_SDL_H */
> +
> +/* Define to 1 if you have the <stdint.h> header file. */
> +#define HAVE_STDINT_H 1
> +
> +/* Define to 1 if you have the <stdlib.h> header file. */
> +#define HAVE_STDLIB_H 1
> +
> +/* Define to 1 if you have the `strdup' function. */
> +#define HAVE_STRDUP 1
> +
> +/* Define to 1 if you have the <strings.h> header file. */
> +#define HAVE_STRINGS_H 1
> +
> +/* Define to 1 if you have the <string.h> header file. */
> +#define HAVE_STRING_H 1
> +
> +/* Define to 1 if you have the <sys/dir.h> header file, and it defines
> `DIR'.
> + */
> +/* #undef HAVE_SYS_DIR_H */
> +
> +/* Define to 1 if you have the <sys/fcntl.h> header file. */
> +#define HAVE_SYS_FCNTL_H 1
> +
> +/* Define to 1 if you have the <sys/mkdev.h> header file. */
> +/* #undef HAVE_SYS_MKDEV_H */
> +
> +/* Define to 1 if you have the <sys/ndir.h> header file, and it defines
> `DIR'.
> + */
> +/* #undef HAVE_SYS_NDIR_H */
> +
> +/* Define to 1 if you have the <sys/stat.h> header file. */
> +#define HAVE_SYS_STAT_H 1
> +
> +/* Define to 1 if you have the <sys/sysmacros.h> header file. */
> +#define HAVE_SYS_SYSMACROS_H 1
> +
> +/* Define to 1 if you have the <sys/types.h> header file. */
> +#define HAVE_SYS_TYPES_H 1
> +
> +/* Define to 1 if you have the <termios.h> header file. */
> +#define HAVE_TERMIOS_H 1
> +
> +/* Define to 1 if you have the <unistd.h> header file. */
> +#define HAVE_UNISTD_H 1
> +
> +/* Define to 1 if you have the <usb.h> header file. */
> +/* #undef HAVE_USB_H */
> +
> +/* Define to 1 if you have the `vasprintf' function. */
> +#define HAVE_VASPRINTF 1
> +
> +/* Define to 1 if `major', `minor', and `makedev' are declared in
> <mkdev.h>.
> + */
> +/* #undef MAJOR_IN_MKDEV */
> +
> +/* Define to 1 if `major', `minor', and `makedev' are declared in
> + <sysmacros.h>. */
> +/* #undef MAJOR_IN_SYSMACROS */
> +
> +/* Define to 1 if you enable memory manager debugging. */
> +/* #undef MM_DEBUG */
> +
> +/* Define to 1 if GCC generates calls to __register_frame_info() */
> +/* #undef NEED_REGISTER_FRAME_INFO */
> +
> +/* Name of package */
> +#define PACKAGE "burg"
> +
> +/* Define to the address where bug reports for this package should be sent.
> */
> +#define PACKAGE_BUGREPORT "address@hidden"
> +
> +/* Define to the full name of this package. */
> +#define PACKAGE_NAME "BURG"
> +
> +/* Define to the full name and version of this package. */
> +#define PACKAGE_STRING "BURG 1.98"
> +
> +/* Define to the one symbol short name of this package. */
> +#define PACKAGE_TARNAME "burg"
> +
> +/* Define to the version of this package. */
> +#define PACKAGE_VERSION "1.98"
> +
> +/* The size of `long', as computed by sizeof. */
> +#define SIZEOF_LONG 8
> +
> +/* The size of `void *', as computed by sizeof. */
> +#define SIZEOF_VOID_P 8
> +
> +/* Define to 1 if you have the ANSI C header files. */
> +#define STDC_HEADERS 1
> +
> +/* Version number of package */
> +#define VERSION "1.98"
> +
> +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
> + significant byte first (like Motorola and SPARC, unlike Intel and VAX).
> */
> +#if defined __BIG_ENDIAN__
> +# define WORDS_BIGENDIAN 1
> +#elif ! defined __LITTLE_ENDIAN__
> +/* # undef WORDS_BIGENDIAN */
> +#endif
> +
> +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
> + `char[]'. */
> +#define YYTEXT_POINTER 1
> +
> +/* Number of bits in a file offset, on hosts where this is settable. */
> +/* #undef _FILE_OFFSET_BITS */
> +
> +/* Define for large files, on AIX-style hosts. */
> +/* #undef _LARGE_FILES */
> +
> +/* Define to 1 if on MINIX. */
> +/* #undef _MINIX */
> +
> +/* Define to 2 if the system does not provide POSIX.1 features except with
> + this defined. */
> +/* #undef _POSIX_1_SOURCE */
> +
> +/* Define to 1 if you need to in order for `stat' and other things to work.
> */
> +/* #undef _POSIX_SOURCE */
> +
> +/* Enable extensions on AIX 3, Interix. */
> +#ifndef _ALL_SOURCE
> +# define _ALL_SOURCE 1
> +#endif
> +/* Enable GNU extensions on systems that have them. */
> +#ifndef _GNU_SOURCE
> +# define _GNU_SOURCE 1
> +#endif
> +/* Enable threading extensions on Solaris. */
> +#ifndef _POSIX_PTHREAD_SEMANTICS
> +# define _POSIX_PTHREAD_SEMANTICS 1
> +#endif
> +/* Enable extensions on HP NonStop. */
> +#ifndef _TANDEM_SOURCE
> +# define _TANDEM_SOURCE 1
> +#endif
> +/* Enable general extensions on Solaris. */
> +#ifndef __EXTENSIONS__
> +# define __EXTENSIONS__ 1
> +#endif
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub_err.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub_err.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub_err.c 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub_err.c 2012-12-28
> 16:02:41.007734164 +0800
> @@ -0,0 +1,186 @@
> +/* err.c - error handling routines */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "grub_err.h"
> +#include "misc.h"
> +#include <stdarg.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +#define GRUB_MAX_ERRMSG 256
> +#define GRUB_ERROR_STACK_SIZE 10
> +
> +grub_err_t grub_errno;
> +char grub_errmsg[GRUB_MAX_ERRMSG];
> +
> +static struct
> +{
> + grub_err_t errno;
> + char errmsg[GRUB_MAX_ERRMSG];
> +} grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
> +
> +static int grub_error_stack_pos;
> +static int grub_error_stack_assert;
> +
> +
> +
> +static int
> +grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
> +{
> + grub_size_t ret;
> +
> + if (!n)
> + return 0;
> +
> +
> + ret = vsnprintf(str, n, fmt, ap);
> + printf("%s\n", str);
> + return ret < n ? ret : n;
> +}
> +
> +
> +
> +static int
> +grub_vprintf (const char *fmt, va_list args)
> +{
> + int ret;
> +
> + ret = grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), fmt, args);
> +
> + return ret;
> +}
> +
> +int
> +grub_err_printf (const char *fmt, ...)
> +{
> + va_list ap;
> + int ret;
> +
> + va_start (ap, fmt);
> + ret = grub_vprintf (fmt, ap);
> + va_end (ap);
> +
> + return ret;
> +}
> +
> +
> +grub_err_t
> +grub_error (grub_err_t n, const char *fmt, ...)
> +{
> + va_list ap;
> +
> + grub_errno = n;
> + va_start (ap, fmt);
> + grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), fmt, ap);
> + va_end (ap);
> +
> + return n;
> +}
> +
> +void
> +grub_fatal (const char *fmt, ...)
> +{
> + va_list ap;
> +
> + va_start (ap, fmt);
> + grub_vprintf (_(fmt), ap);
> + va_end (ap);
> +
> + exit(1);
> +}
> +
> +void
> +grub_error_push (void)
> +{
> + /* Only add items to stack, if there is enough room. */
> + if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
> + {
> + /* Copy active error message to stack. */
> + grub_error_stack_items[grub_error_stack_pos].errno = grub_errno;
> + grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
> + grub_errmsg,
> + sizeof (grub_errmsg));
> +
> + /* Advance to next error stack position. */
> + grub_error_stack_pos++;
> + }
> + else
> + {
> + /* There is no room for new error message. Discard new error message
> + and mark error stack assertion flag. */
> + grub_error_stack_assert = 1;
> + }
> +
> + /* Allow further operation of other components by resetting
> + active errno to GRUB_ERR_NONE. */
> + grub_errno = GRUB_ERR_NONE;
> +}
> +
> +int
> +grub_error_pop (void)
> +{
> + if (grub_error_stack_pos > 0)
> + {
> + /* Pop error message from error stack to current active error. */
> + grub_error_stack_pos--;
> +
> + grub_errno = grub_error_stack_items[grub_error_stack_pos].errno;
> + grub_memcpy (grub_errmsg,
> + grub_error_stack_items[grub_error_stack_pos].errmsg,
> + sizeof (grub_errmsg));
> +
> + return 1;
> + }
> + else
> + {
> + /* There is no more items on error stack, reset to no error state.
> */
> + grub_errno = GRUB_ERR_NONE;
> +
> + return 0;
> + }
> +}
> +
> +void
> +grub_print_error (void)
> +{
> + /* Print error messages in reverse order. First print active error
> message
> + and then empty error stack. */
> + do
> + {
> + if (grub_errno != GRUB_ERR_NONE)
> + grub_err_printf ("error: %s.\n", grub_errmsg);
> + }
> + while (grub_error_pop ());
> +
> + /* If there was an assert while using error stack, report about it. */
> + if (grub_error_stack_assert)
> + {
> + grub_err_printf ("assert: error stack overflow detected!\n");
> + grub_error_stack_assert = 0;
> + }
> +}
> +
> +
> +int test_grub_err()
> +{
> + grub_error(222, "test %s\n", "grub_error");
> + grub_err_printf("test %s\n", "grub_err_printf");
> + grub_fatal("test %s\n", "grub_fatal");
> +}
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub_err.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub_err.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub_err.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub_err.h 2012-12-28
> 16:02:41.007734164 +0800
> @@ -0,0 +1,81 @@
> +/* err.h - error numbers and prototypes */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_ERR_HEADER
> +#define GRUB_ERR_HEADER 1
> +
> +
> +typedef enum
> + {
> + GRUB_ERR_NONE = 0,
> + GRUB_ERR_TEST_FAILURE,
> + GRUB_ERR_BAD_MODULE,
> + GRUB_ERR_OUT_OF_MEMORY,
> + GRUB_ERR_BAD_FILE_TYPE,
> + GRUB_ERR_FILE_NOT_FOUND,
> + GRUB_ERR_FILE_READ_ERROR,
> + GRUB_ERR_BAD_FILENAME,
> + GRUB_ERR_UNKNOWN_FS,
> + GRUB_ERR_BAD_FS,
> + GRUB_ERR_BAD_NUMBER,
> + GRUB_ERR_OUT_OF_RANGE,
> + GRUB_ERR_UNKNOWN_DEVICE,
> + GRUB_ERR_BAD_DEVICE,
> + GRUB_ERR_READ_ERROR,
> + GRUB_ERR_WRITE_ERROR,
> + GRUB_ERR_UNKNOWN_COMMAND,
> + GRUB_ERR_INVALID_COMMAND,
> + GRUB_ERR_BAD_ARGUMENT,
> + GRUB_ERR_BAD_PART_TABLE,
> + GRUB_ERR_UNKNOWN_OS,
> + GRUB_ERR_BAD_OS,
> + GRUB_ERR_NO_KERNEL,
> + GRUB_ERR_BAD_FONT,
> + GRUB_ERR_NOT_IMPLEMENTED_YET,
> + GRUB_ERR_SYMLINK_LOOP,
> + GRUB_ERR_BAD_GZIP_DATA,
> + GRUB_ERR_MENU,
> + GRUB_ERR_TIMEOUT,
> + GRUB_ERR_IO,
> + GRUB_ERR_ACCESS_DENIED,
> + GRUB_ERR_MENU_ESCAPE,
> + GRUB_ERR_NOT_FOUND,
> + GRUB_ERR_UNKNOWN
> +
> + }
> +grub_err_t;
> +
> +
> +#ifndef _
> +# define _(String) String
> +#endif
> +
> +extern grub_err_t grub_errno;
> +extern char grub_errmsg[];
> +
> +grub_err_t grub_error (grub_err_t n, const char *fmt, ...);
> +void grub_fatal (const char *fmt, ...) __attribute__((noreturn));
> +void grub_error_push (void);
> +int grub_error_pop (void);
> +void grub_print_error (void);
> +int grub_err_printf (const char *fmt, ...)
> + __attribute__ ((format (printf, 1, 2)));
> +int test_grub_err(void);
> +
> +#endif /* ! GRUB_ERR_HEADER */
> diff --exclude=.svn -rpN -U8
> xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/config.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/config.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/config.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/config.h 2012-12-28
> 16:02:41.008640838 +0800
> @@ -0,0 +1,251 @@
> +/* config.h. Generated from config.h.in by configure. */
> +/* config.h.in. Generated from configure.ac by autoheader. */
> +
> +/* Define it if GAS requires that absolute indirect calls/jumps are not
> + prefixed with an asterisk */
> +/* #undef ABSOLUTE_WITHOUT_ASTERISK */
> +
> +/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
> +#define ADDR32 addr32
> +
> +/* Define it to \"data32\" or \"data32;\" to make GAS happy */
> +#define DATA32 data32
> +
> +/* Define to 1 if translation of program messages to the user's native
> + language is requested. */
> +#define ENABLE_NLS 1
> +
> +/* Define if C symbols get an underscore after compilation */
> +/* #undef HAVE_ASM_USCORE */
> +
> +/* Define to 1 if you have the `asprintf' function. */
> +#define HAVE_ASPRINTF 1
> +
> +/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
> + CoreFoundation framework. */
> +/* #undef HAVE_CFLOCALECOPYCURRENT */
> +
> +/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue
> in
> + the CoreFoundation framework. */
> +/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
> +
> +/* Define to 1 if you have the <curses.h> header file. */
> +/* #undef HAVE_CURSES_H */
> +
> +/* Define if the GNU dcgettext() function is already present or
> preinstalled.
> + */
> +#define HAVE_DCGETTEXT 1
> +
> +/* Define to 1 if you have the <dirent.h> header file, and it defines
> `DIR'.
> + */
> +#define HAVE_DIRENT_H 1
> +
> +/* Define to 1 if you have the <ft2build.h> header file. */
> +#define HAVE_FT2BUILD_H 1
> +
> +/* Define to 1 if you have the `getgid' function. */
> +#define HAVE_GETGID 1
> +
> +/* Define if getrawpartition() in -lutil can be used */
> +/* #undef HAVE_GETRAWPARTITION */
> +
> +/* Define if the GNU gettext() function is already present or preinstalled.
> */
> +#define HAVE_GETTEXT 1
> +
> +/* Define to 1 if you have the `getuid' function. */
> +#define HAVE_GETUID 1
> +
> +/* Define if you have the iconv() function and it works. */
> +/* #undef HAVE_ICONV */
> +
> +/* Define to 1 if you have the <inttypes.h> header file. */
> +#define HAVE_INTTYPES_H 1
> +
> +/* Define to 1 if you have the <limits.h> header file. */
> +#define HAVE_LIMITS_H 1
> +
> +/* Define to 1 if you have the `lstat' function. */
> +#define HAVE_LSTAT 1
> +
> +/* Define to 1 if you have the <malloc.h> header file. */
> +#define HAVE_MALLOC_H 1
> +
> +/* Define to 1 if you have the `memalign' function. */
> +#define HAVE_MEMALIGN 1
> +
> +/* Define to 1 if you have the `memmove' function. */
> +#define HAVE_MEMMOVE 1
> +
> +/* Define to 1 if you have the <memory.h> header file. */
> +#define HAVE_MEMORY_H 1
> +
> +/* Define to 1 if you have the <ncurses/curses.h> header file. */
> +/* #undef HAVE_NCURSES_CURSES_H */
> +
> +/* Define to 1 if you have the <ncurses.h> header file. */
> +/* #undef HAVE_NCURSES_H */
> +
> +/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'.
> */
> +/* #undef HAVE_NDIR_H */
> +
> +/* Define if opendisk() in -lutil can be used */
> +/* #undef HAVE_OPENDISK */
> +
> +/* Define to 1 if you have the <pci/pci.h> header file. */
> +/* #undef HAVE_PCI_PCI_H */
> +
> +/* Define to 1 if you have the `posix_memalign' function. */
> +#define HAVE_POSIX_MEMALIGN 1
> +
> +/* Define if returns_twice attribute is supported */
> +/* #undef HAVE_RETURNS_TWICE */
> +
> +/* Define to 1 if you have the `sbrk' function. */
> +#define HAVE_SBRK 1
> +
> +/* Define to 1 if you have the <SDL/SDL.h> header file. */
> +/* #undef HAVE_SDL_SDL_H */
> +
> +/* Define to 1 if you have the <stdint.h> header file. */
> +#define HAVE_STDINT_H 1
> +
> +/* Define to 1 if you have the <stdlib.h> header file. */
> +#define HAVE_STDLIB_H 1
> +
> +/* Define to 1 if you have the `strdup' function. */
> +#define HAVE_STRDUP 1
> +
> +/* Define to 1 if you have the <strings.h> header file. */
> +#define HAVE_STRINGS_H 1
> +
> +/* Define to 1 if you have the <string.h> header file. */
> +#define HAVE_STRING_H 1
> +
> +/* Define to 1 if you have the <sys/dir.h> header file, and it defines
> `DIR'.
> + */
> +/* #undef HAVE_SYS_DIR_H */
> +
> +/* Define to 1 if you have the <sys/fcntl.h> header file. */
> +#define HAVE_SYS_FCNTL_H 1
> +
> +/* Define to 1 if you have the <sys/mkdev.h> header file. */
> +/* #undef HAVE_SYS_MKDEV_H */
> +
> +/* Define to 1 if you have the <sys/ndir.h> header file, and it defines
> `DIR'.
> + */
> +/* #undef HAVE_SYS_NDIR_H */
> +
> +/* Define to 1 if you have the <sys/stat.h> header file. */
> +#define HAVE_SYS_STAT_H 1
> +
> +/* Define to 1 if you have the <sys/sysmacros.h> header file. */
> +#define HAVE_SYS_SYSMACROS_H 1
> +
> +/* Define to 1 if you have the <sys/types.h> header file. */
> +#define HAVE_SYS_TYPES_H 1
> +
> +/* Define to 1 if you have the <termios.h> header file. */
> +#define HAVE_TERMIOS_H 1
> +
> +/* Define to 1 if you have the <unistd.h> header file. */
> +#define HAVE_UNISTD_H 1
> +
> +/* Define to 1 if you have the <usb.h> header file. */
> +/* #undef HAVE_USB_H */
> +
> +/* Define to 1 if you have the `vasprintf' function. */
> +#define HAVE_VASPRINTF 1
> +
> +/* Define to 1 if `major', `minor', and `makedev' are declared in
> <mkdev.h>.
> + */
> +/* #undef MAJOR_IN_MKDEV */
> +
> +/* Define to 1 if `major', `minor', and `makedev' are declared in
> + <sysmacros.h>. */
> +/* #undef MAJOR_IN_SYSMACROS */
> +
> +/* Define to 1 if you enable memory manager debugging. */
> +/* #undef MM_DEBUG */
> +
> +/* Define to 1 if GCC generates calls to __register_frame_info() */
> +/* #undef NEED_REGISTER_FRAME_INFO */
> +
> +/* Name of package */
> +#define PACKAGE "burg"
> +
> +/* Define to the address where bug reports for this package should be sent.
> */
> +#define PACKAGE_BUGREPORT "address@hidden"
> +
> +/* Define to the full name of this package. */
> +#define PACKAGE_NAME "BURG"
> +
> +/* Define to the full name and version of this package. */
> +#define PACKAGE_STRING "BURG 1.98"
> +
> +/* Define to the one symbol short name of this package. */
> +#define PACKAGE_TARNAME "burg"
> +
> +/* Define to the version of this package. */
> +#define PACKAGE_VERSION "1.98"
> +
> +/* The size of `long', as computed by sizeof. */
> +#define SIZEOF_LONG 8
> +
> +/* The size of `void *', as computed by sizeof. */
> +#define SIZEOF_VOID_P 8
> +
> +/* Define to 1 if you have the ANSI C header files. */
> +#define STDC_HEADERS 1
> +
> +/* Version number of package */
> +#define VERSION "1.98"
> +
> +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
> + significant byte first (like Motorola and SPARC, unlike Intel and VAX).
> */
> +#if defined __BIG_ENDIAN__
> +# define WORDS_BIGENDIAN 1
> +#elif ! defined __LITTLE_ENDIAN__
> +/* # undef WORDS_BIGENDIAN */
> +#endif
> +
> +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
> + `char[]'. */
> +#define YYTEXT_POINTER 1
> +
> +/* Number of bits in a file offset, on hosts where this is settable. */
> +/* #undef _FILE_OFFSET_BITS */
> +
> +/* Define for large files, on AIX-style hosts. */
> +/* #undef _LARGE_FILES */
> +
> +/* Define to 1 if on MINIX. */
> +/* #undef _MINIX */
> +
> +/* Define to 2 if the system does not provide POSIX.1 features except with
> + this defined. */
> +/* #undef _POSIX_1_SOURCE */
> +
> +/* Define to 1 if you need to in order for `stat' and other things to work.
> */
> +/* #undef _POSIX_SOURCE */
> +
> +/* Enable extensions on AIX 3, Interix. */
> +#ifndef _ALL_SOURCE
> +# define _ALL_SOURCE 1
> +#endif
> +/* Enable GNU extensions on systems that have them. */
> +#ifndef _GNU_SOURCE
> +# define _GNU_SOURCE 1
> +#endif
> +/* Enable threading extensions on Solaris. */
> +#ifndef _POSIX_PTHREAD_SEMANTICS
> +# define _POSIX_PTHREAD_SEMANTICS 1
> +#endif
> +/* Enable extensions on HP NonStop. */
> +#ifndef _TANDEM_SOURCE
> +# define _TANDEM_SOURCE 1
> +#endif
> +/* Enable general extensions on Solaris. */
> +#ifndef __EXTENSIONS__
> +# define __EXTENSIONS__ 1
> +#endif
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/fat.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/fat.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/fat.c 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/fat.c 2012-12-28
> 16:02:41.008640838 +0800
> @@ -0,0 +1,711 @@
> +/* fat.c - FAT filesystem */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free
> Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include "misc.h"
> +#include "fat.h"
> +
> +
> +static int
> +fat_log2 (unsigned x)
> +{
> + int i;
> +
> + if (x == 0)
> + return -1;
> +
> + for (i = 0; (x & 1) == 0; i++)
> + x >>= 1;
> +
> + if (x != 1)
> + return -1;
> +
> + return i;
> +}
> +
> +
> +struct grub_fat_data *
> +grub_fat_mount (BlockDriverState *bs, uint32_t part_off_sector)
> +{
> + struct grub_fat_bpb bpb;
> + struct grub_fat_data *data = 0;
> + grub_uint32_t first_fat, magic;
> + int64_t off_bytes = (int64_t)part_off_sector << GRUB_DISK_SECTOR_BITS;
> +
> + if (! bs)
> + goto fail;
> +
> + data = (struct grub_fat_data *) malloc (sizeof (*data));
> + if (! data)
> + goto fail;
> +
> + /* Read the BPB. */
> + if (bdrv_pread(bs, off_bytes, &bpb, sizeof(bpb)) != sizeof(bpb))
> + {
> + printf("bdrv_pread fail....\n");
> + goto fail;
> + }
> +
> + if (grub_strncmp((const char *)
> bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5)
> + && grub_strncmp((const char *)
> bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5)
> + && grub_strncmp((const char *) bpb.version_specific.fat32.fstype,
> "FAT32", 5))
> + {
> +
> + printf("fail here-->grub_strncmp......line[%u]\n", __LINE__);
> + goto fail;
> + }
> +
> + /* Get the sizes of logical sectors and clusters. */
> + data->logical_sector_bits =
> + fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
> + printf("bpb.bytes_per_sector=0x%x, le_to_cpu16=0x%x\n",
> + bpb.bytes_per_sector, grub_le_to_cpu16 (bpb.bytes_per_sector));
> +
> +
> + if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS)
> + {
> + printf("fail here-->logical_sector_bits......line[%u]\n", __LINE__);
> + goto fail;
> + }
> + data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
> +
> + printf("bpb.sectors_per_cluster=%u\n", bpb.sectors_per_cluster);
> + data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
> + if (data->cluster_bits < 0)
> + {
> + printf("fail here-->cluster_bits......line[%u]\n", __LINE__);
> + goto fail;
> + }
> + data->cluster_bits += data->logical_sector_bits;
> +
> + /* Get information about FATs. */
> + printf("bpb.num_reserved_sectors=%u, le_to_cpu16=%u\n",
> + bpb.num_reserved_sectors, grub_le_to_cpu16 (bpb.num_reserved_sectors));
> + data->fat_sector = part_off_sector + (grub_le_to_cpu16
> (bpb.num_reserved_sectors)
> + << data->logical_sector_bits);
> + printf("data->fat_sector=%u\n", data->fat_sector);
> + if (data->fat_sector == 0)
> + {
> + printf("fail here-->fat_sector......line[%u]\n", __LINE__);
> + goto fail;
> + }
> + data->sectors_per_fat = ((bpb.sectors_per_fat_16
> + ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
> + : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
> + << data->logical_sector_bits);
> + printf("bpb.version_specific.fat32.sectors_per_fat_32=%u\n"
> + "grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)=%u\n",
> + bpb.version_specific.fat32.sectors_per_fat_32,
> + grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32));
> + if (data->sectors_per_fat == 0)
> + goto fail;
> +
> + /* Get the number of sectors in this volume. */
> + data->num_sectors = ((bpb.num_total_sectors_16
> + ? grub_le_to_cpu16 (bpb.num_total_sectors_16)
> + : grub_le_to_cpu32 (bpb.num_total_sectors_32))
> + << data->logical_sector_bits);
> + if (data->num_sectors == 0)
> + {
> + printf("fail here-->num_sectors......line[%u]\n", __LINE__);
> + goto fail;
> + }
> + /* Get information about the root directory. */
> + if (bpb.num_fats == 0)
> + {
> + printf("fail here-->num_fats......line[%u]\n", __LINE__);
> + goto fail;
> + }
> + data->root_sector = data->fat_sector + bpb.num_fats *
> data->sectors_per_fat;
> + data->num_root_sectors
> + = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
> + * GRUB_FAT_DIR_ENTRY_SIZE
> + + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
> + >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
> + << (data->logical_sector_bits));
> +
> + data->cluster_sector = data->root_sector + data->num_root_sectors;
> + data->num_clusters = (((data->num_sectors - data->cluster_sector)
> + >> (data->cluster_bits + data->logical_sector_bits))
> + + 2);
> +
> + if (data->num_clusters <= 2)
> + {
> + printf("fail here-->num_clusters......line[%u]\n", __LINE__);
> + goto fail;
> + }
> + if (! bpb.sectors_per_fat_16)
> + {
> + /* FAT32. */
> + grub_uint16_t flags = grub_le_to_cpu16
> (bpb.version_specific.fat32.extended_flags);
> +
> + data->root_cluster = grub_le_to_cpu32
> (bpb.version_specific.fat32.root_cluster);
> + data->fat_size = 32;
> + data->cluster_eof_mark = 0x0ffffff8;
> +
> + if (flags & 0x80)
> + {
> + /* Get an active FAT. */
> + unsigned active_fat = flags & 0xf;
> +
> + if (active_fat > bpb.num_fats)
> + goto fail;
> +
> + data->fat_sector += active_fat * data->sectors_per_fat;
> + }
> +
> + if (bpb.num_root_entries != 0 ||
> bpb.version_specific.fat32.fs_version != 0)
> + goto fail;
> + }
> + else
> + {
> + /* FAT12 or FAT16. */
> + data->root_cluster = ~0U;
> +
> + if (data->num_clusters <= 4085 + 2)
> + {
> + /* FAT12. */
> + data->fat_size = 12;
> + data->cluster_eof_mark = 0x0ff8;
> + }
> + else
> + {
> + /* FAT16. */
> + data->fat_size = 16;
> + data->cluster_eof_mark = 0xfff8;
> + }
> + }
> +
> + /* More sanity checks. */
> + if (data->num_sectors <= data->fat_sector)
> + goto fail;
> +
> +
> + printf("data->fat_sector=%u, data->sectors_per_fat=%u\n",
> + data->fat_sector, data->sectors_per_fat);
> + if (bdrv_pread(bs,
> + data->fat_sector << GRUB_DISK_SECTOR_BITS,
> + &first_fat,
> + sizeof (first_fat)) != sizeof(first_fat))
> + {
> + printf("fail here-->bdrv_pread......line[%u]\n", __LINE__);
> + goto fail;
> + }
> +
> + first_fat = grub_le_to_cpu32 (first_fat);
> +
> + if (data->fat_size == 32)
> + {
> + first_fat &= 0x0fffffff;
> + magic = 0x0fffff00;
> + }
> + else if (data->fat_size == 16)
> + {
> + first_fat &= 0x0000ffff;
> + magic = 0xff00;
> + }
> + else
> + {
> + first_fat &= 0x00000fff;
> + magic = 0x0f00;
> + }
> +
> + /* Serial number. */
> + if (bpb.sectors_per_fat_16)
> + data->uuid = grub_le_to_cpu32
> (bpb.version_specific.fat12_or_fat16.num_serial);
> + else
> + data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
> +
> + /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
> + descriptor, even if it is a so-called superfloppy (e.g. an USB key).
> + The check may be too strict for this kind of stupid BIOSes, as
> + they overwrite the media descriptor. */
> + if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
> + {
> + printf("fail here-->first_fat=0x%x, magic=0x%x......line[%u]\n",
> + first_fat, magic, __LINE__);
> + goto fail;
> + }
> + /* Start from the root directory. */
> + data->file_cluster = data->root_cluster;
> + data->cur_cluster_num = ~0U;
> + data->attr = GRUB_FAT_ATTR_DIRECTORY;
> + printf("data->file_cluster=%u \ndata->cur_cluster_num=%u
> \ndata->attr=0x%x\n"
> + "data->logical_sector_bits=%u\n"
> + "data->cluster_bits=%u\n",
> + data->file_cluster, data->cur_cluster_num, data->attr,
> + data->logical_sector_bits, data->cluster_bits);
> + return data;
> +
> + fail:
> +
> + free (data);
> + errx ("not a FAT filesystem...\n");
> + return 0;
> +}
> +
> +
> +
> +//从文件的指定偏移offset字节处读取len字节的数据到buf
> +//文件由data->file_cluster指定
> +//data->file_cluster指定了文件的起始簇号
> +//默认data->file_cluster=2,代表根目录
> +static grub_ssize_t
> +grub_fat_read_data (BlockDriverState *bs, struct grub_fat_data *data,
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset, unsigned length,
> + void *closure),
> + void *closure,
> + grub_off_t offset, grub_size_t len, char *buf)
> +{
> + grub_size_t size;
> + grub_uint32_t logical_cluster;
> + unsigned logical_cluster_bits;
> + grub_ssize_t ret = 0;
> + unsigned long sector;
> + uint64_t off_bytes = 0;
> + /* This is a special case. FAT12 and FAT16 doesn't have the root
> directory
> + in clusters. */
> + if (data->file_cluster == ~0U)
> + {
> + size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
> + if (size > len)
> + size = len;
> +
> + off_bytes = ((uint64_t)data->root_sector << GRUB_DISK_SECTOR_BITS) +
> offset;
> + if(bdrv_read(bs, off_bytes, buf, size ) != size)
> + return -1;
> +
> + return size;
> + }
> +
> + /* Calculate the logical cluster number and offset. */
> + logical_cluster_bits = (data->cluster_bits
> + + data->logical_sector_bits
> + + GRUB_DISK_SECTOR_BITS);
> + logical_cluster = offset >> logical_cluster_bits; //which cluster to
> read
> + offset &= (1 << logical_cluster_bits) - 1; //mod
> +
> + if (logical_cluster < data->cur_cluster_num) //
> + {
> + data->cur_cluster_num = 0;
> + data->cur_cluster = data->file_cluster; // 第2个fat表项开始记录目录和文件
> + }
> +
> + while (len)
> + {
> + while (logical_cluster > data->cur_cluster_num)
> + {
> + /* Find next cluster. */
> + grub_uint32_t next_cluster;
> + unsigned long fat_offset;
> +
> + switch (data->fat_size)
> + {
> + case 32:
> + fat_offset = data->cur_cluster << 2;
> + break;
> + case 16:
> + fat_offset = data->cur_cluster << 1;
> + break;
> + default:
> + /* case 12: */
> + fat_offset = data->cur_cluster + (data->cur_cluster >> 1);
> + break;
> + }
> +
> + /* Read the FAT. */
> + int len = (data->fat_size + 7) >> 3;
> + uint64_t off_bytes = ((uint64_t)data->fat_sector <<
> GRUB_DISK_SECTOR_BITS) + fat_offset;
> + if (bdrv_pread (bs, off_bytes,
> + (char *) &next_cluster,
> + len) != len) //从fat表读取簇号
> + return -1;
> +
> + next_cluster = grub_le_to_cpu32 (next_cluster);
> + switch (data->fat_size)
> + {
> + case 16:
> + next_cluster &= 0xFFFF;
> + break;
> + case 12:
> + if (data->cur_cluster & 1)
> + next_cluster >>= 4;
> +
> + next_cluster &= 0x0FFF;
> + break;
> + }
> +
> + printf ("fat_size=%d, next_cluster=%u\n",
> + data->fat_size, next_cluster);
> +
> + /* Check the end. */
> + if (next_cluster >= data->cluster_eof_mark)
> + return ret;
> +
> + if (next_cluster < 2 || next_cluster >= data->num_clusters)
> + {
> + printf("invalid cluster %u................\n",
> + next_cluster);
> + return -1;
> + }
> +
> + data->cur_cluster = next_cluster;
> + data->cur_cluster_num++;
> + }
> +
> + /* Read the data here. */
> + //逻辑簇所对应的绝对扇区
> + sector = (data->cluster_sector
> + + ((data->cur_cluster - 2)
> + << (data->cluster_bits + data->logical_sector_bits)));
> + //绝对扇区中去掉偏移后的字节数
> + size = (1 << logical_cluster_bits) - offset;
> + if (size > len)
> + size = len;
> +
> + //disk->read_hook = read_hook;
> + //disk->closure = closure;
> + int64_t off_bytes = ((uint64_t)sector << GRUB_DISK_SECTOR_BITS) +
> offset;
> + //disk->read_hook = 0;
> + if (bdrv_pread (bs, off_bytes, buf, size) != size)
> + return -1;
> +
> + len -= size;
> + buf += size;
> + ret += size;
> + logical_cluster++;
> + offset = 0; //以后读的都是完整扇区
> + }
> +
> + return ret;
> +}
> +
> +//遍历由data->file_cluster指定的目录
> +int
> +grub_fat_iterate_dir (BlockDriverState *bs, struct grub_fat_data *data)
> +{
> + struct grub_fat_dir_entry dir;
> + char *filename, *filep = 0;
> + grub_uint16_t *unibuf;
> + int slot = -1, slots = -1;
> + int checksum = -1;
> + grub_ssize_t offset = -sizeof(dir);
> +
> + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
> + return printf("not a directory......\n");
> +
> + /* Allocate space enough to hold a long name. */
> + filename = (char*)malloc (0x40 * 13 * 4 + 1);
> + unibuf = (grub_uint16_t *) malloc (0x40 * 13 * 2);
> + if (! filename || ! unibuf)
> + {
> + free (filename);
> + free (unibuf);
> + return -1;
> + }
> +
> +
> + int count = 0;
> + while (1)
> + {
> + unsigned i;
> +
> + /* Adjust the offset. */
> + offset += sizeof (dir);
> + printf("[%d]offset=%u\n"
> + "data->cur_cluster_num=%u,data->cur_cluster=%u\n",
> + count+1, offset,
> + data->cur_cluster_num, data->cur_cluster);
> + /* Read a directory entry. */
> + //0x0表示空目录
> + if ((grub_fat_read_data (bs, data, 0, 0,
> + offset, sizeof (dir), (char *) &dir)
> + != sizeof (dir) || dir.name[0] == 0))
> + {
> + printf("break...dir.name[0]==%d\n", dir.name[0]);
> + break;
> + }
> + /* Handle long name entries. */
> + if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
> + {
> + printf("long name...\n");
> + struct grub_fat_long_name_entry *long_name
> + = (struct grub_fat_long_name_entry *) &dir;
> + grub_uint8_t id = long_name->id;
> +
> + if (id & 0x40) //the last item
> + {
> + id &= 0x3f; //index or ordinal number 1~31
> + slots = slot = id;
> + checksum = long_name->checksum;
> + printf("the last ordinal num=%d!!!\n", id);
> + }
> +
> + if (id != slot || slot == 0 || checksum != long_name->checksum)
> + {
> + printf("not valid ordinal number ,ignore...continue\n");
> + checksum = -1;
> + continue;
> + }
> +
> + slot--;
> + memcpy (unibuf + slot * 13, long_name->name1, 5 * 2);
> + memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
> + memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
> + printf("memcpy...continue\n");
> + continue;
> + }
> +
> +
> + /* Check if this entry is valid. */
> + //oxe5表示已经被删除
> + if (dir.name[0] == 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID))
> + {
> + printf("dir.name[0]=0x%x, dir.attr=0x%x not valid...continue\n",
> + dir.name[0], dir.attr);
> + continue;
> + }
> +
> + printf("checksum=%d, slot=%d\n", checksum, slot);
> + /* This is a workaround for Japanese. */
> + if (dir.name[0] == 0x05)
> + dir.name[0] = 0xe5;
> +
> + if (checksum != -1 && slot == 0)
> + {
> + printf("checksuming\n");
> + grub_uint8_t sum;
> +
> + for (sum = 0, i = 0; i < sizeof (dir.name); i++)
> + sum = ((sum >> 1) | (sum << 7)) + dir.name[i];
> +
> + if (sum == checksum)
> + {//长名表项后面紧接短名表项,验证成功则证明真正是长名字
> + int u;
> +
> + for (u = 0; u < slots * 13; u++)
> + unibuf[u] = grub_le_to_cpu16 (unibuf[u]);
> +
> + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
> + slots * 13) = '\0';
> +
> + //if (hook (filename, &dir, closure))
> + //break;
> +
> + checksum = -1;
> + for (i = 0; i < sizeof (dir.name); i++)
> + printf("0x%x ", dir.name[i]);
> + char *gbname = (char*)malloc(256);
> + u2g(filename, strlen(filename), gbname, 256);
> + printf("\ndir.name=%s, filename=%s, dir.attr=0x%x,"
> + "sum==checksum...continue\n",
> + dir.name, gbname, dir.attr);
> + free(gbname);
> + count++;
> + continue;
> + }
> +
> + checksum = -1;
> + }
> +
> + //后面的处理针对非真实长名和真实短名
> + /* Convert the 8.3 file name. */
> + //去掉短名的空格,全改为小写
> + filep = filename;
> + if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
> + {
> + printf("VOLUME\n");
> + for (i = 0; i < sizeof (dir.name) && dir.name[i]
> + && ! grub_isspace (dir.name[i]); i++)
> + *filep++ = dir.name[i];
> + }
> + else
> + {
> + for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
> + *filep++ = grub_tolower (dir.name[i]);
> +
> + *filep = '.';
> +
> + for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
> + *++filep = grub_tolower (dir.name[i]);
> +
> + if (*filep != '.')
> + filep++;
> + }
> + *filep = '\0';
> +
> +
> + for (i = 0; i < sizeof (dir.name); i++)
> + printf("0x%x ", dir.name[i]);
> + printf("\ndir.name=%s, filename=【%s】, dir.attr=0x%x,"
> + "...next while\n",
> + dir.name, filename, dir.attr);
> + count++;
> + /*if(strcmp(filename, ".") && strcmp(filename, ".."))
> + {
> + printf("{==============>\n");
> + struct grub_fat_data *data2 = NULL;
> + data2 = (struct grub_fat_data*)malloc(sizeof(*data));
> + memcpy(data2, data, sizeof(*data));
> + data2->attr = dir.attr;
> + data2->file_size = grub_le_to_cpu32 (dir.file_size);
> + data2->file_cluster = ((grub_le_to_cpu16 (dir.first_cluster_high) << 16)
> + | grub_le_to_cpu16 (dir.first_cluster_low));
> + data2->cur_cluster_num = ~0U;
> + (grub_fat_iterate_dir(bs, data2) < 0) ? printf("error !!!!!!\n") : 0;
> + free(data2);
> + printf("<===================}\n");
> + }
> + */
> + //if (hook (filename, &dir, closure))
> + //break;
> + }
> +
> + free (filename);
> + free (unibuf);
> +
> + return 0;
> +}
> +
> +
> +/*
> +struct grub_fat_find_dir_closure
> +{
> + struct grub_fat_data *data;
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure);
> + void *closure;
> + char *dirname;
> + int call_hook;
> + int found;
> +};
> +
> +
> +static int
> +grub_fat_find_dir_hook (const char *filename, struct grub_fat_dir_entry
> *dir,
> + void *closure)
> +{
> + struct grub_fat_find_dir_closure *c = closure;
> + struct grub_dirhook_info info;
> + grub_memset (&info, 0, sizeof (info));
> +
> + info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
> + info.case_insensitive = 1;
> +
> + if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
> + return 0;
> + if (*(c->dirname) == '\0' && (c->call_hook))
> + return c->hook (filename, &info, c->closure);
> +
> + if (grub_strcasecmp (c->dirname, filename) == 0)
> + {
> + struct grub_fat_data *data = c->data;
> +
> + c->found = 1;
> + data->attr = dir->attr;
> + data->file_size = grub_le_to_cpu32 (dir->file_size);
> + data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) <<
> 16)
> + | grub_le_to_cpu16 (dir->first_cluster_low));
> + data->cur_cluster_num = ~0U;
> +
> + if (c->call_hook)
> + c->hook (filename, &info, c->closure);
> +
> + return 1;
> + }
> + return 0;
> +}
> +*/
> +
> +/* Find the underlying directory or file in PATH and return the
> + next path. If there is no next path or an error occurs, return NULL.
> + If HOOK is specified, call it with each file name. */
> +char *
> +grub_fat_find_dir (BlockDriverState *bs, struct grub_fat_data *data,
> + const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure),
> + void *closure)
> +{
> + char *dirname, *dirp;
> + //struct grub_fat_find_dir_closure c;
> +
> + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
> + {
> + printf("not a directory.............\n");
> + return 0;
> + }
> +
> + /* Extract a directory name. */
> + while (*path == '/')
> + path++;
> +
> + dirp = grub_strchr (path, '/');
> + if (dirp)
> + {
> + unsigned len = dirp - path;
> +
> + dirname = (char*)malloc (len + 1);
> + if (! dirname)
> + return 0;
> +
> + memcpy (dirname, path, len);
> + dirname[len] = '\0';
> + }
> + else
> + {
> + /* This is actually a file. */
> + dirname = grub_strdup (path);
> + }
> + //c.data = data;
> + //c.hook = hook;
> + //c.closure = closure;
> + //c.dirname =dirname;
> + //c.found = 0;
> + //c.call_hook = (! dirp && hook);
> + if(grub_fat_iterate_dir (bs, data)<0)
> + {
> + printf("file not found..\n");
> + return 0;
> + }
> +
> +
> + free (dirname);
> +
> + return dirp;
> +}
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/fat.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/fat.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/fat.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/fat.h 2012-12-28
> 16:02:41.009937738 +0800
> @@ -0,0 +1,146 @@
> +#ifndef FS_FAT_H
> +#define FS_FAT_H
> +
> +
> +#include "fs-types.h"
> +#include "block_int.h"
> +
> +#define GRUB_DISK_SECTOR_BITS 9
> +#define GRUB_FAT_DIR_ENTRY_SIZE 32
> +
> +#define GRUB_FAT_ATTR_READ_ONLY 0x01
> +#define GRUB_FAT_ATTR_HIDDEN 0x02
> +#define GRUB_FAT_ATTR_SYSTEM 0x04
> +#define GRUB_FAT_ATTR_VOLUME_ID 0x08
> +#define GRUB_FAT_ATTR_DIRECTORY 0x10
> +#define GRUB_FAT_ATTR_ARCHIVE 0x20
> +
> +#define GRUB_FAT_MAXFILE 256
> +
> +#define GRUB_FAT_ATTR_LONG_NAME (GRUB_FAT_ATTR_READ_ONLY \
> + | GRUB_FAT_ATTR_HIDDEN \
> + | GRUB_FAT_ATTR_SYSTEM \
> + | GRUB_FAT_ATTR_VOLUME_ID)
> +#define GRUB_FAT_ATTR_VALID (GRUB_FAT_ATTR_READ_ONLY \
> + | GRUB_FAT_ATTR_HIDDEN \
> + | GRUB_FAT_ATTR_SYSTEM \
> + | GRUB_FAT_ATTR_DIRECTORY \
> + | GRUB_FAT_ATTR_ARCHIVE \
> + | GRUB_FAT_ATTR_VOLUME_ID)
> +
> +struct grub_fat_bpb
> +{
> + grub_uint8_t jmp_boot[3];
> + grub_uint8_t oem_name[8];
> + grub_uint16_t bytes_per_sector;
> + grub_uint8_t sectors_per_cluster;
> + grub_uint16_t num_reserved_sectors;
> + grub_uint8_t num_fats;
> + grub_uint16_t num_root_entries;
> + grub_uint16_t num_total_sectors_16;
> + grub_uint8_t media;
> + grub_uint16_t sectors_per_fat_16;
> + grub_uint16_t sectors_per_track;
> + grub_uint16_t num_heads;
> + grub_uint32_t num_hidden_sectors;
> + grub_uint32_t num_total_sectors_32;
> + union
> + {
> + struct
> + {
> + grub_uint8_t num_ph_drive;
> + grub_uint8_t reserved;
> + grub_uint8_t boot_sig;
> + grub_uint32_t num_serial;
> + grub_uint8_t label[11];
> + grub_uint8_t fstype[8];
> + } __attribute__ ((packed)) fat12_or_fat16;
> + struct
> + {
> + grub_uint32_t sectors_per_fat_32;
> + grub_uint16_t extended_flags;
> + grub_uint16_t fs_version;
> + grub_uint32_t root_cluster;
> + grub_uint16_t fs_info;
> + grub_uint16_t backup_boot_sector;
> + grub_uint8_t reserved[12];
> + grub_uint8_t num_ph_drive;
> + grub_uint8_t reserved1;
> + grub_uint8_t boot_sig;
> + grub_uint32_t num_serial;
> + grub_uint8_t label[11];
> + grub_uint8_t fstype[8];
> + } __attribute__ ((packed)) fat32;
> + } __attribute__ ((packed)) version_specific;
> +} __attribute__ ((packed));
> +
> +struct grub_fat_dir_entry
> +{
> + grub_uint8_t name[11];
> + grub_uint8_t attr;
> + grub_uint8_t nt_reserved;
> + grub_uint8_t c_time_tenth;
> + grub_uint16_t c_time;
> + grub_uint16_t c_date;
> + grub_uint16_t a_date;
> + grub_uint16_t first_cluster_high;
> + grub_uint16_t w_time;
> + grub_uint16_t w_date;
> + grub_uint16_t first_cluster_low;
> + grub_uint32_t file_size;
> +} __attribute__ ((packed));
> +
> +struct grub_fat_long_name_entry
> +{
> + grub_uint8_t id;
> + grub_uint16_t name1[5];
> + grub_uint8_t attr;
> + grub_uint8_t reserved;
> + grub_uint8_t checksum;
> + grub_uint16_t name2[6];
> + grub_uint16_t first_cluster;
> + grub_uint16_t name3[2];
> +} __attribute__ ((packed));
> +
> +struct grub_fat_data
> +{
> + int logical_sector_bits;
> + grub_uint32_t num_sectors;
> +
> + grub_uint16_t fat_sector;
> + grub_uint32_t sectors_per_fat;
> + int fat_size;
> +
> + grub_uint32_t root_cluster;
> + grub_uint32_t root_sector;
> + grub_uint32_t num_root_sectors;
> +
> + int cluster_bits;
> + grub_uint32_t cluster_eof_mark;
> + grub_uint32_t cluster_sector;
> + grub_uint32_t num_clusters;
> +
> + grub_uint8_t attr;
> + grub_ssize_t file_size;
> + grub_uint32_t file_cluster;
> + grub_uint32_t cur_cluster_num;
> + grub_uint32_t cur_cluster;
> +
> + grub_uint32_t uuid;
> +};
> +
> +
> +
> +
> +
> +
> +struct grub_fat_data* grub_fat_mount (BlockDriverState *bs, uint32_t
> part_off_sector);
> +int grub_fat_iterate_dir (BlockDriverState *bs, struct grub_fat_data
> *data);
> +
> +
> +
> +
> +
> +
> +
> +#endif
> diff --exclude=.svn -rpN -U8
> xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/fs-types.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/fs-types.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/fs-types.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/fs-types.h 2012-12-28
> 16:02:41.009937738 +0800
> @@ -0,0 +1,228 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2005,2006,2007,2008,2009 Free Software Foundation,
> Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TYPES_HEADER
> +#define GRUB_TYPES_HEADER 1
> +
> +#include <config.h>
> +#include <x86_64/types.h>
> +
> +#ifdef GRUB_UTIL
> +# define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P
> +# define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG
> +# ifdef WORDS_BIGENDIAN
> +# define GRUB_CPU_WORDS_BIGENDIAN 1
> +# else
> +# undef GRUB_CPU_WORDS_BIGENDIAN
> +# endif
> +#else /* ! GRUB_UTIL */
> +# define GRUB_CPU_SIZEOF_VOID_P GRUB_TARGET_SIZEOF_VOID_P
> +# define GRUB_CPU_SIZEOF_LONG GRUB_TARGET_SIZEOF_LONG
> +# ifdef GRUB_TARGET_WORDS_BIGENDIAN
> +# define GRUB_CPU_WORDS_BIGENDIAN 1
> +# else
> +# undef GRUB_CPU_WORDS_BIGENDIAN
> +# endif
> +#endif /* ! GRUB_UTIL */
> +
> +#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8
> +# error "This architecture is not supported because sizeof(void *) != 4 and
> sizeof(void *) != 8"
> +#endif
> +
> +#ifndef GRUB_TARGET_WORDSIZE
> +# if GRUB_TARGET_SIZEOF_VOID_P == 4
> +# define GRUB_TARGET_WORDSIZE 32
> +# elif GRUB_TARGET_SIZEOF_VOID_P == 8
> +# define GRUB_TARGET_WORDSIZE 64
> +# endif
> +#endif
> +
> +/* Define various wide integers. */
> +typedef signed char grub_int8_t;
> +typedef short grub_int16_t;
> +typedef int grub_int32_t;
> +#if GRUB_CPU_SIZEOF_LONG == 8
> +typedef long grub_int64_t;
> +#else
> +typedef long long grub_int64_t;
> +#endif
> +
> +typedef unsigned char grub_uint8_t;
> +typedef unsigned short grub_uint16_t;
> +typedef unsigned grub_uint32_t;
> +#if GRUB_CPU_SIZEOF_LONG == 8
> +typedef unsigned long grub_uint64_t;
> +#else
> +typedef unsigned long long grub_uint64_t;
> +#endif
> +
> +/* Misc types. */
> +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> +typedef grub_uint64_t grub_target_addr_t;
> +typedef grub_uint64_t grub_target_off_t;
> +typedef grub_uint64_t grub_target_size_t;
> +typedef grub_int64_t grub_target_ssize_t;
> +#else
> +typedef grub_uint32_t grub_target_addr_t;
> +typedef grub_uint32_t grub_target_off_t;
> +typedef grub_uint32_t grub_target_size_t;
> +typedef grub_int32_t grub_target_ssize_t;
> +#endif
> +
> +#if GRUB_CPU_SIZEOF_VOID_P == 8
> +typedef grub_uint64_t grub_addr_t;
> +typedef grub_uint64_t grub_size_t;
> +typedef grub_int64_t grub_ssize_t;
> +#else
> +typedef grub_uint32_t grub_addr_t;
> +typedef grub_uint32_t grub_size_t;
> +typedef grub_int32_t grub_ssize_t;
> +#endif
> +
> +#if GRUB_CPU_SIZEOF_VOID_P == 8
> +# define GRUB_ULONG_MAX 18446744073709551615UL
> +# define GRUB_LONG_MAX 9223372036854775807L
> +# define GRUB_LONG_MIN (-9223372036854775807L - 1)
> +#else
> +# define GRUB_ULONG_MAX 4294967295UL
> +# define GRUB_LONG_MAX 2147483647L
> +# define GRUB_LONG_MIN (-2147483647L - 1)
> +#endif
> +
> +#if GRUB_CPU_SIZEOF_VOID_P == 4
> +#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
> +#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
> +#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
> +#else
> +#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
> +#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
> +#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
> +#endif
> +
> +/* The type for representing a file offset. */
> +typedef grub_uint64_t grub_off_t;
> +
> +/* The type for representing a disk block address. */
> +typedef grub_uint64_t grub_disk_addr_t;
> +
> +/* Byte-orders. */
> +#define grub_swap_bytes16(x) \
> +({ \
> + grub_uint16_t _x = (x); \
> + (grub_uint16_t) ((_x << 8) | (_x >> 8)); \
> +})
> +
> +#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__
>>= 3) && defined(GRUB_TARGET_I386)
> +static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x)
> +{
> + return __builtin_bswap32(x);
> +}
> +
> +static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
> +{
> + return __builtin_bswap64(x);
> +}
> +#else /* not gcc 4.3 or newer */
> +#define grub_swap_bytes32(x) \
> +({ \
> + grub_uint32_t _x = (x); \
> + (grub_uint32_t) ((_x << 24) \
> + | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \
> + | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \
> + | (_x >> 24)); \
> +})
> +
> +#define grub_swap_bytes64(x) \
> +({ \
> + grub_uint64_t _x = (x); \
> + (grub_uint64_t) ((_x << 56) \
> + | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \
> + | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \
> + | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
> + | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \
> + | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \
> + | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \
> + | (_x >> 56)); \
> +})
> +#endif /* not gcc 4.3 or newer */
> +
> +#ifdef GRUB_CPU_WORDS_BIGENDIAN
> +# define grub_cpu_to_le16(x) grub_swap_bytes16(x)
> +# define grub_cpu_to_le32(x) grub_swap_bytes32(x)
> +# define grub_cpu_to_le64(x) grub_swap_bytes64(x)
> +# define grub_le_to_cpu16(x) grub_swap_bytes16(x)
> +# define grub_le_to_cpu32(x) grub_swap_bytes32(x)
> +# define grub_le_to_cpu64(x) grub_swap_bytes64(x)
> +# define grub_cpu_to_be16(x) ((grub_uint16_t) (x))
> +# define grub_cpu_to_be32(x) ((grub_uint32_t) (x))
> +# define grub_cpu_to_be64(x) ((grub_uint64_t) (x))
> +# define grub_be_to_cpu16(x) ((grub_uint16_t) (x))
> +# define grub_be_to_cpu32(x) ((grub_uint32_t) (x))
> +# define grub_be_to_cpu64(x) ((grub_uint64_t) (x))
> +# ifdef GRUB_TARGET_WORDS_BIGENDIAN
> +# define grub_target_to_host16(x) ((grub_uint16_t) (x))
> +# define grub_target_to_host32(x) ((grub_uint32_t) (x))
> +# define grub_target_to_host64(x) ((grub_uint64_t) (x))
> +# define grub_host_to_target16(x) ((grub_uint16_t) (x))
> +# define grub_host_to_target32(x) ((grub_uint32_t) (x))
> +# define grub_host_to_target64(x) ((grub_uint64_t) (x))
> +# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
> +# define grub_target_to_host16(x) grub_swap_bytes16(x)
> +# define grub_target_to_host32(x) grub_swap_bytes32(x)
> +# define grub_target_to_host64(x) grub_swap_bytes64(x)
> +# define grub_host_to_target16(x) grub_swap_bytes16(x)
> +# define grub_host_to_target32(x) grub_swap_bytes32(x)
> +# define grub_host_to_target64(x) grub_swap_bytes64(x)
> +# endif
> +#else /* ! WORDS_BIGENDIAN */
> +# define grub_cpu_to_le16(x) ((grub_uint16_t) (x))
> +# define grub_cpu_to_le32(x) ((grub_uint32_t) (x))
> +# define grub_cpu_to_le64(x) ((grub_uint64_t) (x))
> +# define grub_le_to_cpu16(x) ((grub_uint16_t) (x))
> +# define grub_le_to_cpu32(x) ((grub_uint32_t) (x))
> +# define grub_le_to_cpu64(x) ((grub_uint64_t) (x))
> +# define grub_cpu_to_be16(x) grub_swap_bytes16(x)
> +# define grub_cpu_to_be32(x) grub_swap_bytes32(x)
> +# define grub_cpu_to_be64(x) grub_swap_bytes64(x)
> +# define grub_be_to_cpu16(x) grub_swap_bytes16(x)
> +# define grub_be_to_cpu32(x) grub_swap_bytes32(x)
> +# define grub_be_to_cpu64(x) grub_swap_bytes64(x)
> +# ifdef GRUB_TARGET_WORDS_BIGENDIAN
> +# define grub_target_to_host16(x) grub_swap_bytes16(x)
> +# define grub_target_to_host32(x) grub_swap_bytes32(x)
> +# define grub_target_to_host64(x) grub_swap_bytes64(x)
> +# define grub_host_to_target16(x) grub_swap_bytes16(x)
> +# define grub_host_to_target32(x) grub_swap_bytes32(x)
> +# define grub_host_to_target64(x) grub_swap_bytes64(x)
> +# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
> +# define grub_target_to_host16(x) ((grub_uint16_t) (x))
> +# define grub_target_to_host32(x) ((grub_uint32_t) (x))
> +# define grub_target_to_host64(x) ((grub_uint64_t) (x))
> +# define grub_host_to_target16(x) ((grub_uint16_t) (x))
> +# define grub_host_to_target32(x) ((grub_uint32_t) (x))
> +# define grub_host_to_target64(x) ((grub_uint64_t) (x))
> +# endif
> +#endif /* ! WORDS_BIGENDIAN */
> +
> +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> +# define grub_host_to_target_addr(x) grub_host_to_target64(x)
> +#else
> +# define grub_host_to_target_addr(x) grub_host_to_target32(x)
> +#endif
> +
> +#endif /* ! GRUB_TYPES_HEADER */
> diff --exclude=.svn -rpN -U8
> xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/i386/types.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/i386/types.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/i386/types.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/i386/types.h 2012-12-28
> 16:02:41.010937619 +0800
> @@ -0,0 +1,35 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2006,2007 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TYPES_CPU_HEADER
> +#define GRUB_TYPES_CPU_HEADER 1
> +
> +/* The size of void *. */
> +#define GRUB_TARGET_SIZEOF_VOID_P 4
> +
> +/* The size of long. */
> +#define GRUB_TARGET_SIZEOF_LONG 4
> +
> +/* i386 is little-endian. */
> +#undef GRUB_TARGET_WORDS_BIGENDIAN
> +
> +#define GRUB_TARGET_I386 1
> +
> +#define GRUB_TARGET_MIN_ALIGN 1
> +
> +#endif /* ! GRUB_TYPES_CPU_HEADER */
> diff --exclude=.svn -rpN -U8
> xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/misc.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/misc.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/misc.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/misc.h 2012-12-28
> 16:02:41.010937619 +0800
> @@ -0,0 +1,17 @@
> +int
> +grub_strncmp (const char *s1, const char *s2, grub_size_t n)
> +{
> + if (n == 0)
> + return 0;
> +
> + while (*s1 && *s2 && --n)
> + {
> + if (*s1 != *s2)
> + break;
> +
> + s1++;
> + s2++;
> + }
> +
> + return (int) *s1 - (int) *s2;
> +}
> diff --exclude=.svn -rpN -U8
> xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/x86_64/types.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/x86_64/types.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/x86_64/types.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/x86_64/types.h 2012-12-28
> 16:02:41.011764159 +0800
> @@ -0,0 +1,39 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2008 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TYPES_CPU_HEADER
> +#define GRUB_TYPES_CPU_HEADER 1
> +
> +/* The size of void *. */
> +#define GRUB_TARGET_SIZEOF_VOID_P 8
> +
> +/* The size of long. */
> +#ifdef __MINGW32__
> +#define GRUB_TARGET_SIZEOF_LONG 4
> +#else
> +#define GRUB_TARGET_SIZEOF_LONG 8
> +#endif
> +
> +/* x86_64 is little-endian. */
> +#undef GRUB_TARGET_WORDS_BIGENDIAN
> +
> +#define GRUB_TARGET_X86_64 1
> +
> +#define GRUB_TARGET_MIN_ALIGN 1
> +
> +#endif /* ! GRUB_TYPES_CPU_HEADER */
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/i386/types.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/i386/types.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/i386/types.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/i386/types.h 2012-12-28
> 16:02:41.017802371 +0800
> @@ -0,0 +1,35 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2006,2007 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TYPES_CPU_HEADER
> +#define GRUB_TYPES_CPU_HEADER 1
> +
> +/* The size of void *. */
> +#define GRUB_TARGET_SIZEOF_VOID_P 4
> +
> +/* The size of long. */
> +#define GRUB_TARGET_SIZEOF_LONG 4
> +
> +/* i386 is little-endian. */
> +#undef GRUB_TARGET_WORDS_BIGENDIAN
> +
> +#define GRUB_TARGET_I386 1
> +
> +#define GRUB_TARGET_MIN_ALIGN 1
> +
> +#endif /* ! GRUB_TYPES_CPU_HEADER */
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/Makefile
> xen-4.1.2-b/tools/ioemu-qemu-xen/Makefile
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/Makefile 2011-02-12 01:54:51.000000000
> +0800
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/Makefile 2012-12-28 16:02:41.011764159
> +0800
> @@ -188,17 +188,18 @@ libqemu_common.a: $(OBJS)
> #######################################################################
> # USER_OBJS is code used by qemu userspace emulation
> USER_OBJS=cutils.o cache-utils.o
>
> libqemu_user.a: $(USER_OBJS)
>
> ######################################################################
>
> -qemu-img$(EXESUF): qemu-img.o qemu-tool.o osdep.o $(BLOCK_OBJS)
> +
> +qemu-img$(EXESUF):fs-time.o grub_err.o partition.o fshelp.o ntfs.o fat.o
> misc.o debug.o qemu-img.o qemu-tool.o osdep.o $(BLOCK_OBJS)
>
> qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o osdep.o $(BLOCK_OBJS)
>
> qemu-img$(EXESUF) qemu-nbd$(EXESUF): LIBS += -lz
>
>
> clean:
> # avoid old build problems by removing potentially incorrect old files
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/Makefile.orig
> xen-4.1.2-b/tools/ioemu-qemu-xen/Makefile.orig
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/Makefile.orig 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/Makefile.orig 2012-12-28
> 15:59:35.354681634 +0800
> @@ -0,0 +1,372 @@
> +# Makefile for QEMU.
> +
> +include config-host.mak
> +include $(SRC_PATH)/rules.mak
> +
> +.PHONY: all clean cscope distclean dvi html info install install-doc \
> + recurse-all speed tar tarbin test
> +
> +VPATH=$(SRC_PATH):$(SRC_PATH)/hw
> +
> +
> +CFLAGS += $(OS_CFLAGS) $(ARCH_CFLAGS)
> +LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS)
> +
> +CPPFLAGS += -I. -I$(SRC_PATH) -MMD -MP -MT $@
> +CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
> +LIBS=
> +ifdef CONFIG_STATIC
> +LDFLAGS += -static
> +endif
> +ifdef BUILD_DOCS
> +DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8
> +else
> +DOCS=
> +endif
> +
> +LIBS+=$(AIOLIBS)
> +
> +ifdef CONFIG_SOLARIS
> +LIBS+=-lsocket -lnsl -lresolv
> +endif
> +
> +ifdef CONFIG_WIN32
> +LIBS+=-lwinmm -lws2_32 -liphlpapi
> +endif
> +
> +all: $(TOOLS) $(DOCS) recurse-all
> +
> +SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
> +
> +subdir-%:
> + $(call quiet-command,$(MAKE) -C $* V="$(V)" TARGET_DIR="$*/" all,)
> +
> +$(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a
> +$(filter %-user,$(SUBDIR_RULES)): libqemu_user.a
> +
> +recurse-all: $(SUBDIR_RULES)
> +
> +CPPFLAGS += -I$(XEN_ROOT)/tools/libxc
> +CPPFLAGS += -I$(XEN_ROOT)/tools/blktap/lib
> +CPPFLAGS += -I$(XEN_ROOT)/tools/xenstore
> +CPPFLAGS += -I$(XEN_ROOT)/tools/include
> +
> +tapdisk-ioemu: tapdisk-ioemu.c cutils.c block.c block-raw.c block-cow.c
> block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c
> block-vpc.c block-vvfat.c block-qcow2.c hw/xen_blktap.c osdep.c
> + $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS)
> $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
> +
> +#######################################################################
> +# BLOCK_OBJS is code used by both qemu system emulation and qemu-img
> +
> +BLOCK_OBJS=cutils.o osdep.o qemu-malloc.o
> +BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
> +BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
> +BLOCK_OBJS+=block-qcow2.o block-parallels.o block-nbd.o
> +BLOCK_OBJS+=nbd.o block.o aio.o
> +
> +ifdef CONFIG_WIN32
> +BLOCK_OBJS += block-raw-win32.o
> +else
> +ifdef CONFIG_AIO
> +BLOCK_OBJS += posix-aio-compat.o
> +endif
> +BLOCK_OBJS += block-raw-posix.o
> +endif
> +
> +######################################################################
> +# libqemu_common.a: Target independent part of system emulation. The
> +# long term path is to suppress *all* target specific code in case of
> +# system emulation, i.e. a single QEMU executable should support all
> +# CPUs and machines.
> +
> +OBJS=$(BLOCK_OBJS)
> +OBJS+=readline.o console.o
> +
> +OBJS+=irq.o
> +OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
> +OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o
> +OBJS+=tmp105.o lm832x.o
> +OBJS+=scsi-disk.o cdrom.o
> +OBJS+=scsi-generic.o
> +OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
> +OBJS+=usb-serial.o usb-net.o
> +OBJS+=sd.o ssi-sd.o
> +OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o
> usb-bt.o
> +OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
> +OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
> +
> +ifdef CONFIG_BRLAPI
> +OBJS+= baum.o
> +LIBS+=-lbrlapi
> +endif
> +
> +ifdef CONFIG_WIN32
> +OBJS+=tap-win32.o
> +else
> +OBJS+=migration-exec.o
> +endif
> +
> +AUDIO_OBJS = audio.o noaudio.o wavaudio.o mixeng.o
> +ifdef CONFIG_SDL
> +AUDIO_OBJS += sdlaudio.o
> +endif
> +ifdef CONFIG_OSS
> +AUDIO_OBJS += ossaudio.o
> +endif
> +ifdef CONFIG_COREAUDIO
> +AUDIO_OBJS += coreaudio.o
> +AUDIO_PT = yes
> +endif
> +ifdef CONFIG_ALSA
> +AUDIO_OBJS += alsaaudio.o
> +endif
> +ifdef CONFIG_DSOUND
> +AUDIO_OBJS += dsoundaudio.o
> +endif
> +ifdef CONFIG_FMOD
> +AUDIO_OBJS += fmodaudio.o
> +audio/audio.o audio/fmodaudio.o: CPPFLAGS := -I$(CONFIG_FMOD_INC)
> $(CPPFLAGS)
> +endif
> +ifdef CONFIG_ESD
> +AUDIO_PT = yes
> +AUDIO_PT_INT = yes
> +AUDIO_OBJS += esdaudio.o
> +endif
> +ifdef CONFIG_PA
> +AUDIO_PT = yes
> +AUDIO_PT_INT = yes
> +AUDIO_OBJS += paaudio.o
> +endif
> +ifdef AUDIO_PT
> +LDFLAGS += -pthread
> +endif
> +ifdef AUDIO_PT_INT
> +AUDIO_OBJS += audio_pt_int.o
> +endif
> +AUDIO_OBJS+= wavcapture.o
> +ifdef CONFIG_AUDIO
> +OBJS+=$(addprefix audio/, $(AUDIO_OBJS))
> +endif
> +
> +ifdef CONFIG_SDL
> +OBJS+=sdl.o x_keymap.o
> +endif
> +ifdef CONFIG_CURSES
> +OBJS+=curses.o
> +endif
> +OBJS+=vnc.o d3des.o
> +
> +ifdef CONFIG_COCOA
> +OBJS+=cocoa.o
> +endif
> +
> +ifdef CONFIG_SLIRP
> +CPPFLAGS+=-I$(SRC_PATH)/slirp
> +SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
> +slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o \
> +tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
> +OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
> +endif
> +
> +LIBS+=$(VDE_LIBS)
> +
> +cocoa.o: cocoa.m
> +
> +sdl.o: sdl.c keymaps.c sdl_keysym.h
> +
> +sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
> +
> +vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
> +
> +vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
> +
> +curses.o: curses.c keymaps.c curses_keys.h
> +
> +bt-host.o: CFLAGS += $(CONFIG_BLUEZ_CFLAGS)
> +
> +libqemu_common.a: $(OBJS)
> +
> +#######################################################################
> +# USER_OBJS is code used by qemu userspace emulation
> +USER_OBJS=cutils.o cache-utils.o
> +
> +libqemu_user.a: $(USER_OBJS)
> +
> +######################################################################
> +
> +qemu-img$(EXESUF): qemu-img.o qemu-tool.o osdep.o $(BLOCK_OBJS)
> +
> +qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o osdep.o $(BLOCK_OBJS)
> +
> +qemu-img$(EXESUF) qemu-nbd$(EXESUF): LIBS += -lz
> +
> +
> +clean:
> +# avoid old build problems by removing potentially incorrect old files
> + rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h
> opc-arm.h gen-op-arm.h
> + rm -f *.o .*.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~
> + rm -f slirp/*.o slirp/.*.d audio/*.o audio/.*.d
> + $(MAKE) -C tests clean
> + for d in $(TARGET_DIRS); do \
> + $(MAKE) -C $$d $@ || exit 1 ; \
> + done
> +
> +distclean: clean
> + rm -f config-host.mak config-host.h $(DOCS)
> + rm -f qemu-{doc,tech}.{info,aux,cp,dvi,fn,info,ky,log,pg,toc,tp,vr}
> + for d in $(TARGET_DIRS); do \
> + rm -rf $$d || exit 1 ; \
> + done
> +
> +KEYMAPS=da en-gb et fr fr-ch is lt modifiers no pt-br sv \
> +ar de en-us fi fr-be hr it lv nl pl ru th \
> +common de-ch es fo fr-ca hu ja mk nl-be pt sl tr
> +
> +ifdef INSTALL_BLOBS
> +BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
> +video.x openbios-sparc32 openbios-sparc64 openbios-ppc \
> +pxe-ne2k_pci.bin pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin \
> +bamboo.dtb
> +else
> +BLOBS=
> +endif
> +
> +install-doc: $(DOCS)
> + mkdir -p "$(DESTDIR)$(docdir)"
> + $(INSTALL) -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)"
> +ifndef CONFIG_WIN32
> + mkdir -p "$(DESTDIR)$(mandir)/man1"
> + $(INSTALL) -m 644 qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
> + mkdir -p "$(DESTDIR)$(mandir)/man8"
> + $(INSTALL) -m 644 qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
> +endif
> +
> +install: all $(if $(BUILD_DOCS),install-doc)
> + mkdir -p "$(DESTDIR)$(bindir)"
> +ifneq ($(TOOLS),)
> + $(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
> +endif
> +ifneq ($(BLOBS),)
> + mkdir -p "$(DESTDIR)$(datadir)"
> + set -e; for x in $(BLOBS); do \
> + $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
> + done
> +endif
> +ifndef CONFIG_WIN32
> + mkdir -p "$(DESTDIR)$(datadir)/keymaps"
> + set -e; for x in $(KEYMAPS); do \
> + $(INSTALL) -m 644 $(SRC_PATH)/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps";
> \
> + done
> +endif
> + for d in $(TARGET_DIRS); do \
> + $(MAKE) -C $$d $@ || exit 1 ; \
> + done
> +
> +# various test targets
> +test speed: all
> + $(MAKE) -C tests $@
> +
> +TAGS:
> + etags *.[ch] tests/*.[ch]
> +
> +cscope:
> + rm -f ./cscope.*
> + find . -name "*.[ch]" -print | sed 's,^\./,,' > ./cscope.files
> + cscope -b
> +
> +# documentation
> +%.html: %.texi
> + texi2html -monolithic -number $<
> +
> +%.info: %.texi
> + makeinfo $< -o $@
> +
> +%.dvi: %.texi
> + texi2dvi $<
> +
> +qemu.1: qemu-doc.texi
> + $(SRC_PATH)/texi2pod.pl $< qemu.pod
> + pod2man --section=1 --center=" " --release=" " qemu.pod > $@
> +
> +qemu-img.1: qemu-img.texi
> + $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
> + pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@
> +
> +qemu-nbd.8: qemu-nbd.texi
> + $(SRC_PATH)/texi2pod.pl $< qemu-nbd.pod
> + pod2man --section=8 --center=" " --release=" " qemu-nbd.pod > $@
> +
> +info: qemu-doc.info qemu-tech.info
> +
> +dvi: qemu-doc.dvi qemu-tech.dvi
> +
> +html: qemu-doc.html qemu-tech.html
> +
> +qemu-doc.dvi qemu-doc.html qemu-doc.info: qemu-img.texi qemu-nbd.texi
> +
> +VERSION ?= $(shell cat VERSION)
> +FILE = qemu-$(VERSION)
> +
> +# tar release (use 'make -k tar' on a checkouted tree)
> +tar:
> + rm -rf /tmp/$(FILE)
> + cp -r . /tmp/$(FILE)
> + cd /tmp && tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS --exclude .git
> --exclude .svn
> + rm -rf /tmp/$(FILE)
> +
> +# generate a binary distribution
> +tarbin:
> + cd / && tar zcvf ~/qemu-$(VERSION)-$(ARCH).tar.gz \
> + $(bindir)/qemu \
> + $(bindir)/qemu-system-x86_64 \
> + $(bindir)/qemu-system-arm \
> + $(bindir)/qemu-system-cris \
> + $(bindir)/qemu-system-m68k \
> + $(bindir)/qemu-system-mips \
> + $(bindir)/qemu-system-mipsel \
> + $(bindir)/qemu-system-mips64 \
> + $(bindir)/qemu-system-mips64el \
> + $(bindir)/qemu-system-ppc \
> + $(bindir)/qemu-system-ppcemb \
> + $(bindir)/qemu-system-ppc64 \
> + $(bindir)/qemu-system-sh4 \
> + $(bindir)/qemu-system-sh4eb \
> + $(bindir)/qemu-system-sparc \
> + $(bindir)/qemu-i386 \
> + $(bindir)/qemu-x86_64 \
> + $(bindir)/qemu-alpha \
> + $(bindir)/qemu-arm \
> + $(bindir)/qemu-armeb \
> + $(bindir)/qemu-cris \
> + $(bindir)/qemu-m68k \
> + $(bindir)/qemu-mips \
> + $(bindir)/qemu-mipsel \
> + $(bindir)/qemu-ppc \
> + $(bindir)/qemu-ppc64 \
> + $(bindir)/qemu-ppc64abi32 \
> + $(bindir)/qemu-sh4 \
> + $(bindir)/qemu-sh4eb \
> + $(bindir)/qemu-sparc \
> + $(bindir)/qemu-sparc64 \
> + $(bindir)/qemu-sparc32plus \
> + $(bindir)/qemu-img \
> + $(bindir)/qemu-nbd \
> + $(datadir)/bios.bin \
> + $(datadir)/vgabios.bin \
> + $(datadir)/vgabios-cirrus.bin \
> + $(datadir)/ppc_rom.bin \
> + $(datadir)/video.x \
> + $(datadir)/openbios-sparc32 \
> + $(datadir)/openbios-sparc64 \
> + $(datadir)/openbios-ppc \
> + $(datadir)/pxe-ne2k_pci.bin \
> + $(datadir)/pxe-rtl8139.bin \
> + $(datadir)/pxe-pcnet.bin \
> + $(datadir)/pxe-e1000.bin \
> + $(docdir)/qemu-doc.html \
> + $(docdir)/qemu-tech.html \
> + $(mandir)/man1/qemu.1 \
> + $(mandir)/man1/qemu-img.1 \
> + $(mandir)/man8/qemu-nbd.8
> +
> +# Include automatically generated dependency files
> +-include $(wildcard .*.d audio/.*.d slirp/.*.d)
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/misc.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/misc.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/misc.c 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/misc.c 2012-12-28 16:02:41.012937846
> +0800
> @@ -0,0 +1,432 @@
> +#include "misc.h"
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include "grub_err.h"
> +
> +
> +int
> +grub_isspace (int c)
> +{
> + return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
> +}
> +
> +int
> +grub_tolower (int c)
> +{
> + if (c >= 'A' && c <= 'Z')
> + return c - 'A' + 'a';
> +
> + return c;
> +}
> +
> +
> +char *
> +grub_strchr (const char *s, int c)
> +{
> + do
> + {
> + if (*s == c)
> + return (char *) s;
> + }
> + while (*s++);
> +
> + return 0;
> +}
> +
> +
> +grub_size_t
> +grub_strlen (const char *s)
> +{
> + const char *p = s;
> +
> + while (*p)
> + p++;
> +
> + return p - s;
> +}
> +
> +
> +
> +
> +
> +char *
> +grub_strncpy (char *dest, const char *src, int c)
> +{
> + char *p = dest;
> +
> + while ((*p++ = *src++) != '\0' && --c)
> + ;
> +
> + return dest;
> +}
> +
> +char *
> +grub_strdup (const char *s)
> +{
> + grub_size_t len;
> + char *p;
> +
> + len = grub_strlen (s) + 1;
> + p = (char *) malloc (len);
> + if (! p)
> + return 0;
> +
> + return memcpy (p, s, len);
> +}
> +
> +
> +
> +char *
> +grub_strndup (const char *s, grub_size_t n)
> +{
> + grub_size_t len;
> + char *p;
> +
> + len = grub_strlen (s);
> + if (len > n)
> + len = n;
> + p = (char *) malloc (len + 1);
> + if (! p)
> + return 0;
> +
> + memcpy (p, s, len);
> + p[len] = '\0';
> + return p;
> +}
> +
> +
> +
> +
> +int
> +grub_strcmp (const char *s1, const char *s2)
> +{
> + while (*s1 && *s2)
> + {
> + if (*s1 != *s2)
> + break;
> +
> + s1++;
> + s2++;
> + }
> +
> + return (int) *s1 - (int) *s2;
> +}
> +
> +int
> +grub_strncmp (const char *s1, const char *s2, grub_size_t n)
> +{
> + if (n == 0)
> + return 0;
> +
> + while (*s1 && *s2 && --n)
> + {
> + if (*s1 != *s2)
> + break;
> +
> + s1++;
> + s2++;
> + }
> +
> + return (int) *s1 - (int) *s2;
> +}
> +
> +
> +int
> +grub_strcasecmp (const char *s1, const char *s2)
> +{
> + while (*s1 && *s2)
> + {
> + if (grub_tolower (*s1) != grub_tolower (*s2))
> + break;
> +
> + s1++;
> + s2++;
> + }
> +
> + return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
> +}
> +
> +
> +int
> +grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
> +{
> + if (n == 0)
> + return 0;
> +
> + while (*s1 && *s2 && --n)
> + {
> + if (grub_tolower (*s1) != grub_tolower (*s2))
> + break;
> +
> + s1++;
> + s2++;
> + }
> +
> + return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
> +}
> +
> +void *
> +grub_memmove (void *dest, const void *src, grub_size_t n)
> +{
> + char *d = (char *) dest;
> + const char *s = (const char *) src;
> +
> + if (d < s)
> + while (n--)
> + *d++ = *s++;
> + else
> + {
> + d += n;
> + s += n;
> +
> + while (n--)
> + *--d = *--s;
> + }
> +
> + return dest;
> +}
> +
> +
> +void *
> +grub_malloc (grub_size_t size)
> +{
> + void *ret;
> + ret = malloc (size);
> + if (!ret)
> + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
> + return ret;
> +}
> +
> +
> +
> +void
> +grub_free (void *ptr)
> +{
> + free (ptr);
> +}
> +
> +
> +void *
> +grub_memset (void *s, int c, grub_size_t n)
> +{
> + unsigned char *p = (unsigned char *) s;
> +
> + while (n--)
> + *p++ = (unsigned char) c;
> +
> + return s;
> +}
> +
> +int
> +grub_memcmp (const void *s1, const void *s2, grub_size_t n)
> +{
> + const char *t1 = s1;
> + const char *t2 = s2;
> +
> + while (n--)
> + {
> + if (*t1 != *t2)
> + return (int) *t1 - (int) *t2;
> +
> + t1++;
> + t2++;
> + }
> +
> + return 0;
> +}
> +
> +
> +void *
> +grub_zalloc (grub_size_t size)
> +{
> + void *ret;
> +
> + ret = grub_malloc (size);
> + if (!ret)
> + return NULL;
> + memset (ret, 0, size);
> + return ret;
> +}
> +
> +/* Divide N by D, return the quotient, and store the remainder in *R. */
> +grub_uint64_t
> +grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
> +{
> + /* This algorithm is typically implemented by hardware. The idea
> + is to get the highest bit in N, 64 times, by keeping
> + upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
> + represents the high 64 bits in 128-bits space. */
> + unsigned bits = 64;
> + unsigned long long q = 0;
> + unsigned m = 0;
> +
> + /* Skip the slow computation if 32-bit arithmetic is possible. */
> + if (n < 0xffffffff)
> + {
> + if (r)
> + *r = ((grub_uint32_t) n) % d;
> +
> + return ((grub_uint32_t) n) / d;
> + }
> +
> + while (bits--)
> + {
> + m <<= 1;
> +
> + if (n & (1ULL << 63))
> + m |= 1;
> +
> + q <<= 1;
> + n <<= 1;
> +
> + if (m >= d)
> + {
> + q |= 1;
> + m -= d;
> + }
> + }
> +
> + if (r)
> + *r = m;
> +
> + return q;
> +}
> +
> +
> +
> +/* Convert UTF-16 to UTF-8. */
> +grub_uint8_t *
> +grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
> + grub_size_t size)
> +{
> + grub_uint32_t code_high = 0;
> +
> + while (size--)
> + {
> + grub_uint32_t code = *src++;
> +
> + if (code_high)
> + {
> + if (code >= 0xDC00 && code <= 0xDFFF)
> + {
> + /* Surrogate pair. */
> + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) +
> 0x10000;
> +
> + *dest++ = (code >> 18) | 0xF0;
> + *dest++ = ((code >> 12) & 0x3F) | 0x80;
> + *dest++ = ((code >> 6) & 0x3F) | 0x80;
> + *dest++ = (code & 0x3F) | 0x80;
> + }
> + else
> + {
> + /* Error... */
> + *dest++ = '?';
> + }
> +
> + code_high = 0;
> + }
> + else
> + {
> + if (code <= 0x007F)
> + *dest++ = code;
> + else if (code <= 0x07FF)
> + {
> + *dest++ = (code >> 6) | 0xC0;
> + *dest++ = (code & 0x3F) | 0x80;
> + }
> + else if (code >= 0xD800 && code <= 0xDBFF)
> + {
> + code_high = code;
> + continue;
> + }
> + else if (code >= 0xDC00 && code <= 0xDFFF)
> + {
> + /* Error... */
> + *dest++ = '?';
> + }
> + else
> + {
> + *dest++ = (code >> 12) | 0xE0;
> + *dest++ = ((code >> 6) & 0x3F) | 0x80;
> + *dest++ = (code & 0x3F) | 0x80;
> + }
> + }
> + }
> +
> + return dest;
> +}
> +
> +
> +
> +
> +
> +
> +static void print_byte(char *p, int len)
> +{
> + printf("\n****************start print %s********************\n", p);
> + int i;
> + unsigned char *pb = (unsigned char*)p;
> + for(i = 0; i < len; i++)
> + {
> + printf("0x%02x,", pb[i]);
> + }
> + printf("\n**********************end**************************\n");
> +}
> +
> +
> +
> +#include <iconv.h>
> +#define OUTLEN 256
> +
> +
> +//代码转换:从一种编码转为另一种编码
> +static int code_convert(const char *from_charset, const char
> *to_charset,
> + char *inbuf, size_t inlen,
> + char *outbuf, size_t outlen)
> +{
> + iconv_t cd;
> + int rc;
> + char **pin = &inbuf;
> + char **pout = &outbuf;
> +
> + //printf("sizeof(int)=%d, sizeof(size_t)=%d\n", sizeof(int),
> sizeof(size_t));
> + cd = iconv_open(to_charset, from_charset);
> + if (cd==0) return -1;
> + memset(outbuf, 0, outlen);
> + if (iconv(cd, pin, &inlen, pout, &outlen)==-1) return -1;
> + iconv_close(cd);
> + return 0;
> +}
> +//UNICODE码转为GB2312码
> +int u2g(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
> +{
> + return code_convert("utf-8", "gb2312", inbuf, inlen, outbuf, outlen);
> +}
> +//GB2312码转为UNICODE码
> +int g2u(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
> +{
> + return code_convert("gb2312", "utf-8", inbuf, inlen, outbuf, outlen);
> +}
> +
> +
> +
> +void test(void)
> +{
> + //字符编码转换=锘垮?绗????浆??
> + char in_utf8[] =
> {0xe5,0xad,0x97,0xe7,0xac,0xa6,0xe7,0xbc,0x96,0xe7,0xa0,0x81,0xe8,0xbd,0xac,0xe6,0x8d,0xa2};
> + char *in_gb2312 = (char*) "字符编码转换";
> + char out[OUTLEN];
> + int rc;
> + //utf8码转为gb2312码
> + rc = u2g(in_utf8, strlen(in_utf8), out, OUTLEN);
> + printf("utf8-->gb2312 out=%s\n", out);
> + print_byte(out, strlen(out));
> + //gb2312码转为utf8码
> + rc = g2u(in_gb2312, strlen(in_gb2312), out, OUTLEN);
> + print_byte(out, strlen(out));
> + printf("gb2312-->utf8 out=%s\n",out);
> +}
> +
> +
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/misc.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/misc.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/misc.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/misc.h 2012-12-28 16:02:41.012937846
> +0800
> @@ -0,0 +1,89 @@
> +#include "fs-types.h"
> +#include <stddef.h>
> +
> +
> +
> +
> +
> +#define grub_memcpy(d,s,n)grub_memmove ((d), (s), (n))
> +
> +
> +int
> +grub_isspace (int c);
> +
> +int
> +grub_tolower (int c);
> +
> +
> +char *
> +grub_strchr (const char *s, int c);
> +
> +
> +grub_size_t
> +grub_strlen (const char *s);
> +
> +
> +
> +char *
> +grub_strdup (const char *s);
> +
> +
> +
> +char *
> +grub_strndup (const char *s, grub_size_t n);
> +
> +
> +char *
> +grub_strncpy (char *dest, const char *src, int c);
> +
> +
> +int
> +grub_strcmp (const char *s1, const char *s2);
> +
> +int
> +grub_strncmp (const char *s1, const char *s2, grub_size_t n);
> +
> +int
> +grub_strcasecmp (const char *s1, const char *s2);
> +
> +int
> +grub_strncasecmp (const char *s1, const char *s2, grub_size_t n);
> +
> +void *
> +grub_memmove (void *dest, const void *src, grub_size_t n);
> +
> +int
> +grub_memcmp (const void *s1, const void *s2, grub_size_t n);
> +
> +void *
> +grub_malloc (grub_size_t size);
> +
> +void *
> +grub_memset (void *s, int c, grub_size_t n);
> +
> +void
> +grub_free (void *ptr);
> +
> +void *
> +grub_zalloc (grub_size_t size);
> +
> +grub_uint64_t
> +grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r);
> +
> +/* Convert UTF-16 to UTF-8. */
> +grub_uint8_t *
> +grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
> + grub_size_t size);
> +
> +
> +//UNICODE码转为GB2312码
> +int u2g(char *inbuf, size_t inlen, char *outbuf, size_t outlen);
> +//GB2312码转为UNICODE码
> +int g2u(char *inbuf, size_t inlen, char *outbuf, size_t outlen);
> +
> +
> +
> +void test(void);
> +
> +
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/ntfs.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/ntfs.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/ntfs.c 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/ntfs.c 2012-12-28 16:02:41.013937038
> +0800
> @@ -0,0 +1,1188 @@
> +/* ntfs.c - NTFS filesystem */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc.
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +
> +#include "misc.h"
> +#include "fshelp.h"
> +#include "ntfs.h"
> +#include "debug.h"
> +#include "grub_err.h"
> +#include "err.h"
> +
> +#define GRUB_DISK_SECTOR_SIZE 0x200
> +ntfscomp_func_t grub_ntfscomp_func;
> +
> +//important
> +//lcn is relative to start sector of the volume
> +static grub_off_t s_part_off_sector;
> +static grub_uint32_t s_bpb_bytes_per_sector;
> +int bdrv_pread_from_lcn_of_volum(BlockDriverState *bs, int64_t offset,
> + void *buf1, int count1)
> +{
> + return bdrv_pread(bs, s_part_off_sector * s_bpb_bytes_per_sector +
> offset,
> + buf1, count1);
> +}
> +
> +
> +static grub_err_t
> +fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic)
> +{
> + int ss;
> + char *pu;
> + grub_uint16_t us;
> +
> + DBG("%x-%x-%x-%x", buf[0], buf[1], buf[2], buf[3]);
> + if (grub_memcmp (buf, magic, 4))
> + return grub_error (GRUB_ERR_BAD_FS, "%s label not found", magic);
> +
> + ss = u16at (buf, 6) - 1;
> + if (ss * (int) data->blocksize != len * GRUB_DISK_SECTOR_SIZE)
> + return grub_error (GRUB_ERR_BAD_FS, "size not match",
> + ss * (int) data->blocksize,
> + len * GRUB_DISK_SECTOR_SIZE);
> + pu = buf + u16at (buf, 4);
> + us = u16at (pu, 0);
> + buf -= 2;
> + while (ss > 0)
> + {
> + buf += data->blocksize;
> + pu += 2;
> + if (u16at (buf, 0) != us)
> + return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match");
> + v16at (buf, 0) = v16at (pu, 0);
> + ss--;
> + }
> +
> + return 0;
> +}
> +
> +static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
> + grub_uint32_t mftno);
> +static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
> + grub_disk_addr_t ofs, grub_size_t len,
> + int cached,
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset,
> + unsigned length,
> + void *closure),
> + void *closure);
> +
> +static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char
> *dest,
> + grub_disk_addr_t ofs, grub_size_t len,
> + int cached,
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset,
> + unsigned length,
> + void *closure),
> + void *closure);
> +
> +static void
> +init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
> +{
> + at->mft = mft;
> + at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0;
> + at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
> + at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
> +}
> +
> +static void
> +free_attr (struct grub_ntfs_attr *at)
> +{
> + grub_free (at->emft_buf);
> + grub_free (at->edat_buf);
> + grub_free (at->sbuf);
> +}
> +
> +static char *
> +find_attr (struct grub_ntfs_attr *at, unsigned char attr)
> +{
> + grub_off_t off_bytes1;
> + grub_off_t off_bytes2;
> +
> + if (at->flags & AF_ALST)
> + {
> + DBG("!!!!!!\nin a attr list======");
> + retry:
> + while (at->attr_nxt < at->attr_end)
> + {
> + at->attr_cur = at->attr_nxt;
> + at->attr_nxt += u16at (at->attr_cur, 4);
> + if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
> + {
> + char *new_pos;
> +
> + if (at->flags & AF_MMFT)
> + {
> + DBG("in AF_MMFT......");
> + off_bytes1 = (grub_off_t)(v32at (at->attr_cur, 0x10)) << BLK_SHR;
> + off_bytes2 = (grub_off_t)(v32at (at->attr_cur, 0x14)) << BLK_SHR;
> + if ((bdrv_pread
> + (at->mft->data->bs, off_bytes1,
> + at->emft_buf, 512))
> + ||
> + (bdrv_pread
> + (at->mft->data->bs, off_bytes2,
> + at->emft_buf + 512, 512)))
> + return NULL;
> +
> + if (fixup
> + (at->mft->data, at->emft_buf, at->mft->data->mft_size,
> + (char*)"FILE"))
> + return NULL;
> + }
> + else
> + {
> + DBG("read extend mft FR======");
> + if (read_mft (at->mft->data, at->emft_buf,
> + u32at (at->attr_cur, 0x10)))
> + return NULL;
> + }
> +
> + new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
> + while ((unsigned char) *new_pos != 0xFF)
> + {
> + DBG("new pos in extend mft======");
> + if (((unsigned char) *new_pos ==
> + (unsigned char) *at->attr_cur)
> + && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
> + {
> + return new_pos;
> + }
> + new_pos += u16at (new_pos, 4);
> + }
> + grub_error (GRUB_ERR_BAD_FS,
> + "can\'t find 0x%X in attribute list",
> + (unsigned char) *at->attr_cur);
> + return NULL;
> + }
> + }
> + return NULL;
> + }
> +
> +
> + DBG("not in a attr list======");
> + at->attr_cur = at->attr_nxt;
> + while ((unsigned char) *at->attr_cur != 0xFF)
> + {
> + at->attr_nxt += u16at (at->attr_cur, 4);
> + if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST)
> + at->attr_end = at->attr_cur;
> + if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
> + {
> + DBG("found======");
> + return at->attr_cur;
> + }
> + at->attr_cur = at->attr_nxt;
> + }
> +
> +
> + if (at->attr_end)
> + {
> + DBG("searching in attr list======");
> + char *pa;
> +
> + at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR);
> + if (at->emft_buf == NULL)
> + return NULL;
> +
> + pa = at->attr_end;
> + if (pa[8])
> + {
> + int n;
> +
> + n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1)
> + & (~(GRUB_DISK_SECTOR_SIZE - 1)));
> + at->attr_cur = at->attr_end;
> + at->edat_buf = grub_malloc (n);
> + if (!at->edat_buf)
> + return NULL;
> + if (read_data (at, pa, at->edat_buf, 0, n, 0, 0, 0))
> + {
> + grub_error (GRUB_ERR_BAD_FS,
> + "fail to read non-resident attribute list");
> + return NULL;
> + }
> + at->attr_nxt = at->edat_buf;
> + at->attr_end = at->edat_buf + u32at (pa, 0x30);
> + }
> + else
> + {
> + at->attr_nxt = at->attr_end + u16at (pa, 0x14);
> + at->attr_end = at->attr_end + u32at (pa, 4);
> + }
> + at->flags |= AF_ALST;
> + while (at->attr_nxt < at->attr_end)
> + {
> + if (((unsigned char) *at->attr_nxt == attr) || (attr == 0))
> + break;
> + at->attr_nxt += u16at (at->attr_nxt, 4);
> + }
> + if (at->attr_nxt >= at->attr_end)
> + {
> + DBG("not found in list");
> + return NULL;
> + }
> + DBG("found in attr list======");
> + if ((at->flags & AF_MMFT) && (attr == AT_DATA))
> + {
> + DBG("AF_GPOS!!!!!!======");
> + at->flags |= AF_GPOS;
> + at->attr_cur = at->attr_nxt;
> + pa = at->attr_cur;
> + v32at (pa, 0x10) = at->mft->data->mft_start;
> + v32at (pa, 0x14) = at->mft->data->mft_start + 1;
> + pa = at->attr_nxt + u16at (pa, 4);
> + while (pa < at->attr_end)
> + {
> + if ((unsigned char) *pa != attr)
> + break;
> + if (read_attr
> + (at, pa + 0x10,
> + u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR),
> + at->mft->data->mft_size << BLK_SHR, 0, 0, 0))
> + return NULL;
> + pa += u16at (pa, 4);
> + }
> + at->attr_nxt = at->attr_cur;
> + at->flags &= ~AF_GPOS;
> + }
> +
> + DBG("goto retry======");
> + goto retry;
> + }
> +
> + DBG("return NULL");
> + return NULL;
> +}
> +
> +static char *
> +locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
> + unsigned char attr)
> +{
> +
> +
> + char *pa;
> +
> + init_attr (at, mft);
> +
> + DBG("\n!!!!!!\nlocating attr=0x%02x, at->flag=0x%02x============",
> + attr, at->flags);
> + if ((pa = find_attr (at, attr)) == NULL)
> + {
> + DBG("1=========not found");
> + return NULL;
> + }
> + if ((at->flags & AF_ALST) == 0)
> + {
> + DBG("2=======not a attr list, continue searching");
> + while (1)
> + {
> + if ((pa = find_attr (at, attr)) == NULL)
> + break;
> + if (at->flags & AF_ALST)
> + {
> + DBG("3==========in a attr list,found");
> + return pa;
> + }
> + }
> + DBG("4========start searching all over again");
> + grub_errno = GRUB_ERR_NONE;
> + free_attr (at);
> + init_attr (at, mft);
> + pa = find_attr (at, attr);
> + }
> + DBG("locate finish======\n\n");
> + return pa;
> +}
> +
> +static char *
> +read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
> +{
> + grub_disk_addr_t r, v;
> +
> + r = 0;
> + v = 1;
> +
> + while (nn--)
> + {
> + r += v * (*(unsigned char *) (run++));
> + v <<= 8;
> + }
> +
> + if ((sig) && (r & (v >> 1)))
> + r -= v;
> +
> + *val = r;
> + return run;
> +}
> +
> +grub_err_t
> +grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
> +{
> + DBG("read run list");
> +
> + int c1, c2;
> + grub_disk_addr_t val;
> + char *run;
> +
> + run = ctx->cur_run;
> +retry:
> + c1 = ((unsigned char) (*run) & 0xF);
> + c2 = ((unsigned char) (*run) >> 4);
> + if (!c1)
> + {
> + if ((ctx->attr) && (ctx->attr->flags & AF_ALST))
> + {
> + void (*save_hook) (grub_disk_addr_t sector,
> + unsigned offset,
> + unsigned length,
> + void *closure);
> +
> + //save_hook = ctx->comp.bs->read_hook;
> + //ctx->comp.bs->read_hook = 0;
> + run = find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur);
> + //ctx->comp.bs->read_hook = save_hook;
> + if (run)
> + {
> + if (run[8] == 0)
> + return grub_error (GRUB_ERR_BAD_FS,
> + "$DATA should be non-resident");
> +
> + run += u16at (run, 0x20);
> + ctx->curr_lcn = 0;
> + goto retry;
> + }
> + }
> + return grub_error (GRUB_ERR_BAD_FS, "run list overflown");
> + }
> + run = read_run_data (run + 1, c1, &val, 0); /* length of current VCN */
> + ctx->curr_vcn = ctx->next_vcn;
> + ctx->next_vcn += val;
> + run = read_run_data (run, c2, &val, 1); /* offset to previous LCN */
> + ctx->curr_lcn += val;
> + if (val == 0)
> + ctx->flags |= RF_BLNK;
> + else
> + ctx->flags &= ~RF_BLNK;
> + ctx->cur_run = run;
> + return 0;
> +}
> +
> +static grub_disk_addr_t
> +grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
> +{
> + struct grub_ntfs_rlst *ctx;
> +
> + ctx = (struct grub_ntfs_rlst *) node;
> + if (block >= ctx->next_vcn)
> + {
> + if (grub_ntfs_read_run_list (ctx))
> + return -1;
> + return ctx->curr_lcn;
> + }
> + else
> + return (ctx->flags & RF_BLNK) ? 0 : (block -
> + ctx->curr_vcn + ctx->curr_lcn);
> +}
> +
> +static grub_err_t
> +read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
> + grub_disk_addr_t ofs, grub_size_t len, int cached,
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset,
> + unsigned length,
> + void *closure),
> + void *closure)
> +{
> + grub_disk_addr_t vcn;
> + struct grub_ntfs_rlst cc, *ctx;
> +
> + if (len == 0)
> + return 0;
> +
> + grub_memset (&cc, 0, sizeof (cc));
> + ctx = &cc;
> + ctx->attr = at;
> + ctx->comp.spc = at->mft->data->spc;
> + ctx->comp.bs = at->mft->data->bs;
> +
> + if (pa[8] == 0)
> + {
> + if (ofs + len > u32at (pa, 0x10))
> + return grub_error (GRUB_ERR_BAD_FS, "read out of range");
> + grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
> + return 0;
> + }
> +
> + if (u16at (pa, 0xC) & FLAG_COMPRESSED)
> + ctx->flags |= RF_COMP;
> + else
> + ctx->flags &= ~RF_COMP;
> + ctx->cur_run = pa + u16at (pa, 0x20);
> +
> + if (ctx->flags & RF_COMP)
> + {
> + if (!cached)
> + return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed");
> +
> + if (at->sbuf)
> + {
> + if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
> + {
> + grub_disk_addr_t n;
> +
> + n = COM_LEN - (ofs - at->save_pos);
> + if (n > len)
> + n = len;
> +
> + grub_memcpy (dest, at->sbuf + ofs - at->save_pos, n);
> + if (n == len)
> + return 0;
> +
> + dest += n;
> + len -= n;
> + ofs += n;
> + }
> + }
> + else
> + {
> + at->sbuf = grub_malloc (COM_LEN);
> + if (at->sbuf == NULL)
> + return grub_errno;
> + at->save_pos = 1;
> + }
> +
> + vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC /
> ctx->comp.spc);
> + ctx->target_vcn &= ~0xF;
> + }
> + else
> + vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc,
> 0);
> +
> + ctx->next_vcn = u32at (pa, 0x10);
> + ctx->curr_lcn = 0;
> + while (ctx->next_vcn <= ctx->target_vcn)
> + {
> + if (grub_ntfs_read_run_list (ctx))
> + return grub_errno;
> + }
> +
> + if (at->flags & AF_GPOS)
> + {
> + grub_disk_addr_t st0, st1;
> + grub_uint32_t m;
> +
> + grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
> +
> + st0 =
> + (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
> + st1 = st0 + 1;
> + if (st1 ==
> + (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
> + {
> + if (grub_ntfs_read_run_list (ctx))
> + return grub_errno;
> + st1 = ctx->curr_lcn * ctx->comp.spc;
> + }
> + v32at (dest, 0) = st0;
> + v32at (dest, 4) = st1;
> + return 0;
> + }
> +
> + if (!(ctx->flags & RF_COMP))
> + {
> + unsigned int pow;
> +
> + if (!grub_fshelp_log2blksize (ctx->comp.spc, &pow))
> + grub_fshelp_read_file (ctx->comp.bs, (grub_fshelp_node_t) ctx,
> + read_hook, closure, ofs, len, dest,
> + grub_ntfs_read_block, ofs + len, pow);
> + return grub_errno;
> + }
> +
> + return (grub_ntfscomp_func) ? grub_ntfscomp_func (at, dest, ofs, len,
> ctx,
> + vcn) :
> + grub_error (GRUB_ERR_BAD_FS, "ntfscomp module not loaded");
> +}
> +
> +static grub_err_t
> +read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
> + grub_size_t len, int cached,
> + void (*read_hook) (grub_disk_addr_t sector,
> + unsigned offset,
> + unsigned length,
> + void *closure),
> + void *closure)
> +{
> + DBG("read attr");
> +
> + char *save_cur;
> + unsigned char attr;
> + char *pp;
> + grub_err_t ret;
> +
> + save_cur = at->attr_cur;
> + at->attr_nxt = at->attr_cur;
> + attr = (unsigned char) *at->attr_nxt;
> + if (at->flags & AF_ALST)
> + {
> + char *pa;
> + grub_disk_addr_t vcn;
> +
> + vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0);
> + pa = at->attr_nxt + u16at (at->attr_nxt, 4);
> + while (pa < at->attr_end)
> + {
> + if ((unsigned char) *pa != attr)
> + break;
> + if (u32at (pa, 8) > vcn)
> + break;
> + at->attr_nxt = pa;
> + pa += u16at (pa, 4);
> + }
> + }
> + pp = find_attr (at, attr);
> + if (pp)
> + ret = read_data (at, pp, dest, ofs, len, cached, read_hook, closure);
> + else
> + ret =
> + (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS,
> + "attribute not found");
> + at->attr_cur = save_cur;
> + return ret;
> +}
> +
> +static grub_err_t
> +read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
> +{
> + if (read_attr
> + (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size)
> << BLK_SHR,
> + data->mft_size << BLK_SHR, 0, 0, 0))
> + return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno);
> + return fixup (data, buf, data->mft_size, (char*)"FILE");
> +}
> +
> +static grub_err_t
> +init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
> +{
> + DBG("init file");
> +
> + unsigned short flag;
> +
> + mft->inode_read = 1;
> +
> + mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
> + if (mft->buf == NULL)
> + return grub_errno;
> +
> + if (read_mft (mft->data, mft->buf, mftno))
> + return grub_errno;
> +
> + flag = u16at (mft->buf, 0x16);
> + if ((flag & 1) == 0)
> + return grub_error (GRUB_ERR_BAD_FS, "MFT 0x%X is not in use", mftno);
> +
> + if ((flag & 2) == 0)
> + {
> + char *pa;
> +
> + pa = locate_attr (&mft->attr, mft, AT_DATA);
> + if (pa == NULL)
> + return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno);
> +
> + if (!pa[8])
> + mft->size = u32at (pa, 0x10);
> + else
> + mft->size = u64at (pa, 0x30);
> +
> + if ((mft->attr.flags & AF_ALST) == 0)
> + mft->attr.attr_end = 0; /* Don't jump to attribute list */
> + }
> + else
> + init_attr (&mft->attr, mft);
> +
> + return 0;
> +}
> +
> +static void
> +free_file (struct grub_ntfs_file *mft)
> +{
> + free_attr (&mft->attr);
> + grub_free (mft->buf);
> +}
> +
> +static int
> +list_file (struct grub_ntfs_file *diro, char *pos,
> + int (*hook) (const char *filename,
> + enum grub_fshelp_filetype filetype,
> + grub_fshelp_node_t node,
> + void *closure),
> + void *closure)
> +{
> + char *np;
> + int ns;
> +
> + while (1)
> + {
> + char *ustr, namespace;
> + char* gbstr;
> +
> + if (pos[0xC] & 2) /* end signature */
> + break;
> +
> + np = pos + 0x50;
> + ns = (unsigned char) *(np++);
> + namespace = *(np++);
> +
> + /*
> + * Ignore files in DOS namespace, as they will reappear as Win32
> + * names.
> + */
> + if ((ns) && (namespace != 2))
> + {
> + enum grub_fshelp_filetype type;
> + struct grub_ntfs_file *fdiro;
> +
> + if (u16at (pos, 4))
> + {
> + grub_error (GRUB_ERR_BAD_FS, "64-bit MFT number");
> + return 0;
> + }
> +
> + type =
> + (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR :
> + GRUB_FSHELP_REG;
> +
> + fdiro = grub_zalloc (sizeof (struct grub_ntfs_file));
> + if (!fdiro)
> + return 0;
> +
> + fdiro->data = diro->data;
> + fdiro->ino = u32at (pos, 0);
> +
> + ustr = grub_malloc (ns * 4 + 1);
> + gbstr = grub_malloc(ns * 2 + 1);
> + if (ustr == NULL || gbstr == NULL)
> + return 0;
> + *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np,
> + ns) = '\0';
> + u2g(ustr, strlen(ustr), gbstr, ns * 2 + 1);
> + DBG("gbstr=%s", gbstr);
> + if (namespace)
> + type |= GRUB_FSHELP_CASE_INSENSITIVE;
> +
> + if (hook (gbstr, type, fdiro, closure))
> + {
> + grub_free (ustr);
> + grub_free (gbstr);
> + return 1;
> + }
> + grub_free(gbstr);
> + grub_free (ustr);
> + }
> + pos += u16at (pos, 8);
> + }
> + return 0;
> +}
> +
> +static int
> +grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
> + int (*hook) (const char *filename,
> + enum grub_fshelp_filetype filetype,
> + grub_fshelp_node_t node,
> + void *closure),
> + void *closure)
> +{
> + unsigned char *bitmap;
> + struct grub_ntfs_attr attr, *at;
> + char *cur_pos, *indx, *bmp;
> + int ret = 0;
> + grub_size_t bitmap_len;
> + struct grub_ntfs_file *mft;
> +
> + mft = (struct grub_ntfs_file *) dir;
> +
> + if (!mft->inode_read)
> + {
> + if (init_file (mft, mft->ino))
> + return 0;
> + }
> +
> + indx = NULL;
> + bmp = NULL;
> +
> + at = &attr;
> + init_attr (at, mft);
> + while (1)
> + {
> + if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL)
> + {
> + grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
> + goto done;
> + }
> +
> + /* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */
> + if ((u32at (cur_pos, 8) != 0x180400) ||
> + (u32at (cur_pos, 0x18) != 0x490024) ||
> + (u32at (cur_pos, 0x1C) != 0x300033))
> + continue;
> + cur_pos += u16at (cur_pos, 0x14);
> + if (*cur_pos != 0x30) /* Not filename index */
> + continue;
> + break;
> + }
> +
> + cur_pos += 0x10; /* Skip index root */
> + ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, closure);
> + if (ret)
> + goto done;
> +
> +
> + bitmap = NULL;
> + bitmap_len = 0;
> + free_attr (at);
> + init_attr (at, mft);
> + while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL)
> + {
> + int ofs;
> +
> + ofs = (unsigned char) cur_pos[0xA];
> + /* Namelen=4, Name="$I30" */
> + if ((cur_pos[9] == 4) &&
> + (u32at (cur_pos, ofs) == 0x490024) &&
> + (u32at (cur_pos, ofs + 4) == 0x300033))
> + {
> + int is_resident = (cur_pos[8] == 0);
> +
> + bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) :
> + u32at (cur_pos, 0x28));
> +
> + bmp = grub_malloc (bitmap_len);
> + if (bmp == NULL)
> + goto done;
> +
> + if (is_resident)
> + {
> + grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)),
> + bitmap_len);
> + }
> + else
> + {
> + if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0, 0))
> + {
> + grub_error (GRUB_ERR_BAD_FS,
> + "fails to read non-resident $BITMAP");
> + goto done;
> + }
> + bitmap_len = u32at (cur_pos, 0x30);
> + }
> +
> + bitmap = (unsigned char *) bmp;
> + break;
> + }
> + }
> +
> + free_attr (at);
> + cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION);
> + while (cur_pos != NULL)
> + {
> + /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */
> + if ((u32at (cur_pos, 8) == 0x400401) &&
> + (u32at (cur_pos, 0x40) == 0x490024) &&
> + (u32at (cur_pos, 0x44) == 0x300033))
> + break;
> + cur_pos = find_attr (at, AT_INDEX_ALLOCATION);
> + }
> +
> + if ((!cur_pos) && (bitmap))
> + {
> + grub_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION");
> + goto done;
> + }
> +
> + if (bitmap)
> + {
> + grub_disk_addr_t v, i;
> +
> + indx = grub_malloc (mft->data->idx_size << BLK_SHR);
> + if (indx == NULL)
> + goto done;
> +
> + v = 1;
> + for (i = 0; i < (grub_disk_addr_t)bitmap_len * 8; i++)
> + {
> + if (*bitmap & v)
> + {
> + if ((read_attr
> + (at, indx, i * (mft->data->idx_size << BLK_SHR),
> + (mft->data->idx_size << BLK_SHR), 0, 0, 0))
> + || (fixup (mft->data, indx, mft->data->idx_size, (char*)"INDX")))
> + goto done;
> + ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook,
> + closure);
> + if (ret)
> + goto done;
> + }
> + v <<= 1;
> + if (v >= 0x100)
> + {
> + v = 1;
> + bitmap++;
> + }
> + }
> + }
> +
> +done:
> + free_attr (at);
> + grub_free (indx);
> + grub_free (bmp);
> +
> + return ret;
> +}
> +
> +
> +struct grub_ntfs_data *
> +grub_ntfs_mount (BlockDriverState* bs, grub_uint32_t part_off_sector)
> +{
> + struct grub_ntfs_bpb bpb;
> + struct grub_ntfs_data *data = 0;
> + grub_off_t off_bytes = (grub_off_t)part_off_sector << BLK_SHR;
> +
> + if (!bs)
> + goto fail;
> +
> + data = (struct grub_ntfs_data *) grub_zalloc (sizeof (*data));
> + if (!data)
> + goto fail;
> +
> + data->bs = bs;
> +
> + /* Read the BPB. */
> + if (bdrv_pread (bs, off_bytes, &bpb, sizeof (bpb)) != sizeof(bpb))
> + {
> + DBG("read bpb err!");
> + goto fail;
> + }
> + if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4))
> + {
> + DBG("bpb.oem_name=%s, not ntfs", bpb.oem_name);
> + goto fail;
> + }
> + data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector);
> + data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR);
> +
> + if (bpb.clusters_per_mft > 0)
> + data->mft_size = data->spc * bpb.clusters_per_mft;
> + else
> + data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR);
> +
> + if (bpb.clusters_per_index > 0)
> + data->idx_size = data->spc * bpb.clusters_per_index;
> + else
> + data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR);
> +
> + data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
> +
> + if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX))
> + goto fail;
> +
> + data->mmft.data = data;
> + data->cmft.data = data;
> +
> + data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR);
> + if (!data->mmft.buf)
> + goto fail;
> +
> + s_bpb_bytes_per_sector = (bpb.bytes_per_sector);
> + s_part_off_sector = part_off_sector;
> + DBG("bpb.bytes_per_sector=blocksize=%u\n"
> + "bpb.sector_per_cluster=%u\n"
> + "data->blocksize=%u\n"
> + "data->spc=%u\n"
> + "bpb.clusters_per_mft=%d\n"
> + "data->mft_size=%u\n"
> + "bpb.total_sectors=%zd\n"
> + "bpb.mft_lcn=%zd\n"
> + "data->mft_start=%u\n",
> + (bpb.bytes_per_sector), (bpb.sectors_per_cluster),
> + (data->blocksize), (data->spc),
> + (bpb.clusters_per_mft), (data->mft_size),
> + (bpb.num_total_sectors),
> + (grub_le_to_cpu64(bpb.mft_lcn)), (data->mft_start));
> +
> + off_bytes = (grub_off_t)data->mft_start << BLK_SHR;
> + grub_uint32_t len = data->mft_size << BLK_SHR;
> + if (bdrv_pread_from_lcn_of_volum(bs, off_bytes,
> + data->mmft.buf, len) != len)
> + {
> + DBG("read mmft error!");
> + goto fail;
> + }
> + data->uuid = grub_le_to_cpu64 (bpb.num_serial);
> +
> + if (fixup (data, data->mmft.buf, data->mft_size, (char*)"FILE"))
> + goto fail;
> +
> + if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA))
> + {
> + DBG("locate_attr AT_DATA in mmft failed! ");
> + goto fail;
> + }
> + if (init_file (&data->cmft, FILE_ROOT))
> + {
> + DBG("init_file FILE_ROOT failed!");
> + goto fail;
> + }
> + return data;
> +
> +fail:
> + grub_error (GRUB_ERR_BAD_FS, "not an ntfs filesystem");
> +
> + if (data)
> + {
> + free_file (&data->mmft);
> + free_file (&data->cmft);
> + grub_free (data);
> + }
> + return 0;
> +}
> +
> +struct grub_ntfs_dir_closure
> +{
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure);
> + void *closure;
> + struct grub_ntfs_file file;
> +};
> +
> +static int
> +iterate (const char *filename,
> + enum grub_fshelp_filetype filetype,
> + grub_fshelp_node_t node,
> + void *closure)
> +{
> + struct grub_ntfs_dir_closure *c = closure;
> + struct grub_dirhook_info info;
> + grub_memset (&info, 0, sizeof (info));
> + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
> + c->file.data = node->data;
> + c->file.ino = node->ino;
> + grub_free (node);
> +
> +
> + if(init_file(&c->file, c->file.ino))
> + {
> + errx(1, "iterate(): init_file error!\n");
> + }
> + else
> + {
> + DBG("......current file mft read successfully!\n");
> + }
> + char *pa = locate_attr(&c->file.attr,
> + &c->file, AT_STANDARD_INFORMATION);
> + if(NULL == pa)
> + {
> + errx(2, "no $STANDARD_INFORMATION in MFT 0x%x\n", c->file.ino);
> + }
> + grub_uint64_t date= 0;
> + if(read_attr(&c->file.attr, (char*)&date, 0, 8, 1, NULL, NULL))
> + {
> + errx(3, "read date error\n");
> + }
> + else
> + {
> +
> + info.time_ntfs = date;
> + DBG("......date: %zu\n", date);
> + }
> + DBG("......size of \'%s\': %zu\n", filename, (c->file.size));
> + info.filesize_ntfs = c->file.size;
> + free_file(&c->file);
> + return c->hook (filename, &info, c->closure);
> +}
> +
> +
> +#include "fs-time.h"
> +static int find_then_ls_hook(const char *filename,
> + const struct grub_dirhook_info *info, void *closure)
> +{
> + struct ls_ctrl* ctrl = (struct ls_ctrl*)closure;
> + DBG("detail=%d", ctrl->detail);
> + if('$' == *filename)
> + goto done;
> +
> + printf("%s", filename);
> + if(!ctrl->detail)
> + {
> + printf("\n");
> + goto done;
> + }
> + else
> + {
> + printf("\t");
> + }
> +
> + char buffer[50]={};
> + struct tm tm0;
> + struct tm* ptm= ntfs_utc2local(info->time_ntfs, &tm0);
> + if(NULL == ptm) errx(1, "ntfs_utc2local fail\n");
> +
> + printf("%zu\t", info->filesize_ntfs);
> + printf("%s\t", (info->dir ? "dir" : "file"));
> + strftime(buffer, 50, "%Y-%m-%d\t%H:%M:%S", ptm);
> + printf("%s", buffer);
> + //printf("%d-%d-%d\t", ptm->tm_year, ptm->tm_mon, ptm->tm_mday);
> + //printf("%d:%d:%d\t", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
> + printf("\n");
> +
> + done:
> + return 0; // 最终返回给iterate
> +}
> +
> +
> +
> +grub_err_t
> +grub_ntfs_ls (grub_file_t file, const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure),
> + void *closure)
> +{
> + struct grub_ntfs_data *data = 0;
> + struct grub_fshelp_node *fdiro = 0;
> + struct grub_ntfs_dir_closure c = {0};
> +
> + data = grub_ntfs_mount (file->bs, file->part_off_sector);
> + if (!data)
> + {
> + DBG("mount failed!");
> + goto fail;
> + }
> + grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir,
> 0,
> + 0, GRUB_FSHELP_DIR);
> +
> +
> + if (grub_errno)
> + goto fail;
> +
> + c.hook = (hook ? hook : find_then_ls_hook);
> + c.closure = closure;
> + grub_ntfs_iterate_dir (fdiro, iterate, &c);
> +
> +fail:
> + if ((fdiro) && (fdiro != &data->cmft))
> + {
> + free_file (fdiro);
> + grub_free (fdiro);
> + }
> + if (data)
> + {
> + free_file (&data->mmft);
> + free_file (&data->cmft);
> + grub_free (data);
> + }
> +
> +
> + return grub_errno;
> +}
> +
> +grub_err_t
> +grub_ntfs_open (grub_file_t file, const char *name)
> +{
> + struct grub_ntfs_data *data = 0;
> + struct grub_fshelp_node *mft = 0;
> +
> +
> + data = grub_ntfs_mount (file->bs, file->part_off_sector);
> + if (!data)
> + {
> + DBG("mount failed!");
> + goto fail;
> + }
> + grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir, 0,
> + 0, GRUB_FSHELP_REG);
> +
> + if (grub_errno)
> + goto fail;
> +
> + if (mft != &data->cmft)
> + {
> + free_file (&data->cmft);
> + grub_memcpy (&data->cmft, mft, sizeof (*mft));
> + grub_free (mft);
> + if (!data->cmft.inode_read)
> + {
> + if (init_file (&data->cmft, data->cmft.ino))
> + goto fail;
> + }
> + }
> +
> + file->size = data->cmft.size;
> + file->data = data;
> + file->offset = 0;
> +
> + return 0;
> +
> +fail:
> + if (data)
> + {
> + free_file (&data->mmft);
> + free_file (&data->cmft);
> + grub_free (data);
> + }
> +
> +
> + return grub_errno;
> +}
> +
> +grub_ssize_t
> +grub_ntfs_read (grub_file_t file, grub_off_t offset, grub_size_t len, char
> *buf)
> +{
> + struct grub_ntfs_file *mft;
> +
> + mft = &((struct grub_ntfs_data *) file->data)->cmft;
> + if (file->read_hook)
> + mft->attr.save_pos = 1;
> +
> + read_attr (&mft->attr, buf, offset, len, 1,
> + file->read_hook, file->closure);
> +
> + return (grub_errno) ? 0 : len;
> +}
> +
> +grub_err_t
> +grub_ntfs_close (grub_file_t file)
> +{
> + struct grub_ntfs_data *data;
> +
> + data = file->data;
> +
> + if (data)
> + {
> + free_file (&data->mmft);
> + free_file (&data->cmft);
> + grub_free (data);
> + }
> +
> +
> + return grub_errno;
> +}
> +
> +
> +
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/ntfs.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/ntfs.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/ntfs.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/ntfs.h 2012-12-28 16:02:41.014936701
> +0800
> @@ -0,0 +1,227 @@
> +/* ntfs.h - header for the NTFS filesystem */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2007,2009 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_NTFS_H
> +#define GRUB_NTFS_H 1
> +
> +
> +#include "block_int.h"
> +#include "fs-types.h"
> +#include "grub_err.h"
> +#include "fs-comm.h"
> +
> +#define FILE_MFT 0
> +#define FILE_MFTMIRR 1
> +#define FILE_LOGFILE 2
> +#define FILE_VOLUME 3
> +#define FILE_ATTRDEF 4
> +#define FILE_ROOT 5
> +#define FILE_BITMAP 6
> +#define FILE_BOOT 7
> +#define FILE_BADCLUS 8
> +#define FILE_QUOTA 9
> +#define FILE_UPCASE 10
> +
> +#define AT_STANDARD_INFORMATION 0x10
> +#define AT_ATTRIBUTE_LIST 0x20
> +#define AT_FILENAME 0x30
> +#define AT_OBJECT_ID 0x40
> +#define AT_SECURITY_DESCRIPTOR 0x50
> +#define AT_VOLUME_NAME 0x60
> +#define AT_VOLUME_INFORMATION 0x70
> +#define AT_DATA 0x80
> +#define AT_INDEX_ROOT 0x90
> +#define AT_INDEX_ALLOCATION 0xA0
> +#define AT_BITMAP 0xB0
> +#define AT_SYMLINK 0xC0
> +#define AT_EA_INFORMATION 0xD0
> +#define AT_EA 0xE0
> +
> +#define ATTR_READ_ONLY 0x1
> +#define ATTR_HIDDEN 0x2
> +#define ATTR_SYSTEM 0x4
> +#define ATTR_ARCHIVE 0x20
> +#define ATTR_DEVICE 0x40
> +#define ATTR_NORMAL 0x80
> +#define ATTR_TEMPORARY 0x100
> +#define ATTR_SPARSE 0x200
> +#define ATTR_REPARSE 0x400
> +#define ATTR_COMPRESSED 0x800
> +#define ATTR_OFFLINE 0x1000
> +#define ATTR_NOT_INDEXED 0x2000
> +#define ATTR_ENCRYPTED 0x4000
> +#define ATTR_DIRECTORY 0x10000000
> +#define ATTR_INDEX_VIEW 0x20000000
> +
> +#define FLAG_COMPRESSED 1
> +#define FLAG_ENCRYPTED 0x4000
> +#define FLAG_SPARSE 0x8000
> +
> +
> +#define GRUB_DISK_SECTOR_BITS 9
> +#define BLK_SHR GRUB_DISK_SECTOR_BITS
> +
> +#define MAX_MFT (1024 >> BLK_SHR)
> +#define MAX_IDX (16384 >> BLK_SHR)
> +
> +#define COM_LEN 4096
> +#define COM_LOG_LEN 12
> +#define COM_SEC (COM_LEN >> BLK_SHR)
> +
> +#define AF_ALST 1
> +#define AF_MMFT 2
> +#define AF_GPOS 4
> +
> +#define RF_COMP 1
> +#define RF_CBLK 2
> +#define RF_BLNK 4
> +
> +#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs))
> +
> +#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t))
> +#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t))
> +#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t))
> +
> +#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t)
> +#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t)
> +#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t)
> +
> +struct grub_ntfs_bpb
> +{
> + grub_uint8_t jmp_boot[3];
> + grub_uint8_t oem_name[8];
> + grub_uint16_t bytes_per_sector;
> + grub_uint8_t sectors_per_cluster;
> + grub_uint8_t reserved_1[7];
> + grub_uint8_t media;
> + grub_uint16_t reserved_2;
> + grub_uint16_t sectors_per_track;
> + grub_uint16_t num_heads;
> + grub_uint32_t num_hidden_sectors;
> + grub_uint32_t reserved_3[2];
> + grub_uint64_t num_total_sectors;
> + grub_uint64_t mft_lcn;
> + grub_uint64_t mft_mirr_lcn;
> + grub_int8_t clusters_per_mft;
> + grub_int8_t reserved_4[3];
> + grub_int8_t clusters_per_index;
> + grub_int8_t reserved_5[3];
> + grub_uint64_t num_serial;
> + grub_uint32_t checksum;
> +} __attribute__ ((packed));
> +
> +#define grub_ntfs_file grub_fshelp_node
> +
> +struct grub_ntfs_attr
> +{
> + int flags;
> + char *emft_buf, *edat_buf;
> + char *attr_cur, *attr_nxt, *attr_end;
> + grub_uint32_t save_pos;
> + char *sbuf;
> + struct grub_ntfs_file *mft;
> +};
> +
> +struct grub_fshelp_node
> +{
> + struct grub_ntfs_data *data;
> + char *buf;
> + grub_uint64_t size;
> + grub_uint32_t ino;
> + int inode_read;
> + struct grub_ntfs_attr attr;
> +};
> +
> +struct grub_ntfs_data
> +{
> + struct grub_ntfs_file cmft;
> + struct grub_ntfs_file mmft;
> + BlockDriverState* bs;
> + grub_uint32_t mft_size;
> + grub_uint32_t idx_size;
> + grub_uint32_t spc;
> + grub_uint32_t blocksize;
> + grub_uint32_t mft_start;
> + grub_uint64_t uuid;
> +};
> +
> +struct grub_ntfs_comp
> +{
> + BlockDriverState* bs;
> + int comp_head, comp_tail;
> + grub_uint32_t comp_table[16][2];
> + grub_uint32_t cbuf_ofs, cbuf_vcn, spc;
> + char *cbuf;
> +};
> +
> +struct grub_ntfs_rlst
> +{
> + int flags;
> + grub_disk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn;
> + char *cur_run;
> + struct grub_ntfs_attr *attr;
> + struct grub_ntfs_comp comp;
> +};
> +
> +
> +
> +
> +
> +
> +
> +typedef grub_err_t (*ntfscomp_func_t) (struct grub_ntfs_attr * at, char
> *dest,
> + grub_uint32_t ofs, grub_uint32_t len,
> + struct grub_ntfs_rlst * ctx,
> + grub_uint32_t vcn);
> +
> +extern ntfscomp_func_t grub_ntfscomp_func;
> +
> +grub_err_t grub_ntfs_read_run_list (struct grub_ntfs_rlst *ctx);
> +
> +
> +
> +
> +int bdrv_pread_from_lcn_of_volum(BlockDriverState *bs, int64_t offset,
> + void *buf1, int count1);
> +
> +struct grub_ntfs_data *
> +grub_ntfs_mount (BlockDriverState* bs, grub_uint32_t part_off_sector);
> +
> +
> +grub_err_t
> +grub_ntfs_ls (grub_file_t file, const char *path,
> + int (*hook) (const char *filename,
> + const struct grub_dirhook_info *info,
> + void *closure),
> + void *closure);
> +
> +grub_err_t
> +grub_ntfs_open (grub_file_t file, const char *name);
> +
> +
> +grub_ssize_t
> +grub_ntfs_read (grub_file_t file, grub_off_t offset,
> + grub_size_t len, char *buf);
> +
> +
> +grub_err_t
> +grub_ntfs_close (grub_file_t file);
> +
> +
> +#endif /* ! GRUB_NTFS_H */
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/partition.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/partition.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/partition.c 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/partition.c 2012-12-28
> 16:02:41.014936701 +0800
> @@ -0,0 +1,240 @@
> +#include "partition.h"
> +#include <err.h>
> +
> +static int is_full_zero(void *p, uint bytes)
> +{
> + int i = 0;
> + uint8_t *p1 = (uint8_t*)p;
> + while(i < bytes)
> + {
> + if(*p1 != 0)
> + {
> + return 0;
> + }else
> + {
> + i++;
> + p1++;
> + }
> + }
> + //printf("..........full zero......\n");
> + return 1;
> +}
> +
> +static void read_partition(uint8_t *p, struct partition_record *r)
> +{
> + r->bootable = p[0];
> + r->start_head = p[1];
> + r->start_cylinder = p[3] | ((p[2] << 2) & 0x0300);
> + r->start_sector = p[2] & 0x3f;
> + r->system = p[4];
> + r->end_head = p[5];
> + r->end_cylinder = p[7] | ((p[6] << 2) & 0x300);
> + r->end_sector = p[6] & 0x3f;
> + r->start_sector_abs = p[8] | p[9] << 8 | p[10] << 16 | p[11] << 24;
> + r->nb_sectors_abs = p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24;
> +}
> +
> +
> +
> +char* judge_fs(ls_partition_t* pt)
> +{
> + if(pt->part.system==0x0b || pt->part.system==0x01)
> + {
> + pt->fs_type = FS_FAT;
> + return (char*)"FAT32";
> + }
> + else if(pt->part.system==0x07)
> + {
> + pt->fs_type = FS_NTFS;
> + return (char*)"NTFS";
> + }
> + else
> + {
> + pt->fs_type = FS_UNKNOWN;
> + return (char*)"UNKNOWN";
> + }
> +}
> +
> +int enum_partition(BlockDriverState *bs, ls_partition_t* parts)
> +{
> + struct partition_record mbr[4];
> + uint8_t data[512];
> + int i;
> + int ext_partnum = 4;
> + struct partition_record ext[10];
> + uint8_t data1[512];
> + int j = 0;
> +
> + if (bdrv_read(bs, 0, data, 1))
> + errx(EINVAL, "error while reading");
> +
> + if (data[510] != 0x55 || data[511] != 0xaa)
> + {
> + errno = -EINVAL;
> + return -1;
> + }
> +
> + int k = 0;
> + for (i = 0; i < 4; i++)
> + {
> + read_partition(&data[446 + 16 * i], &mbr[i]);
> +
> + if (!mbr[i].nb_sectors_abs)
> + continue;
> + //printf("the %d partition:boot=0x%x, start=%u, system=0x%x, total=%u\t",
> + // i+1, mbr[i].bootable, mbr[i].start_sector_abs, mbr[i].system,
> mbr[i].nb_sectors_abs);
> + parts[k].part = mbr[i];
> + parts[k].id = i+1;
> + k++;
> + if (mbr[i].system == 0xF || mbr[i].system == 0x5)
> + {
> + //printf("is a extend partition......\n");
> + if (bdrv_read(bs, mbr[i].start_sector_abs, data1, 1))
> + errx(EINVAL, "error while reading");
> + ///////////////////////////
> + //dump ebr
> + ///////////////////////////
> + uint32_t ext_start_sector = mbr[i].start_sector_abs;
> + struct partition_record ext_next = {0};
> + while (1)
> + {
> + read_partition(&data1[446 + 16 * 0], &ext[j]);
> + //printf("the %dth partition:boot=0x%x, start=%u, system=0x%x,
> total=%u\t",
> + // ext_partnum+j+1, ext[j].bootable,
> ext[j].start_sector_abs+ext_start_sector,
> + // ext[j].system, ext[j].nb_sectors_abs);
> +
> +
> + if(0 != ext[j].nb_sectors_abs)
> + {
> + ext[j].start_sector_abs += ext_start_sector;
> + if(j > 0)
> + ext[j].start_sector_abs += ext_next.start_sector_abs;
> + parts[k].part = ext[j];
> + parts[k].id = ext_partnum + j +1;
> + k++;
> + j++;
> + }
> + else
> + {
> + printf("nb_sectors_abs=0>>>>>>>>>>>>\n");
> + }
> + //////////////////////
> + if(ext[j-1].system == 0xF )
> + {
> + printf("...............again extend.............\n");
> + ext_start_sector = ext[j-1].start_sector_abs + ext_start_sector;
> + if (bdrv_read(bs, ext_start_sector, data1, 1))
> + errx(EINVAL, "error while reading");
> + continue;
> + }
> + else
> + {
> + ;//printf("is a logical part\n");
> + }
> + /////////////////////
> + read_partition(&data1[446 + 16 * 1], &ext_next);
> + if (is_full_zero(&ext_next, sizeof(ext_next)))
> + break;
> +
> + if (bdrv_read(bs, ext_start_sector + ext_next.start_sector_abs , data1,
> 1))
> + errx(EINVAL, "error while reading");
> + }
> + }else
> + {
> + ;//printf("is a main partition......\n");
> + }
> + }
> +
> + return k;
> +}
> +
> +
> +
> +
> +
> +int find_partition(BlockDriverState *bs, int partition,
> + off_t *offset, off_t *size)
> +{
> + struct partition_record mbr[4];
> + uint8_t data[512];
> + int i;
> + int ext_partnum = 4;
> +
> +
> + if (bdrv_read(bs, 0, data, 1))
> + errx(EINVAL, "error while reading");
> +
> + if (data[510] != 0x55 || data[511] != 0xaa)
> + {
> + errno = -EINVAL;
> + return -1;
> + }
> +
> + int k = 0;
> + for (i = 0; i < 4; i++)
> + {
> + read_partition(&data[446 + 16 * i], &mbr[i]);
> +
> + if (!mbr[i].nb_sectors_abs)
> + continue;
> + //printf("the %d partition:", i+1);
> +
> + if (mbr[i].system == 0xF || mbr[i].system == 0x5)
> + {
> + //printf("is a extend partition......\n");
> + struct partition_record ext[10];
> + uint8_t data1[512];
> + int j = 0;
> +
> + if (bdrv_read(bs, mbr[i].start_sector_abs, data1, 1))
> + errx(EINVAL, "error while reading");
> +
> + uint32_t ext_start_sector = mbr[i].start_sector_abs;
> + struct partition_record ext_next = {0};
> + while (1)
> + {
> + read_partition(&data1[446 + 16 * 0], &ext[j]);
> + printf("start=%u, total=%u, system=0x%x\t",
> + ext[j].start_sector_abs, ext[j].nb_sectors_abs, ext[j].system);
> + printf("the %dth partition is a logical part\n", ext_partnum + j + 1);
> +
> + if(0 != ext[j].nb_sectors_abs)
> + {
> + if ((ext_partnum + j + 1) == partition)
> + {
> + ext[j].start_sector_abs += ext_start_sector;
> + if(j > 0)
> + ext[j].start_sector_abs += ext_next.start_sector_abs;
> + *offset = (uint64_t)ext[j].start_sector_abs << 9;
> + *size = (uint64_t)ext[j].nb_sectors_abs << 9;
> + return 0;
> + }
> + j++;
> + }
> +
> + read_partition(&data1[446 + 16 * 1], &ext_next);
> + if (is_full_zero(&ext_next, sizeof(ext_next)))
> + break;
> + //ext_start_sector += ext_next.start_sector_abs;
> + if (bdrv_read(bs, ext_start_sector + ext_next.start_sector_abs, data1, 1))
> + errx(EINVAL, "error while reading");
> + }
> +
> + }
> + else
> + {
> + //printf("is a main partition......\n");
> + if ((i + 1) == partition)
> + {
> + *offset = (uint64_t)mbr[i].start_sector_abs << 9;
> + *size = (uint64_t)mbr[i].nb_sectors_abs << 9;
> + return 0;
> + }
> + }
> + }
> +
> + errno = -ENOENT;
> + return -1;
> +}
> +
> +///////////////////////////////////////////////////////
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/partition.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/partition.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/partition.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/partition.h 2012-12-28
> 16:02:41.015940225 +0800
> @@ -0,0 +1,46 @@
> +#ifndef _PARTITION_H
> +#define _PARTITION_H
> +
> +#include <stdint.h>
> +
> +typedef struct partition_record
> +{
> + uint8_t bootable;
> + uint8_t start_head;
> + uint32_t start_cylinder;
> + uint8_t start_sector;
> + uint8_t system;
> + uint8_t end_head;
> + uint8_t end_cylinder;
> + uint8_t end_sector;
> + uint32_t start_sector_abs;
> + uint32_t nb_sectors_abs;
> +} __attribute__ ((packed)) part_record_t;
> +
> +
> +
> +typedef enum
> + {
> + FS_UNKNOWN = 0,
> + FS_FAT,
> + FS_NTFS
> + }FS_TYPE;
> +
> +typedef struct ls_partition
> +{
> + part_record_t part;
> + int id;
> + FS_TYPE fs_type;
> +}ls_partition_t;
> +
> +
> +char* judge_fs(ls_partition_t* pt);
> +
> +#include "block_int.h"
> +int enum_partition(BlockDriverState *bs, ls_partition_t* parts);
> +
> +int find_partition(BlockDriverState *bs, int partition,
> + off_t *offset, off_t *size);
> +
> +
> +#endif
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/qemu-img.c
> xen-4.1.2-b/tools/ioemu-qemu-xen/qemu-img.c
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/qemu-img.c 2011-02-12
> 01:54:51.000000000 +0800
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/qemu-img.c 2012-12-28
> 16:02:41.016932622 +0800
> @@ -20,23 +20,35 @@
> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> IN
> * THE SOFTWARE.
> */
> #include "qemu-common.h"
> #include "osdep.h"
> #include "block_int.h"
> #include <assert.h>
> +#include <err.h>
> +
> +
> +#include "partition.h"
> +#include "fs-comm.h"
> +#include "fat.h"
> +#include "ntfs.h"
> +#include "misc.h"
> +
> +
> +
>
> #ifdef _WIN32
> #define WIN32_LEAN_AND_MEAN
> #include <windows.h>
> #endif
>
> /* Default to cache=writeback as data integrity is not important for
> qemu-tcg. */
> +#define MAX_PARTITIONS 20
> #define BRDV_O_FLAGS BDRV_O_CACHE_WB
>
> static void QEMU_NORETURN error(const char *fmt, ...)
> {
> va_list ap;
> va_start(ap, fmt);
> fprintf(stderr, "qemu-img: ");
> vfprintf(stderr, fmt, ap);
> @@ -53,16 +65,18 @@ static void format_print(void *opaque, c
> /* Please keep in synch with qemu-img.texi */
> static void help(void)
> {
> printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008
> Fabrice Bellard\n"
> "usage: qemu-img command [command options]\n"
> "QEMU disk image utility\n"
> "\n"
> "Command syntax:\n"
> + " ls [-v] [[-l] -d directory] imgfile\n"
> + " cat [-v] -f file imgfile\n"
> " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
> " commit [-f fmt] filename\n"
> " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B
> output_base_image] filename [filename2 [...]] output_filename\n"
> " info [-f fmt] filename\n"
> " snapshot [-l | -a snapshot | -c snapshot | -d snapshot]
> filename\n"
> "\n"
> "Command parameters:\n"
> " 'filename' is a disk image filename\n"
> @@ -209,16 +223,343 @@ static BlockDriverState *bdrv_new_open(c
> if (read_password(password, sizeof(password)) < 0)
> error("No password given");
> if (bdrv_set_key(bs, password) < 0)
> error("invalid password");
> }
> return bs;
> }
>
> +static void get_partition_path(const char *dir, int *which_part, char
> **path)
> +{
> + static char full_path[512];
> + char part[5]={};
> +
> + strncpy(full_path, dir, 512);
> + full_path[511] = '\0';
> +
> + //限制以/开头 结尾
> + char *p1 = full_path + 1;
> + char *p2 = strchr(full_path + 1, '/');
> + if(!p2)
> + {
> + errx(1, "check the file path!\n");
> + }
> +
> + *path = p2;
> + strncpy(part, p1, p2-p1);
> + *which_part = atoi(part);
> +}
> +
> +typedef struct grub_fs
> +{
> + grub_open open;
> + grub_ls ls;
> + grub_read read;
> + grub_close close;
> +}grub_fs_t;
> +
> +static grub_fs_t grub_fs_plug[10] = {};
> +
> +static void grub_fs_plugin(void)
> +{
> + grub_fs_plug[FS_FAT].open = grub_fat_open;
> + grub_fs_plug[FS_FAT].read = grub_fat_read;
> + grub_fs_plug[FS_FAT].close = grub_fat_close;
> + grub_fs_plug[FS_FAT].ls = grub_fat_ls;
> +
> + grub_fs_plug[FS_NTFS].open = grub_ntfs_open;
> + grub_fs_plug[FS_NTFS].read = grub_ntfs_read;
> + grub_fs_plug[FS_NTFS].close = grub_ntfs_close;
> + grub_fs_plug[FS_NTFS].ls = grub_ntfs_ls;
> +}
> +
> +static int img_ls(int argc, char **argv)
> +{
> + int c = -1;
> + char *imgfile = NULL;
> + char *dir = NULL;
> + char verbose = 0;
> + struct ls_ctrl ctrl={};
> +
> + for(;;)
> + {
> + c = getopt(argc, argv, "d:hlv");
> + if (c == -1)
> + break;
> +
> + switch(c)
> + {
> + case 'v':
> + verbose = 1;
> + break;
> + case 'l':
> + ctrl.detail = 1;
> + break;
> + case 'h':
> + help();
> + break;
> + case 'd':
> + dir = optarg;
> + break;
> + default:
> + break;
> + }
> + }
> +
> + imgfile = argv[optind++];
> +
> + if (optind > argc)
> + help();
> +
> + BlockDriverState *bs = bdrv_new("");
> + if(!bs)
> + error("Not enough memory for bdrv_new\n");
> + if(bdrv_open(bs, imgfile, BRDV_O_FLAGS) < 0)
> + error("Could not open '%s'\n", imgfile);
> +
> + off_t off_bytes = 0;
> + off_t size_bytes = 0;
> + int i = 0;
> + ls_partition_t* parts = (ls_partition_t*)malloc(MAX_PARTITIONS *
> sizeof(ls_partition_t));
> + int count = enum_partition(bs, parts);
> +
> + if(!dir)
> + {
> + //find_partition(bs, 15, &off_bytes, &size_bytes);
> + printf("id\tactive\ttype\tfs\tstart_sector\ttotal_sectors\n");
> + for(i = 0; i < count; i++)
> + {
> + printf("%d\t%s\t%s\t%s\t%u\t%u\n",
> + parts[i].id,
> + parts[i].part.bootable==0x80 ? "active" : "none-active",
> + (parts[i].part.system==0x0f ||
> parts[i].part.system==0x05) ? "extend" : (parts[i].id>=5 ? "logical" :
> "primary"),
> + judge_fs(&parts[i]),
> + parts[i].part.start_sector_abs,
> + parts[i].part.nb_sectors_abs
> + );
> + }
> +
> + goto fail;
> + }
> + else
> + {
> + grub_fs_plugin();
> +
> + grub_file_t file = NULL;
> + char *path = NULL;
> + int which_part = 1;
> +
> + file = (grub_file_t)malloc(sizeof(*file));
> + file->bs = bs;
> + file->data = NULL;
> +
> + if('/' != dir[strlen(dir) - 1])
> + strcat(dir, "/");
> +
> + get_partition_path(dir, &which_part, &path);
> + if(which_part < 1 || which_part > count)
> + {
> + fprintf(stderr, "error: check the partition number!\n");
> + goto fail;
> + }
> +
> + file->part_off_sector = parts[which_part -
> 1].part.start_sector_abs;
> + ctrl.dirname = dir;
> + printf("【name\t"
> + "size(bytes)\t"
> + "dir?\t"
> + "date\t"
> + "time】\n");
> +
> + judge_fs(&parts[which_part - 1]);
> + FS_TYPE fs_type = parts[which_part - 1].fs_type;
> + if (fs_type == FS_UNKNOWN)
> + {
> + errx(1, "unknown file system!\n");
> + }
> +
> + grub_fs_plug[fs_type].ls(file, path, NULL, (void*)&ctrl);
> + file->data ? free(file->data) : 0;
> + free(file);
> + }
> +
> +
> + fail:
> + bdrv_delete(bs);
> + free(parts);
> + return 0;
> +}
> +
> +
> +
> +static int img_cat(int argc, char **argv)
> +{
> + int c = -1;
> + char *imgfile = NULL;
> + char *filename = NULL;
> + char verbose = 0;
> +
> + for(;;) {
> + c = getopt(argc, argv, "f:hv");
> + if (c == -1)
> + break;
> + switch(c) {
> + case 'v':
> + verbose = 1;
> + break;
> + case 'h':
> + help();
> + break;
> + case 'f':
> + filename = optarg;
> + break;
> + default:
> + break;
> + }
> + }
> +
> + imgfile = argv[optind++];
> + if (optind > argc)
> + help();
> +
> +
> + if(!filename)
> + {
> + printf("error: specific the file to show!\n");
> + return -1;
> + }
> +
> + BlockDriverState *bs = bdrv_new("");
> + if(!bs)
> + errx(-1, "Not enough memory for bdrv_new\n");
> + if(bdrv_open(bs, imgfile, BRDV_O_FLAGS) < 0)
> + errx(-1, "Could not open %s\n", imgfile);
> +
> +
> + uint buf_size = 4096;
> + char* buf = (char*)malloc(buf_size);
> + off_t off_bytes = 0;
> + off_t size_bytes = 0;
> + int i = 0;
> + ls_partition_t *parts = (ls_partition_t*)malloc(MAX_PARTITIONS *
> sizeof(ls_partition_t));
> + int count = enum_partition(bs, parts);
> +
> +
> + {
> + grub_fs_plugin();
> +
> + grub_file_t file = NULL;
> + char *path = NULL;
> + int which_part = 1;
> +
> + file = (grub_file_t)malloc(sizeof(*file));
> + file->bs = bs;
> + file->data = NULL;
> +
> + char* p = strchr(filename, '/');
> + if(!p)
> + {
> + errx(-1, "please check the file path!\n");
> + }
> + else
> + {
> + p = strchr(p, '/');
> + if(!p) errx(-1, "check the file path!!\n");
> + }
> +
> + get_partition_path(filename, &which_part, &path);
> + DBG("part=%d, path=%s", which_part, path);
> + if(which_part < 1 || which_part > count)
> + {
> + printf("error: check the partition number!\n");
> + goto fail;
> + }
> + file->part_off_sector = parts[which_part -
> 1].part.start_sector_abs;
> + judge_fs(&parts[which_part - 1]);
> + FS_TYPE fs_type = parts[which_part - 1].fs_type;
> + (fs_type == FS_UNKNOWN) ? errx(1, "unknown file system!\n") : 0;
> + grub_fs_t grub_fs_plg = grub_fs_plug[fs_type];
> +
> + if(grub_fs_plg.open(file, path) == 0)
> + {
> + //printf("file size=%zd bytes\n", (file->size));
> +
> + grub_size_t len = file->size;
> + grub_off_t off = 0;
> + char tmpfile[256]={};
> + strncpy(tmpfile, getenv("HOME"), sizeof(tmpfile));
> + tmpfile[sizeof(tmpfile) - 1] = '\0';
> + strcat(tmpfile, "/tmp.file");
> +
> + if(!buf)
> + {
> + perror("not enough memory!\n");
> + goto fail;
> + }
> + else
> + {
> + grub_size_t readed = 0;
> + grub_size_t left = len;
> + grub_size_t total = 0;
> + FILE* f = fopen(tmpfile ,"w");
> + if(!f)
> + {
> + perror("fopen error");
> + goto fail;
> + }
> +
> +
> + (left > buf_size) ? (left = buf_size) : 0;
> + while((readed = grub_fs_plg.read(file, off, left, buf))
> + && total <= len
> + && readed > 0)
> + {
> + DBG("readed=%zd", readed);
> + total += fwrite(buf, 1, readed, f);
> + off = total;
> + left = len - total;
> + (left <= buf_size) ? 0 : (left = buf_size);
> + DBG("total=%zd", total);
> + };
> + fclose(f);
> +
> + if(total != len)
> + {
> + perror("read error");
> + goto fail;
> + }
> + else
> + {
> + sprintf(buf, "cat %s", tmpfile);
> + system(buf);
> +
> + }
> + }
> + }
> + else
> + {
> + printf("open failed!\n");
> + }
> +
> +
> + grub_fs_plg.close(file);
> + free(file);
> + }
> +
> +
> + fail:
> + free(buf);
> + bdrv_delete(bs);
> + free(parts);
> + return 0;
> +}
> +
> +
> +
> static int img_create(int argc, char **argv)
> {
> int c, ret, flags;
> const char *fmt = "raw";
> const char *filename;
> const char *base_filename = NULL;
> uint64_t size;
> const char *p;
> @@ -850,16 +1191,17 @@ static void img_snapshot(int argc, char
> }
>
> /* Cleanup */
> bdrv_delete(bs);
> }
>
> int main(int argc, char **argv)
> {
> +
> const char *cmd;
>
> bdrv_init();
> if (argc < 2)
> help();
> cmd = argv[1];
> argc--; argv++;
> if (!strcmp(cmd, "create")) {
> @@ -867,13 +1209,19 @@ int main(int argc, char **argv)
> } else if (!strcmp(cmd, "commit")) {
> img_commit(argc, argv);
> } else if (!strcmp(cmd, "convert")) {
> img_convert(argc, argv);
> } else if (!strcmp(cmd, "info")) {
> img_info(argc, argv);
> } else if (!strcmp(cmd, "snapshot")) {
> img_snapshot(argc, argv);
> - } else {
> + } else if (!strcmp(cmd, "ls")) {
> + img_ls(argc, argv);
> + } else if (!strcmp(cmd, "cat")) {
> + img_cat(argc, argv);
> + }
> + else {
> help();
> }
> +
> return 0;
> }
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/types.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/types.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/types.h 1970-01-01 07:00:00.000000000
> +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/types.h 2012-12-28 16:02:41.016932622
> +0800
> @@ -0,0 +1,35 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2002,2006,2007 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TYPES_CPU_HEADER
> +#define GRUB_TYPES_CPU_HEADER 1
> +
> +/* The size of void *. */
> +#define GRUB_TARGET_SIZEOF_VOID_P 4
> +
> +/* The size of long. */
> +#define GRUB_TARGET_SIZEOF_LONG 4
> +
> +/* i386 is little-endian. */
> +#undef GRUB_TARGET_WORDS_BIGENDIAN
> +
> +#define GRUB_TARGET_I386 1
> +
> +#define GRUB_TARGET_MIN_ALIGN 1
> +
> +#endif /* ! GRUB_TYPES_CPU_HEADER */
> diff --exclude=.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/x86_64/types.h
> xen-4.1.2-b/tools/ioemu-qemu-xen/x86_64/types.h
> --- xen-4.1.2-a/tools/ioemu-qemu-xen/x86_64/types.h 1970-01-01
> 07:00:00.000000000 +0700
> +++ xen-4.1.2-b/tools/ioemu-qemu-xen/x86_64/types.h 2012-12-28
> 16:02:41.017802371 +0800
> @@ -0,0 +1,39 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2008 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TYPES_CPU_HEADER
> +#define GRUB_TYPES_CPU_HEADER 1
> +
> +/* The size of void *. */
> +#define GRUB_TARGET_SIZEOF_VOID_P 8
> +
> +/* The size of long. */
> +#ifdef __MINGW32__
> +#define GRUB_TARGET_SIZEOF_LONG 4
> +#else
> +#define GRUB_TARGET_SIZEOF_LONG 8
> +#endif
> +
> +/* x86_64 is little-endian. */
> +#undef GRUB_TARGET_WORDS_BIGENDIAN
> +
> +#define GRUB_TARGET_X86_64 1
> +
> +#define GRUB_TARGET_MIN_ALIGN 1
> +
> +#endif /* ! GRUB_TYPES_CPU_HEADER */
>
>
- [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, 马磊, 2013/01/09
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system,
Blue Swirl <=
- Message not available
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, 马磊, 2013/01/10
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, Wei-Ren Chen, 2013/01/10
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, 马磊, 2013/01/10
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, Wei-Ren Chen, 2013/01/10
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, 马磊, 2013/01/10
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, Paolo Bonzini, 2013/01/10
- Message not available
- Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, 马磊, 2013/01/10
Re: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system, Daniel P. Berrange, 2013/01/10