//
// 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");
}