Read physical memory information from registry

/
//
//  Module:
//    Read physical memory information from registry
//    HKLM/HARDWARE/RESOURCEMAP/System Resources/Physical Memory
//
//  Author:
//    CDrea (CDrea_at_SafeChina[dot]ORG
//
//  Version:
//    2007-12-24  v0.1
//
/

#include <windows.h>
#include <stdio.h>

struct _mi {
    LARGE_INTEGER    Address;
    DWORD            Length;
    DWORD            Reserved;
};

#define MI_LEN    sizeof(struct _mi)

typedef struct _phy_mem_info {
    DWORD        BusCount;
    DWORD        MemoryRangeCount;
    struct _mi*    MemInfoPtr;
}PHY_MEM_INFO;

BOOL
GetPhyMemoryInfo(
    OUT PHY_MEM_INFO* PhyMemInfo
    );

void logo();

int main()
{
    PHY_MEM_INFO    PhyMemInfo  = {0};
    LARGE_INTEGER    TotalSize = {0};

    logo();

    if(!GetPhyMemoryInfo(&PhyMemInfo)) return -1;

    for(DWORD i = 0; i < PhyMemInfo.MemoryRangeCount; i++)
    {
        TotalSize.QuadPart += (PhyMemInfo.MemInfoPtr + i)->Length;
    }

    printf("Total memory: %d MB/n", TotalSize.QuadPart / 1024 / 1024);
    printf("Bus count: %d/n", PhyMemInfo.BusCount);
    printf("Memory ranges:/n");
    for(DWORD i = 0; i < PhyMemInfo.MemoryRangeCount; i++)
    {
        printf("  0x%-016I64X  Length: 0x%X (%dK)/n",
            (PhyMemInfo.MemInfoPtr + i)->Address.QuadPart,
            (PhyMemInfo.MemInfoPtr + i)->Length,
            (PhyMemInfo.MemInfoPtr + i)->Length / 1024);
    }

    if(PhyMemInfo.MemInfoPtr != NULL)
        free(PhyMemInfo.MemInfoPtr);
    return 0;
}

BOOL
GetPhyMemoryInfo(
    OUT PHY_MEM_INFO* PhyMemInfo
)
{
    HKEY hKey;
    int nRet = 0;

    nRet = RegOpenKey(HKEY_LOCAL_MACHINE, "Hardware//ResourceMap//System Resources//Physical Memory", &hKey);
    if(nRet != ERROR_SUCCESS)
    {
        fprintf(stderr, "RegOpenKey() failed. --err: %d/n", GetLastError());
        return FALSE;
    }

    DWORD Type = 0;
    DWORD cbData = 0;
    LPBYTE lpData = NULL;
    LPBYTE pmrc = NULL;

    RegQueryValueEx(hKey, ".Translated", 0, &Type, NULL, &cbData);
    lpData = (LPBYTE)malloc(cbData);
    RegQueryValueEx(hKey, ".Translated", 0, &Type, lpData, &cbData);
    if(nRet != ERROR_SUCCESS)
    {
        fprintf(stderr, "RegQueryValueEx() failed. --err: %d/n", GetLastError());
        return FALSE;
    }

    DWORD BusCount = *(DWORD*)lpData;
    if(BusCount <= 0)
    {
        fprintf(stderr, "Cannot get valid memory information./n");
        return FALSE;
    }

    LPBYTE p = lpData + 0x10;
    DWORD MemoryRangesCount = 0;
    for(DWORD i = 1; i <= BusCount; i++)
    {
        MemoryRangesCount += *(DWORD*)p;
        p = p + 0x8 + i * (*(DWORD*)p) * 0x10;
    }
    p = lpData + 0x10;

    PhyMemInfo->MemInfoPtr = (struct _mi*)malloc(MI_LEN * MemoryRangesCount);
    if(PhyMemInfo->MemInfoPtr == NULL)
    {
        fprintf(stderr, "Not enough memory./n");
        return FALSE;
    }

    LPBYTE pmi = NULL;
    struct _mi* ptr = PhyMemInfo->MemInfoPtr;
    for(DWORD i = 1; i <= BusCount; i++)
    {
        pmi = p + 0x8;
        for(DWORD j = 0; j < *(DWORD*)p; j++)
        {
            ptr->Address.LowPart = *(DWORD*)pmi;
            ptr->Address.HighPart = *(long*)(pmi + 0x4);
            ptr->Length  = *(DWORD*)(pmi + 0x8);
            ptr++;
            pmi += MI_LEN;
        }

        p = p + 0x8 + i * (*(DWORD*)p) * 0x10;
    }

    PhyMemInfo->BusCount = BusCount;
    PhyMemInfo->MemoryRangeCount = MemoryRangesCount;

    RegCloseKey(hKey);
    free(lpData);
    return TRUE;
}

void logo()
{
    printf("+------------------------------------+/n");
    printf("|  Physical Memory Information v0.1  |/n");
    printf("|  Write by CDrea                    |/n");
    printf("|  CDrea_at_SafeChina[dot]ORG        |/n");
    printf("|  2007-12-24                        |/n");
    printf("|  http://www.safechina.org          |/n");
    printf("+------------------------------------+/n/n");
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值