NB. built from project: ~Source\api\registry\registry
NB. Windows Registry functions
NB.
NB. These functions allow data to be stored into and retrived
NB.   from the Windows Registry.  Only Query and Set are supported;
NB.   Links and Subkeys are not supported.
NB. To access the Registry, you first get a key, then use that
NB.   key to query and set values.  Once you have made your
NB.   accesses to the Registry, you should close the key (DO NOT
NB.   leave it open for future use).
NB. The handle used to get a key is either one of the
NB.   permanently-available classes or a key returned from a
NB.   previous regcreatekey.  The permanent classes are
NB.   HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE,
NB.   and HKEY_USERS.
NB. When you create a key, you specify whether it will be used for
NB.   reading(1) , writing (2), or both (3)
NB.
NB. Example of use:
NB.
NB. h =. 1 {:: regcreatekey HKEY_CURRENT_USER;'SOFTWARE\XXX\xxx.ini';3
NB. regsetvalue h;'Drive';1;'J:'
NB. v =. regqueryvalue h;'Drive'
NB. regclosekey h
NB.
NB. Contributed by Henry H. Rich (glasss@bellsouth.net), May 2001

script_z_ '~system\main\dll.ijs'

cocurrent 'z'


NB. =========================================================
winerror=: verb define
FORMAT_MESSAGE_FROM_SYSTEM=. 4096
deb=. #~ (+. 1: |. (> </\))@(' '&~:)
deb >5{'kernel32 FormatMessageA i i i i i *c i i'cd FORMAT_MESSAGE_FROM_SYSTEM;0;y.;0;(255#' ');255;0
)

HKEY_CLASSES_ROOT=: _2147483648
HKEY_CURRENT_USER=: _2147483647
HKEY_LOCAL_MACHINE=: _2147483646
HKEY_USERS=: _2147483645

NB. Root codes:
NB. 80000000 _2147483648 HKEY_CLASSES_ROOT
NB. 80000001 _2147483647 HKEY_CURRENT_USER
NB. 80000002 _2147483646 HKEY_LOCAL_MACHINE
NB. 80000003 _2147483645 HKEY_USERS

NB. Type codes:
NB. 1 REG_SZ
NB. 2 REG_EXPAND_SZ  vbl subst (not supported)
NB. 3 REG_BINARY
NB. 4 REG_DWORD (only a single dword is supported)
NB. 5 REG_DWORD_BIG_ENDIAN (not supported)
NB. 6 REG_LINK (not supported)
NB. 7 REG_MULTI_SZ (not supported)
NB. 8 REG_RESOURCE_LIST (not supported)
NB. 9 REG_FULL_RESOURCE_DESCRIPTOR (not supported)
NB. 10 REG_RESOURCE_REQUIREMENTS_LIST  (not supported)

NB. Access codes:
NB. 1 KEY_QUERY_VALUE
NB. 2 KEY_SET_VALUE
NB. 4 KEY_CREATE_SUB_KEY (not supported)
NB. 8 KEY_ENUMERATE_SUB_KEYS (not supported)
NB. 16 KEY_NOTIFY (not supported)
NB. 32 KEY_CREATE_LINK (not supported)

NB. =========================================================
NB. LONG RegCreateKeyEx(
NB.   HKEY hKey,                // handle to an open key
NB.   LPCTSTR lpSubKey,         // address of subkey name
NB.   DWORD Reserved,           // reserved
NB.   LPTSTR lpClass,           // address of class string
NB.   DWORD dwOptions,          // special options flag
NB.   REGSAM samDesired,        // desired security access
NB.   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
NB.                             // address of key security structure
NB.   PHKEY phkResult,          // address of buffer for opened handle
NB.   LPDWORD lpdwDisposition   // address of disposition value buffer
NB. );

NB.*regcreatekey v-- Create a Registry key.  Monad.
NB. Create or open a key, return 0;handle (or 1;emsg_text if error)
NB. y. is rootcode;keystring;security
NB.  rootcode is a previously-opened handle, or one of the permanently-open
NB.    HKEY_ names
NB.  keystring is a string describing the key you want to open
NB.  security is the access code, a combination of KEY_QUERY_VALUE (1) and
NB.    KEY_SET_VALUE (2)
regcreatekey=: 3 : 0
'root key sam'=. y.
if. =/ sam >: 0 4 do. 'Unsupported security' 13!:8 (3) end.
createrc=. 'Advapi32 RegCreateKeyExA i   i *c i *c i i i *i *i' cd root;key;0;'';0;sam;0;(,_1);(,_1)
if. 0 = >@{. createrc do.
  0;{. 8 {:: createrc  NB. Convert response to scalar for use as memory address
else.
  1;winerror >@{. createrc  NB. If error, return the error code
end.
)

NB. =========================================================
NB. LONG RegSetValueEx(
NB.   HKEY hKey,           // handle to key to set value for
NB.   LPCTSTR lpValueName, // name of the value to set
NB.   DWORD Reserved,      // reserved
NB.   DWORD dwType,        // flag for value type
NB.   CONST BYTE *lpData,  // address of value data
NB.   DWORD cbData         // size of value data
NB. );

NB.*regsetvalue v-- Install a value in the Registry.  Monad.
NB. y. is (handle from regcreatekey);(name of vbl);type;value
NB.   type is one of: 1 (string), 3 (boolean) , 4 (dword)
NB.   value must match the type
NB. Result is 0;'' if no error, 1;emsg text if error
regsetvalue=: 3 : 0
'key value valuetype data'=. y.
select. ,valuetype
case. ,1 do. NB. string
  if. ,2 ~: 3!:0 data do. 'Data type is not string' 13!:8 (3) end.
  len=. >: # data
case. ,4 do.  NB. dword
  if. -. 1 4 e.~ 3!:0 data do. 'Data type is not integer' 13!:8 (3) end.
  if. 4 ~: len=. 4 * # ,data do. 'Data length not 1' 13!:8 (3) end.
case. ,3 do. NB. binary
  if. -. 1 4 e.~ 3!:0 data do. 'Data type is not binary' 13!:8 (3) end.
  data=. 2 ic data
  len=. # data
case. do.
  'Unsupported type' 13!:8 (3)
end.
r=. >@{. 'Advapi32 RegSetValueExA i   i *c i i * i' cd key;value;0;valuetype;(,data);len
if. r=0 do. 0;'' else. 1 ; winerror >@{.r end.
)

NB. =========================================================
NB. LONG RegQueryValueEx(
NB.   HKEY hKey,            // handle to key to query
NB.   LPCTSTR lpValueName,  // address of name of value to query
NB.   LPDWORD lpReserved,   // reserved
NB.   LPDWORD lpType,       // address of buffer for value type
NB.   LPBYTE lpData,        // address of data buffer
NB.   LPDWORD lpcbData      // address of data buffer size
NB. );
NB. y. is (handle from regcreatekey);(name of vbl);(max length)
NB. Result is (retcode, 0 if good);(value if no error, emsg text if error)
regqueryvalue=: 3 : 0
'key value maxsize'=. 3 {. y. ,<128
queryrc=. 'Advapi32 RegQueryValueExA i   i *c i *i *c *i' cd key;value;0;(,_1);($&'z' ; ,&]) maxsize
if. 0 = >@{. queryrc do.
  select. ,4 {:: queryrc
  case. ,1 do.  NB. string - trim trailing zero
    0 ; (<: 6 {:: queryrc) {. 5 {:: queryrc
  case. ,4 do.  NB. dword - convert to integer
    if. 4 ~: 6 {:: queryrc do. 'Data length not 4' 13!:8 (3) end.
    0 ; _2 (3!:4) 4 {. 5 {:: queryrc
  case. ,3 do. NB. binary
    sz=. 6 {:: queryrc
    0 ; _2 (3!:4) sz {. 5 {:: queryrc
  case. do.
    'Unsupported type' 13!:8 (3)
  end.
else.
  1 ; winerror >@{.queryrc  NB. If error, return the error code
end.

)

NB. =========================================================
NB. LONG RegCloseKey(
NB.   HKEY hKey   // handle to key to close
NB. );
NB. y. is handle from regcreatekey.  The key is closed.  Result is the
NB. result from the system call
regclosekey=: 3 : 0
>@{. 'Advapi32 RegCloseKey i   i' cd y.
)

NB. =========================================================
NB. Change ^:0 to ^:1 for debug text
smoutput^:0 (0 : 0)
HND=. 1 {:: regcreatekey HKEY_LOCAL_MACHINE;'SOFTWARE\Iverson Software\J\4.06a';3
regqueryvalue HND;'path'
regsetvalue HND;'MyVal1';3;(i.5)
regqueryvalue HND;'MyVal1'
regclosekey HND
)

