'===========================================================================
' Subject: READ/WRITE FROM REGISTRY           Date: 01-14-98 (12:29)       
'  Author: Kerry S. Goodin                    Code: PBDLL                  
'  Origin: medvrsys@venus.net               Packet: PBDLL.ABC
'===========================================================================
'///////////////////////////////////////////////////////////
'written by: Kerry S. Goodin, D.D.S.                      //
'FOR PBDLL 5.0 32 bit ONLY.                               //
'released into public domain January 1998                 //
'no responsibility is assumed or accepted.                //
'///////////////////////////////////////////////////////////
'                                                         //
'PbRegEdit.bas is a program to show how to write to and   //
'read from the windows registry using PBDLL 5.0.  This is //
'only a 32 bit mode program for Windows 9X and Windows NT //
'Use at your own risk.  Look at keys with RegEdit.exe     //
'in Windows.  This code is based on code found in         //
'microsoft's knowledge base.                              //
'                                                         //
'///////////////////////////////////////////////////////////

'note: a few modifications and this becomes a dll 
'      capable of being called from other 32 bit programs.

$COMPILE EXE
$DIM ALL
$INCLUDE "WIN32API.INC"

GLOBAL REG_SZ AS LONG
GLOBAL REG_DWORD AS LONG 

GLOBAL HKEY_CLASSES_ROOT AS LONG 
GLOBAL HKEY_CURRENT_USER  AS LONG
GLOBAL HKEY_LOCAL_MACHINE AS LONG
GLOBAL HKEY_PERFORMANCE_DATA AS LONG
GLOBAL HKEY_USERS AS LONG
GLOBAL HKEY_DYN_DATA AS LONG
GLOBAL HKEY_CURRENT_CONFIG AS LONG

GLOBAL ERROR_NONE AS LONG
GLOBAL ERROR_BADDB AS LONG
GLOBAL ERROR_BADKEY AS LONG
GLOBAL ERROR_CANTOPEN AS LONG
GLOBAL ERROR_CANTREAD AS LONG
GLOBAL ERROR_CANTWRITE AS LONG
GLOBAL ERROR_OUTOFMEMORY AS LONG
GLOBAL ERROR_INVALID_PARAMETER AS LONG
GLOBAL ERROR_ACCESS_DENIED AS LONG
GLOBAL ERROR_INVALID_PARAMETERS AS LONG
GLOBAL ERROR_NO_MORE_ITEMS AS LONG

GLOBAL KEY_ALL_ACCESS AS LONG
GLOBAL REG_OPTION_NON_VOLATILE AS LONG                 
GLOBAL NULLSTRING AS STRING 

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Return true if OS is Windows 95
' From PbDll Common32.bas
' Copyright (c) 1997 by PowerBASIC, Inc.
'
FUNCTION IsWin95() EXPORT AS LONG

  LOCAL vi AS OSVERSIONINFO

  vi.dwOsVersionInfoSize = SIZEOF(vi)
  GetVersionEx vi

  FUNCTION = (vi.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS)

END FUNCTION

FUNCTION QueryValueEx(lhKey AS LONG,BYVAL szValueName AS STRING, _
		      vValue AS STRING) AS LONG

         DIM cch AS LONG
         DIM lRetVal AS LONG
         DIM lType AS LONG
         DIM lValue AS LONG
         DIM sValue AS ASCIIZ * 255

         On Error GoTo QueryValueExError

         ' Determine the size and type of data to be read
         
         lRetVal = RegQueryValueEx(lhKey, BYCOPY szValueName, 0& , lType , BYVAL ERROR_NONE , cch )
         
         IF lRetVal <> ERROR_NONE THEN Error 5

         SELECT CASE lType

             CASE REG_SZ:            ' For strings

                 sValue = STRING$(cch, 0)
                 lRetVal = RegQueryValueEx(lhKey, BYCOPY szValueName, 0&, lType, sValue, cch)                    
                 IF lRetVal = ERROR_NONE THEN
                     vValue = Left$(sValue, cch)
                 ELSE
                     vValue = ""
                 END IF
             
             CASE REG_DWORD:         ' For DWORDS
             
                 lRetVal = RegQueryValueEx(lhKey, BYCOPY szValueName, 0&, lType, lValue, cch)
                 If lRetVal = ERROR_NONE THEN vValue = str$(lValue)

             CASE ELSE               'all other data types not supported
             
                 lRetVal = -1

         END SELECT

