NativeCall and C String question

2019-12-29 Thread ToddAndMargo via perl6-users

Hi All,

When Native call gives me back an address and byte count
to a C string, how do I turn that into a Raku string?

Address = 5636171  0x56004B
byte count = 14  (UTF16) two of these are presumed to be chr(0)

Actual string is `KVM-W7`

Many thanks,
-T

--
~~
Computers are like air conditioners.
They malfunction when you open windows
~~


Re: My Windows Modules

2019-12-29 Thread ToddAndMargo via perl6-users

On 2019-12-29 18:47, ToddAndMargo via perl6-users wrote:

On 2019-12-29 17:39, ToddAndMargo via perl6-users wrote:

Hi All,

I have been working feverishly on Windows modules to
support a program I have been tasked to write for
a customer.

And after all the wonderful help everyone has given me,
I better show what I have done with it!

So far there are four of them.  I have completed the
windows popup module.  There are test lines at the
top of the module:





Oops, I have to move constant around to they do not conflict with my 
other modules.  So, ignore this for now.


Three more to follow in a few days

This what I came up with with all the shared Native
Call constants.

Two modules to follow:  NativeConstants.pm6 and MessageBox.pm6



# unit module NativeConstants;
# NativeConstants.pm6

#`{

Constants used across Windows libraries that use Native Call

Reference to types and values: 
http://dsource.org/projects/tango/ticket/820


https://docs.microsoft.com/en-us/windows/win32/sysinfo/registry-key-security-and-access-rights

https://docs.microsoft.com/en-us/windows/win32/intl/language-identifiers

https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-

perl6 -I. -c NativeConstants.pm6

Test one liner:
   perl6 -I. -e "use NativeConstants; say 
FORMAT_MESSAGE_ALLOCATE_BUFFER.base(16);"


}


use NativeCall;

constant BYTE := uint8;
constant WCHAR:= uint16;
constant DWORD:= int32;
constant REGSAM   := int32;
constant WCHARS   := CArray[WCHAR];
constant BYTES:= CArray[BYTE];
constant CPOINTER := int32;

constant INT  = int32;
constant UINT = uint32;
constant HANDLE   = Pointer[void];
constant LPWCTSTR = CArray[WCHAR];

constant FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x0100;
constant FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
constant FORMAT_MESSAGE_IGNORE_INSERTS  = 0x0200;

constant KEY_QUERY_VALUE   = 1;
constant ERROR_SUCCESS = 0; # Win-Api  0 = success

constant KEY_READ  = 0x20019;
constant KEY_SET_VALUE = 0x0002;

constant REG_NONE   = 0;   # No value type
constant REG_SZ = 1;   # Unicode nul terminated 
string
constant REG_EXPAND_SZ  = 2;   # Unicode nul terminated 
string = (with environment variable references)

constant REG_BINARY = 3;   # Free form binary
constant REG_DWORD  = 4;   # 32-bit number
constant REG_DWORD_LITTLE_ENDIAN= 4;   # 32-bit number = (same 
as REG_DWORD)

constant REG_DWORD_BIG_ENDIAN   = 5;   # 32-bit number
constant REG_LINK   = 6;   # Symbolic Link = (unicode)
constant REG_MULTI_SZ   = 7;   # Multiple Unicode strings
constant REG_RESOURCE_LIST  = 8;   # Resource list in the 
resource map
constant REG_FULL_RESOURCE_DESCRIPTOR   = 9;   # Resource list in the 
hardware description

constant REG_RESOURCE_REQUIREMENTS_LIST = 10;
constant REG_QWORD  = 11;  # 64-bit number
constant REG_QWORD_LITTLE_ENDIAN= 11;  # same as REG_QWORD



And this is MessageBox.pm6



# unit module WinMessageBox;
# MessageBox.pm6

#`{

This Module provides access to Windows "user32" MessageBox function and
give a WinMsg to substitute for Windows Professional's msg.exe 
program, without

the networking.

This module is not able to retrieve information from the user other 
than the buttons


   Test one liners:
perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say 
MessageBox( 'Some Title', 'Something Cleaver', MB_ICONINFORMATION, MB_OK 
);"
perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say 
MessageBox( 'Some Title', 'Something Cleaver', MB_ICONQUESTION, 
MB_YESNOCANCEL );
perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say 
MessageBox( 'Some Title', 'Something Cleaver', MB_ICONERROR, 
MB_CANCELTRYCONTINUE );"


perl6 -e "use lib '.'; use WinMessageBox :WinMsg; say 
WinMsg( 'Some Title', 'Something Cleaver' );"



  References:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox

https://stackoverflow.com/questions/59105696/how-can-i-create-pop-up-windows-for-perl6-in-windows
 https://docs.perl6.org/language/nativecall
}

use NativeCall;
use NativeConstants;


enum Icons (
   MB_ICONEXCLAMATION   => 0x0030,
   MB_ICONWARNING   => 0x0030,
   MB_ICONINFORMATION   => 0x0040,
   MB_ICONASTERISK  => 0x0040,
   MB_ICONQUESTION  => 0x0020,
   MB_ICONSTOP  => 0x0010,
   MB_ICONERROR => 0x0010,
   MB_ICONHAND  => 0x0010
);

enum Buttons (
   MB_ABORTRETRYIGNORE  => 0x0002,
   MB_CANCELTRYCONTINUE => 0x0006,
   MB_HELP  => 0x4000,
   MB_OK=> 0x,
   MB_OKCANCEL  => 0x0001,
   MB_RETRYCANCEL   => 0x0005,
   MB_YESNO => 0x0004,
   MB_YESNOCANCEL   => 0x0003
);

enum 

Re: My Windows Modules

2019-12-29 Thread ToddAndMargo via perl6-users

On 2019-12-29 17:39, ToddAndMargo via perl6-users wrote:

Hi All,

I have been working feverishly on Windows modules to
support a program I have been tasked to write for
a customer.

And after all the wonderful help everyone has given me,
I better show what I have done with it!

So far there are four of them.  I have completed the
windows popup module.  There are test lines at the
top of the module:





Oops, I have to move constant around to they do not conflict with my 
other modules.  So, ignore this for now.


My Windows Modules

2019-12-29 Thread ToddAndMargo via perl6-users

Hi All,

I have been working feverishly on Windows modules to
support a program I have been tasked to write for
a customer.

And after all the wonderful help everyone has given me,
I better show what I have done with it!

So far there are four of them.  I have completed the
windows popup module.  There are test lines at the
top of the module:



# unit module WinMessageBox;
# MessageBox.pm6

#`{

This Module provides access to Windows "user32" MessageBox function and
give a WinMsg to substitute for Windows Professional's msg.exe 
program, without

the networking.

This module is not able to retrieve information from the user other 
than the buttons


   Test one liners:
perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say 
MessageBox( 'Some Title', 'Something Cleaver', MB_ICONINFORMATION, MB_OK 
);"
perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say 
MessageBox( 'Some Title', 'Something Cleaver', MB_ICONQUESTION, 
MB_YESNOCANCEL );
perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say 
MessageBox( 'Some Title', 'Something Cleaver', MB_ICONERROR, 
MB_CANCELTRYCONTINUE );"


perl6 -e "use lib '.'; use WinMessageBox :WinMsg; say 
WinMsg( 'Some Title', 'Something Cleaver' );"



  References:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox

https://stackoverflow.com/questions/59105696/how-can-i-create-pop-up-windows-for-perl6-in-windows
 https://docs.perl6.org/language/nativecall
}

use NativeCall;

constant WCHAR= uint16;
constant INT  = int32;
constant UINT = uint32;
constant HANDLE   = Pointer[void];
constant LPWCTSTR = CArray[WCHAR];


enum Icons (
   MB_ICONEXCLAMATION   => 0x0030,
   MB_ICONWARNING   => 0x0030,
   MB_ICONINFORMATION   => 0x0040,
   MB_ICONASTERISK  => 0x0040,
   MB_ICONQUESTION  => 0x0020,
   MB_ICONSTOP  => 0x0010,
   MB_ICONERROR => 0x0010,
   MB_ICONHAND  => 0x0010
);

enum Buttons (
   MB_ABORTRETRYIGNORE  => 0x0002,
   MB_CANCELTRYCONTINUE => 0x0006,
   MB_HELP  => 0x4000,
   MB_OK=> 0x,
   MB_OKCANCEL  => 0x0001,
   MB_RETRYCANCEL   => 0x0005,
   MB_YESNO => 0x0004,
   MB_YESNOCANCEL   => 0x0003
);

enum MessageBoxReturn (
   ABORT =>  3,
   CANCEL   =>  2,
   CONTINUE => 11,
   IGNORE   =>  5,
   NO   =>  7,
   OK   =>  1,
   RETRY=>  4,
   TRYAGAIN => 10,
   YES  =>  6
);


sub MessageBoxW(
   HANDLE,
   LPWCTSTR,
   LPWCTSTR,
   UINT
)
   is native("user32")
   is symbol("MessageBoxW")
   returns INT
{ * };


sub MessageBox(
   Str $Title,
   Str $Message,
   Icons $Icon = Icons::MB_ICONINFORMATION,
   Buttons $Button = Buttons::MB_OK
)
   returns MessageBoxReturn is export( :MessageBox )
{

#`{
Pop up a message box to the user.
Windows only.
Return what button was pressed

See top for test one liners
}

   my Str $SubName = &?ROUTINE.name;
   my Str $OS  = $*KERNEL.name;

   if not $OS eq "win32" {
  say "Sorry, $SubName only work in Windows.";
  exit;
   }

   my $lpText= CArray[uint16].new( $Message.encode.list ); 
$lpText[$lpText.elems]   = 0;
   my $lpCaption = CArray[uint16].new( $Title.encode.list ); 
$lpCaption[$lpCaption.elems] = 0;

   my $uType = $Icon +| $Button;   # bitwise OR them together

   return MessageBoxReturn( MessageBoxW( my $Handle, $lpText, 
$lpCaption, $uType ));

}


sub WinMsg( Str $TitleStr, Str $MessageStr ) is export( :WinMsg )  {

#`{
Simple "Ok" pop up with no return value.  Thjis as a subsitute for 
Windows `msg.exe` program

that only runs in the Professinal version and without the netowrking.

See top for test one liners
}

   my Str $SubName = &?ROUTINE.name;
   my Str $OS  = $*KERNEL.name;
   if not $OS eq "win32" {
   say "Sorry, $SubName only work in Windows.";
   exit;
   }

   return  MessageBox( $TitleStr, $MessageStr, MB_ICONINFORMATION, MB_OK );
}



Re: My pop ups for windows module

2019-12-29 Thread ToddAndMargo via perl6-users

On 2019-12-26 23:15, WFB wrote:

Hi Todd,
I refactored your code a bit to make it a bit more readable IMHO. 
Thinking on publish it on modules.raku.org  if 
you are not interested to do so.



Hi Bill,

I did not think I would like enum, but wound up liking
it anyway.

my win message is ready to go.  I changed the name
and added a lot of your ideas to it.

I will open a new thread call "My Win Modules" and
start posting them there.  Three more to go!

Thank you for the wonderful tips!

-T


Re: My Native Call notes

2019-12-29 Thread ToddAndMargo via perl6-users

On 2019-12-29 14:56, ToddAndMargo via perl6-users wrote:

Hi All,

This is my keeper on Native Call.

-T



Raku: Native Call notes:

Really poor reference: https://docs.raku.org/language/nativecall


1) Kernel32.dll call variables with a "p" in them are "C" pointers.

    LSTATUS RegOpenKeyExW(
    HKEY    hKey,
    LPCWSTR lpSubKey,
    DWORD   ulOptions,
    REGSAM  samDesired,
    PHKEY   phkResult
    );

     LPCWSTR and PHKEY in the above would be "C" pointers.

   A) Native Call converts Raku variables into C Pointer for you

   B) NativeCall converts the pointers to their contents of a
  returned “C” variable for you

2) to pass a "C" NULL to Native Call, send it a numerical zero.
    Note: in “C”, a NULL is a pointer whose value is zero

3) a “C” string is an array of characters terminated with chr(0)

4) Kernel32.dll calls with a “W” in them use UTF16 `uint16` values
    in their strings.  The rest you can use UTF8 `uint8`.  Most of
    the time they are interchangeable if you are using standard
    characters.

    Use the following to convert a Raku strings, `abcdefg` below,
    into a “C” string

   UTF8:  my $L =  CArray[uint8].new("abcdefg".encode.list);
   UTF16: my $M = CArray[uint16].new("abcdefg".encode.list);

    Native Call is tack the chr(0) at the end for you.

