2010년 1월 20일 수요일

시스템사양 하드웨어 정보 알아내기

현재 시스템에 부착되어 있는 메인 메모리의 양과 CPU와 운영체제의 종류를 알고 싶습니다.
먼저 시스템에 부착되어 있는 메인 메모리의 크기는 GlobalMemoryStatus라는
API를 이용하면 됩니다. 예제 코드는 다음과 같습니다.
//===========================================================
// lMemTotal      : 실제 메모리의 전체 크기 (KB 단위)
// lAvailMemTotal : 사용 가능한 실제 메모리의 크기 (KB 단위)
// lVirtualTotal  : 가상 메모리의 전체 크기  (KB 단위)
//===========================================================
void GetMemoryStatus(long *lMemTotal, long *lAvailMemTotal, long *lVirtualTotal)
{
    double var;
    MEMORYSTATUS memoryStatus;
    memset (&memoryStatus, sizeof (MEMORYSTATUS), 0);
    memoryStatus.dwLength = sizeof (MEMORYSTATUS);
    GlobalMemoryStatus (&memoryStatus);
    lMemTotal = memoryStatus.dwTotalPhys / 1024;
    lAvailMemTotal = memoryStatus.dwAvailPhys / 1024;
    lVirtualTotal = memoryStatus.dwTotalVirtual / 1024;
}
다음으로 CPU의 종류를 알아내는 코드는 다음과 같습니다.
//===============================================================
// GetProcessorInfo : 프로세서에 대한 정보를 읽어온다.
// lpCPUSpeed      : CPU의 속도. 기록된 시스템에서만 읽어온다.
// lpProcessorType : 프로세서의 종류
// lpNumProcessors : 프로세서의 개수. NT의 경우에만 의미가 있다.
//===============================================================
void GetProcessorInfo(LPSTR lpCPUSpeed, LPSTR lpProcessorType, LPSTR lpNumProcessors)
{
    SYSTEM_INFO sysInfo;
    LONG result;
    HKEY hKey;
    DWORD data;
    DWORD dataSize;
    lpCPUSpeed[0] = 0;
    // ---------------------------------------------
    // 프로세서의 속도를 얻어낸다.
    // ---------------------------------------------
    result = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE,"HardwareDescriptionSystemCentralProcessor", 0, KEY_QUERY_VALUE, &hKey);
    if (result == ERROR_SUCCESS)
    {
        result = ::RegQueryValueEx (hKey, "~MHz", NULL, NULL,(LPBYTE)&data, &dataSize);
 wsprintf(lpCPUSpeed, "%d MHz", data);
    }
    RegCloseKey (hKey);
    // ------------------------------------------
    // 하드웨어 정보를 얻어낸다.
    // ------------------------------------------
    GetSystemInfo (&sysInfo);
    // 프로세서 타입부터 검사한다.
    if (sysInfo.dwProcessorType  == PROCESSOR_INTEL_386)
        strcpy(lpProcessorType,  "Intel 386");
    else if (sysInfo.dwProcessorType  == PROCESSOR_INTEL_486)
             strcpy(lpProcessorType,  "Intel 486");
      else if (sysInfo.dwProcessorType  == PROCESSOR_INTEL_PENTIUM)
      {
          if (sysInfo.wProcessorLevel == 6)
       strcpy(lpProcessorType, "Intel Pentium (II/Pro)");
       else strcpy(lpProcessorType,  "Intel Pentium");
      }else strcpy(lpProcessorType, "알 수 없는 시스템");
      // 프로세서의 갯수를 검사한다.
      wsprintf(lpNumProcessors, "%d", sysInfo.dwNumberOfProcessors);
}다음으로 현재 사용 중인 운영체제의 종류를 알아내는 코드는 다음과 같습니다.
//===============================================================
// GetOSVersion : OS의 버전을 얻어온다.
// --------------------------------------------------------------
// lpstInfo
// lpstBuildNumber
// lpstServicePack
//===============================================================
void GetOSVersion (LPSTR lpstInfo, LPSTR lpstBuildNumber, LPSTR lpstServicePack)
{
    int stat = 0;
    TCHAR data [64];
    DWORD dataSize;
    DWORD win95Info;
    OSVERSIONINFO versionInfo;
    HKEY hKey;
    LONG result;
    lpstServicePack[0] = 0;
    versionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
    // 버전 정보를 얻어낸다.
    if (!::GetVersionEx (&versionInfo))
    {
        strcpy(lpstInfo, "운영체제 정보를 얻을 수 없습니다.");
 return;
    }
    // NT이면 서버인지 웍스테이션인지 검사한다. 이는 레지스트리를 보고 검사한다.
    if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
    {
        strcpy(lpstInfo, "Windows NT");
 dataSize = sizeof (data);
 result = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE,"SystemCurrentControlSetControlProductOptions", 0, KEY_QUERY_VALUE, &hKey);
 if (result != ERROR_SUCCESS)
     return;
 result = ::RegQueryValueEx (hKey, "ProductType", NULL, NULL, (LPBYTE) data, &dataSize);
 RegCloseKey (hKey);
 if (result != ERROR_SUCCESS)
     return;
 if (lstrcmpi (data, "WinNT") == 0)
     strcpy(lpstInfo, "Windows NT Workstation");
 else if (lstrcmpi (data, "ServerNT") == 0)
          strcpy(lpstInfo, "Windows NT Server");
   else strcpy(lpstInfo, "Windows NT Server - Domain Controller");
   // NT 버전을 알아낸다.
 if (versionInfo.dwMajorVersion == 3 || versionInfo.dwMinorVersion == 51)
     strcat(lpstInfo, " 3.51");
 else if (versionInfo.dwMajorVersion == 5)
 // 윈도우 2000의 경우
          strcat(lpstInfo, " 5.0");
 else strcat(lpstInfo, " 4.0");
 // Build 번호를 알아낸다.
 wsprintf(lpstBuildNumber, "%d", versionInfo.dwBuildNumber);
    }
    else if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
    {
        strcpy(lpstInfo, "Windows 95");
 if ((versionInfo.dwMajorVersion > 4) || ((versionInfo.dwMajorVersion == 4)&& (versionInfo.dwMinorVersion > 0)))
 {
     strcpy(lpstInfo, "Windows 98");
  }
  // 윈도우 95는 Build 번호가 하위 워드에 들어간다.
  win95Info = (DWORD)(LOBYTE(LOWORD(versionInfo.dwBuildNumber)));
  wsprintf(lpstBuildNumber, "%d", win95Info);
    }
    else wsprintf(lpstInfo, "Windows 3.1");
    // 서비스 팩 정보를 얻어낸다.
    strcpy(lpstServicePack, versionInfo.szCSDVersion);
}


레지스트리 읽고 쓰기

API를 이용해서 레지스트리에 한 항목을 생성하거나 기존 항목의 값을 읽어들이려면
어떻게 해야합니까 ?
레지스트리 관련 API를 사용하려면 winreg.h라는 헤더 파일을 소스에 포함해야 합니다.
레지스트리에 키를 생성하는 방법과 레지스트리에 존재하는 키의 값을 읽는 방법을
차례로 살펴보겠습니다.
레지스트리 키 생성 예제
// 예를 들어 HKEY_LOCAL_MACHINE밑의 SystemCurrentControlSetServicesGenPort라는 키를
// 생성하고 거기에 DWORD 타입의 값으로 Type을 만들고 문자열 타입의 값으로 Group
// 을 만들어 본다.
#include "winreg.h"
LONG error = 0;
HKEY hKey;
DWORD dwDisp, dwData;
char lpData[] = "Write this down";
// 먼저 만들려는 키가 이미 존재하는 것인지 살혀본다.
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SystemCurrentControlSetServicesGenPort",0, KEY_ALL_ACCESS, &hKey);
if (error != ERROR_SUCCESS)
// 없다면 새로 생성한다.
{
    // 키를 생성한다.
    error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SystemCurrentControlSetServicesGenPort",0, "REG_BINARY",REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwDisp);
    // 위의 키 밑에 Type이란 DWORD 타입의 값을 만들고 1로 초기화
    dwData = 0x1;
    error = RegSetValueEx( hKey, "Type", 0, REG_DWORD,&dwData,4);
    // 위의 키 밑에 Group이란 문자열 타입의 값을 만들고 lpData의 값으로 초기화
    error = RegSetValueEx( hKey, "Group", 0, REG_SZ, lpData, strlen(lpData));
    // 키를 닫는다.
    RegCloseKey(hKey);
}
기존의 레지스트리 키에서 값 읽기
// HKEY_CURRENT_USERSoftwareNetscapeNetscape NavigatorMain 밑의 Install Directory
// 값의 문자열 값을 읽어들인다.
DWORD dwType, cbData;
HKEY hSubKey;
long lRet;
char pszString[255];
// 키를 오픈한다.
if ((lRet = RegOpenKeyEx(HKEY_CURRENT_USER,"SoftwareNetscapeNetscape NavigatorMain",0, KEY_READ | KEY_QUERY_VALUE , &hSubKey)) == ERROR_SUCCESS)
{
    cbData = 255;
    // 문자열 값을 읽어올 데이터의 크기를 준다.
    if ((lRet = RegQueryValueEx(hSubKey, "Install Directory",NULL, &dwType, pszString, &cbData)) == ERROR_SUCCESS)
    {
         // 제대로 읽힌 경우
    }else
    {
         // 에러가 발생한 경우
    }
    RegCloseKey(hSubKey);}
  
    레지스트리 키 삭제하기 -
    RegDeleteKey 함수를 사용한다.
