How to check remote physical memory without a remote client 
Author Message
 How to check remote physical memory without a remote client

Hack solution, if somebody wants to clean it up, please do!  Previously,
there have been questions on how to check the remote physical memory with
only API calls.  Well, after a frustrating day, I got it to work (I use it
for a hardware monitoring program).  Here's the overview:

In the registry under HKLM\Hardware\ResourceMap\System Resources\Physical
Memory there is a value called .Translated.  The data type for this is this
is a Resource List, but is read just like a binary value (an array of byte).
This data seems to be either 68 or 84 bytes long (at least at my company),
which I think corresponds to three or four physical RAM slots (in machines
with five slots, the data is 68 bytes long, so who knows?)

Anyways, once you have gathered this remote value, you take the last four
bytes of this array and reverse their order.  Having reversed their order,
you now have the data needed to construct a 32 bit decimal number.

To do this (if the data length is 68 bytes)
Multiply byte 67 by 16777216 (which is 256^3)
Multiple byte 66 by 65536 (which is 256^2)
Multiple byte 65 by 256
Add the result of those three with byte 64, add 16371712, and divide the
result by 1048576 to get a MB sized result

To use the 84 byte length, see the module below.

How do you access the remote registry?  I used this module (it's everywhere
on the net), you'll see where the code gets sloppy, that's where I was
hacking.  I had some big problems with data types, which is why the code
looks extra bad, but I had a deadline!

Thoughts?  Comments?  Easier way?  Better math?  Problems?

----------------------------------------------------------------------------
------------------------------------------
'This bas module is based mainly on the code found in KB Article Q172274
'Titled: INFO: Using the Registry API to Save and Retrieve Settings
'This demo does not use all of the functions included in the module,
'but could easily be expanded to use them.

Global Const REG_SZ As Long = 1
Global Const REG_DWORD As Long = 4
Global Const REG_BINARY As Long = 3
Global Const REG_RESOURCE_LIST = 8

Global Const HKEY_CLASSES_ROOT = &H80000000
Global Const HKEY_CURRENT_USER = &H80000001
Global Const HKEY_LOCAL_MACHINE = &H80000002
Global Const HKEY_USERS = &H80000003

Global Const ERROR_NONE = 0
Global Const ERROR_BADDB = 1
Global Const ERROR_BADKEY = 2
Global Const ERROR_CANTOPEN = 3
Global Const ERROR_CANTREAD = 4
Global Const ERROR_CANTWRITE = 5
Global Const ERROR_OUTOFMEMORY = 6
Global Const ERROR_INVALID_PARAMETER = 7
Global Const ERROR_ACCESS_DENIED = 8
Global Const ERROR_INVALID_PARAMETERS = 87
Global Const ERROR_NO_MORE_ITEMS = 259

Global Const KEY_ALL_ACCESS = &H3F

Global Const REG_OPTION_NON_VOLATILE = 0

Declare Function RegConnectRegistry Lib "advapi32.dll" Alias _
"RegConnectRegistryA" (ByVal lpMachineName As String, ByVal hKey As Long, _
phkResult As Long) As Long

Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long

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

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

Declare Function RegQueryValueExBinary Lib "advapi32.dll" Alias
"RegQueryValueExA" (ByVal lngHKey As Long, ByVal lpValueName As String,
ByVal lpReserved As Long, lpType As Long, ByVal lpData As Long, lpcbData As
Long) As Long

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

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

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

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

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 Function SetValueEx(ByVal hKey As Long, sValueName As String, _
                             lType As Long, vValue As Variant) As Long
    Dim lValue As Long
    Dim sValue As String
    Select Case lType

        Case REG_SZ
            sValue = vValue & Chr$(0)
            SetValueEx = RegSetValueExString(hKey, sValueName, 0&, _
                                             lType, sValue, Len(sValue))
        Case REG_DWORD
            lValue = vValue
            SetValueEx = RegSetValueExLong(hKey, sValueName, 0&, _
                         lType, lValue, 4)
        End Select
