프로세서 정보 얻기
VOID GetSystemInfo(
LPSYSTEM_INFO lpSystemInfo // address of system information
// structure
)
typedef struct _SYSTEM_INFO { // sinf
union {
DWORD dwOemId;
struct {
WORD wProcessorArchitecture;
WORD wReserved;
};
};
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
} SYSTEM_INFO;
SYSTEM_INFO구조체의wProcessorArchitecture멤버의
값을 확인 하면 32비트 인지 64비트 인지 알 수 있다
그런데, 64비트 컴퓨터에서 64비트 운영체제를 실행하고 있더라도 32비트 프로그램은 언제나 이 값이 0, 즉 32비트(x86)이 돌아온다.
이는 호환성 차원에서 취해진 조치이다.
64비트 프로그램이라면 그냥 기존의 GetSystemInfo만 써도 x64를 의미하는 9가 돌아온다.
시스템 메모리 정보 얻기
GlobalMemoryStatus. GlobalMemoryStatusEx 함수를 써야 한다.
빌드되는 실행 파일의 헤더에 large address aware 플래그가 켜져 있어야 한다.
비주얼 C++ 기준 Linker → System → Enable Large Addresses를 yes로 지정해 주면 된다.
64비트 플랫폼에서는 이 값이 기본적으로 yes이지만, 32비트 플랫폼에서는 기본값이 no이다.
large address aware이 켜져 있지 않으면 32비트에서는 사용 가능한 가상 메모리가 아예 4GB가 아닌 2GB로 반토막이 난 채 표시된다.포인터의 최상위 1비트를 비워 준다.
그리고 64비트 바이너리에 대해서는 사용 가능한 가상 메모리의 양이야 언제나 있는 그대로 운영체제가 알려 주지만,
해당 바이너리에 이 플래그가 없으면, 운영체제는 아예 상위 32비트를 비워 줘서 DLL 같은 걸 LoadLibrary해도 언제나 32비트 영역 안에서만 주소를 잡는다.
포인터까지 4바이트짜리 int와 구분 없이 작성된 구식 코드들의 64비트 포팅을 수월하게 해 주기 위한 조치이다.
참고로 64비트 전용 프로그램이라면 Ex 대신 기존의 GlobalMemoryStatus만 써도 괜찮다.
받아들이는 구조체의 크기가 int가 아니라 SIZE_T이기 때문에, 32비트 플랫폼에서는 32비트이지만 64비트 플랫폼에서는 자동으로 64비트가 설정되기 때문이다.
Ex 함수는 플랫폼의 비트 수에 관계없이 숫자의 크기가 언제나 64비트 크기를 보장해 줄 뿐이다.
64비트 운영체제에서 동작하고 있는지 감지하기
IsWow64Process();
윈도우 시스템 디렉터리에 접근하기
64비트 운영체제는 잘 알다시피 시스템 디렉터리가 64비트용과 32비트용으로 두 개 존재한다.
32비트와 64비트 프로그램에 관계없이 GetSystemDirectory는 언제나 C:\Windows\system32를 되돌린다.
그리고 윈도우 XP에서 추가된 GetSystemWow64Directory라는 함수가 있어서 역시 32비트와 64비트에관계없이 C:\Windows\SysWow64를 되돌린다.
다만, 운영체제 자체가 64비트가 아닌 32비트 에디션이라면, 후자의 함수는 에러를 리턴한다.
그러니 의외로 이 함수는 플랫폼에 관계없이 절대적으로 같은 결과를 되돌리는 듯한데,
문제는 64비트 운영체제는 32비트 프로그램에 대해 시스템 디렉터리를 기본적으로 redirection한다는 것이다.
즉, 64비트 운영체제는 32비트 프로그램이 C:\Windows\System32를 요청한다고 해도
SysWow64의 내용을 보여주지 진짜 64비트용 시스템 디렉터리의 내용을 보여주지 않는다.
만약 32비트 기반으로 응용 프로그램 설치 관리자나 파일 유틸리티 같은 걸 만들 생각이어서 진짜로 64비트 시스템 디렉터리에 접근을 하고 싶다면,
운영체제에다 별도의 함수를 호출해서 요청을 해야 한다.
그래서 처음에는 Wow64EnableWow64FsRedirection라는 함수가 추가되었다.
이걸로 잠시 예외 요청을 한 뒤, 내가 할 일이 끝난 뒤엔 다시 설정을 원상복귀해야 했다.
왜냐하면 64비트 시스템 디렉터리에 접근 가능하게 해 놓은 예외 동작을 그대로 방치하면,
나중에 다른 32비트 모듈들이 32비트 시스템 디렉터리에 접근하지 못하게 되기 때문이다.
그런데 MS에서는 함수 디자인을 저렇게 한 것을 후회하고, 위의 함수의 기능을
Wow64DisableWow64FsRedirection과 Wow64RevertWow64FsRedirection 쌍으로 대체한다고 밝혔다.
MSDN을 읽어 보면 알겠지만, 64비트 접근 여부 설정치를 마치 stack처럼 다단계로 저장했다가
다시 원상복귀를 더 쉽게 할 수 있게 만들려는 의도이다.
Program Files 디렉터리에 접근하기
64비트 운영체제는 응용 프로그램 디렉터리도 64비트용과 32비트용이 두 개 존재한다.
64비트 운영체제에서 64비트 프로그램은 64비트와 32비트용 Program Files 위치를 아주 쉽게 얻어 올 수 있다.32비트를 가리키는 식별자가 따로 할당되어 있기 때문이다.
그러나 32비트 프로그램이 64비트 운영체제의 64비트 위치를 얻는 것은 위의 두 함수로 가능하지 않다.
SpecialFolder 함수는 64비트만을 가리키는 식별자 자체가 없으며,
KnownFolder함수도 32비트 프로그램에서 FOLDERID_ProgramFilesX64 같은 64비트 식별자를 사용할 경우 에러만 돌아오기 때문이다.
32비트 프로그램이 64비트 Program Files 위치를 얻는 거의 유일한 공식적인 통로는 의외의 곳에 있다. 바로 환경변수이다.
::ExpandEnvironmentStrings(_T("%ProgramW6432%\\"), wt, 256);
위의 환경변수를 사용한 코드는 32비트와 64비트에서 동일하게 64비트용 Program Files 위치를 되돌려 준다.
'개발언어 > c++' 카테고리의 다른 글
| Memory(-Leak) and Exception Trace (CRT and COM Leaks) (0) | 2016.07.16 |
|---|---|
| 메모리누수(leak) 탐지소스 (0) | 2016.07.16 |
| MFC 다국어 지원 방법(국가별 언어설정) (0) | 2016.07.15 |
| ATL Event Thread, ATL 쓰레드 이벤트 발생 시키기 (0) | 2016.07.09 |
| Event Driven Programming using Template Specializations in C++ (0) | 2016.07.09 |