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