End Function

Function QueryValueEx(ByVal lhkey As Long, ByVal szValueName As String, _
                      vValue As Variant) As Long
    Dim a1, a2, a3, a4 As Integer

    Dim b As Long

    Dim cch As Long
    Dim lrc As Long
    Dim lType As Long
    Dim lValue As Long
    Dim sValue As String
    Dim abytValueData() As Byte

    On Error GoTo QueryValueExError

    ' Determine the size and type of data to be read
    lrc = RegQueryValueExNULL(lhkey, szValueName, 0&, lType, 0&, cch)
    If lrc <> ERROR_NONE Then Error 5

    Select Case lType
        ' For strings
        Case REG_SZ:
            sValue = String(cch, 0)
            lrc = RegQueryValueExString(lhkey, szValueName, 0&, lType,
sValue, cch)
            If lrc = ERROR_NONE Then
                vValue = Left$(sValue, cch)
            Else
                vValue = Empty
            End If
        ' For DWORDS
        Case REG_DWORD:
            lrc = RegQueryValueExLong(lhkey, szValueName, 0&, lType, lValue,
cch)
            If lrc = ERROR_NONE Then vValue = lValue

        Case REG_RESOURCE_LIST:
            ReDim abytValueData(cch - 1) As Byte
            lrc = RegQueryValueExBinary(lhkey, szValueName, 0&, lType,
VarPtr(abytValueData(0)), cch)

            If cch = 68 Then 'means there are three RAM slots?
            a1 = Int(abytValueData(67)) '* 16777216
            a2 = Int(abytValueData(66)) '* 65536
            a3 = Int(abytValueData(65)) '* 256
            a4 = Int(abytValueData(64))
            b = Round(((a1 * 16777216) + (a2 * 65536) + (a3 * 256) + a4 +
16371712) / 1048576)
            vValue = b
            End If

            If cch = 84 Then 'means there are four RAM slots?
            a1 = Int(abytValueData(83)) '* 16777216
            a2 = Int(abytValueData(82)) '* 65536
            a3 = Int(abytValueData(81)) '* 256
            a4 = Int(abytValueData(80))
            b = Round(((a1 * 16777216) + (a2 * 65536) + (a3 * 256) + a4 +
16363520) / 1048576)
            vValue = b
            End If

        Case REG_BINARY:
            If cch > 0 Then
            ReDim abytValueData(cch - 1) As Byte
            lrc = RegQueryValueExBinary(lhkey, szValueName, 0&, lType,
VarPtr(abytValueData(0)), cch)
            End If
            If lrc = ERROR_NONE Then vValue = abytValueData

            Case Else
            'all other data types not supported
            lrc = -1
    End Select

QueryValueExExit:
    QueryValueEx = lrc
    Exit Function
QueryValueExError:
    Resume QueryValueExExit

End Function



Sun, 23 May 2004 08:57:20 GMT  
 How to check remote physical memory without a remote client
I have had no luck getting this code to work.  I have been
writing an application that can read registry keys from
any machine on the network.  When I try to pull this value
and convert it to Physical Memory I only get the value of
16.  Which tells me that the array is not being populated
at all.  When at look at this statement
Redim(aByteValueData(KeyValSize - 1)) As Byte
The KeyValSize is showing a value of 84, but the array
keeps showing subscript out of range.  What am I doing
wrong?  I'm new to API programming and not very versed by
any means in byte arrays.  Please help.

Thanks,

Steve

Quote:
>-----Original Message-----
>Hack solution, if somebody wants to clean it up, please
do!  Previously,
>there have been questions on how to check the remote

physical memory with
Quote:
>only API calls.  Well, after a frustrating day, I got it
to work (I use it
>for a hardware monitoring program).  Here's the overview:

>In the registry under HKLM\Hardware\ResourceMap\System
Resources\Physical
>Memory there is a value called .Translated.  The data

