I was told a bit ago, after posting this on ActiveState's Perl list and on the perl-users list that I might bring this problem to the perl monks, as they may have greatly increased wisdom and insight into rooting out this problem.

I wanted to use perl to manipulate the registry on Windows XP. According to Microsoft's website "Key names are not case sensitive. Key names cannot include a backslash (\), but any other printable or unprintable character can be used."
(http://msdn.microsoft.com/library/en-us/sysinfo/base/regcreatekey.asp).

Depending on the locale in effect at the time you create the key, it seems virtually any keyname is possible. This also supports the creation of multi-byte characterset keys and keynames or valuenames with unprintable characters.

I wrote a simple routine to "iterate" all the keynames and their values. This worked fine for the HKEY_CLASSES sub-key. However for HKEY_CURRENT_USER (me), Microsoft's Sound-font selector for system actions had created some odd keynames.

Now one might say "oh, just delete those keys, they are of no use, anyway", but, I answer -- they are of excellent use: they point out a bug in the interface.

To date, no one know's exactly where the bug is -- if it is in the Win32 routines or if it is in Perl. I'm thinking there is a 30% chance it's in Perl and not specific but I don't know enough perl to verify this.

I do know that others rewrote my iteration routine and one person tried the older ("deprecated") Win32::Registry functions and none were able to iterate the suspect keys.

I wrote a simple test-case registry file that one can use to create the problem keynames. NOTE: this example file won't harm one's registry and can easily be deleted in the Registry Editory.

--- Reg5 file to create sample keys: --- Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\_ATEST_\.Default\Curren0] @="myvalue1" [HKEY_CURRENT_USER\_ATEST_\.Default\current0?] @="myvalue2" [HKEY_CURRENT_USER\_ATEST_\.Default\current0肼] @="myvalue3" [HKEY_CURRENT_USER\_ATEST_\AppGPFault\Curren0] @="myvalue4" [HKEY_CURRENT_USER\_ATEST_\AppGPFault\current0肼] @="myvalue5" -------------
Just to "get it right" in case it doesn't display/store or copy correctly above, here is the same file encoded using uuencode:
begin 640 reg5-format.reg M__Y7`&D`;@!D`&\`=P!S`"``4@!E`&<`:0!S`'0`<@!Y`"``10!D`&D`=`!O M`'(`(`!6`&4`<@!S`&D`;P!N`"``-0`N`#``,``-``H`#0`*`%L`2`!+`$4` M60!?`$,`50!2`%(`10!.`%0`7P!5`%,`10!2`%P`7P!!`%0`10!3`%0`7P!< M`"X`1`!E`&8`80!U`&P`=`!<`$,`=0!R`'(`90!N`#``!@!=``T`"@!``#T` M(@!M`'D`=@!A`&P`=0!E`#$`(@`-``H`#0`*`%L`2`!+`$4`60!?`$,`50!2 M`%(`10!.`%0`7P!5`%,`10!2`%P`7P!!`%0`10!3`%0`7P!<`"X`1`!E`&8` M80!U`&P`=`!<`&,`=0!R`'(`90!N`'0`,``_`%T`#0`*`$``/0`B`&T`>0!V M`&$`;`!U`&4`,@`B``T`"@`-``H`6P!(`$L`10!9`%\`0P!5`%(`4@!%`$X` M5`!?`%4`4P!%`%(`7`!?`$$`5`!%`%,`5`!?`%P`+@!$`&4`9@!A`'4`;`!T M`%P`8P!U`'(`<@!E`&X`=``P`+R`70`-``H`0``]`"(`;0!Y`'8`80!L`'4` M90`S`"(`#0`*``T`"@!;`$@`2P!%`%D`7P!#`%4`4@!2`$4`3@!4`%\`50!3 M`$4`4@!<`%\`00!4`$4`4P!4`%\`7`!!`'``<`!'`%``1@!A`'4`;`!T`%P` M0P!U`'(`<@!E`&X`,``&`%T`#0`*`$``/0`B`&T`>0!V`&$`;`!U`&4`-``B M``T`"@`-``H`6P!(`$L`10!9`%\`0P!5`%(`4@!%`$X`5`!?`%4`4P!%`%(` M7`!?`$$`5`!%`%,`5`!?`%P`00!P`'``1P!0`$8`80!U`&P`=`!<`&,`=0!R M`'(`90!N`'0`,`"\@%T`#0`*`$``/0`B`&T`>0!V`&$`;`!U`&4`-0`B``T` &"@`-``H` ` end
------- here is the perl program to list the above key:
#!/perl/bin/perl -w use UTF8; use Win32::TieRegistry 0.24 ; #"Classes" for HKEY_CLASSES_ROOT #"CUser" for HKEY_CURRENT_USER #"LMachine" for HKEY_LOCAL_MACHINE #"Users" for HKEY_USERS #"CConfig" for HKEY_CURRENT_CONFIG select STDERR;$|=1; select STDOUT;$|=1; my $col=1; $keyname='CUser\\_ATEST_'; print_key($Registry->{$keyname},$keyname,0); sub print_key { my ($cur_key, $keyname, $level)=@_; if ($col) { print "\n"; $col=0; } print " " x $level; $col=2; print "$keyname\\";my $nospaces=1; foreach $member ($cur_key->MemberNames) { if ($member =~ m|^(.+)\\$|) { $keyname=$1; if ($col) { print "\n"; $col=0; } $nospaces=0; print_key($cur_key->{"$keyname\\"}, "$keyname",$level+1); } elsif ($member =~ m|^\\(.*)$|) { $valuename=$1; $value=$cur_key->GetValue("$valuename"); $value=(defined $value)?$value:"(value not set)"; $value=(length($value))?$value:"(null)"; if (!$nospaces) {print " " x ($level+1); $col+=2;}; $nospaces=0; print "$valuename => $value"; if ($col) { print "\n"; $col=0; } } } }

----- The above program dies due to the error. Here is the "broken" output:
CUser\_ATEST_\ .Default\ Curren0&#9824;\ => myvalue1 current0?\ => myvalue2 current0?\ => myvalue2 AppGPFault\ Curren0&#9824;\ => myvalue4 current0?\Can't call method "MemberNames" on an undefined value at + ./test.pl line 34.

As it doesn't seem specific to TieRegistry and is in the Registry function of Win32 as well, the problem would seem to lie either in "Win32" or in perl. As I mentioned before, I'd give it about 2:1 odds of being in perl but I've no idea how Win32 works.

As it stands now, I have this "vague" uneasy feeling about how robust perl is in handling unexpected sequences in string data.

Many thanks for anyone who can isolate this problem....

Linda


In reply to possible perl bug or, at least, Win32::[TieRegistry|Registry] bug with difficult keynames by perl-diddler

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.