Page 1 of 1 1
Topic Options
#134433 - 2005-02-24 04:52 AM Open request for Memory UDF improvements
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11634
Loc: Space
Based on some testing and code modifications I've taken the core code from Glenn's Memory() UDF which has also been modified with updates from myself and Al_Po and some from the discussion here: Detect amount of RAM / memory

Glenn's original Memory UDF
Memory() - Get Physical RAM size - local or remote

Here are the items looking to improve.

  • A.) Better method to correct UNC or confirmation code functions correctly as is
  • B.) Code must derive memory size from both local and remote registry read, not from COM methods
  • C.) Looking to reduce code size by better methodolgy if it exists, but not for the sheer sake of reducing to unreadable code like Golfing produces.
  • D.) Ensure that all possible errors are properly returned to the calling script
  • E.) A normal user should be able to run it during logon as well


i.e. If, as was said in the discussion in the other thread, there is un-needed bloat, can it be removed by using cleaner/smaller/tighter code not just character size reduction. As it is, Glenn's code appears to be about the only properly working code with various memory tests.

Lonkero's UDF MemSize() - returns installed memory size appears to work locally.


Function Memory(Optional $sComputer)

Dim $MemKey, $HexDmp, $Pointer, $Counter, $Start, $Hex, $HVal, $Hex2Dec
$MemKey = 'HKLM\Hardware\ResourceMap\System Resources\Physical Memory'
;Correct any UNC paths if supplied or missing
$MemKey = IIf((Not $sComputer), $MemKey,('\\'+Join(Split($sComputer,'\'),'',3)+'\'+$MemKey))
; Get the memory value from the registry
$HexDmp = ReadValue($MemKey, '.Translated')
; Check for invalid read and Return
If Not $HexDmp
$Memory = @ERROR Exit $Memory
EndIf
If Len($HexDmp) = 0
$Memory = 1 Exit $Memory
EndIf
; Prepare the array
Dim $HVals[((Len($HexDmp) / 32) - 2)]
$Pointer = 0
; Resequence the bytes in the HexDump, starting in the 65th position,
; and take 8 bytes every 32 bytes
For $Start = 65 To Len($HexDmp) Step 32
$Hex = ''
For $Counter = 6 To 0 Step -2
$Hex = $Hex + SubStr($HexDmp, $Start + $Counter, 2)
Next
; Load the hex value into the array and increment position
$HVals[$Pointer] = $Hex
$Pointer = $Pointer + 1
Next
; Now have an array of hex values representing installed physical RAM
For Each $HVal In $HVals
$Hex2Dec = 0.0
While $HVal
$Hex2Dec = 16.0 * $Hex2Dec + Execute('Exit &' + Left($HVal ,1))
$HVal = SubStr($HVal ,2)
Loop
$Memory = $Memory + CDbl($Hex2Dec) / 1024
Next
$Memory = Int(($Memory + 648) / 1024)
If ($Memory Mod 2)=1
$Memory = $Memory+1
EndIf
EndFunction



Edited by NTDOC (2005-02-24 06:12 AM)

Top
#134434 - 2005-02-24 04:57 AM Re: Open request for Memory UDF improvements
Sealeopard Offline
KiX Master
*****

Registered: 2001-04-25
Posts: 11165
Loc: Boston, MA, USA
I'd have the function return 0 in case of errors with appropriate error codes, otherwise you might have an error 512 and assume you got 512 MB of memory instead.
_________________________
There are two types of vessels, submarines and targets.

Top
#134435 - 2005-02-24 05:07 AM Re: Open request for Memory UDF improvements
Les Offline
KiX Master
*****

Registered: 2001-06-11
Posts: 12734
Loc: fortfrances.on.ca
How about a -1 return for errors?
_________________________
Give a man a fish and he will be back for more. Slap him with a fish and he will go away forever.

Top
#134436 - 2005-02-24 05:18 AM Re: Open request for Memory UDF improvements
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4403
Loc: New Jersey
My original code returned 0 on error, plus exited the error code. This is a mutation of my original UDF. Maybe you should post the original and work from there?

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#134437 - 2005-02-24 05:22 AM Re: Open request for Memory UDF improvements
Allen Administrator Offline
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4574
Loc: USA
Doc... looks like the postprep is still a little messed up:

Quote:


$Hex2Dec = 16.0 * $Hex2Dec + Execute('Exit &' + Left($HVal ,1))



_________________________
(... better days ahead)

Top
#134438 - 2005-02-24 06:41 AM Re: Open request for Memory UDF improvements
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11634
Loc: Space
Thanks Al... fixed the post.

Glenn's original code did this

Code:
; Check for invalid read and Return 

If Len($HexDmp) = 0 Or @ERROR
$Memory = 0
$Error = IIf(@ERROR, @ERROR, 87)
Exit $Error
EndIf



After further testing it does appear the original method Glenn used does seem to work.


Glenn is using for 0 length
87 The parameter is incorrect.

Maybe for a zero length use
24 The program issued a command but the command length is incorrect
Or
13 The data is invalid

Which number would everyone rather use?

I'm okay with putting back Glenn's original code for that too.

Overall though I think all of you are missing the bigger picture, yes I did ask about the error codes and I guess those are the easy target to pick out, but really looking for someone to maybe be able to provide a better coding solution overall or agree that at least for now no one can seem to find a better method so the error code changes are the only obvious things that can use some modifications.


Dim $Mem

$Mem=Memory()
If @ERROR
? 'Error: ' + @ERROR
Else
? 'Memory: ' + $Mem
EndIf
Color 'r/w'
? 'Press any key to continue...' ?
Get $Pause




Function Memory(Optional $sComputer)

Dim $MemKey, $HexDmp, $Pointer, $Counter, $Start, $Hex, $HVal, $Hex2Dec
$MemKey = 'HKLM\Hardware\ResourceMap\System Resources\Physical Memory'
$MemKey = IIf((Not $sComputer), $MemKey,('\\'+Join(Split($sComputer,'\'),'',3)+'\'+$MemKey))
$HexDmp = ReadValue($MemKey, '.Translated')
If Len($HexDmp) = 0 Or @ERROR
$Memory = 0
$Error = IIf(@ERROR, @ERROR, 87)
Exit $Error
EndIf
Dim $HVals[((Len($HexDmp) / 32) - 2)]
$Pointer = 0
For $Start = 65 To Len($HexDmp) Step 32
$Hex = ''
For $Counter = 6 To 0 Step -2
$Hex = $Hex + SubStr($HexDmp, $Start + $Counter, 2)
Next
$HVals[$Pointer] = $Hex
$Pointer = $Pointer + 1
Next
For Each $HVal In $HVals
$Hex2Dec = 0.0
While $HVal
$Hex2Dec = 16.0 * $Hex2Dec + Execute('Exit &' + Left($HVal ,1))
$HVal = SubStr($HVal ,2)
Loop
$Memory = $Memory + CDbl($Hex2Dec) / 1024
Next
$Memory = Int(($Memory + 648) / 1024)
If ($Memory Mod 2)=1
$Memory = $Memory+1
EndIf
EndFunction



Edited by NTDOC (2005-02-24 09:05 AM)

Top
#134439 - 2005-02-24 09:56 AM Re: Open request for Memory UDF improvements
ShaneEP Moderator Offline
MM club member
*****

Registered: 2002-11-29
Posts: 2127
Loc: Tulsa, OK
About the only help i can offer right now, is confirming that it does not work on Win9x systems And since thats the only OS I currently have access to, im not so much help besides that, sorry Doc.
Top
#134440 - 2005-02-24 06:51 PM Re: Open request for Memory UDF improvements
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4403
Loc: New Jersey
Here's the latest UDF that I use. It's trimmed down a bit from the original, but still examines all of the appropriate bytes in the .Translated key, and uses a modified Hex conversion routine. Using Val('&' + $hex) can return negatives, probably due to a limitation of the Val() function.

[Glenn, I updated your post because your function name was missing, also updated some missing entries for the UDF header NTDOC]

;;FUNCTION		Memory() 

;;
;;AUTHOR Glenn Barnas / FRIT-EROC
;;
;;ACTION Returns the amount of Physical RAM in a local or remote 32GB system
;;
;;SYNTAX Memory([system])
;;
;;VERSION 1.0
;;
;;DATE 2005/02/25
;;
;;DATE REVISED
;;
;;PARAMETERS System - OPTIONAL - name of system to query. Default is local system
;;
;;REMARKS Returns RAM size using registry value
;; Returns @ERROR on registry read failure, or 13/"Data is Invalid" if null
;;
;;RETURNS Installed Physical RAM (in Megabytes)
;;
;;DEPENDENCIES None
;;
;;TESTED WITH WinNT, Win2K, WinXP, Win2K3
;; Tested with up to 6G of RAM
;;
;;EXAMPLES $RAM = Memory('ThatPC')
;;

Function Memory(Optional $System)

dim $, $MemKey, $HexDmp, $Pointer, $Counter, $Start, $Hex, $HVal, $Error, $Hex2Dec
$Memory = 0.0

; Insure $System has "\\System\" format if it is specified
If $System <> ''
$System = '\\' + Join(Split($System, '\'), '', 3) + '\'
EndIf

; Get the memory value from the registry
$MemKey = $System + 'HKEY_LOCAL_MACHINE\hardware\resourcemap\system resources\physical memory'
$HexDmp = ReadValue($MemKey, '.Translated')

; Check for invalid read and Return
If Len($HexDmp) = 0 Or @ERROR
$Memory = 0 ; return 0 Mbytes
$Error = IIf(@ERROR, @ERROR, 13) ; Return "Data is Invalid" if no error but data is blank
Exit $Error
EndIf

; Resequence the bytes in the HexDump, starting in the 65th position,
; and take 8 bytes every 32 bytes for the total memory amount, sum the values
For $Start = 65 to Len($HexDmp) step 32
$Hex = SubStr($HexDmp, $Start+6, 2)
+ SubStr($HexDmp, $Start+4, 2)
+ SubStr($HexDmp, $Start+2, 2)
+ SubStr($HexDmp, $Start, 2)
$Hex2Dec = 0.0
; Simply taking the Val($Hex) can return negatives for values
While $Hex
$Hex2Dec = 16.0 * $Hex2Dec + Val('&' + Left($Hex,1))
$Hex = SubStr($Hex ,2)
Loop
$Memory = $Memory + CDbl($Hex2Dec) / 1024
Next

; Reduce to meg value, add the lowest 640K that isn't referenced in the HexDump
$Memory = CInt(($Memory + 648) / 1024)

EndFunction


The section:
; Simply taking the Val($Hex) can return negatives for values
While $Hex
$Hex2Dec = 16.0 * $Hex2Dec + Val('&' + Left($Hex,1))
$Hex = SubStr($Hex ,2)
Loop
$Memory = $Memory + CDbl($Hex2Dec) / 1024

Could be replaced with:
$Memory = $Memory + CDbl(Val('&'+$Hex)) / 1024

If the "Val('&'+$Hex)" didn't return negative numbers for certain values (above 2M)


Edited by NTDOC (2005-02-24 08:35 PM)
_________________________
Actually I am a Rocket Scientist! \:D

Top
#134441 - 2005-02-24 08:55 PM Re: Open request for Memory UDF improvements
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11634
Loc: Space
Looks good Glenn. I notice you do much more stepping in this version, but is still accurate.

Just tested 53 systems, some from other cities across T1 and completed results in under 5 seconds.

1536
2048
384
1024
3712
1024
2040
1024
1024
1024
1024
1024
2048
2304
2048
3680
2048
1024
1536
3072
1664
1024
2048
2048
2048
2048
2048
1536
2304
2048
512
3072
3072
2048
2048
1024
1024
1024
1024
1152
3808
2048
2048
2048
2048
1024
2048
2048
2304
2304
2304
256
2048
2048
1024
256
512

Top
#134442 - 2005-02-24 09:29 PM Re: Open request for Memory UDF improvements
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4403
Loc: New Jersey
Thanks for the tests. What do you mean "more stepping"?

The key changes from the original post are:

  • Streamlined system name processing
  • Replaced Counter loop with 4 SubStr commands
  • Integrated the Hex conversion, eliminating the need for the array and the second loop
  • Used CInt() instead of Int() to eliminate the If $Memory Mod 2 test.

This was tested with systems with 512M, 1G, 2G, 4G, and 5.5G - I can test it with some smaller memory model systems at home, where one system has 192M.
_________________________
Actually I am a Rocket Scientist! \:D

Top
Page 1 of 1 1


Moderator:  Arend_, Allen, Jochen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 1114 anonymous users online.
Newest Members
Viginette, ManuvdWielNL, Sir_Barrington, batdk82, StuTheCoder
17888 Registered Users

Generated in 0.063 seconds in which 0.025 seconds were spent on a total of 12 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org