Jump to content











Photo
* * * * * 1 votes

Grub4dos Find and boot


  • Please log in to reply
113 replies to this topic

#26 steve6375

steve6375

    Platinum Member

  • Developer
  • 7566 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
  •  
    United Kingdom

Posted 25 April 2013 - 04:00 PM

(bd) is the current drive or volume,  e.g. ls (bd)/  will list files on the boot volume.

 

I have added more comments below.

title Boot to Windows from an internal hard disk
# map some random 8 sectors in memory containing junk data as current disk device  (usually bd=hd0)
# using +1 will fail, using +2 or more will work, +8 is arbitrary!, --mem is not required as md is memory anyway???
map --mem (md)+8 (bd)
map --hook

# any access to (bd) = (hd0) will access memory sectors and result in bad partition message
# thus find command will try to access hd0 but fail as it is just junk!
find --set-root --ignore-floppies --ignore-cd /bootmgr || find --set-root --ignore-floppies --ignore-cd /ntldr

# this maps the current boot drive (hd0) to (hd0) again  and not (md)
map (bd) (bd)

# use rehook as --hook does not work (reports 'empty drive map table')
map --rehook
chainloader /bootmgr || chainloader /ntldr

a map command adds a mapping to a 'map table'

 

when you 'hook' it adds a patch to a 'hooked map table' which is in the int 13h interrupt handler.

 

so --hook will patch the interrupt table by patching any new map commands to the  current 'hooked map' table

 

If you use --rehook, it discards the whole current hooked map table, and then re-creates the hooked map table based on the current 'map' table.

 

As we have just mapped (bd) to (bd), the current map table will be empty of mappings so the new 'hooked map' table will be empty but rehook will not complain about an empty map table whereas hook does - so we need to use rehook.

 

We could just have used instead:

map --unhook
map --unmap=0x80

or

 

map (0x80) (0x80)
map --rehook


#27 steve6375

steve6375

    Platinum Member

  • Developer
  • 7566 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
  •  
    United Kingdom

Posted 25 April 2013 - 04:00 PM

(bd) is the current drive or volume,  e.g. ls (bd)/  will list files on the boot volume.

 

I have added more comments below.

title Boot to Windows from an internal hard disk
# map some random 8 sectors in memory containing junk data as current disk device  (usually bd=hd0)
# using +1 will fail, using +2 or more will work, +8 is arbitrary!, --mem is not required as md is memory anyway???
map --mem (md)+8 (bd)
map --hook

# any access to (bd) = (hd0) will access memory sectors and result in bad partition message
# thus find command will try to access hd0 but fail as it is just junk!
find --set-root --ignore-floppies --ignore-cd /bootmgr || find --set-root --ignore-floppies --ignore-cd /ntldr

# this maps the current boot drive (hd0) to (hd0) again  and not (md)
map (bd) (bd)

# use rehook as --hook does not work (reports 'empty drive map table')
map --rehook
chainloader /bootmgr || chainloader /ntldr

a map command adds a mapping to a 'map table'

 

when you 'hook' it adds a patch to a 'hooked map table' which is in the int 13h interrupt handler.

 

so --hook will patch the interrupt table by patching any new map commands to the  current 'hooked map' table

 

If you use --rehook, it discards the whole current hooked map table, and then re-creates the hooked map table based on the current 'map' table.

 

As we have just mapped (bd) to (bd), the current map table will be empty of mappings so the new 'hooked map' table will be empty but rehook will not complain about an empty map table whereas hook does - so we need to use rehook.

 

We could just have used instead:

map --unhook
map --unmap=0x80

or

 

map (0x80) (0x80)
map --rehook


#28 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 25 April 2013 - 04:43 PM

Maybe I am starting to understand.

The (bd) remains "(hd0)" this is the part that i was completely failing to understand.

Drive 0x80 is still "drive 128" or (hd0), right?

 

 

So this works "as is" ONLY if the bootdisk is (hd0).

I mean if the (bd) is floppy or cd it is unneeded, as in that case what really "works" is the " --ignore-floppies --ignore-cd" in the find command :unsure:

BUT there is still something that still seems to me NOT entirely "kosher".

 

If you boot to grub4dos without a menu.lst, when you do (example):

 

 

root (bd)

 

you get something like:

 

 

Filesystem type is fat, partition type 0x06

and if you do immediately after:

 

 

root

 

you get:

 

 

(hd0,0) Filesystem type is fat, partition type 0x06

so (bd) is not the disk aka (hd0) but rather the partition on it aka (hd0,0) in this example.

 

It is possible that when you do the map:

 

 

map (md)+8 (bd)

(bd) is interpreted (special case :w00t:) as the whole disk and not just the partition on it. :dubbio:

 

:cheers:

Wonko



#29 steve6375

steve6375

    Platinum Member

  • Developer
  • 7566 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
  •  
    United Kingdom

Posted 25 April 2013 - 04:51 PM

i think it can be either,    ls (bd)/  lists files...



#30 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 26 April 2013 - 10:04 AM

i think it can be either,    ls (bd)/  lists files...

Yes :), BUT there is an issue. :ph34r:
If the (bd) (whole disk, still (hd0)) has more than one partition the sheer moment you map it the "fake" (md)+8 disk to it, you "lose" not only the first partition, but also all the others on the same disk. :w00t:


The result of:



  
map (md)+8 (bd)
map --hook

 
and of:
 



  
map (md)+8 (hd0,0)
map --hook

 
 
 



 
map (md)+8 (hd0)
map --hook

 
is exactly the same.
I seem :unsure: to remember that once you could not map to a partition, but only to a disk. Probably this has changed in the sense that the "to" is intended to be the disk where the partition resides (which would makes sense as what you have in map --status is disk 0x80).

 

We must anyway find another way for multipartitioned (bd)'s. :frusty:

 

:cheers:

Wonko



#31 jc24

jc24

    Newbie

  • Members
  • 11 posts

Posted 28 April 2013 - 12:54 PM

I've tested both the stripped menu.lst I posted in #14 works as well as incorporated into a large menu.lst, each with the same result.



#32 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 28 April 2013 - 01:13 PM

I've tested both the stripped menu.lst I posted in #14 works as well as incorporated into a large menu.lst, each with the same result.

I am not sure to understand :unsure:, actually I am sure I am not understanding. :ph34r:

What does the menu.lst Steve6375 posted on #16, used EXACTLY "as is" AND WITHOUT any change:

  1. Work?
  2. Does NOT work?

:cheers:

Wonko

 

P.S.: OT :ph34r:, but not much ;), digging in some (half-chinese) grub4dos batches on chenall's :worship: blog, I found a possible way to list just the devices available (as opposed to "try" each and every device, like (hd0,0);(hd0,1);(hd0,2) etc.):

 

 



find --devices=h

the batch also has a way to make a list by writing to (md) and re-parsing the output, which I tried to adapt to variable assignment:

finddev.g4b:

 

 






!BAT
set n=1
set skip=0
find --devices=h > (md)0x20A+6
call :loop
clear
set dev
goto :EOF


