topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Thursday March 28, 2024, 5:47 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: In search of a partition identifier ...  (Read 7511 times)

barney

  • Charter Member
  • Joined in 2006
  • ***
  • Posts: 1,294
    • View Profile
    • Donate to Member
In search of a partition identifier ...
« on: February 05, 2011, 03:28 PM »
Folk,

I thought this would be simplicity ... definitely misthought!

Been searching for something, preferably portable, that will identify the currently active OS partition.

OK, that's prolly not clear, so here's an example.

Take a desktop with multiple partitions on the HD(s).  Four (4) of these [bootable] partitions are loaded with the same OS, although there are variants within each.  OK, sounds stupid, but special circumstances make some sense of it.  Personally, I'd have done this with VMs, but, oh, well.

So what I'm trying to find is something that will let me identify the active partition w/o having to reboot.  Drive letters are not reliable in this instance, as they can be changed within each OS partition.

I really thought this was going to be simple, but it's turned out to be a bear.  Any thoughts that might be helpful?

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #1 on: February 05, 2011, 03:55 PM »
If nobody on BootLand forum knows, then I don't know who would:

http://reboot.pro/index.php?

sword

  • Charter Member
  • Joined in 2005
  • ***
  • Posts: 200
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #2 on: February 05, 2011, 04:47 PM »
PowerQuest PartitionMagic v7 lists:
Disk | Partition |...| Status |...
 1       C...             Active

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #3 on: February 05, 2011, 05:17 PM »
There are some WinAPI calls to get volume information but I haven't used them myself to know if the info can be easily meaningfully interpreted. Just about everything at BootLand is boot related so there must be some programmers there willing to share some of their secrets.

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #4 on: February 05, 2011, 05:57 PM »
Been searching for something, preferably portable, that will identify the currently active OS partition.

When you say 'active' do you mean the partition that is marked as Active that carries the MBR, (I only have one per all drives), or do you mean the current System partition ?

ie. In the picture below: The Active or the Boot partition?

2011-02-06_10-50-09.jpg

Try the attached compiled AutoIt script, it's console only, (so you can stick it in batch file or something), let me know if you want GUI instead.

D:\My Docs\AutoIt>whatboot a
\Device\Harddisk2\Partition1
D:\My Docs\AutoIt>whatboot b
\Device\Harddisk2\Partition2
D:\My Docs\AutoIt>whatboot o
Microsoft Windows 7 Home Premium
D:\My Docs\AutoIt>whatboot s
C:\Windows
D:\My Docs\AutoIt>whatboot e
\Device\Harddisk2\Partition1
Microsoft Windows 7 Home Premium
C:\Windows
\Device\Harddisk2\Partition2

D:\My Docs\AutoIt>whatboot
WhatBoot [A|O|B|S|E]
Where: A - Active partition
       O - Operating System
       B - Boot partition
       S - System directory
       E - Everything
D:\My Docs\AutoIt>

EDIT: Should have mentioned, numbering starts at 1 for partitions.
« Last Edit: February 05, 2011, 08:59 PM by 4wd »

barney

  • Charter Member
  • Joined in 2006
  • ***
  • Posts: 1,294
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #5 on: February 05, 2011, 09:22 PM »
When you say 'active' do you mean the partition that is marked as Active that carries the MBR, (I only have one per all drives), or do you mean the current System partition ?

OK, active refers to the partition which supports the OS version I'm using at the moment, i.e., the partition which carries the currently active OS.  Perhaps booted partition would be more clear.

Anyway, curse you, 4wd :P for making me learn another scripting bit - your WhatBoot seems to do what's needful here.  So I'll order the O'Reilly/Safari AutoIt V3:  Your Quick Guide and pray that it really is.  (I hate ebooks.)

