#134433 - 2005-02-24 04:52 AM
Open request for Memory UDF improvements
|
NTDOC
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
|
|
|
|
#134438 - 2005-02-24 06:41 AM
Re: Open request for Memory UDF improvements
|
NTDOC
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
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
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!
|
|
Top
|
|
|
|
Moderator: Arend_, Allen, Jochen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 871 anonymous users online.
|
|
|