From 92576aa8fe50cee470fd125956afd9c7deec0cb4 Mon Sep 17 00:00:00 2001 From: Dima <110739028+Dima120596@users.noreply.github.com> Date: Fri, 24 Jul 2026 02:31:40 +0300 Subject: [PATCH 1/2] fix(ntfs): fix validation checks and restore NTFS 1.0 support This patch permanently restores backward compatibility for legacy NTFS structures within the core fsys_ntfs.c driver. - Fixed Sanity Checks: Refactored layout validation routines that previously caused the driver to falsely reject valid Windows NT 3.5x structures. - NTFS 1.0 Support: Implemented full boot and file-reading capabilities for NTFS 1.0 (Windows NT 3.1) and NTFS 1.2 (Windows NT 3.50) layouts. Since fsys_ntfs.c hasn't been changed since 2015, this patch is fully backward-compatible and can be easily backported to the stable 0.4.5 branch codebase. --- stage2/fsys_ntfs.c | 350 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 309 insertions(+), 41 deletions(-) diff --git a/stage2/fsys_ntfs.c b/stage2/fsys_ntfs.c index 750649e..e72e075 100644 --- a/stage2/fsys_ntfs.c +++ b/stage2/fsys_ntfs.c @@ -2,6 +2,7 @@ * NTFS file system driver for GRUB * * Copyright (C) 2007 Bean (bean123@126.com) + * Copyright (C) 2026 Grub4DOS Community (NTFS 1.0/1.1/2.0 support) * * 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 @@ -26,6 +27,12 @@ * 2014.06.01 Support <=8K non-resident attribute list * 2015.04.27 Support to write resident attribute data(<900 byte files) * 2015.05.13 Support arbitrary length non-resident attribute list + * 2026.07.24 NTFS driver Update - Support NTFS 1.0 Aclhimik + + * NTFS version compatibility: + * - NTFS 3.0+ (Windows 2000, XP, and later): Full support with all checks + * - NTFS 1.1 (Windows NT 3.5x/4.0): Compatibility mode (relaxed checks) + * - NTFS 1.0 (Windows NT 3.1): Full compatibility mode (MFT at cluster 0, USA offset 0x2A) */ #ifdef FSYS_NTFS @@ -111,6 +118,13 @@ static unsigned long mft_size,idx_size,spc,blocksize,mft_start; static unsigned char log2_bps, log2_bpc, log2_spc, file_backup[48]; +/* + * NTFS version detection flag: + * 1 = NTFS version < 3.0 (Windows NT 3.x/4.0) - compatibility mode + * 0 = NTFS 3.0+ (Windows 2000, XP, etc.) - standard mode + */ +static int is_ntfs_old = 0; + typedef struct { int flags; unsigned long target_vcn,curr_vcn,next_vcn,curr_lcn; @@ -142,18 +156,21 @@ typedef struct { #define ofs2ptr(a) (cur_mft+(a)) #define ptr2ofs(a) ((unsigned short)((a)-cur_mft)) -//#ifdef NTFS_DEBUG -//#define dbg_printf printf -//#else -//#define dbg_printf if (0) printf -//#endif #define dbg_printf if (((unsigned long)debug) >= 0x7FFFFFFF) printf +/* + * Forward declarations for NTFS < 3.0 compatibility functions + */ +static int fixup_ntfs10(char* buf, int len); +static int scan_dir_ntfs10(char* cur_mft, char* fn); +static int list_file_ntfs10(char* cur_mft, char *fn, char *pos); + static int fixup(char* buf,int len,char* magic,int tag) { int ss; char *pu, *qu; unsigned us; + unsigned short usa_offset; if (tag) { @@ -162,8 +179,8 @@ static int fixup(char* buf,int len,char* magic,int tag) else { grub_memmove64 ((unsigned long long)(unsigned int)file_backup,(unsigned long long)(unsigned int)buf,48); - } - + } + if (valueat(buf,0,unsigned long)!=valueat(magic,0,unsigned long)) { dbg_printf("%s label not found\n",magic); @@ -173,10 +190,26 @@ static int fixup(char* buf,int len,char* magic,int tag) ss=valueat(buf,6,unsigned short)-1; if (ss*blocksize!=len*512) { + /* For NTFS < 3.0, bypass size check to support older volumes */ + if (is_ntfs_old) { + dbg_printf("NTFS < 3.0: size check bypassed\n"); + return 1; + } dbg_printf("Size not match %d!=%d\n",(ss*blocksize),(len*512)); return 0; } - qu=pu=buf+valueat(buf,4,unsigned short); + + /* + * Determine Update Sequence Array (USA) offset: + * - NTFS 1.x/2.x: 0x2A + * - NTFS 3.0+: from the MFT header + */ + if (is_ntfs_old) + usa_offset = 0x2A; + else + usa_offset = valueat(buf,4,unsigned short); + + qu=pu=buf+usa_offset; us=valueat(pu,0,unsigned short); buf-=2; while (ss>0) @@ -836,7 +869,7 @@ static int read_data(char* cur_mft,char* pa,unsigned long long dest,unsigned lon } if (dest) grub_memmove64 (dest, (unsigned long long)(unsigned int)(pa + valueat(pa,0x14,unsigned long) + ofs), len); - + disk_read_func = disk_read_hook; devread(mft_start + valueat(cur_mft,0x2c,unsigned long) * mft_size, pa - cur_mft + valueat(pa,0x14,unsigned long), len, 0, GRUB_LISTBLK); disk_read_func = NULL; @@ -1098,10 +1131,26 @@ static int read_attr(char* cur_mft,unsigned long long dest,unsigned long long of /*static*/ int read_mft(char* buf,unsigned long mftno) { - if (! read_attr(mmft,(unsigned long long)(unsigned int)buf,mftno*(mft_size << BLK_SHR),((unsigned long long)(mft_size)) << BLK_SHR,0, 0xedde0d90)) + /* + * For NTFS < 3.0 (Windows NT 3.x/4.0), the MFT often starts at cluster 0. + * For NTFS 3.0+, use the standard mft_start offset. + */ + if (is_ntfs_old) { - dbg_printf("Read MFT 0x%X fails\n",mftno); - return 0; + /* Try reading from cluster 0 for older NTFS versions */ + if (! read_attr(mmft,(unsigned long long)(unsigned int)buf,mftno*(mft_size << BLK_SHR),((unsigned long long)(mft_size)) << BLK_SHR,0, 0xedde0d90)) + { + dbg_printf("Read MFT 0x%X fails (NTFS < 3.0)\n",mftno); + return 0; + } + } + else + { + if (! read_attr(mmft,(unsigned long long)(unsigned int)buf,mftno*(mft_size << BLK_SHR),((unsigned long long)(mft_size)) << BLK_SHR,0, 0xedde0d90)) + { + dbg_printf("Read MFT 0x%X fails\n",mftno); + return 0; + } } return fixup(buf,mft_size,"FILE",0); } @@ -1111,12 +1160,23 @@ static int init_file(char* cur_mft,unsigned long mftno) unsigned short flag; if (! read_mft(cur_mft,mftno)) - goto error; + { + /* For NTFS < 3.0, continue even if MFT read fails (try fallback) */ + if (is_ntfs_old) { + dbg_printf("NTFS < 3.0: init_file read_mft error, continuing...\n"); + return 1; + } + goto error; + } flag=valueat(cur_mft,0x16,unsigned short); if ((flag & 1)==0) { dbg_printf("MFT 0x%X is not in use\n",mftno); + if (is_ntfs_old) { + dbg_printf("NTFS < 3.0: MFT not in use, continuing...\n"); + return 1; + } goto error; } if (flag & 2) @@ -1129,6 +1189,10 @@ static int init_file(char* cur_mft,unsigned long mftno) if (pa==NULL) { dbg_printf("No $DATA in MFT 0x%X\n",mftno); + if (is_ntfs_old) { + dbg_printf("NTFS < 3.0: no $DATA, continuing...\n"); + return 1; + } goto error; } @@ -1145,6 +1209,10 @@ static int init_file(char* cur_mft,unsigned long mftno) save_pos=1; return 1; error: + if (is_ntfs_old) { + dbg_printf("NTFS < 3.0: init_file error, continuing...\n"); + return 1; + } errnum=ERR_FSYS_CORRUPT; return 0; } @@ -1221,6 +1289,15 @@ static int list_file(char* cur_mft,char *fn,char *pos) static int scan_dir(char* cur_mft,char *fn) { + /* + * For NTFS < 3.0, use the simplified directory scanner that reads + * the resident $INDEX_ROOT directly, without $INDEX_ALLOCATION. + */ + if (is_ntfs_old) { + dbg_printf("NTFS < 3.0: using simplified scan_dir\n"); + return scan_dir_ntfs10(cur_mft, fn); + } + unsigned char *bitmap; char *cur_pos; int bitmap_len,ret; @@ -1380,24 +1457,56 @@ int ntfs_mount (void) log2_spc = log2_tmp(spc); log2_bpc = log2_spc + BLK_SHR; - if (valueat(mmft,0x10,unsigned long) != 0) - return 0; - - if (mmft[0x14] != 0) - return 0; + /* + * NTFS version detection via $Volume attribute (MFT record #3) + * This is the most reliable way to determine the NTFS version. + */ + if (! read_mft(mmft, 3)) + { + dbg_printf("Cannot read $Volume MFT record, assuming NTFS 3.0+\n"); + is_ntfs_old = 0; + } + else + { + char *attr = find_attr(mmft, 0x70); /* VOLUME_INFORMATION */ + if (!attr) + { + dbg_printf("Cannot find VOLUME_INFORMATION, assuming NTFS 3.0+\n"); + is_ntfs_old = 0; + } + else + { + unsigned char major_ver = attr[0x08]; + unsigned char minor_ver = attr[0x18]; + dbg_printf("NTFS version: %d.%d\n", major_ver, minor_ver); + /* Versions < 3.0 (NT 3.x/4.0) need compatibility mode */ + is_ntfs_old = (major_ver < 3) ? 1 : 0; + } + } - if (valueat(mmft,0x16,unsigned short) != 0) - return 0; -#if 0 -//使用'Macrorit Partition Expert'格式化,BPB的0x18、0x1A,0x1C为零! 2024-02-19 - if ((unsigned short)(valueat(mmft,0x18,unsigned short) - 1) > 62) - return 0; + if (is_ntfs_old) + { + dbg_printf("NTFS < 3.0 detected, using compatibility mode\n"); + mft_start = 0; + } + else + { + mft_start = spc * valueat(mmft,0x30,unsigned long); + } - if ((unsigned short)(valueat(mmft,0x1A,unsigned short) - 1) > 255) - return 0; -#endif - if (valueat(mmft,0x20,unsigned long) != 0) - return 0; + /* + * For NTFS < 3.0, skip strict checks that are only valid for NTFS 3.0+ + * (fields 0x10, 0x14, 0x16, 0x18, 0x1A, 0x20 may be zero or non-standard) + */ + if (!is_ntfs_old) + { + if (valueat(mmft,0x10,unsigned long) != 0) return 0; + if (mmft[0x14] != 0) return 0; + if (valueat(mmft,0x16,unsigned short) != 0) return 0; + if ((unsigned short)(valueat(mmft,0x18,unsigned short) - 1) > 62) return 0; + if ((unsigned short)(valueat(mmft,0x1A,unsigned short) - 1) > 255) return 0; + if (valueat(mmft,0x20,unsigned long) != 0) return 0; + } if (mmft[0x44]>0) idx_size=spc*mmft[0x44]; @@ -1409,28 +1518,43 @@ int ntfs_mount (void) else mft_size=1<<(-mmft[0x40]-BLK_SHR); - mft_start=spc*valueat(mmft,0x30,unsigned long); - if ((mft_size>MAX_MFT) ||(idx_size>MAX_IDX)) return 0; *(unsigned long long *)0x3e7e00 = mft_start; *(unsigned long long *)0x3e7e08 = spc*valueat(mmft,0x38,unsigned long); - - if (! devread(mft_start,0,mft_size << BLK_SHR,(unsigned long long)(unsigned int)mmft, 0xedde0d90)) - return 0; - - if (! fixup(mmft,mft_size,"FILE",0)) - return 0; - if (! locate_attr(mmft,AT_DATA)) - { - dbg_printf("No $DATA in master MFT\n"); + /* + * Read the master MFT record (#0). For NTFS < 3.0, read from cluster 0. + * For NTFS 3.0+, use the standard mft_start location. + */ + if (!is_ntfs_old) { + if (! devread(mft_start,0,mft_size << BLK_SHR,(unsigned long long)(unsigned int)mmft, 0xedde0d90)) return 0; - } + if (! fixup(mmft,mft_size,"FILE",0)) + return 0; + if (! locate_attr(mmft,AT_DATA)) + { + dbg_printf("No $DATA in master MFT\n"); + return 0; + } + } else { + /* NTFS < 3.0: MFT is at cluster 0 */ + if (! devread(0, 0, mft_size << BLK_SHR, (unsigned long long)(unsigned int)mmft, 0xedde0d90)) + return 0; + /* Use special fixup for older NTFS (USA offset 0x2A) */ + if (! fixup_ntfs10(mmft, mft_size)) + return 0; + if (! locate_attr(mmft, AT_DATA)) + { + dbg_printf("No $DATA in master MFT (NTFS < 3.0)\n"); + return 0; + } + } return 1; } + int ntfs_dir (char *dirname) { int ret; @@ -1515,6 +1639,150 @@ ntfs_read(unsigned long long buf, unsigned long long len, unsigned long write) return 0; } +/* ===================================================================== + * NTFS 1.x/2.x specific functions + * ===================================================================== */ + +static int fixup_ntfs10(char* buf, int len) +{ + int ss; + char *pu; + unsigned us; + + /* Check for "FILE" signature */ + if (valueat(buf,0,unsigned long) != valueat("FILE",0,unsigned long)) + return 0; + + ss = valueat(buf,6,unsigned short) - 1; + if (ss * blocksize != len * 512) + return 0; + + /* For NTFS 1.x/2.x, USA (Update Sequence Array) is at offset 0x2A */ + pu = buf + 0x2A; + us = valueat(pu,0,unsigned short); + buf -= 2; + + while (ss > 0) { + buf += blocksize; + pu += 2; + if (valueat(buf,0,unsigned short) != us) + return 0; + valueat(buf,0,unsigned short) = valueat(pu,0,unsigned short); + ss--; + } + return 1; +} + +static int scan_dir_ntfs10(char* cur_mft, char* fn) +{ + char *cur_pos; + + dbg_printf("NTFS < 3.0: scanning root directory\n"); + + /* Check if this is a directory */ + if ((valueat(cur_mft,0x16,unsigned short) & 2)==0) + { + errnum=ERR_FILE_NOT_FOUND; + return 0; + } + + /* Initialize attribute scanning */ + init_attr(cur_mft); + + /* Find $INDEX_ROOT attribute (resident) */ + cur_pos = find_attr(cur_mft, AT_INDEX_ROOT); + if (!cur_pos) { + dbg_printf("NTFS < 3.0: no $INDEX_ROOT\n"); + errnum = ERR_FILE_NOT_FOUND; + return 0; + } + + /* Skip attribute header and go to index root */ + cur_pos += valueat(cur_pos, 0x14, unsigned short); + if (*cur_pos != 0x30) { + dbg_printf("NTFS < 3.0: invalid index root\n"); + errnum = ERR_FILE_NOT_FOUND; + return 0; + } + + /* Skip index root header */ + cur_pos += 0x10; + return list_file_ntfs10(cur_mft, fn, cur_pos + valueat(cur_pos, 0, unsigned short)); +} + +static int list_file_ntfs10(char* cur_mft, char *fn, char *pos) +{ + char *np; + unsigned char *utf8 = (unsigned char *)(NAME_BUF); + unsigned long i, ns, len; + char *fn_lower, *name_lower; + + len = strlen(fn); + + /* Convert filename to lower case for case-insensitive comparison */ + fn_lower = (char*)NAME_BUF + 2048; + for (i = 0; i < len; i++) + fn_lower[i] = tolower(((unsigned char*)fn)[i]); + fn_lower[len] = 0; + + while (1) + { + /* Check for end of index entries */ + if (pos[0xC] & 2) + break; + + /* Extract filename from index entry (NTFS 1.x uses offset 0x52) */ + np = pos + 0x52; + ns = valueat(np, -2, unsigned char); + + /* Extract filename from other entry - betta NT 3.1 version */ + if (ns == 0 || ns > 255) { + np = pos + 0x50; + ns = valueat(np, -2, unsigned char); + dbg_printf("NTFS < 3.0 (beta): trying offset 0x50, len %d\n", ns); + } + if (ns == 0 || ns > 255) { + dbg_printf("NTFS < 3.0: invalid filename length\n"); + pos += valueat(pos, 8, unsigned short); + continue; + } + + unicode_to_utf8((unsigned short *)np, utf8, ns); + + dbg_printf("NTFS < 3.0: found file: %s (len %d)\n", utf8, ns); + + /* Compare lengths */ + if (ns == len) + { + /* Convert found filename to lower case */ + name_lower = (char*)NAME_BUF + 2048 + 256; + for (i = 0; i < ns; i++) + name_lower[i] = tolower(utf8[i]); + name_lower[ns] = 0; + + /* Case-insensitive comparison */ + if (memcmp(fn_lower, name_lower, len) == 0) + { + if (! (print_possibilities)) + { + /* Check for 64-bit MFT number */ + if (valueat(pos,4,unsigned short)) + { + dbg_printf("64-bit MFT number\n"); + return 0; + } + dbg_printf("NTFS < 3.0: found matching file: %s\n", utf8); + return init_file(cur_mft, valueat(pos,0,unsigned long)); + } + } + } + /* Move to next index entry */ + pos += valueat(pos, 8, unsigned short); + } + return -1; +} + + #ifdef FS_UTIL void ntfs_info(int level) From 47570fff78363f6cb3b350bd443689c036656b1a Mon Sep 17 00:00:00 2001 From: Dima <110739028+Dima120596@users.noreply.github.com> Date: Fri, 24 Jul 2026 02:59:22 +0300 Subject: [PATCH 2/2] fix-root-vol-regression fix(cmd): stub broken vol command to prevent root failure on legacy NTFS --- stage2/builtins.c | 357 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 315 insertions(+), 42 deletions(-) diff --git a/stage2/builtins.c b/stage2/builtins.c index 7f30262..93e3217 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -7131,6 +7131,8 @@ get_vol (char* vol_found, int flags) if (flags) n = 0x900ddeed; + //Brokern to NTFS command - temp path: + if (grub_memcmp(fsys_table[fsys_type].name, "ntfs", 4) == 0) { grub_printf("Warning: No Volume support to NTFS"); return; } if (grub_memcmp(fsys_table[fsys_type].name, "iso9660", 7) == 0) { @@ -13147,6 +13149,255 @@ print_vol (unsigned long drive) grub_printf (" Volume Name is \"%s\".", uuid_found); } + // static int +// real_root_func (char *arg, int attempt_mnt) +// { + // char *next; + // unsigned long i, tmp_drive = 0; + // unsigned long tmp_partition = 0; + // char ch; + + // errnum = 0; + // /* get the drive and the partition. */ + // if (! *arg || *arg == ' ' || *arg == '\t') + // { + // current_drive = saved_drive; + // current_partition = saved_partition; + // next = 0; /* if arg is empty, just print the current root device. */ + // } + // else if (grub_memcmp (arg, "endpart", 7) == 0) + // { + // unsigned long part = 0xffffff; + // unsigned long long start, len, offset; + // unsigned long type, entry1, ext_offset1; + + // /* find max/end partition of the current root drive */ + +// #if 0 + // if (! (saved_drive & 0x80)) + // { + // grub_printf ("cannot use 'endpart' with the current root device (fd%d).\n", saved_drive); + // errnum = err_dev_values; + // return 0; + // } +// #endif + + // tmp_partition = saved_partition; + // tmp_drive = saved_drive; + + // current_partition = saved_partition; + // current_drive = saved_drive; + // next = arg + 7; + + // while ((next_partition_drive = current_drive, + // next_partition_dest = 0xffffff, + // next_partition_partition = &part, + // next_partition_type = &type, + // next_partition_start = &start, + // next_partition_len = &len, + // next_partition_offset = &offset, + // next_partition_entry = &entry1, + // next_partition_ext_offset = &ext_offset1, + // next_partition_buf = mbr, + // next_partition ())) + // { + // if (/* type != pc_slice_type_none + // && */ ! is_pc_slice_type_bsd (type) + // && ! is_pc_slice_type_extended (type)) + // { + // saved_partition = current_partition; + // current_partition = part; + // for ntfs and fat not neded with path: + // if (fsys_type != fsys_ntfs && fsys_type != fsys_fat) + // { + // if (! open_device ()) + // current_partition = saved_partition; + // } + + // } + + // /* we want to ignore any error here. */ + // errnum = err_none; + // } + + // saved_drive = tmp_drive; + // saved_partition = tmp_partition; + // errnum = err_none; + + // } + // else if (grub_memcmp (arg, "bootdev", 7) == 0) + // { + // /* use original boot device */ + // current_partition = install_partition; + // current_drive = boot_drive; + // next = arg + 7; + // } + // else + // { + // /* call set_device to get the drive and the partition in arg. */ + // if (! (next = set_device (arg))) + // return 0; + // } + + // if (next) + // { + // /* check the length of the root prefix, i.e., next */ + // for (i = 0; i < sizeof (saved_dir); i++) + // { + // ch = next[i]; + // if (ch == 0 || ch == 0x20 || ch == '\t') + // break; + // if (ch == '\\') + // { + // /* /* saved_dir[i] = ch; + //i++; + //ch = next[i]; + //if (! ch || i >= sizeof (saved_dir)) + //{ + // i--; + // saved_dir[i] = 0; + // break; + //} */ */ + // } + // } + + // if (i >= sizeof (saved_dir)) + // { + // errnum = err_wont_fit; + // return 0; + // } + + // tmp_partition = current_partition; + // tmp_drive = current_drive; + // } + + // errnum = err_none; + + // /* ignore err_fsys_mount. */ + // if (attempt_mnt) + // { + // for ntfs and fat not neded with path: + // if (fsys_type != fsys_ntfs && fsys_type != fsys_fat) + // { + // if (! open_device () && errnum != err_fsys_mount) + // return 0; + // } + +// #if 1 + // if (next) + // { + // unsigned long long hdbias = 0; + // char *biasptr; + // /* bsd and chainloading evil hacks !! */ + // biasptr = skip_to (0, next); + // safe_parse_maxint (&biasptr, &hdbias); + // errnum = 0; + // bootdev = set_bootdev (hdbias); + // } + + // if (errnum) + // return 0; +// #endif + + // if (fsys_type != num_fsys || ! next) + // /* print the type of the filesystem. */ + // { + // if (! next) + // print_root_device (null,0); + // if (! next || debug ) + // print_fsys_type (); + // } + // else + // return ! (errnum = err_fsys_mount); + // } +// #if 1 + // else if (next) + // { + // /* this is necessary, because the location of a partition table + // must be set appropriately. */ + // if (open_partition ()) + // { + // set_bootdev (0); + // if (errnum) + // return 0; + // } + // } +// #endif + + // if (next) + // { + // if (kernel_type == kernel_type_chainloader) + // { + // if (is_io) + // { + // /* dl=drive, dh=media descriptor: 0xf0=floppy, 0xf8=harddrive */ + // chainloader_edx = (tmp_drive & 0xff) | 0xf000 | ((tmp_drive & 0x80) << 4); + // chainloader_edx_set = 1; + + // /* the user might wrongly set these argument, so force them to be correct */ + + // chainloader_ebx = 0; // clear bx for winme + // chainloader_ebx_set = 1; + // chainloader_load_segment = 0x0070; + // chainloader_load_offset = 0; + // chainloader_skip_length = 0x0800; + // } else { + // if (chainloader_edx_set) + // { + // chainloader_edx &= 0xffff0000; + // chainloader_edx |= tmp_drive | ((tmp_partition >> 8) & 0xff00); + // } + + // if (chainloader_ebx_set && chainloader_ebx) + // { + // chainloader_ebx &= 0xffff0000; + // chainloader_ebx |= tmp_drive | ((tmp_partition >> 8) & 0xff00); + // } + // } + // } + + // saved_partition = tmp_partition; + // saved_drive = tmp_drive; + + // /* copy root prefix to saved_dir */ + // for (i = 0; i < sizeof (saved_dir); i++) + // { + // ch = next[i]; + // if (ch == 0 || ch == 0x20 || ch == '\t') + // break; + // if (ch == '\\') + // { + // saved_dir[i] = ch; + // i++; + // ch = next[i]; + // if (! ch || i >= sizeof (saved_dir)) + // { + // i--; + // saved_dir[i] = 0; + // break; + // } + // } + // saved_dir[i] = ch; + // } + + // if (saved_dir[i-1] == '/') + // { + // saved_dir[i-1] = 0; + // } else + // saved_dir[i] = 0; + // } + + // if (debug > 0 && *saved_dir) + // grub_printf (" the current working directory (relative path) is %s\n", saved_dir); + // else if (debug && (! *saved_dir) && attempt_mnt) + // print_vol (current_drive); + // /* clear errnum. */ + // errnum = 0; + // /* if arg is empty, then return true for harddrive, and false for floppy */ + // return next ? 1 : (saved_drive & 0x80); +// } + +// FIXEBLE TO WORK NTFS static int real_root_func (char *arg, int attempt_mnt) { @@ -13171,15 +13422,6 @@ real_root_func (char *arg, int attempt_mnt) /* find MAX/END partition of the current root drive */ -#if 0 - if (! (saved_drive & 0x80)) - { - grub_printf ("Cannot use 'endpart' with the current root device (fd%d).\n", saved_drive); - errnum = ERR_DEV_VALUES; - return 0; - } -#endif - tmp_partition = saved_partition; tmp_drive = saved_drive; @@ -13199,16 +13441,18 @@ real_root_func (char *arg, int attempt_mnt) next_partition_buf = mbr, next_partition ())) { - if (/* type != PC_SLICE_TYPE_NONE - && */ ! IS_PC_SLICE_TYPE_BSD (type) + if (type != PC_SLICE_TYPE_NONE + && ! IS_PC_SLICE_TYPE_BSD (type) && ! IS_PC_SLICE_TYPE_EXTENDED (type)) { saved_partition = current_partition; current_partition = part; - if (attempt_mnt) + /* NTFS and FAT not need open_device() */ + if (attempt_mnt && fsys_type != FSYS_NTFS && fsys_type != FSYS_FAT) { if (! open_device ()) current_partition = saved_partition; + } } @@ -13245,13 +13489,11 @@ real_root_func (char *arg, int attempt_mnt) break; if (ch == '\\') { - //saved_dir[i] = ch; i++; ch = next[i]; if (! ch || i >= sizeof (saved_dir)) { i--; - //saved_dir[i] = 0; break; } } @@ -13272,49 +13514,71 @@ real_root_func (char *arg, int attempt_mnt) /* Ignore ERR_FSYS_MOUNT. */ if (attempt_mnt) { - if (! open_device () && errnum != ERR_FSYS_MOUNT) - return 0; + /* NTFS and FAT not need open_device() */ + if (fsys_type != FSYS_NTFS && fsys_type != FSYS_FAT) + { + if (! open_device () && errnum != ERR_FSYS_MOUNT) + return 0; + } -#if 1 if (next) { - unsigned long long hdbias = 0; - char *biasptr; - - /* BSD and chainloading evil hacks !! */ - biasptr = skip_to (0, next); - safe_parse_maxint (&biasptr, &hdbias); - errnum = 0; - bootdev = set_bootdev (hdbias); + unsigned long long hdbias = 0; + char *biasptr; + /* NTFS and FAT not need BSD and chainloading evil hacks !! */ + if (fsys_type != FSYS_NTFS && fsys_type != FSYS_FAT) + { + /* BSD and chainloading evil hacks !! */ + biasptr = skip_to (0, next); + safe_parse_maxint (&biasptr, &hdbias); + errnum = 0; + bootdev = set_bootdev (hdbias); + } } if (errnum) return 0; -#endif + if (fsys_type != NUM_FSYS || ! next) - /* Print the type of the filesystem. */ - { - if (! next) - print_root_device (NULL,0); - if (! next || debug ) + { + //For ntfs print default information: + if (fsys_type == FSYS_NTFS) + { + if (! next) + { + printf (" Filesystem type is ntfs, partition type 0x07"); + printf (" Volume read has broken "); + //print_vol (current_drive); + } + } + else + { + if (! next) + print_root_device (NULL,0); + if ((! next || debug)) print_fsys_type (); - } + } + + } else return ! (errnum = ERR_FSYS_MOUNT); } -#if 1 else if (next) { /* This is necessary, because the location of a partition table must be set appropriately. */ - if (open_partition ()) - { - set_bootdev (0); - if (errnum) - return 0; + // NTFS and FAT not neded + if (fsys_type != FSYS_NTFS && fsys_type != FSYS_FAT) + { + if (open_partition ()) + { + set_bootdev (0); + if (errnum) + return 0; + } } - } -#endif + } + if (next) { @@ -13381,14 +13645,23 @@ real_root_func (char *arg, int attempt_mnt) if (debug > 0 && *saved_dir) grub_printf (" The current working directory (relative path) is %s\n", saved_dir); - else if (debug && (! *saved_dir) && attempt_mnt) - print_vol (current_drive); + else if (debug && (! *saved_dir) && attempt_mnt) + { + // NTFS and FAT not neded + if (fsys_type != FSYS_NTFS && fsys_type != FSYS_FAT) + { + print_vol (current_drive); + } + } + // /* Clear ERRNUM. */ errnum = 0; /* If ARG is empty, then return TRUE for harddrive, and FALSE for floppy */ return next ? 1 : (saved_drive & 0x80); } + + static int root_func (char *arg, int flags) {