Home > OS >  How to get the RAM name?
How to get the RAM name?

Time:03-13

I have a question about RAM information - How do you get its name?

So far, from Win32_PhysicalMemory and Win32_PhysicalMemoryArray classes I was able to get most of the info except the name (display name; eg. CRUCIAL BALLISTIX SPORT LT RED)

The platform I'm coding on is .NET WinForms - C#.

References I looked at

  • enter image description here

    If this occurs, one needs to refer to the enter image description here

    enter image description here

    How will this work? In C#, we can use & for logical AND operations. Likewise, | is used for logical OR operations.

    To put this into practice, let's start with a test hex value: 85.

    HEX: 85
    DEC: 133
    BIN: 1000 0101
    

    We need to determine what value we can use with a logical AND that will change the 8th bit to 0. The bit order is [8][7][6][5][4][3][2][1] (Little Endian)

    To Determine Endianness: (PowerShell)

    [System.BitConverter]::IsLittleEndian
    

    The following will change the parity bit to 0 when odd parity is used.

    GetValueWithoutParity:

    private uint GetValueWithoutParity(uint originalValue)
    {
        //values have odd parity
        //if number of 1's is odd, then eighth bit = 0
        //if number of 1's is even, then eighth bit = 1
    
        //we need to zero out the eighth bit in order to get the actual value
        //ie: in order to get the value of bits 0-7
    
        uint mask = 0x7F; //01111111
    
        //logical AND - search "Bitwise operators" for more info
        return originalValue & mask; 
    }
    

    If one has a value without parity, one can get the value after adding the parity bit by doing the following:

    GetValueWithParity:

    Note: The code for this method is from here.

    private uint GetValueWithParity(uint originalValue)
    {
        //values have odd parity
        //if number of 1's is odd, then eighth bit = 0
        //if number of 1's is even, then eighth bit = 1
    
        string binaryVal = Convert.ToString(originalValue, 2);
        byte[] numberAsByte = new byte[] { (byte)originalValue };
    
        //create new instance and set value
        BitArray bits = new BitArray(numberAsByte);
    
        int onesCount = 0;
        
        //count number of 1's
        for (int i = 0; i < 8; i  )
        {
            if (bits[i])
                onesCount  ; //increment
        }
    
        if (onesCount % 2 == 0)
        {
            //set the left most bit for odd parity
            bits[7] = true; 
        }
    
        //copy
        bits.CopyTo(numberAsByte, 0);
    
        return numberAsByte[0];
    }
    

    Now, we're able to decode the hex value into a value without parity. After removing the parity bit for 85, we've determined the value without parity is 5. As previously mentioned, the first hex value is the number of continuations, and the second hex value is the (1-based) entry/index number. (if there are 5 continuations, that means that the desired value is in the 6th bank/group).

    After decoding the second value, we find the (1-based) index/entry, is 27


    Before proceeding, let's create some classes to store our data in. I've decided that I'll store the data as JSON. You could use XML, if you like.

    Download/install NuGet package: Newtonsoft.Json

    • In VS menu, click View
    • Select Solution Explorer
    • In Solution Explorer, right-click your <project name>, select Manage NuGet Packages.... Click Browse. In search box, type Newtonsoft.Json. Click Install. If a prompt appears, click Yes.

    Create a class: (name: Manufacturer)

    public class Manufacturer
    {
        [JsonProperty(PropertyName = "groupNumber")]
        public int GroupNumber { get; set; }
    
        [JsonProperty(PropertyName = "names")]
        public List<String> Names { get; set; } = new List<String>();
    }
    

    Create a class: (name: RootObjectJson)

    public class RootObjectJson
    {
        [JsonProperty(PropertyName = "manufacturer")]
        public List<Manufacturer> Manufacturers { get; set; } = new List<Manufacturer>();
    }
    

    Add the following using statements to your classes:

    • using System;
    • using System.Collections.Generic;
    • using Newtonsoft.Json;

    ToDo: Load data into the classes. This repository may be useful.

    Note: When using the code below, it's necessary to align data so that the desired data starts at index 1. A simple way of doing this is to add filler data (data that won't be used) in index 0.

    Example:

    The following represents a data entry in index 0. This data won't be used, but is used to make it seem that our data is using a 1-based index.

    {
      "manufacturer": [
        {
          "groupNumber": 0,
          "names": [ "None" ]
        }
     ]
    }
    

    Then given a value (ex: 859B), one can do something similar to the following to retrieve the desired data.

    Note: If you don't want to use "filler data" (place unused data in index 0), change the indices in the method below.

    DecodeManufacturer:

    private void DecodeManufacturer(string manufacturerVal, RootObjectJson root)
    {
        uint groupNumber = 0;
        uint numberOfContinuations = 1;
        uint entryNumber = 1;
        if (!String.IsNullOrEmpty(manufacturerVal))
        {
            if (manufacturerVal.Length > 2)
            {
                uint currentVal = 0;
    
                //ToDo: ensure each hex value is 2 chars
                //if necessary, pad with a leading '0'
                for (int i = 0; i < manufacturerVal.Length; i =2)
                {
                    //Debug.WriteLine($"i = {i} manufacturerVal.Length: {manufacturerVal.Length}");
    
                    //get decimal value of hex value
                    string currentStr = manufacturerVal.Substring(i, 2);
                    string currentStrAsHex = String.Format("0x{0}", currentStr);
    
                    //convert to uint
                    currentVal = Convert.ToUInt32(currentStrAsHex, 16);
    
                    //Debug.WriteLine($"currentStrAsHex: {currentStrAsHex} currentVal: {currentVal}");
    
                    if (i == 0 && manufacturerVal.Length > 2 && manufacturerVal.Length <= 4)
                    {
                        
                        numberOfContinuations = GetValueWithoutParity(currentVal);
    
                        //set value
                        groupNumber = numberOfContinuations   1;
    
                        //Debug.WriteLine($"numberOfContinuations: {numberOfContinuations} groupNumber: {groupNumber}");
                    }
                    else if (i == 2 && manufacturerVal.Length > 2 && manufacturerVal.Length <= 4)
                    {
                        
                        entryNumber = GetValueWithoutParity(currentVal);
                        //Debug.WriteLine("entryNumber: "   entryNumber);
    
                        Debug.WriteLine($"numberOfContinuations: {numberOfContinuations} groupNumber: {groupNumber} entryNumber: {entryNumber}");
    
                        //need to convert to int to use as an index for the lists
                        int groupNumberInt = (int)groupNumber;
                        int entryNumberInt = (int)entryNumber;
    
                        if (groupNumberInt < root.Manufacturers.Count && entryNumber < root.Manufacturers[groupNumberInt].Names.Count)
                        {
                            Debug.WriteLine($"Manufacturer Name: '{root.Manufacturers[groupNumberInt].Names[entryNumberInt]}' Hex: {GetValueWithParity(entryNumber).ToString("X2")} Hex2: {GetValueWithParity2(entryNumber).ToString("X2")}");
                        }
                        else
                        {
                            Debug.WriteLine("Error: Invalid input.");
                        }
                    }
                }
            }
        }
    }
    

    Resources:

  • Related