QueryValueExExit:

         QueryValueEx = lRetVal
         Exit FUNCTION

QueryValueExError:

         Resume QueryValueExExit

END FUNCTION

FUNCTION SetRegString(hKey AS LONG, BYVAL sValueName AS STRING, _
	              BYVAL lType AS LONG, sValue AS ASCIIZ) AS LONG

         DIM lLength AS LONG
         lLength = Len(sValue)
         SetRegString = RegSetValueEx(hKey, BYCOPY sValueName, 0&, lType, sValue, lLength)

END FUNCTION

FUNCTION SetRegLong(hKey AS LONG, BYVAL sValueName AS STRING, _
		    BYVAL lType AS LONG, BYVAL lValue AS LONG) AS LONG
         
         DIM lLength AS LONG
         lLength = 4&
         SetRegLong = RegSetValueEx(hKey, BYCOPY sValueName, 0&, lType, lValue, lLength)

END FUNCTION

FUNCTION QueryValue(lPredefinedKey AS LONG, sKeyName AS STRING, _
		    sValueName AS STRING) AS STRING

         DIM lRetVal AS LONG       'result of the API FUNCTIONs
         DIM hKey AS LONG          'handle of opened key
         DIM sValue AS STRING      'setting of queried value
                     
         lRetVal = RegOpenKeyEx(lPredefinedKey, BYCOPY sKeyName, 0&, BYVAL KEY_ALL_ACCESS, hKey)
         lRetVal = QueryValueEx(hKey, sValueName, sValue)
         lRetVal = RegCloseKey(hKey)
         FUNCTION = sValue

END FUNCTION

SUB SetStringKeyValue(lPredefinedKey AS LONG, sKeyName AS STRING, _
                      sValueName AS STRING, sValueSetting AS STRING, lValueType AS LONG)

         DIM lRetVal AS LONG                    'result of the SetStringKeyValue
         DIM hKey AS LONG                       'handle of open key
         LOCAL SecurAtt AS SECURITY_ATTRIBUTES  'user defined type
        
         SecurAtt.nLength = 0&
	 SecurAtt.lpSecurityDescriptor = 0&
	 SecurAtt.bInheritHandle = 0&
	  
         'open and set the specified key
         lRetVal = RegCreateKeyEx(BYVAL lPredefinedKey, BYCOPY sKeyName, 0&, _
                   BYCOPY NULLSTRING, BYVAL REG_OPTION_NON_VOLATILE, BYVAL KEY_ALL_ACCESS, _
                   SecurAtt, hKey, lRetVal)
         lRetVal = SetRegString(hKey, sValueName, lValueType, BYCOPY sValueSetting)
         lRetVal = RegCloseKey(hKey)

END SUB

SUB SetLongKeyValue(lPredefinedKey AS LONG, sKeyName AS STRING, _
                    sValueName AS STRING, lValueSetting AS LONG, lValueType AS LONG)

         DIM lRetVal AS LONG                    'result of the SetLongKeyValue
         DIM hKey AS LONG                       'handle of open key
         LOCAL SecurAtt AS SECURITY_ATTRIBUTES  'user defined type
        
         SecurAtt.nLength = 0&
	 SecurAtt.lpSecurityDescriptor = 0&
	 SecurAtt.bInheritHandle = 0&

         'open and set the specified key
         lRetVal = RegCreateKeyEx(BYVAL lPredefinedKey, BYCOPY sKeyName, 0&, _
                   BYCOPY NULLSTRING, BYVAL REG_OPTION_NON_VOLATILE, BYVAL KEY_ALL_ACCESS, _
                   SecurAtt, hKey, lRetVal)
         lRetVal = SetRegLong(hKey, sValueName, lValueType, BYVAL lValueSetting)
         lRetVal = RegCloseKey (hKey)