5) create two line to pass a call to Native Call (see 1) above for
    the call definition):

    constant WCHAR   := uint16;
    constant DWORD   := int32;

    sub RegQueryValueExW(
   DWORD,
   WCHARS,
   DWORD,
   DWORD,
   DWORD is rw,
   DWORD is rw
    )
   is native("Kernel32.dll")
   is symbol("RegQueryValueExW")
   returns DWORD
    { * };

    $RtnCode = RegQueryValueExW(
    $Handle, $lpValueName, 0, 0, $lpData, $lpcbData );

    $RtnCode is the Windows return error code.  Note: 0 is success

    $lpData is the actual data converted from the “C” pointer

    $lpcbData is the converted number of bytes in $lpData’s
    converted data





Today's revised revision:

4) Kernel32.dll calls with a “W” in them use UTF16 `uint16` values
   in their strings.  The rest you can use UTF8 `uint8`.  Most of
   the time they are interchangeable if you are using standard
   characters.

   Use the following to convert a Raku strings, `abcdefg` below,
   into a “C” string

  UTF8:  my $L =  CArray[uint8].new("abcdefg".encode.list);
  UTF16: my $M = CArray[uint16].new("abcdefg".encode.list);

   Native Call is tack the chr(0) at the end for you, most of the time

   To tack a nul on the end (two nuls won't hurt anything)

  my $M = CArray[uint16].new("abcdefg".encode.list); $M[$M.elems] = 0
  Note: you can't use `push` as it is an "immutable 'List'"

   A sub to convert and tack on the nul:

  constant WCHAR  = uint16;
  sub to-c-str( Str $str ) returns CArray[WCHAR]  {
 my @str := CArray[WCHAR].new;
 for ( $str.comb ).kv -> $i, $char { @str[$i] = $char.ord; }
 @str[ $str.chars ] = 0;
 @str;
  }




--
~~
Computers are like air conditioners.
They malfunction when you open windows
~~


My Native Call notes

2019-12-29 Thread ToddAndMargo via perl6-users

Hi All,

This is my keeper on Native Call.

-T



Raku: Native Call notes:

Really poor reference: https://docs.raku.org/language/nativecall


1) Kernel32.dll call variables with a "p" in them are "C" pointers.

   LSTATUS RegOpenKeyExW(
   HKEYhKey,
   LPCWSTR lpSubKey,
   DWORD   ulOptions,
   REGSAM  samDesired,
   PHKEY   phkResult
   );

LPCWSTR and PHKEY in the above would be "C" pointers.

  A) Native Call converts Raku variables into C Pointer for you

  B) NativeCall converts the pointers to their contents of a
 returned “C” variable for you

2) to pass a "C" NULL to Native Call, send it a numerical zero.
   Note: in “C”, a NULL is a pointer whose value is zero

3) a “C” string is an array of characters terminated with chr(0)

4) Kernel32.dll calls with a “W” in them use UTF16 `uint16` values
   in their strings.  The rest you can use UTF8 `uint8`.  Most of
   the time they are interchangeable if you are using standard
   characters.

   Use the following to convert a Raku strings, `abcdefg` below,
   into a “C” string

  UTF8:  my $L =  CArray[uint8].new("abcdefg".encode.list);
  UTF16: my $M = CArray[uint16].new("abcdefg".encode.list);

   Native Call is tack the chr(0) at the end for you.

5) create two line to pass a call to Native Call (see 1) above for
   the call definition):

   constant WCHAR   := uint16;
   constant DWORD   := int32;

   sub RegQueryValueExW(
  DWORD,
  WCHARS,
  DWORD,
  DWORD,
  DWORD is rw,
  DWORD is rw
   )
  is native("Kernel32.dll")
  is symbol("RegQueryValueExW")
  returns DWORD
   { * };

   $RtnCode = RegQueryValueExW(
   $Handle, $lpValueName, 0, 0, $lpData, $lpcbData );

   $RtnCode is the Windows return error code.  Note: 0 is success

   $lpData is the actual data converted from the “C” pointer

   $lpcbData is the converted number of bytes in $lpData’s
   converted data




Re: null and native call question

2019-12-29 Thread ToddAndMargo via perl6-users

On 2019-12-29 05:46, WFB wrote:

Hi Todd,
I am curious, what was the problem?
I tried 0 in the first place and the script died. Though it has 
something to do with the 0 but obviously it has not.




Hi Bill,

I have a major rewrite underway for several of my
modules. Hopefully I will post them her today
for evaluation.

On the "null and native call question", Native
Call translates a zero into a C NULL for you.
My run and die issue was not lpReserved being
sent a NULL incorrectly.  The culprit was M$ and
lpType.

https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw

 C++
 LSTATUS RegQueryValueExW(
   HKEYhKey,
   LPCWSTR lpValueName,
   LPDWORD lpReserved,
   LPDWORD lpType,
   LPBYTE  lpData,
   LPDWORD lpcbData
 );

lpType

A pointer to a variable that receives a code
indicating the type of data stored in the
specified value. For a list of the possible
type codes, see Registry Value Types. The
lpType parameter can be NULL if the type code
is not required.

I was sending lpType the value for REG_DWORD (0x0004)
and sometimes REG_SZ (0x0001).  This caused
the call to die with no error message.

The ONLY value of lpType that actually works is 0
(NULL).

Ha!  M$ STRIKES AGAIN!  Good gracious I wasted and
a lot of others helping me wasted a lot of time on this!

  AAHHH!!!  

-T


Re: null and native call question

2019-12-29 Thread WFB
Hi Todd,
I am curious, what was the problem?
I tried 0 in the first place and the script died. Though it has something
to do with the 0 but obviously it has not.

On Sun, 29 Dec 2019 at 10:31, ToddAndMargo via perl6-users <
perl6-users@perl.org> wrote:

> On 2019-12-29 00:28, ToddAndMargo via perl6-users wrote:
> >>> On Fri, Dec 27, 2019 at 6:06 AM ToddAndMargo via perl6-users
> >>> mailto:perl6-users@perl.org>> wrote:
> >>>
> >>> Hi All,
> >>>
> >>> https://docs.perl6.org/language/nativecall
> >>>
> >>>"As you may have predicted by now, a NULL pointer
> >>>is represented by the type object of the struct type."
> >>>
> >>>
> >>>
> https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw
> >>>
> >>>
> >>>C++
> >>>LSTATUS RegQueryValueExW(
> >>>  HKEYhKey,
> >>>  LPCWSTR lpValueName,
> >>>  LPDWORD lpReserved,
> >>>  LPDWORD lpType,
> >>>  LPBYTE  lpData,
> >>>  LPDWORD lpcbData
> >>>);
> >>>
> >>>lpReserved
> >>>This parameter is reserved and must be NULL.
> >>>
> >>> With "native", how do I satisfy the "NULL" requirement?
> >>>
> >>> constant WCHAR   := uint16;
> >>>
> >>> constant DWORD   := int32;
> >>>
> >>>
> >>> sub RegQueryValueExW( DWORD, WCHARS, DWORD, DWORD, DWORD is rw,
> >>> DWORD is
> >>> rw ) is native("Kernel32.dll") returns DWORD { * };
> >>>
> >>> $RtnCode = RegQueryValueExW( $Handle, $lpValueName, int32,
> >>> REG_DWORD,
> >>> $lpData, $lpcbData );
> >>>
> >>> "int32" returns:
> >>>
> >>>   Cannot unbox a type object (int32) to int in method
> >>>   CALL-ME at C:\rakudo\share\perl6\sources
> >>> \947BDAB9F96E0E5FCCB383124F9
> >>>   23A6BF6F8D76B (NativeCall) line 587
> >>>
> >>>
> >>> Many thanks,
> >>> -T
> >>>
> >
> > On 2019-12-27 06:10, Brad Gilbert wrote:
> >> A Null pointer is just a pointer that points to the address 0.
> >>
> >> So if you are dealing with it as an integer it will be 0.
>
> Hi Brad,
>
> Disregard my last post.  I found a booboo somewhere else.
> You were correct about the zero.
>
> Thank you!
>
> -T
>


Re: null and native call question

2019-12-29 Thread ToddAndMargo via perl6-users

On 2019-12-29 00:28, ToddAndMargo via perl6-users wrote:
On Fri, Dec 27, 2019 at 6:06 AM ToddAndMargo via perl6-users 
mailto:perl6-users@perl.org>> wrote:


    Hi All,

    https://docs.perl6.org/language/nativecall

   "As you may have predicted by now, a NULL pointer
   is represented by the type object of the struct type."


https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw 



   C++
   LSTATUS RegQueryValueExW(
 HKEY    hKey,
 LPCWSTR lpValueName,
 LPDWORD lpReserved,
 LPDWORD lpType,
 LPBYTE  lpData,
 LPDWORD lpcbData
   );

   lpReserved
   This parameter is reserved and must be NULL.

    With "native", how do I satisfy the "NULL" requirement?

    constant WCHAR   := uint16;

    constant DWORD   := int32;


    sub RegQueryValueExW( DWORD, WCHARS, DWORD, DWORD, DWORD is rw,
    DWORD is
    rw ) is native("Kernel32.dll") returns DWORD { * };

    $RtnCode = RegQueryValueExW( $Handle, $lpValueName, int32, 
REG_DWORD,

    $lpData, $lpcbData );

    "int32" returns:

  Cannot unbox a type object (int32) to int in method
  CALL-ME at C:\rakudo\share\perl6\sources
    \947BDAB9F96E0E5FCCB383124F9
  23A6BF6F8D76B (NativeCall) line 587


    Many thanks,
    -T



On 2019-12-27 06:10, Brad Gilbert wrote:

A Null pointer is just a pointer that points to the address 0.

So if you are dealing with it as an integer it will be 0.


Hi Brad,

Disregard my last post.  I found a booboo somewhere else.
You were correct about the zero.

Thank you!

-T


Re: null and native call question

2019-12-29 Thread ToddAndMargo via perl6-users
On Fri, Dec 27, 2019 at 6:06 AM ToddAndMargo via perl6-users 
mailto:perl6-users@perl.org>> wrote:


Hi All,

https://docs.perl6.org/language/nativecall

   "As you may have predicted by now, a NULL pointer
   is represented by the type object of the struct type."


https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw

   C++
   LSTATUS RegQueryValueExW(
 HKEYhKey,
 LPCWSTR lpValueName,
 LPDWORD lpReserved,
 LPDWORD lpType,
 LPBYTE  lpData,
 LPDWORD lpcbData
   );

   lpReserved
   This parameter is reserved and must be NULL.

With "native", how do I satisfy the "NULL" requirement?

constant WCHAR   := uint16;

constant DWORD   := int32;


sub RegQueryValueExW( DWORD, WCHARS, DWORD, DWORD, DWORD is rw,
DWORD is
rw ) is native("Kernel32.dll") returns DWORD { * };

$RtnCode = RegQueryValueExW( $Handle, $lpValueName, int32, REG_DWORD,
$lpData, $lpcbData );

"int32" returns:

  Cannot unbox a type object (int32) to int in method
  CALL-ME at C:\rakudo\share\perl6\sources
\947BDAB9F96E0E5FCCB383124F9
  23A6BF6F8D76B (NativeCall) line 587


Many thanks,
-T



On 2019-12-27 06:10, Brad Gilbert wrote:

A Null pointer is just a pointer that points to the address 0.

So if you are dealing with it as an integer it will be 0.



Hi Brad,

Sending a zero to it causes the program to exit with no
error code.

The offending line is:
$RtnCode = RegQueryValueExW( $Handle, $lpValueName, 0, REG_DWORD, 
$lpData, $lpcbData );



Sending it a zero:

say "RegQueryValueExW";

sub RegQueryValueExW( DWORD, WCHARS, DWORD, DWORD, DWORD is rw, DWORD is 
rw ) is native("Kernel32.dll") returns DWORD { * };



say "1";


$RtnCode = RegQueryValueExW( $Handle, $lpValueName, 0, REG_DWORD, 
$lpData, $lpcbData );



say "2";


say "RegQueryValueExW   RtnCode $RtnCode  (6 = The handle is invalid; 87 
= ERROR_INVALID_PARAMETER)\nlpData pointer $lpData\nlpcbData data length 
$lpcbData\n";





RegQueryValueExW
1

Note that it dies without an error code.


Sending it a one:

say "RegQueryValueExW";

sub RegQueryValueExW( DWORD, WCHARS, DWORD, DWORD, DWORD is rw, DWORD is 
rw ) is native("Kernel32.dll") returns DWORD { * };


say "1";

   $RtnCode = RegQueryValueExW( $Handle, $lpValueName, 1, REG_DWORD, 
$lpData, $lpcbData );


say "2";

say "RegQueryValueExW   RtnCode $RtnCode  (6 = The handle is invalid; 87 
= ERROR_INVALID_PARAMETER)\nlpData pointer $lpData\nlpcbData data length 
$lpcbData\n";




RegQueryValueExW
1
2
RegQueryValueExW   RtnCode 87  (6 = The handle is invalid; 87 = 
ERROR_INVALID_PARAMETER)

lpData pointer 0
lpcbData data length 0



I can't win.

:'(

Thank you for the help.

-T

--
~~
Computers are like air conditioners.
They malfunction when you open windows
~~