type for this is this
Quote:
>is a Resource List, but is read just like a binary value
(an array of byte).
>This data seems to be either 68 or 84 bytes long (at

least at my company),
Quote:
>which I think corresponds to three or four physical RAM
slots (in machines
>with five slots, the data is 68 bytes long, so who knows?)

>Anyways, once you have gathered this remote value, you
take the last four
>bytes of this array and reverse their order.  Having

reversed their order,
Quote:
>you now have the data needed to construct a 32 bit
decimal number.

>To do this (if the data length is 68 bytes)
>Multiply byte 67 by 16777216 (which is 256^3)
>Multiple byte 66 by 65536 (which is 256^2)
>Multiple byte 65 by 256
>Add the result of those three with byte 64, add 16371712,
and divide the
>result by 1048576 to get a MB sized result

>To use the 84 byte length, see the module below.

>How do you access the remote registry?  I used this

module (it's everywhere
Quote:
>on the net), you'll see where the code gets sloppy,
that's where I was
>hacking.  I had some big problems with data types, which
is why the code
>looks extra bad, but I had a deadline!

>Thoughts?  Comments?  Easier way?  Better math?  Problems?

>----------------------------------------------------------
------------------
>------------------------------------------
>'This bas module is based mainly on the code found in KB
Article Q172274
>'Titled: INFO: Using the Registry API to Save and
Retrieve Settings
>'This demo does not use all of the functions included in
the module,
>'but could easily be expanded to use them.

>Global Const REG_SZ As Long = 1
>Global Const REG_DWORD As Long = 4
>Global Const REG_BINARY As Long = 3
>Global Const REG_RESOURCE_LIST = 8

>Global Const HKEY_CLASSES_ROOT = &H80000000
>Global Const HKEY_CURRENT_USER = &H80000001
>Global Const HKEY_LOCAL_MACHINE = &H80000002
>Global Const HKEY_USERS = &H80000003

>Global Const ERROR_NONE = 0
>Global Const ERROR_BADDB = 1
>Global Const ERROR_BADKEY = 2
>Global Const ERROR_CANTOPEN = 3
>Global Const ERROR_CANTREAD = 4
>Global Const ERROR_CANTWRITE = 5
>Global Const ERROR_OUTOFMEMORY = 6
>Global Const ERROR_INVALID_PARAMETER = 7
>Global Const ERROR_ACCESS_DENIED = 8
>Global Const ERROR_INVALID_PARAMETERS = 87
>Global Const ERROR_NO_MORE_ITEMS = 259

>Global Const KEY_ALL_ACCESS = &H3F

>Global Const REG_OPTION_NON_VOLATILE = 0

>Declare Function RegConnectRegistry Lib "advapi32.dll"
Alias _
>"RegConnectRegistryA" (ByVal lpMachineName As String,

ByVal hKey As Long, _
Quote:
>phkResult As Long) As Long

>Declare Function RegCloseKey Lib "advapi32.dll" _
>(ByVal hKey As Long) As Long

>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 _
Quote:
>As Long, phkResult As Long, lpdwDisposition As Long) As
Long

>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

>Declare Function RegQueryValueExBinary Lib "advapi32.dll"
Alias
>"RegQueryValueExA" (ByVal lngHKey As Long, ByVal

lpValueName As String,

- Show quoted text -

Quote:
>ByVal lpReserved As Long, lpType As Long, ByVal lpData As
Long, lpcbData As
>Long) As Long

>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

>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

>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

>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

>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 Function SetValueEx(ByVal hKey As Long,

sValueName As String, _
Quote:
>                             lType As Long, vValue As
Variant) As Long
>    Dim lValue As Long
>    Dim sValue As String
>    Select Case lType

>        Case REG_SZ
>            sValue = vValue & Chr$(0)
>            SetValueEx = RegSetValueExString(hKey,
sValueName, 0&, _
>                                             lType,

sValue, Len(sValue))
Quote:
>        Case REG_DWORD
>            lValue = vValue
>            SetValueEx = RegSetValueExLong(hKey,
sValueName, 0&, _
>                         lType, lValue, 4)
>        End Select
>End Function