END SUB

FUNCTION WinMain (BYVAL hInstance     AS LONG, _
                  BYVAL hPrevInstance AS LONG, _
                  lpCmdLine           AS ASCIIZ PTR, _
                  BYVAL iCmdShow      AS LONG) AS LONG

'setup program                  

  REG_SZ = 1&                'value for registry string
  REG_DWORD = 4&             'value for registry dword
  
  HKEY_CLASSES_ROOT = &H80000000
  HKEY_CURRENT_USER = &H80000001
  HKEY_LOCAL_MACHINE = &H80000002
  HKEY_PERFORMANCE_DATA = &H80000004
  HKEY_USERS = &H80000003
  HKEY_DYN_DATA = &H80000006
  HKEY_CURRENT_CONFIG = &H80000005
                  
  ERROR_NONE = 0&
  ERROR_BADDB = 1&
  ERROR_BADKEY = 2&
  ERROR_CANTOPEN = 3&
  ERROR_CANTREAD = 4&
  ERROR_CANTWRITE = 5&
  ERROR_OUTOFMEMORY = 6&
  ERROR_INVALID_PARAMETER = 7&
  ERROR_ACCESS_DENIED = 8&
  ERROR_INVALID_PARAMETERS = 87&
  ERROR_NO_MORE_ITEMS = 259&
                 
  KEY_ALL_ACCESS = &H3F
  REG_OPTION_NON_VOLATILE = 0&
  NULLSTRING = ""

  DIM sRetVal AS STRING	    'returned STRING value
  DIM sKeyName AS STRING    'key name to insert
  DIM sPath AS STRING       'sub key path. example: "SubKey1\SubKey1a". note: no leading "\" or trailing "\"
  DIM sKeyValue AS STRING   'string value of key 
  DIM lKeyValue AS LONG     'long integer value of key

'******************************************************************************************
'program execution begins here

  sPath = "TestKey\Level1\Level2\Level3"
  sKeyName = "MY_STRING_KEY"
  sKeyValue = "My Default String Key"

'how to set and query a key string value
  CALL SetStringKeyValue(HKEY_CURRENT_USER, sPath, sKeyName, sKeyValue, REG_SZ)
  sRetVal = QueryValue(HKEY_CURRENT_USER, sPath , sKeyName)
  MsgBox "For '" & sPath & "\" & sKeyValue & "' the value is '" & sRetVal & "'"

  sKeyName = "MY_LONG_KEY"
  lKeyValue = 1000&

'how to set and query a key long integer value 
  CALL SetLongKeyValue(HKEY_CURRENT_USER, sPath, sKeyName, lKeyValue, REG_DWORD)
  sRetVal = QueryValue(HKEY_CURRENT_USER, sPath, sKeyName)
  MsgBox "For '" & sPath & "\" & sKeyName & "' the value is '" & sRetVal & "'"

'look up some key values
  IF IsWin95 THEN
	  sPath = "System\CurrentcontrolSet\Services\VxD\VNETSUP"
	  sKeyName = "ComputerName"
	  sRetVal = QueryValue(HKEY_LOCAL_MACHINE, sPath , sKeyName)
	  MsgBox "For '" & sKeyName & "' the value is '" & sRetVal & "'"

	  sKeyName = "Comment"
	  sRetVal = QueryValue(HKEY_LOCAL_MACHINE, sPath , sKeyName)
	  MsgBox "For '" & sKeyName & "' the value is '" & sRetVal & "'"
  ELSE
  	  sPath = "System\ControlSet001\Control\ComputerName\ActiveComputerName"
          sKeyName = "ComputerName"
	  sRetVal = QueryValue(HKEY_LOCAL_MACHINE, sPath , sKeyName)
	  MsgBox "For '" & sKeyName & "' the value is '" & sRetVal & "'"
  END IF

'program execution ends here
'******************************************************************************************
  
END FUNCTION
