From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:54771) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsqQr-0005Wo-UE for qemu-devel@nongnu.org; Wed, 09 Jan 2013 02:51:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TsqQO-00068l-Kr for qemu-devel@nongnu.org; Wed, 09 Jan 2013 02:50:41 -0500 Received: from mail-ee0-f41.google.com ([74.125.83.41]:35243) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tsq8g-0001Zs-5T for qemu-devel@nongnu.org; Wed, 09 Jan 2013 02:31:55 -0500 Received: by mail-ee0-f41.google.com with SMTP id d41so642068eek.0 for ; Tue, 08 Jan 2013 23:31:52 -0800 (PST) MIME-Version: 1.0 Date: Wed, 9 Jan 2013 15:31:50 +0800 Message-ID: From: =?UTF-8?B?6ams56OK?= Content-Type: multipart/alternative; boundary=e89a8f502b9249b9ff04d2d60ecc Subject: [Qemu-devel] [PATCH] reading files from qcow2-formated image disk for windows system List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com --e89a8f502b9249b9ff04d2d60ecc Content-Type: text/plain; charset=GB2312 Content-Transfer-Encoding: quoted-printable Hi, >> The final effect is as follows: >> >> >> *[malei@xentest-4-1 Fri Dec 28 ~/honeypot/xen/xen-4.1.2]$ qemu-img-xen >> cat -f /1/boot.ini ~/vm-check.img * >> *[boot loader]* >> *timeout=3D30* >> *default=3Dmulti(0)disk(0)rdisk(0)partition(1)\WINDOWS* >> *[operating systems]* >> *multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=3D"Microsoft Windows XP >> Professional" /noexecute=3Doptin /fastdetect* >> >> [malei@xentest-4-1 Fri Dec 28 ~/honeypot/xen/xen-4.1.2]$ qemu-img-xen ls >> -l -d /1/ ~/vm-check.img >> *=A1=BEname size(bytes) dir? date >> create-time=A1=BF* >> *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=A3=BA= cat >> and ls.* >> * >> * >> *For details in the patch, please check the attachment. * >> >> >> *Does anyone prefer this feature?!* * * * * * * Signed-off-by: Lei Ma (malei@360.cn) diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/debug.c 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 +#include +#include +#include +#include"debug.h" +#include +#include + +#define KB(x) ((x)*1024) + +static int dbg_term =3D 0, dbg_file =3D 0, log_day =3D 0; +static FILE* fp_log =3D NULL; +static char dir[128]=3D{0,}, filename[160]; +static void init_file_path(void); +static char printbuf[1024]=3D{}; +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=3Dvsprintf( printbuf, fmt, args ); + printbuf[i] =3D 0; + va_end(args); + + if( dbg_term ) + { + printf("[%s]%s(%d):\n%s\n", file, function, line, printbuf); + } + + if( dbg_file ) + { + time_t t =3D time( NULL ); + struct tm* tm1 =3D localtime(&t); + if( !tm1 ) return; + //if( tm1->tm_mday !=3D 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 =3D "0123456789abcdef"; + char *tmp; + unsigned char *end; + if (len > 1024) + len =3D 1024; + end =3D buf + len; + tmp =3D &outstr[0]; + while (buf < end) + { + *tmp++ =3D set[ (*buf) >> 4 ]; + *tmp++ =3D set[ (*buf) & 0xF ]; + *tmp++ =3D ' '; + buf ++; + } + *tmp =3D '\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 =3D 1; +} + +void debug_term_off() +{ + dbg_term =3D 0; +} + + +int mkdir_recursive( char* path ) +{ + char *p; + + if( access( path, 0 ) =3D=3D 0 ) + return 0; + + for( p=3Dpath; *p; p++ ) + { + if( p>path && *p =3D=3D '/' ) + { + *p =3D 0; + if( access( path, 0 ) !=3D 0 ) + { +#ifdef __WIN32__ + mkdir( path ); +#else + if( mkdir( path, S_IRWXU ) !=3D 0 ) + return -1; +#endif + } + *p =3D '/'; + } + } +#ifdef __WIN32__ + return mkdir( path ); +#else + return mkdir( path, S_IRWXU ); +#endif +} + +void init_file_path() +{ + char tmp[64]; + time_t t =3D time( NULL ); + struct tm* tm1 =3D localtime(&t); + + if( !tm1 ) + { + perror("debug.c init_file_path: ERROR GETTING SYSTEM TIME."); + } + log_day =3D tm1->tm_mday; + strftime( tmp, 64, "/%Y-%m-%d.txt", tm1 ); + + if( access( dir, 0 )!=3D0 ) + { + (mkdir_recursive( dir )<0) ? perror("mkdir_recursive fail!!\n") : 0; + } + strcpy( filename, dir ); + strcat( filename, tmp ); + if( fp_log ) + fclose( fp_log ); + fp_log =3D fopen( filename, "w" ); + if(fp_log) + { + fprintf(fp_log,"=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3DLOG START=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D\n"); + fclose(fp_log); fp_log=3DNULL; + fp_log =3D fopen( filename, "a+" ); + NULL=3D=3Dfp_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 =3D 1; +} + +void debug_file_off() +{ + if( !dbg_file ) + return; + dbg_file =3D 0; + if( fp_log ) + fclose( fp_log ); +} + +void debug_set_dir(char* str) +{ + strcpy( dir, str ); +} + diff --exclude=3D.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 +#include +#include + +//#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=3D.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 . + */ +#include "misc.h" +#include "fat.h" +#include "debug.h" + + +int g_err =3D 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 =3D 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 =3D=3D 0) + return -1; + + for (i =3D 0; (x & 1) =3D=3D 0; i++) + x >>=3D 1; + + if (x !=3D 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 =3D 0; + grub_uint32_t first_fat, magic; + int64_t off_bytes =3D (int64_t)part_off_sector << GRUB_DISK_SECTOR_BITS; + + if (! bs) + goto fail; + + data =3D (struct grub_fat_data *) malloc (sizeof (*data)); + if (! data) + goto fail; + + /* Read the BPB. */ + if (bdrv_pread(bs, off_bytes, &bpb, sizeof(bpb)) !=3D 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 =3D (bpb.bytes_per_sector); + s_part_off_sector =3D part_off_sector; + data->logical_sector_bits =3D + fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector)); + DBG("bpb.bytes_per_sector=3D0x%x, le_to_cpu16=3D0x%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 -=3D GRUB_DISK_SECTOR_BITS; + + DBG("bpb.sectors_per_cluster=3D%u", bpb.sectors_per_cluster); + data->cluster_bits =3D fat_log2 (bpb.sectors_per_cluster); + if (data->cluster_bits < 0) + { + DBG("fail here-->cluster_bits......line[%u]", __LINE__); + goto fail; + } + data->cluster_bits +=3D data->logical_sector_bits; + + /* Get information about FATs. */ + DBG("bpb.num_reserved_sectors=3D%u," + "le_to_cpu16=3D%u", + bpb.num_reserved_sectors, + grub_le_to_cpu16 (bpb.num_reserved_sectors)); + data->fat_sector =3D (grub_le_to_cpu16 (bpb.num_reserved_sectors) + << data->logical_sector_bits); + DBG("data->fat_sector=3D%u, part_off_sector=3D%u", + data->fat_sector, part_off_sector); + if (data->fat_sector =3D=3D 0) + { + DBG("fail here-->fat_sector......"); + goto fail; + } + data->sectors_per_fat =3D ((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=3D%u\n" + "grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)=3D%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 =3D=3D 0) + goto fail; + + /* Get the number of sectors in this volume. */ + data->num_sectors =3D ((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 =3D=3D 0) + { + DBG("fail here-->num_sectors......"); + goto fail; + } + /* Get information about the root directory. */ + if (bpb.num_fats =3D=3D 0) + { + DBG("fail here-->num_fats......"); + goto fail; + } + data->root_sector =3D data->fat_sector + bpb.num_fats * data->sectors_per_fat; + data->num_root_sectors + =3D ((((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 =3D data->root_sector + data->num_root_sectors; + data->num_clusters =3D (((data->num_sectors - data->cluster_sector) + >> (data->cluster_bits + data->logical_sector_bits)) + + 2); + + if (data->num_clusters <=3D 2) + { + DBG("fail here-->num_clusters......"); + goto fail; + } + if (! bpb.sectors_per_fat_16) + { + /* FAT32. */ + grub_uint16_t flags =3D grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags); + + data->root_cluster =3D grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster); + data->fat_size =3D 32; + data->cluster_eof_mark =3D 0x0ffffff8; + + if (flags & 0x80) + { + /* Get an active FAT. */ + unsigned active_fat =3D flags & 0xf; + + if (active_fat > bpb.num_fats) + goto fail; + + data->fat_sector +=3D active_fat * data->sectors_per_fat; + } + + if (bpb.num_root_entries !=3D 0 || bpb.version_specific.fat32.fs_version !=3D 0) + goto fail; + } + else + { + /* FAT12 or FAT16. */ + data->root_cluster =3D ~0U; + + if (data->num_clusters <=3D 4085 + 2) + { + /* FAT12. */ + data->fat_size =3D 12; + data->cluster_eof_mark =3D 0x0ff8; + } + else + { + /* FAT16. */ + data->fat_size =3D 16; + data->cluster_eof_mark =3D 0xfff8; + } + } + + /* More sanity checks. */ + if (data->num_sectors <=3D data->fat_sector) + goto fail; + + + DBG("data->fat_sector=3D%u, data->sectors_per_fat=3D%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)) !=3D sizeof(first_fat)) + { + DBG("fail here-->bdrv_pread......"); + goto fail; + } + + first_fat =3D grub_le_to_cpu32 (first_fat); + + if (data->fat_size =3D=3D 32) + { + first_fat &=3D 0x0fffffff; + magic =3D 0x0fffff00; + } + else if (data->fat_size =3D=3D 16) + { + first_fat &=3D 0x0000ffff; + magic =3D 0xff00; + } + else + { + first_fat &=3D 0x00000fff; + magic =3D 0x0f00; + } + + /* Serial number. */ + if (bpb.sectors_per_fat_16) + data->uuid =3D grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial); + else + data->uuid =3D 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) !=3D (magic | bpb.media | 0x8)) + { + DBG("fail here-->first_fat=3D0x%x, magic=3D0x%x", + first_fat, magic); + goto fail; + } + /* Start from the root directory. */ + data->file_cluster =3D data->root_cluster; + data->cur_cluster_num =3D ~0U; + data->attr =3D GRUB_FAT_ATTR_DIRECTORY; + DBG("data->file_cluster=3D%u \ndata->cur_cluster_num=3D%u \ndata->attr=3D0x%x\n" + "data->logical_sector_bits=3D%u\n" + "data->cluster_bits=3D%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; +} + + + +//=B4=D3=CE=C4=BC=FE=B5=C4=D6=B8=B6=A8=C6=AB=D2=C6offset=D7=D6=BD=DA=B4=A6= =B6=C1=C8=A1len=D7=D6=BD=DA=B5=C4=CA=FD=BE=DD=B5=BDbuf +//=CE=C4=BC=FE=D3=C9data->file_cluster=D6=B8=B6=A8 +//data->file_cluster=D6=B8=B6=A8=C1=CB=CE=C4=BC=FE=B5=C4=C6=F0=CA=BC=B4=D8= =BA=C5 +//=C4=AC=C8=CFdata->file_cluster=3D2=A3=AC=B4=FA=B1=ED=B8=F9=C4=BF=C2=BC +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 =3D 0; + unsigned long sector; + uint64_t off_bytes =3D 0; + /* This is a special case. FAT12 and FAT16 doesn't have the root directory + in clusters. */ + if (data->file_cluster =3D=3D ~0U) + { + size =3D (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset; + if (size > len) + size =3D len; + + off_bytes =3D ((uint64_t)data->root_sector << GRUB_DISK_SECTOR_BITS)= + offset; + if(bdrv_pread_from_sector_of_volume(bs, off_bytes, buf, size ) !=3D size) + return -1; + + return size; + } + + /* Calculate the logical cluster number and offset. */ + logical_cluster_bits =3D (data->cluster_bits + + data->logical_sector_bits + + GRUB_DISK_SECTOR_BITS); + logical_cluster =3D offset >> logical_cluster_bits; //which cluster t= o read + offset &=3D (1 << logical_cluster_bits) - 1; //mod + + if (logical_cluster < data->cur_cluster_num) // + { + data->cur_cluster_num =3D 0; + data->cur_cluster =3D data->file_cluster; // =B5=DA2=B8=F6fat=B1=ED= =CF=EE=BF=AA=CA=BC=BC=C7=C2=BC=C4=BF=C2=BC=BA=CD=CE=C4=BC=FE + } + + 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 =3D data->cur_cluster << 2; + break; + case 16: + fat_offset =3D data->cur_cluster << 1; + break; + default: + /* case 12: */ + fat_offset =3D data->cur_cluster + (data->cur_cluster >> 1); + break; + } + + /* Read the FAT. */ + int len =3D (data->fat_size + 7) >> 3; + uint64_t off_bytes =3D ((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) !=3D len) //=B4=D3fat=B1=ED=B6=C1=C8=A1=B4=D8=BA=C5 + return -1; + + next_cluster =3D grub_le_to_cpu32 (next_cluster); + switch (data->fat_size) + { + case 16: + next_cluster &=3D 0xFFFF; + break; + case 12: + if (data->cur_cluster & 1) + next_cluster >>=3D 4; + + next_cluster &=3D 0x0FFF; + break; + } + + DBG ("fat_size=3D%d, next_cluster=3D%u", + data->fat_size, next_cluster); + + /* Check the end. */ + if (next_cluster >=3D data->cluster_eof_mark) + return ret; + + if (next_cluster < 2 || next_cluster >=3D data->num_clusters) + { + DBG("invalid cluster %u................", + next_cluster); + return -1; + } + + data->cur_cluster =3D next_cluster; + data->cur_cluster_num++; + } + + /* Read the data here. */ + //=C2=DF=BC=AD=B4=D8=CB=F9=B6=D4=D3=A6=B5=C4=BE=F8=B6=D4=C9=C8=C7=F8 + sector =3D (data->cluster_sector + + ((data->cur_cluster - 2) + << (data->cluster_bits + data->logical_sector_bits))); + //=BE=F8=B6=D4=C9=C8=C7=F8=D6=D0=C8=A5=B5=F4=C6=AB=D2=C6=BA=F3=B5=C4= =D7=D6=BD=DA=CA=FD + size =3D (1 << logical_cluster_bits) - offset; + if (size > len) + size =3D len; + + //disk->read_hook =3D read_hook; + //disk->closure =3D closure; + int64_t off_bytes =3D ((uint64_t)sector << GRUB_DISK_SECTOR_BITS) + offset; + //disk->read_hook =3D 0; + if (bdrv_pread_from_sector_of_volume (bs, off_bytes, buf, size) !=3D size) + return -1; + + len -=3D size; + buf +=3D size; + ret +=3D size; + logical_cluster++; + offset =3D 0; //=D2=D4=BA=F3=B6=C1=B5=C4=B6=BC=CA=C7=CD=EA=D5=FB=C9= =C8=C7=F8 + } + + return ret; +} + +//=B1=E9=C0=FA=D3=C9data->file_cluster=D6=B8=B6=A8=B5=C4=C4=BF=C2=BC +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 =3D 0; + grub_uint16_t *unibuf; + int slot =3D -1, slots =3D -1; + int checksum =3D -1; + grub_ssize_t offset =3D -sizeof(dir); + + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) + return printf("not a directory......\n"); + + /* Allocate space enough to hold a long name. */ + filename =3D (char*)malloc (0x40 * 13 * 4 + 1); + unibuf =3D (grub_uint16_t *) malloc (0x40 * 13 * 2); + char *gbname =3D (char*)malloc(0x40 * 13 * 2); + if (! filename || ! unibuf || !gbname) + { + free(gbname); + free (filename); + free (unibuf); + perror("iterate: malloc failed!...\n"); + return -1; + } + + + int count =3D 0; + while (1) + { + unsigned i; + + /* Adjust the offset. */ + offset +=3D sizeof (dir); + DBG("\n[%d]offset=3D%u," + "data->cur_cluster_num=3D%u,data->cur_cluster=3D%u", + count+1, offset, + data->cur_cluster_num, data->cur_cluster); + /* Read a directory entry. */ + //0x0=B1=ED=CA=BE=BF=D5=C4=BF=C2=BC + if ((grub_fat_read_data (bs, data, 0, 0, + offset, sizeof (dir), (char *) &dir) + !=3D sizeof (dir) || dir.name[0] =3D=3D 0)) + { + DBG("break...dir.name[0]=3D=3D%d", dir.name[0]); + break; + } + /* Handle long name entries. */ + if (dir.attr =3D=3D GRUB_FAT_ATTR_LONG_NAME) + { + DBG("long name..."); + struct grub_fat_long_name_entry *long_name + =3D (struct grub_fat_long_name_entry *) &dir; + grub_uint8_t id =3D long_name->id; + + if (id & 0x40) //the last item + { + id &=3D 0x3f; //index or ordinal number 1~31 + slots =3D slot =3D id; + checksum =3D long_name->checksum; + DBG("the last ordinal num=3D%d!!!", id); + } + + if (id !=3D slot || slot =3D=3D 0 || checksum !=3D long_name->checksum) + { + DBG("not valid ordinal number ,ignore...continue"); + checksum =3D -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=B1=ED=CA=BE=D2=D1=BE=AD=B1=BB=C9=BE=B3=FD + if (dir.name[0] =3D=3D 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID)) + { + DBG("dir.name[0]=3D0x%x, dir.attr=3D0x%x not valid...continue", + dir.name[0], dir.attr); + continue; + } + + DBG("checksum=3D%d, slot=3D%d", checksum, slot); + /* This is a workaround for Japanese. */ + if (dir.name[0] =3D=3D 0x05) + dir.name[0] =3D 0xe5; + + if (checksum !=3D -1 && slot =3D=3D 0) + { + DBG("checksuming"); + grub_uint8_t sum; + + for (sum =3D 0, i =3D 0; i < sizeof (dir.name); i++) + sum =3D ((sum >> 1) | (sum << 7)) + dir.name[i]; + + if (sum =3D=3D checksum) + {//=B3=A4=C3=FB=B1=ED=CF=EE=BA=F3=C3=E6=BD=F4=BD=D3=B6=CC=C3=FB=B1=ED= =CF=EE=A3=AC=D1=E9=D6=A4=B3=C9=B9=A6=D4=F2=D6=A4=C3=F7=D5=E6=D5=FD=CA=C7=B3= =A4=C3=FB=D7=D6 + int u; + + for (u =3D 0; u < slots * 13; u++) + unibuf[u] =3D grub_le_to_cpu16 (unibuf[u]); + + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf, + slots * 13) =3D '\0'; + + + checksum =3D -1; + for (i =3D 0; i < sizeof (dir.name); i++) + DBG("0x%x ", dir.name[i]); + + u2g(filename, strlen(filename), gbname, 0x40 * 13 * 2); + DBG("\ndir.name=3D%s, filename=3D%s, dir.attr=3D0x%x," + "sum=3D=3Dchecksum...continue", + dir.name, gbname, dir.attr); + + count++; + + if (hook && hook (gbname, &dir, closure)) + break; + + continue; + } + + checksum =3D -1; + } + + //=BA=F3=C3=E6=B5=C4=B4=A6=C0=ED=D5=EB=B6=D4=B7=C7=D5=E6=CA=B5=B3=A4= =C3=FB=BA=CD=D5=E6=CA=B5=B6=CC=C3=FB + /* Convert the 8.3 file name. */ + //=C8=A5=B5=F4=B6=CC=C3=FB=B5=C4=BF=D5=B8=F1=A3=AC=C8=AB=B8=C4=CE=AA= =D0=A1=D0=B4 + filep =3D filename; + if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID) + { + DBG("VOLUME"); + for (i =3D 0; i < sizeof (dir.name) && dir.name[i] + && ! grub_isspace (dir.name[i]); i++) + *filep++ =3D dir.name[i]; + } + else + { + for (i =3D 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++= ) + *filep++ =3D grub_tolower (dir.name[i]); + + *filep =3D '.'; + + for (i =3D 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i+= +) + *++filep =3D grub_tolower (dir.name[i]); + + if (*filep !=3D '.') + filep++; + } + *filep =3D '\0'; + + //for (i =3D 0; i < sizeof (dir.name); i++) + // DBG("0x%x ", dir.name[i]); + DBG("\ndir.name=3D%s, filename=3D=A1=BE%s=A1=BF, dir.attr=3D0x%x," + "...next while", + dir.name, filename, dir.attr); + count++; + /*if(strcmp(filename, ".") && strcmp(filename, "..")) + { + DBG("{=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D>"); + struct grub_fat_data *data2 =3D NULL; + data2 =3D (struct grub_fat_data*)malloc(sizeof(*data)); + memcpy(data2, data, sizeof(*data)); + data2->attr =3D dir.attr; + data2->file_size =3D grub_le_to_cpu32 (dir.file_size); + data2->file_cluster =3D ((grub_le_to_cpu16 (dir.first_cluster_high) << = 16) + | grub_le_to_cpu16 (dir.first_cluster_low)); + data2->cur_cluster_num =3D ~0U; + (grub_fat_iterate_dir(bs, data2, NULL, NULL) < 0) ? DBG("error !!!!!!") : 0; + free(data2); + DBG("<=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D}"); + } + */ + if (hook && hook (filename, &dir, closure)) + break; + } + + free(gbname); + free (filename); + free (unibuf); + + return 0; +} + + + +//=B4=AB=B8=F8grub_fat_find_hook=B5=C4=B2=CE=CA=FDclosure +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 =3D closure; + struct grub_dirhook_info info; + memset (&info, 0, sizeof (info)); + + info.dir =3D !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY); + info.case_insensitive =3D 1; + info.mtimeset =3D (dir->c_date || dir->c_time); + info.mtime =3D (((grub_uint32_t)dir->c_date << 16) | (dir->c_time)); + info.filesize =3D dir->file_size; + + DBG("target file =A1=BE%s=A1=BF=3D=3D=3D=3D=3D=3D", c->dirname); + if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID) + { + DBG("volume id , ignore=3D=3D=3D=3D=3D=3D"); + return 0; + } + + if (*(c->dirname) =3D=3D '\0' && (c->call_hook)) + { //=B4=F2=BF=AA=B5=C4=CA=C7=C4=BF=C2=BC /x/path1/path2/ + //=B7=B5=BB=D80=A3=AC=C8=C3iterate=CA=B1=D6=BB=CA=C7=B4=F2=D3=A1=D0= =C5=CF=A2=A3=AC=B6=F8=B2=BB=CD=CB=B3=F6while + c->found =3D 1; + if(!(c->data->attr & GRUB_FAT_ATTR_DIRECTORY)) + { + printf("it's not a directory!\n"); + } + DBG("list the dir =A1=BE%s=A1=BF=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D", + ((struct ls_ctrl*)c->closure)->dirname); + return c->hook (filename, &info, c->closure); + } + + + if (grub_strcasecmp (c->dirname, filename) =3D=3D 0) + { //=B4=F2=BF=AA=B5=C4=CA=C7=CE=C4=BC=FE /x/path1/file + DBG("found=3D=3D=3D=3D=3D=3D"); + struct grub_fat_data *data =3D c->data; + + c->found =3D 1; + data->attr =3D dir->attr; + data->file_size =3D grub_le_to_cpu32 (dir->file_size); + data->file_cluster =3D ((grub_le_to_cpu16 (dir->first_cluster_high) = << 16) + | grub_le_to_cpu16 (dir->first_cluster_low)); + data->cur_cluster_num =3D ~0U; + + if (c->call_hook) + c->hook (filename, &info, c->closure); + + return 1; + } + else + { + DBG("not match=3D=3D=3D=3D=3D=3D"); + } + 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. */ +//=D4=DA=D3=C9data=D6=B8=B6=A8=B5=C4=C4=BF=C2=BC=CF=C2=B2=E9=D5=D2=D3=C9pa= th=C2=B7=BE=B6=D6=B8=B6=A8=B5=C4=CE=C4=BC=FE=BC=D0=BB=F2=CE=C4=BC=FE +//=D5=D2=B5=BD=D6=AE=BA=F3=BD=BB=D3=C9 grub_fat_find_dir_hook=BA=AF=CA=FD= =B4=A6=C0=ED=A3=AC=C6=E4=D6=D0closure=B2=CE=CA=FD=CA=C7=B9=D8=BC=FC +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=3D0x%x", path, data->attr); + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) + { + printf("not a directory...........\n"); + return 0; + } + + /* Extract a directory name. */ + while (*path =3D=3D '/') + path++; + + dirp =3D grub_strchr (path, '/'); + if (dirp) + { + unsigned len =3D dirp - path; + + dirname =3D (char*)malloc (len + 1); + if (! dirname) + return 0; + + memcpy (dirname, path, len); + dirname[len] =3D '\0'; + } + else + { + /* This is actually a file. */ + dirname =3D grub_strdup (path); + } + DBG("searching \"%s\"=3D=3D=3D=3D=3D=3D", dirname); + c.data =3D data; + c.hook =3D hook; + c.closure =3D closure; + c.dirname =3Ddirname; + c.found =3D 0; + c.call_hook =3D (! dirp && hook); //=D5=EB=B6=D4=C4=BF=C2=BC=B5=C4hook + + int ret =3D grub_fat_iterate_dir (bs, data, grub_fat_find_dir_hook, &c); + if(0 =3D=3D ret && !c.found) + { + g_err =3D GRUB_ERR_NOT_FOUND; + printf("file not found..\n"); + } + else if(ret < 0) + { + g_err =3D GRUB_ERR_UNKNOWN; + printf("iterate error!\n"); + } + + + free (dirname); + + return (c.found && 0=3D=3Dret) ? dirp : 0; +} + + + + + +grub_err_t +grub_fat_open (grub_file_t file, const char *name) +{ + struct grub_fat_data *data =3D 0; + char *p =3D (char *) name; + + + data =3D grub_fat_mount (file->bs, file->part_off_sector); + if (! data) + { + printf("[%s]: mount error!\n", name); + goto fail; + } + + int i =3D 0; + do + { + p =3D grub_fat_find_dir (file->bs, data, p, 0, 0); + DBG("%d cycle past=A1=BEpath=3D%s=A1=BF.......", i+1, p); + //error judge...... + } + while (p); + + DBG("exit while=3D=3D=3D=3D=3D=3D"); + + if ((GRUB_ERR_NONE =3D=3D g_err) + && (data->attr & GRUB_FAT_ATTR_DIRECTORY)) + { + printf ("[%s]: not a file!\n", name); + goto fail; + } + + if(GRUB_ERR_NONE =3D=3D g_err) + { + DBG("found=3D=3D=3D=3D=3D=3D"); + } + else + { + printf("not found or error!\n"); + goto fail; + } + + DBG("11111111111111111111111"); + file->data =3D data; + file->size =3D data->file_size; + return 0; + + fail: + free(data); + file->data =3D 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 =3D (struct ls_ctrl*)closure; + DBG("detail=3D%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 =3D ((info->mtime) & TIME_BIT); + grub_uint16_t date =3D ((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; // =D7=EE=D6=D5=B7=B5=BB=D8=B8=F8iterate +} + + +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 =3D 0; + grub_size_t len; + char *dirname =3D 0; + char *p; + + data =3D grub_fat_mount (file->bs, file->part_off_sector); + if (! data) + goto fail; + + file->data =3D data; + /* Make sure that DIRNAME terminates with '/'. */ + len =3D strlen(path); + dirname =3D (char*)malloc (len + 1 + 1); + if (! dirname) + goto fail; + memcpy (dirname, path, len); + p =3D dirname + len; + if (path[len - 1] !=3D '/') + *p++ =3D '/'; + *p =3D '\0'; + p =3D dirname; + + do + { + p =3D grub_fat_find_dir (file->bs, data, p, find_then_ls_hook, closure); + } + while (p && g_err =3D=3D GRUB_ERR_NONE); + + + + fail: + + free (dirname); + free (data); file->data =3D 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=3D.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=3D.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=3D.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 . + */ + +#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 !=3D c->rootnode && node !=3D 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 =3D closure; + DBG("list_file hooked by fshelp:iterate(), filename=3D%s", filename); + if (filetype =3D=3D 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) =3D filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; + *(c->oldnode) =3D *(c->currnode); + *(c->currnode) =3D 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 =3D fpath; + char *next; + enum grub_fshelp_filetype type =3D GRUB_FSHELP_DIR; + grub_fshelp_node_t currnode =3D currroot; + grub_fshelp_node_t oldnode =3D currroot; + + c->currroot =3D currroot; + + grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1); + + /* Remove all leading slashes. */ + while (*name =3D=3D '/') + name++; + + if (! *name) + { + *currfound =3D currnode; + return 0; + } + + for (;;) + { + int found; + struct find_file_closure cc; + + /* Extract the actual part from the pathname. */ + next =3D grub_strchr (name, '/'); + if (next) + { + /* Remove all leading slashes. */ + while (*next =3D=3D '/') + *(next++) =3D '\0'; + } + + /* At this point it is expected that the current node is a + directory, check if this is true. */ + if (type !=3D GRUB_FSHELP_DIR) + { + free_node (currnode, c); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + } + + DBG("find_file_closure cc.name=3D=A1=BE%s=A1=BF", name); + cc.name =3D name; + cc.type =3D &type; + cc.oldnode =3D &oldnode; + cc.currnode =3D &currnode; + /* Iterate over the directory. */ + DBG("******fshelp:find_file hooked by \'grub_ntfs_iterate_dir\'," + "nested another hook \'fshelp:iterator\'"); + found =3D c->iterate_dir (currnode, iterate, &cc); + if (! found) + { + if (grub_errno) + return grub_errno; + + break; + } + + /* Read in the symlink and follow it. */ + if (type =3D=3D GRUB_FSHELP_SYMLINK) + { + char *symlink; + + /* Test if the symlink does not loop. */ + if (++(c->symlinknest) =3D=3D 8) + { + free_node (currnode, c); + free_node (oldnode, c); + return grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + } + + symlink =3D 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] =3D=3D '/') + { + free_node (oldnode, c); + oldnode =3D c->rootnode; + } + + /* Lookup the node the symlink points to. */ + find_file (symlink, oldnode, &currnode, c); + type =3D 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 =3D=3D '\0') + { + *currfound =3D currnode; + c->foundtype =3D type; + return 0; + } + + name =3D 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=3D3. */ +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 =3D rootnode; + c.iterate_dir =3D iterate_dir; + c.closure =3D closure; + c.read_symlink =3D read_symlink; + c.symlinknest =3D 0; + c.foundtype =3D GRUB_FSHELP_DIR; + + if (!path || path[0] !=3D '/') + { + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); + return grub_errno; + } + + + DBG("going to find_file\n"); + err =3D find_file (path, rootnode, foundnode, &c); + if (err) + return err; + + /* Check if the node that was found was of the expected type. */ + if (expecttype =3D=3D GRUB_FSHELP_REG && c.foundtype !=3D expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); + else if (expecttype =3D=3D GRUB_FSHELP_DIR && c.foundtype !=3D expecttyp= e) + 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 =3D 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 =3D filesize - pos; + + blockcnt =3D ((len + pos) + blocksize - 1) >> + (log2blocksize + GRUB_DISK_SECTOR_BITS); + + for (i =3D pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++) + { + grub_disk_addr_t blknr; + int blockoff =3D pos & (blocksize - 1); + int blockend =3D blocksize; + + int skipfirst =3D 0; + + blknr =3D get_block (node, i); + if (grub_errno) + return -1; + + blknr =3D blknr << log2blocksize; + off_bytes =3D blknr << GRUB_DISK_SECTOR_BITS; + + /* Last block. */ + if (i =3D=3D blockcnt - 1) + { + blockend =3D (len + pos) & (blocksize - 1); + + /* The last portion is exactly blocksize. */ + if (! blockend) + blockend =3D blocksize; + } + + /* First block. */ + if (i =3D=3D (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS))) + { + skipfirst =3D blockoff; + blockend -=3D skipfirst; + } + + /* If the block number is 0 this block is not stored on disk but + is zero filled instead. */ + if (blknr) + { + //bs->read_hook =3D read_hook; + //bs->closure =3D closure; + + bdrv_pread_from_lcn_of_volum(bs, off_bytes + skipfirst, + buf, blockend); + //bs->read_hook =3D 0; + if (grub_errno) + return -1; + } + else + grub_memset (buf, 0, blockend); + + buf +=3D blocksize - skipfirst; + } + + return len; +} + +unsigned int +grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow) +{ + int mod; + + *pow =3D 0; + while (blksize > 1) + { + mod =3D blksize - ((blksize >> 1) << 1); + blksize >>=3D 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=3D.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 . + */ + +#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=3D3. */ +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=3D.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 =3D a; + rl =3D (uint64_t)u.l.low * (uint64_t)b; + rh =3D (uint64_t)u.l.high * (uint64_t)b; + rh +=3D (rl >> 32); + res.l.high =3D rh / c; + res.l.low =3D (((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 =3D a>>32; + a1.low =3D a&0xffffffff; + b1.high =3D b>>32; + b1.low =3D b&0xffffffff; + + if(a1.high < b1.high) + { + c=3Db1; + b1=3Da1; + a1=3Dc; + } + + a1.high -=3D b1.high; + a1.low -=3D b1.low; + if(a1.low & 0x80000000) + { + a1.low =3D (~(a1.low & 0x7fffffff))+1; + a1.high -=3D 1; + } + + uint64_t ret =3D (uint64_t)a1.high<<32 | a1.low; + return ret; +} + +struct tm* ntfs_utc2local(grub_uint64_t time, struct tm* ptm) +{ + //time_t time2 =3D sub64(time, NTFS_TIME_OFFSET); + time_t time2 =3D time - NTFS_TIME_OFFSET; + /*DBG("sizeof(int)=3D%d", sizeof(int)); + DBG("sizeof(short)=3D%d", sizeof(short)); + DBG("sizeof(long)=3D%d", sizeof(long)); + DBG("sizeof(long long)=3D%d", sizeof(unsigned long long)); + DBG("sizeof(time_t)=3D%d, time=3D%zu, time2=3D%zu", sizeof(time_t), time= , time2);*/ + //time2 =3D div64(time2,1,10000000); + time2 =3D time2 / 10000000; + DBG("sizeof(time_t)=3D%d, time=3D%zu, time2=3D%zu", sizeof(time_t), time= , time2); + ////time2 =3D 0;//time(NULL); + return localtime_r(&time2, ptm); +} diff --exclude=3D.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 +#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=3D.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 . + */ + +#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 !=3D 4 && GRUB_CPU_SIZEOF_VOID_P !=3D 8 +# error "This architecture is not supported because sizeof(void *) !=3D 4 and sizeof(void *) !=3D 8" +#endif + +#ifndef GRUB_TARGET_WORDSIZE +# if GRUB_TARGET_SIZEOF_VOID_P =3D=3D 4 +# define GRUB_TARGET_WORDSIZE 32 +# elif GRUB_TARGET_SIZEOF_VOID_P =3D=3D 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 =3D=3D 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 =3D=3D 8 +typedef unsigned long grub_uint64_t; +#else +typedef unsigned long long grub_uint64_t; +#endif + +/* Misc types. */ +#if GRUB_TARGET_SIZEOF_VOID_P =3D=3D 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 =3D=3D 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 =3D=3D 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 =3D=3D 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 =3D (x); \ + (grub_uint16_t) ((_x << 8) | (_x >> 8)); \ +}) + +#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >=3D 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 =3D (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 =3D (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 =3D=3D 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=3D.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 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 header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the 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 header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the 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 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 header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSES_CURSES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSES_H */ + +/* Define to 1 if you have the 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 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 header file. */ +/* #undef HAVE_SDL_SDL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the 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 header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MKDEV_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSMACROS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the 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 . + */ +/* #undef MAJOR_IN_MKDEV */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in + . */ +/* #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 "bean123ch@gmail.com" + +/* 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 mos= t + 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=3D.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 . + */ + +#include "grub_err.h" +#include "misc.h" +#include +#include +#include + +#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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 1; + } + + /* Allow further operation of other components by resetting + active errno to GRUB_ERR_NONE. */ + grub_errno =3D 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 =3D 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 =3D 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 !=3D 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 =3D 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=3D.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 . + */ + +#ifndef GRUB_ERR_HEADER +#define GRUB_ERR_HEADER 1 + + +typedef enum + { + GRUB_ERR_NONE =3D 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=3D.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 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 header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the 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 header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the 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 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 header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSES_CURSES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSES_H */ + +/* Define to 1 if you have the 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 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 header file. */ +/* #undef HAVE_SDL_SDL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the 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 header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MKDEV_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSMACROS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the 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 . + */ +/* #undef MAJOR_IN_MKDEV */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in + . */ +/* #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 "bean123ch@gmail.com" + +/* 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 mos= t + 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=3D.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 . + */ +#include "misc.h" +#include "fat.h" + + +static int +fat_log2 (unsigned x) +{ + int i; + + if (x =3D=3D 0) + return -1; + + for (i =3D 0; (x & 1) =3D=3D 0; i++) + x >>=3D 1; + + if (x !=3D 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 =3D 0; + grub_uint32_t first_fat, magic; + int64_t off_bytes =3D (int64_t)part_off_sector << GRUB_DISK_SECTOR_BITS; + + if (! bs) + goto fail; + + data =3D (struct grub_fat_data *) malloc (sizeof (*data)); + if (! data) + goto fail; + + /* Read the BPB. */ + if (bdrv_pread(bs, off_bytes, &bpb, sizeof(bpb)) !=3D 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 =3D + fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector)); + printf("bpb.bytes_per_sector=3D0x%x, le_to_cpu16=3D0x%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 -=3D GRUB_DISK_SECTOR_BITS; + + printf("bpb.sectors_per_cluster=3D%u\n", bpb.sectors_per_cluster); + data->cluster_bits =3D 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 +=3D data->logical_sector_bits; + + /* Get information about FATs. */ + printf("bpb.num_reserved_sectors=3D%u, le_to_cpu16=3D%u\n", + bpb.num_reserved_sectors, grub_le_to_cpu16 (bpb.num_reserved_sectors)); + data->fat_sector =3D part_off_sector + (grub_le_to_cpu16 (bpb.num_reserved_sectors) + << data->logical_sector_bits); + printf("data->fat_sector=3D%u\n", data->fat_sector); + if (data->fat_sector =3D=3D 0) + { + printf("fail here-->fat_sector......line[%u]\n", __LINE__); + goto fail; + } + data->sectors_per_fat =3D ((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=3D%u\n" + "grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)=3D%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 =3D=3D 0) + goto fail; + + /* Get the number of sectors in this volume. */ + data->num_sectors =3D ((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 =3D=3D 0) + { + printf("fail here-->num_sectors......line[%u]\n", __LINE__); + goto fail; + } + /* Get information about the root directory. */ + if (bpb.num_fats =3D=3D 0) + { + printf("fail here-->num_fats......line[%u]\n", __LINE__); + goto fail; + } + data->root_sector =3D data->fat_sector + bpb.num_fats * data->sectors_per_fat; + data->num_root_sectors + =3D ((((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 =3D data->root_sector + data->num_root_sectors; + data->num_clusters =3D (((data->num_sectors - data->cluster_sector) + >> (data->cluster_bits + data->logical_sector_bits)) + + 2); + + if (data->num_clusters <=3D 2) + { + printf("fail here-->num_clusters......line[%u]\n", __LINE__); + goto fail; + } + if (! bpb.sectors_per_fat_16) + { + /* FAT32. */ + grub_uint16_t flags =3D grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags); + + data->root_cluster =3D grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster); + data->fat_size =3D 32; + data->cluster_eof_mark =3D 0x0ffffff8; + + if (flags & 0x80) + { + /* Get an active FAT. */ + unsigned active_fat =3D flags & 0xf; + + if (active_fat > bpb.num_fats) + goto fail; + + data->fat_sector +=3D active_fat * data->sectors_per_fat; + } + + if (bpb.num_root_entries !=3D 0 || bpb.version_specific.fat32.fs_version !=3D 0) + goto fail; + } + else + { + /* FAT12 or FAT16. */ + data->root_cluster =3D ~0U; + + if (data->num_clusters <=3D 4085 + 2) + { + /* FAT12. */ + data->fat_size =3D 12; + data->cluster_eof_mark =3D 0x0ff8; + } + else + { + /* FAT16. */ + data->fat_size =3D 16; + data->cluster_eof_mark =3D 0xfff8; + } + } + + /* More sanity checks. */ + if (data->num_sectors <=3D data->fat_sector) + goto fail; + + + printf("data->fat_sector=3D%u, data->sectors_per_fat=3D%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)) !=3D sizeof(first_fat)) + { + printf("fail here-->bdrv_pread......line[%u]\n", __LINE__); + goto fail; + } + + first_fat =3D grub_le_to_cpu32 (first_fat); + + if (data->fat_size =3D=3D 32) + { + first_fat &=3D 0x0fffffff; + magic =3D 0x0fffff00; + } + else if (data->fat_size =3D=3D 16) + { + first_fat &=3D 0x0000ffff; + magic =3D 0xff00; + } + else + { + first_fat &=3D 0x00000fff; + magic =3D 0x0f00; + } + + /* Serial number. */ + if (bpb.sectors_per_fat_16) + data->uuid =3D grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial); + else + data->uuid =3D 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) !=3D (magic | bpb.media | 0x8)) + { + printf("fail here-->first_fat=3D0x%x, magic=3D0x%x......line[%u]\n", + first_fat, magic, __LINE__); + goto fail; + } + /* Start from the root directory. */ + data->file_cluster =3D data->root_cluster; + data->cur_cluster_num =3D ~0U; + data->attr =3D GRUB_FAT_ATTR_DIRECTORY; + printf("data->file_cluster=3D%u \ndata->cur_cluster_num=3D%u \ndata->attr=3D0x%x\n" + "data->logical_sector_bits=3D%u\n" + "data->cluster_bits=3D%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; +} + + + +//=B4=D3=CE=C4=BC=FE=B5=C4=D6=B8=B6=A8=C6=AB=D2=C6offset=D7=D6=BD=DA=B4=A6= =B6=C1=C8=A1len=D7=D6=BD=DA=B5=C4=CA=FD=BE=DD=B5=BDbuf +//=CE=C4=BC=FE=D3=C9data->file_cluster=D6=B8=B6=A8 +//data->file_cluster=D6=B8=B6=A8=C1=CB=CE=C4=BC=FE=B5=C4=C6=F0=CA=BC=B4=D8= =BA=C5 +//=C4=AC=C8=CFdata->file_cluster=3D2=A3=AC=B4=FA=B1=ED=B8=F9=C4=BF=C2=BC +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 =3D 0; + unsigned long sector; + uint64_t off_bytes =3D 0; + /* This is a special case. FAT12 and FAT16 doesn't have the root directory + in clusters. */ + if (data->file_cluster =3D=3D ~0U) + { + size =3D (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset; + if (size > len) + size =3D len; + + off_bytes =3D ((uint64_t)data->root_sector << GRUB_DISK_SECTOR_BITS)= + offset; + if(bdrv_read(bs, off_bytes, buf, size ) !=3D size) + return -1; + + return size; + } + + /* Calculate the logical cluster number and offset. */ + logical_cluster_bits =3D (data->cluster_bits + + data->logical_sector_bits + + GRUB_DISK_SECTOR_BITS); + logical_cluster =3D offset >> logical_cluster_bits; //which cluster t= o read + offset &=3D (1 << logical_cluster_bits) - 1; //mod + + if (logical_cluster < data->cur_cluster_num) // + { + data->cur_cluster_num =3D 0; + data->cur_cluster =3D data->file_cluster; // =B5=DA2=B8=F6fat=B1=ED= =CF=EE=BF=AA=CA=BC=BC=C7=C2=BC=C4=BF=C2=BC=BA=CD=CE=C4=BC=FE + } + + 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 =3D data->cur_cluster << 2; + break; + case 16: + fat_offset =3D data->cur_cluster << 1; + break; + default: + /* case 12: */ + fat_offset =3D data->cur_cluster + (data->cur_cluster >> 1); + break; + } + + /* Read the FAT. */ + int len =3D (data->fat_size + 7) >> 3; + uint64_t off_bytes =3D ((uint64_t)data->fat_sector << GRUB_DISK_SECTOR_BITS) + fat_offset; + if (bdrv_pread (bs, off_bytes, + (char *) &next_cluster, + len) !=3D len) //=B4=D3fat=B1=ED=B6=C1=C8=A1=B4=D8=BA=C5 + return -1; + + next_cluster =3D grub_le_to_cpu32 (next_cluster); + switch (data->fat_size) + { + case 16: + next_cluster &=3D 0xFFFF; + break; + case 12: + if (data->cur_cluster & 1) + next_cluster >>=3D 4; + + next_cluster &=3D 0x0FFF; + break; + } + + printf ("fat_size=3D%d, next_cluster=3D%u\n", + data->fat_size, next_cluster); + + /* Check the end. */ + if (next_cluster >=3D data->cluster_eof_mark) + return ret; + + if (next_cluster < 2 || next_cluster >=3D data->num_clusters) + { + printf("invalid cluster %u................\n", + next_cluster); + return -1; + } + + data->cur_cluster =3D next_cluster; + data->cur_cluster_num++; + } + + /* Read the data here. */ + //=C2=DF=BC=AD=B4=D8=CB=F9=B6=D4=D3=A6=B5=C4=BE=F8=B6=D4=C9=C8=C7=F8 + sector =3D (data->cluster_sector + + ((data->cur_cluster - 2) + << (data->cluster_bits + data->logical_sector_bits))); + //=BE=F8=B6=D4=C9=C8=C7=F8=D6=D0=C8=A5=B5=F4=C6=AB=D2=C6=BA=F3=B5=C4= =D7=D6=BD=DA=CA=FD + size =3D (1 << logical_cluster_bits) - offset; + if (size > len) + size =3D len; + + //disk->read_hook =3D read_hook; + //disk->closure =3D closure; + int64_t off_bytes =3D ((uint64_t)sector << GRUB_DISK_SECTOR_BITS) + offset; + //disk->read_hook =3D 0; + if (bdrv_pread (bs, off_bytes, buf, size) !=3D size) + return -1; + + len -=3D size; + buf +=3D size; + ret +=3D size; + logical_cluster++; + offset =3D 0; //=D2=D4=BA=F3=B6=C1=B5=C4=B6=BC=CA=C7=CD=EA=D5=FB=C9= =C8=C7=F8 + } + + return ret; +} + +//=B1=E9=C0=FA=D3=C9data->file_cluster=D6=B8=B6=A8=B5=C4=C4=BF=C2=BC +int +grub_fat_iterate_dir (BlockDriverState *bs, struct grub_fat_data *data) +{ + struct grub_fat_dir_entry dir; + char *filename, *filep =3D 0; + grub_uint16_t *unibuf; + int slot =3D -1, slots =3D -1; + int checksum =3D -1; + grub_ssize_t offset =3D -sizeof(dir); + + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) + return printf("not a directory......\n"); + + /* Allocate space enough to hold a long name. */ + filename =3D (char*)malloc (0x40 * 13 * 4 + 1); + unibuf =3D (grub_uint16_t *) malloc (0x40 * 13 * 2); + if (! filename || ! unibuf) + { + free (filename); + free (unibuf); + return -1; + } + + + int count =3D 0; + while (1) + { + unsigned i; + + /* Adjust the offset. */ + offset +=3D sizeof (dir); + printf("[%d]offset=3D%u\n" + "data->cur_cluster_num=3D%u,data->cur_cluster=3D%u\n", + count+1, offset, + data->cur_cluster_num, data->cur_cluster); + /* Read a directory entry. */ + //0x0=B1=ED=CA=BE=BF=D5=C4=BF=C2=BC + if ((grub_fat_read_data (bs, data, 0, 0, + offset, sizeof (dir), (char *) &dir) + !=3D sizeof (dir) || dir.name[0] =3D=3D 0)) + { + printf("break...dir.name[0]=3D=3D%d\n", dir.name[0]); + break; + } + /* Handle long name entries. */ + if (dir.attr =3D=3D GRUB_FAT_ATTR_LONG_NAME) + { + printf("long name...\n"); + struct grub_fat_long_name_entry *long_name + =3D (struct grub_fat_long_name_entry *) &dir; + grub_uint8_t id =3D long_name->id; + + if (id & 0x40) //the last item + { + id &=3D 0x3f; //index or ordinal number 1~31 + slots =3D slot =3D id; + checksum =3D long_name->checksum; + printf("the last ordinal num=3D%d!!!\n", id); + } + + if (id !=3D slot || slot =3D=3D 0 || checksum !=3D long_name->checksum) + { + printf("not valid ordinal number ,ignore...continue\n"); + checksum =3D -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=B1=ED=CA=BE=D2=D1=BE=AD=B1=BB=C9=BE=B3=FD + if (dir.name[0] =3D=3D 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID)) + { + printf("dir.name[0]=3D0x%x, dir.attr=3D0x%x not valid...continue\n", + dir.name[0], dir.attr); + continue; + } + + printf("checksum=3D%d, slot=3D%d\n", checksum, slot); + /* This is a workaround for Japanese. */ + if (dir.name[0] =3D=3D 0x05) + dir.name[0] =3D 0xe5; + + if (checksum !=3D -1 && slot =3D=3D 0) + { + printf("checksuming\n"); + grub_uint8_t sum; + + for (sum =3D 0, i =3D 0; i < sizeof (dir.name); i++) + sum =3D ((sum >> 1) | (sum << 7)) + dir.name[i]; + + if (sum =3D=3D checksum) + {//=B3=A4=C3=FB=B1=ED=CF=EE=BA=F3=C3=E6=BD=F4=BD=D3=B6=CC=C3=FB=B1=ED= =CF=EE=A3=AC=D1=E9=D6=A4=B3=C9=B9=A6=D4=F2=D6=A4=C3=F7=D5=E6=D5=FD=CA=C7=B3= =A4=C3=FB=D7=D6 + int u; + + for (u =3D 0; u < slots * 13; u++) + unibuf[u] =3D grub_le_to_cpu16 (unibuf[u]); + + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf, + slots * 13) =3D '\0'; + + //if (hook (filename, &dir, closure)) + //break; + + checksum =3D -1; + for (i =3D 0; i < sizeof (dir.name); i++) + printf("0x%x ", dir.name[i]); + char *gbname =3D (char*)malloc(256); + u2g(filename, strlen(filename), gbname, 256); + printf("\ndir.name=3D%s, filename=3D%s, dir.attr=3D0x%x," + "sum=3D=3Dchecksum...continue\n", + dir.name, gbname, dir.attr); + free(gbname); + count++; + continue; + } + + checksum =3D -1; + } + + //=BA=F3=C3=E6=B5=C4=B4=A6=C0=ED=D5=EB=B6=D4=B7=C7=D5=E6=CA=B5=B3=A4= =C3=FB=BA=CD=D5=E6=CA=B5=B6=CC=C3=FB + /* Convert the 8.3 file name. */ + //=C8=A5=B5=F4=B6=CC=C3=FB=B5=C4=BF=D5=B8=F1=A3=AC=C8=AB=B8=C4=CE=AA= =D0=A1=D0=B4 + filep =3D filename; + if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID) + { + printf("VOLUME\n"); + for (i =3D 0; i < sizeof (dir.name) && dir.name[i] + && ! grub_isspace (dir.name[i]); i++) + *filep++ =3D dir.name[i]; + } + else + { + for (i =3D 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++= ) + *filep++ =3D grub_tolower (dir.name[i]); + + *filep =3D '.'; + + for (i =3D 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i+= +) + *++filep =3D grub_tolower (dir.name[i]); + + if (*filep !=3D '.') + filep++; + } + *filep =3D '\0'; + + + for (i =3D 0; i < sizeof (dir.name); i++) + printf("0x%x ", dir.name[i]); + printf("\ndir.name=3D%s, filename=3D=A1=BE%s=A1=BF, dir.attr=3D0x%x,= " + "...next while\n", + dir.name, filename, dir.attr); + count++; + /*if(strcmp(filename, ".") && strcmp(filename, "..")) + { + printf("{=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D>\n"); + struct grub_fat_data *data2 =3D NULL; + data2 =3D (struct grub_fat_data*)malloc(sizeof(*data)); + memcpy(data2, data, sizeof(*data)); + data2->attr =3D dir.attr; + data2->file_size =3D grub_le_to_cpu32 (dir.file_size); + data2->file_cluster =3D ((grub_le_to_cpu16 (dir.first_cluster_high) << = 16) + | grub_le_to_cpu16 (dir.first_cluster_low)); + data2->cur_cluster_num =3D ~0U; + (grub_fat_iterate_dir(bs, data2) < 0) ? printf("error !!!!!!\n") : 0; + free(data2); + printf("<=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D}\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 =3D closure; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + + info.dir =3D !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY); + info.case_insensitive =3D 1; + + if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID) + return 0; + if (*(c->dirname) =3D=3D '\0' && (c->call_hook)) + return c->hook (filename, &info, c->closure); + + if (grub_strcasecmp (c->dirname, filename) =3D=3D 0) + { + struct grub_fat_data *data =3D c->data; + + c->found =3D 1; + data->attr =3D dir->attr; + data->file_size =3D grub_le_to_cpu32 (dir->file_size); + data->file_cluster =3D ((grub_le_to_cpu16 (dir->first_cluster_high) = << 16) + | grub_le_to_cpu16 (dir->first_cluster_low)); + data->cur_cluster_num =3D ~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 =3D=3D '/') + path++; + + dirp =3D grub_strchr (path, '/'); + if (dirp) + { + unsigned len =3D dirp - path; + + dirname =3D (char*)malloc (len + 1); + if (! dirname) + return 0; + + memcpy (dirname, path, len); + dirname[len] =3D '\0'; + } + else + { + /* This is actually a file. */ + dirname =3D grub_strdup (path); + } + //c.data =3D data; + //c.hook =3D hook; + //c.closure =3D closure; + //c.dirname =3Ddirname; + //c.found =3D 0; + //c.call_hook =3D (! dirp && hook); + if(grub_fat_iterate_dir (bs, data)<0) + { + printf("file not found..\n"); + return 0; + } + + + free (dirname); + + return dirp; +} + + + + + + + + + + + + + + + + + + diff --exclude=3D.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=3D.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 . + */ + +#ifndef GRUB_TYPES_HEADER +#define GRUB_TYPES_HEADER 1 + +#include +#include + +#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 !=3D 4 && GRUB_CPU_SIZEOF_VOID_P !=3D 8 +# error "This architecture is not supported because sizeof(void *) !=3D 4 and sizeof(void *) !=3D 8" +#endif + +#ifndef GRUB_TARGET_WORDSIZE +# if GRUB_TARGET_SIZEOF_VOID_P =3D=3D 4 +# define GRUB_TARGET_WORDSIZE 32 +# elif GRUB_TARGET_SIZEOF_VOID_P =3D=3D 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 =3D=3D 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 =3D=3D 8 +typedef unsigned long grub_uint64_t; +#else +typedef unsigned long long grub_uint64_t; +#endif + +/* Misc types. */ +#if GRUB_TARGET_SIZEOF_VOID_P =3D=3D 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 =3D=3D 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 =3D=3D 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 =3D=3D 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 =3D (x); \ + (grub_uint16_t) ((_x << 8) | (_x >> 8)); \ +}) + +#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >=3D 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 =3D (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 =3D (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 =3D=3D 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=3D.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 . + */ + +#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=3D.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 =3D=3D 0) + return 0; + + while (*s1 && *s2 && --n) + { + if (*s1 !=3D *s2) + break; + + s1++; + s2++; + } + + return (int) *s1 - (int) *s2; +} diff --exclude=3D.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 . + */ + +#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=3D.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 . + */ + +#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=3D.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=3Dcutils.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 +=3D -lz clean: # avoid old build problems by removing potentially incorrect old files diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/Makefile.or= ig 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=3D$(SRC_PATH):$(SRC_PATH)/hw + + +CFLAGS +=3D $(OS_CFLAGS) $(ARCH_CFLAGS) +LDFLAGS +=3D $(OS_LDFLAGS) $(ARCH_LDFLAGS) + +CPPFLAGS +=3D -I. -I$(SRC_PATH) -MMD -MP -MT $@ +CPPFLAGS +=3D -D_GNU_SOURCE -D_FILE_OFFSET_BITS=3D64 -D_LARGEFILE_SOURCE +LIBS=3D +ifdef CONFIG_STATIC +LDFLAGS +=3D -static +endif +ifdef BUILD_DOCS +DOCS=3Dqemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 +else +DOCS=3D +endif + +LIBS+=3D$(AIOLIBS) + +ifdef CONFIG_SOLARIS +LIBS+=3D-lsocket -lnsl -lresolv +endif + +ifdef CONFIG_WIN32 +LIBS+=3D-lwinmm -lws2_32 -liphlpapi +endif + +all: $(TOOLS) $(DOCS) recurse-all + +SUBDIR_RULES=3D$(patsubst %,subdir-%, $(TARGET_DIRS)) + +subdir-%: + $(call quiet-command,$(MAKE) -C $* V=3D"$(V)" TARGET_DIR=3D"$*/" all,) + +$(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a +$(filter %-user,$(SUBDIR_RULES)): libqemu_user.a + +recurse-all: $(SUBDIR_RULES) + +CPPFLAGS +=3D -I$(XEN_ROOT)/tools/libxc +CPPFLAGS +=3D -I$(XEN_ROOT)/tools/blktap/lib +CPPFLAGS +=3D -I$(XEN_ROOT)/tools/xenstore +CPPFLAGS +=3D -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=3Dcutils.o osdep.o qemu-malloc.o +BLOCK_OBJS+=3Dblock-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o +BLOCK_OBJS+=3Dblock-dmg.o block-bochs.o block-vpc.o block-vvfat.o +BLOCK_OBJS+=3Dblock-qcow2.o block-parallels.o block-nbd.o +BLOCK_OBJS+=3Dnbd.o block.o aio.o + +ifdef CONFIG_WIN32 +BLOCK_OBJS +=3D block-raw-win32.o +else +ifdef CONFIG_AIO +BLOCK_OBJS +=3D posix-aio-compat.o +endif +BLOCK_OBJS +=3D 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=3D$(BLOCK_OBJS) +OBJS+=3Dreadline.o console.o + +OBJS+=3Dirq.o +OBJS+=3Di2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o +OBJS+=3Dssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o +OBJS+=3Dtmp105.o lm832x.o +OBJS+=3Dscsi-disk.o cdrom.o +OBJS+=3Dscsi-generic.o +OBJS+=3Dusb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o +OBJS+=3Dusb-serial.o usb-net.o +OBJS+=3Dsd.o ssi-sd.o +OBJS+=3Dbt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o +OBJS+=3Dbuffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o +OBJS+=3Dqemu-char.o aio.o net-checksum.o savevm.o cache-utils.o + +ifdef CONFIG_BRLAPI +OBJS+=3D baum.o +LIBS+=3D-lbrlapi +endif + +ifdef CONFIG_WIN32 +OBJS+=3Dtap-win32.o +else +OBJS+=3Dmigration-exec.o +endif + +AUDIO_OBJS =3D audio.o noaudio.o wavaudio.o mixeng.o +ifdef CONFIG_SDL +AUDIO_OBJS +=3D sdlaudio.o +endif +ifdef CONFIG_OSS +AUDIO_OBJS +=3D ossaudio.o +endif +ifdef CONFIG_COREAUDIO +AUDIO_OBJS +=3D coreaudio.o +AUDIO_PT =3D yes +endif +ifdef CONFIG_ALSA +AUDIO_OBJS +=3D alsaaudio.o +endif +ifdef CONFIG_DSOUND +AUDIO_OBJS +=3D dsoundaudio.o +endif +ifdef CONFIG_FMOD +AUDIO_OBJS +=3D fmodaudio.o +audio/audio.o audio/fmodaudio.o: CPPFLAGS :=3D -I$(CONFIG_FMOD_INC) $(CPPFLAGS) +endif +ifdef CONFIG_ESD +AUDIO_PT =3D yes +AUDIO_PT_INT =3D yes +AUDIO_OBJS +=3D esdaudio.o +endif +ifdef CONFIG_PA +AUDIO_PT =3D yes +AUDIO_PT_INT =3D yes +AUDIO_OBJS +=3D paaudio.o +endif +ifdef AUDIO_PT +LDFLAGS +=3D -pthread +endif +ifdef AUDIO_PT_INT +AUDIO_OBJS +=3D audio_pt_int.o +endif +AUDIO_OBJS+=3D wavcapture.o +ifdef CONFIG_AUDIO +OBJS+=3D$(addprefix audio/, $(AUDIO_OBJS)) +endif + +ifdef CONFIG_SDL +OBJS+=3Dsdl.o x_keymap.o +endif +ifdef CONFIG_CURSES +OBJS+=3Dcurses.o +endif +OBJS+=3Dvnc.o d3des.o + +ifdef CONFIG_COCOA +OBJS+=3Dcocoa.o +endif + +ifdef CONFIG_SLIRP +CPPFLAGS+=3D-I$(SRC_PATH)/slirp +SLIRP_OBJS=3Dcksum.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+=3D$(addprefix slirp/, $(SLIRP_OBJS)) +endif + +LIBS+=3D$(VDE_LIBS) + +cocoa.o: cocoa.m + +sdl.o: sdl.c keymaps.c sdl_keysym.h + +sdl.o audio/sdlaudio.o: CFLAGS +=3D $(SDL_CFLAGS) + +vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h + +vnc.o: CFLAGS +=3D $(CONFIG_VNC_TLS_CFLAGS) + +curses.o: curses.c keymaps.c curses_keys.h + +bt-host.o: CFLAGS +=3D $(CONFIG_BLUEZ_CFLAGS) + +libqemu_common.a: $(OBJS) + +####################################################################### +# USER_OBJS is code used by qemu userspace emulation +USER_OBJS=3Dcutils.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 +=3D -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=3Dda 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=3Dbios.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=3D +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=3D1 --center=3D" " --release=3D" " qemu.pod > $@ + +qemu-img.1: qemu-img.texi + $(SRC_PATH)/texi2pod.pl $< qemu-img.pod + pod2man --section=3D1 --center=3D" " --release=3D" " qemu-img.pod > $@ + +qemu-nbd.8: qemu-nbd.texi + $(SRC_PATH)/texi2pod.pl $< qemu-nbd.pod + pod2man --section=3D8 --center=3D" " --release=3D" " 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 ?=3D $(shell cat VERSION) +FILE =3D 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=3D.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 +#include +#include +#include "grub_err.h" + + +int +grub_isspace (int c) +{ + return (c =3D=3D '\n' || c =3D=3D '\r' || c =3D=3D ' ' || c =3D=3D '\t')= ; +} + +int +grub_tolower (int c) +{ + if (c >=3D 'A' && c <=3D 'Z') + return c - 'A' + 'a'; + + return c; +} + + +char * +grub_strchr (const char *s, int c) +{ + do + { + if (*s =3D=3D c) + return (char *) s; + } + while (*s++); + + return 0; +} + + +grub_size_t +grub_strlen (const char *s) +{ + const char *p =3D s; + + while (*p) + p++; + + return p - s; +} + + + + + +char * +grub_strncpy (char *dest, const char *src, int c) +{ + char *p =3D dest; + + while ((*p++ =3D *src++) !=3D '\0' && --c) + ; + + return dest; +} + +char * +grub_strdup (const char *s) +{ + grub_size_t len; + char *p; + + len =3D grub_strlen (s) + 1; + p =3D (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 =3D grub_strlen (s); + if (len > n) + len =3D n; + p =3D (char *) malloc (len + 1); + if (! p) + return 0; + + memcpy (p, s, len); + p[len] =3D '\0'; + return p; +} + + + + +int +grub_strcmp (const char *s1, const char *s2) +{ + while (*s1 && *s2) + { + if (*s1 !=3D *s2) + break; + + s1++; + s2++; + } + + return (int) *s1 - (int) *s2; +} + +int +grub_strncmp (const char *s1, const char *s2, grub_size_t n) +{ + if (n =3D=3D 0) + return 0; + + while (*s1 && *s2 && --n) + { + if (*s1 !=3D *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) !=3D 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 =3D=3D 0) + return 0; + + while (*s1 && *s2 && --n) + { + if (grub_tolower (*s1) !=3D 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 =3D (char *) dest; + const char *s =3D (const char *) src; + + if (d < s) + while (n--) + *d++ =3D *s++; + else + { + d +=3D n; + s +=3D n; + + while (n--) + *--d =3D *--s; + } + + return dest; +} + + +void * +grub_malloc (grub_size_t size) +{ + void *ret; + ret =3D 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 =3D (unsigned char *) s; + + while (n--) + *p++ =3D (unsigned char) c; + + return s; +} + +int +grub_memcmp (const void *s1, const void *s2, grub_size_t n) +{ + const char *t1 =3D s1; + const char *t2 =3D s2; + + while (n--) + { + if (*t1 !=3D *t2) + return (int) *t1 - (int) *t2; + + t1++; + t2++; + } + + return 0; +} + + +void * +grub_zalloc (grub_size_t size) +{ + void *ret; + + ret =3D 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) =3D upper((Q * 10 + M) * 2^i), where upper + represents the high 64 bits in 128-bits space. */ + unsigned bits =3D 64; + unsigned long long q =3D 0; + unsigned m =3D 0; + + /* Skip the slow computation if 32-bit arithmetic is possible. */ + if (n < 0xffffffff) + { + if (r) + *r =3D ((grub_uint32_t) n) % d; + + return ((grub_uint32_t) n) / d; + } + + while (bits--) + { + m <<=3D 1; + + if (n & (1ULL << 63)) + m |=3D 1; + + q <<=3D 1; + n <<=3D 1; + + if (m >=3D d) + { + q |=3D 1; + m -=3D d; + } + } + + if (r) + *r =3D 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 =3D 0; + + while (size--) + { + grub_uint32_t code =3D *src++; + + if (code_high) + { + if (code >=3D 0xDC00 && code <=3D 0xDFFF) + { + /* Surrogate pair. */ + code =3D ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; + + *dest++ =3D (code >> 18) | 0xF0; + *dest++ =3D ((code >> 12) & 0x3F) | 0x80; + *dest++ =3D ((code >> 6) & 0x3F) | 0x80; + *dest++ =3D (code & 0x3F) | 0x80; + } + else + { + /* Error... */ + *dest++ =3D '?'; + } + + code_high =3D 0; + } + else + { + if (code <=3D 0x007F) + *dest++ =3D code; + else if (code <=3D 0x07FF) + { + *dest++ =3D (code >> 6) | 0xC0; + *dest++ =3D (code & 0x3F) | 0x80; + } + else if (code >=3D 0xD800 && code <=3D 0xDBFF) + { + code_high =3D code; + continue; + } + else if (code >=3D 0xDC00 && code <=3D 0xDFFF) + { + /* Error... */ + *dest++ =3D '?'; + } + else + { + *dest++ =3D (code >> 12) | 0xE0; + *dest++ =3D ((code >> 6) & 0x3F) | 0x80; + *dest++ =3D (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 =3D (unsigned char*)p; + for(i =3D 0; i < len; i++) + { + printf("0x%02x,", pb[i]); + } + printf("\n**********************end**************************\n"); +} + + + +#include +#define OUTLEN 256 + + +//=B4=FA=C2=EB=D7=AA=BB=BB:=B4=D3=D2=BB=D6=D6=B1=E0=C2=EB=D7=AA=CE=AA=C1= =ED=D2=BB=D6=D6=B1=E0=C2=EB +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 =3D &inbuf; + char **pout =3D &outbuf; + + //printf("sizeof(int)=3D%d, sizeof(size_t)=3D%d\n", sizeof(int), sizeof(size_t)); + cd =3D iconv_open(to_charset, from_charset); + if (cd=3D=3D0) return -1; + memset(outbuf, 0, outlen); + if (iconv(cd, pin, &inlen, pout, &outlen)=3D=3D-1) return -1; + iconv_close(cd); + return 0; +} +//UNICODE=C2=EB=D7=AA=CE=AAGB2312=C2=EB +int u2g(char *inbuf, size_t inlen, char *outbuf, size_t outlen) +{ + return code_convert("utf-8", "gb2312", inbuf, inlen, outbuf, outlen); +} +//GB2312=C2=EB=D7=AA=CE=AAUNICODE=C2=EB +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) +{ + //=D7=D6=B7=FB=B1=E0=C2=EB=D7=AA=BB=BB=3D=EF=BB=BF=E5?=E7=AC????=BD=AC?? + char in_utf8[] =3D {0xe5,0xad,0x97,0xe7,0xac,0xa6,0xe7,0xbc,0x96,0xe7,0xa0,0x81,0xe8,0xbd,0xac= ,0xe6,0x8d,0xa2}; + char *in_gb2312 =3D (char*) "=D7=D6=B7=FB=B1=E0=C2=EB=D7=AA=BB=BB"; + char out[OUTLEN]; + int rc; + //utf8=C2=EB=D7=AA=CE=AAgb2312=C2=EB + rc =3D u2g(in_utf8, strlen(in_utf8), out, OUTLEN); + printf("utf8-->gb2312 out=3D%s\n", out); + print_byte(out, strlen(out)); + //gb2312=C2=EB=D7=AA=CE=AAutf8=C2=EB + rc =3D g2u(in_gb2312, strlen(in_gb2312), out, OUTLEN); + print_byte(out, strlen(out)); + printf("gb2312-->utf8 out=3D%s\n",out); +} + + + diff --exclude=3D.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 + + + + + +#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=C2=EB=D7=AA=CE=AAGB2312=C2=EB +int u2g(char *inbuf, size_t inlen, char *outbuf, size_t outlen); +//GB2312=C2=EB=D7=AA=CE=AAUNICODE=C2=EB +int g2u(char *inbuf, size_t inlen, char *outbuf, size_t outlen); + + + +void test(void); + + + diff --exclude=3D.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 . + */ + + +#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 =3D u16at (buf, 6) - 1; + if (ss * (int) data->blocksize !=3D 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 =3D buf + u16at (buf, 4); + us =3D u16at (pu, 0); + buf -=3D 2; + while (ss > 0) + { + buf +=3D data->blocksize; + pu +=3D 2; + if (u16at (buf, 0) !=3D us) + return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match"); + v16at (buf, 0) =3D 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 =3D mft; + at->flags =3D (mft =3D=3D &mft->data->mmft) ? AF_MMFT : 0; + at->attr_nxt =3D mft->buf + u16at (mft->buf, 0x14); + at->attr_end =3D at->emft_buf =3D at->edat_buf =3D at->sbuf =3D 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=3D=3D=3D=3D=3D=3D"); + retry: + while (at->attr_nxt < at->attr_end) + { + at->attr_cur =3D at->attr_nxt; + at->attr_nxt +=3D u16at (at->attr_cur, 4); + if (((unsigned char) *at->attr_cur =3D=3D attr) || (attr =3D=3D 0)) + { + char *new_pos; + + if (at->flags & AF_MMFT) + { + DBG("in AF_MMFT......"); + off_bytes1 =3D (grub_off_t)(v32at (at->attr_cur, 0x10)) << BLK_SHR; + off_bytes2 =3D (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=3D=3D=3D=3D=3D=3D"); + if (read_mft (at->mft->data, at->emft_buf, + u32at (at->attr_cur, 0x10))) + return NULL; + } + + new_pos =3D &at->emft_buf[u16at (at->emft_buf, 0x14)]; + while ((unsigned char) *new_pos !=3D 0xFF) + { + DBG("new pos in extend mft=3D=3D=3D=3D=3D=3D"); + if (((unsigned char) *new_pos =3D=3D + (unsigned char) *at->attr_cur) + && (u16at (new_pos, 0xE) =3D=3D u16at (at->attr_cur, 0x18))) + { + return new_pos; + } + new_pos +=3D 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=3D=3D=3D=3D=3D=3D"); + at->attr_cur =3D at->attr_nxt; + while ((unsigned char) *at->attr_cur !=3D 0xFF) + { + at->attr_nxt +=3D u16at (at->attr_cur, 4); + if ((unsigned char) *at->attr_cur =3D=3D AT_ATTRIBUTE_LIST) + at->attr_end =3D at->attr_cur; + if (((unsigned char) *at->attr_cur =3D=3D attr) || (attr =3D=3D 0)) + { + DBG("found=3D=3D=3D=3D=3D=3D"); + return at->attr_cur; + } + at->attr_cur =3D at->attr_nxt; + } + + + if (at->attr_end) + { + DBG("searching in attr list=3D=3D=3D=3D=3D=3D"); + char *pa; + + at->emft_buf =3D grub_malloc (at->mft->data->mft_size << BLK_SHR); + if (at->emft_buf =3D=3D NULL) + return NULL; + + pa =3D at->attr_end; + if (pa[8]) + { + int n; + + n =3D ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1) + & (~(GRUB_DISK_SECTOR_SIZE - 1))); + at->attr_cur =3D at->attr_end; + at->edat_buf =3D 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 =3D at->edat_buf; + at->attr_end =3D at->edat_buf + u32at (pa, 0x30); + } + else + { + at->attr_nxt =3D at->attr_end + u16at (pa, 0x14); + at->attr_end =3D at->attr_end + u32at (pa, 4); + } + at->flags |=3D AF_ALST; + while (at->attr_nxt < at->attr_end) + { + if (((unsigned char) *at->attr_nxt =3D=3D attr) || (attr =3D=3D 0)) + break; + at->attr_nxt +=3D u16at (at->attr_nxt, 4); + } + if (at->attr_nxt >=3D at->attr_end) + { + DBG("not found in list"); + return NULL; + } + DBG("found in attr list=3D=3D=3D=3D=3D=3D"); + if ((at->flags & AF_MMFT) && (attr =3D=3D AT_DATA)) + { + DBG("AF_GPOS!!!!!!=3D=3D=3D=3D=3D=3D"); + at->flags |=3D AF_GPOS; + at->attr_cur =3D at->attr_nxt; + pa =3D at->attr_cur; + v32at (pa, 0x10) =3D at->mft->data->mft_start; + v32at (pa, 0x14) =3D at->mft->data->mft_start + 1; + pa =3D at->attr_nxt + u16at (pa, 4); + while (pa < at->attr_end) + { + if ((unsigned char) *pa !=3D 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 +=3D u16at (pa, 4); + } + at->attr_nxt =3D at->attr_cur; + at->flags &=3D ~AF_GPOS; + } + + DBG("goto retry=3D=3D=3D=3D=3D=3D"); + 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=3D0x%02x, at->flag=3D0x%02x=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D", + attr, at->flags); + if ((pa =3D find_attr (at, attr)) =3D=3D NULL) + { + DBG("1=3D=3D=3D=3D=3D=3D=3D=3D=3Dnot found"); + return NULL; + } + if ((at->flags & AF_ALST) =3D=3D 0) + { + DBG("2=3D=3D=3D=3D=3D=3D=3Dnot a attr list, continue searching"); + while (1) + { + if ((pa =3D find_attr (at, attr)) =3D=3D NULL) + break; + if (at->flags & AF_ALST) + { + DBG("3=3D=3D=3D=3D=3D=3D=3D=3D=3D=3Din a attr list,found"); + return pa; + } + } + DBG("4=3D=3D=3D=3D=3D=3D=3D=3Dstart searching all over again"); + grub_errno =3D GRUB_ERR_NONE; + free_attr (at); + init_attr (at, mft); + pa =3D find_attr (at, attr); + } + DBG("locate finish=3D=3D=3D=3D=3D=3D\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 =3D 0; + v =3D 1; + + while (nn--) + { + r +=3D v * (*(unsigned char *) (run++)); + v <<=3D 8; + } + + if ((sig) && (r & (v >> 1))) + r -=3D v; + + *val =3D 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 =3D ctx->cur_run; +retry: + c1 =3D ((unsigned char) (*run) & 0xF); + c2 =3D ((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 =3D ctx->comp.bs->read_hook; + //ctx->comp.bs->read_hook =3D 0; + run =3D find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur); + //ctx->comp.bs->read_hook =3D save_hook; + if (run) + { + if (run[8] =3D=3D 0) + return grub_error (GRUB_ERR_BAD_FS, + "$DATA should be non-resident"); + + run +=3D u16at (run, 0x20); + ctx->curr_lcn =3D 0; + goto retry; + } + } + return grub_error (GRUB_ERR_BAD_FS, "run list overflown"); + } + run =3D read_run_data (run + 1, c1, &val, 0); /* length of current VCN *= / + ctx->curr_vcn =3D ctx->next_vcn; + ctx->next_vcn +=3D val; + run =3D read_run_data (run, c2, &val, 1); /* offset to previous LCN */ + ctx->curr_lcn +=3D val; + if (val =3D=3D 0) + ctx->flags |=3D RF_BLNK; + else + ctx->flags &=3D ~RF_BLNK; + ctx->cur_run =3D 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 =3D (struct grub_ntfs_rlst *) node; + if (block >=3D 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 =3D=3D 0) + return 0; + + grub_memset (&cc, 0, sizeof (cc)); + ctx =3D &cc; + ctx->attr =3D at; + ctx->comp.spc =3D at->mft->data->spc; + ctx->comp.bs =3D at->mft->data->bs; + + if (pa[8] =3D=3D 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 |=3D RF_COMP; + else + ctx->flags &=3D ~RF_COMP; + ctx->cur_run =3D 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))) =3D=3D at->save_pos) + { + grub_disk_addr_t n; + + n =3D COM_LEN - (ofs - at->save_pos); + if (n > len) + n =3D len; + + grub_memcpy (dest, at->sbuf + ofs - at->save_pos, n); + if (n =3D=3D len) + return 0; + + dest +=3D n; + len -=3D n; + ofs +=3D n; + } + } + else + { + at->sbuf =3D grub_malloc (COM_LEN); + if (at->sbuf =3D=3D NULL) + return grub_errno; + at->save_pos =3D 1; + } + + vcn =3D ctx->target_vcn =3D (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc); + ctx->target_vcn &=3D ~0xF; + } + else + vcn =3D ctx->target_vcn =3D grub_divmod64 (ofs >> BLK_SHR, ctx->comp.s= pc, 0); + + ctx->next_vcn =3D u32at (pa, 0x10); + ctx->curr_lcn =3D 0; + while (ctx->next_vcn <=3D 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 =3D + (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m; + st1 =3D st0 + 1; + if (st1 =3D=3D + (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + st1 =3D ctx->curr_lcn * ctx->comp.spc; + } + v32at (dest, 0) =3D st0; + v32at (dest, 4) =3D 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 =3D at->attr_cur; + at->attr_nxt =3D at->attr_cur; + attr =3D (unsigned char) *at->attr_nxt; + if (at->flags & AF_ALST) + { + char *pa; + grub_disk_addr_t vcn; + + vcn =3D grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0); + pa =3D at->attr_nxt + u16at (at->attr_nxt, 4); + while (pa < at->attr_end) + { + if ((unsigned char) *pa !=3D attr) + break; + if (u32at (pa, 8) > vcn) + break; + at->attr_nxt =3D pa; + pa +=3D u16at (pa, 4); + } + } + pp =3D find_attr (at, attr); + if (pp) + ret =3D read_data (at, pp, dest, ofs, len, cached, read_hook, closure)= ; + else + ret =3D + (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS, + "attribute not found"); + at->attr_cur =3D 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 =3D 1; + + mft->buf =3D grub_malloc (mft->data->mft_size << BLK_SHR); + if (mft->buf =3D=3D NULL) + return grub_errno; + + if (read_mft (mft->data, mft->buf, mftno)) + return grub_errno; + + flag =3D u16at (mft->buf, 0x16); + if ((flag & 1) =3D=3D 0) + return grub_error (GRUB_ERR_BAD_FS, "MFT 0x%X is not in use", mftno); + + if ((flag & 2) =3D=3D 0) + { + char *pa; + + pa =3D locate_attr (&mft->attr, mft, AT_DATA); + if (pa =3D=3D NULL) + return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno); + + if (!pa[8]) + mft->size =3D u32at (pa, 0x10); + else + mft->size =3D u64at (pa, 0x30); + + if ((mft->attr.flags & AF_ALST) =3D=3D 0) + mft->attr.attr_end =3D 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 =3D pos + 0x50; + ns =3D (unsigned char) *(np++); + namespace =3D *(np++); + + /* + * Ignore files in DOS namespace, as they will reappear as Win32 + * names. + */ + if ((ns) && (namespace !=3D 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 =3D + (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : + GRUB_FSHELP_REG; + + fdiro =3D grub_zalloc (sizeof (struct grub_ntfs_file)); + if (!fdiro) + return 0; + + fdiro->data =3D diro->data; + fdiro->ino =3D u32at (pos, 0); + + ustr =3D grub_malloc (ns * 4 + 1); + gbstr =3D grub_malloc(ns * 2 + 1); + if (ustr =3D=3D NULL || gbstr =3D=3D NULL) + return 0; + *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np, + ns) =3D '\0'; + u2g(ustr, strlen(ustr), gbstr, ns * 2 + 1); + DBG("gbstr=3D%s", gbstr); + if (namespace) + type |=3D 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 +=3D 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 =3D 0; + grub_size_t bitmap_len; + struct grub_ntfs_file *mft; + + mft =3D (struct grub_ntfs_file *) dir; + + if (!mft->inode_read) + { + if (init_file (mft, mft->ino)) + return 0; + } + + indx =3D NULL; + bmp =3D NULL; + + at =3D &attr; + init_attr (at, mft); + while (1) + { + if ((cur_pos =3D find_attr (at, AT_INDEX_ROOT)) =3D=3D NULL) + { + grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT"); + goto done; + } + + /* Resident, Namelen=3D4, Offset=3D0x18, Flags=3D0x00, Name=3D"$I30"= */ + if ((u32at (cur_pos, 8) !=3D 0x180400) || + (u32at (cur_pos, 0x18) !=3D 0x490024) || + (u32at (cur_pos, 0x1C) !=3D 0x300033)) + continue; + cur_pos +=3D u16at (cur_pos, 0x14); + if (*cur_pos !=3D 0x30) /* Not filename index */ + continue; + break; + } + + cur_pos +=3D 0x10; /* Skip index root */ + ret =3D list_file (mft, cur_pos + u16at (cur_pos, 0), hook, closure); + if (ret) + goto done; + + + bitmap =3D NULL; + bitmap_len =3D 0; + free_attr (at); + init_attr (at, mft); + while ((cur_pos =3D find_attr (at, AT_BITMAP)) !=3D NULL) + { + int ofs; + + ofs =3D (unsigned char) cur_pos[0xA]; + /* Namelen=3D4, Name=3D"$I30" */ + if ((cur_pos[9] =3D=3D 4) && + (u32at (cur_pos, ofs) =3D=3D 0x490024) && + (u32at (cur_pos, ofs + 4) =3D=3D 0x300033)) + { + int is_resident =3D (cur_pos[8] =3D=3D 0); + + bitmap_len =3D ((is_resident) ? u32at (cur_pos, 0x10) : + u32at (cur_pos, 0x28)); + + bmp =3D grub_malloc (bitmap_len); + if (bmp =3D=3D 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 =3D u32at (cur_pos, 0x30); + } + + bitmap =3D (unsigned char *) bmp; + break; + } + } + + free_attr (at); + cur_pos =3D locate_attr (at, mft, AT_INDEX_ALLOCATION); + while (cur_pos !=3D NULL) + { + /* Non-resident, Namelen=3D4, Offset=3D0x40, Flags=3D0, Name=3D"$I30= " */ + if ((u32at (cur_pos, 8) =3D=3D 0x400401) && + (u32at (cur_pos, 0x40) =3D=3D 0x490024) && + (u32at (cur_pos, 0x44) =3D=3D 0x300033)) + break; + cur_pos =3D 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 =3D grub_malloc (mft->data->idx_size << BLK_SHR); + if (indx =3D=3D NULL) + goto done; + + v =3D 1; + for (i =3D 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 =3D list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook, + closure); + if (ret) + goto done; + } + v <<=3D 1; + if (v >=3D 0x100) + { + v =3D 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 =3D 0; + grub_off_t off_bytes =3D (grub_off_t)part_off_sector << BLK_SHR; + + if (!bs) + goto fail; + + data =3D (struct grub_ntfs_data *) grub_zalloc (sizeof (*data)); + if (!data) + goto fail; + + data->bs =3D bs; + + /* Read the BPB. */ + if (bdrv_pread (bs, off_bytes, &bpb, sizeof (bpb)) !=3D sizeof(bpb)) + { + DBG("read bpb err!"); + goto fail; + } + if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4)) + { + DBG("bpb.oem_name=3D%s, not ntfs", bpb.oem_name); + goto fail; + } + data->blocksize =3D grub_le_to_cpu16 (bpb.bytes_per_sector); + data->spc =3D bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR); + + if (bpb.clusters_per_mft > 0) + data->mft_size =3D data->spc * bpb.clusters_per_mft; + else + data->mft_size =3D 1 << (-bpb.clusters_per_mft - BLK_SHR); + + if (bpb.clusters_per_index > 0) + data->idx_size =3D data->spc * bpb.clusters_per_index; + else + data->idx_size =3D 1 << (-bpb.clusters_per_index - BLK_SHR); + + data->mft_start =3D 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 =3D data; + data->cmft.data =3D data; + + data->mmft.buf =3D grub_malloc (data->mft_size << BLK_SHR); + if (!data->mmft.buf) + goto fail; + + s_bpb_bytes_per_sector =3D (bpb.bytes_per_sector); + s_part_off_sector =3D part_off_sector; + DBG("bpb.bytes_per_sector=3Dblocksize=3D%u\n" + "bpb.sector_per_cluster=3D%u\n" + "data->blocksize=3D%u\n" + "data->spc=3D%u\n" + "bpb.clusters_per_mft=3D%d\n" + "data->mft_size=3D%u\n" + "bpb.total_sectors=3D%zd\n" + "bpb.mft_lcn=3D%zd\n" + "data->mft_start=3D%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 =3D (grub_off_t)data->mft_start << BLK_SHR; + grub_uint32_t len =3D data->mft_size << BLK_SHR; + if (bdrv_pread_from_lcn_of_volum(bs, off_bytes, + data->mmft.buf, len) !=3D len) + { + DBG("read mmft error!"); + goto fail; + } + data->uuid =3D 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 =3D closure; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir =3D ((filetype & GRUB_FSHELP_TYPE_MASK) =3D=3D GRUB_FSHELP_DIR)= ; + c->file.data =3D node->data; + c->file.ino =3D 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 =3D locate_attr(&c->file.attr, + &c->file, AT_STANDARD_INFORMATION); + if(NULL =3D=3D pa) + { + errx(2, "no $STANDARD_INFORMATION in MFT 0x%x\n", c->file.ino); + } + grub_uint64_t date=3D 0; + if(read_attr(&c->file.attr, (char*)&date, 0, 8, 1, NULL, NULL)) + { + errx(3, "read date error\n"); + } + else + { + + info.time_ntfs =3D date; + DBG("......date: %zu\n", date); + } + DBG("......size of \'%s\': %zu\n", filename, (c->file.size)); + info.filesize_ntfs =3D 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 =3D (struct ls_ctrl*)closure; + DBG("detail=3D%d", ctrl->detail); + if('$' =3D=3D *filename) + goto done; + + printf("%s", filename); + if(!ctrl->detail) + { + printf("\n"); + goto done; + } + else + { + printf("\t"); + } + + char buffer[50]=3D{}; + struct tm tm0; + struct tm* ptm=3D ntfs_utc2local(info->time_ntfs, &tm0); + if(NULL =3D=3D 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; // =D7=EE=D6=D5=B7=B5=BB=D8=B8=F8iterate +} + + + +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 =3D 0; + struct grub_fshelp_node *fdiro =3D 0; + struct grub_ntfs_dir_closure c =3D {0}; + + data =3D 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 =3D (hook ? hook : find_then_ls_hook); + c.closure =3D closure; + grub_ntfs_iterate_dir (fdiro, iterate, &c); + +fail: + if ((fdiro) && (fdiro !=3D &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 =3D 0; + struct grub_fshelp_node *mft =3D 0; + + + data =3D 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 !=3D &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 =3D data->cmft.size; + file->data =3D data; + file->offset =3D 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 =3D &((struct grub_ntfs_data *) file->data)->cmft; + if (file->read_hook) + mft->attr.save_pos =3D 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 =3D file->data; + + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + + + return grub_errno; +} + + + diff --exclude=3D.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 . + */ + +#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=3D.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 + +static int is_full_zero(void *p, uint bytes) +{ + int i =3D 0; + uint8_t *p1 =3D (uint8_t*)p; + while(i < bytes) + { + if(*p1 !=3D 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 =3D p[0]; + r->start_head =3D p[1]; + r->start_cylinder =3D p[3] | ((p[2] << 2) & 0x0300); + r->start_sector =3D p[2] & 0x3f; + r->system =3D p[4]; + r->end_head =3D p[5]; + r->end_cylinder =3D p[7] | ((p[6] << 2) & 0x300); + r->end_sector =3D p[6] & 0x3f; + r->start_sector_abs =3D p[8] | p[9] << 8 | p[10] << 16 | p[11] << 24; + r->nb_sectors_abs =3D p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24; +} + + + +char* judge_fs(ls_partition_t* pt) +{ + if(pt->part.system=3D=3D0x0b || pt->part.system=3D=3D0x01) + { + pt->fs_type =3D FS_FAT; + return (char*)"FAT32"; + } + else if(pt->part.system=3D=3D0x07) + { + pt->fs_type =3D FS_NTFS; + return (char*)"NTFS"; + } + else + { + pt->fs_type =3D 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 =3D 4; + struct partition_record ext[10]; + uint8_t data1[512]; + int j =3D 0; + + if (bdrv_read(bs, 0, data, 1)) + errx(EINVAL, "error while reading"); + + if (data[510] !=3D 0x55 || data[511] !=3D 0xaa) + { + errno =3D -EINVAL; + return -1; + } + + int k =3D 0; + for (i =3D 0; i < 4; i++) + { + read_partition(&data[446 + 16 * i], &mbr[i]); + + if (!mbr[i].nb_sectors_abs) + continue; + //printf("the %d partition:boot=3D0x%x, start=3D%u, system=3D0x%x, total= =3D%u\t", + // i+1, mbr[i].bootable, mbr[i].start_sector_abs, mbr[i].system, mbr[i].nb_sectors_abs); + parts[k].part =3D mbr[i]; + parts[k].id =3D i+1; + k++; + if (mbr[i].system =3D=3D 0xF || mbr[i].system =3D=3D 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 =3D mbr[i].start_sector_abs; + struct partition_record ext_next =3D {0}; + while (1) + { + read_partition(&data1[446 + 16 * 0], &ext[j]); + //printf("the %dth partition:boot=3D0x%x, start=3D%u, system=3D0x%x, total=3D%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 !=3D ext[j].nb_sectors_abs) + { + ext[j].start_sector_abs +=3D ext_start_sector; + if(j > 0) + ext[j].start_sector_abs +=3D ext_next.start_sector_abs; + parts[k].part =3D ext[j]; + parts[k].id =3D ext_partnum + j +1; + k++; + j++; + } + else + { + printf("nb_sectors_abs=3D0>>>>>>>>>>>>\n"); + } + ////////////////////// + if(ext[j-1].system =3D=3D 0xF ) + { + printf("...............again extend.............\n"); + ext_start_sector =3D 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 =3D 4; + + + if (bdrv_read(bs, 0, data, 1)) + errx(EINVAL, "error while reading"); + + if (data[510] !=3D 0x55 || data[511] !=3D 0xaa) + { + errno =3D -EINVAL; + return -1; + } + + int k =3D 0; + for (i =3D 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 =3D=3D 0xF || mbr[i].system =3D=3D 0x5) + { + //printf("is a extend partition......\n"); + struct partition_record ext[10]; + uint8_t data1[512]; + int j =3D 0; + + if (bdrv_read(bs, mbr[i].start_sector_abs, data1, 1)) + errx(EINVAL, "error while reading"); + + uint32_t ext_start_sector =3D mbr[i].start_sector_abs; + struct partition_record ext_next =3D {0}; + while (1) + { + read_partition(&data1[446 + 16 * 0], &ext[j]); + printf("start=3D%u, total=3D%u, system=3D0x%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 !=3D ext[j].nb_sectors_abs) + { + if ((ext_partnum + j + 1) =3D=3D partition) + { + ext[j].start_sector_abs +=3D ext_start_sector; + if(j > 0) + ext[j].start_sector_abs +=3D ext_next.start_sector_abs; + *offset =3D (uint64_t)ext[j].start_sector_abs << 9; + *size =3D (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 +=3D 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) =3D=3D partition) + { + *offset =3D (uint64_t)mbr[i].start_sector_abs << 9; + *size =3D (uint64_t)mbr[i].nb_sectors_abs << 9; + return 0; + } + } + } + + errno =3D -ENOENT; + return -1; +} + +/////////////////////////////////////////////////////// diff --exclude=3D.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 + +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 =3D 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=3D.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 +#include + + +#include "partition.h" +#include "fs-comm.h" +#include "fat.h" +#include "ntfs.h" +#include "misc.h" + + + #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #endif /* Default to cache=3Dwriteback 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]=3D{}; + + strncpy(full_path, dir, 512); + full_path[511] =3D '\0'; + + //=CF=DE=D6=C6=D2=D4/=BF=AA=CD=B7 =BD=E1=CE=B2 + char *p1 =3D full_path + 1; + char *p2 =3D strchr(full_path + 1, '/'); + if(!p2) + { + errx(1, "check the file path!\n"); + } + + *path =3D p2; + strncpy(part, p1, p2-p1); + *which_part =3D 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] =3D {}; + +static void grub_fs_plugin(void) +{ + grub_fs_plug[FS_FAT].open =3D grub_fat_open; + grub_fs_plug[FS_FAT].read =3D grub_fat_read; + grub_fs_plug[FS_FAT].close =3D grub_fat_close; + grub_fs_plug[FS_FAT].ls =3D grub_fat_ls; + + grub_fs_plug[FS_NTFS].open =3D grub_ntfs_open; + grub_fs_plug[FS_NTFS].read =3D grub_ntfs_read; + grub_fs_plug[FS_NTFS].close =3D grub_ntfs_close; + grub_fs_plug[FS_NTFS].ls =3D grub_ntfs_ls; +} + +static int img_ls(int argc, char **argv) +{ + int c =3D -1; + char *imgfile =3D NULL; + char *dir =3D NULL; + char verbose =3D 0; + struct ls_ctrl ctrl=3D{}; + + for(;;) + { + c =3D getopt(argc, argv, "d:hlv"); + if (c =3D=3D -1) + break; + + switch(c) + { + case 'v': + verbose =3D 1; + break; + case 'l': + ctrl.detail =3D 1; + break; + case 'h': + help(); + break; + case 'd': + dir =3D optarg; + break; + default: + break; + } + } + + imgfile =3D argv[optind++]; + + if (optind > argc) + help(); + + BlockDriverState *bs =3D 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 =3D 0; + off_t size_bytes =3D 0; + int i =3D 0; + ls_partition_t* parts =3D (ls_partition_t*)malloc(MAX_PARTITIONS * sizeof(ls_partition_t)); + int count =3D 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 =3D 0; i < count; i++) + { + printf("%d\t%s\t%s\t%s\t%u\t%u\n", + parts[i].id, + parts[i].part.bootable=3D=3D0x80 ? "active" : "none-act= ive", + (parts[i].part.system=3D=3D0x0f || parts[i].part.system=3D=3D0x05) ? "extend" : (parts[i].id>=3D5 ? "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 =3D NULL; + char *path =3D NULL; + int which_part =3D 1; + + file =3D (grub_file_t)malloc(sizeof(*file)); + file->bs =3D bs; + file->data =3D NULL; + + if('/' !=3D 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 =3D parts[which_part - 1].part.start_sector_abs; + ctrl.dirname =3D dir; + printf("=A1=BEname\t" + "size(bytes)\t" + "dir?\t" + "date\t" + "time=A1=BF\n"); + + judge_fs(&parts[which_part - 1]); + FS_TYPE fs_type =3D parts[which_part - 1].fs_type; + if (fs_type =3D=3D 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 =3D -1; + char *imgfile =3D NULL; + char *filename =3D NULL; + char verbose =3D 0; + + for(;;) { + c =3D getopt(argc, argv, "f:hv"); + if (c =3D=3D -1) + break; + switch(c) { + case 'v': + verbose =3D 1; + break; + case 'h': + help(); + break; + case 'f': + filename =3D optarg; + break; + default: + break; + } + } + + imgfile =3D argv[optind++]; + if (optind > argc) + help(); + + + if(!filename) + { + printf("error: specific the file to show!\n"); + return -1; + } + + BlockDriverState *bs =3D 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 =3D 4096; + char* buf =3D (char*)malloc(buf_size); + off_t off_bytes =3D 0; + off_t size_bytes =3D 0; + int i =3D 0; + ls_partition_t *parts =3D (ls_partition_t*)malloc(MAX_PARTITIONS * sizeof(ls_partition_t)); + int count =3D enum_partition(bs, parts); + + + { + grub_fs_plugin(); + + grub_file_t file =3D NULL; + char *path =3D NULL; + int which_part =3D 1; + + file =3D (grub_file_t)malloc(sizeof(*file)); + file->bs =3D bs; + file->data =3D NULL; + + char* p =3D strchr(filename, '/'); + if(!p) + { + errx(-1, "please check the file path!\n"); + } + else + { + p =3D strchr(p, '/'); + if(!p) errx(-1, "check the file path!!\n"); + } + + get_partition_path(filename, &which_part, &path); + DBG("part=3D%d, path=3D%s", which_part, path); + if(which_part < 1 || which_part > count) + { + printf("error: check the partition number!\n"); + goto fail; + } + file->part_off_sector =3D parts[which_part - 1].part.start_sector_abs; + judge_fs(&parts[which_part - 1]); + FS_TYPE fs_type =3D parts[which_part - 1].fs_type; + (fs_type =3D=3D FS_UNKNOWN) ? errx(1, "unknown file system!\n") : = 0; + grub_fs_t grub_fs_plg =3D grub_fs_plug[fs_type]; + + if(grub_fs_plg.open(file, path) =3D=3D 0) + { + //printf("file size=3D%zd bytes\n", (file->size)); + + grub_size_t len =3D file->size; + grub_off_t off =3D 0; + char tmpfile[256]=3D{}; + strncpy(tmpfile, getenv("HOME"), sizeof(tmpfile)); + tmpfile[sizeof(tmpfile) - 1] =3D '\0'; + strcat(tmpfile, "/tmp.file"); + + if(!buf) + { + perror("not enough memory!\n"); + goto fail; + } + else + { + grub_size_t readed =3D 0; + grub_size_t left =3D len; + grub_size_t total =3D 0; + FILE* f =3D fopen(tmpfile ,"w"); + if(!f) + { + perror("fopen error"); + goto fail; + } + + + (left > buf_size) ? (left =3D buf_size) : 0; + while((readed =3D grub_fs_plg.read(file, off, left, buf)) + && total <=3D len + && readed > 0) + { + DBG("readed=3D%zd", readed); + total +=3D fwrite(buf, 1, readed, f); + off =3D total; + left =3D len - total; + (left <=3D buf_size) ? 0 : (left =3D buf_size); + DBG("total=3D%zd", total); + }; + fclose(f); + + if(total !=3D 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 =3D "raw"; const char *filename; const char *base_filename =3D 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 =3D 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=3D.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 . + */ + +#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=3D.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 . + */ + +#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 */ --e89a8f502b9249b9ff04d2d60ecc Content-Type: text/html; charset=GB2312 Content-Transfer-Encoding: quoted-printable

=
Hi,
    The final= effect is as follows:
    
[malei@xentest-4-1 Fri Dec 28 ~/honeypot/x= en/xen-4.1.2]$ qemu-img-xen cat -f /1/boot.ini= ~/vm-check.img 
[boot loader]
timeout=3D30
defaul= t=3Dmulti(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating= systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=3D&q= uot;Microsoft Windows XP Professional" /noexecute=3Doptin /fastdetect<= /b>

[malei@xentest-4-1 Fri Dec 28 ~/honeypot/xen/xen-4.1.2]= $ qemu-img-xen ls -l -d /1/ ~/vm-check.img&nbs= p;
=A1=BEname                 size(bytes)= dir?      date                create-= time=A1=BF
AUTOEXEC.BAT 0           &nbs= p;    file 2010-12-22=        17:= 30:37
boot.ini     =           211                file 2010-12-23        01:24:41
bootfont.bin  3227= 30         =        file 2004-11-23      = ;  20:00:00



As you see above, the patch add two sub-commands for qemu-img-xen=A3= =BAcat and ls.

For details in the patch, p= lease check the attachment. 



Does anyone p= refer this feature?!

<= br>

Signed-off-by: Lei Ma (malei@360.cn)

diff --= exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/debug.c 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<= /div>
+++ 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>
+#includ= e<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 =3D 0, dbg_fil= e =3D 0, log_day =3D 0;
+static FILE* fp_log =3D NULL;
= +static char dir[128]=3D{0,}, filename[160];
+static void init_file_path(void);
+static char printbuf[102= 4]=3D{};
+int mkdir_recursive(char* path);
+
= +
+void print_error(char* file, char* function, int line, const c= har *fmt, ...)
+{
+  va_list args;
+  int i;
= +
+  if( !dbg_term && !dbg_file )
+  =  return;
+
+  va_start(args, fmt);
+  i=3Dvsprintf( printbuf, fmt, args );
+  printbuf[i] =3D 0;
+  va_end(args);
+=
+  if( dbg_term )
+    {
+ &n= bsp;    printf("[%s]%s(%d):\n%s\n", file, function, lin= e, printbuf);
+    }
+
+  if( dbg_file )
+    {
+ &= nbsp;    time_t t =3D time( NULL );
+     &nb= sp;struct tm* tm1 =3D localtime(&t);
+      if= ( !tm1 ) return;
+      //if( tm1->tm_mday !=3D= log_day )
+      {
+ //init_file_path();
+    =  }
+      char tmp[16];
+   &= nbsp;  strftime( tmp, 15, "%X", tm1 );
+      fprintf( fp_log, "%s [%s]%s(%d): %s\n", tmp= , file, function, line, printbuf);
+      fflush( = fp_log );
+    }
+}
+
+st= atic char* hex_str(unsigned char *buf, int len, char* outstr )
+{
+
+  const char *set =3D "0123456789a= bcdef";
+  char *tmp;
+  unsigned char *= end;
+  if (len > 1024)
+    len =3D = 1024;
+  end =3D buf + len;
+  tmp =3D &outstr[0];
+  while (buf < end)=
+    {
+      *tmp++ =3D set[= (*buf) >> 4 ];
+      *tmp++ =3D set[ (*buf= ) & 0xF ];
+      *tmp++ =3D ' ';
+      buf ++;
+    }
+ &= nbsp;*tmp =3D '\0';
+  return outstr;
+}
+
+void hex_dump( unsigned char * buf, int len )
+{
+  char str[KB(4)];
+  if( dbg_term )
+    puts( hex_str( buf, le= n, str ) );
+  if( dbg_file ){
+    fput= s( hex_str( buf, len, str ), fp_log );
+    fprintf( fp= _log, "\n" );
+    fflush( fp_log );
+  }
+  //fprintf( stderr, hex_str( buf, len ) );<= /div>
+}
+
+void debug_term_on()
+{
=
+  dbg_term =3D 1;
+}
+
+void debug= _term_off()
+{
+  dbg_term =3D 0;
+}
+
+
+int mkdir_recursive( char* path )
+{
+ &= nbsp;char *p;
+
+  if( access( path, 0 ) =3D=3D 0 = )
+    return 0;
+
+  for( p=3Dpath; *p; p++ )
+    = {
+      if( p>path && *p =3D=3D '/= ' )
+ {
+   *p =3D 0;
+ &nbs= p; if( access( path, 0 ) !=3D 0 )
+     {
+#if= def __WIN32__
+       mkdir( path );
+#else
+       if( mkdir( path, S_IRWXU ) !=3D 0 )<= /div>
+ return -1;
+#endif
+ &nbs= p;   }
+   *p =3D '/';
+ }
+    }
+#ifdef __WIN32__
+  return = mkdir( path );
+#else
+  return mkdir( path, S_IRW= XU );
+#endif
+}
+
+void init_file_= path()
+{
+  char tmp[64];
+  time_t t =3D time( NUL= L );
+  struct tm* tm1 =3D localtime(&t);
+ &n= bsp;
+  if( !tm1 )
+    {
+ &n= bsp;    perror("debug.c init_file_path: ERROR GETTING SYSTEM= TIME.");
+    }
+  log_day =3D tm1->tm_mday;
<= div>+  strftime( tmp, 64, "/%Y-%m-%d.txt", tm1 );
= +  
+  if( access( dir, 0 )!=3D0 )
+   &= nbsp;{
+      (mkdir_recursive( dir )<0) ? perr= or("mkdir_recursive fail!!\n") : 0;
+    }
+  strcpy( filename, dir );
= +  strcat( filename, tmp );
+  if( fp_log )
+=    fclose( fp_log );
+  fp_log =3D fopen( filenam= e, "w" );
+  if(fp_log)
+    {
+      fprintf(fp_log,"= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DLOG  = ;START=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D\n");
+      fclose(fp_log);  fp_log= =3DNULL;
+      fp_log =3D fopen( filename, "= a+" );
+      NULL=3D=3Dfp_log ? printf("init_file_path()= :fopen(a+) fail\n") : 0;
+    }
+}
=
+
+void debug_file_on(char *path)
+{
+ &= nbsp;if( dbg_file )
+    return;
+  debug_set_dir(path);
+ &= nbsp;init_file_path();
+  dbg_file =3D 1;
+}
=
+
+void debug_file_off()
+{
+  if( = !dbg_file )
+    return;
+  dbg_file =3D 0;
+  if( fp_log )
+ &nb= sp;  fclose( fp_log );
+}
+
+void debug_= set_dir(char* str)
+{
+  strcpy( dir, str );
=
+}
+
diff --exclude=3D.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<= /div>
@@ -0,0 +1,34 @@
+#ifndef _DEBUG_H
+#define _= DEBUG_H
+
+#include <stdio.h>
+#include <errno.h&= gt;
+#include <assert.h>
+
+//#define R= ELEASE
+
+#ifndef RELEASE
+#define DBG(args .= ..) \
+  print_error( (char*)__FILE__, (char*)__func__, __LINE__, ##arg= s )
+#else
+#define DBG(args ...)   \
+ &nb= sp;do =   \
+    {               &nbs= p;                     &n= bsp;         \
+fprintf(logfile,"%s::[%s= ]::(%d):\n",                \<= /div>
+ (char*)__FILE__, (char*)__func__, __LINE__);      \
+fprintf(logfile, ##args); fprintf(logfile, "\n");   \
+} &nbs= p;                     &n= bsp;                     =        \
+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=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qem= u-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
<= div>+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 &n= bsp;Free Software Foundation, Inc.
+ *
+ *  GRUB i= s free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "misc.h"
+#include "= fat.h"
+#include "debug.h"
+
+=
+int g_err =3D GRUB_ERR_NONE;
+int64_t s_bpb_bytes_per= _sector;
+int64_t s_part_off_sector;
+
+static int bdrv_pre= ad_from_sector_of_volume(BlockDriverState *bs, int64_t offset,
+ =               void *buf1, int count1)
+{
+  int64_t off =3D s_bpb_bytes_per_sector * s_par= t_off_sector + offset;
+  return bdrv_pread(bs, off, buf1, count1);
+}
+
+
+static int
+fat_log2 (unsigned x)
+{
+  int i;
+
+  if (x =3D= =3D 0)
+    return -1;
+
+  for (i =3D 0; (x &a= mp; 1) =3D=3D 0; i++)
+    x >>=3D 1;
+=
+  if (x !=3D 1)
+    return -1;
<= div>+
+  return i;
+}
+
+
+char *
+grub_fat_find_dir (BlockDri= verState *bs, struct grub_fat_data *data,
+    const char *path,<= /div>
+  &n= bsp; 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 =3D 0;
+  grub_uint32_t first_fat, magi= c;
+  int64_t off_bytes =3D (int64_t)part_off_sector << GRUB_DISK_S= ECTOR_BITS;
+
+  if (! bs)
+   &nbs= p;goto fail;
+
+  data =3D (struct grub_fat_data *= ) malloc (sizeof (*data));
+  if (! data)
+    goto fail;
+
+  /* Read the BPB.  */
+  if (bdrv_pread(= bs, off_bytes, &bpb, sizeof(bpb)) !=3D sizeof(bpb))
+   =  {
+      DBG("bdrv_pread fail...."= );
+      goto fail;
+    }
= +    
+  if (grub_strncmp((const char *) bpb.versi= on_specific.fat12_or_fat16.fstype,
+    "FAT12", 5)
+      && grub_strncmp((const char *) bpb.versi= on_specific.fat12_or_fat16.fstype,
+       "FAT16&= quot;, 5)
+      && grub_strncmp((const ch= ar *) bpb.version_specific.fat32.fstype,
+ &nb= sp;     "FAT32", 5)
+     &nbs= p;)
+    {
+      
+=      DBG("fail here-->grub_strncmp......");
+      goto fail;
+    }
= +
+  /* Get the sizes of logical sectors and clusters.  = ;*/
+  s_bpb_bytes_per_sector =3D (bpb.bytes_per_sector);
+  s_part_off_sector =3D part_off_sector;
+  data->logical_sector_bits =3D
+    fat_= log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
+  DBG("= ;bpb.bytes_per_sector=3D0x%x, le_to_cpu16=3D0x%x",
+  bpb.bytes_pe= r_sector, grub_le_to_cpu16 (bpb.bytes_per_sector));
+  
+
+  if (data->logical_sector_bit= s < GRUB_DISK_SECTOR_BITS)
+  {
+    = DBG("fail here-->logical_sector_bits"); 
+ &nbs= p;  goto fail;
+  }
+  data->logical_sector_bits -=3D GRUB_DISK_SECTOR_BITS;
=
+
+  DBG("bpb.sectors_per_cluster=3D%u", bpb.= sectors_per_cluster);
+  data->cluster_bits =3D fat_log2 = (bpb.sectors_per_cluster);
+  if (data->cluster_bits < 0)
+    {
+      DBG("fail here-->cluster_bits......l= ine[%u]", __LINE__); 
+      goto fail;<= /div>
+    }
+  data->cluster_bits +=3D dat= a->logical_sector_bits;
+
+  /* Get information about FATs.  */
= +  DBG("bpb.num_reserved_sectors=3D%u,"
+   &= nbsp;  "le_to_cpu16=3D%u",
+      b= pb.num_reserved_sectors,
+      grub_le_to_cpu16 (= bpb.num_reserved_sectors));
+  data->fat_sector =3D (grub_le_to_cpu16 (bpb.num_reserved_se= ctors)
+=       << data->logical_sector_bits);<= /div>
+  DBG("data->fat_sector=3D%u, part_off_sector=3D%u&= quot;,
+      data->fat_sector, part_off_sector);
+  if (data->fat_sector =3D=3D 0)
+    {
=
+      DBG("fail here-->fat_sector......")= ; 
+      goto fail;
+    = ;}
+  data->sectors_per_fat =3D ((bpb.sectors_per_fat_16
+  = ;   ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
+    &= nbsp;: grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
+ &n= bsp;  << data->logical_sector_bits);
+  DBG(&q= uot;bpb.version_specific.fat32.sectors_per_fat_32=3D%u\n"
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre">  "= ;grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)=3D%u"= ;,
+ &nbs= p;bpb.version_specific.fat32.sectors_per_fat_32,
+  grub_le_to_cpu32 (b= pb.version_specific.fat32.sectors_per_fat_32));
+  if (data->sectors_per_fat =3D=3D 0)
+   &nbs= p;goto fail;
+
+  /* Get the number of sectors in = this volume.  */
+  data->num_sectors =3D ((bpb.num_= total_sectors_16
+ ? grub_le_to_cpu16 (bpb.num_total_sectors_16)
+ : = grub_le_to_cpu32 (bpb.num_total_sectors_32))
+        &= lt;< data->logical_sector_bits);
+  if (data->num_sectors =3D=3D 0)
+    {<= /div>
+      DBG("fail here-->num_sectors......&= quot;); 
+      goto fail;
+  =  }
+  /* Get information about the root directory. &nb= sp;*/
+  if (bpb.num_fats =3D=3D 0)
+    {
+      DBG("fail here-->num_fats......");&nbs= p;
+      goto fail;
+    }
+  data->root_sector =3D data->fat_sector + bpb.num_fats= * data->sectors_per_fat;
+  data->num_root_sectors
+    =3D ((((gru= b_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))
+ &n= bsp;     << (data->logical_sector_bits));
+ &n= bsp;//in fat32 : root is not included in file cluster??
+  data->cluster_sector =3D data->root_sector + data->nu= m_root_sectors;
+  data->num_clusters =3D (((data->num= _sectors - data->cluster_sector)
+  >> (data->cluster_bit= s + data->logical_sector_bits))
+ + = 2);
+
+  if (data->num_clusters <=3D 2)
+    {
+      DBG("fail here-= ->num_clusters......"); 
+      goto fail;
+    }
= +  if (! bpb.sectors_per_fat_16)
+    {
= +      /* FAT32.  */
+      gr= ub_uint16_t flags =3D grub_le_to_cpu16 (bpb.version_specific.fat32.extended= _flags);
+
+      data->root_cluster =3D grub_le_to= _cpu32 (bpb.version_specific.fat32.root_cluster);
+    =  data->fat_size =3D 32;
+      data->c= luster_eof_mark =3D 0x0ffffff8;
+
+      if (flags & 0x80)
+ {
+   /* Get an= active FAT.  */
+   unsigned active_fat =3D flags & 0xf;=
+
+=   if (active_fat > bpb.num_fats)
+     g= oto fail;
+
+  &nb= sp;data->fat_sector +=3D active_fat * data->sectors_per_fat;
+ }
=
+
+      if (bpb.num_root_entries !=3D 0 || bpb.version_specif= ic.fat32.fs_version !=3D 0)
+ goto fail;
+    }
+  else
+    {
+      /* FAT12 or FAT16.  */
+   &= nbsp;  data->root_cluster =3D ~0U;
+
+   &= nbsp;  if (data->num_clusters <=3D 4085 + 2)
+ {
+ &nbs= p; /* FAT12.  */
+   data->fat_size =3D 12;
+  &= nbsp;data->cluster_eof_mark =3D 0x0ff8;
+ }
+      else
+ {
+   /* FAT16.  */
+ &nbs= p; data->fat_size =3D 16;
+   data->cluster_eof_mark = =3D 0xfff8;
+ }
+    }
+
+  /* More sanity checks. =  */
+  if (data->num_sectors <=3D data->fat_se= ctor)
+    goto fail;
+
+  
+  DBG("data->fat_sector=3D%u, data->sectors_per_fa= t=3D%u",
+ &nbs= p;data->fat_sector, data->sectors_per_fat);
+  if (bdr= v_pread_from_sector_of_volume(bs,
+  data->fat_sector << GRUB= _DISK_SECTOR_BITS,
+ &nb= sp;&first_fat,
+  sizeof (first_fat)) !=3D sizeof(first_fat))
+    {
+      DBG("fail here-->bdrv_pread......")= ; 
+      goto fail;
+    = ;}
+
+  first_fat =3D grub_le_to_cpu32 (first_fat)= ;
+
+  if (data->fat_size =3D=3D 32)
+    {
+      first_fat &=3D 0x= 0fffffff;
+      magic =3D 0x0fffff00;
+=    }
+  else if (data->fat_size =3D=3D 16)
+    {
+      first_fat &=3D = 0x0000ffff;
+      magic =3D 0xff00;
+    }
+  else
+    {
+     &n= bsp;first_fat &=3D 0x00000fff;
+      magic = =3D 0x0f00;
+    }
+
+  /* Ser= ial number.  */
+  if (bpb.sectors_per_fat_16)
+    data->= uuid =3D grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);=
+  else
+    data->uuid =3D 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) !=3D (magic | bpb.media | 0x8))
+=    {
+      DBG("fail here-->fi= rst_fat=3D0x%x, magic=3D0x%x",
+      first_fat, magic);=  
+      goto fail;
+    }
= +  /* Start from the root directory.  */
+  data-&= gt;file_cluster =3D data->root_cluster;
+  data->cur_c= luster_num =3D ~0U;
+  data->attr =3D GRUB_FAT_ATTR_DIREC= TORY;
+  DBG("data->file_cluster=3D%u \ndata->cur_cluster_nu= m=3D%u \ndata->attr=3D0x%x\n"
+  "data->logical_sector_= bits=3D%u\n"
+ &nbs= p;"data->cluster_bits=3D%u",
+  data->file_cluster, dat= a->cur_cluster_num, data->attr,
+ &nbs= p;data->logical_sector_bits, data->cluster_bits);
+  r= eturn data;
+
+ fail:
+
+  fre= e (data);
+  printf("not a FAT filesystem!\n");
+  = ;return 0;
+}
+
+
+
+//= =B4=D3=CE=C4=BC=FE=B5=C4=D6=B8=B6=A8=C6=AB=D2=C6offset=D7=D6=BD=DA=B4=A6=B6= =C1=C8=A1len=D7=D6=BD=DA=B5=C4=CA=FD=BE=DD=B5=BDbuf
+//=CE=C4=BC= =FE=D3=C9data->file_cluster=D6=B8=B6=A8
+//data->file_clust= er=D6=B8=B6=A8=C1=CB=CE=C4=BC=FE=B5=C4=C6=F0=CA=BC=B4=D8=BA=C5
+//=C4=AC=C8=CFdata->file_cluster=3D2=A3=AC=B4=FA=B1=ED=B8=F9=C4=BF= =C2=BC
+static grub_ssize_t
+grub_fat_read_data (BlockD= riverState *bs, struct grub_fat_data *data,
+     void (*rea= d_hook) (grub_disk_addr_t sector,
+ &= nbsp;      unsigned offset, unsigned length,
+   = ;     void *closure),
+     void *closure,
+ &nb= sp;   grub_off_t offset, grub_size_t len, char *buf)
+{=
+  grub_size_t size;
+  grub_uint32_t logica= l_cluster;
+  unsigned logical_cluster_bits;
+  grub_ssize_t ret =3D 0;
+  unsigned long sector= ;
+  uint64_t off_bytes =3D 0; 
+  /* Th= is is a special case. FAT12 and FAT16 doesn't have the root directory
+     in clusters.  */
+  if (data->file_cluster =3D=3D ~0U)
+    = ;{
+      size =3D (data->num_root_sectors <= < GRUB_DISK_SECTOR_BITS) - offset;
+      if (s= ize > len)
+ size =3D len;
+
+      off_bytes =3D ((uint64_t)data->ro= ot_sector << GRUB_DISK_SECTOR_BITS) + offset;
+   &nbs= p;  if(bdrv_pread_from_sector_of_volume(bs, off_bytes, buf, size ) != =3D size) 
+ return -1;
+
+      return size;
+   &nbs= p;}
+
+  /* Calculate the logical cluster number a= nd offset.  */
+  logical_cluster_bits =3D (data->cl= uster_bits
+   + data->logical_sector_bits
+ &n= bsp; + GRUB_DISK_SECTOR_BITS);
+  logical_cluster =3D o= ffset >> logical_cluster_bits;    //which cluster to read&n= bsp;
+  offset &=3D (1 << logical_cluster_bits) - = 1;           //mod
+
+  if (logical_cluster < data->cur_cluster_num)=   //
+    {
+      data-= >cur_cluster_num =3D 0;
+      data->cur_clu= ster =3D data->file_cluster; // =B5=DA2=B8=F6fat=B1=ED=CF=EE=BF=AA=CA=BC= =BC=C7=C2=BC=C4=BF=C2=BC=BA=CD=CE=C4=BC=FE
+    }
+
+  while (len)
+=    {
+      while (logical_cluster >= data->cur_cluster_num)
+ {
+  &nb= sp;/* Find next cluster.  */
+   grub_uint32_t next_cluster;<= /div>
+   unsigned long fat_offset;
+
+=   switch (data->fat_size)
+     {
<= div>+  = ;   case 32:
+ &nbs= p;     fat_offset =3D data->cur_cluster << 2;
=
+ &nbs= p;     break;
+     case 16:
+ &nbs= p;     fat_offset =3D data->cur_cluster << 1;
=
+ &nbs= p;     break;
+     default:
+ &nbs= p;     /* case 12: */
+       fat_offset = =3D data->cur_cluster + (data->cur_cluster >> 1);
+ &nbs= p;     break;
+     }
+
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre">   = ;/* Read the FAT.  */
+ &nbs= p; int len =3D (data->fat_size + 7) >> 3;
+   uint64= _t off_bytes =3D  ((uint64_t)data->fat_sector << GRUB_DISK_SE= CTOR_BITS) + fat_offset; 
+ &nbs= p; if (bdrv_pread_from_sector_of_volume (bs, off_bytes, 
+  = ; (char *) &next_cluster, 
+ &n= bsp; len) !=3D len)   //=B4=D3fat=B1=ED=B6=C1=C8=A1=B4=D8=BA=C5
+ =     return -1;
+
+   next_cluster =3D gru= b_le_to_cpu32 (next_cluster);
+ &nbs= p; switch (data->fat_size)
+     {
+    &nbs= p;case 16:
+ &nbs= p;     next_cluster &=3D 0xFFFF;
+      &= nbsp;break;
+     case 12:
+ &nbs= p;     if (data->cur_cluster & 1)
+ next_cluster >= >=3D 4;
+
+ &nbs= p;     next_cluster &=3D 0x0FFF;
+      &= nbsp;break;
+     }
+
+=   DBG ("fat_size=3D%d, next_cluster=3D%u",
+ d= ata->fat_size, next_cluster);
+
+=   /* Check the end.  */
+   if (next_cluste= r >=3D data->cluster_eof_mark)
+ &nbs= p;   return ret;
+
+   if (next_cluster < 2= || next_cluster >=3D data->num_clusters)
+ &nbs= p;   {
+       DBG("invalid cluster %u...= .............",
+   next_cluster);
+ &nbs= p;     return -1;
+     }
+
+  &= nbsp;data->cur_cluster =3D next_cluster;
+ &nbs= p; data->cur_cluster_num++;
+ }
+
+    = ;  /* Read the data here.  */
+      //=C2=DF=BC=AD=B4=D8=CB=F9=B6=D4=D3=A6=B5=C4=BE= =F8=B6=D4=C9=C8=C7=F8
+      sector =3D (data->= cluster_sector
+ + ((data->cur_cluster - 2)
+    << (dat= a->cluster_bits + data->logical_sector_bits))); 
+      //=BE=F8=B6=D4=C9=C8=C7=F8=D6=D0=C8=A5=B5=F4=C6= =AB=D2=C6=BA=F3=B5=C4=D7=D6=BD=DA=CA=FD
+      siz= e =3D (1 << logical_cluster_bits) - offset;
+    =  if (size > len)
+ size =3D len;
+
+      //disk->read_hook =3D read_hook;<= /div>
+      //disk->closure =3D closure;
+=      int64_t off_bytes =3D ((uint64_t)sector << GRUB_= DISK_SECTOR_BITS) + offset;
+      //disk->read= _hook =3D 0;
+      if (bdrv_pread_from_sector_of_volume (bs, off_by= tes, buf, size) !=3D size)
+ return -1;
+
+   &nbs= p;  len -=3D size;
+      buf +=3D size;
+      ret +=3D size;
+      l= ogical_cluster++;
+      offset =3D 0;  //=D2= =D4=BA=F3=B6=C1=B5=C4=B6=BC=CA=C7=CD=EA=D5=FB=C9=C8=C7=F8
+  = ;  }
+
+  return ret;
+}
= +
+//=B1=E9=C0=FA=D3=C9data->file_cluster=D6=B8=B6=A8=B5=C4=C4= =BF=C2=BC
+static int
+grub_fat_iterate_dir (BlockDriverState *bs, str= uct grub_fat_data *data,
+       int (*hook) (const cha= r *filename,
+  =   struct grub_fat_dir_entry *dir,
+    void *closure),
+ &= nbsp;     void *closure)
+{
+  struct grub_fat_dir_entry dir;
+  = char *filename, *filep =3D 0;
+  grub_uint16_t *unibuf;
+  int slot =3D -1, slots =3D -1;
+  int checksum= =3D -1;
+  grub_ssize_t offset =3D -sizeof(dir);
+
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY= ))
+    return printf("not a directory......\n&quo= t;);
+
+  /* Allocate space enough to hold a long = name.  */
+  filename =3D (char*)malloc (0x40 * 13 * 4 + 1);
+  u= nibuf =3D (grub_uint16_t *) malloc (0x40 * 13 * 2);
+  char = *gbname =3D (char*)malloc(0x40 * 13 * 2);
+  if (! filename = || ! unibuf || !gbname)
+    {
+      free(gbname);
+      free (filename);
+      f= ree (unibuf);
+      perror("iterate: malloc = failed!...\n");
+      return -1;
+=    }
+
+  
+  int count =3D 0;
+ &n= bsp;while (1)
+    {
+      un= signed i;
+
+      /* Adjust the offset.=  */
+      offset +=3D sizeof (dir);
+      DBG("\n[%d]offset=3D%u,"
+    &nbs= p; "data->cur_cluster_num=3D%u,data->cur_cluster=3D%u",&nbs= p;
+      count+1, offset, 
+ &nbs= p;    data->cur_cluster_num, data->cur_cluster);
= +      /* Read a directory entry.  */
+  = ;    //0x0=B1=ED=CA=BE=BF=D5=C4=BF=C2=BC
+    = ;  if ((grub_fat_read_data (bs, data, 0, 0,
+ &n= bsp;      offset, sizeof (dir), (char *) &dir)
+  &n= bsp; !=3D sizeof (dir) || dir.name[0] =3D= =3D 0))
+ {
+ &= nbsp; DBG("break...dir.name[0]=3D= =3D%d", dir.name[0]);
+ &nbs= p; break;
+ }
+      /* Handle long name entri= es.  */
+      if (dir.attr =3D=3D GRUB_FAT_A= TTR_LONG_NAME)
+ {
+ &= nbsp; DBG("long name...");
+   struct grub_fat_long= _name_entry *long_name
+ &nbs= p;   =3D (struct grub_fat_long_name_entry *) &dir;
= +  &nb= sp;grub_uint8_t id =3D long_name->id;
+
+=   if (id & 0x40)  //the last item
+    =  {
+       id &=3D 0x3f;   //index or ordi= nal number  1~31
+ &nbs= p;     slots =3D slot =3D id;
+       che= cksum =3D long_name->checksum;
+       DBG("the = last ordinal num=3D%d!!!", id);
+ &nbs= p;   }
+
+   if (id !=3D slot || slot =3D=3D 0= || checksum !=3D long_name->checksum)
+ &nbs= p;   {
+       DBG("not valid ordinal num= ber ,ignore...continue");
+  &nb= sp;    checksum =3D -1;
+       continue;
+ &nb= sp;   }
+
+=   slot--;
+   memcpy (unibuf + slot * 13, long_n= ame->name1, 5 * 2);
+ &nbs= p; memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
<= div>+  = ; memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
+ &nbs= p; DBG("memcpy...continue");
+   continue;
+ }
+
+      
+      /* = Check if this entry is valid.  */
+      //ox= e5=B1=ED=CA=BE=D2=D1=BE=AD=B1=BB=C9=BE=B3=FD
+     &nbs= p;if (dir.name[0] =3D=3D 0xe5 || (dir.attr = & ~GRUB_FAT_ATTR_VALID))
+ {
+ &= nbsp; DBG("dir.name[0]=3D0x%x, di= r.attr=3D0x%x not valid...continue", 
+ &nb= sp;dir.name[0], dir.attr);
+   con= tinue;
+= }
+
+      DBG("checksum=3D%d, slot=3D%d&q= uot;, checksum, slot);
+      /* This is a workaro= und for Japanese.  */
+      if (dir.name[0] =3D=3D 0x05)
+ d= ir.name[0] =3D 0xe5;
+
+      if (checksum !=3D -1 && slot= =3D=3D 0)
+ {
+   DBG("checksuming");
+ &nbs= p; grub_uint8_t sum;
+
+   for (sum =3D 0, i =3D 0;= i < sizeof (dir.name); i++)
+ &nbs= p;   sum =3D ((sum >> 1) | (sum << 7)) + dir.name[i];
+
+   if (sum =3D=3D ch= ecksum)
+ &nbs= p;   {//=B3=A4=C3=FB=B1=ED=CF=EE=BA=F3=C3=E6=BD=F4=BD=D3=B6=CC=C3= =FB=B1=ED=CF=EE=A3=AC=D1=E9=D6=A4=B3=C9=B9=A6=D4=F2=D6=A4=C3=F7=D5=E6=D5=FD= =CA=C7=B3=A4=C3=FB=D7=D6
+       int u;
+
+ &nb= sp;     for (u =3D 0; u < slots * 13; u++)
+ uni= buf[u] =3D grub_le_to_cpu16 (unibuf[u]);
+
+      &= nbsp;*grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
+ &= nbsp;  slots * 13) =3D '\0';
+
+      =  
+=       checksum =3D -1;
+ &nbs= p;     for (i =3D 0; i < sizeof (dir.name); i++)
+ DBG("0x%x  ", dir.name[i]);
+ &nbs= p;     
+       u2g(filename, strlen(file= name), gbname, 0x40 * 13 * 2);
+       DBG("\ndir.name=3D%s, filename=3D%s, dir.attr=3D0x%x,&= quot;
+ &nb= sp;    "sum=3D=3Dchecksum...continue",
+    &= nbsp; dir.name, gbname, dir.attr);
+ &nbs= p;     
+       count++;
+    &n= bsp;  
+ &nbs= p;     if (hook && hook (gbname, &dir, closure))=
+         break;
+  &nb= sp;    
+       continue;
+     = }
+
+=   checksum =3D -1;
+ }
+
+   &nbs= p;  //=BA=F3=C3=E6=B5=C4=B4=A6=C0=ED=D5=EB=B6=D4=B7=C7=D5=E6=CA=B5=B3= =A4=C3=FB=BA=CD=D5=E6=CA=B5=B6=CC=C3=FB
+      /* Convert the 8.3 file name.  */
+      //=C8=A5=B5=F4=B6=CC=C3=FB=B5=C4=BF=D5=B8=F1=A3=AC= =C8=AB=B8=C4=CE=AA=D0=A1=D0=B4
+      filep =3D fi= lename;
+      if (dir.attr & GRUB_FAT_ATTR_VO= LUME_ID)
+ {
+ &nbs= p; DBG("VOLUME");
+   for (i =3D 0; i < sizeof (= dir.name) && dir.name[i]
+ &nb= sp;&& ! grub_isspace (dir.name[i]);= i++)
+ =     *filep++ =3D dir.name= [i];
+ }
+      else
+ {
+   for (i =3D 0; i < 8 &= amp;& dir.name[i] && ! grub_iss= pace (dir.name[i]); i++)
+ &nbs= p;   *filep++ =3D grub_tolower (dir.n= ame[i]);
+
+   *filep =3D '.';
+
+=   for (i =3D 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+ &nbs= p;   *++filep =3D grub_tolower (dir.n= ame[i]);
+
+   if (*filep !=3D '.')
+ &nbs= p;   filep++;
+ }
+      *filep =3D '= \0';
+      
+      //for (i =3D 0; i < sizeof (dir.name); i++)
+      // DBG("0x%x  &quo= t;, dir.name[i]);
+      DBG("\ndir.nam= e=3D%s, filename=3D=A1=BE%s=A1=BF, dir.attr=3D0x%x,"
+   =   "...next while",
+      dir.name, filename, dir.attr);
+      count++;
+      /*if(st= rcmp(filename, ".") && strcmp(filename, ".."))<= /div>
+ {
+   DBG("{=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D>&q= uot;);
+ &nbs= p; struct grub_fat_data *data2 =3D NULL;
+   data2 =3D (struc= t grub_fat_data*)malloc(sizeof(*data));
+ &nbs= p; memcpy(data2, data, sizeof(*data));
+   data2->attr =3D= dir.attr;
+   data2->file_size =3D grub_le_to_cpu32 (dir.file_= size);
+ &nbs= p; data2->file_cluster =3D ((grub_le_to_cpu16 (dir.first_cluster_hi= gh) << 16)
+  | grub_le_to_cpu16 (dir.first_cluster_low));
+ &nbs= p; data2->cur_cluster_num =3D ~0U;
+   (grub_fat_iterate_d= ir(bs, data2, NULL, NULL) < 0) ? DBG("error !!!!!!") : 0;
+ &nbs= p; free(data2);
+   DBG("<=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D}");
+ }
+      */
+      if (hook &= ;& hook (filename, &dir, closure))
+      =  break;
+    }
+
+  free= (gbname);
+  free (filename);
+  free (unibuf= );
+
+  return 0;
+}
+
+
+
+//=B4=AB=B8=F8grub_fat_find_hook=B5=C4=B2=CE=CA=FDclosu= re
+struct grub_fat_find_dir_closure
+{
+ &nb= sp;struct grub_fat_data *data;
+  int (*hook) (const char *filename,
+       = const struct grub_dirhook_info *info,
+        void *cl= osure);
+  void *closure;
+  char *dirname;
+ &n= bsp;int call_hook;
+  int found;
+};
+
+
+static int
+grub_fat_find_dir_hook (const c= har *filename, struct grub_fat_dir_entry *dir,
+ vo= id *closure)
+{
+  struct grub_fat_find_dir_closur= e *c =3D closure;
+  struct grub_dirhook_info info;
+  memset (&info, 0, sizeof (info));
+
+  info.dir =3D !! (dir->attr & GRUB_FAT_ATTR_= DIRECTORY);
+  info.case_insensitive =3D 1;
+ &nbs= p;info.mtimeset =3D (dir->c_date || dir->c_time);
+  i= nfo.mtime =3D (((grub_uint32_t)dir->c_date << 16) | (dir->c_tim= e));
+  info.filesize =3D dir->file_size;
+  
<= div>+  DBG("target file =A1=BE%s=A1=BF=3D=3D=3D=3D=3D=3D", c= ->dirname);
+  if (dir->attr & GRUB_FAT_ATTR_VOLUM= E_ID)
+    {
+      DBG("= volume id , ignore=3D=3D=3D=3D=3D=3D");
+      return 0;
+    }
+=  
+  if (*(c->dirname) =3D=3D '\0' &&am= p; (c->call_hook))
+    { //=B4=F2=BF=AA=B5=C4=CA=C7= =C4=BF=C2=BC  /x/path1/path2/
+      //=B7=B5= =BB=D80=A3=AC=C8=C3iterate=CA=B1=D6=BB=CA=C7=B4=F2=D3=A1=D0=C5=CF=A2=A3=AC= =B6=F8=B2=BB=CD=CB=B3=F6while
+      c->found =3D 1;
+     &nb= sp;if(!(c->data->attr & GRUB_FAT_ATTR_DIRECTORY))
+ {
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre">   = ;printf("it's not a directory!\n");
+ }
+      DBG("list the dir =A1=BE%s=A1=BF=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D",
+   ((struct ls_ctrl*)c->clo= sure)->dirname);
+      return c->hook (filename, &info, c->cl= osure);
+    }
+
+  
+  if (grub_strcasecmp (c->dirname, filename) =3D=3D 0)
= +    { //=B4=F2=BF=AA=B5=C4=CA=C7=CE=C4=BC=FE /x/path1/file
+      DBG("found=3D=3D=3D=3D=3D=3D");
<= div>+      struct grub_fat_data *data =3D c->data;
<= div>+
+      c->found =3D 1;
+  =    data->attr =3D dir->attr;
+     &nb= sp;data->file_size =3D grub_le_to_cpu32 (dir->file_size);
+      data->file_cluster =3D ((grub_le_to_cpu16 (di= r->first_cluster_high) << 16)
+        | grub= _le_to_cpu16 (dir->first_cluster_low));
+      data->cur_cluster_num =3D ~0U;
+
+      if (c->call_hook)
+ c->hook (filename,= &info, c->closure);
+
+      return 1;
+    }
+  else
+    {
+     &nb= sp;DBG("not match=3D=3D=3D=3D=3D=3D");
+    }=
+  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, retur= n NULL.
+   If HOOK is specified, call it with each file nam= e.  */
+//=D4=DA=D3=C9data=D6=B8=B6=A8=B5=C4=C4=BF=C2=BC=CF= =C2=B2=E9=D5=D2=D3=C9path=C2=B7=BE=B6=D6=B8=B6=A8=B5=C4=CE=C4=BC=FE=BC=D0= =BB=F2=CE=C4=BC=FE
+//=D5=D2=B5=BD=D6=AE=BA=F3=BD=BB=D3=C9 grub_f= at_find_dir_hook=BA=AF=CA=FD=B4=A6=C0=ED=A3=AC=C6=E4=D6=D0closure=B2=CE=CA= =FD=CA=C7=B9=D8=BC=FC
+char *
+grub_fat_find_dir (BlockDriverState *bs, struct gru= b_fat_data *data,
+    const char *path,
+    int (*h= ook) (const char *filename,
+ c= onst struct grub_dirhook_info *info,
+ void *closure),
+    voi= d *closure)
+{
+  char *dirname, *dirp;
+  struct gr= ub_fat_find_dir_closure c;
+  DBG("to search [%s]...in = data->attr=3D0x%x", path, data->attr);
+  if (! (= data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    {
+      printf("not a di= rectory...........\n");
+      return 0;
+    }
+
+  /* Extract a directory= name.  */
+  while (*path =3D=3D '/')
+    path++;
+
+  dirp =3D grub_str= chr (path, '/');
+  if (dirp)
+   &nb= sp;{
+      unsigned len =3D dirp - path;
+
+      dirname =3D (char*)malloc (len + 1);
+      if (! dirname)
+ return 0;
+
= +      memcpy (dirname, path, len);
+    = ;  dirname[len] =3D '\0';
+    }
+  else
+    {
+    /* This is actually a file.  */
+   &n= bsp;  dirname =3D grub_strdup (path);
+    }
=
+  DBG("searching \"%s\"=3D=3D=3D=3D=3D=3D", = dirname);
+  c.data =3D data;
+  c.hook =3D hook;
= +  c.closure =3D closure;
+  c.dirname =3Ddirname;
+  c.found =3D 0;
+  c.call_hook =3D (! dirp &= ;& hook);  //=D5=EB=B6=D4=C4=BF=C2=BC=B5=C4hook
+  =
+  int ret =3D grub_fat_iterate_dir (bs, data, grub_fat_find_dir_= hook, &c);
+  if(0 =3D=3D ret && !c.found)
=
+    {
+      g_err =3D GRUB_ERR_NO= T_FOUND; 
+      printf("file not found.= .\n");
+    }
+  else if(ret < 0)
+ &nb= sp;  {
+      g_err =3D GRUB_ERR_UNKNOWN;
+      printf("iterate error!\n");
+    }
+    
+  
+=  free (dirname);
+
+  return (c.found && 0=3D=3Dret) ? dirp : 0;=
+}
+
+
+
+
+
+grub_err_t
+grub_fat_open (grub_file_t file, const char= *name)
+{
+  struct grub_fat_data *data =3D 0;
+ &nb= sp;char *p =3D (char *) name;
+
+  
+ &n= bsp;data =3D grub_fat_mount (file->bs, file->part_off_sector);
<= div>+  if (! data)
+    {
+      printf("[%s]: mo= unt error!\n", name);
+      goto fail;
=
+    }
+
+  int i =3D 0;
= +  do
+    {
+      p =3D= grub_fat_find_dir (file->bs, data, p, 0, 0);
+      DBG("%d cycle past=A1=BEpath=3D%s=A1=BF....= ...", i+1, p);
+      //error judge......
+    }
+  while (p);
+
= +  DBG("exit while=3D=3D=3D=3D=3D=3D");
+  if ((GRUB_ERR_NONE =3D=3D g_err) 
+   &nbs= p;  && (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    {
+      printf ("[%s]: not = a file!\n", name);
+      goto fail;
+    }
+  
+  if(GRUB_ERR_NONE= =3D=3D g_err)
+    {
+      D= BG("found=3D=3D=3D=3D=3D=3D");
+    }
+  else
+    {
+      = printf("not found or error!\n");
+      goto fail;
+    }
= +
+  DBG("11111111111111111111111");
+ &= nbsp;file->data =3D data;
+  file->size =3D data->f= ile_size;
+  return 0;
+
+ fail:
+  free(data); 
+  f= ile->data =3D NULL;
+  DBG("2222222222222222222222&q= uot;);
+  return 1;
+}
+
+
+#define    TIME_BIT    0xFFFF
+#define    TIME_HOUR_BIT    0xF800
+#de= fine    TIME_MINUTE_BIT    0x07E0
+#define &n= bsp;  TIME_SECOND_BIT    0x001F
+#define   &n= bsp;DATE_BIT    0xFFFF0000
+#define    DATE_Y= EAR_BIT    0xFE00
+#define    DATE_MONTH_BIT    0x01E0
+#d= efine    DATE_DAY_BIT    0x001F
+static  = ;int find_then_ls_hook(const char *filename,
+    const struct g= rub_dirhook_info *info, void *closure)
+{
+  struct ls_ctrl* ctrl =3D (struct ls_ctrl*)closure= ;
+  DBG("detail=3D%d", ctrl->detail);
+  printf("%s", filename);
+  if(!ctrl->= detail)
+    {
+      printf("\n");
+    = ;  return 0;
+    }
+  else
+    {
+      printf("\t");=
+    }
+
+
+  print= f("%ubytes\t", (info->filesize));
+  printf("%s\t", (info->dir ? "dir" : &qu= ot;file"));
+  grub_uint16_t time =3D ((info->mtime)= & TIME_BIT);
+  grub_uint16_t date =3D ((info->mtime= ) & DATE_BIT) >> 16;
+  
+  printf("%04d/%02d/%02d\t",
<= div>+  = ;((date & DATE_YEAR_BIT) >> 9) + 1980,
+  (date & DATE_MO= NTH_BIT) >> 5,
+ &nbs= p;(date & DATE_DAY_BIT));
+  printf("%02d:%02d:%02d= \n", 
+  (time & TIME_HOUR_BIT) >> 11,
+ &nbs= p;(time & TIME_MINUTE_BIT) >> 5,
+  time & TIME_SECOND_BI= T) * 2;  
+  
+  return 0;  // =D7=EE=D6=D5=B7=B5=BB=D8= =B8=F8iterate
+}
+
+
+grub_err_t
+grub_fat_ls (grub_file_t file, const char *path,
+    &nb= sp;  int (*hook) (const char *filename,
+ &n= bsp;  const struct grub_dirhook_info *info, void *closure),
= +  &nb= sp;    void *closure)
+{
+  struct grub_fat_data *data =3D 0;
+ &nb= sp;grub_size_t len;
+  char *dirname =3D 0;
+ &nbs= p;char *p;
+  
+  data =3D grub_fat_mount (fi= le->bs, file->part_off_sector);
+  if (! data)
+    goto fail;
+
+  file->data =3D data;
+  /* Make sure that= DIRNAME terminates with '/'.  */
+  len =3D st= rlen(path);
+  dirname =3D (char*)malloc (len + 1 + 1);
+  if (! dirname)
+    goto fail;
+=  memcpy (dirname, path, len);
+  p =3D dirname + len;<= /div>
+  if (path[len - 1] !=3D '/')
+   &n= bsp;*p++ =3D '/';
+  *p =3D '\0';
+  p =3D dirname;
+
+  do
+ &n= bsp;  {
+      p =3D grub_fat_find_dir (file-= >bs, data, p, find_then_ls_hook, closure);
+    }
+  while (p && g_err =3D=3D GRUB_ERR_NONE);
+
+  
+
+ fail:
+
+  free (dirname);
+  free (data);  file->da= ta =3D 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,
+ &n= bsp;  grub_size_t len, char *buf)
+{
+  retur= n grub_fat_read_data(file->bs, file->data, NULL, NULL, offset, len, b= uf);
+}
+
+
+
+
+
+<= /div>
+
diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioem= u-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"
+#i= nclude "block_int.h"
+#include "fs-comm.h"
+#include "grub_err.h"
+
+
+#define GRUB_DISK_SECTOR_BITS      9
+#define GRU= B_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<= span class=3D"Apple-tab-span" style=3D"white-space:pre"> 0x20
<= div>+
+#define GRUB_FAT_MAXFILE 256
+
+#define GRUB_FAT_ATTR_LONG_N= AME (GRUB_F= AT_ATTR_READ_ONLY \
+ &= nbsp;| 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 \
+ &= nbsp;| GRUB_FAT_ATTR_SYSTEM \
+  | GRUB_FAT_ATTR_DIRECTORY \
+ &nb= sp;| GRUB_FAT_ATTR_ARCHIVE \
+ &= nbsp;| GRUB_FAT_ATTR_VOLUME_ID)
+
+struct grub_fat_bpb<= /div>
+{
+  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 n= um_root_entries;
+  grub_uint16_t num_total_sectors_16;
+  grub_uin= t8_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;
+ &n= bsp;    grub_uint8_t reserved;
+      gr= ub_uint8_t boot_sig;
+      grub_uint32_t num_serial;
+   &nb= sp;  grub_uint8_t label[11];
+      grub_uint= 8_t fstype[8];
+    } __attribute__ ((packed)) fat12_or= _fat16;
+    struct
+    {
+      grub_uint32_t sectors_per_fat_32;
+ &n= bsp;    grub_uint16_t extended_flags;
+     &= nbsp;grub_uint16_t fs_version;
+      grub_uint32_= t root_cluster;
+      grub_uint16_t fs_info;
+      grub_uint16_t backup_boot_sector;
+ &n= bsp;    grub_uint8_t reserved[12];
+     &nbs= p;grub_uint8_t num_ph_drive;
+      grub_uint8_t r= eserved1;
+      grub_uint8_t boot_sig;
+      grub_uint32_t num_serial;
+     &= nbsp;grub_uint8_t label[11];
+      grub_uint8_t f= stype[8];
+    } __attribute__ ((packed)) fat32;
<= div>+  } __attribute__ ((packed)) version_specific;
+} __attribute__ ((packed));
+
+struct grub_fat_di= r_entry
+{
+  grub_uint8_t name[11];
+ &= nbsp;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;<= /div>
+  grub_uint16_t a_date;
+  grub_uint16_t fir= st_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 chec= ksum;
+  grub_uint16_t name2[6];
+  grub_uint= 16_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_p= er_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_uin= t8_t attr;
+  grub_ssize_t file_size;
+  grub_uint32_t file_cluste= r;
+  grub_uint32_t cur_cluster_num;
+  grub_= uint32_t cur_cluster;
+
+  grub_uint32_t uuid;
+};
+
+
+
+
+
+
+
+struct grub_fat_data* 
+grub_fat_mount (BlockDrive= rState *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,
+ &n= bsp;  const struct grub_dirhook_info *info,
+    void *clos= ure),
+ =      void *closure);
+
+grub_err_t grub_fat_close(grub_file_t file);
+<= /div>
+grub_ssize_t grub_fat_read(grub_file_t file, grub_off_t offset,<= /div>
+   grub_size_t len, char *buf);
+
+
+#endif
diff --exclude=3D.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:0= 0:00.000000000 +0700
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/fs-comm.h 2012-12-28 16:02:41.003846897 +080= 0
@@ -0,0 +1,60 @@
+#ifndef _FS_COMM_H
+#defi= ne _FS_COMM_H
+
+#include "fs-types.h"
+#include "= ;block_int.h"
+#include "grub_err.h"
+#i= nclude "debug.h"
+
+typedef struct  grub= _file
+{
+  void *data;
+  BlockDriverState *b= s;
+  uint32_t part_off_sector;
+  grub_size_= t size;
+  grub_off_t offset;
+  /* This is c= alled when a sector is read. Used only for a disk device.  */
+  void (*read_hook) (grub_disk_addr_t sector,
+    &nb= sp; unsigned offset, unsigned length, void *closure);
+  voi= d *closure;
+}*grub_file_t;
+
+struct grub_dirhook_info
+{
+  u= nsigned dir:1;
+  unsigned mtimeset:1;
+  uns= igned case_insensitive:1;
+  grub_uint32_t mtime;   &nb= sp;//(date | time)
+  grub_uint32_t filesize;
+  grub_uint64_t filesize_nt= fs;
+  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,
+ &nbs= p;     int (*hook) (const char *filename,
+    co= nst struct grub_dirhook_info *info,
+ &n= bsp;  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=3D.svn -rpN -= U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fshelp.c xen-4.1.2-b/tools/ioemu-qemu-x= en/fshelp.c
--- xen-4.1.2-a/tools/ioemu-qemu-xen/fshelp.c 1970-01-01 07:00:0= 0.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 fu= nctions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Softwa= re Foundation, Inc.
+ *
+ *  GRUB is free software= : you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "err.h"
+#inc= lude "misc.h"
+#include "block_int.h"
+#include "fshelp.h"
+#include "ntfs.h"
+#include "debug.h"
+
+struct grub_fshel= p_find_file_closure
+{
+  grub_fshelp_node_t rootn= ode;
+  int (*iterate_dir) (grub_fshelp_node_t dir,
+  =      int (*hook)
+ &nb= sp;     (const char *filename,
+        = enum grub_fshelp_filetype filetype,
+  &n= bsp;     grub_fshelp_node_t node, void *closure),
+    =    void *closure);
+  void *closure;
+  char *(*read_symlink) (grub_fshelp_node_t node);
+ &= nbsp;int symlinknest;
+  enum grub_fshelp_filetype foundtype= ;
+  grub_fshelp_node_t currroot;
+};
+<= /div>
+static void
+free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_clos= ure *c)
+{
+  if (node !=3D c->rootnode &&a= mp; node !=3D c->currroot)
+    grub_free (node);
+}
+
+struct find_file_closure
+{
+  c= har *name;
+  enum grub_fshelp_filetype *type;
+ &= nbsp;grub_fshelp_node_t *oldnode;
+  grub_fshelp_node_t *cur= rnode;
+};
+
+static int
+iterate (const char *filen= ame,
+ <= /span> enum grub_fshelp_filetype filetype,
+  grub_fshelp_node_t n= ode,
+ &nbs= p;void *closure)
+{
+  struct find_file_closure *c= =3D closure;
+  DBG("list_file hooked by fshelp:iterat= e(), filename=3D%s", filename);
+  if (filetype =3D=3D GRUB_FSHELP_UNKNOWN ||
+   =    (grub_strcmp (c->name, filename) &&
+ &nb= sp;     (! (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) =3D filetype & ~GRUB_FSHELP_CASE_INSENSITIVE= ;
+  *(c->oldnode) =3D *(c->currnode);
+ &nb= sp;*(c->currnode) =3D node;
+  DBG("found!!>>&= gt;>>>");
+  return 1;
+}
+
+static grub_err_= t
+find_file (const char *currpath, grub_fshelp_node_t currroot,<= /div>
+    grub_fshelp_node_t *currfound,
+ &nbs= p;  struct grub_fshelp_find_file_closure *c)
+{
+ =  char fpath[grub_strlen (currpath) + 1];
+  char *name = =3D fpath;
+  char *next;
+  enum grub_fshelp_filetype type =3D GRUB_FSHELP_DIR;
= +  grub_fshelp_node_t currnode =3D currroot;
+  grub_fs= help_node_t oldnode =3D currroot;
+
+  c->currr= oot =3D currroot;
+
+  grub_strncpy (fpath, currpath, grub_strlen (currpath) += 1);
+
+  /* Remove all leading slashes.  */<= /div>
+  while (*name =3D=3D '/')
+    = ;name++;
+
+  if (! *name)
+    {
+     &= nbsp;*currfound =3D currnode;
+      return 0;
+    }
+
+  for (;;)
+ =    {
+      int found;
+  = ;    struct find_file_closure cc;
+
+      /* Extract the actual part from the = pathname.  */
+      next =3D grub_strchr (na= me, '/');
+      if (next)
+ {
+ &nbs= p; /* Remove all leading slashes.  */
+   while (*next = =3D=3D '/')
+     *(next++) =3D '\0';
+ }
+
+      /* At this point it is expected t= hat the current node is a
+  directory, check if this is true.  = */
+      if (type !=3D GRUB_FSHELP_DIR)
+ {
+   f= ree_node (currnode, c);
+  &nb= sp;return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");=
+ }
+
+      DBG("find_file_closure cc.name=3D=A1=BE%s=A1=BF", name);
+  =    cc.name =3D name;
+ =      cc.type =3D &type;
+      = cc.oldnode =3D &oldnode;
+      cc.currnode =3D &currnode;
+  = ;    /* Iterate over the directory.  */
+   &= nbsp;  DBG("******fshelp:find_file hooked by \'grub_ntfs_iter= ate_dir\',"
+   "nested another hook \'fshelp:it= erator\'");
+      found =3D c->iterate_dir (currnode, iterate, = &cc); 
+      if (! found)
+ {
+=  &nbs= p;if (grub_errno)
+ &nbs= p;   return grub_errno;
+
+   break;
+ }
+
+      /* Read in the symlink and follow it= .  */
+      if (type =3D=3D GRUB_FSHELP_SYML= INK)
+ <= /span>{
+   char *symlink;
+
+=   /* Test if the symlink does not loop.  */
+  &= nbsp;if (++(c->symlinknest) =3D=3D 8)
+ &nbs= p;   {
+       free_node (currnode, c);
<= div>+  = ;     free_node (oldnode, c);
+ &nbs= p;     return grub_error (GRUB_ERR_SYMLINK_LOOP,
+=  &= quot;too deep nesting of symlinks");
+ &nbs= p;   }
+
+   symlink =3D c->read_symlink (c= urrnode);
+   free_node (currnode, c);
+
+=   if (!symlink)
+     {
+     = ;  free_node (oldnode, c);
+ &nbs= p;     return grub_errno;
+     }
+<= /div>
+   /* The symlink is an absolute path, go back to the root inode.=  */
+ &nbs= p; if (symlink[0] =3D=3D '/')
+     {
= +  &nb= sp;    free_node (oldnode, c);
+ &nbs= p;     oldnode =3D c->rootnode;
+     }
+
+   /* Lookup the node the symlink points to.  */
+ &nbs= p; find_file (symlink, oldnode, &currnode, c);
+   type = =3D c->foundtype;
+  &nb= sp;grub_free (symlink);
+
+   if (grub_errno)
= +  &nb= sp;  {
+ &nbs= p;     free_node (oldnode, c);
+       re= turn grub_errno;
+     }
+ }
+
+      free_node (oldnode, c);
+
+      /* Found the node!  */
+ =      if (! next || *next =3D=3D '\0')
+ {
+ &= nbsp; *currfound =3D currnode;
+   c->foundtype =3D type;<= /div>
+ &nbs= p; return 0;
+ }
+
+      name =3D n= ext;
+    }
+
+  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file = not found");
+}
+
+/* Lookup the node PA= TH.  The node ROOTNODE describes the root of the
+   di= rectory 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, a= n
+   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=3D3.  */<= /div>
+grub_err_t
+grub_fshelp_find_file (const char *path, g= rub_fshelp_node_t rootnode,
+        grub_fshelp_node_t= *foundnode,
+ &nb= sp;      int (*iterate_dir) (grub_fshelp_node_t dir,
+ &n= bsp;  int (*hook)
+    (const char *filename,
+ =     enum grub_fshelp_filetype filetype,
+    &n= bsp;grub_fshelp_node_t node,
+ =     void *closure),
+    void *closure),
<= div>+ &nbs= p;      void *closure,
+ &nb= sp;      char *(*read_symlink) (grub_fshelp_node_t node),
+ =        enum grub_fshelp_filetype expecttype)
+{
+  grub_err_t err;
+  struct grub_fsh= elp_find_file_closure c;
+
+  c.rootnode =3D rootn= ode;
+  c.iterate_dir =3D iterate_dir;
+  c.c= losure =3D closure;
+  c.read_symlink =3D read_symlink;
+  c.symlinknest = =3D 0;
+  c.foundtype =3D GRUB_FSHELP_DIR;
+
=
+  if (!path || path[0] !=3D '/')
+   &nbs= p;{
+      grub_error (GRUB_ERR_BAD_FILENAME, &quo= t;bad filename");
+      return grub_errno;
+    }
+  
+  
+  DBG("going to fi= nd_file\n");
+  err =3D find_file (path, rootnode, foun= dnode, &c);
+  if (err)
+    return err;
+
+  /* Check if t= he node that was found was of the expected type.  */
+  = ;if (expecttype =3D=3D GRUB_FSHELP_REG && c.foundtype !=3D expectty= pe)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, &qu= ot;not a regular file");
+  else if (expecttype =3D=3D GRUB_FSHELP_DIR && c.foundt= ype !=3D expecttype)
+    return grub_error (GRUB_ERR_B= AD_FILE_TYPE, "not a directory");
+
+  r= eturn 0;
+}
+
+/* Read LEN bytes from the file NODE on disk DISK into th= e buffer BUF,
+   beginning with the block POS.  READ_H= OOK 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 a= nd the
+   blocks have a size of LOG2BLOCKSIZE (in log2). &n= bsp;*/
+grub_ssize_t
+grub_fshelp_read_file (BlockDrive= rState* bs, grub_fshelp_node_t node,
+ &nb= sp;      void (*read_hook) (grub_disk_addr_t sector,
+ &n= bsp; unsigned offset,
+  = ; unsigned length,
+   void *closure),
+    &nb= sp;   void *closure,
+ &nb= sp;      grub_off_t pos, grub_size_t len, char *buf,
+  = ;      grub_disk_addr_t (*get_block) (grub_fshelp_node_t nod= e,
+       grub_disk_addr_t block),
+      =   grub_off_t filesize, int log2blocksize)
+{
+  grub_disk_addr_t i, blockcnt;
+  g= rub_off_t off_bytes;
+  int blocksize =3D 1 << (log2bl= ocksize + GRUB_DISK_SECTOR_BITS);
+
+  /* Adjust L= EN so it we can't read past the end of the file.  */
+  if (pos + len > filesize)
+    len =3D = filesize - pos;
+
+  blockcnt =3D ((len + pos) + b= locksize - 1) >>
+    (log2blocksize + GRUB_DISK_= SECTOR_BITS);
+
+  for (i =3D pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS= ); i < blockcnt; i++)
+    {
+   &nbs= p;  grub_disk_addr_t blknr;
+      int blocko= ff =3D pos & (blocksize - 1);
+      int block= end =3D blocksize;
+
+      int skipfirst =3D 0;
+
+      blknr =3D get_block (node, i);
+ &nb= sp;    if (grub_errno)
+ return -1;
+
+      blknr =3D blknr << log2blocksi= ze;
+      off_bytes =3D blknr << GRUB_DISK_= SECTOR_BITS;
+
+      /* Last block. &nb= sp;*/
+      if (i =3D=3D blockcnt - 1)
+ {
+ &= nbsp; blockend =3D (len + pos) & (blocksize - 1);
+
+ &nb= sp; /* The last portion is exactly blocksize.  */
+ &nbs= p; if (! blockend)
+     blockend =3D blocksize;
+ }
+
+      /* First block.  */
+=      if (i =3D=3D (pos >> (log2blocksize + GRUB_DISK_= SECTOR_BITS)))
+ {
+   skipfirst =3D blockoff;
+ &nbs= p; blockend -=3D skipfirst;
+ }
+
+     &= nbsp;/* If the block number is 0 this block is not stored on disk but
+ &nbs= p;is zero filled instead.  */
+      if (blkn= r)
+ {
+ =   //bs->read_hook =3D read_hook;
+ &nbs= p; //bs->closure =3D closure;
+   
+   bdrv_prea= d_from_lcn_of_volum(bs, off_bytes + skipfirst,
+ &nb= sp;     buf, blockend);
+   //bs->read_hook =3D = 0;
+   if (grub_errno)
+ &nbs= p;   return -1;
+ }
+      else
+ grub_m= emset (buf, 0, blockend);
+
+      buf +=3D blocksize - skipfirst;
+    }
+
+  return len;
= +}
+
+unsigned int
+grub_fshelp_log2blksize (= unsigned int blksize, unsigned int *pow)
+{
+  int mod;
+
+  *pow =3D 0= ;
+  while (blksize > 1)
+    {
=
+      mod =3D blksize - ((blksize >> 1) <<= 1);
+      blksize >>=3D 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 --excl= ude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fshelp.h xen-4.1.2-b/t= ools/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 Boo= tloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Fr= ee Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it= and/or modify
+ *  it under the terms of the GNU General Pu= blic License as published by
+ *  the Free Software Foundati= on, 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. &nb= sp;See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FSHELP_HEADER
+#def= ine GRUB_FSHELP_HEADER 1
+
+#include "fs-types.h"
<= div> +#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
+  {
+   &nbs= p;GRUB_FSHELP_UNKNOWN,
+    GRUB_FSHELP_REG,
= +    GRUB_FSHELP_DIR,
+    GRUB_FSHELP_SYMLIN= K
+  };
+
+/* Lookup the node PATH. &nbs= p;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 director= y entries in the current node.
+   READ_SYMLINK is used to read the symlink if a node is a symli= nk.
+   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 req= uired
+   because GCC has a nasty bug when using regparm=3D3= .  */
+grub_err_t grub_fshelp_find_file (const char *path,
+   grub_fshelp_node_t rootnode,
+ &= nbsp; grub_fshelp_node_t *foundnode,
+   int (*iterate_dir= )
+ <= /span>  (grub_fshelp_node_t dir,
+ &= nbsp;  int (*hook)
+    (const char *filename,
+=  &= nbsp;  enum grub_fshelp_filetype filetype,
+ &= nbsp;   grub_fshelp_node_t node,
+     void *clo= sure),
+=    void *closure),
+ &= nbsp; void *closure,
+   char *(*read_symlink) (grub_fsh= elp_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 tra= nslate file
+   blocks to disk blocks.  The file is FIL= ESIZE bytes big and the
+   blocks have a size of LOG2BLOCKS= IZE (in log2).  */
+grub_ssize_t grub_fshelp_read_file (BlockDriverState* bs, grub_fshelp= _node_t node,
+     void (*read_hook)
+    &nb= sp;(grub_disk_addr_t sector,
+ &= nbsp;    unsigned offset,
+      unsigned length= ,
+ <= /span>     void *closure),
+ &= nbsp;   void *closure,
+     grub_off_t pos, gru= b_size_t len, char *buf,
+  =    grub_disk_addr_t (*get_block)
+     (grub_fsh= elp_node_t node,
+      grub_disk_addr_t block),
+ &= nbsp;   grub_off_t filesize, int log2blocksize);
+
+unsigned int grub_fshelp_log2blksize (unsigned int blksize,
+ &nbs= p;     unsigned int *pow);
+
+#endif /* ! GRUB_FSHELP_HEADER */
diff --exclud= e=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/fs-time.c xen-4.1.2-b/to= ols/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 +080= 0
@@ -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;
+     &= nbsp;  struct {
+#ifdef WORDS_BIGENDIAN
+            uint32_t high, low;
+#else
+            uint32_t low= , high;
+#endif
+        } l;
=
+    } u, res;
+    uint64_t rl, rh;
+
+    u.ll =3D a;
+    rl =3D (uint64_t)u.l.low * (uint64_t)b;
+ &nb= sp;  rh =3D (uint64_t)u.l.high * (uint64_t)b;
+    = ;rh +=3D (rl >> 32);
+    res.l.high =3D rh / c;<= /div>
+    res.l.low =3D (((rh % c) << 32) + (rl & = 0xffffffff)) / c;
+    return res.ll;
+}
+
+stat= ic uint64_t sub64(uint64_t a, uint64_t b)
+{
+  st= ruct
+  {
+#ifdef WORDS_BIGENDIAN
+ &nbs= p;          uint32_t high, low;
+#else
+            uint32_t l= ow, high;
+#endif
+  }a1,b1,c;
+  <= /div>
+  a1.high =3D a>>32;
+  a1.low =3D a&a= mp;0xffffffff;
+  b1.high =3D b>>32;
+  b1.low =3D b&0xffffffff;
+  
+ &n= bsp;if(a1.high < b1.high)
+    {
+   =    c=3Db1;
+      b1=3Da1;
+ &= nbsp;    a1=3Dc;
+    }
+  
+  a1.high -=3D b1.high;
+  a1.low -=3D b1.low;
+  if(a1.low & 0x800000= 00)
+    {
+      a1.low =3D (= ~(a1.low & 0x7fffffff))+1;
+      a1.high -=3D= 1;
+    }
+  
+  uint64_= t ret =3D (uint64_t)a1.high<<32 | a1.low;
+  return ret;
+}
+
+struct tm* ntf= s_utc2local(grub_uint64_t time, struct tm* ptm)
+{
+ &n= bsp;//time_t time2 =3D sub64(time, NTFS_TIME_OFFSET);
+  tim= e_t time2 =3D time - NTFS_TIME_OFFSET;
+  /*DBG("sizeof(int)=3D%d", sizeof(int));
+ =  DBG("sizeof(short)=3D%d", sizeof(short));
+  = ;DBG("sizeof(long)=3D%d", sizeof(long));
+  DBG(&q= uot;sizeof(long long)=3D%d", sizeof(unsigned long long));
+  DBG("sizeof(time_t)=3D%d, time=3D%zu, time2=3D%zu", = sizeof(time_t), time, time2);*/
+  //time2 =3D div64(time2,1= ,10000000);
+  time2 =3D time2 / 10000000;
+  = ;DBG("sizeof(time_t)=3D%d, time=3D%zu, time2=3D%zu", sizeof(time_= t), time, time2);
+  ////time2 =3D 0;//time(NULL);
+  return localti= me_r(&time2, ptm);
+}
diff --exclude=3D.svn -rpN -U= 8 xen-4.1.2-a/tools/ioemu-qemu-xen/fs-time.h xen-4.1.2-b/tools/ioemu-qemu-x= en/fs-time.h
--- xen-4.1.2-a/tools/ioemu-qemu-xen/fs-time.h 1970-01-01 07:00:00.000000000 +070= 0
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/fs-time.h 2012-12-28 16:02:41.0056857= 98 +0800
@@ -0,0 +1,12 @@
+#ifndef FS_TIME_H
+#define FS_TI= ME_H
+
+#include <time.h>
+#include &qu= ot;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=3D.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 +07= 00
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/fs-types.h 2012-12-28 16:02:41.00693= 2417 +0800
@@ -0,0 +1,234 @@
+/*
+ *  GRUB  -- &nbs= p;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 publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_HEADER
+#defi= ne GRUB_TYPES_HEADER 1
+
+#include "grub-config.h"
+#include "x86_64/types.h"
+
+#ifdef GRU= B_UTIL
+# define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P
+# define GR= UB_CPU_SIZEOF_LONG= SIZEOF_LONG
+# ifdef WORDS_BIGENDIAN
+#  define GRUB_CPU_WORDS_BIGE= NDIAN 1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIAN
= +# endif
+#else /* ! GRUB_UTIL */
+# define GRUB_CPU_SIZEOF_VOID_P GRUB_TARGET_S= IZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG GRUB_TARGET_SIZEOF_LONG
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define GRUB_CP= U_WORDS_BIGENDIAN = 1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIA= N
+# endif
+#endif /* ! GRUB_UTIL */
+
+#if GRU= B_CPU_SIZEOF_VOID_P !=3D 4 && GRUB_CPU_SIZEOF_VOID_P !=3D 8
+# error "This architecture is not supported because sizeof(void *)= !=3D 4 and sizeof(void *) !=3D 8"
+#endif
+
+#ifndef GRUB_TARGET_WORDSIZE
= +# if GRUB_TARGET_SIZEOF_VOID_P =3D=3D 4
+#  define GRUB_TAR= GET_WORDSIZE 32
+# elif GRUB_TARGET_SIZEOF_VOID_P =3D=3D 8
<= div>+#  define GRUB_TARGET_WORDSIZE 64
+# endif
+#endif
+
+/* Define various wi= de integers.  */
+typedef signed char grub_int8_t;
+typedef = short gru= b_int16_t;
+typedef int = grub_int32_t;
+#if GRUB_CPU_SIZEOF_LONG =3D=3D 8
+typedef long = grub_int64_t;
+#else
+typedef long long grub_int64_t;
+#endif
+<= /div>
+typedef unsigned char grub_uint8_t;
+typedef unsigned short grub_uint16_t;
+typedef unsigned grub_uint32_t;
+#if GRUB_CPU_SIZEOF_LONG =3D=3D 8
+typedef unsigned long grub_uint64_t;
+#else
+typedef unsign= ed long long grub_uint64_t;
+#endif
+
+/* Misc types.  */
+#if = GRUB_TARGET_SIZEOF_VOID_P =3D=3D 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_ui= nt32_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 =3D=3D 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 =3D=3D 8
+# define GRUB_ULONG_MAX 18446744073709551615UL
+# define = GRUB_LONG_MAX 9223372036854775807L
+# define GRUB_LONG_MIN (-9223= 372036854775807L - 1)
+#else
+# define GRUB_ULONG_MAX 4294967295UL
+# de= fine GRUB_LONG_MAX 2147483647L
+# define GRUB_LONG_MIN (-21474836= 47L - 1)
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_= P =3D=3D 4
+#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
+#define= PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
+#define PT= R_TO_UINT32(x) ((grub_uint32_t)(x))
+#else
+#define UIN= T_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_byt= es16(x) \
+({ \
+   grub_uint16_t _x =3D (x); \
+ &= nbsp; (grub_uint16_t) ((_x << 8) | (_x >> 8)); \
+})
+
+#if defined(__GNUC__) && (__GNUC__ = > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >=3D 3) &&= defined(GRUB_TARGET_I386)
+static inline grub_uint32_t grub_swap= _bytes32(grub_uint32_t x)
+{
+ return __builtin_bswap32(x);
+}
+
+s= tatic inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
+{<= /div>
+ retu= rn __builtin_bswap64(x);
+}
+#else /* not gcc 4.3 or newer */<= /div>
+#define grub_swap_bytes32(x) \
+({ \
+   grub_uint32_t = _x =3D (x); \
+   (grub_uint32_t) ((_x << 24) \
<= div>+                    = | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \
+                    = ;| ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \
+   =                  | (_x >>= ; 24)); \
+})
+
+#define grub_swap_bytes64(x)= \
+({ \
+   grub_uint64_t _x =3D (x); \
+  = ; (grub_uint64_t) ((_x << 56) \
+       &nbs= p;            | ((_x & (grub_uint64_t) 0x= FF00ULL) << 40) \
+           &nbs= p;        | ((_x & (grub_uint64_t) 0xFF0000ULL) <= ;< 24) \
+                    = ;| ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
+ &nbs= p;                  | ((_x &am= p; (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)<= /div>
+# define grub_cpu_to_le64(x) grub_swap_bytes64(x)
+# define grub_le_to= _cpu16(x) g= rub_swap_bytes16(x)
+# define grub_le_to_cpu32(x) grub_swap_bytes32(x)
+# define grub_le_to= _cpu64(x) g= rub_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_t= o_cpu16(x) = ((grub_uint16_t) (x))
+# define grub_be_to_cpu32(x) ((grub_uint32_t) (x))
+# define grub_be_t= o_cpu64(x) = ((grub_uint64_t) (x))
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_ta= rget_to_host16(x) = ((grub_uint16_t) (x))
+#  define grub_target_to_host3= 2(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_t= o_cpu16(x) = ((grub_uint16_t) (x))
+# define grub_le_to_cpu32(x) ((grub_uint32_t) (x))
+# define grub_le_t= o_cpu64(x) = ((grub_uint64_t) (x))
+# define grub_cpu_to_be16(x) grub_swap_bytes16(x)
+# define grub_cpu_t= o_be32(x) g= rub_swap_bytes32(x)
+# define grub_cpu_to_be64(x) grub_swap_bytes64(x)
+# define grub_be_to= _cpu16(x) g= rub_swap_bytes16(x)
+# define grub_be_to_cpu32(x) grub_swap_bytes32(x)
+# define grub_be_to= _cpu64(x) g= rub_swap_bytes64(x)
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_ta= rget_to_host16(x) = grub_swap_bytes16(x)
+#  define grub_target_to_host32= (x) grub_sw= ap_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_t= o_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 =3D=3D 8
+#  define grub_h= ost_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=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub-confi= g.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 t= o \"addr32\" or \"addr32;\" to make GAS happy */
+#define ADDR32 addr32
+
+/* Define it to \"d= ata32\" or \"data32;\" to make GAS happy */
+#defi= ne DATA32 data32
+
+/* Define to 1 if translation of pr= ogram messages to the user's native
+   language is requested. */
+#define ENABLE_NLS 1
+
+/* Define if C symbols get an underscore after compilat= ion */
+/* #undef HAVE_ASM_USCORE */
+
+/* De= fine 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
+   Cor= eFoundation framework. */
+/* #undef HAVE_CFLOCALECOPYCURRENT */<= /div>
+
+/* Define to 1 if you have the MacOS X function CFPrefere= ncesCopyAppValue 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 GN= U dcgettext() function is already present or preinstalled.
+ &nbs= p; */
+#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 ha= ve the `getgid' function. */
+#define HAVE_GETGID 1
+
+/* Define if getrawparti= tion() 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 h= ave the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* Define if you have the iconv() function and it works. */<= /div>
+/* #undef HAVE_ICONV */
+
+/* Define to 1 if you = have the <inttypes.h> header file. */
+#define HAVE_INTTYPE= S_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 h= ave 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 t= o 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_POSI= X_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_STDIN= T_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 fil= e. */
+#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 i= f 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 HAV= E_SYS_SYSMACROS_H 1
+
+/* Define to 1 if you have the <sys/types.h> header= file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* D= efine 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 fi= le. */
+/* #undef HAVE_USB_H */
+
+/* Define to 1 if you = have the `vasprintf' function. */
+#define HAVE_VASPRINTF 1
+
+/* Define to 1 if `major', `minor', and `make= dev' are declared in <mkdev.h>.
+   */
+/* #undef MAJOR_IN_MKDEV */
+
+/* Define to 1 if `major', `minor', and `makedev' are decla= red in
+   <sysmacros.h>. */
+/* #undef MAJO= R_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 "bu= rg"
+
+/* Define to the address where bug reports = for this package should be sent. */
+#define PACKAGE_BUGREPORT &q= uot;bean123ch@gmail.com"
+
+/* Define to the full name of this package. */
= +#define PACKAGE_NAME "BURG"
+
+/* Define to = the full name and version of this package. */
+#define PACKAGE_ST= RING "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_V= ERSION "1.98"
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 8
+
+/* The size of `void *&= #39;, 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 th= e 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_BIGENDI= AN */
+#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 _FI= LE_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 oth= er 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.  */
+#ifn= def _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threadi= ng extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANT= ICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
<= div> +/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SO= URCE
+# define _TANDEM_SOURCE 1
+#endif
+/* E= nable general extensions on Solaris.  */
+#ifndef __EXTENSIO= NS__
+# define __EXTENSIONS__ 1
+#endif
+
dif= f --exclude=3D.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/io= emu-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 +08= 00
@@ -0,0 +1,186 @@
+/* err.c - error handling routine= s */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Fo= undation, Inc.
+ *
+ *  GRUB is free software: you= can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c 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];<= /div>
+
+static struct
+{
+  grub_er= r_t errno;
+  char errmsg[GRUB_MAX_ERRMSG];
+} gru= b_error_stack_items[GRUB_ERROR_STACK_SIZE];
+
+static int grub_error_stack_pos;
+static int gr= ub_error_stack_assert;
+
+
+
+stati= c int
+grub_vsnprintf (char *str, grub_size_t n, const char *fmt,= va_list ap)
+{
+  grub_size_t ret;
+
+  if= (!n)
+    return 0;
+
+  
+  ret =3D 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 =3D grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), fmt, ar= gs);
+
+  return ret;
+}
+
+in= t
+grub_err_printf (const char *fmt, ...)
+{
= +  va_list ap;
+  int ret;
+
+ &nbs= p;va_start (ap, fmt);
+  ret =3D 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_er= rno =3D n;
+  va_start (ap, fmt);
+  grub_vsn= printf (grub_errmsg, sizeof (grub_errmsg), fmt, ap);
+  va_e= nd (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. &= nbsp;*/
+  if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
+ &n= bsp;  {
+      /* Copy active error message t= o stack.  */
+      grub_error_stack_items[gr= ub_error_stack_pos].errno =3D grub_errno;
+      grub_memcpy (grub_error_stack_items[grub_error_stack_= pos].errmsg,
+               &= nbsp;   grub_errmsg,
+           &n= bsp;       sizeof (grub_errmsg));
+
+ &n= bsp;    /* Advance to next error stack position.  */
+      grub_error_stack_pos++;
+    = ;}
+  else
+    {
+   &nb= sp;  /* There is no room for new error message. Discard new error mess= age
+         and mark error stack assertion = flag.  */
+      grub_error_stack_assert =3D 1;
+  = ;  }
+
+  /* Allow further operation of other= components by resetting
+     active errno to GRUB_ERR= _NONE.  */
+  grub_errno =3D GRUB_ERR_NONE;
+}
+
+int
+grub_error_pop (void)
+{
+  if (grub_error_stack_pos > 0)
+  =  {
+      /* Pop error message from error st= ack to current active error.  */
+      grub_error_stack_pos--;
+
+ =      grub_errno =3D grub_error_stack_items[grub_error_stack_= pos].errno;
+      grub_memcpy (grub_errmsg,
=
+                   grub_= error_stack_items[grub_error_stack_pos].errmsg,
+                   sizeo= f (grub_errmsg));
+
+      return 1;
+    }
+  else
+    {
+      /* There is no more items on error stack, re= set to no error state.  */
+      grub_errno =3D GRUB_ERR_NONE;
+
<= div>+      return 0;
+    }
+}=
+
+void
+grub_print_error (void)
+= {
+  /* Print error messages in reverse order. First print a= ctive error message
+     and then empty error stack.  */
+  = ;do
+    {
+      if (grub_err= no !=3D GRUB_ERR_NONE)
+        grub_err_prin= tf ("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 over= flow detected!\n");
+      grub_error_stack_assert =3D 0;
+  = ;  }
+}
+
+
+int test_grub_err= ()
+{
+  grub_error(222, "test %s\n", &q= uot;grub_error");
+  grub_err_printf("test %s\n", "grub_err_printf&q= uot;);
+  grub_fatal("test %s\n", "grub_fatal= ");
+}
+
diff --exclude=3D.svn -rpN -U8 = xen-4.1.2-a/tools/ioemu-qemu-xen/grub_err.h xen-4.1.2-b/tools/ioemu-qemu-xe= n/grub_err.h
--- xen-4.1.2-a/tools/ioemu-qemu-xen/grub_err.h 1970-01-01 07:00:00.000000000 +07= 00
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub_err.h 2012-12-28 16:02:41.00773= 4164 +0800
@@ -0,0 +1,81 @@
+/* err.h - error numbers and prototypes */=
+/*
+ *  GRUB  --  GRand Unified Bootlo= ader
+ *  Copyright (C) 2002,2005,2007,2008 Free Software Fo= undation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it= and/or modify
+ *  it under the terms of the GNU General Pu= blic License as published by
+ *  the Free Software Foundati= on, 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. &nb= sp;See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ERR_HEADER
+#define= GRUB_ERR_HEADER <= /span>1
+
+
+typedef enum
+  {=
+    GRUB_ERR_NONE =3D 0,
+    GRUB_ERR_= TEST_FAILURE,
+    GRUB_ERR_BAD_MODULE,
+ &nb= sp;  GRUB_ERR_OUT_OF_MEMORY,
+    GRUB_ERR_BAD_FIL= E_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_NUMBE= R,
+    GRUB_ERR_OUT_OF_RANGE,
+    GRUB_ERR_UNKNOWN_DEVICE,
+    GRUB_= ERR_BAD_DEVICE,
+    GRUB_ERR_READ_ERROR,
+ &= nbsp;  GRUB_ERR_WRITE_ERROR,
+    GRUB_ERR_UNKNOWN= _COMMAND,
+    GRUB_ERR_INVALID_COMMAND,
+    GRUB_ERR_BAD_ARGUMENT,
+    GRUB_ER= R_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_ER= R_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_U= NKNOWN
+
+  }
+grub_err_t;
+
+
+#ifndef _
+# define _(String) String
<= div>+#endif
+
+extern grub_err_t grub_errno;
+extern char grub_errm= sg[];
+
+grub_err_t grub_error (grub_err_t n, const cha= r *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 (cons= t char *fmt, ...)
+     __attribute__ ((format (printf,= 1, 2)));
+int test_grub_err(void);
+
+#endif /* ! GRUB_ERR_= HEADER */
diff --exclude=3D.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.000000= 000 +0700
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/config.h<= span class=3D"Apple-tab-span" style=3D"white-space:pre"> 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 t= o \"addr32\" or \"addr32;\" to make GAS happy */
+#define ADDR32 addr32
+
+/* Define it to \"d= ata32\" or \"data32;\" to make GAS happy */
+#defi= ne DATA32 data32
+
+/* Define to 1 if translation of pr= ogram messages to the user's native
+   language is requested. */
+#define ENABLE_NLS 1
+
+/* Define if C symbols get an underscore after compilat= ion */
+/* #undef HAVE_ASM_USCORE */
+
+/* De= fine 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
+   Cor= eFoundation framework. */
+/* #undef HAVE_CFLOCALECOPYCURRENT */<= /div>
+
+/* Define to 1 if you have the MacOS X function CFPrefere= ncesCopyAppValue 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 GN= U dcgettext() function is already present or preinstalled.
+ &nbs= p; */
+#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 ha= ve the `getgid' function. */
+#define HAVE_GETGID 1
+
+/* Define if getrawparti= tion() 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 h= ave the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* Define if you have the iconv() function and it works. */<= /div>
+/* #undef HAVE_ICONV */
+
+/* Define to 1 if you = have the <inttypes.h> header file. */
+#define HAVE_INTTYPE= S_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 h= ave 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 t= o 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_POSI= X_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_STDIN= T_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 fil= e. */
+#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 i= f 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 HAV= E_SYS_SYSMACROS_H 1
+
+/* Define to 1 if you have the <sys/types.h> header= file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* D= efine 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 fi= le. */
+/* #undef HAVE_USB_H */
+
+/* Define to 1 if you = have the `vasprintf' function. */
+#define HAVE_VASPRINTF 1
+
+/* Define to 1 if `major', `minor', and `make= dev' are declared in <mkdev.h>.
+   */
+/* #undef MAJOR_IN_MKDEV */
+
+/* Define to 1 if `major', `minor', and `makedev' are decla= red in
+   <sysmacros.h>. */
+/* #undef MAJO= R_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 "bu= rg"
+
+/* Define to the address where bug reports = for this package should be sent. */
+#define PACKAGE_BUGREPORT &q= uot;bean123ch@gmail.com"
+
+/* Define to the full name of this package. */
= +#define PACKAGE_NAME "BURG"
+
+/* Define to = the full name and version of this package. */
+#define PACKAGE_ST= RING "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_V= ERSION "1.98"
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 8
+
+/* The size of `void *&= #39;, 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 th= e 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_BIGENDI= AN */
+#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 _FI= LE_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 oth= er 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.  */
+#ifn= def _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threadi= ng extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANT= ICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
<= div> +/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SO= URCE
+# define _TANDEM_SOURCE 1
+#endif
+/* E= nable general extensions on Solaris.  */
+#ifndef __EXTENSIO= NS__
+# define __EXTENSIONS__ 1
+#endif
+
dif= f --exclude=3D.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 */<= /div>
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,20= 09  Free Software Foundation, Inc.
+ *
+ *  G= RUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "misc.h"
+#include "= fat.h"
+
+
+static int
+fat_lo= g2 (unsigned x)
+{
+  int i;
+
+  if (x =3D=3D 0)
+    return -1;
+
+  for (i =3D 0; (x & 1) =3D=3D 0; i++)
+   =  x >>=3D 1;
+
+  if (x !=3D 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 gru= b_fat_data *data =3D 0;
+  grub_uint32_t first_fat, magic;
+  int64_t off_= bytes =3D (int64_t)part_off_sector << GRUB_DISK_SECTOR_BITS;
+
+  if (! bs)
+    goto fail;
+
+  data =3D (struct grub_fat_data *) malloc (sizeof (*d= ata));
+  if (! data)
+    goto fail;
+
+  /* Read the BPB.  */
+  if (bdrv_pread(= bs, off_bytes, &bpb, sizeof(bpb)) !=3D sizeof(bpb))
+   =  {
+      printf("bdrv_pread fail....\n&= quot;);
+      goto fail;
+    }
= +    
+  if (grub_strncmp((const char *) bpb.versi= on_specific.fat12_or_fat16.fstype, "FAT12", 5)
+  =    && grub_strncmp((const char *) bpb.version_specific.f= at12_or_fat16.fstype, "FAT16", 5)
+      && grub_strncmp((const char *) bpb.versi= on_specific.fat32.fstype, "FAT32", 5))
+    {=
+      
+      printf(&q= uot;fail here-->grub_strncmp......line[%u]\n", __LINE__);
+      goto fail;
+    }
= +
+  /* Get the sizes of logical sectors and clusters.  = ;*/
+  data->logical_sector_bits =3D
+   &= nbsp;fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
+  printf("bpb.bytes_per_sector=3D0x%x, le_to_cpu16=3D0x%x\n= ",
+  bpb.bytes_per_sector, grub_le_to_cpu16 (bpb.bytes_per_sector= ));
+  
+
+  if (data->logical_sector_bits <= ; GRUB_DISK_SECTOR_BITS)
+  {
+    print= f("fail here-->logical_sector_bits......line[%u]\n", __LINE__)= ; 
+    goto fail;
+  }
+  data->logical_sector_bits -=3D GRUB_DIS= K_SECTOR_BITS;
+
+  printf("bpb.sectors_per_c= luster=3D%u\n", bpb.sectors_per_cluster);
+  data->c= luster_bits =3D fat_log2 (bpb.sectors_per_cluster);
+  if (data->cluster_bits < 0)
+    {
+      printf("fail here-->cluster_bits....= ..line[%u]\n", __LINE__); 
+      goto f= ail;
+    }
+  data->cluster_bits += =3D data->logical_sector_bits;
+
+  /* Get information about FATs.  */
= +  printf("bpb.num_reserved_sectors=3D%u, le_to_cpu16=3D%u\n"= ;,
+  bpb.num_reserved_sectors, grub_le_to_cpu16 (bpb.num_reserved_sect= ors));
+  data->fat_sector =3D part_off_sector + (grub_le_to_cpu16 (b= pb.num_reserved_sectors)
+       << data->logi= cal_sector_bits);
+  printf("data->fat_sector=3D%u\n", data->fat_sector)= ;
+  if (data->fat_sector =3D=3D 0)
+   &n= bsp;{
+      printf("fail here-->fat_secto= r......line[%u]\n", __LINE__); 
+      goto fail;
+    }
= +  data->sectors_per_fat =3D ((bpb.sectors_per_fat_16
+  &nbs= p;  ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
+ &n= bsp;   : 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=3D%= u\n"
+  "grub_le_to_cpu32 (bpb.version_specific.fat32.sectors= _per_fat_32)=3D%u\n",
+ &nbs= p;bpb.version_specific.fat32.sectors_per_fat_32,
+  grub_le_to_cpu32 (b= pb.version_specific.fat32.sectors_per_fat_32));
+  if (data->sectors_per_fat =3D=3D 0)
+   &nbs= p;goto fail;
+
+  /* Get the number of sectors in = this volume.  */
+  data->num_sectors =3D ((bpb.num_= total_sectors_16
+ ? grub_le_to_cpu16 (bpb.num_total_sectors_16)
+ : = grub_le_to_cpu32 (bpb.num_total_sectors_32))
+        &= lt;< data->logical_sector_bits);
+  if (data->num_sectors =3D=3D 0)
+    {<= /div>
+      printf("fail here-->num_sectors....= ..line[%u]\n", __LINE__); 
+      goto f= ail;
+    }
+  /* Get information about = the root directory.  */
+  if (bpb.num_fats =3D=3D 0)
+    {
+      printf("fail here-->num_fats......line[%u]\= n", __LINE__); 
+      goto fail;
<= div>+    }
+  data->root_sector =3D data->fa= t_sector + bpb.num_fats * data->sectors_per_fat;
+  data->num_root_sectors
+    =3D ((((gru= b_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))
+ &n= bsp;     << (data->logical_sector_bits));
+
+  data->cluster_sector =3D data->root_sector + data->= ;num_root_sectors;
+  data->num_clusters =3D (((data->num_sectors - data->c= luster_sector)
+  >> (data->cluster_bits + data->logical_= sector_bits))
+ + = 2);
+
+  if (data->num_clusters <=3D 2)
+    {
+      printf("fail he= re-->num_clusters......line[%u]\n", __LINE__); 
+      goto fail;
+    }
= +  if (! bpb.sectors_per_fat_16)
+    {
= +      /* FAT32.  */
+      gr= ub_uint16_t flags =3D grub_le_to_cpu16 (bpb.version_specific.fat32.extended= _flags);
+
+      data->root_cluster =3D grub_le_to= _cpu32 (bpb.version_specific.fat32.root_cluster);
+    =  data->fat_size =3D 32;
+      data->c= luster_eof_mark =3D 0x0ffffff8;
+
+      if (flags & 0x80)
+ {
+   /* Get an= active FAT.  */
+   unsigned active_fat =3D flags & 0xf;=
+
+=   if (active_fat > bpb.num_fats)
+     g= oto fail;
+
+  &nb= sp;data->fat_sector +=3D active_fat * data->sectors_per_fat;
+ }
=
+
+      if (bpb.num_root_entries !=3D 0 || bpb.version_specif= ic.fat32.fs_version !=3D 0)
+ goto fail;
+    }
+  else
+    {
+      /* FAT12 or FAT16.  */
+   &= nbsp;  data->root_cluster =3D ~0U;
+
+   &= nbsp;  if (data->num_clusters <=3D 4085 + 2)
+ {
+ &nbs= p; /* FAT12.  */
+   data->fat_size =3D 12;
+  &= nbsp;data->cluster_eof_mark =3D 0x0ff8;
+ }
+      else
+ {
+   /* FAT16.  */
+ &nbs= p; data->fat_size =3D 16;
+   data->cluster_eof_mark = =3D 0xfff8;
+ }
+    }
+
+  /* More sanity checks. =  */
+  if (data->num_sectors <=3D data->fat_se= ctor)
+    goto fail;
+
+  
+  printf("data->fat_sector=3D%u, data->sectors_per= _fat=3D%u\n",
+ &nbs= p;data->fat_sector, data->sectors_per_fat);
+  if (bdr= v_pread(bs,
+  data->fat_sector << GRUB_DISK_SECTOR_BITS,
+ &nb= sp;&first_fat,
+  sizeof (first_fat)) !=3D sizeof(first_fat))
+    {
+      printf("fail here-->bdrv_pread......line= [%u]\n", __LINE__); 
+      goto fail;
+    }
+
+  first_fat =3D grub_= le_to_cpu32 (first_fat);
+
+  if (data->fat_siz= e =3D=3D 32)
+    {
+      first_fat &=3D 0x= 0fffffff;
+      magic =3D 0x0fffff00;
+=    }
+  else if (data->fat_size =3D=3D 16)
+    {
+      first_fat &=3D = 0x0000ffff;
+      magic =3D 0xff00;
+    }
+  else
+    {
+     &n= bsp;first_fat &=3D 0x00000fff;
+      magic = =3D 0x0f00;
+    }
+
+  /* Ser= ial number.  */
+  if (bpb.sectors_per_fat_16)
+    data->= uuid =3D grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);=
+  else
+    data->uuid =3D 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) !=3D (magic | bpb.media | 0x8))
+=    {
+      printf("fail here-->= ;first_fat=3D0x%x, magic=3D0x%x......line[%u]\n",
+ &nbs= p;    first_fat, magic, __LINE__); 
+    = ;  goto fail;
+    }
+  /* Start fr= om the root directory.  */
+  data->file_cluster =3D= data->root_cluster;
+  data->cur_cluster_num =3D ~0U;
+  data->a= ttr =3D GRUB_FAT_ATTR_DIRECTORY;
+  printf("data->fi= le_cluster=3D%u \ndata->cur_cluster_num=3D%u \ndata->attr=3D0x%x\n&qu= ot;
+  "data->logical_sector_bits=3D%u\n"
+ &nbs= p;"data->cluster_bits=3D%u\n",
+  data->file_cluster, d= ata->cur_cluster_num, data->attr,
+ &nbs= p;data->logical_sector_bits, data->cluster_bits);
+  r= eturn data;
+
+ fail:
+
+  fre= e (data);
+  errx ("not a FAT filesystem...\n");
+ &nbs= p;return 0;
+}
+
+
+
+//= =B4=D3=CE=C4=BC=FE=B5=C4=D6=B8=B6=A8=C6=AB=D2=C6offset=D7=D6=BD=DA=B4=A6=B6= =C1=C8=A1len=D7=D6=BD=DA=B5=C4=CA=FD=BE=DD=B5=BDbuf
+//=CE=C4=BC= =FE=D3=C9data->file_cluster=D6=B8=B6=A8
+//data->file_cluster=D6=B8=B6=A8=C1=CB=CE=C4=BC=FE=B5=C4=C6=F0=CA=BC=B4= =D8=BA=C5
+//=C4=AC=C8=CFdata->file_cluster=3D2=A3=AC=B4=FA=B1= =ED=B8=F9=C4=BF=C2=BC
+static grub_ssize_t
+grub_fat_re= ad_data (BlockDriverState *bs, struct grub_fat_data *data,
+    &= nbsp;void (*read_hook) (grub_disk_addr_t sector,
+ &= nbsp;      unsigned offset, unsigned length,
+   = ;     void *closure),
+     void *closure,
+ &nb= sp;   grub_off_t offset, grub_size_t len, char *buf)
+{=
+  grub_size_t size;
+  grub_uint32_t logica= l_cluster;
+  unsigned logical_cluster_bits;
+  grub_ssize_t ret =3D 0;
+  unsigned long sector= ;
+  uint64_t off_bytes =3D 0; 
+  /* Th= is is a special case. FAT12 and FAT16 doesn't have the root directory
+     in clusters.  */
+  if (data->file_cluster =3D=3D ~0U)
+    = ;{
+      size =3D (data->num_root_sectors <= < GRUB_DISK_SECTOR_BITS) - offset;
+      if (s= ize > len)
+ size =3D len;
+
+      off_bytes =3D ((uint64_t)data->ro= ot_sector << GRUB_DISK_SECTOR_BITS) + offset;
+   &nbs= p;  if(bdrv_read(bs, off_bytes, buf, size ) !=3D size) 
+ return -= 1;
+
+      return size;
+   &nbs= p;}
+
+  /* Calculate the logical cluster number a= nd offset.  */
+  logical_cluster_bits =3D (data->cl= uster_bits
+   + data->logical_sector_bits
+ &n= bsp; + GRUB_DISK_SECTOR_BITS);
+  logical_cluster =3D o= ffset >> logical_cluster_bits;    //which cluster to read&n= bsp;
+  offset &=3D (1 << logical_cluster_bits) - = 1;           //mod
+
+  if (logical_cluster < data->cur_cluster_num)=   //
+    {
+      data-= >cur_cluster_num =3D 0;
+      data->cur_clu= ster =3D data->file_cluster; // =B5=DA2=B8=F6fat=B1=ED=CF=EE=BF=AA=CA=BC= =BC=C7=C2=BC=C4=BF=C2=BC=BA=CD=CE=C4=BC=FE
+    }
+
+  while (len)
+=    {
+      while (logical_cluster >= data->cur_cluster_num)
+ {
+  &nb= sp;/* Find next cluster.  */
+   grub_uint32_t next_cluster;<= /div>
+   unsigned long fat_offset;
+
+=   switch (data->fat_size)
+     {
<= div>+  = ;   case 32:
+ &nbs= p;     fat_offset =3D data->cur_cluster << 2;
=
+ &nbs= p;     break;
+     case 16:
+ &nbs= p;     fat_offset =3D data->cur_cluster << 1;
=
+ &nbs= p;     break;
+     default:
+ &nbs= p;     /* case 12: */
+       fat_offset = =3D data->cur_cluster + (data->cur_cluster >> 1);
+ &nbs= p;     break;
+     }
+
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre">   = ;/* Read the FAT.  */
+ &nbs= p; int len =3D (data->fat_size + 7) >> 3;
+   uint64= _t off_bytes =3D  ((uint64_t)data->fat_sector << GRUB_DISK_SE= CTOR_BITS) + fat_offset; 
+ &nbs= p; if (bdrv_pread (bs, off_bytes, 
+   (char *) &n= ext_cluster, 
+   len) !=3D len)   //=B4=D3fat=B1=ED= =B6=C1=C8=A1=B4=D8=BA=C5
+ &nbs= p;   return -1;
+
+   next_cluster =3D grub_le= _to_cpu32 (next_cluster);
+ &nbs= p; switch (data->fat_size)
+     {
+    &nbs= p;case 16:
+ &nbs= p;     next_cluster &=3D 0xFFFF;
+      &= nbsp;break;
+     case 12:
+ &nbs= p;     if (data->cur_cluster & 1)
+ next_cluster >= >=3D 4;
+
+ &nbs= p;     next_cluster &=3D 0x0FFF;
+      &= nbsp;break;
+     }
+
+=   printf ("fat_size=3D%d, next_cluster=3D%u\n",=
+ data->fat_size, next_cluster);
+
+=   /* Check the end.  */
+   if (next_cluste= r >=3D data->cluster_eof_mark)
+ &nbs= p;   return ret;
+
+   if (next_cluster < 2= || next_cluster >=3D data->num_clusters)
+ &nbs= p;   {
+       printf("invalid cluster %u= ................\n",
+   next_cluster);
+ &nbs= p;     return -1;
+     }
+
+  &= nbsp;data->cur_cluster =3D next_cluster;
+ &nbs= p; data->cur_cluster_num++;
+ }
+
+    = ;  /* Read the data here.  */
+      //=C2=DF=BC=AD=B4=D8=CB=F9=B6=D4=D3=A6=B5=C4=BE= =F8=B6=D4=C9=C8=C7=F8
+      sector =3D (data->= cluster_sector
+ + ((data->cur_cluster - 2)
+    << (dat= a->cluster_bits + data->logical_sector_bits))); 
+      //=BE=F8=B6=D4=C9=C8=C7=F8=D6=D0=C8=A5=B5=F4=C6= =AB=D2=C6=BA=F3=B5=C4=D7=D6=BD=DA=CA=FD
+      siz= e =3D (1 << logical_cluster_bits) - offset;
+    =  if (size > len)
+ size =3D len;
+
+      //disk->read_hook =3D read_hook;<= /div>
+      //disk->closure =3D closure;
+=      int64_t off_bytes =3D ((uint64_t)sector << GRUB_= DISK_SECTOR_BITS) + offset;
+      //disk->read= _hook =3D 0;
+      if (bdrv_pread (bs, off_bytes, buf, size) !=3D s= ize)
+ <= /span>return -1;
+
+      len -=3D size;=
+      buf +=3D size;
+      ret +=3D size;
+      l= ogical_cluster++;
+      offset =3D 0;  //=D2= =D4=BA=F3=B6=C1=B5=C4=B6=BC=CA=C7=CD=EA=D5=FB=C9=C8=C7=F8
+  = ;  }
+
+  return ret;
+}
= +
+//=B1=E9=C0=FA=D3=C9data->file_cluster=D6=B8=B6=A8=B5=C4=C4= =BF=C2=BC
+int
+grub_fat_iterate_dir (BlockDriverState *bs, struct gru= b_fat_data *data)
+{
+  struct grub_fat_dir_entry = dir;
+  char *filename, *filep =3D 0;
+  grub= _uint16_t *unibuf;
+  int slot =3D -1, slots =3D -1;
+  int checksum = =3D -1;
+  grub_ssize_t offset =3D -sizeof(dir);
+=
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    return printf("not a directory......\n");
+
+  /* Allocate space enough to hold a long name. &nbs= p;*/
+  filename =3D (char*)malloc (0x40 * 13 * 4 + 1);
+  unibuf =3D (grub_uint16_t *) malloc (0x40 * 13 * 2);
+  if (! filename || ! unibuf)
+    {
+      free (filename);
+      free (unibuf);
+      = return -1;
+    }
+
+
+ &= nbsp;int count =3D 0;
+  while (1)
+    = {
+      unsigned i;
+
+     &nb= sp;/* Adjust the offset.  */
+      offset += =3D sizeof (dir);
+      printf("[%d]offset= =3D%u\n"
+      "data->cur_cluster_num=3D%u,data= ->cur_cluster=3D%u\n", 
+ &nbs= p;    count+1, offset, 
+      data->cur_cl= uster_num, data->cur_cluster);
+      /* Read a directory entry.  */
+ =      //0x0=B1=ED=CA=BE=BF=D5=C4=BF=C2=BC
+   =    if ((grub_fat_read_data (bs, data, 0, 0,
+     = ;   offset, sizeof (dir), (char *) &dir)
+ &nbs= p;  !=3D sizeof (dir) || dir.name[0] = =3D=3D 0))
+ {
+  &nb= sp;printf("break...dir.name[0]=3D=3D%d= \n", dir.name[0]);
+   break;=
+ }
+      /* Handle long name entries.  */
+      if (dir.attr =3D=3D GRUB_FAT_ATTR_LONG_NAME)
=
+ {
+ &nbs= p; printf("long name...\n");
+   struct grub_fat_lo= ng_name_entry *long_name
+ &nbs= p;   =3D (struct grub_fat_long_name_entry *) &dir;
= +  &nb= sp;grub_uint8_t id =3D long_name->id;
+
+=   if (id & 0x40)  //the last item
+    =  {
+       id &=3D 0x3f;   //index or ordi= nal number  1~31
+ &nbs= p;     slots =3D slot =3D id;
+       che= cksum =3D long_name->checksum;
+       printf("t= he last ordinal num=3D%d!!!\n", id);
+ &nbs= p;   }
+
+   if (id !=3D slot || slot =3D=3D 0= || checksum !=3D long_name->checksum)
+ &nbs= p;   {
+       printf("not valid ordinal = number ,ignore...continue\n");
+ &nbs= p;     checksum =3D -1;
+       continue;=
+     }
+
+=   slot--;
+   memcpy (unibuf + slot * 13, long_n= ame->name1, 5 * 2);
+ &nbs= p; memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
<= div>+  = ; memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
+ &nbs= p; printf("memcpy...continue\n");
+   continue;
+ }<= /div>
+
+      
+      /* = Check if this entry is valid.  */
+      //ox= e5=B1=ED=CA=BE=D2=D1=BE=AD=B1=BB=C9=BE=B3=FD
+     &nbs= p;if (dir.name[0] =3D=3D 0xe5 || (dir.attr = & ~GRUB_FAT_ATTR_VALID))
+ {
+ &= nbsp; printf("dir.name[0]=3D0x%x,= dir.attr=3D0x%x not valid...continue\n", 
+ &nb= sp;dir.name[0], dir.attr);
+   con= tinue;
+= }
+
+      printf("checksum=3D%d, slot=3D%= d\n", checksum, slot);
+      /* This is a wo= rkaround for Japanese.  */
+      if (dir.name[0] =3D=3D 0x05)
+ dir.name[0] =3D 0xe5;
+
+ &nbs= p;    if (checksum !=3D -1 && slot =3D=3D 0)
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre"> {
+ &nbs= p; printf("checksuming\n");
+   grub_uint8_t sum;
+
+   for (sum =3D 0, i =3D 0; i < sizeof (dir.name); i++)
+ &nbs= p;   sum =3D ((sum >> 1) | (sum << 7)) + dir.name[i];
+
+   if (sum =3D=3D ch= ecksum)
+ &nbs= p;   {//=B3=A4=C3=FB=B1=ED=CF=EE=BA=F3=C3=E6=BD=F4=BD=D3=B6=CC=C3= =FB=B1=ED=CF=EE=A3=AC=D1=E9=D6=A4=B3=C9=B9=A6=D4=F2=D6=A4=C3=F7=D5=E6=D5=FD= =CA=C7=B3=A4=C3=FB=D7=D6
+       int u;
+
+ &nb= sp;     for (u =3D 0; u < slots * 13; u++)
+ uni= buf[u] =3D grub_le_to_cpu16 (unibuf[u]);
+
+      &= nbsp;*grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
+ &= nbsp;  slots * 13) =3D '\0';
+
+      =  //if (hook (filename, &dir, closure))
+ &nbs= p;       //break;
+
+      &nbs= p;checksum =3D -1;
+       for (i =3D 0; i < sizeof (= dir.name); i++)
+ pri= ntf("0x%x  ", dir.name[i]);<= /div>
+       char *gbname =3D (char*)malloc(256);
+ &nbs= p;     u2g(filename, strlen(filename), gbname, 256);
+  =      printf("\ndir.name=3D%s, filename=3D%s, dir.attr=3D0x%x,"
+ &nb= sp;    "sum=3D=3Dchecksum...continue\n",
+   =   dir.name, gbname, dir.attr);
+ &nbs= p;     free(gbname);
+       count++;
+ &n= bsp;     continue;
+ &nbs= p;   }
+
+   checksum =3D -1;
+ }
+
+      //=BA=F3=C3=E6=B5=C4=B4=A6=C0=ED=D5= =EB=B6=D4=B7=C7=D5=E6=CA=B5=B3=A4=C3=FB=BA=CD=D5=E6=CA=B5=B6=CC=C3=FB
=
+      /* Convert the 8.3 file name.  */
+      //=C8=A5=B5=F4=B6=CC=C3=FB=B5=C4=BF=D5=B8=F1=A3=AC= =C8=AB=B8=C4=CE=AA=D0=A1=D0=B4
+      filep =3D fi= lename;
+      if (dir.attr & GRUB_FAT_ATTR_VO= LUME_ID)
+ {
+ &= nbsp; printf("VOLUME\n");
+   for (i =3D 0; i < = sizeof (dir.name) && dir.name[i]
+ &nb= sp;&& ! grub_isspace (dir.name[i]);= i++)
+ =     *filep++ =3D dir.name= [i];
+ }
+      else
+ {
+   for (i =3D 0; i < 8 &= amp;& dir.name[i] && ! grub_iss= pace (dir.name[i]); i++)
+ &nbs= p;   *filep++ =3D grub_tolower (dir.n= ame[i]);
+
+   *filep =3D '.';
+
+=   for (i =3D 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+ &nbs= p;   *++filep =3D grub_tolower (dir.n= ame[i]);
+
+   if (*filep !=3D '.')
+ &nbs= p;   filep++;
+ }
+      *filep =3D '= \0';
+
+      
+      for (i =3D 0; i < sizeof (dir.name); i++)
+ printf("0x%x  ", dir.name[i]);
+      printf("\ndir.= name=3D%s, filename=3D=A1=BE%s=A1=BF, dir.attr=3D0x%x,"
= +  &nb= sp;   "...next while\n",
+  &nb= sp;   dir.name, filename, dir.attr);
+      count++;
+      /*i= f(strcmp(filename, ".") && strcmp(filename, ".."= ;))
+ {
+ &= nbsp; printf("{=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D>\n&q= uot;);
+=   struct grub_fat_data *data2 =3D NULL;
+ &nbs= p; data2 =3D (struct grub_fat_data*)malloc(sizeof(*data));
+=  &nbs= p;memcpy(data2, data, sizeof(*data));
+ &nbs= p; data2->attr =3D dir.attr;
+   data2->file_size =3D g= rub_le_to_cpu32 (dir.file_size);
+ &nbs= p; data2->file_cluster =3D ((grub_le_to_cpu16 (dir.first_cluster_hi= gh) << 16)
+  | grub_le_to_cpu16 (dir.first_cluster_low));
+ &nbs= p; data2->cur_cluster_num =3D ~0U;
+   (grub_fat_iterate_d= ir(bs, data2) < 0) ? printf("error !!!!!!\n") : 0;
+ &nbs= p; free(data2);
+   printf("<=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D}\n");
+ }
+      */
+      //if (hook (f= ilename, &dir, closure))
+        //break= ;
+    }
+
+  free (filename);=
+  free (unibuf);
+
+  return 0;
+}
+
+
+/*
+struct grub_fat_fi= nd_dir_closure
+{
+  struct grub_fat_data *data;
+  int (*hook) (const char *filename,
+      &= nbsp; const struct grub_dirhook_info *info,
+ &nbs= p;      void *closure);
+  void *closure;
+  char *dirname;
+  int call_hook;
+ =  int found;
+};
+
+
+static int
+grub_fat_find_dir_hook (cons= t char *filename, struct grub_fat_dir_entry *dir,
+ void *closure)
+{
+  struct grub_fat_find_dir_closure *c =3D closure;
=
+  struct grub_dirhook_info info;
+  grub_memset (= &info, 0, sizeof (info));
+
+  info.dir =3D !!= (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
+  info.case_insensitive =3D 1;
+
+  if = (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
+    retur= n 0;
+  if (*(c->dirname) =3D=3D '\0' && = (c->call_hook))
+    return c->hook (filename, &info, c->closure);
+
+  if (grub_strcasecmp (c->dirname, filename) =3D= =3D 0)
+    {
+      struct gr= ub_fat_data *data =3D c->data;
+
+      c->found =3D 1;
+   &nb= sp;  data->attr =3D dir->attr;
+      d= ata->file_size =3D grub_le_to_cpu32 (dir->file_size);
+ &nb= sp;    data->file_cluster =3D ((grub_le_to_cpu16 (dir->firs= t_cluster_high) << 16)
+ &n= bsp;      | grub_le_to_cpu16 (dir->first_cluster_low));
+      data->cur_cluster_num =3D ~0U;
= +
+      if (c->call_hook)
+ c-&g= t;hook (filename, &info, c->closure);
+
+  =    return 1;
+    }
+  return= 0;
+}
+*/
+
+/* Find the underlying directory or file in PATH and retu= rn the
+   next path. If there is no next path or an error o= ccurs, return NULL.
+   If HOOK is specified, call it with e= ach file name.  */
+char *
+grub_fat_find_dir (BlockDriverState *bs, struct gru= b_fat_data *data,
+    const char *path,
+    int (*h= ook) (const char *filename,
+ c= onst struct grub_dirhook_info *info,
+ void *closure),
+    voi= d *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 =3D=3D '/')
+    path++;
+
+  dirp =3D grub_strchr (path, '/');
+  if (dirp)
+    {
+    =  unsigned len =3D dirp - path;
+
+     =  dirname =3D (char*)malloc (len + 1);
+      = if (! dirname)
+ return 0;
+
+      memcpy (dirname, path, len);
+      dirname[len] =3D '\0';
+   =  }
+  else
+    {
+  = ;  /* This is actually a file.  */
+     &nbs= p;dirname =3D grub_strdup (path);
+    }
+  //c.data =3D data;
+ &nbs= p;//c.hook =3D hook;
+  //c.closure =3D closure;
+=  //c.dirname =3Ddirname;
+  //c.found =3D 0;
+  //c.call_hook =3D (! dirp && hook);
+  if(grub_fat_iterate_dir (bs, data)<0)
+   &n= bsp;{
+       printf("file not found..\n"= ;);
+       return 0;
+    }
+    
+  
+  free (dirname= );
+
+  return dirp;
+}
+
+<= /div>
+
+
+
+
+
+
+
+
+
+
+
+
<= div> +
+
+
+
diff --exclude=3D.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/gru= b-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"
+#i= nclude "block_int.h"
+
+#define GRUB_DISK_SEC= TOR_BITS      9
+#define GRUB_FAT_DIR_ENTRY_SIZE 32
+
+#define GRUB_FAT_ATTR_READ_ONLY 0x01
+#define GRUB_FAT_ATT= R_HIDDEN 0x= 02
+#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_MAXFI= LE 256
+
+#define GRUB_FAT_ATTR_LONG_NAME (GRUB_FAT_ATTR_READ_ONLY \
+  | GR= UB_FAT_ATTR_HIDDEN \
+ &= nbsp;| GRUB_FAT_ATTR_SYSTEM \
+  | GRUB_FAT_ATTR_VOLUME_ID)
+#define GRUB_FAT_ATTR_VALID (GRUB_FAT_ATTR_READ_ONLY \
+ &= nbsp;| GRUB_FAT_ATTR_HIDDEN \
+  | GRUB_FAT_ATTR_SYSTEM \
= +  = | GRUB_FAT_ATTR_DIRECTORY \
+ &= nbsp;| 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_uint1= 6_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_roo= t_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_h= idden_sectors;
+  grub_uint32_t num_total_sectors_32;
<= div>+  union
+  {
+    struct
=
+    {
+      grub_uint8_t num_ph_d= rive;
+      grub_uint8_t reserved;
+    =  grub_uint8_t boot_sig;
+      grub_uint32_t= num_serial;
+      grub_uint8_t label[11];
<= div>+      grub_uint8_t fstype[8];
+    = } __attribute__ ((packed)) fat12_or_fat16;
+    struct
+    {
+   &n= bsp;  grub_uint32_t sectors_per_fat_32;
+     &nbs= p;grub_uint16_t extended_flags;
+      grub_uint16= _t fs_version;
+      grub_uint32_t root_cluster;<= /div>
+      grub_uint16_t fs_info;
+    =  grub_uint16_t backup_boot_sector;
+      gr= ub_uint8_t reserved[12];
+      grub_uint8_t num_p= h_drive;
+      grub_uint8_t reserved1;
+      grub_uint8_t boot_sig;
+     &nbs= p;grub_uint32_t num_serial;
+      grub_uint8_t la= bel[11];
+      grub_uint8_t fstype[8];
= +    } __attribute__ ((packed)) fat32;
+  } __attr= ibute__ ((packed)) version_specific;
+} __attribute__ ((packed));
+
+struct grub_fat_di= r_entry
+{
+  grub_uint8_t name[11];
+ &= nbsp;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;<= /div>
+  grub_uint16_t a_date;
+  grub_uint16_t fir= st_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 chec= ksum;
+  grub_uint16_t name2[6];
+  grub_uint= 16_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_p= er_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_uin= t8_t attr;
+  grub_ssize_t file_size;
+  grub_uint32_t file_cluste= r;
+  grub_uint32_t cur_cluster_num;
+  grub_= uint32_t cur_cluster;
+
+  grub_uint32_t uuid;
+};
+
+
+
+
+
+
+st= ruct 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=3D.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/g= rub-fat/fs-types.h
--- xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/fs-types.h 1970-01-01 07:00:00.0000= 00000 +0700
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/fs-type= s.h 2012-12= -28 16:02:41.009937738 +0800
@@ -0,0 +1,228 @@
+/*
+ *  GRUB  -- &nbs= p;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 publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_HEADER
+#defi= ne GRUB_TYPES_HEADER 1
+
+#include <config.h>
+#in= clude <x86_64/types.h>
+
+#ifdef GRUB_UTIL
+# define GRUB_CPU_SIZEOF_VOID= _P SIZEOF_V= OID_P
+# define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG
+# ifdef WORDS_BIGENDIAN
+#  define GRUB_CPU_WORDS_BIGE= NDIAN 1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIAN
= +# endif
+#else /* ! GRUB_UTIL */
+# define GRUB_CPU_SIZEOF_VOID_P GRUB_TARGET_S= IZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG GRUB_TARGET_SIZEOF_LONG
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define GRUB_CP= U_WORDS_BIGENDIAN = 1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIA= N
+# endif
+#endif /* ! GRUB_UTIL */
+
+#if GRU= B_CPU_SIZEOF_VOID_P !=3D 4 && GRUB_CPU_SIZEOF_VOID_P !=3D 8
+# error "This architecture is not supported because sizeof(void *)= !=3D 4 and sizeof(void *) !=3D 8"
+#endif
+
+#ifndef GRUB_TARGET_WORDSIZE
= +# if GRUB_TARGET_SIZEOF_VOID_P =3D=3D 4
+#  define GRUB_TAR= GET_WORDSIZE 32
+# elif GRUB_TARGET_SIZEOF_VOID_P =3D=3D 8
<= div>+#  define GRUB_TARGET_WORDSIZE 64
+# endif
+#endif
+
+/* Define various wi= de integers.  */
+typedef signed char grub_int8_t;
+typedef = short gru= b_int16_t;
+typedef int = grub_int32_t;
+#if GRUB_CPU_SIZEOF_LONG =3D=3D 8
+typedef long = grub_int64_t;
+#else
+typedef long long grub_int64_t;
+#endif
+<= /div>
+typedef unsigned char grub_uint8_t;
+typedef unsigned short grub_uint16_t;
+typedef unsigned grub_uint32_t;
+#if GRUB_CPU_SIZEOF_LONG =3D=3D 8
+typedef unsigned long grub_uint64_t;
+#else
+typedef unsign= ed long long grub_uint64_t;
+#endif
+
+/* Misc types.  */
+#if = GRUB_TARGET_SIZEOF_VOID_P =3D=3D 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_ui= nt32_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 =3D=3D 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 =3D=3D 8
+# define GRUB_ULONG_MAX 18446744073709551615UL
+# define = GRUB_LONG_MAX 9223372036854775807L
+# define GRUB_LONG_MIN (-9223= 372036854775807L - 1)
+#else
+# define GRUB_ULONG_MAX 4294967295UL
+# de= fine GRUB_LONG_MAX 2147483647L
+# define GRUB_LONG_MIN (-21474836= 47L - 1)
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_= P =3D=3D 4
+#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
+#define= PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
+#define PT= R_TO_UINT32(x) ((grub_uint32_t)(x))
+#else
+#define UIN= T_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_byt= es16(x) \
+({ \
+   grub_uint16_t _x =3D (x); \
+ &= nbsp; (grub_uint16_t) ((_x << 8) | (_x >> 8)); \
+})
+
+#if defined(__GNUC__) && (__GNUC__ = > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >=3D 3) &&= defined(GRUB_TARGET_I386)
+static inline grub_uint32_t grub_swap= _bytes32(grub_uint32_t x)
+{
+ return __builtin_bswap32(x);
+}
+
+s= tatic inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
+{<= /div>
+ retu= rn __builtin_bswap64(x);
+}
+#else /* not gcc 4.3 or newer */<= /div>
+#define grub_swap_bytes32(x) \
+({ \
+   grub_uint32_t = _x =3D (x); \
+   (grub_uint32_t) ((_x << 24) \
<= div>+                    = | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \
+                    = ;| ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \
+   =                  | (_x >>= ; 24)); \
+})
+
+#define grub_swap_bytes64(x)= \
+({ \
+   grub_uint64_t _x =3D (x); \
+  = ; (grub_uint64_t) ((_x << 56) \
+       &nbs= p;            | ((_x & (grub_uint64_t) 0x= FF00ULL) << 40) \
+           &nbs= p;        | ((_x & (grub_uint64_t) 0xFF0000ULL) <= ;< 24) \
+                    = ;| ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
+ &nbs= p;                  | ((_x &am= p; (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)<= /div>
+# define grub_cpu_to_le64(x) grub_swap_bytes64(x)
+# define grub_le_to= _cpu16(x) g= rub_swap_bytes16(x)
+# define grub_le_to_cpu32(x) grub_swap_bytes32(x)
+# define grub_le_to= _cpu64(x) g= rub_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_t= o_cpu16(x) = ((grub_uint16_t) (x))
+# define grub_be_to_cpu32(x) ((grub_uint32_t) (x))
+# define grub_be_t= o_cpu64(x) = ((grub_uint64_t) (x))
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_ta= rget_to_host16(x) = ((grub_uint16_t) (x))
+#  define grub_target_to_host3= 2(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_t= o_cpu16(x) = ((grub_uint16_t) (x))
+# define grub_le_to_cpu32(x) ((grub_uint32_t) (x))
+# define grub_le_t= o_cpu64(x) = ((grub_uint64_t) (x))
+# define grub_cpu_to_be16(x) grub_swap_bytes16(x)
+# define grub_cpu_t= o_be32(x) g= rub_swap_bytes32(x)
+# define grub_cpu_to_be64(x) grub_swap_bytes64(x)
+# define grub_be_to= _cpu16(x) g= rub_swap_bytes16(x)
+# define grub_be_to_cpu32(x) grub_swap_bytes32(x)
+# define grub_be_to= _cpu64(x) g= rub_swap_bytes64(x)
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_ta= rget_to_host16(x) = grub_swap_bytes16(x)
+#  define grub_target_to_host32= (x) grub_sw= ap_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_t= o_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 =3D=3D 8
+#  define grub_h= ost_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 */
<= div>diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fa= t/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.0= 00000000 +0700
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/i386= /types.h 20= 12-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 publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c 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 *.  */<= /div>
+#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_C= PU_HEADER */
diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioe= mu-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.00000000= 0 +0700
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/grub-fat/misc.h 2012-12-28 16:0= 2:41.010937619 +0800
@@ -0,0 +1,17 @@
+int
+grub_strncmp (const char *s= 1, const char *s2, grub_size_t n)
+{
+  if (n =3D= =3D 0)
+    return 0;
+
+  whi= le (*s1 && *s2 && --n)
+    {
+      if (*s1 !=3D *s2)
+        break;
+
+   &= nbsp;  s1++;
+      s2++;
+   =  }
+
+  return (int) *s1 - (int) *s2;
+}
diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/grub-fat/x8= 6_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 @@
+/*
+ * &nbs= p;GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute i= t and/or modify
+ *  it under the terms of the GNU General P= ublic License as published by
+ *  the Free Software Foundation, either version 3 of the Licens= e, 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. &nbs= p;See the
+ *  GNU General Public License for more details.<= /div>
+ *
+ *  You should have received a copy of the GNU General Public Li= cense
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
<= div>+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYP= ES_CPU_HEADER 1
+
+/* The size of void *.  */
+#def= ine GRUB_TARGET_SIZEOF_VOID_P 8
+
+/* The size of long.  */
+#ifdef __MINGW32= __
+#define GRUB_TARGET_SIZEOF_LONG 4
+#else
+#define G= RUB_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=3D.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.0= 17802371 +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 publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c 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 *.  */<= /div>
+#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_C= PU_HEADER */
diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioe= mu-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=3Dcutils.o  cache-utils.o
 
 libqemu_user.a: $(USER_OBJS)
 
 ############################################################= ##########
 
-qemu-img$(EXESUF): qemu-img.o qemu-t= ool.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 +=3D = -lz
 
 
 clean:
&nbs= p;# avoid old build problems by removing potentially incorrect old files
diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/Mak= efile.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 in= stall-doc \
+ recu= rse-all speed tar tarbin test
+
+VPATH=3D$(SRC_PATH):$(= SRC_PATH)/hw
+
+
+CFLAGS +=3D $(OS_CFLAGS) $(= ARCH_CFLAGS)
+LDFLAGS +=3D $(OS_LDFLAGS) $(ARCH_LDFLAGS)
+
+CPP= FLAGS +=3D -I. -I$(SRC_PATH) -MMD -MP -MT $@
+CPPFLAGS +=3D -D_GN= U_SOURCE -D_FILE_OFFSET_BITS=3D64 -D_LARGEFILE_SOURCE
+LIBS=3D
+ifdef CONFIG_STATIC
+LDFLAGS +=3D -static
+endif
=
+ifdef BUILD_DOCS
+DOCS=3Dqemu-doc.html qemu-tech.html qemu.= 1 qemu-img.1 qemu-nbd.8
+else
+DOCS=3D
+endif=
+
+LIBS+=3D$(AIOLIBS)
+
+ifdef CONFIG_SO= LARIS
+LIBS+=3D-lsocket -lnsl -lresolv
+endif
+
+ifdef CONFIG_WIN32
+LIBS+=3D-lwinmm -lws2_32 -liphl= papi
+endif
+
+all: $(TOOLS) $(DOCS) recurse-all
<= div>+
+SUBDIR_RULES=3D$(patsubst %,subdir-%, $(TARGET_DIRS))
+
+subdir-%:
+ $(call quiet-command,$(MAKE) -C $* V=3D"= $(V)" TARGET_DIR=3D"$*/" all,)
+
+$(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a
+$(filter %-user,$(SUBDIR_RULES)): libqemu_user.a
+
<= div>+recurse-all: $(SUBDIR_RULES)
+
+CPPFLAGS +=3D -I$(= XEN_ROOT)/tools/libxc
+CPPFLAGS +=3D -I$(XEN_ROOT)/tools/blktap/lib
+CPPFLAGS +=3D= -I$(XEN_ROOT)/tools/xenstore
+CPPFLAGS +=3D -I$(XEN_ROOT)/tools/= include
+
+tapdisk-ioemu: tapdisk-ioemu.c cutils.c bloc= k.c block-raw.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c b= lock-dmg.c block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c hw/xen_blk= tap.c osdep.c
+ $(CC= ) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAG= S) -o $@ $^ -lz $(LIBS)
+
+############################= ###########################################
+# BLOCK_OBJS is code used by both qemu system emulation and qemu-img<= /div>
+
+BLOCK_OBJS=3Dcutils.o osdep.o qemu-malloc.o
+BLOCK_OBJS+=3Dblock-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o<= /div>
+BLOCK_OBJS+=3Dblock-dmg.o block-bochs.o block-vpc.o block-vvfat.o
+BLOCK_OBJS+=3Dblock-qcow2.o block-parallels.o block-nbd.o
+BLOCK_OBJS+=3Dnbd.o block.o aio.o
+
+ifdef CONFIG_WIN= 32
+BLOCK_OBJS +=3D block-raw-win32.o
+else
+ifdef CO= NFIG_AIO
+BLOCK_OBJS +=3D posix-aio-compat.o
+endif
+BLOCK_OBJS +=3D block-raw-posix.o
+endif
+
+######################################################################
+# libqemu_common.a: Target independent part of system emulation. Th= e
+# long term path is to suppress *all* target specific code in = case of
+# system emulation, i.e. a single QEMU executable should support all<= /div>
+# CPUs and machines.
+
+OBJS=3D$(BLOCK_OBJS)=
+OBJS+=3Dreadline.o console.o
+
+OBJS+=3Dirq= .o
+OBJS+=3Di2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
+OBJS+=3Dssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o<= /div>
+OBJS+=3Dtmp105.o lm832x.o
+OBJS+=3Dscsi-disk.o cdrom.o=
+OBJS+=3Dscsi-generic.o
+OBJS+=3Dusb.o usb-hub.o usb-$(HOST_= USB).o usb-hid.o usb-msd.o usb-wacom.o
+OBJS+=3Dusb-serial.o usb-= net.o
+OBJS+=3Dsd.o ssi-sd.o
+OBJS+=3Dbt.o bt-host.o bt= -vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
+OBJS+=3Dbuffered_file.o migration.o migration-tcp.o net.o qemu-socket= s.o
+OBJS+=3Dqemu-char.o aio.o net-checksum.o savevm.o cache-util= s.o
+
+ifdef CONFIG_BRLAPI
+OBJS+=3D baum.o
+LIBS+=3D-lbrlapi
+endif
+
+ifdef CONFIG= _WIN32
+OBJS+=3Dtap-win32.o
+else
+OBJS+=3Dmi= gration-exec.o
+endif
+
+AUDIO_OBJS =3D audio= .o noaudio.o wavaudio.o mixeng.o
+ifdef CONFIG_SDL
+AUDIO_OBJS +=3D sdlaudio.o
+end= if
+ifdef CONFIG_OSS
+AUDIO_OBJS +=3D ossaudio.o
<= div>+endif
+ifdef CONFIG_COREAUDIO
+AUDIO_OBJS +=3D cor= eaudio.o
+AUDIO_PT =3D yes
+endif
+ifdef CONFIG_ALSA
<= div>+AUDIO_OBJS +=3D alsaaudio.o
+endif
+ifdef CONFIG_D= SOUND
+AUDIO_OBJS +=3D dsoundaudio.o
+endif
+= ifdef CONFIG_FMOD
+AUDIO_OBJS +=3D fmodaudio.o
+audio/audio.o audio/fmodaudio.= o: CPPFLAGS :=3D -I$(CONFIG_FMOD_INC) $(CPPFLAGS)
+endif
+ifdef CONFIG_ESD
+AUDIO_PT =3D yes
+AUDIO_PT_INT =3D= yes
+AUDIO_OBJS +=3D esdaudio.o
+endif
+ifdef CONFIG_P= A
+AUDIO_PT =3D yes
+AUDIO_PT_INT =3D yes
+AU= DIO_OBJS +=3D paaudio.o
+endif
+ifdef AUDIO_PT
+LDFLAGS +=3D -pthread
+endif
+ifdef AUDIO_PT_INT
+AUDIO_OBJS +=3D audio_= pt_int.o
+endif
+AUDIO_OBJS+=3D wavcapture.o
= +ifdef CONFIG_AUDIO
+OBJS+=3D$(addprefix audio/, $(AUDIO_OBJS))
+endif
+
+ifdef CONFIG_SDL
+OBJS+=3Dsdl.= o x_keymap.o
+endif
+ifdef CONFIG_CURSES
+OBJ= S+=3Dcurses.o
+endif
+OBJS+=3Dvnc.o d3des.o
+=
+ifdef CONFIG_COCOA
+OBJS+=3Dcocoa.o
+endif
<= div>+
+ifdef CONFIG_SLIRP
+CPPFLAGS+=3D-I$(SRC_PATH)/sl= irp
+SLIRP_OBJS=3Dcksum.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+= =3D$(addprefix slirp/, $(SLIRP_OBJS))
+endif
+
+LIBS+=3D$(VDE_LIBS)
+
+cocoa.o: cocoa.m
+
+sdl.o: sdl.c keymaps.c sdl_keysym.h
+
+sdl.o a= udio/sdlaudio.o: CFLAGS +=3D $(SDL_CFLAGS)
+
+vnc.o: vn= c.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
+
+vnc.o: CFLAGS +=3D $(CONFIG_VNC_TLS_CFLAGS)
+
+curses.o: curses.c keymaps.c curses_keys.h
+
= +bt-host.o: CFLAGS +=3D $(CONFIG_BLUEZ_CFLAGS)
+
+libqe= mu_common.a: $(OBJS)
+
+#########################################################= ##############
+# USER_OBJS is code used by qemu userspace emulat= ion
+USER_OBJS=3Dcutils.o  cache-utils.o
+
+libqemu_user.a: $(USER_OBJS)
+
+######################= ################################################
+
+qem= u-img$(EXESUF): qemu-img.o qemu-tool.o osdep.o $(BLOCK_OBJS)
+
+qemu-nbd$(EXESUF):  qemu-nbd.o qemu-tool.o osdep.o $(BLOC= K_OBJS)
+
+qemu-img$(EXESUF) qemu-nbd$(EXESUF): LIBS += =3D -lz
+
+
+clean:
+# avoid old bu= ild 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 \
+ $(MA= KE) -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=3Dda     en-gb  et  fr   &nbs= p; fr-ch  is  lt  modifiers  no  pt-br  sv \<= /div>
+ar      de     en-us  fi  fr-be  h= r     it  lv  nl         pl  r= u     th \
+common  de-ch  es     f= o  fr-ca  hu     ja  mk  nl-be     =  pt  sl     tr
+
+ifdef INSTALL_BLO= BS
+BLOBS=3Dbios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \=
+video.x openbios-sparc32 openbios-sparc64 openbios-ppc \
+p= xe-ne2k_pci.bin pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin \
+ba= mboo.dtb
+else
+BLOBS=3D
+endif
+
+install-doc: $(DOCS)
+ mkdir -p "$(DESTDIR)$(docdir)"
=
+ $(IN= STALL) -m 644 qemu-doc.html  qemu-tech.html "$(DESTDIR)$(docdir)&= quot;
+ifndef CONFIG_WIN32
+ mkdir -p "$(DESTDIR)$(mandir)/man1"<= /div>
+ $(INSTALL) -m 644 qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
+ mkdi= r -p "$(DESTDIR)$(mandir)/man8"
+ $(INSTALL) -m 644 qemu-nbd.8 &qu= ot;$(DESTDIR)$(mandir)/man8"
+endif
+
+install: all $(if $(BUILD_DOCS),install-= doc)
+ <= /span>mkdir -p "$(DESTDIR)$(bindir)"
+ifneq ($(TOOLS),)=
+ $(IN= STALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
+endif<= /div>
+ifneq ($(BLOBS),)
+ mkdir -p "$(DESTDIR)$(datadir)"
+ set = -e; for x in $(BLOBS); do \
+ $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x &qu= ot;$(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 &= quot;$(DESTDIR)$(datadir)/keymaps"; \
+ done=
+endif
+ for d in $(TARGET_DIRS); do \
+ $(MAKE) -C $$d $@ || exit= 1 ; \
+        done
+
+# various tes= t targets
+test speed: all
+ $(MAKE) -C tests $@
+
=
+TAGS:
+ etags *.[= ch] tests/*.[ch]
+
+cscope:
+ rm -f ./cscope.*
+ find . -= name "*.[ch]" -print | sed 's,^\./,,' > ./cscope.files=
+ csco= pe -b
+
+# documentation
+%.html: %.texi
+ tex= i2html -monolithic -number $<
+
+%.info: %.texi
+ makeinfo $< -o $@
+
+%.dvi: %.texi
+ texi2dvi $<
+
+qemu.1: qemu-doc.texi
+ $(SRC_PATH)/texi2pod.pl $< qemu.pod
+ pod2man --section=3D1 --center=3D&= quot; " --release=3D" " qemu.pod > $@
+
+qemu-img.1: qemu-img.texi
+ $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
+ pod2man --section=3D1 --ce= nter=3D" " --release=3D" " qemu-img.pod > $@
+
+qemu-nbd.8: qemu-nbd.texi
+ $(SRC_PATH)/texi2pod.pl $< qemu-nbd.pod
+ pod2man --section=3D8 --ce= nter=3D" " --release=3D" " qemu-nbd.pod > $@
+
+
= +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
+
+VE= RSION ?=3D $(shell cat VERSION)
+FILE =3D 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 .g= it --exclude .svn
+ rm -rf /tmp/$(FILE)
+
+# generate a binary distribution
+tarbin:
=
+ cd /= && tar zcvf ~/qemu-$(VERSION)-$(ARCH).tar.gz \
+ $(bindir)/qemu \
+ $(bi= ndir)/qemu-system-x86_64 \
+ $(bindir)/qemu-system-arm \
+ $(bindir)/qemu-sy= stem-cris \
+ $(bi= ndir)/qemu-system-m68k \
+ $(bindir)/qemu-system-mips \
+ $(bindir)/qemu-syst= em-mipsel \
+ $(bi= ndir)/qemu-system-mips64 \
+ $(bindir)/qemu-system-mips64el \
+ $(bindir)/qe= mu-system-ppc \
+ $(bi= ndir)/qemu-system-ppcemb \
+ $(bindir)/qemu-system-ppc64 \
+ $(bindir)/qemu-= system-sh4 \
+ $(bi= ndir)/qemu-system-sh4eb \
+ $(bindir)/qemu-system-sparc \
+ $(bindir)/qemu-= i386 \
+ $(bi= ndir)/qemu-x86_64 \
+ $(bindir)/qemu-alpha \
+ $(bindir)/qemu-arm \
+ $(bi= ndir)/qemu-armeb \
+ $(bindir)/qemu-cris \
+ $(bindir)/qemu-m68k \
+ $(bi= ndir)/qemu-mips \
+ $(bindir)/qemu-mipsel \
+ $(bindir)/qemu-ppc \
+ $(bi= ndir)/qemu-ppc64 \
+ $(bindir)/qemu-ppc64abi32 \
+ $(bindir)/qemu-sh4 \
+ $(bi= ndir)/qemu-sh4eb \
+ $(bindir)/qemu-sparc \
+ $(bindir)/qemu-sparc64 \
+ $(bi= ndir)/qemu-sparc32plus \
+ $(bindir)/qemu-img \
+ $(bindir)/qemu-nbd \
+ $(da= tadir)/bios.bin \
+ $(datadir)/vgabios.bin \
+ $(datadir)/vgabios-cirrus.bin = \
+ $(da= tadir)/ppc_rom.bin \
+ $(datadir)/video.x \
+ $(datadir)/openbios-sparc32 \
+ $(da= tadir)/openbios-sparc64 \
+ $(datadir)/openbios-ppc \
+ $(datadir)/pxe-ne2k= _pci.bin \
+ $(da= tadir)/pxe-rtl8139.bin \
+ $(datadir)/pxe-pcnet.bin \
+ $(datadir)/pxe-e1000.= bin \
+ $(do= cdir)/qemu-doc.html \
+ $(docdir)/qemu-tech.html \
+ $(mandir)/man1/qemu.1 \<= /div>
+ $(ma= ndir)/man1/qemu-img.1 \
+ $(mandir)/man8/qemu-nbd.8
+
+#= Include automatically generated dependency files
+-include $(wildcard .*.d audio/.*.d slirp/.*.d)
diff --excl= ude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/misc.c xen-4.1.2-b/too= ls/ioemu-qemu-xen/misc.c
--- xen-4.1.2-a/tools/ioemu-qemu-xen/mis= c.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 =3D=3D '\n' || c =3D=3D '\r'= || c =3D=3D ' ' || c =3D=3D '\t');
+}
= +
+int
+grub_tolower (int c)
+{
+ &= nbsp;if (c >=3D 'A' && c <=3D 'Z')
+    return c - 'A' + 'a';
+
=
+  return c;
+}
+
+
+char= *
+grub_strchr (const char *s, int c)
+{
+ &= nbsp;do
+    {
+      if (*s =3D=3D c)
+ return (= char *) s;
+    }
+  while (*s++);
=
+
+  return 0;
+}
+
+
+grub_size_t
+grub_strlen (const cha= r *s)
+{
+  const char *p =3D s;
+
=
+  while (*p)
+    p++;
+
+  return p - s;
+}
+
+
+
+
+
+char *
+grub_strncpy (char *dest, const char *src, int c)
+{
+  char *p =3D dest;
+
+  = ;while ((*p++ =3D *src++) !=3D '\0' && --c)
+    ;
+
+  return dest;
= +}
+
+char *
+grub_strdup (const char *s)
+{
+  grub_size_t len;
+  char *p;
+
+  len =3D grub_strlen (s) + 1;
+  p =3D (char *) malloc (len);
+  if (! p)
<= div>+    return 0;
+
+  return memcpy (p= , s, len);
+}
+
+
+
+char= *
+grub_strndup (const char *s, grub_size_t n)
+{
+  grub_size_t len;
+  char *p;
=
+
+  len =3D grub_strlen (s);
+  if (len= > n)
+    len =3D n;
+  p =3D (char = *) malloc (len + 1);
+  if (! p)
+    return 0;
+
+  memcpy (p, s, l= en);
+  p[len] =3D '\0';
+  return p;=
+}
+
+
+
+
+in= t
+grub_strcmp (const char *s1, const char *s2)
+{
+  while (*s1 && *s2)
+   &nb= sp;{
+      if (*s1 !=3D *s2)
+ break;
+<= /div>
+      s1++;
+      s2++;
+    }
+
+  return (int) *s1 - (int) *s2;
+}
+
= +int
+grub_strncmp (const char *s1, const char *s2, grub_size_t n= )
+{
+  if (n =3D=3D 0)
+    return 0;
+
+  while (*s1 &= ;& *s2 && --n)
+    {
+   &n= bsp;  if (*s1 !=3D *s2)
+ break;
+
+      s1++;
+     &nbs= p;s2++;
+    }
+
+  return (in= t) *s1 - (int) *s2;
+}
+
+
+int
+grub_strcasecmp (const char *s1, const char *s2)
+{
+  while (*s1 && *s2)
+   &nb= sp;{
+      if (grub_tolower (*s1) !=3D grub_tolow= er (*s2))
+ break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) grub_tolo= wer (*s1) - (int) grub_tolower (*s2);
+}
+
+<= /div>
+int
+grub_strncasecmp (const char *s1, const char *s2,= grub_size_t n)
+{
+  if (n =3D=3D 0)
+    return 0= ;
+
+  while (*s1 && *s2 && --n)
+    {
+      if (grub_tolower = (*s1) !=3D grub_tolower (*s2))
+ break;
+
+      s1++;
+     &nbs= p;s2++;
+    }
+
+  return (in= t) grub_tolower (*s1) - (int) grub_tolower (*s2);
+}
+<= /div>
+void *
+grub_memmove (void *dest, const void *src, gru= b_size_t n)
+{
+  char *d =3D (char *) dest;
+  cons= t char *s =3D (const char *) src;
+
+  if (d < = s)
+    while (n--)
+      *d+= + =3D *s++;
+  else
+    {
+      d +=3D n;
+      s +=3D= n;
+
+      while (n--)
+ *--d =3D *--s;=
+    }
+
+  return dest;
+}
+
+
+void *
+grub_malloc (g= rub_size_t size)
+{
+  void *ret;
+ &nbs= p;ret =3D malloc (size);
+  if (!ret)
+   &nb= sp;grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+  return ret;
+}
+
+
+
+void
+grub_free (void *ptr)
+{
+ &n= bsp;free (ptr);
+}
+
+
+void *
+grub_memset (void *s, int c, grub_size_t n)
+{
+  = ;unsigned char *p =3D (unsigned char *) s;
+
+  wh= ile (n--)
+    *p++ =3D (unsigned char) c;
+<= /div>
+  return s;
+}
+
+int
+grub_memcmp (const void *s1, = const void *s2, grub_size_t n)
+{
+  const char *t= 1 =3D s1;
+  const char *t2 =3D s2;
+
+ =  while (n--)
+    {
+      if (*t1 !=3D *t2)
+ re= turn (int) *t1 - (int) *t2;
+
+      t1+= +;
+      t2++;
+    }
+
+  return 0;
+}
+
+
+void *
+grub_zalloc (grub_size_t size)
+{
=
+  void *ret;
+
+  ret =3D grub_malloc (= size);
+  if (!ret)
+    return NULL;
+  m= emset (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 typic= ally implemented by hardware. The idea
+     is to get = the highest bit in N, 64 times, by keeping
+     upper(N * 2^i) =3D upper((Q * 10 + M) * 2^i), where up= per
+     represents the high 64 bits in 128-bits space= .  */
+  unsigned bits =3D 64;
+  unsign= ed long long q =3D 0;
+  unsigned m =3D 0;
+
+  /* Skip the slow computation if 32-bit arithmetic = is possible.  */
+  if (n < 0xffffffff)
+ =    {
+      if (r)
+ *r =3D ((grub_uint32= _t) n) % d;
+
+      return ((grub_uint32_t) n) / d;
+    }
+
+  while (bits--)
+    {
+      m <<=3D 1;
<= div>+
+      if (n & (1ULL << 63))
+ m |= =3D 1;
+
+      q <<=3D 1;
+      n <<=3D 1;
+
+   &n= bsp;  if (m >=3D d)
+ {
+ &nbs= p; q |=3D 1;
+   m -=3D d;
+ }
+    }
+
+  if (r)
+ &nbs= p;  *r =3D m;
+
+  return q;
+}
+
+
+
+/* Convert UTF-16 to UTF-8. &nb= sp;*/
+grub_uint8_t *
+grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
+                    gru= b_size_t size)
+{
+  grub_uint32_t code_high =3D 0= ;
+
+  while (size--)
+    {
+      grub_uint32_t code =3D *src++;
+
=
+      if (code_high)
+       =  {
+          if (code >=3D 0xDC= 00 && code <=3D 0xDFFF)
+         =    {
+              = /* Surrogate pair.  */
+              code =3D ((code_high= - 0xD800) << 12) + (code - 0xDC00) + 0x10000;
+
= +              *dest++ =3D (code >>= ; 18) | 0xF0;
+              *= dest++ =3D ((code >> 12) & 0x3F) | 0x80;
+              *dest++ =3D ((code &= gt;> 6) & 0x3F) | 0x80;
+         &nbs= p;    *dest++ =3D (code & 0x3F) | 0x80;
+   &n= bsp;        }
+         &= nbsp;else
+            {
= +              /* Error...  */
+              *dest++ =3D '?&#= 39;;
+            }
+
+          code_high =3D 0;
+ &nb= sp;      }
+      else
+ =        {
+          = if (code <=3D 0x007F)
+            *dest++ =3D code;
+          else if (code <=3D 0x07FF)
+            {
+     &n= bsp;        *dest++ =3D (code >> 6) | 0xC0;
=
+              *dest++ =3D (code &a= mp; 0x3F) | 0x80;
+            }
+    =      else if (code >=3D 0xD800 && code <=3D 0= xDBFF)
+            {
+ &= nbsp;            code_high =3D code;
+              continue;
+ &= nbsp;          }
+          else if (code >=3D 0xDC00 &= & code <=3D 0xDFFF)
+           &= nbsp;{
+              /* Error= ... */
+              *dest++ = =3D '?';
+            }
+          else
+       &= nbsp;    {
+             =  *dest++ =3D (code >> 12) | 0xE0;
+     &nbs= p;        *dest++ =3D ((code >> 6) & 0x3F) | = 0x80;
+              *dest++ = =3D (code & 0x3F) | 0x80;
+            }
+    =    }
+    }
+
+  re= turn dest;
+}
+
+
+
+
+
+
+static void print_byte(char *p, int len)
+{
+  printf("\n****************start print %s****= ****************\n", p);
+  int i;
+  un= signed char *pb =3D (unsigned char*)p;
+  for(i =3D 0; i <= ; len; i++)
+    {
+      printf("0x%02x,"= , pb[i]);
+    }
+  printf("\n*****= *****************end**************************\n");
+}
=
+
+
+
+#include   <iconv.h> 
+#define   OUTLE= N   256 
+
+
+//=B4=FA=C2=EB=D7=AA= =BB=BB:=B4=D3=D2=BB=D6=D6=B1=E0=C2=EB=D7=AA=CE=AA=C1=ED=D2=BB=D6=D6=B1=E0= =C2=EB 
+static int   code_convert(const char   *f= rom_charset, const char   *to_charset, 
+ &nb= sp;   char   *inbuf, size_t   inlen,
+    cha= r   *outbuf, size_t   outlen) 
+{ 
+  iconv_t   cd; 
+  int &= nbsp; rc; 
+  char   **pin   =3D   &= inbuf; 
+  char   **pout   =3D   &ou= tbuf; 
+
+  //printf("sizeof(int)=3D%d, = sizeof(size_t)=3D%d\n", sizeof(int), sizeof(size_t));
+  cd   =3D   iconv_open(to_charset, from_charset);&nbs= p;
+  if   (cd=3D=3D0)   return   -1; 
+  memset(outbuf, 0, outlen); 
+  if &nbs= p; (iconv(cd, pin, &inlen, pout, &outlen)=3D=3D-1)   return &n= bsp; -1; 
+  iconv_close(cd); 
+  return   0; = ;
+} 
+//UNICODE=C2=EB=D7=AA=CE=AAGB2312=C2=EB&nbs= p;
+int   u2g(char   *inbuf, size_t   inlen, char =   *outbuf, size_t  outlen) 
+{
+  r= eturn   code_convert("utf-8", "gb2312", inbuf, inl= en, outbuf, outlen); 
+} 
+//GB2312=C2=EB=D7=AA=CE=AAUNICODE=C2=EB 
+int   g2u(char   *inbuf, size_t   inlen, char   = *outbuf, size_t   outlen) 
+{ 
+  r= eturn   code_convert("gb2312", "utf-8", inbuf, inl= en, outbuf, outlen); 
+} 
+
+
+
+void test(void= ) 
+{
+  //=D7=D6=B7=FB=B1=E0=C2=EB=D7=AA=BB= =BB=3D=EF=BB=BF=E5?=E7=AC????=BD=AC??
+  char   in_utf8= []   =3D   {0xe5,0xad,0x97,0xe7,0xac,0xa6,0xe7,0xbc,0x96,0xe7,0xa= 0,0x81,0xe8,0xbd,0xac,0xe6,0x8d,0xa2}; 
+  char   *in_gb2312   =3D (char*)  "=D7=D6= =B7=FB=B1=E0=C2=EB=D7=AA=BB=BB"; 
+  char   o= ut[OUTLEN]; 
+  int rc;
+  //utf8=C2=EB= =D7=AA=CE=AAgb2312=C2=EB 
+  rc   =3D   u2g(i= n_utf8, strlen(in_utf8), out, OUTLEN); 
+  printf("utf8-->gb2312   out=3D%s\n", out);
<= div>+  print_byte(out, strlen(out));
+  //gb2312=C2=EB= =D7=AA=CE=AAutf8=C2=EB 
+  rc   =3D   g2u(in_= gb2312, strlen(in_gb2312), out, OUTLEN); 
+  print_byte= (out, strlen(out));
+  printf("gb2312-->utf8   out=3D%s\n",out);&nb= sp;
+} 
+
+
+
diff -= -exclude=3D.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 +08= 00
@@ -0,0 +1,89 @@
+#include "fs-types.h"
= +#include <stddef.h>
+
+
+
+<= /div>
+
+#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 cha= r *s);
+
+
+
+char *
+gru= b_strdup (const char *s);
+
+
+
+char *
+grub_strndup (const char *s, grub_size_t n);
+=
+
+char *
+grub_strncpy (char *dest, const c= har *src, int c);
+
+
+int
+grub_st= rcmp (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 *s= rc, grub_size_t n);
+
+int
+grub_memcmp (cons= t 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);
+
+voi= d
+grub_free (void *ptr);
+
+void *
+grub_zalloc (grub_size_t size);
+
+grub_uint64_t<= /div>
+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,
+                    gru= b_size_t size);
+
+
+//UNICODE=C2=EB=D7=AA=CE= =AAGB2312=C2=EB 
+int   u2g(char   *inbuf, size_t =   inlen, char   *outbuf, size_t   outlen);
+//GB2312=C2=EB=D7=AA=CE=AAUNICODE=C2=EB 
+int   g= 2u(char   *inbuf, size_t   inlen, char   *outbuf, size_t &nb= sp; outlen);
+
+
+
+void test(void)= ;
+
+
+
diff --exclude=3D.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-q= emu-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, I= nc.
+ *
+ *  This program is free software: you ca= n redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as publ= ished 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 wil= l be useful,
+ *  but WITHOUT ANY WARRANTY; without even the= implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A P= ARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with this program.  If not, see &l= t;http://www.gnu.org/licenses/= >.
+ */
+
+
+#include "misc.h"
+#include "fshelp.h"
+#include "ntfs.h&quo= t;
+#include "debug.h"
+#include "grub_e= rr.h"
+#include "err.h"
+
+#define GRUB_DISK_S= ECTOR_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(BlockDr= iverState *bs, int64_t offset,
+  void *buf1, int count1)
+{
+  return bdrv_pread(bs, s_part_off_sector * s_bpb_b= ytes_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))
+    retu= rn grub_error (GRUB_ERR_BAD_FS, "%s label not found", magic);
+
+  ss =3D u16at (buf, 6) - 1;
+  if = (ss * (int) data->blocksize !=3D len * GRUB_DISK_SECTOR_SIZE)
+    return grub_error (GRUB_ERR_BAD_FS, "size not matc= h",
+        ss * (int) data->blocksize,
<= div>+ &nbs= p;      len * GRUB_DISK_SECTOR_SIZE);
+  pu =3D buf + u16at (buf, 4);
+  us =3D u16at (p= u, 0);
+  buf -=3D 2;
+  while (ss > 0)
+    {
+      buf +=3D data->= blocksize;
+      pu +=3D 2;
+   &n= bsp;  if (u16at (buf, 0) !=3D us)
+ retu= rn grub_error (GRUB_ERR_BAD_FS, "fixup signature not match");
+      v16at (buf, 0) =3D 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,
+ &n= bsp;    void (*read_hook) (grub_disk_addr_t sector,
+ unsigne= d offset,
+ unsi= gned length,
+ void *closure),
+      void *closure);
+
+static grub_err_t read_data (struct grub_ntfs_attr *at, c= har *pa, char *dest,
+      grub_disk_addr_t ofs, grub_size= _t len,
+  &= nbsp;   int cached,
+      void (*read_hook) (grub_dis= k_addr_t sector,
+ unsigned offset,
+ unsigned length,
+ void *closure),
+      void *closur= e);
+
+static void
+init_attr (struct grub_ntfs_attr *= at, struct grub_ntfs_file *mft)
+{
+  at->mft = =3D mft;
+  at->flags =3D (mft =3D=3D &mft->data-&= gt;mmft) ? AF_MMFT : 0;
+  at->attr_nxt =3D mft->buf + u16at (mft->buf, 0x14);
+  at->attr_end =3D at->emft_buf =3D at->edat_buf = =3D at->sbuf =3D NULL;
+}
+
+static void
+free_attr (struct grub_ntfs_attr *at)
+{
+  grub_free (at->emft_buf);
+  gr= ub_free (at->edat_buf);
+  grub_free (at->sbuf);
=
+}
+
+static char *
+find_attr (struct g= rub_ntfs_attr *at, unsigned char attr)
+{
+  grub_off_t off_bytes1;
+  grub_off= _t off_bytes2;
+  if (at->flags & A= F_ALST)
+    {
+      DBG(&quo= t;!!!!!!\nin a attr list=3D=3D=3D=3D=3D=3D");
+    retry:
+      while (at->at= tr_nxt < at->attr_end)
+ {
+   at->attr_cur =3D at->att= r_nxt;
+ &nbs= p; at->attr_nxt +=3D u16at (at->attr_cur, 4);
+   if ((= (unsigned char) *at->attr_cur =3D=3D attr) || (attr =3D=3D 0))
+ &nbs= p;   {
+       char *new_pos;
+
+ &nb= sp;     if (at->flags & AF_MMFT)
+ {
+   DBG("in AF_MMFT......");
+   off_bytes1 = =3D (grub_off_t)(v32at (at->attr_cur, 0x10)) << BLK_SHR;
+ &nb= sp; off_bytes2 =3D (grub_off_t)(v32at (at->attr_cur, 0x14)) <<= ; BLK_SHR;
+   if ((bdrv_pread
+ &nb= sp;      (at->mft->data->bs, off_bytes1,
= + at->= emft_buf, 512))
+  &n= bsp;    ||
+       (bdrv_pread
+   =     (at->mft->data->bs, off_bytes2,
+ at= ->emft_buf + 512, 512)))
+     return NULL;
+
+   if (fixup
+ &nb= sp;     (at->mft->data, at->emft_buf, at->mft-&g= t;data->mft_size,
+        (char*)"FILE"))=
+ &nb= sp;   return NULL;
+ }
+       else
+ {
+   DBG("read extend mft FR=3D=3D=3D=3D=3D=3D");
+  = ; if (read_mft (at->mft->data, at->emft_buf,
+ u= 32at (at->attr_cur, 0x10)))
+     return NULL;
= + }
+
+=       new_pos =3D &at->emft_buf[u16at (a= t->emft_buf, 0x14)];
+       while ((unsigned char) *= new_pos !=3D 0xFF)
+ {
+   DBG("new pos in extend mft=3D=3D=3D=3D=3D=3D");
+ &n= bsp; if (((unsigned char) *new_pos =3D=3D
+ &nb= sp;      (unsigned char) *at->attr_cur)
+    &n= bsp;  && (u16at (new_pos, 0xE) =3D=3D u16at (at->attr_cur, = 0x18)))
+ &nb= sp;   {
+       return new_pos;
+   = ;  }
+ &nb= sp; new_pos +=3D u16at (new_pos, 4);
+ }
+       gr= ub_error (GRUB_ERR_BAD_FS,
+ &n= bsp; "can\'t find 0x%X in attribute list",
+  &nbs= p;(unsigned char) *at->attr_cur);
+ &nbs= p;     return NULL;
+     }
+ }
+      return NULL;
+    }
+
+
+  DBG("not in a attr list=3D=3D=3D=3D= =3D=3D");
+  at->attr_cur =3D at->attr_nxt;
=
+  while ((unsigned char) *at->attr_cur !=3D 0xFF)
+    {
+      at->attr_nxt +=3D = u16at (at->attr_cur, 4);
+      if ((unsigned c= har) *at->attr_cur =3D=3D AT_ATTRIBUTE_LIST)
+ at->attr_end =3D at->= ;attr_cur;
+      if (((unsigned char) *at->attr_cur =3D=3D att= r) || (attr =3D=3D 0))
+ {
+   DBG("found=3D=3D=3D=3D=3D=3D&= quot;);
+ &nbs= p; return at->attr_cur;
+ }
+      at->a= ttr_cur =3D at->attr_nxt;
+    }
+  
+  
+ &nb= sp;if (at->attr_end)
+    {
+    = ;  DBG("searching in attr list=3D=3D=3D=3D=3D=3D");
+      char *pa;
+
+     &nb= sp;at->emft_buf =3D grub_malloc (at->mft->data->mft_size <&l= t; BLK_SHR);
+      if (at->emft_buf =3D=3D NULL)
+ return NULL;
+
+      pa =3D at->attr_end;
+      if (pa[8])
+ {
+          int n;
+
+ &nb= sp;        n =3D ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_= SIZE - 1)
+               &= ; (~(GRUB_DISK_SECTOR_SIZE - 1)));
+   at->attr_cur =3D at->= attr_end;
+ &nbs= p; at->edat_buf =3D grub_malloc (n);
+   if (!at->edat_= buf)
+ <= /span>    return NULL;
+ &nbs= p; if (read_data (at, pa, at->edat_buf, 0, n, 0, 0, 0))
+=  &nbs= p;  {
+       grub_error (GRUB_ERR_BAD_FS,
+ &n= bsp; "fail to read non-resident attribute list");
= +  &nb= sp;    return NULL;
+ &nbs= p;   }
+   at->attr_nxt =3D at->edat_buf;
+  &= nbsp;at->attr_end =3D at->edat_buf + u32at (pa, 0x30);
+ }
+      else
+ {
+   at->attr_nxt =3D at-&= gt;attr_end + u16at (pa, 0x14);
+ &nbs= p; at->attr_end =3D at->attr_end + u32at (pa, 4);
+ }
+=      at->flags |=3D AF_ALST;
+      while (at->attr_nxt < at->attr_end)
+ {<= /div>
+   if (((unsigned char) *at->attr_nxt =3D=3D attr) || (attr = =3D=3D 0))
+ &nbs= p;   break;
+   at->attr_nxt +=3D u16at (at->attr_= nxt, 4);
+ }
+      if (at->attr_nxt >=3D at->attr_end)
+ {<= /div>
+   DBG("not found in list");
+ &nbs= p; return NULL;
+ }
+      DBG("found in = attr list=3D=3D=3D=3D=3D=3D");
+      if ((at->flags & AF_MMFT) && (att= r =3D=3D AT_DATA))
+ {
+   DBG("AF_GPOS!!!!!!=3D=3D=3D=3D=3D= =3D");
+ &nbs= p; at->flags |=3D AF_GPOS;
+   at->attr_cur =3D at->= attr_nxt;
+   pa =3D at->attr_cur;
+ &nbs= p; v32at (pa, 0x10) =3D at->mft->data->mft_start;
+=  &nbs= p;v32at (pa, 0x14) =3D at->mft->data->mft_start + 1;
+ &nbs= p; pa =3D at->attr_nxt + u16at (pa, 4);
+   while (pa <= at->attr_end)
+  &nb= sp;  {
+       if ((unsigned char) *pa !=3D attr)
+ break;
+ &nbs= p;     if (read_attr
+   (at, pa + 0x10,
+  &= nbsp; u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR= ),
+ &nb= sp;  at->mft->data->mft_size << BLK_SHR, 0, 0, 0))
+ re= turn NULL;
+ &nbs= p;     pa +=3D u16at (pa, 4);
+     }
+  &= nbsp;at->attr_nxt =3D at->attr_cur;
+ &nbs= p; at->flags &=3D ~AF_GPOS;
+ }
+      =
+      DBG("goto retry=3D=3D=3D=3D=3D=3D&quo= t;);
+      goto retry;
+    }
+
+  DBG("return NULL");
+  return= NULL;
+}
+
+static char *
+locate_= attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
+ &nbs= p;    unsigned char attr)
+{
+  
+
+  char *pa;
+  
+  init_= attr (at, mft);
+
+  DBG("\n!!!!!!\nlocating attr=3D0x%02x, at->flag=3D0x%02x=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D",
+      at= tr, at->flags);
+  if ((pa =3D find_attr (at, attr)) =3D= =3D NULL)
+    {
+      DBG(&q= uot;1=3D=3D=3D=3D=3D=3D=3D=3D=3Dnot found");
+      return NULL;
+    }
+  if ((at->flags & AF_ALST) =3D=3D 0)
+   &nb= sp;{
+      DBG("2=3D=3D=3D=3D=3D=3D=3Dnot a = attr list, continue searching");
+      while= (1)
+ {
+ &= nbsp; if ((pa =3D find_attr (at, attr)) =3D=3D NULL)
+    &nb= sp;break;
+ &nbs= p; if (at->flags & AF_ALST)
+     {
+   =    DBG("3=3D=3D=3D=3D=3D=3D=3D=3D=3D=3Din a attr list,found= ");
+ &nbs= p;     return pa;
+     }
+ }
+      DBG("4=3D=3D=3D=3D=3D=3D=3D=3Dstart searchi= ng all over again");
+      grub_errno =3D GR= UB_ERR_NONE;
+      free_attr (at);
+ &n= bsp;    init_attr (at, mft);
+      pa = =3D find_attr (at, attr);
+    }
+  DBG("locate finish=3D=3D=3D=3D= =3D=3D\n\n");
+  return pa;
+}
+
+static char *
+read_run_data (char *run, int nn, grub_di= sk_addr_t * val, int sig)
+{
+  grub_disk_addr_t r, v;
+
+ &n= bsp;r =3D 0;
+  v =3D 1;
+
+  while= (nn--)
+    {
+      r +=3D v= * (*(unsigned char *) (run++));
+      v <<= =3D 8;
+    }
+
+  if ((sig) && (r= & (v >> 1)))
+    r -=3D v;
+
+  *val =3D r;
+  return run;
+}
<= div>+
+grub_err_t
+grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
+{
+  DBG("read run list");
+
+  in= t c1, c2;
+  grub_disk_addr_t val;
+  char *r= un;
+
+  run =3D ctx->cur_run;
+retry:
+  c= 1 =3D ((unsigned char) (*run) & 0xF);
+  c2 =3D ((unsign= ed char) (*run) >> 4);
+  if (!c1)
+   =  {
+      if ((ctx->attr) && (ctx-= >attr->flags & AF_ALST))
+ {
+ &= nbsp; void (*save_hook) (grub_disk_addr_t sector,
+    &nbs= p; unsigned offset,
+ &n= bsp;    unsigned length,
+      void *closure);
+ =   
+ &nbs= p; //save_hook =3D ctx->comp.bs->read_hook;
+   //ctx-&= gt;comp.bs->read_hook =3D 0;
+ &nbs= p; run =3D find_attr (ctx->attr, (unsigned char) *ctx->attr->= attr_cur);
+   //ctx->comp.bs->read_hook =3D save_hook;
+ &nbs= p; if (run)
+     {
+       if (run[8= ] =3D=3D 0)
+ ret= urn grub_error (GRUB_ERR_BAD_FS,
+    "$DATA should be non= -resident");
+
+=       run +=3D u16at (run, 0x20);
+   =    ctx->curr_lcn =3D 0;
+  &nb= sp;    goto retry;
+     }
+ }
+      return grub_error (GRUB_ERR_BAD_FS, "run li= st overflown");
+    }
+  run =3D r= ead_run_data (run + 1, c1, &val, 0); /* length of current VCN */
+  ctx->curr_vcn =3D ctx->next_vcn;
+  ctx-&= gt;next_vcn +=3D val;
+  run =3D read_run_data (run, c2, &am= p;val, 1); = /* offset to previous LCN */
+  ctx->curr_lcn +=3D val;
+  if (val =3D=3D 0)=
+    ctx->flags |=3D RF_BLNK;
+  els= e
+    ctx->flags &=3D ~RF_BLNK;
+ &nb= sp;ctx->cur_run =3D run;
+  return 0;
+}
+
+static grub_disk_addr_t
+grub_ntfs= _read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
+{<= /div>
+  struct grub_ntfs_rlst *ctx;
+
+  = ;ctx =3D (struct grub_ntfs_rlst *) node;
+  if (block >=3D ctx->next_vcn)
+    {=
+      if (grub_ntfs_read_run_list (ctx))
+ return= -1;
+      return ctx->curr_lcn;
+    }
+  else
+    retur= n (ctx->flags & RF_BLNK) ? 0 : (block -
+  ctx->curr_vcn = + ctx->curr_lcn);
+}
+
+static grub_err_t
+read_data (struct gr= ub_ntfs_attr *at, char *pa, char *dest,
+    grub_disk_addr_t ofs,= grub_size_t len, int cached,
+ &nbs= p;  void (*read_hook) (grub_disk_addr_t sector,
+     =  unsigned offset,
+  &= nbsp;    unsigned length,
+       void *clos= ure),
+ =    void *closure)
+{
+  grub_disk_addr_t vcn;
+  struct gr= ub_ntfs_rlst cc, *ctx;
+
+  if (len =3D=3D 0)
+    return 0;
+
+  grub_memset (&= amp;cc, 0, sizeof (cc));
+  ctx =3D &cc;
+  ctx->attr =3D at;
<= div>+  ctx->comp.spc =3D at->mft->data->spc;
+ &= nbsp;ctx->comp.bs =3D at->mft->data= ->bs;
+
+  if (pa[8] =3D=3D 0)
+    {
+ &nb= sp;    if (ofs + len > u32at (pa, 0x10))
+ return grub_error (G= RUB_ERR_BAD_FS, "read out of range");
+      grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, = len);
+      return 0;
+    }<= /div>
+
+  if (u16at (pa, 0xC) & FLAG_COMPRESSED)
+    ctx->flags |=3D RF_COMP;
+  else
+    ctx->flags &=3D ~RF_COMP;=
+  ctx->cur_run =3D pa + u16at (pa, 0x20);
+
+  if (ctx->flags & RF_COMP)
+    = {
+      if (!cached)
+ retu= rn grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed&qu= ot;);
+
+      if (at->sbuf)
+ {
+ &nbs= p; if ((ofs & (~(COM_LEN - 1))) =3D=3D at->save_pos)
= +  &nb= sp;  {
+       grub_disk_addr_t n;
+
+=       n =3D COM_LEN - (ofs - at->save_pos);<= /div>
+       if (n > len)
+ n = =3D len;
+
+       grub_memcpy (dest, at->s= buf + ofs - at->save_pos, n);
+ &nbs= p;     if (n =3D=3D len)
+ return 0;
+
+=  &nbs= p;    dest +=3D n;
+ &nbs= p;     len -=3D n;
+       ofs +=3D n;
+ &= nbsp;   }
+ }
+      else
+ {
+   at->sbuf =3D grub_mal= loc (COM_LEN);
+ &nbs= p; if (at->sbuf =3D=3D NULL)
+     return grub_errno;=
+   at->save_pos =3D 1;
+ }
+
+      vcn =3D ctx->target_vcn =3D (o= fs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc);
+  =    ctx->target_vcn &=3D ~0xF;
+    }
+  else
+    vcn = =3D ctx->target_vcn =3D grub_divmod64 (ofs >> BLK_SHR, ctx->com= p.spc, 0);
+
+  ctx->next_vcn =3D u32at (pa, 0x= 10);
+  ctx->curr_lcn =3D 0;
+  while (ctx->next_vcn <=3D ctx->target_vcn)
= +    {
+      if (grub_ntfs_read_run_lis= t (ctx))
+ return grub_errno;
+    }
+
+  if (at->flags & = AF_GPOS)
+    {
+      grub_di= sk_addr_t st0, st1;
+      grub_uint32_t m;
<= div>+
+      grub_divmod64 (ofs >> BLK_SHR, = ctx->comp.spc, &m);
+
+      st0 =3D
+ (ctx->target_vcn - ctx-&= gt;curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
+   =    st1 =3D st0 + 1;
+      if (st1 =3D=3D
+   (ctx->next_vcn - = ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
+ {
+ &nbs= p; if (grub_ntfs_read_run_list (ctx))
+     return grub_= errno;
+=   st1 =3D ctx->curr_lcn * ctx->comp.spc;
+ }
+      v32at (dest, 0) =3D st0;
+   &= nbsp;  v32at (dest, 4) =3D 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,
+ &n= bsp;      read_hook, closure, ofs, len, dest,
+   = ;     grub_ntfs_read_block, ofs + len, pow);
+      return grub_errno;
+    }
+
+  return (grub_ntfscomp_func) ? grub_ntfscomp_fun= c (at, dest, ofs, len, ctx,
+     vcn) :
+    grub_error (GRUB_ERR_BAD_FS, "ntfscomp module not = loaded");
+}
+
+static grub_err_t
<= div>+read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs= ,
+ &nbs= p;  grub_size_t len, int cached,
+    void (*read_hook) (grub= _disk_addr_t sector,
+ &n= bsp;     unsigned offset,
+       unsig= ned length,
+       void *closure),
+ &nbs= p;  void *closure)
+{
+  DBG("read attr&= quot;);
+  
+  char *save_cur;
+ &n= bsp;unsigned char attr;
+  char *pp;
+  grub_err_t ret;
+
+=  save_cur =3D at->attr_cur;
+  at->attr_nxt =3D = at->attr_cur;
+  attr =3D (unsigned char) *at->attr_nx= t;
+  if (at->flags & AF_ALST)
+    {
+      char *pa;
+=      grub_disk_addr_t vcn;
+
+   &= nbsp;  vcn =3D grub_divmod64 (ofs, at->mft->data->spc <<= ; BLK_SHR, 0);
+      pa =3D at->attr_nxt + u16= at (at->attr_nxt, 4);
+      while (pa < at->attr_end)
+ {
+   = if ((unsigned char) *pa !=3D attr)
+ &nbs= p;   break;
+   if (u32at (pa, 8) > vcn)
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre">   = ;  break;
+ &nbs= p; at->attr_nxt =3D pa;
+   pa +=3D u16at (pa, 4);
+ }
+    }
+  pp =3D find_attr (at, attr);
<= div>+  if (pp)
+    ret =3D read_data (at, pp, des= t, ofs, len, cached, read_hook, closure);
+  else
= +    ret =3D
+      (grub_errno) ? grub_= errno : grub_error (GRUB_ERR_BAD_FS,
+ =       "attribute not found");
+ &nb= sp;at->attr_cur =3D save_cur;
+  return ret;
+}=
+
+static grub_err_t
+read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno= )
+{
+  if (read_attr
+     &n= bsp;(&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-&= gt;mft_size, (char*)"FILE");
+}
+
+static grub_err_t
+init_file (stru= ct grub_ntfs_file *mft, grub_uint32_t mftno)
+{
+  = ;DBG("init file");
+  
+  unsigned = short flag;
+
+  mft->inode_read =3D 1;
+
+ =  mft->buf =3D grub_malloc (mft->data->mft_size << BLK_S= HR);
+  if (mft->buf =3D=3D NULL)
+   &nbs= p;return grub_errno;
+
+  if (read_mft (mft->data, mft->buf, mftno))
<= div>+    return grub_errno;
+
+  flag = =3D u16at (mft->buf, 0x16);
+  if ((flag & 1) =3D=3D = 0)
+    return grub_error (GRUB_ERR_BAD_FS, "MFT 0= x%X is not in use", mftno);
+
+  if ((flag & 2) =3D=3D 0)
+   &n= bsp;{
+      char *pa;
+
+ &nb= sp;    pa =3D locate_attr (&mft->attr, mft, AT_DATA);
+      if (pa =3D=3D NULL)
+ return grub_error (GRUB_ER= R_BAD_FS, "no $DATA in MFT 0x%X", mftno);
+
+      if (!pa[8])
+ mft->size =3D u32a= t (pa, 0x10);
+      else
+ mft->size =3D u64a= t (pa, 0x30);
+
+      if ((mft->attr.flags & AF_ALS= T) =3D=3D 0)
+ mft->attr.attr_end =3D 0; /*  Don't jump to attribute list *= /
+    }
+  else
+    init_= attr (&mft->attr, mft);
+
+  return 0;
+}
+
+static void
+free_file (struct gr= ub_ntfs_file *mft)
+{
+  free_attr (&mft->attr);
+  grub_= free (mft->buf);
+}
+
+static int
+list_file (struct grub_ntfs_file *diro, char *pos,
+    int (*h= ook) (const char *filename,
+ en= um grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node,
+ void *clos= ure),
+ &nbs= p;  void *closure)
+{
+  char *np;
= +  int ns;
+
+  while (1)
+   =  {
+      char *ustr, namespace;
+      char* gbstr;
+
+   &nbs= p;  if (pos[0xC] & 2) /* end signature */
+ break;
+
+      np =3D pos + 0x50;
+  = ;    ns =3D (unsigned char) *(np++);
+     &n= bsp;namespace =3D *(np++);
+
+      /*
+       *  Ignore files in DOS namespace, as t= hey will reappear as Win32
+       *  names.
+      = */
+      if ((ns) && (namespace !=3D 2))=
+ {
+   enum grub_fshelp_filetype type;
+ &nbs= p; struct grub_ntfs_file *fdiro;
+
+   if (u16at (p= os, 4))
+     {
+ &nbs= p;     grub_error (GRUB_ERR_BAD_FS, "64-bit MFT number&= quot;);
+       return 0;
+ &nbs= p;   }
+
+   type =3D
+     (u= 32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR :
+ &nbs= p;   GRUB_FSHELP_REG;
+
+   fdiro =3D grub_zal= loc (sizeof (struct grub_ntfs_file));
+ &nbs= p; if (!fdiro)
+     return 0;
+
+   = fdiro->data =3D diro->data;
+ &nbs= p; fdiro->ino =3D u32at (pos, 0);
+
+   ustr =3D= grub_malloc (ns * 4 + 1);
+ &nbs= p; gbstr =3D grub_malloc(ns * 2 + 1);
+     if (ustr =3D= =3D NULL || gbstr =3D=3D NULL)
+  &nb= sp;  return 0;
+   *grub_utf16_to_utf8 ((grub_uint8_t *) ustr= , (grub_uint16_t *) np,
+ &n= bsp;      ns) =3D '\0';
+   u2g(ustr, strle= n(ustr), gbstr, ns * 2 + 1);
+  &nb= sp;DBG("gbstr=3D%s", gbstr);
+       &nb= sp;  if (namespace)
+           &nb= sp;type |=3D GRUB_FSHELP_CASE_INSENSITIVE;
+
+   if (hoo= k (gbstr, type, fdiro, closure))
+ &nbs= p;   {
+       grub_free (ustr);
+   =    grub_free (gbstr);
+ &nbs= p;     return 1;
+     }
+   grub_fre= e(gbstr);
+ &nbs= p; grub_free (ustr);
+ }
+      pos +=3D u16= at (pos, 8);
+    }
+  return 0;
+}
+
+static int
=
+grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
+      =   int (*hook) (const char *filename,
+ &= nbsp;   enum grub_fshelp_filetype filetype,
+    &nbs= p;grub_fshelp_node_t node,
+  =    void *closure),
+        void *closure)
+{
+  unsigned char *bitmap;
+  struct grub_ntfs_attr attr, *at;
+  char *cur_p= os, *indx, *bmp;
+  int ret =3D 0;
+  grub_si= ze_t bitmap_len;
+  struct grub_ntfs_file *mft;
+<= /div>
+  mft =3D (struct grub_ntfs_file *) dir;
+
+  if (!mft->inode_read)
+    = {
+      if (init_file (mft, mft->ino))
+ return= 0;
+    }
+
+  indx =3D NULL;
+  bmp =3D NULL;
+
+  at =3D &attr;
+  init_attr (at, mf= t);
+  while (1)
+    {
+ &nbs= p;    if ((cur_pos =3D find_attr (at, AT_INDEX_ROOT)) =3D=3D NULL= )
+ {
+ &= nbsp; grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
<= div>+  = ; goto done;
+ }
+
+      /* Resident, Namelen=3D4, Offset= =3D0x18, Flags=3D0x00, Name=3D"$I30" */
+    =  if ((u32at (cur_pos, 8) !=3D 0x180400) ||
+ &nbs= p; (u32at (cur_pos, 0x18) !=3D 0x490024) ||
+   (u32at (cur_p= os, 0x1C) !=3D 0x300033))
+ cont= inue;
+      cur_pos +=3D u16at (cur_pos, 0x14);
+      if (*cur_pos !=3D 0x30) /* Not filename index */
+ cont= inue;
+      break;
+    }
+
+  cur_pos +=3D 0x10; /* Skip index root */
+  ret =3D list_file (mft, cur_pos + u16at (cur_pos, 0), hook, cl= osure);
+  if (ret)
+    goto done;
+    
+
+  bitmap =3D NULL;
<= div>+  bitmap_len =3D 0;
+  free_attr (at);
+  init_attr (at, mft);
+  while ((cur_pos =3D fin= d_attr (at, AT_BITMAP)) !=3D NULL)
+    {
+ &= nbsp;    int ofs;
+
+      ofs= =3D (unsigned char) cur_pos[0xA];
+      /* Namel= en=3D4, Name=3D"$I30" */
+      if ((cur_pos[9] =3D=3D 4) &&
+=  &nbs= p;(u32at (cur_pos, ofs) =3D=3D 0x490024) &&
+   (u32at (c= ur_pos, ofs + 4) =3D=3D 0x300033))
+ {
+          int is_resident =3D (cur_pos[8]= =3D=3D 0);
+
+          bitma= p_len =3D ((is_resident) ? u32at (cur_pos, 0x10) :
+                     &nb= sp;  u32at (cur_pos, 0x28));
+
+     &nb= sp;    bmp =3D grub_malloc (bitmap_len);
+    = ;      if (bmp =3D=3D NULL)
+      =      goto done;
+
+   if (is_resident)
+ &nbs= p;   {
+             &nbs= p;grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)),
+=                     &nbs= p;     bitmap_len);
+  &nb= sp;  }
+          else
+ =            {
+      =        if (read_data (at, cur_pos, bmp, 0, bitmap_len,= 0, 0, 0))
+               &nb= sp;{
+                  grub_e= rror (GRUB_ERR_BAD_FS,
+            = ;                  "fails= to read non-resident $BITMAP");
+       &nbs= p;          goto done;
+     &= nbsp;          }
+              bitmap_len =3D u32at (cur= _pos, 0x30);
+            }
+
+          bitmap =3D (unsigned cha= r *) bmp;
+   break;
+ }
+    }
+
+  free_attr (at);
+  cur_pos =3D locate_attr (at, mft, AT_INDEX_ALLOCATION);
=
+  while (cur_pos !=3D NULL)
+    {
+      /* Non-resident, Name= len=3D4, Offset=3D0x40, Flags=3D0, Name=3D"$I30" */
+ &= nbsp;    if ((u32at (cur_pos, 8) =3D=3D 0x400401) &&
+ &nb= sp; (u32at (cur_pos, 0x40) =3D=3D 0x490024) &&
+ &nbs= p; (u32at (cur_pos, 0x44) =3D=3D 0x300033))
+ break;
+  =    cur_pos =3D find_attr (at, AT_INDEX_ALLOCATION);
+    }
+
+  if ((!cur_pos) &&am= p; (bitmap))
+    {
+      gru= b_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION");
+      goto done;
+    }
+
+  if (bitmap)
+ &nbs= p;  {
+      grub_disk_addr_t v, i;
+
+      indx =3D grub_malloc (mft->data->i= dx_size << BLK_SHR);
+      if (indx =3D=3D = NULL)
+ goto= done;
+
+      v =3D 1;
+ &nb= sp;    for (i =3D 0; i < (grub_disk_addr_t)bitmap_len * 8; i++= )
+ {
+ &nbs= p; if (*bitmap & v)
+     {
+      &= nbsp;if ((read_attr
+ &nb= sp;  (at, indx, i * (mft->data->idx_size << BLK_SHR),
+ &n= bsp;   (mft->data->idx_size << BLK_SHR), 0, 0, 0))
+ &nb= sp; || (fixup (mft->data, indx, mft->data->idx_size, (char*)&= quot;INDX")))
+ goto done;
+ &nbs= p;     ret =3D list_file (mft, &indx[0x18 + u16at (indx,= 0x18)], hook,
+        closure);
+ &nbs= p;     if (ret)
+ goto done;
+     }
+ &nbs= p; v <<=3D 1;
+   if (v >=3D 0x100)
+    &n= bsp;{
+ &nbs= p;     v =3D 1;
+       bitmap++;
+  =    }
+ }
+    }
+
+done:
+  fre= e_attr (at);
+  grub_free (indx);
+  grub_fre= e (bmp);
+
+  return ret;
+}
+
+
+st= ruct grub_ntfs_data *
+grub_ntfs_mount (BlockDriverState* bs, gru= b_uint32_t part_off_sector)
+{
+  struct grub_ntfs= _bpb bpb;
+  struct grub_ntfs_data *data =3D 0;
+  grub_off_= t off_bytes =3D (grub_off_t)part_off_sector << BLK_SHR; 
+  
+  if (!bs)
+    goto fail;<= /div>
+
+  data =3D (struct grub_ntfs_data *) grub_zallo= c (sizeof (*data));
+  if (!data)
+    goto fail;
+
+  data->bs =3D bs;
+
+  /* Read th= e BPB.  */
+  if (bdrv_pread (bs, off_bytes, &bpb, = sizeof (bpb)) !=3D sizeof(bpb))
+    {
+      DBG("read bpb er= r!");
+      goto fail;
+   &n= bsp;}
+  if (grub_memcmp ((char *) &bpb.oem_name, "= NTFS", 4))
+    {
+      = DBG("bpb.oem_name=3D%s, not ntfs", bpb.oem_name);
+      goto fail;
+    }
= +  data->blocksize =3D grub_le_to_cpu16 (bpb.bytes_per_sector);
+  data->spc =3D bpb.sectors_per_cluster * (data->blocksi= ze >> BLK_SHR);
+
+  if (bpb.clusters_per_mft > 0)
+    data= ->mft_size =3D data->spc * bpb.clusters_per_mft;
+  el= se
+    data->mft_size =3D 1 << (-bpb.clusters= _per_mft - BLK_SHR);
+
+  if (bpb.clusters_per_index > 0)
+   &= nbsp;data->idx_size =3D data->spc * bpb.clusters_per_index;
+  else
+    data->idx_size =3D 1 << (-b= pb.clusters_per_index - BLK_SHR);
+
+  data->mft_start =3D grub_le_to_cpu64 (bpb.mft_l= cn) * data->spc;
+
+  if ((data->mft_size &g= t; MAX_MFT) || (data->idx_size > MAX_IDX))
+    g= oto fail;
+
+  data->mmft.data =3D data;
+  data->= ;cmft.data =3D data;
+
+  data->mmft.buf =3D gr= ub_malloc (data->mft_size << BLK_SHR);
+  if (!data= ->mmft.buf)
+    goto fail;
+
+  s_bpb_bytes_per_sec= tor =3D (bpb.bytes_per_sector);
+  s_part_off_sector =3D par= t_off_sector;
+  DBG("bpb.bytes_per_sector=3Dblocksize= =3D%u\n"
+      "bpb.sector_per_cluster= =3D%u\n"
+      "data->blocksize=3D%u\n"
= +      "data->spc=3D%u\n"
+   &n= bsp;  "bpb.clusters_per_mft=3D%d\n"
+    = ;  "data->mft_size=3D%u\n"
+     &nbs= p;"bpb.total_sectors=3D%zd\n"
+      "bpb.mft_lcn=3D%zd\n"
+ &nbs= p;    "data->mft_start=3D%u\n",
+   &= nbsp;  (bpb.bytes_per_sector), (bpb.sectors_per_cluster),
+ =      (data->blocksize), (data->spc),
+      (bpb.clusters_per_mft), (data->mft_size),
+      (bpb.num_total_sectors),
+   &n= bsp;  (grub_le_to_cpu64(bpb.mft_lcn)), (data->mft_start));
+  
+  off_bytes =3D (grub_off_t)data->mft_start &= lt;< BLK_SHR;
+  grub_uint32_t len =3D data->mft_size << BLK_SHR;
+  if (bdrv_pread_from_lcn_of_volum(bs, off_bytes,
+  data-= >mmft.buf, len) !=3D len)
+    {
+      DBG("read mmft e= rror!");
+      goto fail;
+  =  }
+  data->uuid =3D grub_le_to_cpu64 (bpb.num_seri= al);
+
+  if (fixup (data, data->mmft.buf, data= ->mft_size, (char*)"FILE"))
+    goto fail;
+
+  if (!locate_at= tr (&data->mmft.attr, &data->mmft, AT_DATA))
+ &nbs= p;  {
+      DBG("locate_attr AT_DATA in= mmft failed! ");
+      goto fail;
+    }
+  if (init_file (&data->cmft, = FILE_ROOT))
+    {
+      DBG(= "init_file FILE_ROOT failed!");
+      g= oto fail;
+    }
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, &quo= t;not an ntfs filesystem");
+
+  if (data)
+    {
+      free_file (&da= ta->mmft);
+      free_file (&data->cmft= );
+      grub_free (data);
+    }
+  return 0;
+}
+
+struct grub_nt= fs_dir_closure
+{
+  int (*hook) (const char *file= name,
+ =        const struct grub_dirhook_info *info,
+ &nbs= p;      void *closure);
+  void *closure;
+  struct grub_ntfs_file file;
+};
+
<= div>+static int
+iterate (const char *filename,
+ &nbs= p;enum grub_fshelp_filetype filetype,
+  grub_fshelp_node_t node,
=
+ &nbs= p;void *closure)
+{
+  struct grub_ntfs_dir_closure *c =3D closure;
+  struct grub_dirhook_info info;
+  grub_memset = (&info, 0, sizeof (info));
+  info.dir =3D ((filetype &a= mp; GRUB_FSHELP_TYPE_MASK) =3D=3D GRUB_FSHELP_DIR);
+  c->file.data =3D node->data;
+  c->fil= e.ino =3D node->ino;
+  grub_free (node);
+ &nb= sp;
+  
+  if(init_file(&c->file, c-&g= t;file.ino))
+    {
+      errx(1, "iterate(): init_file error!\n"= ;);
+    }
+  else
+   &n= bsp;{
+      DBG("......current file mft read= successfully!\n");
+    }
+  char *pa =3D locate_attr(&c->file.attr,
+  &c->= file, AT_STANDARD_INFORMATION);
+  if(NULL =3D=3D pa)
<= div>+    {
+      errx(2, "no $STANDARD_INFORMATION in MFT 0x%x\n&= quot;, c->file.ino);
+    }
+  grub_u= int64_t date=3D 0;
+  if(read_attr(&c->file.attr, (ch= ar*)&date, 0, 8, 1, NULL, NULL))
+    {
+      errx(3, "read da= te error\n");
+    }
+  else
<= div>+    {
+
+      info.time_= ntfs =3D date;
+      DBG("......date: %zu\n&= quot;, date);
+    }
+  DBG("......size of \'%s\&#= 39;: %zu\n", filename, (c->file.size));
+  info.file= size_ntfs =3D 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 =3D (struct ls_ctrl*)closure= ;
+  DBG("detail=3D%d", ctrl->detail);
+  if('$' =3D=3D *filename)
+    goto do= ne;
+
+  printf("%s", filename);
+  if(!ctrl->detail)
+    {
+ &n= bsp;    printf("\n");
+      g= oto done;
+    }
+  else
+ &nb= sp;  {
+      printf("\t");
+    }
+  
+  char buffer[50]=3D{};
+  str= uct tm tm0;  
+  struct tm* ptm=3D ntfs_utc2local(info-= >time_ntfs, &tm0);
+  if(NULL =3D=3D ptm) errx(1, &qu= ot;ntfs_utc2local fail\n");
+           
+  printf(&q= uot;%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(&qu= ot;%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;  // =D7=EE=D6=D5=B7=B5=BB=D8=B8=F8iterate
+}
+
+
+
+grub_err_t
+g= rub_ntfs_ls (grub_file_t file, const char *path,
+ &nbs= p;      int (*hook) (const char *filename,
+    &= nbsp;const struct grub_dirhook_info *info,
+ &n= bsp;   void *closure),
+        void *closure)=
+{
+  struct grub_ntfs_data *data =3D 0;
+  struct grub_fshelp_node *fdiro =3D 0;
+  struct= grub_ntfs_dir_closure c =3D {0};
+
+  data =3D gr= ub_ntfs_mount (file->bs, file->part_off_sector);
+  if= (!data)
+    {
+      DBG("mount failed!");
+ &nbs= p;    goto fail;
+    }
+  gru= b_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate= _dir, 0,
+  0, GRUB_FSHELP_DIR);
+
+  
+  if (grub_errno)
+ &nb= sp;  goto fail;
+
+  c.hook =3D (hook ? hook = : find_then_ls_hook);
+  c.closure =3D closure;
+ =  grub_ntfs_iterate_dir (fdiro, iterate, &c);
+
+fail:
+  if ((fdiro) && (fdiro != =3D &data->cmft))
+    {
+   &nbs= p;  free_file (fdiro);
+      grub_free (fdir= o);
+    }
+  if (data)
+    {
+      free_file (&data-= >mmft);
+      free_file (&data->cmft);<= /div>
+      grub_free (data);
+    = }
+
+
+  return grub_errno;
+}
+
+grub_err_t
+grub_ntfs_open (grub_f= ile_t file, const char *name)
+{
+  struct grub_nt= fs_data *data =3D 0;
+  struct grub_fshelp_node *mft =3D 0;<= /div>
+
+
+  data =3D grub_ntfs_mount (file->bs, file= ->part_off_sector);
+  if (!data)
+   &nbs= p;{
+      DBG("mount failed!");
+      goto fail;
+    }
+  grub_fshelp_find_file (name, &data->cmft, &mft, gru= b_ntfs_iterate_dir, 0,
+  0, GRUB_FSHELP_REG);
+
= +  if (grub_errno)
+    goto fail;
+
+  if (mft !=3D &= amp;data->cmft)
+    {
+     &nb= sp;free_file (&data->cmft);
+      grub_mem= cpy (&data->cmft, mft, sizeof (*mft));
+      grub_free (mft);
+      if (= !data->cmft.inode_read)
+ {
+   if (init_file (&data->cm= ft, data->cmft.ino))
+ &nbs= p;   goto fail;
+ }
+    }
+
=
+  file->size =3D data->cmft.size;
+  file->data =3D data;
+  file->offset =3D = 0;
+
+  return 0;
+
+fail:
+  if (data)
+    {
+   &nbs= p;  free_file (&data->mmft);
+      free_file (&data->cmft);
+ &nbs= p;    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 =3D &((struct grub_ntfs_data *) file->data)->cmft;
+  if (file->read_hook)
+    mft->a= ttr.save_pos =3D 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 =3D file->data;
+
+=  if (data)
+    {
+      free_file (&data-= >mmft);
+      free_file (&data->cmft);<= /div>
+      grub_free (data);
+    = }
+
+
+  return grub_errno;
+}
+
+
+
diff --exclude=3D.svn= -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/ntfs.h xen-4.1.2-b/tools/ioemu-q= emu-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 files= ystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2009  Free Software Foundation, = Inc.
+ *
+ *  GRUB is free software: you can redis= tribute it and/or modify
+ *  it under the terms of the GNU General Public License as publ= ished 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 use= ful,
+ *  but WITHOUT ANY WARRANTY; without even the implied= warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULA= R PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Publi= c License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NTFS_H
+#define GRU= B_NTFS_H 1<= /div>
+
+
+#include "block_int.h"
+#include "fs-types.h"
+#include "grub_err.h"=
+#include "fs-comm.h"
+
+#define F= ILE_MFT      0
+#define FILE_MFTMIRR  1
=
+#define FILE_LOGFILE  2
+#define FILE_VOLUME   3
+#define FILE_ATTRDEF  4<= /div>
+#define FILE_ROOT     5
+#define FILE_BITMAP=   6
+#define FILE_BOOT     7
+#define F= ILE_BADCLUS  8
+#define FILE_QUOTA    9
+#define FILE_UPCASE  10
+
+#define AT_STANDA= RD_INFORMATION 0x10
+#define AT_ATTRIBUTE_LIST 0x20
+#define AT_FILENAME 0x30
+#define AT_OBJECT_ID 0x40
+#define AT_SECUR= ITY_DESCRIPTOR 0x50
+#define AT_VOLUME_NAME 0x60
+#define AT_VOLUME_INFORMATION 0x70
+#defi= ne 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
+#def= ine ATTR_SYSTEM <= /span>0x4
+#define ATTR_ARCHIVE 0x20
+#define ATTR_DEVICE 0x40
+#define ATTR_NOR= MAL 0x80
+#define ATTR_TEMPORARY 0x100
+#define ATTR_SPARSE 0x200
+#define ATTR= _REPARSE 0= x400
+#define ATTR_COMPRESSED 0x800
+#define ATTR_OFFLINE 0x1000
+#define A= TTR_NOT_INDEXED 0x2000
+#define ATTR_ENCRYPTED 0x4000
+#define ATTR_DIRECTORY 0x10000000
+#de= fine ATTR_INDEX_VIEW 0x20000000
+
+#define FLAG_COMPRESSED 1
+#define FLAG_ENCRYPTED 0x4000
= +#define FLAG_SPARSE 0x8000
+
+
+#define GRUB_DISK_SECTOR_BITS   9
<= div>+#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)
+
<= div> +#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))<= /div>
+#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)
+#de= fine v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t)
+#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t)
+
+str= uct grub_ntfs_bpb
+{
+  grub_uint8_t jmp_boot[3];<= /div>
+  grub_uint8_t oem_name[8];
+  grub_uint16_t byte= s_per_sector;
+  grub_uint8_t sectors_per_cluster;
+  grub_uint8_t reserved_1[7];
+  grub_uint8_t media;<= /div>
+  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_t= otal_sectors;
+  grub_uint64_t mft_lcn;
+  grub_uint64_t mft_mirr_lcn= ;
+  grub_int8_t clusters_per_mft;
+  grub_in= t8_t reserved_4[3];
+  grub_int8_t clusters_per_index;
=
+  grub_int8_t reserved_5[3];
+  grub_uint64_t num_serial;
+  grub_uint32_t chec= ksum;
+} __attribute__ ((packed));
+
+#define= grub_ntfs_file grub_fshelp_node
+
+struct grub_ntfs_at= tr
+{
+  int flags;
+  char *emft_buf, *eda= t_buf;
+  char *attr_cur, *attr_nxt, *attr_end;
+ =  grub_uint32_t save_pos;
+  char *sbuf;
+ &nb= sp;struct grub_ntfs_file *mft;
+};
+
+struct grub_fshelp_node
+{
<= div>+  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_fi= le cmft;
+  struct grub_ntfs_file mmft;
+  Bl= ockDriverState* bs;
+  grub_uint32_t mft_size;
+  grub_uint32_t idx_si= ze;
+  grub_uint32_t spc;
+  grub_uint32_t bl= ocksize;
+  grub_uint32_t mft_start;
+  grub_= uint64_t uuid;
+};
+
+struct grub_ntfs_comp
+{
+  Bloc= kDriverState* bs;
+  int comp_head, comp_tail;
+ &= nbsp;grub_uint32_t comp_table[16][2];
+  grub_uint32_t cbuf_= ofs, cbuf_vcn, spc;
+  char *cbuf;
+};
+
+struct grub_n= tfs_rlst
+{
+  int flags;
+  grub_d= isk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn;
+  char= *cur_run;
+  struct grub_ntfs_attr *attr;
+  struct grub_ntf= s_comp comp;
+};
+
+
+
+<= /div>
+
+
+
+typedef grub_err_t (*ntfscom= p_func_t) (struct grub_ntfs_attr * at, char *dest,
+ &= nbsp;      grub_uint32_t ofs, grub_uint32_t len,
+=  &= nbsp;     struct grub_ntfs_rlst * ctx,
+ &= nbsp;      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_l= cn_of_volum(BlockDriverState *bs, int64_t offset,
+  void *buf1, int= count1);
+
+struct grub_ntfs_data *
+grub_ntfs_mount (Block= DriverState* bs, grub_uint32_t part_off_sector);
+
+
+grub_err_t
+grub_ntfs_ls (grub_file_t file, const char *= path,
+ &nbs= p;      int (*hook) (const char *filename,
+    &= nbsp;const struct grub_dirhook_info *info,
+ &n= bsp;   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_f= ile_t file);
+
+
+#endif /* ! GRUB_NTFS_H */<= /div>
diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/p= artition.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 +0= 700
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/partition.c 2012-12-28 16:02:41.0= 14936701 +0800
@@ -0,0 +1,240 @@
+#include "partition.h"
+#include <err.h>
+
+static int is_full_zero(vo= id *p, uint bytes)
+{
+  int i =3D 0;
+ =  uint8_t *p1 =3D (uint8_t*)p;
+  while(i < bytes)
+  {
+   &nb= sp;if(*p1 !=3D 0)
+    {
+     &nbs= p;return 0;
+    }else
+    {
=
+      i++;
+      p1++;
=
+    }
+  }
+  //printf("..........full zero......\n"= ;);
+  return 1;
+}
+
+static = void read_partition(uint8_t *p, struct partition_record *r)
+{
+    r->bootable =3D p[0];
+    r->start_head =3D p[1];
+    r-&= gt;start_cylinder =3D p[3] | ((p[2] << 2) & 0x0300);
+ =    r->start_sector =3D p[2] & 0x3f;
+   &nb= sp;r->system =3D p[4];
+    r->end_head =3D p[5];=
+    r->end_cylinder =3D p[7] | ((p[6] << 2) & = 0x300);
+    r->end_sector =3D p[6] & 0x3f;
+    r->start_sector_abs =3D p[8] | p[9] << 8 | p[= 10] << 16 | p[11] << 24;
+    r->nb_sectors_abs =3D p[12] | p[13] << 8 | p[1= 4] << 16 | p[15] << 24;
+}
+
+
+
+char* judge_fs(ls_partition_t* pt)
+{
<= div>+  if(pt->part.system=3D=3D0x0b || pt->part.system=3D=3D0x01= )
+    {
+      pt->fs_type =3D FS= _FAT;
+      return (char*)"FAT32";
+    }
+  else if(pt->part.system=3D=3D0x= 07)
+    {
+      pt->fs_ty= pe =3D FS_NTFS;
+      return (char*)"NTFS";
+ &nbs= p;  }
+  else
+    {
+ &n= bsp;    pt->fs_type =3D FS_UNKNOWN;
+     =  return  (char*)"UNKNOWN";
+    }
+}
+
+int enum_partition(BlockDriverState *bs, ls_parti= tion_t* parts)
+{
+    struct partition_recor= d mbr[4];
+    uint8_t data[512];
+   &n= bsp;int i;
+    int ext_partnum =3D 4;
+    struct partition_record ext[10];
+   &nb= sp;uint8_t data1[512];
+    int j =3D 0;
+
+    if (bdrv_read(bs, 0, data, 1))
+   &n= bsp;    errx(EINVAL, "error while reading");
+
+    if (data[510] !=3D 0x55 || data[511] !=3D 0= xaa) 
+    {
+       &nbs= p;errno =3D -EINVAL;
+        return -1;
+    }
+    
+    i= nt k =3D 0;
+    for (i =3D 0; i < 4; i++) 
+    {
+        read_partition= (&data[446 + 16 * i], &mbr[i]);
+
+   &nbs= p;    if (!mbr[i].nb_sectors_abs)
+      = ;      continue;
+ //printf("the %d partition:boot=3D0x%= x, start=3D%u, system=3D0x%x, total=3D%u\t", 
+ // &= nbsp;     i+1, mbr[i].bootable, mbr[i].start_sector_abs, mbr[i].s= ystem, mbr[i].nb_sectors_abs);
+ parts[k].part =3D mbr[i];
+ part= s[k].id =3D i+1;
+ k++;
+        if (mbr[i].sy= stem =3D=3D 0xF || mbr[i].system =3D=3D 0x5) 
+ {
+ &= nbsp;   //printf("is a extend partition......\n");
+ &nb= sp;   if (bdrv_read(bs, mbr[i].start_sector_abs, data1, 1))
+                errx(EINVAL, = "error while reading");
+     /////////////////////= //////
+=     //dump ebr
+ &nbs= p;   ///////////////////////////
+     uint32_t ext= _start_sector =3D mbr[i].start_sector_abs;
+ &nbs= p;   struct partition_record ext_next =3D {0};
+  =          while (1) 
+     {<= /div>
+ &nbs= p;       read_partition(&data1[446 + 16 * 0], &= ext[j]);
+ //printf("the %dth partition:boot=3D0x%x, start=3D%u, syste= m=3D0x%x, total=3D%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 !=3D ext[j].nb_sectors_abs) 
+ {
+   ext[j].start_sector_abs +=3D ext_start_sector;
+   i= f(j > 0)
+ &nb= sp;   ext[j].start_sector_abs +=3D ext_next.start_sector_abs;
+ &= nbsp; parts[k].part =3D ext[j];
+ &nb= sp; parts[k].id =3D ext_partnum + j +1;
+   k++;
+=  &nb= sp;j++;
+ &nbs= p;       }
+ else
+ {
+ &nb= sp; printf("nb_sectors_abs=3D0>>>>>>>>>= ;>>>\n");
+ }
+ ///= ///////////////////
+ if(ext[j-1].system =3D=3D 0xF )
+   {
+ &nb= sp;   printf("...............again extend.............\n&quo= t;);
+ =     ext_start_sector =3D ext[j-1].start_sector_abs + = ext_start_sector;
+ &nb= sp;   if (bdrv_read(bs, ext_start_sector, data1, 1))
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre">  &nbs= p;    errx(EINVAL, "error while reading");
+ &nb= sp;   continue;
+   }
+ else
+ &nb= sp; {
+     ;//printf("is a logical part\n");=
+   }
+ ///= //////////////////
+ read_partition(&data1[446 + 16 * 1], &ext_next= );
+ if = (is_full_zero(&ext_next, sizeof(ext_next)))
+     &= nbsp;              break;
+
+ = if (bdrv_read(bs, ext_start_sector + ext_next.start_sector_abs , data1, 1))=
+ &nb= sp; errx(EINVAL, "error while reading");
+     = ;}
+ }else
+ {
+ &= nbsp; ;//printf("is a main partition......\n");
+<= span class=3D"Apple-tab-span" style=3D"white-space:pre"> }
+    }
+    
+    re= turn k;
+}
+
+
+
+
<= div>+
+int find_partition(BlockDriverState *bs, int partition,
+                   &n= bsp;      off_t *offset, off_t *size)
+{
+    struct partition_record mbr[4];
= +    uint8_t data[512];
+    int i;
+    int ext_partnum =3D 4;
+
+
+ =    if (bdrv_read(bs, 0, data, 1))
+        errx(EINVAL, "error while reading&qu= ot;);
+
+    if (data[510] !=3D 0x55 || data[= 511] !=3D 0xaa) 
+    {
+     =    errno =3D -EINVAL;
+        retu= rn -1;
+    }
+    
+    in= t k =3D 0;
+    for (i =3D 0; i < 4; i++) 
+    {
+        read_partitio= n(&data[446 + 16 * i], &mbr[i]);
+
+   &nb= sp;    if (!mbr[i].nb_sectors_abs)
+            continue;
+ //printf("t= he %d partition:", i+1);
+
+        if (mbr[i].system =3D=3D 0xF || mbr[i].sy= stem =3D=3D 0x5) 
+ {
+   //printf("is a extend partiti= on......\n");
+            struct partition_record ext= [10];
+            uint8_t data1[51= 2];
+            int j =3D 0;
=
+
+            if (bdrv_read(b= s, mbr[i].start_sector_abs, data1, 1))
+                errx(EINVAL, = "error while reading");
+     
+     = uint32_t ext_start_sector =3D mbr[i].start_sector_abs;
+ &nbs= p;   struct partition_record ext_next =3D {0};
+  =          while (1) 
+     {<= /div>
+ &nbs= p;       read_partition(&data1[446 + 16 * 0], &= ext[j]);
+ printf("start=3D%u, total=3D%u, system=3D0x%x\t",
+ &nb= sp;      ext[j].start_sector_abs, ext[j].nb_sectors_abs, ext= [j].system);
+ printf("the %dth partition is a logical part\n", e= xt_partnum + j + 1);
+
+ = if(0 !=3D ext[j].nb_sectors_abs) 
+ {
+ &nb= sp; if ((ext_partnum + j + 1) =3D=3D partition) 
+   {<= /div>
+     ext[j].start_sector_abs +=3D  ext_start_sector;
+ &nb= sp;   if(j > 0)
+       ext[j].start_secto= r_abs +=3D ext_next.start_sector_abs;
+ &nb= sp;   *offset =3D (uint64_t)ext[j].start_sector_abs << 9;
+     *size =3D (uint64_t)ext[j].nb_sectors_abs << 9;
+ &nb= sp;   return 0;
+   }
+   j++;
+ &nbs= p;       }
+
+ read_partition(&data1[446 + 16 * 1]= , &ext_next);
+ if = (is_full_zero(&ext_next, sizeof(ext_next)))
+     &= nbsp;              break;
+ //ext_start_= sector +=3D ext_next.start_sector_abs;
+ if = (bdrv_read(bs, ext_start_sector + ext_next.start_sector_abs, data1, 1))
+ &= nbsp;   errx(EINVAL, "error while reading");
+ &nbs= p;   }
+            
+        } 
+ else 
+ {
+ &nbs= p; //printf("is a main partition......\n");
+    &n= bsp;if ((i + 1) =3D=3D partition) 
+ &nbs= p;   {
+       *offset =3D (uint64_t)mbr[i].st= art_sector_abs << 9;
+       *size =3D (uint64_t)= mbr[i].nb_sectors_abs << 9;
+ &nbs= p;     return 0;
+     }
+ }
+    }
+
+    errno =3D -ENOEN= T;
+    return -1;
+}
+
+= ///////////////////////////////////////////////////////
diff --ex= clude=3D.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 +0= 700
+++ xen-4.1.2-b/tools/ioemu-qemu-xen/partition.h 2012-12-28 16:02:41.0= 15940225 +0800
@@ -0,0 +1,46 @@
+#ifndef _PARTITION_H
+#define _P= ARTITION_H
+
+#include <stdint.h>
+
+typedef struct partition_record
+{
+   &nb= sp;uint8_t bootable;
+    uint8_t start_head;
+    uint32_t s= tart_cylinder;
+    uint8_t start_sector;
+ &= nbsp;  uint8_t system;
+    uint8_t end_head;
+    uint8_t end_cylinder;
+    uint8_t= end_sector;
+    uint32_t start_sector_abs;
+    uin= t32_t nb_sectors_abs;
+} __attribute__ ((packed)) part_record_t;<= /div>
+
+
+
+typedef enum
+ &nb= sp;{
+    FS_UNKNOWN =3D 0,
+    FS_FAT,
+    FS_NTFS
+ &n= bsp;}FS_TYPE;
+
+typedef struct ls_partition
= +{
+  part_record_t part;
+  int id;
+  FS_TYPE fs_type;
+}ls_partition_t;
+
+
+char* judge_fs(ls_part= ition_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=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-xen/qemu-i= mg.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 +08= 00
@@ -20,23 +20,35 @@
  * LIABILITY, WHETHER IN A= N 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 "os= dep.h"
 #include "block_int.h"
 #include <assert.= h>
+#include <err.h>
+
+
+= #include "partition.h"
+#include "fs-comm.h"<= /div>
+#include "fat.h"
+#include "ntfs.h"
+#include "misc.h"
+
+
+
 
 #ifdef _WIN32
 #define WIN32_LEAN_A= ND_MEAN
 #include <windows.h>
 #endif
&nbs= p;
 /* Default to cache=3Dwriteback 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);
     fpri= ntf(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(&qu= ot;qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fab= rice Bellard\n"
            "usage: qemu-img comman= d [command options]\n"
          &n= bsp; "QEMU disk image utility\n"
      &= nbsp;     "\n"
        &n= bsp;   "Command syntax:\n"
+           "  ls [-v] [[-l] -d dir= ectory] imgfile\n"
+           &quo= t;  cat [-v] -f file imgfile\n"
      &n= bsp;     "  create [-e] [-6] [-b base_image] [-f fmt] f= ilename [size]\n"
            "  commit [-f fmt]= filename\n"
            "= ;  convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_ima= ge] filename [filename2 [...]] output_filename\n"
  &nb= sp;         "  info [-f fmt] filename\n"=
            "  snapshot [-l | = -a snapshot | -c snapshot | -d snapshot] filename\n"
  =           "\n"
    &= nbsp;       "Command parameters:\n"
&nbs= p;           "  'filename' is a = disk image filename\n"
@@ -209,16 +223,343 @@ static BlockDriverState *bdrv_new_open(c
<= div>         if (read_password(password, sizeof(pa= ssword)) < 0)
             = error("No password given");
       =  if (bdrv_set_key(bs, password) < 0)
             error("invalid pa= ssword");
     }
    &nbs= p;return bs;
 }
 
+static void get_= partition_path(const char *dir, int *which_part, char **path)
+{
+    static char full_path[512];
+   =  char part[5]=3D{};
+
+    strncpy(full_= path, dir, 512);
+    full_path[511] =3D '\0';<= /div>
+
+    //=CF=DE=D6=C6=D2=D4/=BF=AA=CD=B7 =BD= =E1=CE=B2
+    char *p1 =3D full_path + 1;
+    ch= ar *p2 =3D strchr(full_path + 1, '/');
+    if(= !p2)
+    {
+        errx= (1, "check the file path!\n");
+    }
+
+    *path =3D p2;
+    strn= cpy(part, p1, p2-p1);
+    *which_part =3D atoi(part);<= /div>
+}
+
+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] =3D {};
+
+static void grub_fs_plugin(void)
+{
+  grub_fs_plug[FS_FAT].open =3D grub_fat_open;
+  grub_fs_plug[FS_FAT].read =3D grub_fat_read;
+ &nbs= p;grub_fs_plug[FS_FAT].close =3D grub_fat_close;
+  grub_fs_= plug[FS_FAT].ls =3D grub_fat_ls;
+
+  grub_fs_plug[FS_NTFS].open =3D grub_ntfs_open;
+  grub_fs_plug[FS_NTFS].read =3D grub_ntfs_read;
+ &= nbsp;grub_fs_plug[FS_NTFS].close =3D grub_ntfs_close;
+  gru= b_fs_plug[FS_NTFS].ls =3D grub_ntfs_ls;
+}
+
+static int img_ls(int argc, char **argv)
+{
+    int c =3D -1;
+    c= har *imgfile =3D NULL;
+    char *dir =3D NULL;
+    char verbose =3D 0;
+    struct ls_ctrl ctrl=3D{};
+
+   &nb= sp;for(;;) 
+    {
+      = ;  c =3D getopt(argc, argv, "d:hlv");
+   &nb= sp;    if (c =3D=3D -1)
+         &= nbsp;  break;
+
+        switch(c) 
+    =    {
+            case &= #39;v':
+               &n= bsp;verbose =3D 1;
+             &n= bsp;  break;
+            case= 'l':
+               =  ctrl.detail =3D 1;
+                break;
<= div>+            case 'h':
= +                help();
= +                break;
+=            case 'd':
+ &nb= sp;              dir =3D optarg;
+                break;
<= div>+            default:
+   =              break;
+   &= nbsp;    }
+    }
+    
+    imgfile =3D argv[optind++];
+   &nbs= p;
+    if (optind > argc)
+      help();
+    
+ &n= bsp;  BlockDriverState *bs =3D bdrv_new("");
+ &nb= sp;  if(!bs)
+        error("Not en= ough 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 =3D 0;
+    off_t size_bytes =3D 0;
+    int i =3D 0;
+    ls_partition_t* parts= =3D (ls_partition_t*)malloc(MAX_PARTITIONS * sizeof(ls_partition_t));
+    int count =3D enum_partition(bs, parts);
+ &n= bsp;  
+    if(!dir)
+    {
+        //find_partition(bs, 15, &off_byte= s, &size_bytes);
+        printf("id= \tactive\ttype\tfs\tstart_sector\ttotal_sectors\n");
+        for(i =3D 0; i < count; i++)
+        {
+         &nb= sp;  printf("%d\t%s\t%s\t%s\t%u\t%u\n", 
+ &n= bsp;                 parts[i].id,&n= bsp;
+                 &n= bsp; parts[i].part.bootable=3D=3D0x80 ? "active" : "none-act= ive",
+                   (part= s[i].part.system=3D=3D0x0f || parts[i].part.system=3D=3D0x05) ? "exten= d" : (parts[i].id>=3D5 ? "logical" : "primary")= ,
+                  = ; judge_fs(&parts[i]),
+                   parts= [i].part.start_sector_abs,
+           &= nbsp;       parts[i].part.nb_sectors_abs
+   =                 );
+ &nbs= p;      }
+
+        = ;goto fail;
+    }
+    else
+    {
+        grub_fs_plugin();
+   =    
+        grub_file_t file =3D N= ULL;
+        char *path =3D NULL;
= +        int which_part =3D 1;
+      
+        file =3D= (grub_file_t)malloc(sizeof(*file));
+        = ;file->bs =3D bs;
+        file->data = =3D NULL;
+
+        if('/'= !=3D dir[strlen(dir) - 1])
+            strcat(dir, "/");=
+
+        get_partition_path(dir,= &which_part, &path);
+        if(whi= ch_part < 1 || which_part > count)
+       &= nbsp;{
+            fprintf(stderr, "error= : check the partition number!\n");
+       &n= bsp;    goto fail;
+        }
=
+
+        file->part_off_sector =3D = parts[which_part - 1].part.start_sector_abs;
+        ctrl.dirname =3D dir;
+   =      printf("=A1=BEname\t"
+   &nbs= p;           "size(bytes)\t"
+=               "dir?\t"
<= div>+               "date\t"
+               "time=A1=BF\n&= quot;);
+
+        judge_fs(&pa= rts[which_part - 1]);
+        FS_TYPE fs_typ= e =3D parts[which_part - 1].fs_type;
+        = ;if (fs_type =3D=3D FS_UNKNOWN) 
+        {
+        =    errx(1, "unknown file system!\n");
+ &nbs= p;      }
+
+        = ;grub_fs_plug[fs_type].ls(file, path, NULL, (void*)&ctrl);
+ =        file->data ? free(file->data) : 0;
+        free(file);
+    }
+    
+    
+  fail:
+    bdrv_delete(bs);
+    free(part= s);
+    return 0;
+}
+
+=
+
+static int img_cat(int argc, char **argv)
+{
+    int c =3D -1;
+    char *imgfile= =3D NULL;
+    char *filename =3D NULL;
+ &n= bsp;  char verbose =3D 0;
+
+    for(;;) {
+        c =3D = getopt(argc, argv, "f:hv");
+       &nbs= p;if (c =3D=3D -1)
+            bre= ak;
+        switch(c) {
+   &= nbsp;        case 'v':
+                verbose =3D 1;
+                break;
+            case 'h':
+                help();
+                break;
+            case 'f':
+                filename =3D optar= g;
+                break= ;
+            default:
+=                break;
+ =        }
+    }
+   =  
+    imgfile =3D argv[optind++];
+    if (optind > argc)
+       =  help();
+
+    
+   &nbs= p;if(!filename)
+    {
+      =  printf("error: specific the file to show!\n");
+=        return -1;
+    }
+        
+ &= nbsp;  BlockDriverState *bs =3D bdrv_new("");
+ &n= bsp;  if(!bs)
+        errx(-1, "No= t enough memory for bdrv_new\n");
+    if(bdrv_ope= n(bs, imgfile, BRDV_O_FLAGS) < 0)
+        errx(-1, "Could not open %s\n",= imgfile);
+    
+
+    u= int buf_size =3D 4096;
+    char* buf =3D (char*)malloc= (buf_size);
+    off_t off_bytes =3D 0;
+    off_t size_bytes =3D 0;
+    int i = =3D 0;
+    ls_partition_t *parts =3D (ls_partition_t*)= malloc(MAX_PARTITIONS * sizeof(ls_partition_t));
+    i= nt count =3D enum_partition(bs, parts);
+    
+       
+ &nb= sp;  {
+        grub_fs_plugin();
<= div>+
+        grub_file_t file =3D NULL;
+        char *path =3D NULL;
+  =      int which_part =3D 1;
+      
+        file =3D= (grub_file_t)malloc(sizeof(*file));
+        = ;file->bs =3D bs;
+        file->data = =3D NULL;
+      
+      =  char* p =3D strchr(filename, '/');
+        if(!p)
+       &= nbsp;{
+            errx(-1, "= please check the file path!\n");
+       &nbs= p;}
+        else
+     &= nbsp;  {
+            p =3D st= rchr(p, '/');
+            if(!p) errx(-1, "check= the file path!!\n");
+        }
+  =  
+        get_partition_path(filename, = &which_part, &path);
+        DBG("part=3D%d, path=3D%s", whi= ch_part, path);
+        if(which_part < 1= || which_part > count)
+        {
+            printf("error: check the= partition number!\n");
+            goto fail;
+ &nbs= p;      }
+        file->pa= rt_off_sector =3D parts[which_part - 1].part.start_sector_abs;
+ =        judge_fs(&parts[which_part - 1]);
= +        FS_TYPE fs_type =3D parts[which_part - 1].fs_t= ype;
+        (fs_type =3D=3D FS_UNKNOWN) ? errx(1, &qu= ot;unknown file system!\n") : 0;
+       &nbs= p;grub_fs_t grub_fs_plg =3D grub_fs_plug[fs_type];
+   =
+        if(grub_fs_plg.open(file, path) =3D= =3D 0)
+        {
+        =    //printf("file size=3D%zd bytes\n", (file->size)= );
+   
+            grub_= size_t len =3D file->size;
+            grub_off_t off =3D 0;
=
+            char  tmpfile[256]=3D{= };
+            strncpy(tmpfile, ge= tenv("HOME"), sizeof(tmpfile));
+       =      tmpfile[sizeof(tmpfile) - 1] =3D '\0';
+            strcat(tmpfile, "/tmp.= file");
+     
+         &= nbsp;  if(!buf)
+            {=
+                perror(= "not enough memory!\n");
+                goto fail;
+            }
+   &nb= sp;        else
+        =    {
+              = ;  grub_size_t readed =3D 0;
+         &= nbsp;      grub_size_t left  =3D len;
+                grub_size_t total = =3D 0;
+                F= ILE* f =3D fopen(tmpfile ,"w");
+       =          if(!f)
+       &= nbsp;        {
+         =            perror("fopen error");
+                    = ;goto fail;
+               &n= bsp;}
+ =       
+       
+                (left > bu= f_size) ? (left =3D buf_size) : 0;
+         =        while((readed =3D grub_fs_plg.read(file, off, le= ft, buf))
+               &nbs= p;      && total <=3D len
+                     &nb= sp;&& readed > 0)
+          =      {
+            = ;        DBG("readed=3D%zd", readed);
+                    t= otal +=3D fwrite(buf, 1, readed, f);
+                    off = =3D total;
+               &nb= sp;    left =3D len - total;
+       &nb= sp;            (left <=3D buf_size) ? 0 &n= bsp;: (left =3D buf_size);
+           &= nbsp;        DBG("total=3D%zd", total);
+                };
= +                fclose(f);
+  =      
+             =    if(total !=3D len)
+         &nb= sp;      {
+                    perr= or("read error");
+           =          goto fail;
+     &nbs= p;          }
+       &nb= sp;        else
+        =        {
+          = ;          sprintf(buf, "cat %s", tmpfil= e);
+                    = ;system(buf);
+  
+         &n= bsp;      }
+           &= nbsp;}
+        }
+     &= nbsp;  else
+        {
+  = ;          printf("open failed!\n");
+        }
+      
<= div>+      
+        grub_fs_p= lg.close(file);
+        free(file);
+    }
+    
+    
+  fail:
+    free(buf);
+    bdrv_delete(bs);
+    free(parts);<= /div>
+    return 0;
+}
+
+
+
 static int img_create(int argc, char **argv)
=
 {
     int c, ret, flags;
     const char *fmt =3D "raw";
&nb= sp;    const char *filename;
     const = char *base_filename =3D NULL;
     uint64_t size;<= /div>
     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();
    &= nbsp;if (argc < 2)
         help();
     cmd =3D argv[1];
     = ;argc--; argv++;
     if (!strcmp(cmd, "creat= e")) {
@@ -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);
&nb= sp;    } else if (!strcmp(cmd, "info")) {
         img_info(argc, argv);
&nbs= p;    } else if (!strcmp(cmd, "snapshot")) {
=          img_snapshot(argc, argv);
- &nb= sp;  } else {
+    } else if (!strcmp(cmd, "l= s")) {
+        img_ls(argc, argv);    
+    } else if (!strcmp(cmd, "cat")) {
+ &= nbsp;      img_cat(argc, argv);
+    }
+    else {
         = help();
     }
+    
     return 0;
&nbs= p;}
diff --exclude=3D.svn -rpN -U8 xen-4.1.2-a/tools/ioemu-qemu-x= en/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<= /div>
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  -- =  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007  Free Software Foundation,= Inc.
+ *
+ *  GRUB is free software: you can redi= stribute 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 Licens= e, 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. &nbs= p;See the
+ *  GNU General Public License for more details.<= /div>
+ *
+ *  You should have received a copy of the GNU General Public Li= cense
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
<= div>+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYP= ES_CPU_HEADER 1
+
+/* The size of void *.  */
+#def= ine GRUB_TARGET_SIZEOF_VOID_P 4
+
+/* The size of long.  */
+#define GRUB_TAR= GET_SIZEOF_LONG <= /span>4
+
+/* i386 is little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+#define GRUB_TARGET_I386 1
+
+#define GRUB_TARG= ET_MIN_ALIGN 1
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --exc= lude=3D.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/i= oemu-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 &n= bsp;--  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute i= t and/or modify
+ *  it under the terms of the GNU General P= ublic License as published by
+ *  the Free Software Foundation, either version 3 of the Licens= e, 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. &nbs= p;See the
+ *  GNU General Public License for more details.<= /div>
+ *
+ *  You should have received a copy of the GNU General Public Li= cense
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
<= div>+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYP= ES_CPU_HEADER 1
+
+/* The size of void *.  */
+#def= ine GRUB_TARGET_SIZEOF_VOID_P 8
+
+/* The size of long.  */
+#ifdef __MINGW32= __
+#define GRUB_TARGET_SIZEOF_LONG 4
+#else
+#define G= RUB_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 */

=

--e89a8f502b9249b9ff04d2d60ecc--