Registry.pm revision 1.1 1 1.1 christos # Registry.pm
2 1.1 christos # A perl module provided easy Windows Registry access
3 1.1 christos #
4 1.1 christos # Author: Shu-Min Chang
5 1.1 christos #
6 1.1 christos # Copyright(c) 2002 Intel Corporation. All rights reserved
7 1.1 christos #
8 1.1 christos # Redistribution and use in source and binary forms, with or without
9 1.1 christos # modification, are permitted provided that the following conditions are met:
10 1.1 christos #
11 1.1 christos # 1. Redistributions of source code must retain the above copyright notice,
12 1.1 christos # this list of conditions and the following disclaimer.
13 1.1 christos # 2. Redistributions in binary form must reproduce the above copyright notice
14 1.1 christos # this list of conditions and the following disclaimer in the documentation
15 1.1 christos # and/or other materials provided with the distribution
16 1.1 christos # 3. Neither the name of Intel Corporation nor the names of its contributors
17 1.1 christos # may be used to endorse or promote products derived from this software
18 1.1 christos # without specific prior written permission.
19 1.1 christos #
20 1.1 christos # THIS SOFTWARE IS PROVIDED BY THE INTEL CORPORATION AND CONTRIBUTORS "AS IS"
21 1.1 christos # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 1.1 christos # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 1.1 christos # ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
24 1.1 christos # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL EXEMPLARY, OR
25 1.1 christos # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO PROCUREMENT OF SUBSTITUE
26 1.1 christos # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 1.1 christos # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 1.1 christos # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 1.1 christos # OF THE USE OF THIS SOFTWARE, EVEN IF ADVICED OF THE POSSIBILITY OF SUCH
30 1.1 christos # DAMAGE.
31 1.1 christos
32 1.1 christos package Registry;
33 1.1 christos use strict;
34 1.1 christos use Win32API::Registry 0.21 qw( :ALL );
35 1.1 christos
36 1.1 christos
37 1.1 christos ###############################################################################
38 1.1 christos
39 1.1 christos #-----------------------------------------
40 1.1 christos sub GetRegKeyVal($*) {
41 1.1 christos my ($FullRegPath, $value) = @_;
42 1.1 christos #-----------------------------------------
43 1.1 christos # Purpose: uses Win32API to get registry information from a given server
44 1.1 christos #
45 1.1 christos # WARNING: this procedure is VERY Win32 specific, you'll need a Win32 manual
46 1.1 christos # to figure out why something is done.
47 1.1 christos # input: $FullRegPath: a MS specific way of fully qualifying a registry path
48 1.1 christos # \\Server\RootKey\Path\ValueName
49 1.1 christos # output: *value: the value of the registry key of $FullRegPath
50 1.1 christos #
51 1.1 christos
52 1.1 christos my ($RemoteMachine, $RootKey, $RegPath, $KeyName, $i);
53 1.1 christos
54 1.1 christos #print "in sub:GetRegKeyVal:Parameters:", @_, "\n";
55 1.1 christos
56 1.1 christos # Check the for valid fully qualified registry path
57 1.1 christos return -1 if (! ($FullRegPath =~ /\\.+\\.+/)) && (!($FullRegPath =~ /\\\\.+\\.+\\.+/));
58 1.1 christos
59 1.1 christos
60 1.1 christos $RemoteMachine = (index($FullRegPath, "\\\\") == $[ ? substr($FullRegPath, $[+2, index($FullRegPath, "\\", $[+2)-2):0);
61 1.1 christos
62 1.1 christos #print "RemoteMachine = $RemoteMachine\n";
63 1.1 christos
64 1.1 christos $i = $RemoteMachine ? $[+3+length($RemoteMachine) : $[+1;
65 1.1 christos $RootKey = substr ($FullRegPath, $i, index($FullRegPath, "\\", $i)-$i);
66 1.1 christos
67 1.1 christos $KeyName = $FullRegPath;
68 1.1 christos $KeyName =~ s/.*\\(.+)/$1/;
69 1.1 christos #print "KeyName = $KeyName\n";
70 1.1 christos
71 1.1 christos $i = index($FullRegPath, $RootKey, $[+length($RemoteMachine)) + $[ + length($RootKey)+1;
72 1.1 christos $RegPath = substr ($FullRegPath, $i, length($FullRegPath) - length($KeyName) -$i - 1);
73 1.1 christos #print "RegPath = $RegPath\n";
74 1.1 christos
75 1.1 christos my ($RootKeyHandle, $handle, $key, $type);
76 1.1 christos
77 1.1 christos if ($RemoteMachine) {
78 1.1 christos $RootKeyHandle = regConstant($RootKey);
79 1.1 christos
80 1.1 christos if (!RegConnectRegistry ($RemoteMachine, $RootKeyHandle, $handle)) {
81 1.1 christos $$value = regLastError();
82 1.1 christos return -2;
83 1.1 christos }
84 1.1 christos } else { # not valid actually because I can't find the mapping table of default
85 1.1 christos # local handle mapping. Should always pass in the Machine name to use for now
86 1.1 christos $handle = $RootKey;
87 1.1 christos }
88 1.1 christos
89 1.1 christos if (!RegOpenKeyEx ($handle, $RegPath, 0, KEY_READ, $key)) {
90 1.1 christos $$value = regLastError();
91 1.1 christos #print "regLastError = $$value\n";
92 1.1 christos return -3;
93 1.1 christos }
94 1.1 christos if (!RegQueryValueEx( $key, $KeyName, [], $type, $$value, [] )) {
95 1.1 christos $$value = regLastError();
96 1.1 christos #print "regLastError = $$value\n";
97 1.1 christos return -4;
98 1.1 christos }
99 1.1 christos
100 1.1 christos #print "RegType=$type\n"; # Perl doesn't fetch type, at this in this
101 1.1 christos # ActiveState 5.6.0 that I'm using
102 1.1 christos #print "RegValue=$$value\n";
103 1.1 christos RegCloseKey ($key);
104 1.1 christos RegCloseKey ($handle);
105 1.1 christos
106 1.1 christos return 0;
107 1.1 christos }
108 1.1 christos
109 1.1 christos ###############################################################################
110 1.1 christos
111 1.1 christos #-----------------------------------------
112 1.1 christos sub GetRegSubkeyList($*) {
113 1.1 christos my ($FullKeyRegPath, $Subkeys) = @_;
114 1.1 christos #-----------------------------------------
115 1.1 christos # Purpose: uses Win32API to get registry subkey list from a given server
116 1.1 christos #
117 1.1 christos # WARNING: this procedure is VERY Win32 specific, you'll need a Win32 manual
118 1.1 christos # to figure out why something is done.
119 1.1 christos # input: $FullKeyRegPath: a MS specific way of fully qualifying a registry path
120 1.1 christos # \\Server\RootKey\Path\KeyName
121 1.1 christos # output: *Subkeys: the list of subkeys in array of the registry key of
122 1.1 christos # $FullKeyRegPath
123 1.1 christos #
124 1.1 christos
125 1.1 christos my ($RemoteMachine, $RootKey, $RegPath, $KeyName, $i);
126 1.1 christos
127 1.1 christos #print "in sub:GetRegSubkeyList:Parameters:", @_, "\n";
128 1.1 christos
129 1.1 christos # Check the for valid registry key path
130 1.1 christos return -1 if (! ($FullKeyRegPath =~ /\\.+\\.+/)) && (!($FullKeyRegPath =~ /\\\\.+\\.+\\.+/));
131 1.1 christos
132 1.1 christos
133 1.1 christos $RemoteMachine = (index($FullKeyRegPath, "\\\\") == $[ ? substr($FullKeyRegPath, $[+2, index($FullKeyRegPath, "\\", $[+2)-2):0);
134 1.1 christos
135 1.1 christos #print "RemoteMachine = $RemoteMachine\n";
136 1.1 christos
137 1.1 christos $i = $RemoteMachine ? $[+3+length($RemoteMachine) : $[+1;
138 1.1 christos $RootKey = substr ($FullKeyRegPath, $i, index($FullKeyRegPath, "\\", $i)-$i);
139 1.1 christos
140 1.1 christos $i = index($FullKeyRegPath, $RootKey, $[+length($RemoteMachine)) + $[ + length($RootKey)+1;
141 1.1 christos $RegPath = substr ($FullKeyRegPath, $i);
142 1.1 christos
143 1.1 christos #print "RegPath = $RegPath\n";
144 1.1 christos
145 1.1 christos my ($RootKeyHandle, $handle, $key, $type);
146 1.1 christos
147 1.1 christos if ($RemoteMachine) {
148 1.1 christos $RootKeyHandle = regConstant($RootKey);
149 1.1 christos
150 1.1 christos if (!RegConnectRegistry ($RemoteMachine, $RootKeyHandle, $handle)) {
151 1.1 christos @$Subkeys[0]= regLastError();
152 1.1 christos return -2;
153 1.1 christos }
154 1.1 christos } else { # not valid actually because I can't find the mapping table of default
155 1.1 christos # local handle mapping. Should always pass in the Machine name to use for now
156 1.1 christos $handle = $RootKey;
157 1.1 christos }
158 1.1 christos
159 1.1 christos if (!RegOpenKeyEx ($handle, $RegPath, 0, KEY_READ, $key)) {
160 1.1 christos @$Subkeys[0] = regLastError();
161 1.1 christos #print "regLastError = @$Subkeys[0]\n";
162 1.1 christos return -3;
163 1.1 christos }
164 1.1 christos
165 1.1 christos my $tmp;
166 1.1 christos # For some reason, the regLastError() stays at ERROR_NO_MORE_ITEMS
167 1.1 christos # in occasional call sequence, so I'm resetting the error code
168 1.1 christos # before entering the loop
169 1.1 christos regLastError(0);
170 1.1 christos for ($i=0; regLastError()==regConstant("ERROR_NO_MORE_ITEMS"); $i++) {
171 1.1 christos #print "\nERROR: error enumumerating reg\n";
172 1.1 christos if (RegEnumKeyEx ($key, $i, $tmp, [], [], [], [], [])) {
173 1.1 christos @$Subkeys[$i] = $tmp;
174 1.1 christos }
175 1.1 christos }
176 1.1 christos
177 1.1 christos #print "RegType=$type\n";
178 1.1 christos #print "RegValue=@$Subkeys\n";
179 1.1 christos RegCloseKey ($key);
180 1.1 christos RegCloseKey ($handle);
181 1.1 christos
182 1.1 christos return 0;
183 1.1 christos }
184 1.1 christos
185 1.1 christos #####################################################
186 1.1 christos
187 1.1 christos sub ExtractOptionIps ($) {
188 1.1 christos my ($MSDHCPOption6Value) = @_;
189 1.1 christos my @ip;
190 1.1 christos # purpose: DHCP registry specific; to return the extracted IP addresses from
191 1.1 christos # the input variable
192 1.1 christos # input:
193 1.1 christos # $MSDHCPOption6Value: Option 6 was used to develop, but it works for any
194 1.1 christos # other options of the same datatype.
195 1.1 christos # output: none
196 1.1 christos # return:
197 1.1 christos # @ip: an arry of IP addresses in human readable format.
198 1.1 christos
199 1.1 christos
200 1.1 christos # First extract the size of the option
201 1.1 christos my ($byte, $size, $ind1, $ind2, @octet) = unpack("VVVV", $MSDHCPOption6Value);
202 1.1 christos # print "byte = $byte\nsize=$size\nind1=$ind1\nind2=$ind2\n";
203 1.1 christos
204 1.1 christos # Calculate total number of bytes that IP addresses occupy
205 1.1 christos my $number = $size * $ind1;
206 1.1 christos ($byte, $size, $ind1, $ind2, @octet) = unpack("VVVVC$number", $MSDHCPOption6Value);
207 1.1 christos
208 1.1 christos for (my $i=0; $i<$#octet; $i=$i+4) {
209 1.1 christos $ip[$i/4] = "$octet[$i+3]\.$octet[$i+2]\.$octet[$i+1]\.$octet[$i]";
210 1.1 christos }
211 1.1 christos
212 1.1 christos return @ip;
213 1.1 christos }
214 1.1 christos
215 1.1 christos #####################################################
216 1.1 christos
217 1.1 christos sub ExtractOptionStrings ($) {
218 1.1 christos my ($MSDHCPOption15Value) = @_;
219 1.1 christos my @string;
220 1.1 christos # purpose: DHCP registry specific; to return the extracted string from
221 1.1 christos # the input variable
222 1.1 christos # input:
223 1.1 christos # $MSDHCPOption15Value: Option 15 was used to develop, but it works for any
224 1.1 christos # other options of the same datatype.
225 1.1 christos # output: none
226 1.1 christos # return:
227 1.1 christos # @string: an arry of strings in human readable format.
228 1.1 christos
229 1.1 christos
230 1.1 christos # First extract the size of the option
231 1.1 christos my ($byte, $start, $ind1, $ind2, $size, @data) = unpack("VVVVV", $MSDHCPOption15Value);
232 1.1 christos # print "byte = $byte\nstart=$start\nind1=$ind1\nind2=$ind2\nsize=$size\n";
233 1.1 christos
234 1.1 christos # Calculate total number of bytes that IP addresses occupy
235 1.1 christos my $number = $size * $ind1;
236 1.1 christos ($byte, $start, $ind1, $ind2, $size, @data) = unpack("VVVVVC$number", $MSDHCPOption15Value);
237 1.1 christos
238 1.1 christos for (my $i=0; $i<$ind1; $i++) {
239 1.1 christos # actually this is only programmed to do one string, until I see
240 1.1 christos # example of how the multiple strings are represented, I don't have a
241 1.1 christos # guess to how to program them properly.
242 1.1 christos for (my $j=0; $j<$#data & $data[$j]!=0; $j+=2) {
243 1.1 christos $string[$i] = $string[$i].chr($data[$j]);
244 1.1 christos }
245 1.1 christos }
246 1.1 christos
247 1.1 christos return @string;
248 1.1 christos }
249 1.1 christos
250 1.1 christos #####################################################
251 1.1 christos
252 1.1 christos sub ExtractOptionHex ($) {
253 1.1 christos my ($MSDHCPOption46Value) = @_;
254 1.1 christos my @Hex;
255 1.1 christos # purpose: DHCP registry specific; to return the extracted hex from the input
256 1.1 christos # variable
257 1.1 christos # input:
258 1.1 christos # $MSDHCPOption46Value: Option 46 was used to develop, but it works for any
259 1.1 christos # other options of the same datatype.
260 1.1 christos # output: none
261 1.1 christos # return:
262 1.1 christos # @Hex: an arry of hex strings in human readable format.
263 1.1 christos my $Temp;
264 1.1 christos
265 1.1 christos
266 1.1 christos # First extract the size of the option
267 1.1 christos my ($byte, $unknown, $ind1, $ind2, @data) = unpack("VVVV", $MSDHCPOption46Value);
268 1.1 christos # print "byte=$byte\nunknown=$unknown\nind1=$ind1\nind2=$ind2\n";
269 1.1 christos
270 1.1 christos # Calculate total number of bytes that IP addresses occupy
271 1.1 christos my $number = $byte - 15;
272 1.1 christos ($byte, $unknown, $ind1, $ind2, @data) = unpack("VVVVC$number", $MSDHCPOption46Value);
273 1.1 christos
274 1.1 christos # printf "data=%4x\n", $data[0];
275 1.1 christos
276 1.1 christos for (my $i=0; $i<$ind1; $i++) {
277 1.1 christos # actually this is only programmed to do one Hex, until I see
278 1.1 christos # example of how the multiple Hexes are represented, I don't have a
279 1.1 christos # guess to how to program them properly.
280 1.1 christos for (my $j=3; $j>=0; $j--) {
281 1.1 christos $Hex[$i] = $Hex[$i].sprintf ("%x", $data[$j+$i*4]);
282 1.1 christos }
283 1.1 christos }
284 1.1 christos
285 1.1 christos return @Hex;
286 1.1 christos }
287 1.1 christos
288 1.1 christos #####################################################
289 1.1 christos
290 1.1 christos sub ExtractExclusionRanges ($) {
291 1.1 christos my ($MSDHCPExclusionRanges) = @_;
292 1.1 christos my @RangeList;
293 1.1 christos # purpose: DHCP registry specific; to return the extracted exclusion ranges
294 1.1 christos # from the input variable
295 1.1 christos # input:
296 1.1 christos # $MSDHCPExclusionRanges: Exclusion range as DHCP server returns them
297 1.1 christos # output: none
298 1.1 christos # return:
299 1.1 christos # @RangeList: an arry of paird IP addresses strings in human readable format.
300 1.1 christos
301 1.1 christos
302 1.1 christos # First extract the size of the option
303 1.1 christos my ($paircount, @data) = unpack("V", $MSDHCPExclusionRanges);
304 1.1 christos # print "paircount = $paircount\n";
305 1.1 christos
306 1.1 christos # Calculate total number of bytes that IP addresses occupy
307 1.1 christos # my $number = $paircount * 4*2;
308 1.1 christos # ($paircount, @data) = unpack("VC$number", $MSDHCPExclusionRanges);
309 1.1 christos #
310 1.1 christos # for (my $i=0; $i<$#data; $i=$i+4) {
311 1.1 christos # $ip[$i/4] = "$data[$i+3]\.$data[$i+2]\.$data[$i+1]\.$data[$i]";
312 1.1 christos # }
313 1.1 christos #
314 1.1 christos my $number = $paircount * 2;
315 1.1 christos ($paircount, @data) = unpack("VL$number", $MSDHCPExclusionRanges);
316 1.1 christos
317 1.1 christos for (my $i=0; $i<=$#data; $i++) {
318 1.1 christos $RangeList[$i] = pack ("L", $data[$i]);
319 1.1 christos # print "extracted", ExtractIp ($RangeList[$i]), "\n";
320 1.1 christos }
321 1.1 christos
322 1.1 christos return @RangeList;
323 1.1 christos }
324 1.1 christos #####################################################
325 1.1 christos
326 1.1 christos sub ExtractIp ($) {
327 1.1 christos my ($octet) = @_;
328 1.1 christos # purpose: to return the registry saved IP address in a readable form
329 1.1 christos # input:
330 1.1 christos # $octet: a 4 byte data storing the IP address as the registry save it as
331 1.1 christos # output: none
332 1.1 christos # return: anonymous variable of a string of IP address
333 1.1 christos
334 1.1 christos my (@data) = unpack ("C4", $octet);
335 1.1 christos
336 1.1 christos return "$data[3]\.$data[2]\.$data[1]\.$data[0]";
337 1.1 christos
338 1.1 christos }
339 1.1 christos #####################################################
340 1.1 christos
341 1.1 christos sub ExtractHex ($) {
342 1.1 christos my ($HexVal) = @_;
343 1.1 christos my @Hex;
344 1.1 christos # purpose: to return the registry saved hex number in a readable form
345 1.1 christos # input:
346 1.1 christos # $octet: a 4 byte data storing the hex number as the registry save it as
347 1.1 christos # output: none
348 1.1 christos # return:
349 1.1 christos # $Hex: string of hex digit
350 1.1 christos
351 1.1 christos
352 1.1 christos # First extract the size of the option
353 1.1 christos my (@data) = unpack("C4", $HexVal);
354 1.1 christos
355 1.1 christos for (my $i=3; $i>=0; $i--) {
356 1.1 christos $Hex[0] = $Hex[0] . sprintf ("%x", $data[$i]);
357 1.1 christos }
358 1.1 christos
359 1.1 christos return @Hex;
360 1.1 christos }
361 1.1 christos 1;
362