:loop
debug off
cat --locate=\x0a --number=1 --skip=%skip% (md)0x20A+6 || exit
set /a length=%?%-%skip%
cat --skip=%skip% --length=%length% (md)0x20A+6 | set dev%n%=
set /a skip=%length%+%skip%+1
set /a n=%n%+1
goto :loop


#33 jc24

jc24

    Newbie

  • Members
  • 11 posts

Posted 29 April 2013 - 11:36 AM

I just realized my issue. During my initial testing the only copy of bootmgr was on (cd) and not (cd0) or (cd1). I confirm that post #14 also works. Apologies for the trouble.



#34 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 29 April 2013 - 11:48 AM

I just realized my issue. During my initial testing the only copy of bootmgr was on (cd) and not (cd0) or (cd1). I confirm that post #14 also works. Apologies for the trouble.

Good, but what does:

 

 

find --devices=c

return in your setup?

 

And:

 

 

find --devices=ch

?

:cheers:

Wonko



#35 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 07 May 2013 - 04:23 AM

Hi.
First, thank you DarkPhoeniX, steve6375 and Wonko for the scripts and for the good ideas.
But I noticed that the speed is still an issue, especially when you try to search into a higher number of drives/partitions (3..5).
The "culprits" are:
- the "find" function (used twice instead of one time);
- the "iftitle"'s;
So I modified the script for one "find" and no "iftitle"'s.

ntsearch.lst:

 

 

clear
echo Please wait, searching...
debug 1
debug on
find --ignore-floppies --ignore-cd /ntldr > (md)0x220+1
debug off

cat --locate="(hd0,0)" (md)0x220+1 > nul && set BNTM11=title Boot to Windows NT/2000/XP on first HDD, first partition\\nUsually the USB drive...\r\nroot (hd0,0)\r\nchainloader /ntldr\r\n
cat --locate="(hd0,1)" (md)0x220+1 > nul && set BNTM12=title Boot to Windows NT/2000/XP on first HDD, second partition\\nUsually the USB drive...\r\nroot (hd0,1)\r\nchainloader /ntldr\r\n
cat --locate="(hd0,2)" (md)0x220+1 > nul && set BNTM13=title Boot to Windows NT/2000/XP on first HDD, third partition\\nUsually the USB drive...\r\nroot (hd0,2)\r\nchainloader /ntldr\r\n
cat --locate="(hd0,3)" (md)0x220+1 > nul && set BNTM14=title Boot to Windows NT/2000/XP on first HDD, fourth partition\\nUsually the USB drive...\r\nroot (hd0,3)\r\nchainloader /ntldr\r\n
cat --locate="(hd0,4)" (md)0x220+1 > nul && set BNTM15=title Boot to Windows NT/2000/XP on first HDD, fifth partition\\nUsually the USB drive...\r\nroot (hd0,4)\r\nchainloader /ntldr\r\n

cat --locate="(hd1,0)" (md)0x220+1 > nul && set BNTM21=title Boot to Windows NT/2000/XP on second HDD, first partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /ntldr\r\n
cat --locate="(hd1,1)" (md)0x220+1 > nul && set BNTM22=title Boot to Windows NT/2000/XP on second HDD, second partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /ntldr\r\n
cat --locate="(hd1,2)" (md)0x220+1 > nul && set BNTM23=title Boot to Windows NT/2000/XP on second HDD, third partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /ntldr\r\n
cat --locate="(hd1,3)" (md)0x220+1 > nul && set BNTM24=title Boot to Windows NT/2000/XP on second HDD, fourth partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /ntldr\r\n
cat --locate="(hd1,4)" (md)0x220+1 > nul && set BNTM25=title Boot to Windows NT/2000/XP on second HDD, fifth partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /ntldr\r\n

cat --locate="(hd2,0)" (md)0x220+1 > nul && set BNTM31=title Boot to Windows NT/2000/XP on third HDD, first partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /ntldr\r\n
cat --locate="(hd2,1)" (md)0x220+1 > nul && set BNTM32=title Boot to Windows NT/2000/XP on third HDD, second partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /ntldr\r\n
cat --locate="(hd2,2)" (md)0x220+1 > nul && set BNTM33=title Boot to Windows NT/2000/XP on third HDD, third partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /ntldr\r\n
cat --locate="(hd2,3)" (md)0x220+1 > nul && set BNTM34=title Boot to Windows NT/2000/XP on third HDD, fourth partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /ntldr\r\n
cat --locate="(hd2,4)" (md)0x220+1 > nul && set BNTM35=title Boot to Windows NT/2000/XP on third HDD, fifth partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /ntldr\r\n

cat --locate="(hd3,0)" (md)0x220+1 > nul && set BNTM41=title Boot to Windows NT/2000/XP on fourth HDD, first partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /ntldr\r\n
cat --locate="(hd3,1)" (md)0x220+1 > nul && set BNTM42=title Boot to Windows NT/2000/XP on fourth HDD, second partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /ntldr\r\n
cat --locate="(hd3,2)" (md)0x220+1 > nul && set BNTM43=title Boot to Windows NT/2000/XP on fourth HDD, third partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /ntldr\r\n
cat --locate="(hd3,3)" (md)0x220+1 > nul && set BNTM44=title Boot to Windows NT/2000/XP on fourth HDD, fourth partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /ntldr\r\n
cat --locate="(hd3,4)" (md)0x220+1 > nul && set BNTM45=title Boot to Windows NT/2000/XP on fourth HDD, fifth partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /ntldr\r\n

cat --locate="(hd4,0)" (md)0x220+1 > nul && set BNTM51=title Boot to Windows NT/2000/XP on fifth HDD, first partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /ntldr\r\n
cat --locate="(hd4,1)" (md)0x220+1 > nul && set BNTM52=title Boot to Windows NT/2000/XP on fifth HDD, second partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /ntldr\r\n
cat --locate="(hd4,2)" (md)0x220+1 > nul && set BNTM53=title Boot to Windows NT/2000/XP on fifth HDD, third partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /ntldr\r\n
cat --locate="(hd4,3)" (md)0x220+1 > nul && set BNTM54=title Boot to Windows NT/2000/XP on fifth HDD, fourth partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /ntldr\r\n
cat --locate="(hd4,4)" (md)0x220+1 > nul && set BNTM55=title Boot to Windows NT/2000/XP on fifth HDD, fifth partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /ntldr\r\n

if "%BNTM11%%BNTM12%%BNTM13%%BNTM14%%BNTM15%%BNTM21%%BNTM22%%BNTM23%%BNTM24%%BNTM25%%BNTM31%%BNTM32%%BNTM33%%BNTM34%%BNTM35%%BNTM41%%BNTM42%%BNTM43%%BNTM44%%BNTM45%%BNTM51%%BNTM52%%BNTM53%%BNTM54%%BNTM55%"=="" clear && echo No bootable Windows NT/2000/XP partitions found, returning to main menu... && pause --wait=5 && configfile (bd)/menu.lst
write (md)0x220+2 %BNTM11%%BNTM12%%BNTM13%%BNTM14%%BNTM15%%BNTM21%%BNTM22%%BNTM23%%BNTM24%%BNTM25%%BNTM31%%BNTM32%%BNTM33%%BNTM34%%BNTM35%%BNTM41%%BNTM42%%BNTM43%%BNTM44%%BNTM45%%BNTM51%%BNTM52%%BNTM53%%BNTM54%%BNTM55%title\r\nroot\r\ntitle Return to main menu...\r\nconfigfile (bd)/menu.lst\r\n\0
configfile (md)0x220+2

 

