소스설명)
레지스트리에서 물리적인 메모리를 추출하는 소스


/////////////////////////////////////////////////////////////////////////
//
//  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");
}
2009/09/30 03:40 2009/09/30 03:40

Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다