📄 dtwinver.cpp
字号:
HMODULE hKernel = GetModuleHandle("KERNEL");
if (hKernel == NULL)
return FALSE;
// Dynamically link to the functions we want, setting the capability
// bits as needed
LoadLibraryEx32W = (lpfnLoadLibraryEx32W) GetProcAddress(hKernel, "LoadLibraryEx32W");
if (LoadLibraryEx32W)
dwCapBits |= WOW_LOADLIBRARY;
FreeLibrary32W = (lpfnFreeLibrary32W) GetProcAddress(hKernel, "FreeLibrary32W");
if (FreeLibrary32W)
dwCapBits |= WOW_FREELIBRARY;
GetProcAddress32W = (lpfnGetProcAddress32W) GetProcAddress(hKernel, "GetProcAddress32W");
if (GetProcAddress32W)
dwCapBits |= WOW_GETPROCADDRESS;
GetVDMPointer32W = (lpfnGetVDMPointer32W) GetProcAddress(hKernel, "GetVDMPointer32W");
if (GetVDMPointer32W)
dwCapBits |= WOW_VDMPTR32;
CallProc32W = (lpfnCallProc32W) GetProcAddress(hKernel, "CallProc32W");
if (CallProc32W)
dwCapBits |= WOW_CALLPROC;
//Call thro' the thunk to the Win32 function "GetVersionEx"
HINSTANCE32 hInstKrnl32 = WOWLoadLibraryEx32("KERNEL32.DLL", NULL, NULL);
//Because we are building the call to the function at runtime, We don't
//forget to include the A at the end to call the ASCII version of GetVersionEx
FARPROC lpfnWin32GetVersionEx = WOWGetProcAddress32(hInstKrnl32, "GetVersionExA");
if (lpfnWin32GetVersionEx)
{
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
DWORD dwSuccess = WOWCallProc32(lpfnWin32GetVersionEx, PARAM_01, 1, (LPOSVERSIONINFO) &osvi);
if (dwSuccess)
{
lpVersionInformation->dwUnderlyingMajorVersion = osvi.dwMajorVersion;
lpVersionInformation->dwUnderlyingMinorVersion = osvi.dwMinorVersion;
lpVersionInformation->dwUnderlyingBuildNumber = LOWORD(osvi.dwBuildNumber); //ignore HIWORD
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, osvi.szCSDVersion);
//Explicitely map the win32 dwPlatformId to our own values
if (osvi.dwPlatformId == VER_PLATFORM_WIN32s)
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_WIN32S;
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_WINDOWS;
//Deterine the Win9x Service pack installed
if (IsWindows95SP1(lpVersionInformation))
{
lpVersionInformation->wEmulatedServicePack = 1;
lpVersionInformation->wUnderlyingServicePack = 1;
}
else if (IsWindows95OSR2(lpVersionInformation))
{
lpVersionInformation->wEmulatedServicePack = 2;
lpVersionInformation->wUnderlyingServicePack = 2;
}
else if (IsWindows98SP1(lpVersionInformation))
{
lpVersionInformation->wEmulatedServicePack = 1;
lpVersionInformation->wUnderlyingServicePack = 1;
}
}
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_NT_WORKSTATION; //As a default assume NT Workstation
//Determine the NT Service pack from the OSVI structure string. This saves
//having to call the Win32 registry api through a generic thunk
if (strlen(osvi.szCSDVersion))
{
//Parse out the CSDVersion string
int i=0;
while (osvi.szCSDVersion[i] != ('\0') && !isdigit(osvi.szCSDVersion[i]))
i++;
lpVersionInformation->wEmulatedServicePack = (WORD) (atoi(&osvi.szCSDVersion[i]));
lpVersionInformation->wUnderlyingServicePack = lpVersionInformation->wEmulatedServicePack;
}
}
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_CE)
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_WINDOWS_CE;
else
return FALSE;
bFoundUnderlyingOS = TRUE;
}
}
else
{
//We failed to get GetVersionEx so try to GetVersion instead. We known that we must be on
//Windows NT 3.5 or earlier since anything released later by MS had this function.
FARPROC lpfnWin32GetVersion = WOWGetProcAddress32(hInstKrnl32, "GetVersion");
if (lpfnWin32GetVersion)
{
DWORD dwVersion = WOWCallProc32(lpfnWin32GetVersion, 0, 0);
lpVersionInformation->dwUnderlyingMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwUnderlyingMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwUnderlyingBuildNumber = 0;
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_NT_WORKSTATION;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "");
bFoundUnderlyingOS = TRUE;
}
}
WOWFreeLibrary32(hInstKrnl32);
if (!bFoundUnderlyingOS)
{
//must be running on a real version of 16 bit Windows whose underlying OS is DOS
lpVersionInformation->dwUnderlyingMajorVersion = HIBYTE(HIWORD(dwVersion));
lpVersionInformation->dwUnderlyingMinorVersion = LOBYTE(HIWORD(dwVersion));
lpVersionInformation->dwUnderlyingBuildNumber = 0;
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_DOS;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "Dos");
}
#else //Must be some version of real or emulated Dos
//Retreive the current version of emulated dos
BYTE DosMinor;
BYTE DosMajor;
_asm
{
mov ax, 3306h
int 21h
mov byte ptr [DosMajor], bl
mov byte ptr [DosMinor], bh
}
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_DOS;
lpVersionInformation->dwEmulatedMajorVersion = (DWORD) DosMajor;
lpVersionInformation->dwEmulatedMinorVersion = (DWORD) DosMinor;
lpVersionInformation->dwEmulatedBuildNumber = 0; //no build number with Dos
//We can detect if NT is running as it reports Dos v5.5
if ((lpVersionInformation->dwEmulatedMajorVersion == 5) &&
(lpVersionInformation->dwEmulatedMinorVersion == 50)) //NT reports Dos v5.5
{
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "Microsoft Windows NT");
//could not find method of determing version of NT from Dos,
//so assume 3.50
lpVersionInformation->dwUnderlyingMajorVersion = 3;
lpVersionInformation->dwUnderlyingMinorVersion = 50;
lpVersionInformation->dwUnderlyingBuildNumber = 0; //cannot get access to build number from Dos
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_NT_WORKSTATION;
}
else
{
//Get the underlying OS here via the int 2FH interface of Windows
GetWinInfo();
if (bRunningWindows)
{
if (lpVersionInformation->dwEmulatedMajorVersion >= 7) //Windows 95/98 marks itself as Dos 7
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_WINDOWS;
else
{
//Could not find method of differentiating between WFW & Win3.1 under Dos,
//so assume Win3.1
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_WINDOWS31;
}
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "Microsoft Windows");
lpVersionInformation->dwUnderlyingMajorVersion = (WinVer & 0xFF00) >> 8;
lpVersionInformation->dwUnderlyingMinorVersion = WinVer & 0x00FF;
if (lpVersionInformation->dwEmulatedMinorVersion == 0)
lpVersionInformation->dwUnderlyingBuildNumber = 950; //Windows 95 Gold reports Dos v7.0
else if (lpVersionInformation->dwUnderlyingMinorVersion > 0 &&
lpVersionInformation->dwUnderlyingMinorVersion < 3)
{
//Testing for 95 SP1 has not been done, so the above check
//may or may not be work
lpVersionInformation->dwUnderlyingBuildNumber = 1080;
}
else if (lpVersionInformation->dwUnderlyingMinorVersion == 3)
lpVersionInformation->dwUnderlyingBuildNumber = 1212; //Windows 95 OSR2 reports Windows 4.03 from 16 bit code
else if (lpVersionInformation->dwUnderlyingMinorVersion <= 10)
lpVersionInformation->dwUnderlyingBuildNumber = 1998; //Otherwise must be Windows 98
else
{
//Need to get the Build number of 98 SE
}
}
else //must be on a real version of Dos
{
lpVersionInformation->dwUnderlyingMajorVersion = (DWORD) DosMajor;
lpVersionInformation->dwUnderlyingMinorVersion = (DWORD) DosMinor;
lpVersionInformation->dwUnderlyingBuildNumber = 0; //no build number with Dos
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_DOS;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "MS-DOS");
}
}
#endif
#endif
return TRUE;
}
#if defined(_WIN32) && !defined(UNDER_CE)
BOOL WhichNTProduct(DWORD& dwVersion)
{
HKEY hKey;
if (RegOpenKey(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\ProductOptions"), &hKey) != ERROR_SUCCESS)
return FALSE;
const int MY_BUFSIZE = 100;
TCHAR szProductType[MY_BUFSIZE];
DWORD dwBufLen = MY_BUFSIZE * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("ProductType"), NULL, NULL, (LPBYTE) szProductType, &dwBufLen) != ERROR_SUCCESS)
return FALSE;
RegCloseKey(hKey);
BOOL bSuccess = FALSE;
// check product options, in order of likelihood
if (_tcsicmp(_T("WINNT"), szProductType) == 0)
{
dwVersion = PLATFORM_NT_WORKSTATION;
bSuccess = TRUE;
}
else if (_tcsicmp(_T("SERVERNT"), szProductType) == 0)
{
dwVersion = PLATFORM_NT_STAND_ALONE_SERVER;
bSuccess = TRUE;
}
else if (_tcsicmp(_T("LANMANNT"), szProductType) == 0)
{
dwVersion = PLATFORM_NT_PRIMARY_DOMAIN_CONTROLLER;
bSuccess = TRUE;
}
else if (_tcsicmp(_T("LANSECNT"), szProductType) == 0)
{
dwVersion = PLATFORM_NT_BACKUP_DOMAIN_CONTROLLER;
bSuccess = TRUE;
}
return bSuccess;
}
#endif
#if defined(_WINDOWS) && !defined(_WIN32)
UINT WINAPI WOWCreateVDMPointer16(DWORD dwLinBase, DWORD dwLimit)
{
UINT uSelector, uDSSel;
if (!(dwCapBits & WOW_VDMPTR16))
return NULL;
// Grab our DS (for access rights)
__asm mov uDSSel, ds
// Allocate a new selector
uSelector = AllocSelector(uDSSel);
if (uSelector)
{
// Assign its linear base address and limit
SetSelectorBase(uSelector, dwLinBase);
SetSelectorLimit(uSelector, dwLimit);
}
return uSelector;
}
UINT WINAPI WOWDeleteVDMPointer16(UINT uSelector)
{
if (!(dwCapBits & WOW_VDMPTR16))
return NULL;
return FreeSelector(uSelector);
}
HWND32 WINAPI WOWHwndToHwnd32(HWND hWnd)
{
if (!(dwCapBits & WOW_HWND32))
return NULL;
// OR mask the upper 16 bits
HWND32 hWnd32 = (HWND32) (WORD) (hWnd);
return (hWnd32 | 0xffff0000);
}
HINSTANCE32 WINAPI WOWLoadLibraryEx32(LPSTR lpszFile, HFILE32 hFile,
DWORD dwFlags)
{
if (!(dwCapBits & WOW_LOADLIBRARY))
return NULL;
return LoadLibraryEx32W(lpszFile, hFile, dwFlags);
}
BOOL WINAPI WOWFreeLibrary32(HINSTANCE32 hInst32)
{
if (!(dwCapBits & WOW_FREELIBRARY))
return NULL;
return FreeLibrary32W(hInst32);
}
FARPROC WINAPI WOWGetProcAddress32(HINSTANCE32 hInst32,
LPCSTR lpszProc)
{
if (!(dwCapBits & WOW_GETPROCADDRESS))
return NULL;
return GetProcAddress32W(hInst32, lpszProc);
}
DWORD WINAPI WOWGetVDMPointer32(LPVOID lpAddress, UINT fMode)
{
if (!(dwCapBits & WOW_VDMPTR32))
return NULL;
return GetVDMPointer32W(lpAddress, fMode);
}
DWORD FAR CDECL WOWCallProc32(FARPROC lpfnFunction, DWORD dwAddressConvert, DWORD dwParams, ...)
{
va_list vaList;
DWORD dwCount;
DWORD dwTemp;
if (!(dwCapBits & WOW_CALLPROC))
return NULL;
// Variable list start
va_start(vaList,dwParams);
for(dwCount=0; dwCount < dwParams; dwCount++)
{
// Pull each variable off of the stack
dwTemp=(DWORD)va_arg(vaList,DWORD);
// Push the DWORD
__asm push word ptr [dwTemp+2];
__asm push word ptr [dwTemp];
}
// Variable list end
va_end(vaList);
// Call Win32. The pushed variable list precedes the parameters.
// Appropriate parameters will be popped by this function (based
// on the value in dwParams)
return CallProc32W(lpfnFunction, dwAddressConvert, dwParams);
}
BOOL WFWLoaded()
{
const WORD WNNC_NET_MultiNet = 0x8000;
const WORD WNNC_SUBNET_WinWorkgroups = 0x0004;
const WORD WNNC_NET_TYPE = 0x0002;
BOOL rVal;
HINSTANCE hUserInst = LoadLibrary("USER.EXE");
lpfnWNetGetCaps lpWNetGetCaps = (lpfnWNetGetCaps) GetProcAddress(hUserInst, "WNetGetCaps");
if (lpWNetGetCaps != NULL)
{
// Get the network type
WORD wNetType = lpWNetGetCaps(WNNC_NET_TYPE);
if (wNetType & WNNC_NET_MultiNet)
{
// a multinet driver is installed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -