Converting C++ to Perl

K

Kenny McCarty

I am trying to convert this snippet of c++ code to perl and am having
some problems getting the results to match up. I was hoping someone
might be able to help me out. Here is the snippet of C++ code:

DWORD dwVolSerial;
BOOL bIsRetrieved;
char *tmp;
char Data[6];
// Get the serial number
bIsRetrieved =
GetVolumeInformation("C:\\",NULL,NULL,&dwVolSerial,NULL,NULL,NULL,NULL);

// Display the serial number
printf("Serial number of drive C is %X\n",dwVolSerial);

tmp = (char*)&dwVolSerial;

Data[0] = tmp[0];
Data[1] = tmp[1];
Data[2] = tmp[2];

printf("Data is %d-%d-%d\n",Data[0],Data[1],Data[2]);

And here is what I tried in perl:

#just hard coded volume serial number here
$str = '303C-6B38';
@pieces = split(/-/,$str);
@data = split(//,$pieces[0]);
printf("Data: %d-%d-%d\n",ord($data[0]),ord($data[1]),ord($data[2]));

The C++ is run on Windows XP and the perl is run on Free-BSD. For the
perl part I want the user to input the volume serial number of their C
drive and I want to create a strign using this data. I think that the
conversions are different between windows and unix and that is where
my problem is but I am not sure. In windows the "3" becomes a "056"
but in unix it becomes a "53". Any help would be apprecieated.
Thanks.
 
S

Sisyphus

Kenny said:
The C++ is run on Windows XP and the perl is run on Free-BSD. For the
perl part I want the user to input the volume serial number of their C
drive and I want to create a strign using this data. I think that the
conversions are different between windows and unix and that is where
my problem is but I am not sure. In windows the "3" becomes a "056"
but in unix it becomes a "53". Any help would be apprecieated.
Thanks.

Are you sure about this ?
Both 'C' and 'perl' report an ASCII value of 51 for '3' (on both Linux
and Windows) for me - which is as I would expect. (Your perl script
outputs '51-48-51'.)

Hth.

Cheers,
Rob
 
J

John W. Krahn

Kenny said:
I am trying to convert this snippet of c++ code to perl and am having
some problems getting the results to match up. I was hoping someone
might be able to help me out. Here is the snippet of C++ code:

DWORD dwVolSerial;

DWORD is I believe an unsigned long (32 bit) integer.

BOOL bIsRetrieved;
char *tmp;
char Data[6];
// Get the serial number
bIsRetrieved =
GetVolumeInformation("C:\\",NULL,NULL,&dwVolSerial,NULL,NULL,NULL,NULL);

// Display the serial number
printf("Serial number of drive C is %X\n",dwVolSerial);

tmp = (char*)&dwVolSerial;

Data[0] = tmp[0];
Data[1] = tmp[1];
Data[2] = tmp[2];

printf("Data is %d-%d-%d\n",Data[0],Data[1],Data[2]);

And here is what I tried in perl:

#just hard coded volume serial number here
$str = '303C-6B38';
@pieces = split(/-/,$str);
@data = split(//,$pieces[0]);
printf("Data: %d-%d-%d\n",ord($data[0]),ord($data[1]),ord($data[2]));

The equivalent perl code is:

my $str = '303C-6B38';
my @pieces = map hex, $str =~ /[[:xdigit:]]{2}/g;
printf "Data: %d-%d-%d\n", @pieces[ 0 .. 2 ];

The C++ is run on Windows XP and the perl is run on Free-BSD. For the
perl part I want the user to input the volume serial number of their C
drive and I want to create a strign using this data. I think that the
conversions are different between windows and unix and that is where
my problem is but I am not sure. In windows the "3" becomes a "056"
but in unix it becomes a "53". Any help would be apprecieated.

Are both OSs running on Intel compatible CPUs? Intel's little-endian
format means that an integer like 0x12345678 converted to a char array
will be { 0x78, 0x56, 0x34, 0x12 } so your volume serial number
'303C-6B38' is really the integer 0x386B3C30.



John
 
K

Kenny McCarty

Sisyphus said:
Are you sure about this ?
Both 'C' and 'perl' report an ASCII value of 51 for '3' (on both Linux
and Windows) for me - which is as I would expect. (Your perl script
outputs '51-48-51'.)

Hth.

Cheers,
Rob

Yes I am sure....however I am not sure if the C code is actually
outputting the ascii values or something else...therein lies my
dilema. I am VERY rusty with C coding and I am trying to convert this
to perl from someone else's C code. So maybe someone who is familiar
with C and perl can figure this out :)
 
S

Sisyphus

Kenny said:
Yes I am sure....however I am not sure if the C code is actually
outputting the ascii values or something else...therein lies my
dilema. I am VERY rusty with C coding and I am trying to convert this
to perl from someone else's C code. So maybe someone who is familiar
with C and perl can figure this out :)

Not sure where to go from here. Did John Krahn's post shed any light on
the problem for you ?

Does it help to know that the serial number can be parsed from the
output of the 'dir' windows system command (so long as it's run in the
appropriate drive, of course) ?

eg the following (transcribed) code works for me on Win2k, though ymmv
on different windows boxes.

my $d = `dir`;
my @stuff = split /\n/, $d;
$stuff[1] =~ s/ Volume Serial Number is //i;
print $stuff[1]; # prints serial number of current drive.

Cheers,
Rob
 
K

Kenny McCarty

John W. Krahn said:
Kenny said:
I am trying to convert this snippet of c++ code to perl and am having
some problems getting the results to match up. I was hoping someone
might be able to help me out. Here is the snippet of C++ code:

DWORD dwVolSerial;

DWORD is I believe an unsigned long (32 bit) integer.

BOOL bIsRetrieved;
char *tmp;
char Data[6];
// Get the serial number
bIsRetrieved =
GetVolumeInformation("C:\\",NULL,NULL,&dwVolSerial,NULL,NULL,NULL,NULL);

// Display the serial number
printf("Serial number of drive C is %X\n",dwVolSerial);

tmp = (char*)&dwVolSerial;

Data[0] = tmp[0];
Data[1] = tmp[1];
Data[2] = tmp[2];

printf("Data is %d-%d-%d\n",Data[0],Data[1],Data[2]);

And here is what I tried in perl:

#just hard coded volume serial number here
$str = '303C-6B38';
@pieces = split(/-/,$str);
@data = split(//,$pieces[0]);
printf("Data: %d-%d-%d\n",ord($data[0]),ord($data[1]),ord($data[2]));

The equivalent perl code is:

my $str = '303C-6B38';
my @pieces = map hex, $str =~ /[[:xdigit:]]{2}/g;
printf "Data: %d-%d-%d\n", @pieces[ 0 .. 2 ];

The C++ is run on Windows XP and the perl is run on Free-BSD. For the
perl part I want the user to input the volume serial number of their C
drive and I want to create a strign using this data. I think that the
conversions are different between windows and unix and that is where
my problem is but I am not sure. In windows the "3" becomes a "056"
but in unix it becomes a "53". Any help would be apprecieated.

Are both OSs running on Intel compatible CPUs? Intel's little-endian
format means that an integer like 0x12345678 converted to a char array
will be { 0x78, 0x56, 0x34, 0x12 } so your volume serial number
'303C-6B38' is really the integer 0x386B3C30.



John

John,

Thanks so much...you code did the trick. It just prints out the
numbers in reverse but I can deal with that. Guess it has to do with
the little-endian/big-endian stuff you said. I vaguely remember
learning about that in college hehe. Thanks again for your help and
everyone else who tried to help too.
 

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

Members online

Forum statistics

Threads
474,257
Messages
2,571,031
Members
48,768
Latest member
first4landlord

Latest Threads

Top