mgrsearch.lst:

 

 

 

clear
echo Please wait, searching...
debug 1
debug on
find --ignore-floppies --ignore-cd /bootmgr > (md)0x220+1
debug off

cat --locate="(hd0,0)" (md)0x220+1 > nul && set BMGRM11=title Boot to Windows Vista/7/8 on first HDD, first partition\\nUsually the USB drive...\r\nroot (hd0,0)\r\nchainloader /bootmgr\r\n
cat --locate="(hd0,1)" (md)0x220+1 > nul && set BMGRM12=title Boot to Windows Vista/7/8 on first HDD, second partition\\nUsually the USB drive...\r\nroot (hd0,1)\r\nchainloader /bootmgr\r\n
cat --locate="(hd0,2)" (md)0x220+1 > nul && set BMGRM13=title Boot to Windows Vista/7/8 on first HDD, third partition\\nUsually the USB drive...\r\nroot (hd0,2)\r\nchainloader /bootmgr\r\n
cat --locate="(hd0,3)" (md)0x220+1 > nul && set BMGRM14=title Boot to Windows Vista/7/8 on first HDD, fourth partition\\nUsually the USB drive...\r\nroot (hd0,3)\r\nchainloader /bootmgr\r\n
cat --locate="(hd0,4)" (md)0x220+1 > nul && set BMGRM15=title Boot to Windows Vista/7/8 on first HDD, fifth partition\\nUsually the USB drive...\r\nroot (hd0,4)\r\nchainloader /bootmgr\r\n

cat --locate="(hd1,0)" (md)0x220+1 > nul && set BMGRM21=title Boot to Windows Vista/7/8 on second HDD, first partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /bootmgr\r\n
cat --locate="(hd1,1)" (md)0x220+1 > nul && set BMGRM22=title Boot to Windows Vista/7/8 on second HDD, second partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /bootmgr\r\n
cat --locate="(hd1,2)" (md)0x220+1 > nul && set BMGRM23=title Boot to Windows Vista/7/8 on second HDD, third partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /bootmgr\r\n
cat --locate="(hd1,3)" (md)0x220+1 > nul && set BMGRM24=title Boot to Windows Vista/7/8 on second HDD, fourth partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /bootmgr\r\n
cat --locate="(hd1,4)" (md)0x220+1 > nul && set BMGRM25=title Boot to Windows Vista/7/8 on second HDD, fifth partition\\nUsually the first internal HDD...\r\nmap (hd1) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /bootmgr\r\n

cat --locate="(hd2,0)" (md)0x220+1 > nul && set BMGRM31=title Boot to Windows Vista/7/8 on third HDD, first partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /bootmgr\r\n
cat --locate="(hd2,1)" (md)0x220+1 > nul && set BMGRM32=title Boot to Windows Vista/7/8 on third HDD, second partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /bootmgr\r\n
cat --locate="(hd2,2)" (md)0x220+1 > nul && set BMGRM33=title Boot to Windows Vista/7/8 on third HDD, third partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /bootmgr\r\n
cat --locate="(hd2,3)" (md)0x220+1 > nul && set BMGRM34=title Boot to Windows Vista/7/8 on third HDD, fourth partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /bootmgr\r\n
cat --locate="(hd2,4)" (md)0x220+1 > nul && set BMGRM35=title Boot to Windows Vista/7/8 on third HDD, fifth partition\\nUsually the second internal HDD...\r\nmap (hd2) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /bootmgr\r\n

cat --locate="(hd3,0)" (md)0x220+1 > nul && set BMGRM41=title Boot to Windows Vista/7/8 on fourth HDD, first partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /bootmgr\r\n
cat --locate="(hd3,1)" (md)0x220+1 > nul && set BMGRM42=title Boot to Windows Vista/7/8 on fourth HDD, second partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /bootmgr\r\n
cat --locate="(hd3,2)" (md)0x220+1 > nul && set BMGRM43=title Boot to Windows Vista/7/8 on fourth HDD, third partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /bootmgr\r\n
cat --locate="(hd3,3)" (md)0x220+1 > nul && set BMGRM44=title Boot to Windows Vista/7/8 on fourth HDD, fourth partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /bootmgr\r\n
cat --locate="(hd3,4)" (md)0x220+1 > nul && set BMGRM45=title Boot to Windows Vista/7/8 on fourth HDD, fifth partition\\nUsually the third internal HDD...\r\nmap (hd3) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /bootmgr\r\n

cat --locate="(hd4,0)" (md)0x220+1 > nul && set BMGRM51=title Boot to Windows Vista/7/8 on fifth HDD, first partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,0)\r\nchainloader /bootmgr\r\n
cat --locate="(hd4,1)" (md)0x220+1 > nul && set BMGRM52=title Boot to Windows Vista/7/8 on fifth HDD, second partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,1)\r\nchainloader /bootmgr\r\n
cat --locate="(hd4,2)" (md)0x220+1 > nul && set BMGRM53=title Boot to Windows Vista/7/8 on fifth HDD, third partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,2)\r\nchainloader /bootmgr\r\n
cat --locate="(hd4,3)" (md)0x220+1 > nul && set BMGRM54=title Boot to Windows Vista/7/8 on fifth HDD, fourth partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,3)\r\nchainloader /bootmgr\r\n
cat --locate="(hd4,4)" (md)0x220+1 > nul && set BMGRM55=title Boot to Windows Vista/7/8 on fifth HDD, fifth partition\\nUsually the fourth internal HDD...\r\nmap (hd4) (hd0)\r\nmap --hook\r\nroot (hd0,4)\r\nchainloader /bootmgr\r\n

if "%BMGRM11%%BMGRM12%%BMGRM13%%BMGRM14%%BMGRM15%%BMGRM21%%BMGRM22%%BMGRM23%%BMGRM24%%BMGRM25%%BMGRM31%%BMGRM32%%BMGRM33%%BMGRM34%%BMGRM35%%BMGRM41%%BMGRM42%%BMGRM43%%BMGRM44%%BMGRM45%%BMGRM51%%BMGRM52%%BMGRM53%%BMGRM54%%BMGRM55%"=="" clear && echo No bootable Windows Vista/7/8 partitions found, returning to main menu... && pause --wait=5 && configfile (bd)/menu.lst
write (md)0x220+2 %BMGRM11%%BMGRM12%%BMGRM13%%BMGRM14%%BMGRM15%%BMGRM21%%BMGRM22%%BMGRM23%%BMGRM24%%BMGRM25%%BMGRM31%%BMGRM32%%BMGRM33%%BMGRM34%%BMGRM35%%BMGRM41%%BMGRM42%%BMGRM43%%BMGRM44%%BMGRM45%%BMGRM51%%BMGRM52%%BMGRM53%%BMGRM54%%BMGRM55%title\r\nroot\r\ntitle Return to main menu...\r\nconfigfile (bd)/menu.lst\r\n\0
configfile (md)0x220+2

 