Oh, yeah, about that curse ... many, many thanks, as well  :Thmbsup: :Thmbsup:.

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #6 on: February 05, 2011, 09:46 PM »
It that case, perhaps you should sign up for the AutoHK Programming School, (which I'm currently going through in AutoIt) ;)

Here's the source, (a heavily edited version of the CompInfo UDF), but I could have also used AutoIt ScriptOMatic to generate and butcher.

I took the easier route.

Code: AutoIt [Select]
  1. #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
  2. #AutoIt3Wrapper_UseUpx=n
  3. #AutoIt3Wrapper_UseX64=n
  4. #AutoIt3Wrapper_Change2CUI=y
  5. #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
  6.  
  7. #region Global Variables and Constants
  8. If Not(IsDeclared("$cI_CompName")) Then
  9.         Global  $cI_CompName = @ComputerName
  10. Global Const $cI_VersionInfo            = "00.03.08"
  11. Global Const $cI_aName                          = 0, _
  12.                          $cI_aDesc                              = 4
  13. Global  $wbemFlagReturnImmediately      = 0x10, _       ;DO NOT CHANGE
  14. $wbemFlagForwardOnly            = 0x20                          ;DO NOT CHANGE
  15. Global  $ERR_NO_INFO                            = "Array contains no information", _
  16.                 $ERR_NOT_OBJ                            = "$colItems isnt an object"
  17. #endregion Global Variables and Constants
  18.  
  19. #region Boot Configuration
  20. Dim $BootConfig
  21. _ComputerGetBootConfig($BootConfig)
  22.         $error = @error
  23.         $extended = @extended
  24.         Switch $extended
  25.                 Case 1
  26.                         _ErrorMsg($ERR_NO_INFO)
  27.                 Case 2
  28.                         _ErrorMsg($ERR_NOT_OBJ)
  29.         EndSwitch
  30. #endregion Boot Configuration
  31.  
  32. #region ComputerOS Configuration
  33. Dim $OSs
  34. _ComputerGetOSs($OSs)
  35.         $error = @error
  36.         $extended = @extended
  37.         Switch $extended
  38.                 Case 1
  39.                         _ErrorMsg($ERR_NO_INFO)
  40.                 Case 2
  41.                         _ErrorMsg($ERR_NOT_OBJ)
  42.         EndSwitch
  43. #endregion ComputerOS Configuration
  44.  
  45. $CompOS = StringSplit($OSs[1][0],'|')
  46. $CompOS[0] = $BootConfig[1][0]
  47.  
  48. If $CmdLine[0] = 1 Then
  49.         Switch $CmdLine[1]
  50.                 Case 'A', 'a'
  51.                         ConsoleWrite($CompOS[0])
  52.                 Case 'O', 'o'
  53.                         ConsoleWrite($CompOS[1])
  54.                 Case 'B', 'b'
  55.                         ConsoleWrite($CompOS[3])
  56.                 Case 'S', 's'
  57.                         ConsoleWrite($CompOS[2])
  58.                 Case 'E', 'e'
  59.                         For $i = 0 To 3
  60.                                 ConsoleWrite($CompOS[$i] & @CRLF)
  61.                         Next
  62.                 Case Else
  63.         EndSwitch
  64.         $info = 'WhatBoot [A|O|B|S|E]' & @CRLF & 'Where: A - Active partition' & @CRLF & '       O - Operating System' & _
  65.                                 @CRLF & '       B - Boot partition' & @CRLF & '       S - System directory' & @CRLF & '       E - Everything'
  66.         ConsoleWrite($info)
  67.  
  68.  
  69. Func _ComputerGetBootConfig(ByRef $aBootConfigInfo)
  70.         Local $colItems, $objWMIService, $objItem
  71.         Dim $aBootConfigInfo[1][8], $i = 1
  72.  
  73.         $objWMIService = ObjGet("winmgmts:\\" & $cI_Compname & "\root\CIMV2")
  74.         $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BootConfiguration", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
  75.  
  76.         If IsObj($colItems) Then
  77.                 For $objItem In $colItems
  78.                         ReDim $aBootConfigInfo[UBound($aBootConfigInfo) + 1][8]
  79.                         $aBootConfigInfo[$i][0]  = $objItem.Description
  80.                         $i += 1
  81.                 Next
  82.                 $aBootConfigInfo[0][0] = UBound($aBootConfigInfo) - 1
  83.                 If $aBootConfigInfo[0][0] < 1 Then
  84.                         SetError(1, 1, 0)
  85.                 EndIf
  86.         Else
  87.                 SetError(1, 2, 0)
  88.         EndIf
  89. EndFunc ;_ComputerGetBootConfig
  90.  
  91. Func _ComputerGetOSs(ByRef $aOSInfo)
  92.         Local $colItems, $objWMIService, $objItem
  93.         Dim $aOSInfo[1][60], $i = 1
  94.  
  95.         $objWMIService = ObjGet("winmgmts:\\" & $cI_Compname & "\root\CIMV2")
  96.         $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
  97.  
  98.         If IsObj($colItems) Then
  99.                 For $objItem In $colItems
  100.                         ReDim $aOSInfo[UBound($aOSInfo) + 1][60]
  101.                         $aOSInfo[$i][0]  = $objItem.Name
  102.                         $i += 1
  103.                 Next
  104.                 $aOSInfo[0][0] = UBound($aOSInfo) - 1
  105.                 If $aOSInfo[0][0] < 1 Then
  106.                         SetError(1, 1, 0)
  107.                 EndIf
  108.         Else
  109.                 SetError(1, 2, 0)
  110.         EndIf
  111. EndFunc ;_ComputerGetOSs
  112.  
  113. #region ---- Internal Functions
  114. Func _ErrorMsg($message, $time = 0)
  115.         ConsoleWrite("Error! - " & $message)
  116. #endregion Internal Functions

Happy it worked  :D

You might not need the ebook, I find the examples in the help docs and throughout the AutoIt forum are usually enough to get me either headed in the right direction or almost exactly what I require.  The hard part is getting the search terms right.  Many a time I've started writing a function to do something then searched in the forum to find that it's included in a UDF so all I need is a function call  :-[

ATM I can't work out how to tell whether or not the program is run via CLI or GUI which would allow me to add both types of output.  I'm sure it's really easy but stuffed if I can find a variable, (or process), to check for so I can do it.
« Last Edit: February 05, 2011, 10:17 PM by 4wd »

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #7 on: February 06, 2011, 03:47 AM »
I found this console detection code. I have no idea if it really works though. :)

http://www.autoitscr...earch__1#entry787423

(scroll up to the post by GodlessSinner for the script)

Not exactly great for doing it inside the file you're checking but you can probably work around it somehow. :)

Also there's a new UDF WinApiEx.au3 that has tons of stuff. It's by the guy who figured out how to get the translucent blue glass dialogs on Windows Seven Aero.
« Last Edit: February 06, 2011, 03:50 AM by MilesAhead »

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #8 on: February 06, 2011, 04:25 AM »
Great!  Thanks Miles, I'll have a look at it - had a look at the WinApiEx UDF earlier but couldn't see anything.

I couldn't believe they didn't have a macro, (eg. @console), already available.

EDIT: Seems that you need to have UPX'd the compiled script for it to work...bummer!  Still, might be able to adapt it.

Found something here, ie. get the parent process - if it's explorer.exe then it was run via double-click, if it's cmd.exe it's via CLI.
« Last Edit: February 06, 2011, 05:13 AM by 4wd »

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #9 on: February 06, 2011, 04:42 PM »
Thanks for the link.  Added it to my code snippets. :)

I also found a port of the Linux "file" command:

http://www.vowles-ho...windows_file_exe.htm

One of the infos output is console or gui when run against an exe file.
C Source is included.  Assuming it works it's some good info on PE fields.
I'm not sure if the exes "compiled" by AutoIt3 conform to the standard.
« Last Edit: February 06, 2011, 04:56 PM by MilesAhead »

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: In search of a partition identifier ...
« Reply #10 on: February 06, 2011, 05:35 PM »
I'm not sure if the exes "compiled" by AutoIt3 conform to the standard.

Excellent!  Works in detecting CUI/GUI compiled AutoIt...now to apply my meager C knowledge in working out how they do it :)

EDIT: Here's a AutoIt conversion, not the whole file.exe program, just up to the part I was interested in.  Seems to work OK as long as the AutoIt program hasn't been UPX'd of course.

Now to turn it into a function.

Code: AutoIt [Select]
  1. #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
  2. #AutoIt3Wrapper_UseUpx=n
  3. #AutoIt3Wrapper_UseX64=n
  4. #AutoIt3Wrapper_Change2CUI=y
  5. #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
  6. ; file.au3
  7.  
  8. $maxfilesize = 8192
  9. Dim $buffer[$maxfilesize]
  10.  
  11. If $CmdLine[0] = 0 Then Exit
  12.  
  13. $hFile = FileOpen($CmdLine[1], 16)
  14. If $hFile = -1 Then
  15.         MsgBox(0, 'Error!', 'Failed to open file.')
  16.         Exit
  17. For $i = 0 To 8191
  18.         $buffer[$i] = Dec(StringMid(FileRead($hFile, 1), 3))
  19.         If @error Then ExitLoop
  20.  
  21. FileClose($hFile)
  22.  
  23. ; Test for executable
  24. If ($buffer[0]=77 And $buffer[1]=90) Or ($buffer[0]=90 And $buffer[1]=77) Then ; MZ or ZM
  25.         ConsoleWrite('DOS/Win executable')
  26.         ConsoleWrite('Not DOS/Win executable')
  27.  
  28. $offset=0
  29. $format=0
  30.  
  31. ; Test for NE/PE format
  32. $neoffset=($buffer[61] + $buffer[60]) * 256
  33. If ($buffer[$neoffset] = 78 And $buffer[$neoffset + 1] = 69) Then
  34.         $format = 3
  35.         $offset = $neoffset
  36.  
  37. $peoffset = $buffer[60]
  38. If ($peoffset > $maxfilesize) Then
  39.         $peoffset = 0
  40.  
  41. If ($buffer[$peoffset] = 80 And $buffer[$peoffset + 1] = 69) Then
  42.         $format = 1
  43.         $offset = $peoffset
  44.  
  45. If ($format = 0) Then
  46.         $i = 0
  47.         While (($format = 0) And ($i < $maxfilesize - 4))
  48.                 If ($buffer[$i] = 80) And ($buffer[$i + 1] = 69) And ($buffer[$i + 2] = 0) And ($buffer[$i + 3] = 0) Then
  49.                         $offset = $i
  50.                         $format = 2
  51.                 EndIf
  52.                 $i += 1
  53.         WEnd
  54.  
  55. ; Depending on the type of Format try to gain further information about the file
  56. If ($format = 1 Or $format = 2) Then
  57.         If ($buffer[$offset + 4] = 0 And $buffer[$offset + 5] = 0) Then ConsoleWrite(', defined as an ANY / unknown machine type executable')
  58.         If ($buffer[$offset + 4] = 76 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', i386 32bit executable')
  59.         If ($buffer[$offset + 4] = 100 And $buffer[$offset + 5] = 134) Then ConsoleWrite(', x86-64 64bit executable')
  60.         If ($buffer[$offset + 4] = 0 And $buffer[$offset + 5] = 2) Then ConsoleWrite(', Intel Itanium executable')
  61.         If ($buffer[$offset + 4] = 240 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Power PC (little endian) executable')
  62.         If ($buffer[$offset + 4] = 241 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Power PC (with floating point support) executable')
  63.         If ($buffer[$offset + 4] = 211 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Matsushita AM33')
  64.         If ($buffer[$offset + 4] = 192 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', ARM little endian')
  65.         If ($buffer[$offset + 4] = 188 And $buffer[$offset + 5] = 14) Then ConsoleWrite(', EFI byte code')
  66.         If ($buffer[$offset + 4] = 65 And $buffer[$offset + 5] = 144) Then ConsoleWrite(', Mitsubishi M32R little endian')
  67.         If ($buffer[$offset + 4] = 102 And $buffer[$offset + 5] = 2) Then ConsoleWrite(', MIPS16')
  68.         If ($buffer[$offset + 4] = 102 And $buffer[$offset + 5] = 3) Then ConsoleWrite(', MIPS with FPU')
  69.         If ($buffer[$offset + 4] = 102 And $buffer[$offset + 5] = 4) Then ConsoleWrite(', MIPS 16 with FPU')
  70.         If ($buffer[$offset + 4] = 102 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', MIPS little endian / R4000')
  71.         If ($buffer[$offset + 4] = 162 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Hitachi SH3')
  72.         If ($buffer[$offset + 4] = 163 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Hitachi SH3 DSP')
  73.         If ($buffer[$offset + 4] = 166 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Hitachi SH4')
  74.         If ($buffer[$offset + 4] = 168 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Hitachi SH5')
  75.         If ($buffer[$offset + 4] = 194 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Thumb')
  76.         If ($buffer[$offset + 4] = 105 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', MIPS little-endian WCE v2')
  77.         If ($buffer[$offset + 4] = 132 And $buffer[$offset + 5] = 1) Then ConsoleWrite(', Alpha')
  78.         If ($buffer[$offset + 4] = 104 And $buffer[$offset + 5] = 2) Then ConsoleWrite(', Motorola 68000')
  79.         If ($buffer[$offset + 4] = 144 And $buffer[$offset + 5] = 2) Then ConsoleWrite(', PA-RISC')
  80.  
  81.         If ($buffer[$offset + 23] = 32 And $buffer[$offset + 22] > 0) Then ConsoleWrite(', dll')
  82.         If ($buffer[$offset + 23] = 10 And $buffer[$offset + 22] > 0) Then ConsoleWrite(', system file')
  83.  
  84.         If ($buffer[$offset + 92] = 0 And $buffer[$offset + 93] = 0) Then ConsoleWrite(', unknown system')
  85.         If ($buffer[$offset + 92] = 1 And $buffer[$offset + 93] = 0) Then ConsoleWrite(', native')
  86.         If ($buffer[$offset + 92] = 2 And $buffer[$offset + 93] = 0) Then ConsoleWrite(', GUI')
  87.         If ($buffer[$offset + 92] = 3 And $buffer[$offset + 93] = 0) Then ConsoleWrite(', console/cmd')
  88.         If ($buffer[$offset + 92] = 7 And $buffer[$offset + 93] = 0) Then ConsoleWrite(', POSIX')
  89.  

EDIT: Got sidetracked, while it will tell how the program was compiled it still won't tell you how it was run...but at least I can make a single program that covers both compilation options.

Here's a function, returns True if compiled for GUI, False for anything else.

Code: AutoIt [Select]
  1. MsgBox(0, '', _GUITest(@ScriptFullPath))
  2.  
  3. Func _GUITest($file)
  4.         Local $maxfilesize = 8192, $hFile, $offset, $buffer, $i, $format, $neoffset, $peoffset
  5.         Dim $buffer[$maxfilesize]
  6.  
  7.         $hFile = FileOpen($file, 16)
  8.         For $i = 0 To 8191
  9.                 $buffer[$i] = Dec(StringMid(FileRead($hFile, 1), 3))
  10.                 If @error Then ExitLoop
  11.         Next
  12.         FileClose($hFile)
  13.  
  14.         $offset=0
  15.         $format=0
  16.  
  17.         $peoffset = $buffer[60]
  18.         If ($peoffset > $maxfilesize) Then
  19.                 $peoffset = 0
  20.         EndIf
  21.  
  22.         If ($buffer[$peoffset] = 80 And $buffer[$peoffset + 1] = 69) Then
  23.                 $format = 1
  24.                 $offset = $peoffset
  25.         EndIf
  26.  
  27.         If ($format = 0) Then
  28.                 $i = 0
  29.                 While (($format = 0) And ($i < $maxfilesize - 4))
  30.                         If ($buffer[$i] = 80) And ($buffer[$i + 1] = 69) And ($buffer[$i + 2] = 0) And ($buffer[$i + 3] = 0) Then
  31.                                 $offset = $i
  32.                                 $format = 2
  33.                         EndIf
  34.                         $i += 1
  35.                 WEnd
  36.         EndIf
  37.  
  38. ; Depending on the type of Format try to gain further information about the file
  39. If ($format = 1 Or $format = 2) Then
  40.         If ($buffer[$offset + 92] = 2 And $buffer[$offset + 93] = 0) Then
  41.                 Return True
  42.         Else
  43.                 Return False
  44.         EndIf
« Last Edit: February 06, 2011, 09:32 PM by 4wd »