Date: Wed, 1 Oct 2008 15:36:58 +0930 (CST) From: "Daniel J. O'Connor" <darius@midget.dons.net.au> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/127764: Patch to preserve NT disk UID data for boot0cfg Message-ID: <200810010606.m9166wf9031075@midget.dons.net.au> Resent-Message-ID: <200810010630.m916U1Sw000581@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 127764 >Category: bin >Synopsis: Patch to preserve NT disk UID data for boot0cfg >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Oct 01 06:30:01 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Daniel J. O'Connor >Release: FreeBSD 8.0-CURRENT i386 >Organization: >Environment: -current as of 1/Oct/08. >Description: boot0/boot0cfg currently overwrite the NT UID in the MBR which causes MS Windows Vista to fail to boot (unless you follow instructions here http://www.clearchain.com/wiki/FreeBSD_&_Windows_Vista), it can also confuse MS Windows XP. Eugene Grosbein wrote patches and posted them here.. http://groups.google.ru/group/fido7.ru.unix.bsd/browse_thread/thread/dbb7ee5ebc159f73/8dab84b83e46ab84?hl=ru&fwc=2 I'd like them committed as they do work and I expect more people to dual boot Vista these days.. >How-To-Repeat: >Fix: Index: lib/libdisk/write_i386_disk.c =================================================================== RCS file: /usr/CVS-Repository/src/lib/libdisk/write_i386_disk.c,v retrieving revision 1.9 diff -u -r1.9 write_i386_disk.c --- lib/libdisk/write_i386_disk.c 4 Jun 2004 11:49:11 -0000 1.9 +++ lib/libdisk/write_i386_disk.c 25 Jul 2007 02:04:25 -0000 @@ -75,9 +75,9 @@ if (mbrblk[0x1b0] == 0x66 && mbrblk[0x1b1] == 0xbb) { if (edd) - mbrblk[0x1bb] |= 0x80; /* Packet mode on */ + mbrblk[0x1af] |= 0x80; /* Packet mode on */ else - mbrblk[0x1bb] &= 0x7f; /* Packet mode off */ + mbrblk[0x1af] &= 0x7f; /* Packet mode off */ } } @@ -94,6 +94,11 @@ int s[4]; int need_edd = 0; /* Need EDD (packet interface) */ +#ifndef OFF_NTSERNUM +#define OFF_NTSERNUM 0x1b8 +#endif + unsigned char ntsernum[4]; + strcpy(device, _PATH_DEV); strcat(device, d1->name); @@ -108,6 +113,7 @@ } dp = (struct dos_partition *)(mbrblk + DOSPARTOFF); memcpy(work, dp, sizeof work); + memcpy(ntsernum, mbrblk + OFF_NTSERNUM, sizeof(ntsernum)); dp = work; free(mbrblk); for (c1 = d1->chunks->part; c1; c1 = c1->next) { @@ -188,6 +194,7 @@ } if (d1->bootmgr) { memcpy(mbrblk, d1->bootmgr, DOSPARTOFF); + memcpy(mbrblk + OFF_NTSERNUM, ntsernum, sizeof(ntsernum)); Cfg_Boot_Mgr(mbrblk, need_edd); } memcpy(mbrblk + DOSPARTOFF, dp, sizeof *dp * NDOSPART); Index: usr.sbin/boot0cfg/boot0cfg.c =================================================================== RCS file: /usr/CVS-Repository/src/usr.sbin/boot0cfg/boot0cfg.c,v retrieving revision 1.20 diff -u -r1.20 boot0cfg.c --- usr.sbin/boot0cfg/boot0cfg.c 15 Jul 2005 08:04:32 -0000 1.20 +++ usr.sbin/boot0cfg/boot0cfg.c 25 Jul 2007 02:08:04 -0000 @@ -44,10 +44,11 @@ #define MBRSIZE 512 /* master boot record size */ +#define OFF_OPT 0x1ad /* offset: default boot option */ +#define OFF_DRIVE 0x1ae /* offset: setdrv drive */ +#define OFF_FLAGS 0x1af /* offset: option flags */ #define OFF_VERSION 0x1b0 /* offset: version number */ -#define OFF_OPT 0x1b9 /* offset: default boot option */ -#define OFF_DRIVE 0x1ba /* offset: setdrv drive */ -#define OFF_FLAGS 0x1bb /* offset: option flags */ +#define OFF_NTSERNUM 0x1b8 /* offset: NT Drive Serial Number */ #define OFF_TICKS 0x1bc /* offset: clock ticks */ #define OFF_PTBL 0x1be /* offset: partition table */ #define OFF_MAGIC 0x1fe /* offset: magic number */ @@ -154,15 +155,17 @@ write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size); /* - * If we are installing the boot loader, read it from disk and copy the - * slice table over from the existing MBR. If not, then point boot0 - * back at the MBR we just read in. After this, boot0 is the data to - * write back to disk if we are going to do a write. + * If we are installing the boot loader, read it from disk and + * copy the slice table and NT Drive Serial Number over from the + * existing MBR. If not, then point boot0 back at the MBR we just + * read in. After this, boot0 is the data to write back to disk + * if we are going to do a write. */ if (B_flag) { boot0_size = read_mbr(bpath, &boot0, 1); memcpy(boot0 + OFF_PTBL, mbr + OFF_PTBL, sizeof(struct dos_partition) * NDOSPART); + memcpy(boot0 + OFF_NTSERNUM, mbr + OFF_NTSERNUM, 4); } else { boot0 = mbr; boot0_size = mbr_size; @@ -374,6 +377,7 @@ static u_int8_t id0[] = {0xfc, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8, 0x8e, 0xd0, 0xbc, 0x00, 0x7c }; static u_int8_t id1[] = {'D', 'r', 'i', 'v', 'e', ' '}; + static u_int8_t id1_alt[] = {'D', 'i', 's', 'k', ' '}; static struct { unsigned off; unsigned len; @@ -381,11 +385,16 @@ } ident[2] = { {0x0, sizeof(id0), id0}, {0x1b2, sizeof(id1), id1} + }, ident_alt[2] = { + {0x0, sizeof(id0), id0}, + {0x1b2, sizeof(id1_alt), id1_alt} }; + unsigned int i; for (i = 0; i < sizeof(ident) / sizeof(ident[0]); i++) - if (memcmp(bs + ident[i].off, ident[i].key, ident[i].len)) + if (memcmp(bs + ident[i].off, ident[i].key, ident[i].len) && + memcmp(bs + ident_alt[i].off, ident_alt[i].key, ident_alt[i].len)) return 0; return 1; } Index: sys/boot/i386/boot0/boot0.S =================================================================== RCS file: /usr/CVS-Repository/src/sys/boot/i386/boot0/boot0.S,v retrieving revision 1.16 diff -u -r1.16 boot0.S --- sys/boot/i386/boot0/boot0.S 26 Mar 2007 21:56:13 -0000 1.16 +++ sys/boot/i386/boot0/boot0.S 25 Jul 2007 01:58:13 -0000 @@ -45,10 +45,10 @@ * Addresses in the sector of embedded data values. * Accessed with negative offsets from the end of the relocated sector (%ebp). */ - .set _NXTDRV,-0x48 # Next drive - .set _OPT,-0x47 # Default option - .set _SETDRV,-0x46 # Drive to force - .set _FLAGS,-0x45 # Flags + .set _NXTDRV,-0x49 # Next drive + .set _OPT,-0x53 # Default option + .set _SETDRV,-0x52 # Drive to force + .set _FLAGS,-0x51 # Flags .set _TICKS,-0x44 # Timeout ticks .set _FAKE,0x0 # Fake partition entry .set _MNUOPT,0xc # Menu options @@ -427,7 +427,7 @@ .byte os_dos-. # Windows .byte os_dos-. # Windows .byte os_linux-. # Linux - .byte os_freebsd-. # FreeBSD + .byte os_bsd-. # FreeBSD .byte os_bsd-. # OpenBSD .byte os_bsd-. # NetBSD .byte os_misc-. # Unknown @@ -438,9 +438,13 @@ os_misc: .ascii "?"; .byte '?'|0x80 os_dos: .ascii "DO"; .byte 'S'|0x80 os_linux: .ascii "Linu"; .byte 'x'|0x80 -os_freebsd: .ascii "Free" os_bsd: .ascii "BS"; .byte 'D'|0x80 + .byte 0x90 # free space +opt: .byte 0x0 # Option +setdrv: .byte 0x80 # Drive to force +flags: .byte FLAGS # Flags + .org PRT_OFF-0xe,0x90 .word B0MAGIC # Magic number @@ -450,11 +454,9 @@ * Be especially careful that nxtdrv: must come after drive:, as it * is part of the same string. */ -drive: .ascii "Drive " +drive: .ascii "Disk " nxtdrv: .byte 0x0 # Next drive number -opt: .byte 0x0 # Option -setdrv: .byte 0x80 # Drive to force -flags: .byte FLAGS # Flags + .byte 0xa8,0xa8,0xa8,0xa8 # NT Drive Serial Number ticks: .word TICKS # Delay /* >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810010606.m9166wf9031075>