I didn't make a script for finding io.sys also because is too old and I haven't seen a computer with 9xME in many years. But, if someone wants it anyway, the script is very easy to "extrapolate" from the other 2. Just use Search&Replace in a text editor...
Also I didn't searched /bootmgr on CD/DVD because, in my opinion, if you have a USB drive, you will want to start /bootmgr faster - so you will copy the CD/DVD in the USB drive and start it from there.

The main "time consumer" is the find function. The rest of the code is quite fast. It's made for 5 drives, each with 5 partitions. But using 2 x 2 or 10 x 10 is not much of a diference (in run time). But for a coder making a 10 x 10 script could be :D

Since it's my first big grub4dos script I'm sure there are mistakes in it and it needs to be improved.
Just be gentle, don't kill me with the first shot  :D

Regards, David

 

later edit: I made some small improvements to the scripts...

 

Later later edit: Well, because of the 512 bytes size limit of the variables in grub4dos, showing 4 or more menu entries was problematic. I fixed that by not using BNTM and BMGRM anymore. The code is a little bit "uglier" but it's functioning better. I updated the scripts.



#36 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 22 May 2013 - 08:48 AM

These scripts are 3x times faster on my computer than my previous ones:

findnt.g4b:
 





!BAT
clear
echo Please wait, searching...
find --devices=h > (md)0x220+8
set SKIPPED=0
set N=0
set BDN=-1
#########   if the batch was started with /abd as parameter it will not search
#########   on boot device (if it's seen as a HDD). Usually is the USB drive (hd0)
if not "%1"=="/abd" goto :noabd
set BDT=%?_BOOT:~1,2%
if "%BDT%"=="hd" set BDN=%?_BOOT:~3,1%
set BDT=
:noabd
:loop
cat --skip=%SKIPPED% --number=1 --locate=" (hd" (md)0x220+8  | set PPOSB=
if "%PPOSB%"=="" goto endloop
set /a SKIPPED=0x%PPOSB%+7 > nul
cat --skip=%SKIPPED% --number=1 --locate=")" (md)0x220+8  | set PPOSE=
if "%PPOSE%"=="" goto endloop
set /a PPOSL=0x%PPOSE%-0x%PPOSB% > nul
set /a SKIPPED=0x%PPOSB%+1 > nul
cat --skip=%SKIPPED% --length=%PPOSL% --locate=" " (md)0x220+8 && set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
cat --skip=%SKIPPED% --length=%PPOSL% --locate="," --number=1 (md)0x220+8 | set CPOS=
if "%CPOS%"=="" set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
set /a PNL=0x%PPOSE%-0x%CPOS%-1 > nul
set /a SKIPPED=0x%CPOS%+1 > nul
cat --skip=%SKIPPED% --length=%PNL% (md)0x220+8 | set PN=
set /a HDNL=0x%CPOS%-0x%PPOSB%-4 > nul
set /a SKIPPED=0x%PPOSB%+4 > nul
cat --skip=%SKIPPED% --length=%HDNL% (md)0x220+8 | set HDN=

if %PN%>=4 goto :notgood
if %BDN%==%HDN% goto notgood
checkrange 0x06:0x0e parttype (hd%HDN%,%PN%) > nul || goto :notgood
if not exist (hd%HDN%,%PN%)/ntldr goto :notgood
set /a N=%N%+1 > nul
if %HDN%==0 set HDNT=first && set HDNTR=USB drive
if %HDN%==1 set HDNT=second && set HDNTR=first internal HDD
if %HDN%==2 set HDNT=third && set HDNTR=second internal HDD
if %HDN%==3 set HDNT=fourth && set HDNTR=third internal HDD
if %HDN%>=4 set HDNT=%HDN%th && set /a HDNN=%HDN%+1 > nul && set HDNTR=%HDN%th internal HDD
if %HDN%==0 set REMAP=
if %HDN%>=1 set REMAP=\r\nmap (hd%HDN%) (hd0)\r\nmap --hook
if %PN%==0 set PNT=first
if %PN%==1 set PNT=second
if %PN%==2 set PNT=third
if %PN%==3 set PNT=fourth

set BNTM%N%=title Boot to Windows NT/2000/XP on %HDNT% HDD, %PNT% partition\\nUsually the %HDNTR%...%REMAP%\r\nroot (hd0,%PN%)\r\nchainloader /ntldr
:notgood

set /a SKIPPED=0x%PPOSE%+2 > nul
if %N%>=10 goto :endloop
goto :loop
:endloop
set BDN=
set SKIPPED=
set PPOSB=
set PPOSE=
set PPOSL=
set CPOS=
set PNL=
set PN=
set HDNL=
set HDN=
set HDNT=
set HDNTR=
set PNT=
set REMAP=
if %N%==0 clear && echo No bootable Windows NT/2000/XP partitions found, returning to main menu... && pause --wait=5 && goto :finish
write (md)0x300+2 %BNTM1%\r\n%BNTM2%\r\n%BNTM3%\r\n%BNTM4%\r\n%BNTM5%\r\n%BNTM6%\r\n%BNTM7%\r\n%BNTM8%\r\n%BNTM9%\r\n%BNTM10%\r\ntitle\r\nroot\r\ntitle Return to main menu...\r\nconfigfile /menu.lst\r\n\0 > nul
set BNTM1=
set BNTM2=
set BNTM3=
set BNTM4=
set BNTM5=
set BNTM6=
set BNTM7=
set BNTM8=
set BNTM9=
set BNTM10=
configfile (md)0x300+2
:finish

findmgr.g4b:

 





!BAT
clear
echo Please wait, searching...
find --devices=h > (md)0x220+8
set SKIPPED=0
set N=0
set BDN=-1
#########   if the batch was started with /abd as parameter it will not search
#########   on boot device (if it's seen as a HDD). Usually is the USB drive (hd0)
if not "%1"=="/abd" goto :noabd
set BDT=%?_BOOT:~1,2%
if "%BDT%"=="hd" set BDN=%?_BOOT:~3,1%
set BDT=
:noabd
:loop
cat --skip=%SKIPPED% --number=1 --locate=" (hd" (md)0x220+8  | set PPOSB=
if "%PPOSB%"=="" goto endloop
set /a SKIPPED=0x%PPOSB%+7 > nul
cat --skip=%SKIPPED% --number=1 --locate=")" (md)0x220+8  | set PPOSE=
if "%PPOSE%"=="" goto endloop
set /a PPOSL=0x%PPOSE%-0x%PPOSB% > nul
set /a SKIPPED=0x%PPOSB%+1 > nul
cat --skip=%SKIPPED% --length=%PPOSL% --locate=" " (md)0x220+8 && set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
cat --skip=%SKIPPED% --length=%PPOSL% --locate="," --number=1 (md)0x220+8 | set CPOS=
if "%CPOS%"=="" set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
set /a PNL=0x%PPOSE%-0x%CPOS%-1 > nul
set /a SKIPPED=0x%CPOS%+1 > nul
cat --skip=%SKIPPED% --length=%PNL% (md)0x220+8 | set PN=
set /a HDNL=0x%CPOS%-0x%PPOSB%-4 > nul
set /a SKIPPED=0x%PPOSB%+4 > nul
cat --skip=%SKIPPED% --length=%HDNL% (md)0x220+8 | set HDN=

if %PN%>=4 goto :notgood
if %BDN%==%HDN% goto notgood
checkrange 0x06:0x0e parttype (hd%HDN%,%PN%) > nul || goto :notgood
if not exist (hd%HDN%,%PN%)/bootmgr goto :notgood
set /a N=%N%+1 > nul
if %HDN%==0 set HDNT=first && set HDNTR=USB drive
if %HDN%==1 set HDNT=second && set HDNTR=first internal HDD
if %HDN%==2 set HDNT=third && set HDNTR=second internal HDD
if %HDN%==3 set HDNT=fourth && set HDNTR=third internal HDD
if %HDN%>=4 set HDNT=%HDN%th && set /a HDNN=%HDN%+1 > nul && set HDNTR=%HDN%th internal HDD
if %HDN%==0 set REMAP=
if %HDN%>=1 set REMAP=\r\nmap (hd%HDN%) (hd0)\r\nmap --hook
if %PN%==0 set PNT=first
if %PN%==1 set PNT=second
if %PN%==2 set PNT=third
if %PN%==3 set PNT=fourth

set BMGRM%N%=title Boot to Windows Vista/7/8 on %HDNT% HDD, %PNT% partition\\nUsually the %HDNTR%...%REMAP%\r\nroot (hd0,%PN%)\r\nchainloader /bootmgr
:notgood

set /a SKIPPED=0x%PPOSE%+2 > nul
if %N%>=10 goto :endloop
goto :loop
:endloop
set BDN=
set SKIPPED=
set PPOSB=
set PPOSE=
set PPOSL=
set CPOS=
set PNL=
set PN=
set HDNL=
set HDN=
set HDNT=
set HDNTR=
set PNT=
set REMAP=
if %N%==0 clear && echo No bootable Windows Vista/7/8 partitions found, returning to main menu... && pause --wait=5 && goto :finish
write (md)0x300+2 %BMGRM1%\r\n%BMGRM2%\r\n%BMGRM3%\r\n%BMGRM4%\r\n%BMGRM5%\r\n%BMGRM6%\r\n%BMGRM7%\r\n%BMGRM8%\r\n%BMGRM9%\r\n%BMGRM10%\r\ntitle\r\nroot\r\ntitle Return to main menu...\r\nconfigfile /menu.lst\r\n\0 > nul
set BMGRM1=
set BMGRM2=
set BMGRM3=
set BMGRM4=
set BMGRM5=
set BMGRM6=
set BMGRM7=
set BMGRM8=
set BMGRM9=
set BMGRM10=
configfile (md)0x300+2
:finish

 

findbwin.g4b:

 





!BAT
clear
echo Please wait, searching...
find --devices=h > (md)0x220+8
set SKIPPED=0
set N=0
set BDN=-1
#########   if the batch was started with /abd as parameter it will not search
#########   on boot device (if it's seen as a HDD). Usually is the USB drive (hd0)
if not "%1"=="/abd" goto :noabd
set BDT=%?_BOOT:~1,2%
if "%BDT%"=="hd" set BDN=%?_BOOT:~3,1%
set BDT=
:noabd
:loop
cat --skip=%SKIPPED% --number=1 --locate=" (hd" (md)0x220+8  | set PPOSB=
if "%PPOSB%"=="" goto endloop
set /a SKIPPED=0x%PPOSB%+7 > nul
cat --skip=%SKIPPED% --number=1 --locate=")" (md)0x220+8  | set PPOSE=
if "%PPOSE%"=="" goto endloop
set /a PPOSL=0x%PPOSE%-0x%PPOSB% > nul
set /a SKIPPED=0x%PPOSB%+1 > nul
cat --skip=%SKIPPED% --length=%PPOSL% --locate=" " (md)0x220+8 && set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
cat --skip=%SKIPPED% --length=%PPOSL% --locate="," --number=1 (md)0x220+8 | set CPOS=
if "%CPOS%"=="" set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
set /a PNL=0x%PPOSE%-0x%CPOS%-1 > nul
set /a SKIPPED=0x%CPOS%+1 > nul
cat --skip=%SKIPPED% --length=%PNL% (md)0x220+8 | set PN=
set /a HDNL=0x%CPOS%-0x%PPOSB%-4 > nul
set /a SKIPPED=0x%PPOSB%+4 > nul
cat --skip=%SKIPPED% --length=%HDNL% (md)0x220+8 | set HDN=

if %PN%>=4 goto :notgood
if %BDN%==%HDN% goto notgood
checkrange 0x06:0x0e parttype (hd%HDN%,%PN%) > nul || goto :notgood

if not exist (hd%HDN%,%PN%)/bootmgr goto :nomgr
set /a N=%N%+1 > nul
if %HDN%==0 set HDNT=first && set HDNTR=USB drive
if %HDN%==1 set HDNT=second && set HDNTR=first internal HDD
if %HDN%==2 set HDNT=third && set HDNTR=second internal HDD
if %HDN%==3 set HDNT=fourth && set HDNTR=third internal HDD
if %HDN%>=4 set HDNT=%HDN%th && set /a HDNN=%HDN%+1 > nul && set HDNTR=%HDN%th internal HDD
if %HDN%==0 set REMAP=
if %HDN%>=1 set REMAP=\r\nmap (hd%HDN%) (hd0)\r\nmap --hook
if %PN%==0 set PNT=first
if %PN%==1 set PNT=second
if %PN%==2 set PNT=third
if %PN%==3 set PNT=fourth

set BWINM%N%=title Boot to Windows Vista/7/8 on %HDNT% HDD, %PNT% partition\\nUsually the %HDNTR%...%REMAP%\r\nroot (hd0,%PN%)\r\nchainloader /bootmgr
:nomgr

if not exist (hd%HDN%,%PN%)/ntldr goto :nont
set /a N=%N%+1 > nul
if %HDN%==0 set HDNT=first && set HDNTR=USB drive
if %HDN%==1 set HDNT=second && set HDNTR=first internal HDD
if %HDN%==2 set HDNT=third && set HDNTR=second internal HDD
if %HDN%==3 set HDNT=fourth && set HDNTR=third internal HDD
if %HDN%>=4 set HDNT=%HDN%th && set /a HDNN=%HDN%+1 > nul && set HDNTR=%HDN%th internal HDD
if %HDN%==0 set REMAP=
if %HDN%>=1 set REMAP=\r\nmap (hd%HDN%) (hd0)\r\nmap --hook
if %PN%==0 set PNT=first
if %PN%==1 set PNT=second
if %PN%==2 set PNT=third
if %PN%==3 set PNT=fourth

