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




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
# - 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:
# <system> <username> <password>
# copyright 2006 H. Carvey, (e-mail address removed)
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} =
$diskpart{$part->{DiskIndex}.":".$part->{Index}}{Bootable} = 1 if
$diskpart{$part->{DiskIndex}.":".$part->{Index}}{BootPartition} = 1 if
$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
print "\n";
#foreach my $x (keys %{$diskpart{$partition}}) {
# print 'Key: '.$x.' = '.$diskpart{$partition}{$x}."\n";
output on my machine: (excerpt)
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
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




Ben said:
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

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{

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.

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 :

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

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question