>Function QueryValueEx(ByVal lhkey As Long, ByVal

szValueName As String, _

- Show quoted text -

Quote:
>                      vValue As Variant) As Long
>    Dim a1, a2, a3, a4 As Integer

>    Dim b As Long

>    Dim cch As Long
>    Dim lrc As Long
>    Dim lType As Long
>    Dim lValue As Long
>    Dim sValue As String
>    Dim abytValueData() As Byte

>    On Error GoTo QueryValueExError

>    ' Determine the size and type of data to be read
>    lrc = RegQueryValueExNULL(lhkey, szValueName, 0&,
lType, 0&, cch)
>    If lrc <> ERROR_NONE Then Error 5

>    Select Case lType
>        ' For strings
>        Case REG_SZ:
>            sValue = String(cch, 0)
>            lrc = RegQueryValueExString(lhkey,

szValueName, 0&, lType,

- Show quoted text -

Quote:
>sValue, cch)
>            If lrc = ERROR_NONE Then
>                vValue = Left$(sValue, cch)
>            Else
>                vValue = Empty
>            End If
>        ' For DWORDS
>        Case REG_DWORD:
>            lrc = RegQueryValueExLong(lhkey, szValueName,
0&, lType, lValue,
>cch)
>            If lrc = ERROR_NONE Then vValue = lValue

>        Case REG_RESOURCE_LIST:
>            ReDim abytValueData(cch - 1) As Byte
>            lrc = RegQueryValueExBinary(lhkey,

szValueName, 0&, lType,

- Show quoted text -

Quote:
>VarPtr(abytValueData(0)), cch)

>            If cch = 68 Then 'means there are three RAM
slots?
>            a1 = Int(abytValueData(67)) '* 16777216
>            a2 = Int(abytValueData(66)) '* 65536
>            a3 = Int(abytValueData(65)) '* 256
>            a4 = Int(abytValueData(64))
>            b = Round(((a1 * 16777216) + (a2 * 65536) +
(a3 * 256) + a4 +
>16371712) / 1048576)
>            vValue = b
>            End If

>            If cch = 84 Then 'means there are four RAM
slots?
>            a1 = Int(abytValueData(83)) '* 16777216
>            a2 = Int(abytValueData(82)) '* 65536
>            a3 = Int(abytValueData(81)) '* 256
>            a4 = Int(abytValueData(80))
>            b = Round(((a1 * 16777216) + (a2 * 65536) +
(a3 * 256) + a4 +
>16363520) / 1048576)
>            vValue = b
>            End If

>        Case REG_BINARY:
>            If cch > 0 Then
>            ReDim abytValueData(cch - 1) As Byte
>            lrc = RegQueryValueExBinary(lhkey,

szValueName, 0&, lType,

- Show quoted text -

Quote:
>VarPtr(abytValueData(0)), cch)
>            End If
>            If lrc = ERROR_NONE Then vValue =
abytValueData

>            Case Else
>            'all other data types not supported
>            lrc = -1
>    End Select

>QueryValueExExit:
>    QueryValueEx = lrc
>    Exit Function
>QueryValueExError:
>    Resume QueryValueExExit

>End Function

>.



Wed, 26 May 2004 03:22:48 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Need to Determine the Total Physical Memory of a Remote Computer

2. Get the physical memory installed on a remote computer

3. Check remote computer's memory resource

4. returning full physical path name of a remote UNC share

5. Extract info about Total Physical Memory WITHOUT WMI????

6. accessing remote resources on a remote computer

7. remote Authentication for running a remote wsh script

8. passsing argument to a remote script - with remote WSH

9. 'Remote Scripting Error: Page invoked does not support remote scripting

10. How to verify if remote machine exists, and remote admin enabled

11. How to verify if remote machine exists, and remote admin enabled

12. How to verify remote machine exists, and remote admin enabled

 

 
Powered by phpBB® Forum Software