set BWINM%N%=title Boot to Windows NT/2000/XP on %HDNT% HDD, %PNT% partition\\nUsually the %HDNTR%...%REMAP%\r\nroot (hd0,%PN%)\r\nchainloader /ntldr
:nont

:notgood

set /a SKIPPED=0x%PPOSE%+2 > nul
if %N%>=15 goto :endloop
goto :loop
:endloop
set BDN=
set SKIPPED=
set PPOSB=
set PPOSE=
set PPOSL=
set CPOS=
set PNL=
set PN=
set HDNL=
set HDN=
set HDNT=
set HDNTR=
set PNT=
set REMAP=
if %N%==0 clear && echo No bootable Windows NT/2000/XP/Vista/7/8 partitions found, returning to main menu... && pause --wait=5 && goto :finish
write (md)0x300+3 %BWINM1%\r\n%BWINM2%\r\n%BWINM3%\r\n%BWINM4%\r\n%BWINM5%\r\n%BWINM6%\r\n%BWINM7%\r\n%BWINM8%\r\n%BWINM9%\r\n%BWINM10%\r\n%BWINM11%\r\n%BWINM12%\r\n%BWINM13%\r\n%BWINM14%\r\n%BWINM15%\r\ntitle\r\nroot\r\ntitle Return to main menu...\r\nconfigfile /menu.lst\r\n\0 > nul
set BWINM1=
set BWINM2=
set BWINM3=
set BWINM4=
set BWINM5=
set BWINM6=
set BWINM7=
set BWINM8=
set BWINM9=
set BWINM10=
set BWINM11=
set BWINM12=
set BWINM13=
set BWINM14=
set BWINM15=
configfile (md)0x300+3
:finish

 

Latest changes:

- corrected some minor problems;

- added /abd as parameter to avoid search on boot device;

- added findbwin.g4b to search ntldr and bootmgr in the same time.



#37 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 22 May 2013 - 07:31 PM

If I may:

checkrange 0x07,0x0c parttype (hd%HDN%,%PN%) > nul || goto :notgood

 

I can understand removing support for FAT12 and small FAT16 partitions, but FAT 16 CHS and/or LBA mapped partition can often be found.... :unsure:

Maybe 06 - 0E could be an enhancement.

 

:cheers:

Wonko



#38 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 23 May 2013 - 12:10 AM

Sure, why not... Thanks for the idea.
I modified the scripts.

Another way to make it faster could be to exclude logical partitions. I never installed Windows there but I don't remember seeing ntldr or bootmgr in that location on any computer... I think only primary partitions can be bootable (in Windows). I hope I'm not wrong :D

Another thing: is there a fast and sure way to detect which one of the hd's is internal and which one is external...? Or perhaps the manufacturer and/or the size... The idea is to help the user to figure out more easily which one should choose to boot.



#39 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 23 May 2013 - 08:43 AM

Another way to make it faster could be to exclude logical partitions. I never installed Windows there but I don't remember seeing ntldr or bootmgr in that location on any computer... I think only primary partitions can be bootable (in Windows). I hope I'm not wrong :D

The good news are that extended partitions are already excluded, the bad news are that you are wrong as you don't want to exclude extended partitions, but rather logical volumes inside extended (and yes, you are wrong, it is possible to have a logical volume inside extended bootable, by correcting the "sectors before" in it's bootsector).

The other good news are that any logical volume inside extended will be (hdm,n) where n >=4 so, it's easy to exclude them.

 

 

Another thing: is there a fast and sure way to detect which one of the hd's is internal and which one is external...? Or perhaps the manufacturer and/or the size... The idea is to help the user to figure out more easily which one should choose to boot.

Not one that I can remember right now :dubbio:, but I doubt there is one at all.

 

:cheers:

Wonko



#40 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 23 May 2013 - 09:38 AM

The good news are that extended partitions are already excluded, the bad news are that you are wrong as you don't want to exclude extended partitions, but rather logical volumes inside extended

 

Well, I said "logical" not "extended"... :D

 

(and yes, you are wrong, it is possible to have a logical volume inside extended bootable, by correcting the "sectors before" in it's bootsector).

 

I'm curious, could you give some example about how a user installing Windows could "correct the "sectors before" in it's bootsector"?

 

The other good news are that any logical volume inside extended will be (hdm,n) where n >=4 so, it's easy to exclude them.

 

I knew that from Steve's website but I wanted to be absolutely sure, because I have met (rare) situations in which the partitions were not numbered correctly.

In conclusion, should I exclude logical volumes or not?

 

Another thing: is there another way (not "ls" or "exist") to know that a name found with "ls" is a filename? Why do I ask: because I want to "combine" the search for ntldr and bootmgr into one: I use "ls (hd*,*)/ > (md)", search the filenames there and find if there are files. This could be a little faster than 2 "if exist".



#41 steve6375

steve6375

    Platinum Member

  • Developer
  • 7566 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
  •  
    United Kingdom

Posted 23 May 2013 - 10:03 AM

Another thing: is there another way (not "ls" or "exist") to know that a name found with "ls" is a filename? Why do I ask: because I want to "combine" the search for ntldr and bootmgr into one: I use "ls (hd*,*)/ > (md)", search the filenames there and find if there are files. This could be a little faster than 2 "if exist".

 

There is no good way that I know! What I do is check that the 'file' is 0 length using cat --length=0,  and that it has no extension but that is not perfect as you could have a directory called fred.me  or a file of 0 length called fred.

 

P.S. Anyone else having problems with reboot.pro in the last week?



#42 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 23 May 2013 - 10:52 AM

Thank you.
Sorry, I forgot to mention "cat --length=0" with "ls" and "exist" in my previous reply. My fault... :(
I tried it before asking but it doesn't seem fast. 1 "ls" + 2 "cat --length=0" are equal in speed with 2 "exist".

On my computer reboot.pro always is loaded and refreshed slow. Windows, Linux, different browsers, same... I don't have this problem with other sites...

 

PS: ping is returning "Request timed out" in 1 from 10..12.



#43 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 23 May 2013 - 01:20 PM

Well, I said "logical" not "extended"... :D

Well, that would be worse, as:
  • Extended partition <- exists as an entry in the MBR partition table
  • Logical volume(s) inside Extended (sometimes wrongly defined "Logical partition(s)<- exist but only as an entry in one the EMBR(s) in the in the EMBR's chain
The issue, as often happens is with the concept of "volume" (the thing that normally gets a drive letter in windows, thus often called "drive").
If a partition is primary it contains a single volume and this volume normally extends for the whole partition (minus one sector if NTFS), normally in the case of primary partitions a volume is the same thing as the partition itself and the two terms are often used as synonyms. To be exact this is a volume inside primary partition.
 
If a partition is extended it contains one or more further "partitions", each containing a single volume. There are as many EMBR's as logical volumes inside it. To be exact this is a volume inside extended partition.
 

The MBR has four partition entries or "slots".
These are (usually) numbered starting from 0 (Windows Arcpaths and Linux and now also GRUB2 number them starting from 1) :
#0 offset 446
#1 offset 462
#2 offset 478
#3 offset 494
Of these ONLY one can be addressing an extended partition.
An extended partition ID MUST be either of 05 or 0F.
Entries are normally (and should, but it is not compulsory) be in the same order they are physically laid out on the disk.
grub4dos:
(hd0,0) means "the volume inside the partition on first hard disk that is in slot #0, UNLESS it's ID is 05 or 0F"
(hd0,1) means "the volume inside the partition on first hard disk that is in slot #1, UNLESS it's ID is 05 or 0F"
(hd0,2) means "the volume inside the partition on first hard disk that is in slot #2, UNLESS it's ID is 05 or 0F"
(hd0,3) means "the volume inside the partition on first hard disk that is in slot #3, UNLESS it's ID is 05 or 0F"
 
IF the ID in any of the above is 05 or 0F, than the corresponding "slot" is ignored by grub4dos and the first logical volume inside the corresponding extended partition becomes (hd0,4), the second (hd0,5), etc.
 
I'm curious, could you give some example about how a user installing Windows could "correct the "sectors before" in it's bootsector"?
The base theory is on gooddell's pages here:
http://www.goodells.net/multiboot/
http://www.goodells....ot/ptable.shtml
 
but grub4dos has a function that will also do that, called "partnew".
By executing partnew grub4dos also corrects the sectors before ion the PBR (or bootsector) of the volume.
(i.e. you can make a backup of a partition entry, run partnew, to create a new entry for the volume inside extended and thus have also the PBR corrected and then restore the previous partition entry in the MBR).
 
It seems like BOOTMGR does not need this correction (though NTLDR does and it is anyway a good idea to have it).
See:
http://reboot.pro/to...ical-partition/
http://reboot.pro/to...s-also-logical/
 
In conclusion, should I exclude logical volumes or not?
As hinted elsewhere:
http://reboot.pro/to...-vs-long-delay/
the "ideal" solution IMHO would be a "fastish" list of primaries and an optional (if not found) slower one including the logical volumes.
 
Another thing: is there another way (not "ls" or "exist") to know that a name found with "ls" is a filename? Why do I ask: because I want to "combine" the search for ntldr and bootmgr into one: I use "ls (hd*,*)/ > (md)", search the filenames there and find if there are files. This could be a little faster than 2 "if exist".
I am not sure to understand this, can you try to explain/expand?
 
:cheers:
Wonko

#44 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 25 May 2013 - 04:06 AM

Well, I made a detection of OS type using ntldr/bootmgr file length. It's not 100% perfect but it's close and it can be improved in time:

 





!BAT
clear
echo Please wait, searching...
find --devices=h > (md)0x220+8
set SKIPPED=0
set N=0
set BDN=-1
#########   if the batch was started with /abd as parameter it will not search
#########   on boot device (if it's seen as a HDD). Usually is the USB drive (hd0)
if "%1"=="/abd" if "%?_BOOT:~1,2%"=="hd" set BDN=%?_BOOT:~3,1%
:loop
cat --skip=%SKIPPED% --number=1 --locate=" (hd" (md)0x220+8  | set PPOSB=
if "%PPOSB%"=="" goto endloop
set /a SKIPPED=0x%PPOSB%+7 > nul
cat --skip=%SKIPPED% --number=1 --locate=")" (md)0x220+8  | set PPOSE=
if "%PPOSE%"=="" goto endloop
set /a PPOSL=0x%PPOSE%-0x%PPOSB% > nul
set /a SKIPPED=0x%PPOSB%+1 > nul
cat --skip=%SKIPPED% --length=%PPOSL% --locate=" " (md)0x220+8 && set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
cat --skip=%SKIPPED% --length=%PPOSL% --locate="," --number=1 (md)0x220+8 | set CPOS=
if "%CPOS%"=="" set /a SKIPPED=0x%PPOSB%+7 > nul && goto :loop
set /a PNL=0x%PPOSE%-0x%CPOS%-1 > nul
set /a SKIPPED=0x%CPOS%+1 > nul
cat --skip=%SKIPPED% --length=%PNL% (md)0x220+8 | set PN=
set /a HDNL=0x%CPOS%-0x%PPOSB%-4 > nul
set /a SKIPPED=0x%PPOSB%+4 > nul
cat --skip=%SKIPPED% --length=%HDNL% (md)0x220+8 | set HDN=

if %PN%>=4 goto :notgood
if %BDN%==%HDN% goto notgood
checkrange 0x06:0x0e parttype (hd%HDN%,%PN%) > nul || goto :notgood

ls (hd%HDN%,%PN%)/ > (md)0x300+8
cat --locate=\0 --number=1 (md)0x300+8 | set ENDFILE=
set /a ENDFILE=0x%ENDFILE% > nul
if not "%ENDFILE%"=="0" write --offset=%ENDFILE% (md)0x300+8 \ \0 > nul

cat --locate=" ntldr " --number=1 (md)0x300+8 > nul || goto :nont
cat --length=0 (hd%HDN%,%PN%)/ntldr | set NTS=
set /a NTS=0x%NTS:~14% > nul
if %NTS%<=74999 goto notgood
set /a N=%N%+1 > nul
if %NTS%>=218976 set OS=XP && goto :esnt
if %NTS%>=185208 set OS=2000 && goto :esnt
set OS=NT
:esnt
if %HDN%==0 set HDNT=first && set HDNTR=USB drive
if %HDN%==1 set HDNT=second && set HDNTR=first internal HDD
if %HDN%==2 set HDNT=third && set HDNTR=second internal HDD
if %HDN%==3 set HDNT=fourth && set HDNTR=third internal HDD
if %HDN%>=4 set HDNT=%HDN%th && set /a HDNN=%HDN%+1 > nul && set HDNTR=%HDN%th internal HDD
if %HDN%==0 set REMAP=
if %HDN%>=1 set REMAP=\r\nmap (hd%HDN%) (hd0)\r\nmap --hook
if %PN%==0 set PNT=first
if %PN%==1 set PNT=second
if %PN%==2 set PNT=third
if %PN%==3 set PNT=fourth

set BWINM%N%=title Boot to Windows %OS% on %HDNT% HDD, %PNT% partition\\nUsually the %HDNTR%...%REMAP%\r\nroot (hd0,%PN%) \> nul\r\nchainloader /ntldr
:nont

cat --locate=" bootmgr " --number=1 (md)0x300+8 > nul || goto :nomgr
cat --length=0 (hd%HDN%,%PN%)/bootmgr | set MGRS=
set /a MGRS=0x%MGRS:~14% > nul
if %MGRS%<=199999 goto notgood
if %MGRS%==438840 set OS=Vista && goto :esmgr
if %MGRS%>=390971 set OS=8 && goto :esmgr
if %MGRS%>=358410 set OS=7 && goto :esmgr
set OS=Vista
:esmgr
set /a N=%N%+1 > nul
if %HDN%==0 set HDNT=first && set HDNTR=USB drive
if %HDN%==1 set HDNT=second && set HDNTR=first internal HDD
if %HDN%==2 set HDNT=third && set HDNTR=second internal HDD
if %HDN%==3 set HDNT=fourth && set HDNTR=third internal HDD
if %HDN%>=4 set HDNT=%HDN%th && set /a HDNN=%HDN%+1 > nul && set HDNTR=%HDN%th internal HDD
if %HDN%==0 set REMAP=
if %HDN%>=1 set REMAP=\r\nmap (hd%HDN%) (hd0)\r\nmap --hook
if %PN%==0 set PNT=first
if %PN%==1 set PNT=second
if %PN%==2 set PNT=third
if %PN%==3 set PNT=fourth

set BWINM%N%=title Boot to Windows %OS% on %HDNT% HDD, %PNT% partition\\nUsually the %HDNTR%...%REMAP%\r\nroot (hd0,%PN%) \> nul\r\nchainloader /bootmgr
:nomgr


:notgood

set /a SKIPPED=0x%PPOSE%+2 > nul
if %N%>=15 goto :endloop
goto :loop
:endloop
set BDN=
set SKIPPED=
set PPOSB=
set PPOSE=
set PPOSL=
set CPOS=
set PNL=
set PN=
set HDNL=
set HDN=
set HDNT=
set HDNTR=
set PNT=
set REMAP=
if %N%==0 clear && echo No bootable Windows NT/2000/XP/Vista/7/8 partitions found, returning to main menu... && pause --wait=5 && goto :finish
write (md)0x300+4 %BWINM1%\r\n%BWINM2%\r\n%BWINM3%\r\n%BWINM4%\r\n%BWINM5%\r\n%BWINM6%\r\n%BWINM7%\r\n%BWINM8%\r\n%BWINM9%\r\n%BWINM10%\r\n%BWINM11%\r\n%BWINM12%\r\n%BWINM13%\r\n%BWINM14%\r\n%BWINM15%\r\ntitle\r\nroot\r\ntitle Return to main menu...\r\nconfigfile /menu.lst\r\n\0 > nul
set BWINM1=
set BWINM2=
set BWINM3=
set BWINM4=
set BWINM5=
set BWINM6=
set BWINM7=
set BWINM8=
set BWINM9=
set BWINM10=
set BWINM11=
set BWINM12=
set BWINM13=
set BWINM14=
set BWINM15=
configfile (md)0x300+4
:finish


#45 steve6375

steve6375

    Platinum Member

  • Developer
  • 7566 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
  •  
    United Kingdom

Posted 25 May 2013 - 09:02 AM

A neat trick to clear all variables except the few that you want to keep is to use set * to clear all variables:

set a=1
set b=2
set c=3
set d=4
set * && set a=%a% && set b=%b%
set
a=1
b=2

 

or just use setlocal and endlocal


setlocal 
set a=1 
set b=2 
(more variables set here) 
endlocal && set kp=%a% && set kp1=%b% 
set 
kp=1 
kp1=2

 

 

 

 

 



#46 tinybit

tinybit

    Gold Member

  • Developer
  • 1175 posts
  •  
    China

Posted 25 May 2013 - 11:07 AM

It is possible that when you do the map:

map (md)+8 (bd)

 

(bd) is interpreted (special case :w00t:) as the whole disk and not just the partition on it. :dubbio:

 

:cheers:

Wonko

 

Yes. as a map argument, a single device name(without any path appended) will be interpreted as whole disk.



#47 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 25 May 2013 - 11:49 AM

A neat trick to clear all variables except the few that you want to keep is to use set * to clear all variables:





set a=1
set b=2
set c=3
set d=4
set * && set a=%a% && set b=%b%
set
a=1
b=2

 

or just use setlocal and endlocal









setlocal 
set a=1 
set b=2 
(more variables set here) 
endlocal && set kp=%a% && set kp1=%b% 
set 
kp=1 
kp1=2

 

 

 

Thank you, steve, I didn't know about "set *". It's a very good command. Unfortunately I can't use it because it will clear ALL variables, including the ones used in the main menu (which I need).
So the solution would be use "setlocal" at the beginning of the batch file and "endlocal" in the 2 "exit points": in "if %N%==0 && ..." and before "configfile (md)0x300+4".
What do you think - the memory area used by grub4dos will be less fragmented when using "local" or there is no difference...?

Another thing: I noticed that, when you press Escape in a "pause --wait=n" it will not start the next command with && but it will go to the next line from the script.
For example in my script:



... && pause --wait=5 && goto :finish
write (md)0x300+4 %BWINM1%...

If I press Escape during the countdown it will not goto :finish but it will start "write".
Is there any way to make it start "&& goto :finish" like any other key does?



#48 steve6375

steve6375

    Platinum Member

  • Developer
  • 7566 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
  •  
    United Kingdom

Posted 25 May 2013 - 12:42 PM

The latest version of grub4dos has ;;   &;   and |;

 

;; is just a command separator.  &; is the same as && except that the first command will immediately affect the environment

 

for instance

 

set a=1 && set b=%a%

 

will not set b to 1  (the first time you run it)

 

but

 

set a=1 &; set b=%a%

 

will set b to 1

 

 

 

 

 

so try

 

... && pause --wait=5 ;; goto :finish

 

This is all mentioned in my grub4dos tutorial



#49 DavidB

DavidB

    Silver Member

  • Developer
  • 611 posts

Posted 25 May 2013 - 01:05 PM

Yes, I read that section of your tutorial but I thought those operators are only in the Beta versions ("versions April 2013 and later"). Since I have the last stable version (0.4.5c-2013-03-03) and not the Beta I haven't used them.
There are arguments against and pro using Beta versions but if this script would also be used by others not just by me I think is wise to keep it for the stable version.
Anyway I tried but it considers ";; goto :finish" as a string and display it.
Thank you anyway.

Sorry :D but I have another question:
Sometimes /chainloader fails and shows an error message, waiting the user to press a key. After that it returns to the menu without starting the next lines of code.
That's normal. But I want to "enhance" it a bit: show the error message, wait for the user to press a key and then start a command.
"chainloader /bootmgr || [next commands]" starts the command but it doesn't display the error message.
I tried "chainloader /bootmgr > (md)0x220+2 || cat (md)0x220+2 && pause && [next commands]", it waits for the user input but still doesn't display the error mesage.
Why do I need this: to reverse the mapping(s) done for chainloader, so the user would know what the error was but continue to use the main menu normally.



#50 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16066 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 25 May 2013 - 01:21 PM

Yes. as a map argument, a single device name(without any path appended) will be interpreted as whole disk.

That was not the point at hand.

(bd) represents the boot volume (i.e. (hd0,0) in this case) BUT when you map *something* to it, it represents the disk containing that volume (i.e. (hd0) in this case).

I do understand (like in Steve6375's nice  example) the utility of such a behaviour, but still it is somehow non-standard.

If you do:

map (md)+8 (hd0)

it is clear that you are mapping to a "whole disk", when you:

map (md)+8 (bd)

it is not so immediate, as if you do:

root (bd)

root

you get as a result (hd0,0)

 

so the same device (bd) in one case represents a disk, and in the other represents a volume.

No issue whatever, is only something one has to know about. :)

 

:cheers:

Wonko






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users