[출처] API Tip|작성자 난뽀다

2010년 1월 19일 화요일

ANSI TO UTF-8 and UTF-8 to ANISI

int ANSIToUTF8(char *pszCode, char *UTF8code)
{
  WCHAR Unicode[100]={0,};
  char utf8[100]={0,};
  // char Lenth 읽어 오기
  int nUnicodeSize = MultiByteToWideChar(CP_ACP, 0, pszCode, strlen(pszCode), Unicode, sizeof(Unicode));
  // UTF-8 Lenth 읽어 오기
  int nUTF8codeSize = WideCharToMultiByte(CP_UTF8, 0, Unicode, nUnicodeSize, UTF8code, sizeof(Unicode), NULL, NULL);
  // UTF-8 변환
  MultiByteToWideChar(CP_UTF8, 0, utf8, nUTF8codeSize, Unicode, sizeof(Unicode));
  return nUTF8codeSize;
}

char* UTF8ToANSI(char *pszCode)
{
    BSTR    bstrWide;
    char*   pszAnsi;
    int     nLength;


    // bstrWide 배열 생성 Lenth를 읽어 온다.
    nLength = MultiByteToWideChar(CP_UTF8, 0, pszCode, lstrlen(pszCode) + 1, NULL, NULL);

    // bstrWide 메모리 설정

    bstrWide = SysAllocStringLen(NULL, nLength);

    MultiByteToWideChar(CP_UTF8, 0, pszCode, lstrlen(pszCode) + 1, bstrWide, nLength);


    // char 배열 생성전 Lenth를 읽어 온다.
    nLength = WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, NULL, 0, NULL, NULL);

    // pszAnsi 배열 생성
    pszAnsi = new char[nLength];

    // char 변환
    WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, pszAnsi, nLength, NULL, NULL);


    // bstrWide 메모리 해제
    SysFreeString(bstrWide);

    return pszAnsi;
}