Hola a toda la comunidad...

Ando liadísimo con una aplicación que consiste en un Scada el cúal tendrá diferentes layers de acceso por lo que se deberán introducir los correspondientes passwords. El tema es que la idea es utilizar la propia gestión que realiza Windows con las cuentas de usuario de modo que nuestra aplicación sea capaz de leer y comprobar las propiedaes de cada perfil de usuario. Cada layer se corresponderá con un grupo de usuarios creado previamente mediante el lusrmgr (Usuarios locales y grupos). El administrador tendrá acceso a esta herramienta de windows (XP).

Una vez haberos dado la chapa con la explicación de la aplicación me centraré en la problemática:

Algo he visto por la red de que las propiedades de usuario están en el registro HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account...

Bién, ya he conseguido acceder, crear y editar claves y valores del registro mediante diferentes funciones API. Sin embargo me falla lo de enumerar claves y valores para saber el número de usuarios. Siempre me falla la función api RegQueryInfoKey por fallo en parámetros .

Aquí os dejo el código:

Option Explicit
Public Const REG_SZ As Long = 1 'cadena
Public Const REG_DWORD As Long = 4 'número
Public Const HKEY_CLASSES_ROOT = &H80000000
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const HKEY_USERS = &H80000003
Public Const ERROR_NONE = 0
Public Const ERROR_BADDB = 1
Public Const ERROR_BADKEY = 2
Public Const ERROR_CANTOPEN = 3
Public Const ERROR_CANTREAD = 4
Public Const ERROR_CANTWRITE = 5
Public Const ERROR_OUTOFMEMORY = 6
Public Const ERROR_ARENA_TRASHED = 7
Public Const ERROR_ACCESS_DENIED = 8
Public Const ERROR_INVALID_PARAMETERS = 87
Public Const ERROR_NO_MORE_ITEMS = 259
Public Const KEY_QUERY_VALUE = &H1
Public Const KEY_SET_VALUE = &H2
Public Const KEY_ALL_ACCESS = &H3F
Public Const REG_OPTION_NON_VOLATILE = 0

Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Public Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Public Declare Function RegCreateKeyEx 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, ByVal lpSecurityAttributes As Long, phkResult As Long, lpdwDisposition As Long) As Long
Public Declare Function RegOpenKeyEx 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
Public Declare Function RegQueryValueExString Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByVal lpData As String, lpcbData As Long) As Long
Public Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Long, lpcbData As Long) As Long
Public Declare Function RegQueryValueExBool Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Boolean, lpcbData As Long) As Long
Public Declare Function RegQueryValueExNULL Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByVal lpData As Long, lpcbData As Long) As Long
Public Declare Function RegSetValueExString Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByVal lpValue As String, ByVal cbData As Long) As Long
Public Declare Function RegSetValueExLong Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpValue As Long, ByVal cbData As Long) As Long
Public Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
Public Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
Public Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, ByVal lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As FILETIME) As Long
Public Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData() As Byte, lpcbData As Long) As Long
Public Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias "RegQueryInfoKeyA" (ByVal hKey As Long, ByVal lpClass As String, lpcbClass As Long, lpReserved As Long, lpcSubKeys As Long, lpcbMaxSubKeyLen As Long, lpcbMaxClassLen As Long, lpcValues As Long, lpcbMaxValueNameLen As Long, lpcbMaxValueLen As Long, lpcbSecurityDescriptor As Long, lpftLastWriteTime As FILETIME) As Long


Public Function EnumKey(lPredefinedKey As Long, sKeyName As String, vSubKeys As Variant) As Long

' SubClaves es un variant que recogerá la matriz de subclaves obtenida
Dim lRetVal As Long 'resultado de las funciones del API
Dim hKey As Long 'handle de la clave abierta
Dim sSubKeyName As String 'nombre de la subclave
Dim lSubKeyLen As Long 'tamaño del nombre de la subclave
Dim lMaxSubKeyLen As Long 'tamaño del nombre de subclave más grande
Dim lNumSubKeys As Long 'número de subclaves existentes
Dim ftLastWriteTime As FILETIME 'fecha última modif. de la clave (sólo NT)
Dim lIndex As Long 'índice de la subclave
Dim sSubClaves() As String 'matriz para contener las subclaves
EnumKey = -1
'si tenemos nombre de clave la abrimos
If sKeyName <> "" Then
lRetVal = RegOpenKeyEx(lPredefinedKey, sKeyName, 0, KEY_ALL_ACCESS, hKey)
Else
hKey = lPredefinedKey
End If
'obtenemos el nº de subclaves y el tamaño máximo de sus nombres
'lResult = RegQueryInfoKey(lHandle, "", 0, 0, 0, 0, 0, lValues, lLenData, 0, 0, tFileTime) 'ESTA FUNCIÓN SIEMPRE ME DEVUELVE ERROR_INVALID_PARAMETERS = 87
lRetVal = RegQueryInfoKey(hKey, "", 0, 0, lNumSubKeys, lMaxSubKeyLen, 0&, 0&, 0&, 0&, 0&, ftLastWriteTime)
If lRetVal = 0 Then
'si no encontré subclaves
If lNumSubKeys = 0 Then
EnumKey = 0
Else
EnumKey = lNumSubKeys
lNumSubKeys = lNumSubKeys - 1 ' va de 0 a n-1
lMaxSubKeyLen = lMaxSubKeyLen + 1 ' dejar sitio para el 0 de fin de string en c
'dimensionamos la matriz
ReDim sSubClaves(lNumSubKeys)
'recorremos las subclaves (en orden inverso, como dice la ayuda ¿?)
For lIndex = lNumSubKeys To 0 Step -1
lSubKeyLen = lMaxSubKeyLen
sSubKeyName = String(lMaxSubKeyLen, 0)
lRetVal = RegEnumKeyEx(hKey, lIndex, sSubKeyName, lSubKeyLen, 0&, 0&, 0&, ftLastWriteTime)
If lRetVal = 0 Then
sSubClaves(lIndex) = Left$(sSubKeyName, lSubKeyLen)
Else
EnumKey = -1
End If
Next lIndex
End If
Else
EnumKey = -1
End If
'devolvemos el resultado
vSubKeys = sSubClaves()
'cerramos la clave
If sKeyName <> "" Then RegCloseKey (hKey)
End Function


También creo que toda la información de usuario se encuentra en modo binario y no tengo ni idea de como leerla...

En fin...que si me puedierais ayudar...