// ==========================================================================
// Class Implementation : COXSysInfo
// ==========================================================================
//
// Version: 9.3
// This software along with its related components, documentation and files ("The Libraries")
// is � 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office. For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
//////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#ifdef _WIN64
#pragma message ("Ultimate Toolbox: COXSysInfo - cpuinf library unavailable for 64 bit - bypassing compilation.")
// v9.3 - update 03 - 64-bit - The intel cpuinf32 library relies on inline assembly
// for compilation, which is not implemeted in the MS 64-bit compilers. Update needed. - TD
#else
#include "OXSysInfo.h"
#include "OXMainRes.h"
#include <winsock.h>
#include <afxdisp.h> // MFC OLE automation classes
#include <math.h>
#include <lm.h>
#include <lmerr.h>
#include <lmaccess.h>
#include "UTBStrOp.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
// Constants used to set unitialized values
#define UNINIT_BYTE 0x17
#define UNINIT_DWORD 0x17171717
IMPLEMENT_DYNAMIC(COXSysInfo, CObject)
// Data members -------------------------------------------------------------
// None
// private:
// Member functions ---------------------------------------------------------
// public:
COXSysInfo::COXSysInfo()
{
// constructor
}
COXSysInfo::~COXSysInfo()
{
// destructor
}
BOOL COXSysInfo::GetComputerName(CString *psComputerName) const
{
// --- In:
// --- Out: CString *psComputerName: Name of local computer
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the name of the local computer
ASSERT(psComputerName != NULL);
BOOL bReturn;
DWORD dwBufSize;
TCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1];
dwBufSize = sizeof(buffer)/sizeof(buffer[0]);
bReturn = ::GetComputerName(buffer, &dwBufSize);
if (bReturn)
*psComputerName = buffer;
else
{
TRACE(_T("COXSysInfo::GetComputerName - ::GetComputerName() failed\n"));
}
return (bReturn);
}
BOOL COXSysInfo::GetUserName(CString *psUserName) const
{
// --- In:
// --- Out: CString *psUserName: Name of current user
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the name of the current user
ASSERT(psUserName != NULL);
BOOL bReturn;
DWORD dwBufSize;
TCHAR buffer[UNLEN+1];
dwBufSize = sizeof(buffer)/sizeof(buffer[0]);
bReturn = ::GetUserName(buffer, &dwBufSize);
if (bReturn)
*psUserName = buffer;
else
{
TRACE(_T("COXSysInfo::GetUserName - ::GetUserName() failed\n"));
}
return (bReturn);
}
BOOL COXSysInfo::GetUserAndDomainName(CString *psUserName, CString *psDomainName) const
{
// --- In:
// --- Out: CString *psUserName: Name of current user
// CString *psDomainName: Name of current domain logged on to
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the name of the current user and the domain. Works only
// on Win NT.
ASSERT(psUserName != NULL);
ASSERT(psDomainName != NULL);
BOOL bSuccess = FALSE;
#define BUF_SIZE 512
DWORD dwBufSize = BUF_SIZE;
TCHAR buffer[BUF_SIZE];
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
if (bIsNT)
// We're running on NT.
{
HANDLE hToken(0);
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken))
{
if (GetLastError() == ERROR_NO_TOKEN)
// We'll try to open the process token since no thread token exists
{
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
TRACE(_T("COXSysInfo::GetUserAndDomainName - ::OpenProcessToken() failed\n"));
return FALSE;
}
}
else
// Failed to get the thread token
{
TRACE(_T("COXSysInfo::GetUserAndDomainName - ::OpenThreadToken() failed\n"));
return FALSE;
}
}
ASSERT(hToken != NULL);
bSuccess = GetTokenInformation(hToken, TokenUser, buffer, dwBufSize, &dwBufSize);
if (!bSuccess)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
// Allocate a bigger bufer and try again
{
TRACE(_T("COXSysInfo::GetUserAndDomainName - Insuffient buffer() trying again ...\n"));
CloseHandle(hToken);
return FALSE;
}
else
// We have an error while getting the token info
{
TRACE(_T("COXSysInfo::GetUserAndDomainName - ::GetTokenInformation() failed\n"));
CloseHandle(hToken);
return FALSE;
}
}
CloseHandle(hToken);
SID_NAME_USE Snu;
DWORD dwUserName = BUF_SIZE;
DWORD dwDomainName = BUF_SIZE;
TCHAR userName[BUF_SIZE];
TCHAR domainName[BUF_SIZE];
bSuccess = LookupAccountSid(NULL, ((PTOKEN_USER)buffer)->User.Sid, userName, &dwUserName, domainName, &dwDomainName, &Snu);
if (bSuccess)
{
*psUserName = userName;
*psDomainName = domainName;
}
}
else
// Not Win NT
{
TRACE(_T("COXSysInfo::GetUserAndDomainName : NON WIN NT NOT SUPPORTED\n"));
VERIFY(psUserName->LoadString(IDS_OX_SYSINFOUNKNOWNUSER)); //"<UNKNOWN>"
VERIFY(psDomainName->LoadString(IDS_OX_SYSINFOUNKNOWNDOMAIN)); //"<UNKNOWN>"
}
return (bSuccess);
}
BOOL COXSysInfo::GetPrimaryIPAddress(CString *psIPAddress,
LPCSTR pszHostName/*=NULL*/) const
{
// --- In: LPCSTR pszHostName: Host name for which primary
// IP address will be retrieved
// --- Out: CString *psIPAddress: Current IP address (0.0.0.0
// if undefined)
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the current network IP address
ASSERT(psIPAddress != NULL);
CStringArray IPArray;
if(!GetListIPAddresses(&IPArray,TRUE,pszHostName))
return FALSE;
*psIPAddress=IPArray[0];
return (TRUE);
}
BOOL COXSysInfo::GetListIPAddresses(CStringArray* psIPAddressList,
BOOL bPrimary /* = FALSE */,
LPCSTR pszHostName/*=NULL*/) const
{
// --- In: BOOL bPrimary : TRUE if only primary IP must be
// retrieved
// LPCSTR pszHostName: Host name for which IP address
// will be retrieved
// --- Out: CStringArray* psIPAddressList: List of IP addresses
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the list of network IP address of a
// multi-homed computer
ASSERT(psIPAddressList!=NULL);
CHAR buffer[255];
WORD wVersionRequested;
WSADATA wsaData;
int err;
HINSTANCE hLib = LoadLibrary(_T("WS2_32.DLL"));
if (hLib != NULL)
{
// Loaded WS2_32.DLL...
typedef int (WINAPI* WSASTARTUP) (WORD wVersionRequested, LPWSADATA lpWSAData);
WSASTARTUP dWSAStartup = (WSASTARTUP) GetProcAddress(hLib, "WSAStartup");
typedef int (WINAPI* GETHOSTNAME) (char FAR* name, int namelen);
GETHOSTNAME dgethostname = (GETHOSTNAME) GetProcAddress(hLib, "gethostname");
typedef struct hostent FAR* (WINAPI* GETHOSTBYNAME) (const char FAR* name);
GETHOSTBYNAME dgethostbyname = (GETHOSTBYNAME) GetProcAddress(hLib, "gethostbyname");
typedef int (WINAPI* WSACLEANUP) ();
WSACLEANUP dWSACleanup = (WSACLEANUP) GetProcAddress(hLib, "WSACleanup");
typedef char FAR* (WINAPI* INET_NTOA) (struct in_addr in);
INET_NTOA dinet_ntoa = (INET_NTOA) GetProcAddress(hLib, "inet_ntoa");
// Verify all dll entries
if (dWSAStartup == NULL || dgethostname == NULL ||
dgethostbyname == NULL || dWSACleanup == NULL || dinet_ntoa == NULL)
{
TRACE(_T("COXSysInfo::GetListIPAddresses - GetProcAddress() failed\n"));
// Free the DLL
FreeLibrary(hLib);
return (FALSE);
}
wVersionRequested = MAKEWORD(1, 1);
err = dWSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
TRACE(_T("COXSysInfo::GetListIPAddresses - WSAStartup() failed\n"));
// Free the DLL
FreeLibrary(hLib);
return (FALSE);
}
BOOL bSuccess=TRUE;
if(pszHostName==NULL)
{
bSuccess=(dgethostname(buffer, sizeof(buffer))==0);
pszHostName=(LPCSTR)buffer;
}
if (bSuccess)
{
hostent* pHostInfo = dgethostbyname(pszHostName);
if (pHostInfo != NULL)
{
ASSERT(pHostInfo->h_addrtype == PF_INET);
ASSERT(pHostInfo->h_length == 4);
// Iterate all the address of this host
// and put them in stringarray
int i = 0;
in_addr address;
while (pHostInfo->h_addr_list[i] != NULL)
{
PBYTE pAddress = (PBYTE)pHostInfo->h_addr_list[i];
// ... Put the seperate bytes in a single long
address.S_un.S_addr = (u_long)pAddress[0];
address.S_un.S_addr += ((u_long)pAddress[1]) << 8;
address.S_un.S_addr += ((u_long)pAddress[2]) << 16;
address.S_un.S_addr += ((u_long)pAddress[3]) << 24;
// ... Convert long to string (4 numbers seperated by dots)
psIPAddressList->Add(CString(dinet_ntoa(address)));
if (bPrimary)
break;
i++;
}
// Free the Winsock resources
dWSACleanup();
// Free the DLL
FreeLibrary(hLib);
return TRUE;
}
}
TRACE(_T("COXSysInfo::GetListIPAddresses - gethostname() or gethostbyname() failed\n"));
// Free the Winsock resources
dWSACleanup();
// Free the DLL
FreeLibrary(hLib);
return FALSE;
}
TRACE(_T("COXSysInfo::GetListIPAddresses - LoadLibrary of WS2_32.DLL failed\n"));
return FALSE;
}
BOOL COXSysInfo::GetWindowsVersion(DWORD *pdwPlatform, DWORD *pdwMajor,
DWORD *pdwMinor) const
{
// --- In:
// --- Out: DWORD *pdwPlatform: Current Windows platform
// DWORD *pdwMajor: Major OS version
// DWORD *pdwMinor: Minor OS version
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the current Windows OS version
ASSERT(pdwPlatform!=NULL && pdwMajor!=NULL && pdwMinor!=NULL);
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
BOOL bReturn = GetVersionEx(&osvi);
if (!bReturn)
{
TRACE(_T("COXSysInfo::GetWindowsVersion - ::GetVersionEx() failed\n"));
return (FALSE);
}
// Possible platform IDs:
// VER_PLATFORM_WIN32s Win32s on Windows 3.1.
// VER_PLATFORM_WIN32_WINDOWS (dwMinorVersion is 0) Windows 95.
// VER_PLATFORM_WIN32_WINDOWS (dwMinorVersion is 1) Windows 98.
// VER_PLATFORM_WIN32_NT Windows NT/XP/Vista.
*pdwPlatform = osvi.dwPlatformId;
*pdwMajor = osvi.dwMajorVersion;
*pdwMinor = osvi.dwMinorVersion;
return (TRUE);
}
BOOL COXSysInfo::GetWindowsBuildNumber(DWORD *pdwBuildNumber) const
{
// --- In:
// --- Out: DWORD *pdwBuildNumber: Windows platform build number
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the current Windows OS version build number
ASSERT(pdwBuildNumber!=NULL);
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
BOOL bReturn = GetVersionEx(&osvi);
if (!bReturn)
{
TRACE(_T("COXSysInfo::GetWindowsBuildNumber - ::GetVersionEx() failed\n"));
return (FALSE);
}
// Possible platform IDs:
// VER_PLATFORM_WIN32s Win32s on Windows 3.1.
// VER_PLATFORM_WIN32_WINDOWS (dwMinorVersion is 0) Windows 95.
// VER_PLATFORM_WIN32_WINDOWS (dwMinorVersion is 1) Windows 98.
// VER_PLATFORM_WIN32_NT Windows NT.
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
*pdwBuildNumber = osvi.dwBuildNumber;
else
*pdwBuildNumber = LOWORD(osvi.dwBuildNumber);
return (TRUE);
}
BOOL COXSysInfo::GetWindowsPlatformInfo(CString& sPlatformInfo) const
{
// --- In:
// --- Out: CString& sPlatformInfo: additional information about
// the operating system
// --- Effect: Retrieves additional information for current
// Windows OS version
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
BOOL bReturn = GetVersionEx(&osvi);
if (!bReturn)
{
TRACE(_T("COXSysInfo::GetWindowsBuildNumber - ::GetVersionEx() failed\n"));
return (FALSE);
}
// Possible platform IDs:
// VER_PLATFORM_WIN32s Win32s on Windows 3.1.
// VER_PLATFORM_WIN32_WINDOWS (dwMinorVersion is 0) Windows 95.
// VER_PLATFORM_WIN32_WINDOWS (dwMinorVersion is 1) Windows 98.
// VER_PLATFORM_WIN32_NT Windows NT.
sPlatformInfo=osvi.szCSDVersion;
return (TRUE);
}
BOOL COXSysInfo::IsNT(BOOL *pbResult) const
{
// --- In:
// --- Out: DWORD *pbResult: TRUE if Windows NT running
// --- Returns: BOOL - TRUE if success
// --- Effect: Determines if the current Windows OS
// version is NT
ASSERT(pbResult!=NULL);
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osvi))
{
TRACE(_T("COXSysInf::IsNT: GetVersionEx() has failed\n"));
return (FALSE);
}
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
// We're running on NT.
*pbResult=TRUE;
else
*pbResult=FALSE;
return (TRUE);
}
BOOL COXSysInfo::IsNTServer(BOOL *pbResult) const
{
// --- In:
// --- Out: DWORD *pbResult: TRUE if Windows NT Server
// installed
// --- Returns: BOOL - TRUE if success
// --- Effect: Determines if the current Windows OS
// version is NT Server or not
ASSERT(pbResult!=NULL);
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
if (bIsNT)
{
HKEY hKey;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
_T("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"),
0, KEY_EXECUTE, &hKey) != ERROR_SUCCESS)
return (FALSE);
DWORD dwType, dwSize;
CString sProductType;
LPTSTR lpProductType=sProductType.GetBuffer(MAX_PATH+1);
if(RegQueryValueEx(hKey,_T("ProductType"),NULL,&dwType,
(LPBYTE)lpProductType,&dwSize)!=ERROR_SUCCESS)
{
sProductType.ReleaseBuffer();
return (FALSE);
}
sProductType.ReleaseBuffer();
ASSERT(dwType==REG_SZ);
RegCloseKey(hKey);
if (sProductType==_T("WinNT"))
*pbResult=FALSE;
else if (sProductType==_T("LanmanNT"))
*pbResult=TRUE;
else if (sProductType==_T("ServerNT"))
*pbResult=TRUE;
else
return (FALSE);
}
else
*pbResult=FALSE;
return (TRUE);
}
BOOL COXSysInfo::IsOSR2(BOOL *pbResult) const
{
// --- In:
// --- Out: DWORD *pbResult: TRUE if Windows 95 OSR 2
// installed
// --- Returns: BOOL - TRUE if success
// --- Effect: Determines if the current Windows OS
// version is Windows 95 OSR 2 or not
ASSERT(pbResult!=NULL);
OSVERSIONINFO osvi = { sizeof(OSVERSIONINFO) };
BOOL bReturn = GetVersionEx(&osvi);
if (!bReturn)
{
TRACE(_T("COXSysInfo::IsOSR2 - ::GetVersionEx() failed\n"));
return (FALSE);
}
WORD wVersion = LOWORD(osvi.dwBuildNumber);
*pbResult=FALSE;
if ((osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && (wVersion > 1000))
// OSR2 (or greater) of Windows 95...
*pbResult=TRUE;
return (TRUE);
}
BOOL COXSysInfo::GetWindowsDir(CString *psWinDir) const
{
// --- In:
// --- Out: CString *psWinDir: Windows directory
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the Windows directory
ASSERT(psWinDir != NULL);
TCHAR buffer[_MAX_PATH+1];
BOOL bReturn;
bReturn = GetWindowsDirectory(buffer, sizeof(buffer)/sizeof(buffer[0]));
if (bReturn)
*psWinDir = buffer;
else
{
TRACE(_T("COXSysInfo::GetWindowsDir - ::GetWindowsDirectory() failed\n"));
}
return (bReturn);
}
BOOL COXSysInfo::GetSystemDir(CString *psSysDir) const
{
// --- In:
// --- Out: CString *psSysDir: System directory
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the System directory
ASSERT(psSysDir != NULL);
TCHAR buffer[MAX_PATH+1];
BOOL bReturn;
bReturn = ::GetSystemDirectory(buffer, sizeof(buffer)/sizeof(buffer[0]));
if (bReturn)
*psSysDir = buffer;
else
TRACE(_T("COXSysInfo::GetSystemDir - ::GetSystemDirectory() failed\n"));
return (bReturn);
}
BOOL COXSysInfo::GetTempDir(CString *psTempDir) const
{
// --- In:
// --- Out: CString *psTempDir: Temp directory
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the temp directory
ASSERT(psTempDir != NULL);
TCHAR buffer[_MAX_PATH+1];
BOOL bReturn;
bReturn = ::GetTempPath(sizeof(buffer)/sizeof(buffer[0]), buffer);
if (bReturn)
*psTempDir = buffer;
else
TRACE(_T("COXSysInfo::GetTempDir - ::GetTempPath() failed\n"));
return (bReturn);
}
HICON COXSysInfo::GetFileIcon(LPCTSTR pszFileName, BOOL bSmall,
BOOL bSelected, BOOL bFileMustExist) const
{
SHFILEINFO shfi;
// FILE_ATTRIBUTE_NORMAL and SHGFI_USEFILEATTRIBUTES allow to retrieve data
// without checking if file exists
if(!::SHGetFileInfo(pszFileName,
(bFileMustExist ? 0 : FILE_ATTRIBUTE_NORMAL),&shfi,sizeof(SHFILEINFO),
SHGFI_SHELLICONSIZE|SHGFI_ICON|
(bFileMustExist ? 0 : SHGFI_USEFILEATTRIBUTES)|
(bSmall ? SHGFI_SMALLICON : SHGFI_LARGEICON)|
(bSelected ? SHGFI_SELECTED : 0)))
{
return NULL;
}
return shfi.hIcon;
}
HICON COXSysInfo::GetFileExtIcon(LPCTSTR pszFileExt, BOOL bSmall, BOOL bSelected) const
{
CString sFileName;
sFileName.Format(_T(".%s"),pszFileExt);
return GetFileIcon(sFileName,bSmall,bSelected,FALSE);
}
BOOL COXSysInfo::GetDriveTypeInfo(int nDrive, CString *psFileSysType,
int *pnDiskType) const
{
// --- In: int nDrive: drive 0-25 (A-Z)
// --- Out: CString *psFileSysType: File system type
// int *pnDiskType: Disk type
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves disk drive information
ASSERT(psFileSysType != NULL);
ASSERT(pnDiskType != NULL);
// Looking for drives 0-25 (A-Z)
if ((nDrive < 0) || (nDrive >= 26))
{
TRACE(_T("COXSysInfo::GetDriveTypeInfo - invalid drive number\n"));
return (FALSE);
}
TCHAR szRoot[8];
TCHAR szVolName[_MAX_PATH+1];
DWORD dwVolSer, dwMaxLen, dwFileSysFlags;
TCHAR szFileSysName[_MAX_PATH+1];
UTBStr::stprintf(szRoot, 8, _T("%c:\\"), 65 + nDrive);
UINT uiDriveType = ::GetDriveType(szRoot);
if ((uiDriveType == DRIVE_UNKNOWN) || (uiDriveType == DRIVE_NO_ROOT_DIR))
{
TRACE(_T("COXSysInfo::GetDriveTypeInfo - ::GetDriveType() failed\n"));
return (FALSE);
}
*pnDiskType = (int) uiDriveType;
if (GetVolumeInformation(szRoot, szVolName,
sizeof(szVolName)/sizeof(szVolName[0]), &dwVolSer, &dwMaxLen,
&dwFileSysFlags, szFileSysName,
sizeof(szFileSysName)/sizeof(szFileSysName[0])) == FALSE)
{
TRACE(_T("COXSysInfo::GetDriveTypeInfo - ::GetVolumeInformation() failed\n"));
return (FALSE);
}
*psFileSysType = szFileSysName;
return (TRUE);
}
BOOL COXSysInfo::GetDriveVolumeInfo(int nDrive, CString *psVolumeName,
DWORD *pdwVolSer, DWORDLONG *pdwTotalSpace,
DWORDLONG *pdwFreeSpace) const
{
// --- In: int nDrive: drive 0-25 (A-Z)
// --- Out: CString *psVolumeName: Disk volume name
// DWORD *pdwVolSer: Disk serial number
// DWORDLONG *pdwTotalSpace: Total space bytes
// DWORDLONG *pdwFreeSpace: Total free space bytes
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves disk drive volume information
ASSERT(psVolumeName != NULL);
ASSERT(pdwVolSer != NULL);
ASSERT(pdwTotalSpace != NULL);
ASSERT(pdwFreeSpace != NULL);
TCHAR szRoot[8];
TCHAR szVolName[_MAX_PATH+1];
DWORD dwVolSer, dwMaxLen, dwFileSysFlags;
TCHAR szFileSysName[_MAX_PATH+1];
BOOL bRet = TRUE;
// Looking for drives 0-25 (A-Z)
if ((nDrive < 0) || (nDrive >= 26))
{
TRACE(_T("COXSysInfo::GetDriveVolumeInfo - invalid drive number\n"));
return (FALSE);
}
UTBStr::stprintf(szRoot, 8, _T("%c:\\"), 65 + nDrive);
dwMaxLen = MAX_PATH;
if (GetVolumeInformation(szRoot, szVolName,
sizeof(szVolName)/sizeof(szVolName[0]), &dwVolSer, &dwMaxLen,
&dwFileSysFlags, szFileSysName,
sizeof(szFileSysName)/sizeof(szFileSysName[0])) == FALSE)
{
TRACE(_T("COXSysInfo::GetDriveVolumeInfo - ::GetVolumeInformation() failed\n"));
return (FALSE);
}
*psVolumeName = szVolName;
*pdwVolSer = dwVolSer;
DWORD dwSectorsPerCluster, dwBytesPerSector;
DWORD dwNumberOfFreeClusters, dwTotalNumberOfClusters;
BOOL bIsOSR2;
if(IsOSR2(&bIsOSR2) && bIsOSR2)
{
// OSR2 (or greater) of Windows 95...
HINSTANCE hLib = LoadLibrary(_T("KERNEL32.DLL"));
if (hLib != NULL)
{
// Loaded KERNEL32.DLL...
typedef BOOL (WINAPI *GETDISKFREESPACEEX) (LPCTSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes);
GETDISKFREESPACEEX dGetDiskFreeSpaceEx =
(GETDISKFREESPACEEX) GetProcAddress(hLib, "GetDiskFreeSpaceExA");
ULARGE_INTEGER ulFreeBytesAvailable;
ULARGE_INTEGER ulTotalBytes;
ULARGE_INTEGER ulTotalFree;
if (dGetDiskFreeSpaceEx != NULL)
{
if (dGetDiskFreeSpaceEx(szRoot, &ulFreeBytesAvailable, &ulTotalBytes,
&ulTotalFree) > 0)
{
// Get total disk space...
*pdwTotalSpace = (DWORDLONG) ulTotalBytes.QuadPart;
// Get free disk space...
*pdwFreeSpace = (DWORDLONG) ulTotalFree.QuadPart;
}
}
else
{
if (GetDiskFreeSpace(szRoot, &dwSectorsPerCluster, &dwBytesPerSector,
&dwNumberOfFreeClusters, &dwTotalNumberOfClusters) == 0)
return (FALSE);
// Get total disk space...
*pdwTotalSpace = (DWORDLONG)dwSectorsPerCluster *
(DWORDLONG)dwBytesPerSector * (DWORDLONG)dwTotalNumberOfClusters;
// Get free disk space...
*pdwFreeSpace = (DWORDLONG)dwSectorsPerCluster *
(DWORDLONG)dwBytesPerSector * (DWORDLONG)dwNumberOfFreeClusters;
}
// Free the DLL
FreeLibrary(hLib);
}
}
else
{
if (GetDiskFreeSpace(szRoot, &dwSectorsPerCluster, &dwBytesPerSector,
&dwNumberOfFreeClusters, &dwTotalNumberOfClusters) == 0)
{
return (FALSE);
}
// Get total disk space...
*pdwTotalSpace = (DWORDLONG)dwSectorsPerCluster *
(DWORDLONG)dwBytesPerSector * (DWORDLONG)dwTotalNumberOfClusters;
// Get free disk space...
*pdwFreeSpace = (DWORDLONG)dwSectorsPerCluster *
(DWORDLONG)dwBytesPerSector * (DWORDLONG)dwNumberOfFreeClusters;
}
return (bRet);
}
BOOL COXSysInfo::GetDisplayResolution(int *pnxRes, int *pnyRes) const
{
// --- In:
// --- Out: int *xRes: horizontal screen resolution (pixels)
// int *yRes: vertical screen resolution (pixels)
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the display resolution size
ASSERT(pnxRes != NULL);
ASSERT(pnyRes != NULL);
int iXRes = DeviceCaps(HORZRES);
if (iXRes == -1)
{
TRACE(_T("COXSysInfo::GetDisplayResolution - invalid X resolution\n"));
return (FALSE);
}
int iYRes = DeviceCaps(VERTRES);
if (iYRes == -1)
{
TRACE(_T("COXSysInfo::GetDisplayResolution - invalid Y resolution\n"));
return (FALSE);
}
*pnxRes = iXRes;
*pnyRes = iYRes;
return (TRUE);
}
BOOL COXSysInfo::GetDisplayNumColors(DWORDLONG *pdwNumColors, int *pnNumBits) const
{
// --- In:
// --- Out: DWORDLONG *pdwNumColors: Number of colors used by current display
// int *pnNumBits: Number of bits for color depth
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the display color usage
ASSERT(pdwNumColors != NULL);
ASSERT(pnNumBits != NULL);
int iBitsPixel = DeviceCaps(PLANES) * DeviceCaps(BITSPIXEL);
int i;
*pdwNumColors = 1;
for(i=0;i<iBitsPixel;i++)
*pdwNumColors = *pdwNumColors * 2;
*pnNumBits = iBitsPixel;
return (TRUE);
}
BOOL COXSysInfo::GetAllDisplayModes(CArrayDisplayMode* parrDisplayMode) const
{
ASSERT(parrDisplayMode!=NULL);
parrDisplayMode->RemoveAll();
// # of DEVMODEs
int nModeNum=-1;
// Information about supported display resolutions, 200 should be enough
DEVMODE dvmd[1024];
// Get all of the possible display modes
::ZeroMemory((void*)&dvmd, sizeof(dvmd));
do
{
nModeNum++;
dvmd[nModeNum].dmSize = sizeof(DEVMODE);
dvmd[nModeNum].dmDriverExtra = 0;
} while(::EnumDisplaySettings(NULL, nModeNum, &dvmd[nModeNum]));
ASSERT(nModeNum>0);
// Sort all of the display modes:
// 1: Resolution (width), 2: color depth, 3: frequency.
::qsort(&dvmd[0],nModeNum,sizeof(DEVMODE),DevModeCompare);
for(int nIndex=0; nIndex<nModeNum; nIndex++)
{
if(nIndex>0)
{
// If this is not the first DEVMODE entry, possibly add a seperator bar
if((dvmd[nIndex].dmPelsWidth==dvmd[nIndex-1].dmPelsWidth) &&
(dvmd[nIndex].dmPelsHeight==dvmd[nIndex-1].dmPelsHeight) &&
(dvmd[nIndex].dmBitsPerPel==dvmd[nIndex-1].dmBitsPerPel))
{
// This entry is identical to the previous entry except for refrash rate
// Let's not add this entry to the menu
continue;
}
}
// We started a new resolution, add it to our array
DISPLAYMODE displayMode;
displayMode.dwBitsPerPixel=dvmd[nIndex].dmBitsPerPel;
displayMode.dwHorzResolution=dvmd[nIndex].dmPelsWidth;
displayMode.dwVertResolution=dvmd[nIndex].dmPelsHeight;
displayMode.dwNumColors=1;
for(DWORD nIndex=0; nIndex<displayMode.dwBitsPerPixel; nIndex++)
displayMode.dwNumColors*=2;
parrDisplayMode->Add(displayMode);
}
return TRUE;
}
BOOL COXSysInfo::GetDisplayMaxResolution(int *pnxRes, int *pnyRes) const
{
// --- In:
// --- Out: int *xRes: max horizontal screen resolution (pixels)
// int *yRes: max vertical screen resolution (pixels)
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the display resolution size
ASSERT(pnxRes != NULL);
ASSERT(pnyRes != NULL);
CArrayDisplayMode arrDisplayMode;
if(!GetAllDisplayModes(&arrDisplayMode) || arrDisplayMode.GetSize()==0)
return (FALSE);
DWORD dwMaxXRes=0;
DWORD dwMaxYRes=0;
for(int nIndex=0; nIndex<arrDisplayMode.GetSize(); nIndex++)
{
DISPLAYMODE displayMode=arrDisplayMode.GetAt(nIndex);
if(dwMaxXRes*dwMaxYRes<
displayMode.dwHorzResolution*displayMode.dwVertResolution)
{
dwMaxXRes=displayMode.dwHorzResolution;
dwMaxYRes=displayMode.dwVertResolution;
}
}
ASSERT(dwMaxXRes*dwMaxYRes>0);
*pnxRes=dwMaxXRes;
*pnyRes=dwMaxYRes;
return (TRUE);
}
BOOL COXSysInfo::GetDisplayMaxNumColors(DWORDLONG *pdwNumColors, int *pnNumBits) const
{
// --- In:
// --- Out: DWORDLONG *pdwNumColors: Max number of colors used
// by current display
// int *pnNumBits: Max number of bits for color depth
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the display color usage
ASSERT(pdwNumColors != NULL);
ASSERT(pnNumBits != NULL);
CArrayDisplayMode arrDisplayMode;
if(!GetAllDisplayModes(&arrDisplayMode) || arrDisplayMode.GetSize()==0)
return (FALSE);
DWORD dwMaxNumBits=0;
int nIndex=0;
for(nIndex=0; nIndex<arrDisplayMode.GetSize(); nIndex++)
{
DISPLAYMODE displayMode=arrDisplayMode.GetAt(nIndex);
if(dwMaxNumBits<displayMode.dwBitsPerPixel)
dwMaxNumBits=displayMode.dwBitsPerPixel;
}
ASSERT(dwMaxNumBits>0);
*pnNumBits=dwMaxNumBits;
*pdwNumColors = 1;
for(nIndex=0;nIndex<(int)dwMaxNumBits;nIndex++)
*pdwNumColors = *pdwNumColors * 2;
return (TRUE);
}
BOOL COXSysInfo::IsSmallFont(BOOL* pbIsSmall) const
{
// --- In:
// --- Out: BOOL *pbIsSmall: if TRUE then small fonts are used,
// otherwise the large ones
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the flag that specifies whether small or
// large fonts are used in the system
ASSERT(pbIsSmall!=NULL);
CWnd* pWnd=CWnd::GetDesktopWindow();
if(pWnd!=NULL)
{
CDC* pDC=pWnd->GetWindowDC();
if(pDC!=NULL)
{
TEXTMETRIC tm;
if(pDC->GetTextMetrics(&tm))
{
if(tm.tmHeight>16)
*pbIsSmall=FALSE;
else
*pbIsSmall=TRUE;
pWnd->ReleaseDC(pDC);
return TRUE;
}
pWnd->ReleaseDC(pDC);
}
}
return FALSE;
}
BOOL COXSysInfo::GetTotalPhysicalMemory(DWORD_PTR *pdwPhysMem)
{
// --- In:
// --- Out: DWORD *pdwPhysMem: Total physical RAM
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the amount of physical memory
ASSERT(pdwPhysMem != NULL);
GetMemStatus() ;
*pdwPhysMem = m_memStatus.dwTotalPhys;
return (TRUE);
}
BOOL COXSysInfo::GetFreePhysicalMemory(DWORD_PTR *pdwFreeMem)
{
// --- In:
// --- Out: DWORD *pdwFreeMem: Total free physical RAM
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the amount of free physical memory
ASSERT(pdwFreeMem != NULL);
GetMemStatus();
*pdwFreeMem = m_memStatus.dwAvailPhys;
return (TRUE);
}
BOOL COXSysInfo::GetTotalPageFile(DWORD_PTR *pdwTotalPageFile)
{
// --- In:
// --- Out: DWORD *pdwTotalPageFile: Total page file size
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the size of the page file
ASSERT(pdwTotalPageFile != NULL);
GetMemStatus();
*pdwTotalPageFile = m_memStatus.dwTotalPageFile;
return (TRUE);
}
BOOL COXSysInfo::GetFreePageFile(DWORD_PTR *pdwFreePageFile)
{
// --- In:
// --- Out: DWORD *pdwFreePageFile: Total free page file size
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the free space of the page file
ASSERT(pdwFreePageFile != NULL);
GetMemStatus();
*pdwFreePageFile = m_memStatus.dwAvailPageFile;
return (TRUE);
}
BOOL COXSysInfo::GetTotalVirtual(DWORD_PTR *pdwTotalVirtual)
{
// --- In:
// --- Out: DWORD *pdwTotalVirtual: Total virtual memory
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the size of virtual memory
ASSERT(pdwTotalVirtual != NULL);
GetMemStatus();
*pdwTotalVirtual = m_memStatus.dwTotalVirtual;
return (TRUE);
}
BOOL COXSysInfo::GetFreeVirtual(DWORD_PTR *pdwFreeVirtual)
{
// --- In:
// --- Out: DWORD *pdwFreeVirtual: Total free virtual memory
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the size of the free virtual memory
ASSERT(pdwFreeVirtual != NULL);
GetMemStatus();
*pdwFreeVirtual = m_memStatus.dwAvailVirtual;
return (TRUE);
}
BOOL COXSysInfo::GetNumProcessors(int *pnNumProcessors)
{
// --- In:
// --- Out: int *pnNumProcessors: Total number of processors in machine
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the number of CPUs
ASSERT(pnNumProcessors != NULL);
GetSysInfo();
*pnNumProcessors = (int) m_sysInfo.dwNumberOfProcessors;
return (TRUE);
}
BOOL COXSysInfo::GetProcessorType(DWORD *pdwProcessorType)
{
// --- In:
// --- Out: DWORD *pdwProcessorType: Processor type
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the processor type (primary processor)
ASSERT(pdwProcessorType != NULL);
GetSysInfo();
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
*pdwProcessorType = (DWORD)PROCESSOR_UNKNOWN;
// VER_PLATFORM_WIN32s Win32s on Windows 3.1.
// VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95.
// VER_PLATFORM_WIN32_NT Win32 on Windows NT.
if (bIsNT)
{
// Running NT - so step through processor
// architecture and type to determine
// the actual CPU
// Now determine processor architecture
switch(m_sysInfo.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_INTEL:
switch(m_sysInfo.wProcessorLevel)
{
case 3:
*pdwProcessorType = PROCESSOR_INTEL_386;
break;
case 4:
*pdwProcessorType = PROCESSOR_INTEL_486;
break;
case 5:
*pdwProcessorType = PROCESSOR_INTEL_PENTIUM;
break;
}
break;
case PROCESSOR_ARCHITECTURE_MIPS:
*pdwProcessorType = PROCESSOR_MIPSR4000;
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
*pdwProcessorType = m_sysInfo.wProcessorLevel;
break;
case PROCESSOR_ARCHITECTURE_PPC:
switch(m_sysInfo.wProcessorLevel)
{
case 1:
*pdwProcessorType = PROCESSOR_PPC601;
break;
case 3:
*pdwProcessorType = PROCESSOR_PPC603;
break;
case 4:
*pdwProcessorType = PROCESSOR_PPC604;
break;
case 6:
*pdwProcessorType = PROCESSOR_PPC603PLUS;
break;
case 9:
*pdwProcessorType = PROCESSOR_PPC604PLUS;
break;
case 20:
*pdwProcessorType = PROCESSOR_PPC620;
break;
}
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
break;
}
}
else
{
// Running Win95
// PROCESSOR_INTEL_386
// PROCESSOR_INTEL_486
// PROCESSOR_INTEL_PENTIUM
*pdwProcessorType = m_sysInfo.dwProcessorType;
}
if(*pdwProcessorType==PROCESSOR_INTEL_PENTIUM ||
*pdwProcessorType == (DWORD)PROCESSOR_UNKNOWN)
{
WORD nCPUType=wincpuid();
ASSERT(nCPUType>=5);
switch(nCPUType)
{
// Pentium
case 5:
{
break;
}
// Pentium Pro, Pentium II, Pentium Celeron, Pentium III
case 6:
{
// retrieve CPUID
WORD nCPUidEx=wincpuidext();
// analyze the model number
int nModel=(nCPUidEx&0x00f0)>>4;
switch(nModel)
{
case 1:
*pdwProcessorType=(DWORD)PROCESSOR_INTEL_PENTIUMPRO;
break;
case 2:
case 3:
case 5:
*pdwProcessorType=(DWORD)PROCESSOR_INTEL_PENTIUM2;
break;
case 6:
*pdwProcessorType=(DWORD)PROCESSOR_INTEL_PENTIUMCELERON;
break;
case 7:
case 8:
*pdwProcessorType=(DWORD)PROCESSOR_INTEL_PENTIUM3;
break;
default:
*pdwProcessorType=(DWORD)PROCESSOR_UNKNOWN;
break;
}
break;
}
default:
{
*pdwProcessorType=(DWORD)PROCESSOR_UNKNOWN;
break;
}
}
}
return (TRUE);
}
BOOL COXSysInfo::IsCoProcessorPresent(BOOL* pbResult)
{
ASSERT(pbResult!=NULL);
BOOL bIsNT;
if(!IsNT(&bIsNT))
return (FALSE);
DWORD dwProcessorType;
GetProcessorType(&dwProcessorType);
// we return TRUE if we're not running on x86
// other CPUs have built in floating-point, with no registry entry
if((dwProcessorType != PROCESSOR_INTEL_386) &&
(dwProcessorType != PROCESSOR_INTEL_486) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUM))
{
*pbResult=TRUE;
}
else
{
if(!bIsNT)
{
DWORD dwFeatures=wincpufeatures();
if(dwFeatures & 0x00000001) //then CPU contains a floating-point unit (FPU)
*pbResult=TRUE;
else
*pbResult=FALSE;
}
else
{
HKEY hKey;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
_T("HARDWARE\\DESCRIPTION\\System\\FloatingPointProcessor"),
0, KEY_EXECUTE, &hKey) != ERROR_SUCCESS)
{
// GetLastError() will indicate ERROR_RESOURCE_DATA_NOT_FOUND
// if we can't find the key. This indicates no coprocessor present
*pbResult=FALSE;
}
RegCloseKey(hKey);
}
}
return TRUE;
}
BOOL COXSysInfo::GetProcessorSpeed(DWORD* pdwProcessorSpeed, int nIndex/*=0*/) const
{
ASSERT(pdwProcessorSpeed!=NULL);
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
if (!bIsNT && nIndex>0)
{
TRACE(_T("COXSysInfo::GetProcessorSpeed: Windows 95 doesn't support multiprocessor systems\n"));
return (FALSE);
}
DWORD dwSpeed=0;
if(nIndex>0 || bIsNT)
{
ASSERT(bIsNT);
// Running NT
CString sRegistryPath;
sRegistryPath.Format(_T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d"),nIndex);
HKEY hKey;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,sRegistryPath,0,KEY_READ,&hKey)!=ERROR_SUCCESS)
return (FALSE);
DWORD dwType, dwValue, dwSize;
if(RegQueryValueEx(hKey,_T("~MHz"),NULL,&dwType,(LPBYTE)&dwValue,&dwSize)!=
ERROR_SUCCESS)
return (FALSE);
ASSERT(dwType==REG_DWORD && dwSize==sizeof(DWORD));
dwSpeed=dwValue;
RegCloseKey(hKey);
}
else
{
struct FREQ_INFO CPUSpeed=cpuspeed(0);
if(CPUSpeed.in_cycles==0 && CPUSpeed.ex_ticks==0)
{
TRACE(_T("This processor cannot be accurately timed with this function.\n The processor is either an Intel Clone or is below 80386 level."));
return (FALSE);
}
dwSpeed=CPUSpeed.norm_freq;
}
enum CPUSpeed arrCPUSpeed[35];
arrCPUSpeed[0]=CPUSPEED_16;
arrCPUSpeed[1]=CPUSPEED_20;
arrCPUSpeed[2]=CPUSPEED_25;
arrCPUSpeed[3]=CPUSPEED_33;
arrCPUSpeed[4]=CPUSPEED_40;
arrCPUSpeed[5]=CPUSPEED_50;
arrCPUSpeed[6]=CPUSPEED_60;
arrCPUSpeed[7]=CPUSPEED_66;
arrCPUSpeed[8]=CPUSPEED_75;
arrCPUSpeed[9]=CPUSPEED_80;
arrCPUSpeed[10]=CPUSPEED_90;
arrCPUSpeed[11]=CPUSPEED_100;
arrCPUSpeed[12]=CPUSPEED_120;
arrCPUSpeed[13]=CPUSPEED_133;
arrCPUSpeed[14]=CPUSPEED_150;
arrCPUSpeed[15]=CPUSPEED_166;
arrCPUSpeed[16]=CPUSPEED_180;
arrCPUSpeed[17]=CPUSPEED_200;
arrCPUSpeed[18]=CPUSPEED_233;
arrCPUSpeed[19]=CPUSPEED_266;
arrCPUSpeed[20]=CPUSPEED_300;
arrCPUSpeed[21]=CPUSPEED_333;
arrCPUSpeed[22]=CPUSPEED_350;
arrCPUSpeed[23]=CPUSPEED_400;
arrCPUSpeed[24]=CPUSPEED_450;
arrCPUSpeed[25]=CPUSPEED_500;
arrCPUSpeed[26]=CPUSPEED_533;
arrCPUSpeed[27]=CPUSPEED_550;
arrCPUSpeed[28]=CPUSPEED_600;
arrCPUSpeed[29]=CPUSPEED_650;
arrCPUSpeed[30]=CPUSPEED_667;
arrCPUSpeed[31]=CPUSPEED_700;
arrCPUSpeed[32]=CPUSPEED_733;
arrCPUSpeed[33]=CPUSPEED_750;
arrCPUSpeed[34]=CPUSPEED_800;
*pdwProcessorSpeed=0;
UINT nMargin=0xffff;
UINT nNewMargin;
for(int nIterator=0; nIterator<countof(arrCPUSpeed); nIterator++)
{
nNewMargin=abs((int) (dwSpeed-arrCPUSpeed[nIterator]));
if(nNewMargin<nMargin)
{
nMargin=nNewMargin;
*pdwProcessorSpeed=arrCPUSpeed[nIterator];
}
}
if(*pdwProcessorSpeed==0)
return (FALSE);
else
return (TRUE);
}
BOOL COXSysInfo::GetTimeStamp(DWORD *pdwHigh, DWORD *pdwLow) const
{
ASSERT(pdwHigh!=NULL);
ASSERT(pdwLow!=NULL);
TIME_STAMP stamp=winrdtsc();
if(stamp.High!=0 || stamp.Low!=0)
{
*pdwHigh=stamp.High;
*pdwLow=stamp.Low;
return TRUE;
}
else
{
TRACE(_T("The primary processor doesn't support time stamp functionality"));
return FALSE;
}
}
BOOL COXSysInfo::IsMMXProcessor(BOOL* pbMMX)
{
ASSERT(pbMMX!=NULL);
DWORD dwProcessorType;
GetProcessorType(&dwProcessorType);
// relevant only to x86 processors
if((dwProcessorType != PROCESSOR_INTEL_386) &&
(dwProcessorType != PROCESSOR_INTEL_486) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUM) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUM2) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUMPRO) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUMCELERON) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUM3))
{
*pbMMX=FALSE;
}
else
{
DWORD dwFeatures=wincpufeatures();
if(dwFeatures & 0x00800000) //then MMX(TM) technology
*pbMMX=TRUE;
else
*pbMMX=FALSE;
}
return TRUE;
}
BOOL COXSysInfo::IsOverdriveProcessor(BOOL* pbOverdrive)
{
ASSERT(pbOverdrive!=NULL);
DWORD dwProcessorType;
GetProcessorType(&dwProcessorType);
// relevant only to x86 processors
if((dwProcessorType != PROCESSOR_INTEL_386) &&
(dwProcessorType != PROCESSOR_INTEL_486) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUM) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUM2) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUMPRO) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUMCELERON) &&
(dwProcessorType != PROCESSOR_INTEL_PENTIUM3))
{
*pbOverdrive=FALSE;
}
else
{
// retrieve CPUID
WORD nCPUidEx=wincpuidext();
// get processor type
if(((nCPUidEx&0x3000)>>12)==1) // if it equals 1 then it is Overdrive processor
*pbOverdrive=TRUE;
else
*pbOverdrive=FALSE;
}
return TRUE;
}
BOOL COXSysInfo::GetModemInfo(CArrayModemInfo* parrModemInfo) const
{
ASSERT(parrModemInfo!=NULL);
parrModemInfo->RemoveAll();
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
CString sRegistryPath;
HKEY hKey=NULL;
HKEY hSubKey=NULL;
BOOL bSuccess=FALSE;
if(bIsNT)
{
// Running NT
sRegistryPath.Format(_T("System\\CurrentControlSet\\Control\\Class"));
if(::RegOpenKeyEx(HKEY_LOCAL_MACHINE,sRegistryPath,0,KEY_READ,&hKey)!=
ERROR_SUCCESS)
{
TRACE(_T("COXSysInfo::GetNumModems: failed to open registry key where modem information should be located"));
return (FALSE);
}
// enumerate all subkeys
DWORD dwIndex=0;
CString sSubKeyPath;
LPTSTR lpName=sSubKeyPath.GetBuffer(MAX_PATH+1);
while(::RegEnumKey(hKey,dwIndex,lpName,MAX_PATH+1)==ERROR_SUCCESS)
{
if(::RegOpenKeyEx(hKey,sSubKeyPath,0,KEY_READ,&hSubKey)==ERROR_SUCCESS)
{
DWORD dwType, dwSize;
LPTSTR lpszValue=NULL;
if(::RegQueryValueEx(hSubKey,_T("Class"),NULL,&dwType,(LPBYTE)lpszValue,
&dwSize)==ERROR_SUCCESS)
{
ASSERT(dwType==REG_SZ);
CString sClassName;
lpszValue=sClassName.GetBuffer(dwSize/sizeof(TCHAR));
VERIFY(::RegQueryValueEx(hSubKey,_T("Class"),NULL,&dwType,
(LPBYTE)lpszValue,&dwSize)==ERROR_SUCCESS);
sClassName.ReleaseBuffer();
if(sClassName==_T("Modem"))
bSuccess=TRUE;
}
if(bSuccess)
break;
else
{
RegCloseKey(hSubKey);
hSubKey=NULL;
}
}
dwIndex++;
}
sSubKeyPath.ReleaseBuffer();
RegCloseKey(hKey);
}
else
{
// Running Windows 95/98
sRegistryPath.Format(_T("System\\CurrentControlSet\\Services\\Class\\Modem"));
if(::RegOpenKeyEx(HKEY_LOCAL_MACHINE,sRegistryPath,0,KEY_READ,&hSubKey)!=
ERROR_SUCCESS)
{
TRACE(_T("COXSysInfo::GetNumModems: failed to open registry key where modem information should be located"));
return (FALSE);
}
// enumerate all subkeys
bSuccess=TRUE;
}
if(bSuccess)
{
ASSERT(hSubKey!=NULL);
DWORD dwModemIndex=0;
CString sModemSubKeyPath;
LPTSTR lpModemName=sModemSubKeyPath.GetBuffer(_MAX_PATH+1);
while(::RegEnumKey(hSubKey,dwModemIndex,lpModemName,
(_MAX_PATH+1)*sizeof(TCHAR))==ERROR_SUCCESS)
{
HKEY hModemSubKey=NULL;
if(::RegOpenKeyEx(hSubKey,sModemSubKeyPath,0,
KEY_QUERY_VALUE,&hModemSubKey)==ERROR_SUCCESS)
{
// enumerate all values
DWORD dwIndex=0;
DWORD dwType, dwSize;
CString sValueName;
LPTSTR lpValueName=sValueName.GetBuffer(_MAX_PATH+1);
DWORD dwValueNameLength=(_MAX_PATH+1)*sizeof(TCHAR);
LPBYTE lpData=NULL;
MODEMINFO modemInfo;
BOOL bModemFound=FALSE;
while(::RegEnumValue(hModemSubKey,dwIndex,lpValueName,&dwValueNameLength,
NULL,&dwType,lpData,&dwSize)==ERROR_SUCCESS)
{
sValueName.ReleaseBuffer();
if(sValueName==_T("DeviceType"))
{
ASSERT(dwType==REG_BINARY && dwSize==1);
lpValueName=sValueName.GetBuffer(_MAX_PATH+1);
dwValueNameLength=(_MAX_PATH+1)*sizeof(TCHAR);
BYTE deviceType;
VERIFY(::RegEnumValue(hModemSubKey,dwIndex,lpValueName,
&dwValueNameLength,NULL,&dwType,&deviceType,&dwSize)==
ERROR_SUCCESS);
if(deviceType==2)
bModemFound=TRUE;
}
else if(sValueName==_T("DriverDesc"))
{
ASSERT(dwType==REG_SZ);
lpValueName=sValueName.GetBuffer(_MAX_PATH+1);
dwValueNameLength=(_MAX_PATH+1)*sizeof(TCHAR);
LPTSTR lpszDriverDesc=modemInfo.sDriverDesc.
GetBuffer(dwSize/sizeof(TCHAR));
VERIFY(::RegEnumValue(hModemSubKey,dwIndex,lpValueName,
&dwValueNameLength,NULL,&dwType,(LPBYTE)lpszDriverDesc,
&dwSize)==ERROR_SUCCESS);
modemInfo.sDriverDesc.ReleaseBuffer();
}
else if(sValueName==_T("Manufacturer"))
{
ASSERT(dwType==REG_SZ);
lpValueName=sValueName.GetBuffer(_MAX_PATH+1);
dwValueNameLength=(_MAX_PATH+1)*sizeof(TCHAR);
LPTSTR lpszManufacturer=modemInfo.sManufacturer.
GetBuffer(dwSize/sizeof(TCHAR));
VERIFY(::RegEnumValue(hModemSubKey,dwIndex,lpValueName,
&dwValueNameLength,NULL,&dwType,(LPBYTE)lpszManufacturer,
&dwSize)==ERROR_SUCCESS);
modemInfo.sManufacturer.ReleaseBuffer();
}
else if(sValueName==_T("Model"))
{
ASSERT(dwType==REG_SZ);
lpValueName=sValueName.GetBuffer(_MAX_PATH+1);
dwValueNameLength=(_MAX_PATH+1)*sizeof(TCHAR);
LPTSTR lpszModel=modemInfo.sModel.
GetBuffer(dwSize/sizeof(TCHAR));
VERIFY(::RegEnumValue(hModemSubKey,dwIndex,lpValueName,
&dwValueNameLength,NULL,&dwType,(LPBYTE)lpszModel,
&dwSize)==ERROR_SUCCESS);
modemInfo.sModel.ReleaseBuffer();
}
else if(sValueName==_T("PortSubClass"))
{
ASSERT(dwType==REG_BINARY && dwSize==1);
lpValueName=sValueName.GetBuffer(_MAX_PATH+1);
dwValueNameLength=(_MAX_PATH+1)*sizeof(TCHAR);
BYTE port;
VERIFY(::RegEnumValue(hModemSubKey,dwIndex,lpValueName,
&dwValueNameLength,NULL,&dwType,&port,&dwSize)==
ERROR_SUCCESS);
modemInfo.nPort=port;
}
lpValueName=sValueName.GetBuffer(_MAX_PATH+1);
dwValueNameLength=(_MAX_PATH+1)*sizeof(TCHAR);
dwIndex++;
}
sValueName.ReleaseBuffer();
RegCloseKey(hModemSubKey);
if(bModemFound)
parrModemInfo->Add(modemInfo);
}
dwModemIndex++;
}
RegCloseKey(hSubKey);
}
return TRUE;
}
BOOL COXSysInfo::GetNumModems(int *pnNumModems) const
{
ASSERT(pnNumModems!=NULL);
CArrayModemInfo arrModemInfo;
if(!GetModemInfo(&arrModemInfo))
return FALSE;
else
{
*pnNumModems= PtrToInt(arrModemInfo.GetSize());
return TRUE;
}
}
BOOL COXSysInfo::GetNICAddress(LPNICADDRESS pNICAddress) const
{
// --- In:
// --- Out: LPNICADDRESS pNICAddress: valid pointer to Network
// Interface Card (NIC) address
// structure
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the NIC address
// --- Comment: This function bases its functionality on the fact that
// the MAC address is part of the GUID generated on given
// machine. It also recognises the fact that on Windows 2000
// and later CoCreateGuid will return GUID, which contains
// encrypted MAC address and therefore cannot be traced back.
// On these platforms UuidCreateSequential has to be used
// to obtain the version of GUID that we expect..
ASSERT(pNICAddress!=NULL);
int nIndex;
GUID guid;
// create signature for the UuidCreateSequential function
typedef int (WINAPI* UuidCreateSequential) (UUID *Uuid);
UuidCreateSequential dUuidCreateSequential = NULL;
// attempt to open the rpcrt4.DLL
HINSTANCE hLib = NULL;
hLib = LoadLibrary(_T("rpcrt4.DLL"));
if (hLib != NULL)
{ // Loaded rpcrt4.DLL, if possible get pointer to the UuidCreateSequential method
dUuidCreateSequential = (UuidCreateSequential) GetProcAddress(hLib, "UuidCreateSequential");
if ( dUuidCreateSequential == NULL )
{ // if the UuidCreateSequential method in the rpcrt4.DLL is not found then use
// the traditional way to retrieve the GUID
if( ::CoCreateGuid( &guid ) != S_OK )
return FALSE;
}
else if( dUuidCreateSequential( &guid ) != RPC_S_OK )
return FALSE;
}
else if(::CoCreateGuid(&guid)!=S_OK)
return FALSE;
for(nIndex=0; nIndex<countof(pNICAddress->data); nIndex++)
pNICAddress->data[nIndex]=guid.Data4[nIndex+2];
for(nIndex=0; nIndex<countof(pNICAddress->data); nIndex++)
if(pNICAddress->data[nIndex]!=0)
return TRUE;
return FALSE;
}
BOOL COXSysInfo::GetFreeSystemResources(int* pnFreeResources,
enum RESOURCETYPE resourceType) const
{
ASSERT(pnFreeResources!=NULL);
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
if (bIsNT)
// We're running on NT.
return (FALSE);
HINSTANCE hLib = LoadLibrary(_T("RSRC32.dll"));
if (hLib != NULL)
{
typedef LONG (WINAPI* GETFREESYSTEMRESOURCES) (int);
GETFREESYSTEMRESOURCES pfnGetFreeSystemResources =
(GETFREESYSTEMRESOURCES) GetProcAddress(hLib, "_MyGetFreeSystemResources32@4");
ASSERT(pfnGetFreeSystemResources!=NULL);
*pnFreeResources=pfnGetFreeSystemResources((int)resourceType);
FreeLibrary(hLib);
return (TRUE);
}
else
return (FALSE);
}
// printers info
//
BOOL COXSysInfo::GetDefaultPrinterName(CString& sPrinterName) const
{
// --- In:
// --- Out: sPrinterName: reference to string to which the
// name of the default printer will be
// copied. If it is empty then there is
// default printers in the system
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the name of the default printer
// Local variables
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
sPrinterName.Empty();
if (!bIsNT)
{
LPTSTR lpszPrinterName=GetRegistryString(HKEY_CURRENT_CONFIG,
_T("SYSTEM\\CurrentControlSet\\Control\\Print\\Printers"),
_T("Default"));
if(lpszPrinterName!=NULL)
{
sPrinterName=lpszPrinterName;
::GlobalFree(lpszPrinterName);
}
}
else
{
TCHAR szTemp[MAX_PATH];
LPTSTR lpszTemp; // Get Default printer name.
GetProfileString(_T("windows"),_T("device"),_T(""),
szTemp, sizeof(szTemp));
if(lstrlen(szTemp)!=0)
{
// Terminate at first comma, just want printer name.
lpszTemp=_tcschr(szTemp,',');
if(lpszTemp!=NULL)
*lpszTemp = '\x0';
sPrinterName=(LPTSTR)szTemp;
}
}
return (TRUE);
}
BOOL COXSysInfo::GetAllPrintersName(CStringArray& arrPrinterName) const
{
// --- In:
// --- Out: sPrinterName: reference to string array to which the
// name of found printers will be copied.
// If it is empty then there is no
// printers found
//
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the name of all printers in the system.
BOOL bIsNT;
if (!IsNT(&bIsNT))
return (FALSE);
arrPrinterName.RemoveAll();
BOOL bReturnCode;
DWORD dwSize, dwPrinters, dwNeeded;
DWORD dwType=PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS;
DWORD dwLevel=(bIsNT) ? 4 : 5;
bReturnCode=::EnumPrinters(dwType,NULL,dwLevel,NULL,0,&dwSize,&dwPrinters);
// If Return Code is TRUE, there is nothing to enumerate.
if (bReturnCode)
return (TRUE);
// If LastError is any thing other than allocate size error, flag and exit.
DWORD dwErrorCode=::GetLastError();
if (dwErrorCode!=ERROR_INSUFFICIENT_BUFFER)
return (FALSE);
// Loop until we have size right.
BOOL bRightSize=FALSE;
LPBYTE lpInfo=NULL;
while(!bRightSize)
{
if(NULL!=(lpInfo=(LPBYTE)GlobalAlloc(GPTR,dwSize)))
{
#ifdef _DEBUG
::memset(lpInfo,UNINIT_BYTE,dwSize);
#endif
// Enumerate
bRightSize=EnumPrinters(dwType,NULL,dwLevel,lpInfo,dwSize,&dwNeeded,&dwPrinters);
if(!bRightSize)
{
dwErrorCode=GetLastError();
// If anything other than allocate size error, flag and exit.
if (dwErrorCode != ERROR_INSUFFICIENT_BUFFER)
{
::GlobalFree(lpInfo);
return (FALSE);
}
else
{
::GlobalFree(lpInfo);
lpInfo=NULL;
dwSize=dwNeeded;
}
}
else // EnumPrinters returned success
{
if(bIsNT)
{
// Save pointer to PRINTER_INFO structure
LPPRINTER_INFO_4 lpPrinterInfo=(LPPRINTER_INFO_4)lpInfo;
for(DWORD dwIndex=0; dwIndex<dwPrinters; dwIndex++)
arrPrinterName.
Add((LPTSTR)lpPrinterInfo[dwIndex].pPrinterName);
}
else
{
// Save pointer to PRINTER_INFO structure
LPPRINTER_INFO_5 lpPrinterInfo=(LPPRINTER_INFO_5)lpInfo;
for(DWORD dwIndex=0; dwIndex<dwPrinters; dwIndex++)
arrPrinterName.
Add((LPTSTR)lpPrinterInfo[dwIndex].pPrinterName);
}
::GlobalFree(lpInfo);
}
}
else
return (FALSE);
}
return(TRUE);
}
BOOL COXSysInfo::GetPrinterInfo(const CString& sPrinterName,
LPPRINTER_INFO_2& lpPrinterInfo) const
{
// --- In: sPrinterName: reference to string which is the
// name of installed printer.
// --- Out: lpPrinterInfo: reference to the pointer to
// PRINTER_INFO_2 structure
// that will be populated with data as
// result of execution of this function.
// You shouldn't allocate any memory.
// This function will allocate all
// necessary memory. The caller will
// be responsible for freeing that memory.
// Use GlobalFree() function in order to
// do that
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the printer info for specified printer
// installed inthe system
ASSERT(!sPrinterName.IsEmpty());
HANDLE hPrinter=NULL;
if(!::OpenPrinter((LPTSTR)(LPCTSTR)sPrinterName,&hPrinter,NULL) ||
hPrinter==NULL)
{
TRACE(_T("COXSysInfo::GetPrinterInfo: OpenPrinter() has failed\n"));
return (FALSE);
}
DWORD dwSize, dwNeeded;
if(::GetPrinter(hPrinter,2,NULL,0,&dwSize))
{
TRACE(_T("COXSysInfo::GetPrinterInfo: GetPrinter() has failed\n"));
return (FALSE);
}
// If LastError is any thing other than allocate size error, flag and exit.
DWORD dwErrorCode=::GetLastError();
if(dwErrorCode!=ERROR_INSUFFICIENT_BUFFER)
return (FALSE);
// Loop until we have size right.
BOOL bRightSize=FALSE;
LPBYTE lpInfo=NULL;
while(!bRightSize)
{
if(NULL!=(lpInfo=(LPBYTE)GlobalAlloc(GPTR,dwSize)))
{
#ifdef _DEBUG
::memset(lpInfo,UNINIT_BYTE,dwSize);
#endif
// Get Printer Info
bRightSize=::GetPrinter(hPrinter,2,lpInfo,dwSize,&dwNeeded);
if(!bRightSize)
{
dwErrorCode=GetLastError();
// If anything other than allocate size error, flag and exit.
if(dwErrorCode!=ERROR_INSUFFICIENT_BUFFER)
{
::GlobalFree(lpInfo);
return (FALSE);
}
else
{
::GlobalFree(lpInfo);
lpInfo=NULL;
dwSize=dwNeeded;
}
}
else // GetPrinter returned success
{
// Save pointer to PRINTER_INFO structure
lpPrinterInfo=(LPPRINTER_INFO_2)lpInfo;
}
}
else
return (FALSE);
}
return (TRUE);
}
BOOL COXSysInfo::IsLocalPrinter(const CString& sPrinterName,
BOOL* pbLocalPrinter) const
{
// --- In: sPrinterName: reference to string which is the
// name of installed printer.
// --- Out: pbLocalPrinter: TRUE if specified printer is local,
// or FALSE otherwise
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the flag that specify whether the printer
// is local or not
ASSERT(pbLocalPrinter!=NULL);
LPPRINTER_INFO_2 lpPrinterInfo=NULL;
if(GetPrinterInfo(sPrinterName,lpPrinterInfo) && lpPrinterInfo!=NULL)
{
*pbLocalPrinter=(lpPrinterInfo->pServerName!=NULL &&
lstrlen(lpPrinterInfo->pServerName)>0) ? FALSE : TRUE;
::GlobalFree(lpPrinterInfo);
return (TRUE);
}
return (FALSE);
}
BOOL COXSysInfo::IsSharedPrinter(const CString& sPrinterName,
BOOL* pbSharedPrinter) const
{
// --- In: sPrinterName: reference to string which is the
// name of installed printer.
// --- Out: pbSharedPrinter:TRUE if specified printer is shared,
// or FALSE otherwise
// --- Returns: BOOL - TRUE if success
// --- Effect: Retrieves the flag that specify whether the printer
// is shared or not
ASSERT(pbSharedPrinter!=NULL);
LPPRINTER_INFO_2 lpPrinterInfo=NULL;
if(GetPrinterInfo(sPrinterName,lpPrinterInfo) && lpPrinterInfo!=NULL)
{
*pbSharedPrinter=((lpPrinterInfo->
Attributes&PRINTER_ATTRIBUTE_SHARED)!=0 &&
lpPrinterInfo->pShareName!=NULL &&
lstrlen(lpPrinterInfo->pShareName)>0) ? TRUE : FALSE;
::GlobalFree(lpPrinterInfo);
return (TRUE);
}
return (FALSE);
}
// protected
int COXSysInfo::DeviceCaps(int iIndex) const
{
int iValue;
HDC hDC = CreateIC(_T("DISPLAY"), NULL, NULL, NULL);
ASSERT(hDC != NULL);
iValue = GetDeviceCaps(hDC, iIndex);
DeleteDC(hDC);
return (iValue);
}
void COXSysInfo::GetMemStatus()
{
m_memStatus.dwLength = sizeof(m_memStatus);
GlobalMemoryStatus(&m_memStatus);
}
void COXSysInfo::GetSysInfo()
{
::GetSystemInfo(&m_sysInfo);
}
LPTSTR COXSysInfo::GetRegistryString(HKEY hKeyClass, LPTSTR lpszSubKey,
LPTSTR lpszValueName) const
{
// Local variables
HKEY hKey=NULL; // Registry key
LPTSTR lpszKeyValue; // Buffer for key name
DWORD dwKeySize=0; // Size of key value
DWORD dwKeyDataType=0; // Type of data stored in key
if(ERROR_SUCCESS!=RegOpenKey(hKeyClass, lpszSubKey, &hKey))
return NULL;
// Got key, get value. First, get the size of the key.
if(ERROR_SUCCESS!=RegQueryValueEx(hKey,lpszValueName,
NULL,NULL,NULL,&dwKeySize))
return NULL;
if(dwKeySize <= 1)
return NULL;
lpszKeyValue=(LPTSTR)GlobalAlloc(GPTR,(++dwKeySize));
if(lpszKeyValue==NULL)
return NULL;
RegQueryValueEx(hKey,lpszValueName,NULL,&dwKeyDataType,
(LPBYTE)lpszKeyValue,&dwKeySize);
// it's caller responsibility to free the memory allocated for lpszKeyValue
return lpszKeyValue;
}
// static
// Sort all of the display modes:
// 1: Resolution (width), 2: color depth, 3: frequency.
int _cdecl DevModeCompare(const void *elem1, const void *elem2)
{
ASSERT(elem1!=NULL);
ASSERT(elem2!=NULL);
PDEVMODE pdvmd1=(PDEVMODE)elem1;
PDEVMODE pdvmd2=(PDEVMODE)elem2;
int nResult=pdvmd1->dmPelsWidth-pdvmd2->dmPelsWidth;
if(nResult!=0)
return (nResult);
nResult=pdvmd1->dmBitsPerPel-pdvmd2->dmBitsPerPel;
if(nResult!=0)
return (nResult);
nResult=pdvmd1->dmDisplayFrequency-pdvmd2->dmDisplayFrequency;
return(nResult);
}
#endif // _WIN64