Mailing List Archive

[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.
Re: [PATCH] patch for listing and reading files from qcow2-formated image file (for xen-4.1.2) [ In reply to ]
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?*
Re: [PATCH] patch for listing and reading files from qcow2-formated image file (for xen-4.1.2) [ In reply to ]
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)
+ {//³¤Ãû±íÏîºóÃæ½ô½Ó¶ÌÃû±íÏÑéÖ¤³É¹¦ÔòÖ¤Ã÷ÕæÕýÊdz¤Ãû×Ö
+ 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)
+ {//³¤Ãû±íÏîºóÃæ½ô½Ó¶ÌÃû±íÏÑéÖ¤³É¹¦ÔòÖ¤Ã÷ÕæÕýÊdz¤Ãû×Ö
+ 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 */
Re: [PATCH] patch for listing and reading files from qcow2-formated image file (for xen-4.1.2) [ In reply to ]
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