CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Mar 2001
    Posts
    10

    Writing to HKEY_LOCAL_MACHINE registry in NT/2K

    I have a couple of VB programs which maintain options in the Registry in (HKEY_Local_Machine/software). It has been running under Win9x but we are migrating to NT/2K in the near future.

    If the client is not an administrator, is it possible to write values to the registry area listed above? (Examples??)

    Is there a better way that will work for all users who login to the machine??

    Please Help . . .



  2. #2
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    Re: Writing to HKEY_LOCAL_MACHINE registry in NT/2K

    Here I tried and it was impossible unless having local admin rights.
    I think your best shot is to change the registry target to hkey_current_user when in winnt...

    (Happy if I learn a way to do it to Local_Machine)
    ;-)


    Special thanks to Lothar "the Great" Haensler, Tom Archer, Chris Eastwood, TCartwright, Bruno Paris, Dr_Michael
    and all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

    The Rater
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  3. #3
    Join Date
    Aug 2000
    Location
    Namibia
    Posts
    139

    Re: Writing to HKEY_LOCAL_MACHINE registry in NT/2K

    If the settings you are trying to write to the registry are universal across all User Profiles on the machine, then I suggest you use the LOCAL_MACHINE Hive. If the settings are User Specific, resort to the CURRENT_USER hive.

    I have had success in creating, opening, querying and writing keys and values to the LOCAL_MACHINE\Software hive. After much searching on the MSDN and not coming up with anything significant, except that you should resort to using the registry APIs with suffixe 'Ex' on WinNT (I guess that goes for 2K as well).

    Most of this, a copy & paste job from a template I use, was taken from www.allapi.net.

    Play around, be snappy, that deadline is looming large, hopefully it helps.

    ' Constants required for values in the keys
    private Const REG_NONE as Long = 0 ' No value type
    private Const REG_SZ as Long = 1 ' nul terminated string
    private Const REG_EXPAND_SZ as Long = 2 ' nul terminated string w/enviornment var
    private Const REG_BINARY as Long = 3 ' Free form binary
    private Const REG_DWORD as Long = 4 ' 32-bit number
    private Const REG_DWORD_LITTLE_ENDIAN as Long = 4 ' 32-bit number (same as REG_DWORD)
    private Const REG_DWORD_BIG_ENDIAN as Long = 5 ' 32-bit number
    private Const REG_LINK as Long = 6 ' Symbolic Link (unicode)
    private Const REG_MULTI_SZ as Long = 7 ' Multiple Unicode strings
    private Const REG_RESOURCE_LIST as Long = 8 ' Resource list in the resource map
    private Const REG_FULL_RESOURCE_DESCRIPTOR as Long = 9 ' Resource list in the hardware description
    private Const REG_RESOURCE_REQUIREMENTS_LIST as Long = 10

    'Registry Specific Access Rights (Fully Described)
    private Const SYNCHRONIZE = &H100000
    private Const READ_CONTROL = &H20000
    private Const STANDARD_RIGHTS_ALL = &H1F0000
    private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
    private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)
    private Const KEY_QUERY_VALUE = &H1
    private Const KEY_SET_VALUE = &H2
    private Const KEY_CREATE_LINK = &H20
    private Const KEY_CREATE_SUB_KEY = &H4
    private Const KEY_ENUMERATE_SUB_KEYS = &H8
    private Const KEY_NOTIFY = &H10
    private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
    private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
    private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
    private Const REG_CREATED_NEW_KEY = &H1 ' new Registry Key created
    private Const REG_OPENED_EXISTING_KEY = &H2 ' Existing Key opened

    ' Constants required for key locations in the registry
    public Const HKEY_CLASSES_ROOT as Long = &H80000000
    public Const HKEY_CURRENT_USER as Long = &H80000001
    public Const HKEY_LOCAL_MACHINE as Long = &H80000002
    public Const HKEY_USERS as Long = &H80000003
    public Const HKEY_PERFORMANCE_DATA as Long = &H80000004
    public Const HKEY_CURRENT_CONFIG as Long = &H80000005
    public Const HKEY_DYN_DATA as Long = &H80000006

    ' Constants required for return values (error code checking)
    private Const ERROR_SUCCESS as Long = 0
    private Const ERROR_ACCESS_DENIED as Long = 5
    private Const ERROR_NO_MORE_ITEMS as Long = 259

    ' Open/Create constants
    private Const REG_OPTION_NON_VOLATILE as Long = 0
    private Const REG_OPTION_VOLATILE as Long = &H1

    'Security Constants
    Const TOKEN_QUERY as Long = &H8&
    Const TOKEN_ADJUST_PRIVILEGES as Long = &H20&
    private Const SE_PRIVILEGE_ENABLED = &H2

    private Const ANYSIZE_ARRAY = 1

    private Type LUID
    LowPart as Long
    HighPart as Long
    End Type

    private Type LUID_AND_ATTRIBUTES
    pLuid as LUID
    Attributes as Long
    End Type

    private Type TOKEN_PRIVILEGES
    PrivilegeCount as Long
    Privileges(ANYSIZE_ARRAY) as LUID_AND_ATTRIBUTES
    End Type

    private Type LARGE_INTEGER
    LowPart as Long
    HighPart as Long
    End Type

    'Declarations Required for Security
    private Declare Function GetCurrentProcess Lib "kernel32" () as Long

    private Declare Function OpenProcessToken Lib "advapi32.dll" _
    (byval ProcessHandle as Long, byval DesiredAccess as Long, _
    TokenHandle as Long) _
    as Long

    private Declare Function LookupPrivilegeValue Lib "advapi32.dll" _
    Alias "LookupPrivilegeValueA" _
    (byval lpSystemName as string, byval lpName as string, lpLuid as LUID) _
    as Long

    private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" _
    (byval TokenHandle as Long, byval DisableAllPrivileges as Long, _
    NewState as TOKEN_PRIVILEGES, byval BufferLength as Long, _
    PreviousState as TOKEN_PRIVILEGES, ReturnLength as Long) _
    as Long

    ' Declarations required to access the Windows registry
    private Declare Function apiRegCloseKey Lib "advapi32.dll" Alias "RegCloseKey" (byval lngRootKey as Long) as Long

    private Declare Function apiRegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" _
    (byval hKey as Long, byval lpSubKey as string, byval Reserved as Long, _
    byval lpClass as string, byval dwOptions as Long, byval samDesired as Long, _
    lpSecurityAttributes as Long, phkResult as Long, _
    lpdwDisposition as Long) _
    as Long

    private Declare Function apiRegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" _
    (byval lngRootKey as Long, byval lpSubKey as string) as Long

    private Declare Function apiRegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" _
    (byval lngRootKey as Long, byval lpValueName as string) as Long

    private Declare Function apiRegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
    (byval hKey as Long, byval lpSubKey as string, byval ulOptions as Long, _
    byval samDesired as Long, phkResult as Long) _
    as Long

    private Declare Function apiRegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _
    (byval lngRootKey as Long, byval lpValueName as string, byval lpReserved as Long, _
    lpType as Long, lpData as Any, lpcbData as Long) as Long

    private Declare Function apiRegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" _
    (byval lngRootKey as Long, byval lpValueName as string, byval Reserved as Long, _
    byval dwType as Long, lpData as Any, byval cbData as Long) as Long

    'private Function SetPrivilege(byval Privilege as string, byval Enable as Boolean) as Boolean
    ''Written by DesmondVDS
    ''If you like this, you use
    ' Dim lTokenHandle as Long
    ' Dim tp_temp as TOKEN_PRIVILEGES
    ' Dim tp_prev as TOKEN_PRIVILEGES
    ' Dim luid_temp as LUID
    ' Dim lRetLen as Long
    ' Dim lRetVal as Long
    '
    ' lRetVal = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, lTokenHandle)
    ' If lRetVal = 0 then
    ' 'an error occurred
    ' Exit Function
    ' ElseIf Err.LastDllError <> 0 then
    ' 'an error occurred
    ' Exit Function
    ' End If
    '
    ' lRetVal = LookupPrivilegeValue(0&, seName, luid_temp) 'Used to look up privilege's LUID.
    ' If lRetVal = 0 then
    ' 'an error occurred
    ' Exit Function
    ' End If
    '
    ' If Not LookupPrivilegeValue(vbNullString, Privilege, luid_temp) then
    ' 'an error occured
    ' else
    ' tp_temp.PrivilegeCount = 1
    ' tp_temp.Privileges.pLuid = luid_temp
    ' If Enable then
    ' tp_temp.Privileges.Attributes = SE_PRIVILEGE_ENABLED
    ' else
    ' tp_temp.Privileges.Attributes = 0
    ' End If
    ' End If
    '
    ' SetPrivilege = AdjustTokenPrivileges(TokenHandle, false, tp_temp, len(tp_temp), tp_prev, lRetLen) <> 0
    'End Function
    '
    public Function regDelete_Sub_Key(byval strRegKey as string, byval strRegSubKey as string) as Boolean
    ' Description: Function for removing a sub key.
    on error GoTo Function_Error
    Dim lKeyHandle as Long

    If regDoes_Key_Exist(strRegKey) then

    ' get the key handle
    m_lngRetVal = apiRegOpenKeyEx(HKEY_LOCAL_MACHINE, strRegKey, 0, KEY_ALL_ACCESS, lKeyHandle)

    ' Delete the sub key. If it does not exist, then ignore it.
    m_lngRetVal = apiRegDeleteValue(lKeyHandle, strRegSubKey)

    ' Always close the handle in the registry. We do not want to
    ' corrupt the registry.
    m_lngRetVal = apiRegCloseKey(lKeyHandle)
    End If

    Function_Exit:
    If m_lngRetVal = ERROR_SUCCESS then
    regDelete_Sub_Key = true
    else
    regDelete_Sub_Key = false
    End If

    Exit Function

    Function_Error:
    resume Function_Exit
    End Function

    public Function regDoes_Key_Exist(byval strRegKey as string) as Long
    ' Description: Function to see if a key does exist
    on error GoTo Function_Error
    Dim lKeyHandle as Long

    lKeyHandle = 0

    m_lngRetVal = apiRegOpenKeyEx(HKEY_LOCAL_MACHINE, strRegKey, 0, KEY_ALL_ACCESS, lKeyHandle)

    If lKeyHandle = 0 then
    regDoes_Key_Exist = false
    else
    regDoes_Key_Exist = true
    End If

    m_lngRetVal = apiRegCloseKey(lKeyHandle)

    Function_Exit:
    Exit Function

    Function_Error:
    resume Function_Exit
    End Function

    public Function regQuery_Key(byval strRegKey as string, byval strRegSubKey as string, optional byval vDefault as Variant) as Variant
    ' Description: Function for querying a sub key value.
    Dim intPosition as Integer
    Dim lKeyHandle as Long
    Dim lngDataType as Long
    Dim lngBufferSize as Long
    Dim lngBuffer as Long
    Dim strBuffer as string

    lKeyHandle = 0
    lngBufferSize = 0

    m_lngRetVal = apiRegOpenKeyEx(HKEY_LOCAL_MACHINE, strRegKey, 0, KEY_ALL_ACCESS, lKeyHandle)

    If lKeyHandle = 0 then
    If Not IsMissing(vDefault) then
    regQuery_Key = vDefault
    else
    regQuery_Key = ""
    End If
    m_lngRetVal = apiRegCloseKey(lKeyHandle) ' always close the handle
    Exit Function
    End If

    ' Query the registry and determine the data type.
    m_lngRetVal = apiRegQueryValueEx(lKeyHandle, strRegSubKey, 0&, _
    lngDataType, byval 0&, lngBufferSize)

    If lKeyHandle = 0 then
    If Not IsMissing(vDefault) then
    regQuery_Key = vDefault
    else
    regQuery_Key = ""
    End If
    m_lngRetVal = apiRegCloseKey(lKeyHandle) ' always close the handle
    Exit Function
    End If

    Select Case lngDataType
    Case REG_SZ: ' string data (most common)
    ' Preload the receiving buffer area
    strBuffer = Space(lngBufferSize)

    m_lngRetVal = apiRegQueryValueEx(lKeyHandle, strRegSubKey, 0&, 0&, _
    byval strBuffer, lngBufferSize)

    ' If NOT a successful call then leave
    If m_lngRetVal <> ERROR_SUCCESS then
    regQuery_Key = ""
    else
    ' Strip out the string data
    intPosition = InStr(1, strBuffer, Chr(0)) ' look for the first null char
    If intPosition > 0 then
    ' if we found one, then save everything up to that point
    regQuery_Key = Left(strBuffer, intPosition - 1)
    else
    ' did not find one. Save everything.
    regQuery_Key = strBuffer
    End If
    End If

    Case REG_DWORD: ' Numeric data (Integer)
    m_lngRetVal = apiRegQueryValueEx(lKeyHandle, strRegSubKey, 0&, lngDataType, _
    lngBuffer, 4&) ' 4& = 4-byte word (long integer)

    ' If NOT a successful call then leave
    If m_lngRetVal <> ERROR_SUCCESS then
    regQuery_Key = ""
    else
    ' Save the captured data
    regQuery_Key = lngBuffer
    End If

    Case else: ' unknown
    regQuery_Key = ""
    End Select

    If regQuery_Key = "" then
    If Not IsMissing(vDefault) then
    regQuery_Key = vDefault
    else
    regQuery_Key = ""
    End If
    End If

    m_lngRetVal = apiRegCloseKey(lKeyHandle)

    End Function

    public Function regCreate_Key_Value(byval strRegKey as string, byval strRegSubKey as string, varRegData as Variant) as Boolean
    ' Description: Function for saving string data.
    on error GoTo Function_Error
    Dim lKeyHandle as Long
    Dim lngDataType as Long
    Dim lngKeyValue as Long
    Dim strKeyValue as string
    Dim lSecurity as Long
    Dim lRetVal as Long

    ' Determine the type of data to be updated
    If IsNumeric(varRegData) then
    lngDataType = REG_DWORD
    else
    lngDataType = REG_SZ
    End If

    ' m_lngRetVal = apiRegCreateKeyEx(HKEY_LOCAL_MACHINE, strRegKey, 0&, vbNullString, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0&, lKeyHandle, lRetVal)
    lSecurity = 0&
    m_lngRetVal = apiRegCreateKeyEx(HKEY_LOCAL_MACHINE, strRegKey, 0&, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, lSecurity, lKeyHandle, lRetVal)
    Select Case lngDataType
    Case REG_SZ: ' string data
    strKeyValue = Trim(varRegData) & Chr(0) ' null terminated
    m_lngRetVal = apiRegSetValueEx(lKeyHandle, strRegSubKey, 0&, lngDataType, _
    byval strKeyValue, len(strKeyValue))

    Case REG_DWORD: ' numeric data
    lngKeyValue = CLng(varRegData)
    m_lngRetVal = apiRegSetValueEx(lKeyHandle, strRegSubKey, 0&, lngDataType, _
    lngKeyValue, 4&) ' 4& = 4-byte word (long integer)

    End Select

    m_lngRetVal = apiRegCloseKey(lKeyHandle)

    Function_Exit:
    If m_lngRetVal <> ERROR_SUCCESS then
    regCreate_Key_Value = false
    else
    regCreate_Key_Value = true
    End If

    Exit Function

    Function_Error:
    resume Function_Exit
    End Function

    public Function regCreate_A_Key(byval strRegKey as string) as Long
    ' Description: This function will create a new key under the Application's Key
    on error GoTo Function_Error
    Dim lKeyHandle as Long
    Dim lRetVal as Long

    m_lngRetVal = apiRegCreateKeyEx(HKEY_LOCAL_MACHINE, strRegKey, 0&, vbNullString, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0&, lKeyHandle, lRetVal)

    m_lngRetVal = apiRegCloseKey(lKeyHandle)

    Function_Exit:
    If m_lngRetVal <> ERROR_SUCCESS then
    regCreate_A_Key = false
    else
    regCreate_A_Key = true
    End If

    Exit Function

    Function_Error:
    resume Function_Exit
    End Function

    public Function regDelete_A_Key(byval strRegSubKey, byval strRegKeyName as string) as Boolean
    on error GoTo Function_Error
    Dim lKeyHandle as Long

    regDelete_A_Key = false

    If regDoes_Key_Exist(strRegSubKey) then

    ' get the key handle
    m_lngRetVal = apiRegOpenKeyEx(HKEY_LOCAL_MACHINE, strRegSubKey, 0, KEY_ALL_ACCESS, lKeyHandle)

    ' Delete the key
    m_lngRetVal = apiRegDeleteKey(lKeyHandle, strRegKeyName)

    ' If the value returned is equal zero then we have succeeded
    If m_lngRetVal = 0 then regDelete_A_Key = true

    ' Always close the handle in the registry. We do not want to
    ' corrupt the registry.
    m_lngRetVal = apiRegCloseKey(lKeyHandle)
    End If

    Function_Exit:
    If m_lngRetVal <> ERROR_SUCCESS then
    regDelete_A_Key = false
    else
    regDelete_A_Key = true
    End If

    Exit Function

    Function_Error:
    resume Function_Exit
    End Function




  4. #4
    Join Date
    Nov 2001
    Posts
    28

    Re: Writing to HKEY_LOCAL_MACHINE registry in NT/2K - Access is denid is the user donT' have Adminis

    Well,
    the code works only when the user have Administrator privileges. What if he doesn't??? Is there a way to write to HKEY_LOCAL_MACHINE from a user without Administrative privileges? if not, is there a way to give the user Administrative privileges? I need to write to HKEY_LOCAL_MACHINE whatever the user have or don't have administrator privileges. SOmeone know how?
    thank you
    Martin



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured