As shown by the LoggedOn console app, written in C and provided by SysInternals,
it's possible to connect to a remote machine's Registry, and enumerate the
HKey_Users entries to determine which subtree contains the information about the
current user account.
This code is part of the AppUser utility form which uses the machine
name from Jet's LDB file to do a remote lookup on the user id.
|
AppUser.zip (Access 2000,
67,445 bytes)
Please note that these are NT/2000 only API functions. |
Private Declare Function apiNetAPIBufferFree _
Lib "netapi32.dll" Alias "NetApiBufferFree" _
(ByVal buffer As Long) _
As Long
Private Declare Function apiFormatMsgLong _
Lib "kernel32" Alias "FormatMessageA" _
(ByVal dwFlags As Long, _
ByVal lpSource As Long, _
ByVal dwMessageId As Long, _
ByVal dwLanguageId As Long, _
ByVal lpBuffer As String, _
ByVal nSize As Long, _
Arguments As Long) _
As Long
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Type SID_IDENTIFIER_AUTHORITY
Value(5) As Byte
End Type
Private Declare Function apiRegConnectRegistry _
Lib "advapi32.dll" Alias "RegConnectRegistryA" _
(ByVal lpMachineName As String, _
ByVal hKey As Long, _
phkResult As Long) _
As Long
Private Declare Function apiRegEnumKeyEx _
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
Private Declare Function apiRegCloseKey _
Lib "advapi32.dll" Alias "RegCloseKey" _
(ByVal hKey As Long) _
As Long
Private Declare Function apiAllocateAndInitializeSid _
Lib "advapi32.dll" Alias "AllocateAndInitializeSid" _
(pIdentifierAuthority As SID_IDENTIFIER_AUTHORITY, _
ByVal nSubAuthorityCount As Byte, _
ByVal nSubAuthority0 As Long, _
ByVal nSubAuthority1 As Long, _
ByVal nSubAuthority2 As Long, _
ByVal nSubAuthority3 As Long, _
ByVal nSubAuthority4 As Long, _
ByVal nSubAuthority5 As Long, _
ByVal nSubAuthority6 As Long, _
ByVal nSubAuthority7 As Long, _
lpPSid As Any) _
As Long
Private Declare Function apiLookupAccountSid _
Lib "advapi32.dll" Alias "LookupAccountSidA" _
(ByVal lpSystemName As String, _
Sid As Any, _
ByVal name As String, _
cbName As Long, _
ByVal ReferencedDomainName As String, _
cbReferencedDomainName As Long, _
peUse As Integer) _
As Long
Private Declare Function apiIsValidSid _
Lib "advapi32.dll" Alias "IsValidSid" _
(pSid As Any) _
As Long
Private Declare Sub sapiFreeSid _
Lib "advapi32.dll" Alias "FreeSid" _
(pSid As Any)
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const ERROR_SUCCESS = 0&
Private Const HKEY_USERS = &H80000003
Private Const MAX_PATH = 260
Private Const ERROR_MORE_DATA = 234
Private Const MAX_NAME_STRING = 1024
Private Const SECURITY_NT_AUTHORITY = 5
Function fGetRemoteLoggedUserID(strMachineName As String) As String
Dim hRemoteUser As Long, j As Long
Dim lngRet As Long, i As Long, lngSubKeyNameSize As Long
Dim strSubKeyName As String
Dim alngSubAuthority() As Long, astrTmpSubAuthority() As String
Dim tFT As FILETIME, tAuthority As SID_IDENTIFIER_AUTHORITY
Dim pSid As Long, lngUserNameSize As Long, lngDomainNameSize As Long
Dim lngSubAuthorityCount As Long, intSidType As Integer
Dim strUserName As String, strDomainName As String
Dim adblTemp As Double
Const ERR_GENERIC = vbObjectError + 5555
Const KEY_TO_SKIP_1 = "classes"
Const KEY_TO_SKIP_2 = ".default"
On Error GoTo ErrHandler
lngRet = apiRegConnectRegistry(strMachineName, _
HKEY_USERS, hRemoteUser)
If lngRet <> ERROR_SUCCESS Then Err.Raise ERR_GENERIC
For i = 0 To 4
tAuthority.Value(i) = 0
Next
i = 0
lngSubKeyNameSize = MAX_PATH
strSubKeyName = String$(lngSubKeyNameSize, vbNullChar)
lngRet = apiRegEnumKeyEx(hRemoteUser, _
i, strSubKeyName, lngSubKeyNameSize, _
0, 0, 0, tFT)
Do While (lngRet = ERROR_SUCCESS Or lngRet = ERROR_MORE_DATA)
If (InStr(1, strSubKeyName, KEY_TO_SKIP_1, vbTextCompare) = 0 _
And InStr(1, strSubKeyName, _
KEY_TO_SKIP_2, vbTextCompare) = 0) Then
strSubKeyName = Left$(strSubKeyName, lngSubKeyNameSize)
astrTmpSubAuthority = Split(strSubKeyName, "-")
lngSubAuthorityCount = UBound(astrTmpSubAuthority)
ReDim alngSubAuthority(lngSubAuthorityCount)
For j = 3 To lngSubAuthorityCount
adblTemp = 0
adblTemp = CDbl(astrTmpSubAuthority(j))
If adblTemp > 2147483647 Then
adblTemp = adblTemp - 4294967296#
End If
alngSubAuthority(j - 3) = CLng(adblTemp)
Next
lngSubAuthorityCount = UBound(alngSubAuthority) - 2
If UBound(alngSubAuthority) < 7 Then ReDim Preserve alngSubAuthority(7)
With tAuthority
.Value(5) = SECURITY_NT_AUTHORITY
.Value(4) = 0
.Value(3) = 0
.Value(2) = 0
.Value(1) = 0
.Value(0) = 0
End With
If (apiAllocateAndInitializeSid(tAuthority, _
lngSubAuthorityCount, _
alngSubAuthority(0), _
alngSubAuthority(1), _
alngSubAuthority(2), _
alngSubAuthority(3), _
alngSubAuthority(4), _
alngSubAuthority(5), _
alngSubAuthority(6), _
alngSubAuthority(7), _
pSid)) Then
If (apiIsValidSid(ByVal pSid)) Then
lngUserNameSize = MAX_NAME_STRING
lngDomainNameSize = MAX_NAME_STRING
strUserName = String$(lngUserNameSize - 1, vbNullChar)
strDomainName = String$( _
lngDomainNameSize - 1, vbNullChar)
lngRet = apiLookupAccountSid(strMachineName, _
ByVal pSid, _
strUserName, _
lngUserNameSize, _
strDomainName, _
lngDomainNameSize, _
intSidType)
If (lngRet <> 0) Then
fGetRemoteLoggedUserID = fGetRemoteLoggedUserID & fTrimNull(strDomainName) _
& "\" & fTrimNull(strUserName) & vbCrLf
Else
With Err
.Raise .LastDllError, _
"fGetRemoteLoggedUserID", _
fAPIErr(.LastDllError)
End With
End If
End If
End If
If (pSid) Then Call sapiFreeSid(pSid)
End If
i = i + 1
lngSubKeyNameSize = MAX_PATH
strSubKeyName = String$(lngSubKeyNameSize, vbNullChar)
lngRet = apiRegEnumKeyEx(hRemoteUser, _
i, strSubKeyName, lngSubKeyNameSize, _
0, 0, 0, tFT)
Loop
ExitHere:
If (pSid) Then Call sapiFreeSid(pSid)
Call apiRegCloseKey(hRemoteUser)
Exit Function
ErrHandler:
With Err
If .Number <> ERR_GENERIC Then
MsgBox "Error: " & .Number & vbCrLf & .Description, _
vbCritical Or vbOKOnly, .Source
End If
End With
Resume ExitHere
End Function
Private Function fAPIErr(ByVal lngErr As Long) As String
Dim strMsg As String
Dim lngRet As Long
strMsg = String$(1024, 0)
lngRet = apiFormatMsgLong( _
FORMAT_MESSAGE_FROM_SYSTEM, 0&, _
lngErr, 0&, strMsg, Len(strMsg), ByVal 0&)
If lngRet Then
fAPIErr = Left$(strMsg, lngRet)
End If
End Function
Private Function fTrimNull(strIn As String) As String
Dim intPos As Integer
intPos = InStr(1, strIn, vbNullChar)
If intPos Then
fTrimNull = Mid$(strIn, 1, intPos - 1)
Else
fTrimNull = strIn
End If
End Function
' ******** Code End ********
|