How do i get the drive letter ? (need win32::ole assistance)

Discussion in 'Perl Misc' started by wolf, Dec 7, 2009.

  1. wolf

    wolf Guest

    Hello,

    i'm trying to battle my way through the following problem:

    a) I need to get a list of all PHYSICAL drives on a machine. (got that)
    b) I need to get a list of all PARTITIONS on each PHYSICAL drive. (got that)

    c) I need to know which partition is assigned which drive letter (if at
    all) and i have no idea how to do this.

    This is surely due to my lack of OLE understanding.
    Can someone point me the way?

    the perl code to get answers to a) and b) is below (found it in a forum).

    Cheers, Wolf
    ------------------
    #!/usr/bin/perl
    #---------------------------------------------------------------------
    # di.pl - Disk ID tool
    # This script is intended to assist investigators in identifying disks
    # attached to systems. It can be used by an investigator to document
    # a disk following acquisition, providing information for use in
    # acquisition worksheets and chain-of-custody documentation.
    #
    # This tool may also be run remotely against managed system, by passing
    # the necessary arguments at the command line.
    #
    # Usage: di.pl
    # di.pl <system> <username> <password>
    #
    # copyright 2006 H. Carvey,
    #---------------------------------------------------------------------
    use strict;
    use Win32::OLE qw(in);

    my $server = shift || Win32::NodeName();
    my $user = shift || "";
    my $pwd = shift || "";

    my $locatorObj = Win32::OLE->new('WbemScripting.SWbemLocator') || die
    "Error creating locator object: ".Win32::OLE->LastError()."\n";
    $locatorObj->{Security_}->{impersonationlevel} = 3;
    my $serverObj = $locatorObj->ConnectServer($server,'root\cimv2',$user,$pwd)
    || die "Error connecting to $server: ".Win32::OLE->LastError()."\n";

    my %capab = (0 => "Unknown",
    1 => "Other",
    2 => "Sequential Access",
    3 => "Random Access",
    4 => "Supports Writing",
    5 => "Encryption",
    6 => "Compression",
    7 => "Supports Removable Media",
    8 => "Manual Cleaning",
    9 => "Automatic Cleaning",
    10 => "SMART Notification",
    11 => "Supports Dual Sided Media",
    12 => "Ejection Prior to Drive Dismount Not Required");

    my %disk = ();
    foreach my $drive (in $serverObj->InstancesOf("Win32_DiskDrive")) {
    $disk{$drive->{Index}}{DeviceID} = $drive->{DeviceID};
    $disk{$drive->{Index}}{Manufacturer} = $drive->{Manufacturer};
    $disk{$drive->{Index}}{Model} = $drive->{Model};
    $disk{$drive->{Index}}{InterfaceType} = $drive->{InterfaceType};
    $disk{$drive->{Index}}{MediaType} = $drive->{MediaType};
    $disk{$drive->{Index}}{Partitions} = $drive->{Partitions};
    # The drive signature is a DWORD value written to offset 0x1b8 (440) in
    the MFT
    # when the drive is formatted. This value can be used to identify a
    specific HDD,
    # either internal/fixed or USB/external, by corresponding the signature
    to the
    # values found in the MountedDevices key of the Registry
    $disk{$drive->{Index}}{Signature} = $drive->{Signature};
    $disk{$drive->{Index}}{Size} = $drive->{Size};
    $disk{$drive->{Index}}{Capabilities} = $drive->{Capabilities};
    }

    my %diskpart = ();
    foreach my $part (in $serverObj->InstancesOf("Win32_DiskPartition")) {
    $diskpart{$part->{DiskIndex}.":".$part->{Index}}{DeviceID} =
    $part->{DeviceID};
    $diskpart{$part->{DiskIndex}.":".$part->{Index}}{Bootable} = 1 if
    ($part->{Bootable});
    $diskpart{$part->{DiskIndex}.":".$part->{Index}}{BootPartition} = 1 if
    ($part->{BootPartition});
    $diskpart{$part->{DiskIndex}.":".$part->{Index}}{PrimaryPartition} = 1
    if ($part->{PrimaryPartition});
    $diskpart{$part->{DiskIndex}.":".$part->{Index}}{Type} = $part->{Type};
    }

    my %media = ();
    foreach my $pm (in $serverObj->InstancesOf("Win32_PhysicalMedia")) {
    $media{$pm->{Tag}} = $pm->{SerialNumber};
    }

    foreach my $dd (sort keys %disk) {
    print "DeviceID : ".$disk{$dd}{DeviceID}."\n";
    print "Model : ".$disk{$dd}{Model}."\n";
    print "Interface : ".$disk{$dd}{InterfaceType}."\n";
    print "Media : ".$disk{$dd}{MediaType}."\n";
    print "Capabilities : \n";
    foreach my $c (in $disk{$dd}{Capabilities}) {
    print "\t".$capab{$c}."\n";
    }
    my $sig = $disk{$dd}{Signature};
    $sig = "<None>" if ($sig == 0x0);
    printf "Signature : 0x%x\n",$sig;

    my $sn = $media{$disk{$dd}{DeviceID}};
    print "Serial No : $sn\n";
    print "\n";
    print $disk{$dd}{DeviceID}." Partition Info : \n";
    my $part = $disk{$dd}{Partitions};
    foreach my $p (0..($part - 1)) {
    my $partition = $dd.":".$p;
    print "\t".$diskpart{$partition}{DeviceID}."\n";
    print "\t".$diskpart{$partition}{Type}."\n";
    print "\t\tBootable\n" if ($diskpart{$partition}{Bootable});
    print "\t\tBoot Partition\n" if ($diskpart{$partition}{BootPartition});
    print "\t\tPrimary Partition\n" if
    ($diskpart{$partition}{PrimaryPartition});
    print "\n";
    #foreach my $x (keys %{$diskpart{$partition}}) {
    # print 'Key: '.$x.' = '.$diskpart{$partition}{$x}."\n";
    #}
    }
    }
    ----------
    output on my machine: (excerpt)
    ----------
    DeviceID : \\.\PHYSICALDRIVE2
    Model : SAMSUNG HD321KJ
    Interface : IDE
    Media : Fixed hard disk media
    Capabilities :
    Random Access
    Supports Writing
    Signature : 0xe6e5e6e5
    Serial No : 30535055314a504e303932303033202020202020

    \\.\PHYSICALDRIVE2 Partition Info :
    Disk #2, Partition #0
    Installable File System
    Bootable
    Boot Partition
    Primary Partition

    Disk #2, Partition #1
    Installable File System
    Primary Partition

    Disk #2, Partition #2
    Installable File System
    Primary Partition

    Disk #2, Partition #3
    Extended Partition
    wolf, Dec 7, 2009
    #1
    1. Advertising

  2. wolf

    wolf Guest

    Ben Morrow schrieb:
    > Quoth wolf <>:
    >> a) I need to get a list of all PHYSICAL drives on a machine. (got that)
    >> b) I need to get a list of all PARTITIONS on each PHYSICAL drive. (got that)
    >>
    >> c) I need to know which partition is assigned which drive letter (if at
    >> all) and i have no idea how to do this.
    >>
    >> This is surely due to my lack of OLE understanding.
    >> Can someone point me the way?

    >
    > You will need to look up the documentation for whatever a
    > WbemScripting.SWbemLocator is. This has nothing to do with Perl, or
    > Win32::OLE: it it just passing the method calls through to the OLE
    > object, so you need that documentation. Try searching on
    > http://msdn.microsoft.com/.
    >
    > <snip>
    >> foreach my $drive (in $serverObj->InstancesOf("Win32_DiskDrive")) {
    >> $disk{$drive->{Index}}{DeviceID} = $drive->{DeviceID};
    >> $disk{$drive->{Index}}{Manufacturer} = $drive->{Manufacturer};
    >> $disk{$drive->{Index}}{Model} = $drive->{Model};
    >> $disk{$drive->{Index}}{InterfaceType} = $drive->{InterfaceType};
    >> $disk{$drive->{Index}}{MediaType} = $drive->{MediaType};
    >> $disk{$drive->{Index}}{Partitions} = $drive->{Partitions};

    >
    > This is very bad style. Factor out the deref into a variable, at least,
    > and I would put property-copying into a loop:
    >
    > for my $drive (...) {
    > my $disk = $disk{$drive->{Index}};
    >
    > $disk->{$_} = $drive->{$_} for qw{
    > DeviceID
    > Manufacturer
    > Model
    > InterfaceType
    > MediaType
    > Partitions
    > Signature
    > Size
    > Capabilities
    > };
    >
    > assuming you can't simply assign
    >
    > $disk{$drive->{Index}} = $drive;
    >
    > (this is often a bad idea with OLE objects, because they end up not
    > being GCed soon enough). There is more of the same below.
    >
    > <snip>
    >> foreach my $dd (sort keys %disk) {
    >> print "DeviceID : ".$disk{$dd}{DeviceID}."\n";
    >> print "Model : ".$disk{$dd}{Model}."\n";
    >> print "Interface : ".$disk{$dd}{InterfaceType}."\n";
    >> print "Media : ".$disk{$dd}{MediaType}."\n";
    >> print "Capabilities : \n";

    >
    > Learn how to use heredocs, at the very least; better would be to use
    > Perl6::Form or TT or something to format the output decently.
    >
    > for my $dd (sort keys %disk) {
    > my $disk = $disk{$dd};
    >
    > print <<OUT;
    > DeviceID : $disk->{DeviceID}
    > Model : $disk->{Model}
    > Interface : $disk->{InterfaceType}
    > Media : $disk->{MediaType}
    > Capabilities :
    > OUT
    > }
    >
    > Ben
    >

    Thanks Ben, gonna try that.
    Usually i cant find my own *ss on MS's website :/ but hey :) at least i
    have a pointer.

    I didnt like the perl style of the snippet either but at least it got me
    some of the info needed. It looks a bit clumsy and overloaded with
    print and if statements :p I basically passed it on without any changes,
    except for trying it out - and it worked. I usually write my own code
    once i understand the basic data retrieval, but alas i'm not there yet.

    Cheers, Wolf
    wolf, Dec 7, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. mh
    Replies:
    4
    Views:
    687
    Wolfgang Strobl
    May 31, 2005
  2. shailesh
    Replies:
    1
    Views:
    765
    Tim Golden
    Mar 28, 2007
  3. lar
    Replies:
    0
    Views:
    183
  4. Croney

    Get UNC From drive letter

    Croney, Aug 18, 2003, in forum: ASP General
    Replies:
    0
    Views:
    109
    Croney
    Aug 18, 2003
  5. Lance Hoffmeyer
    Replies:
    0
    Views:
    230
    Lance Hoffmeyer
    Nov 17, 2003
Loading...

Share This Page