Skip to content

Commit

Permalink
Allow osver to indicate the edition of the system in use
Browse files Browse the repository at this point in the history
  • Loading branch information
malxau committed Jan 20, 2021
1 parent 22e7fe6 commit b2a884d
Show file tree
Hide file tree
Showing 5 changed files with 397 additions and 27 deletions.
30 changes: 29 additions & 1 deletion lib/dyld.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Yori dynamically loaded OS function support
*
* Copyright (c) 2018-2019 Malcolm J. Smith
* Copyright (c) 2018-2021 Malcolm J. Smith
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -638,6 +638,34 @@ YoriLibLoadVirtDiskFunctions(VOID)
return TRUE;
}

/**
A structure containing pointers to winbrand.dll functions that can be used if
they are found but programs do not have a hard dependency on.
*/
YORI_WINBRAND_FUNCTIONS DllWinBrand;

/**
Load pointers to all optional WinBrand.dll functions.
@return TRUE to indicate success, FALSE to indicate failure.
*/
BOOL
YoriLibLoadWinBrandFunctions(VOID)
{

if (DllWinBrand.hDll != NULL) {
return TRUE;
}

DllWinBrand.hDll = YoriLibLoadLibraryFromSystemDirectory(_T("WINBRAND.DLL"));
if (DllWinBrand.hDll == NULL) {
return FALSE;
}

DllWinBrand.pBrandingFormatString = (PBRANDING_FORMAT_STRING)GetProcAddress(DllWinBrand.hDll, "BrandingFormatString");
return TRUE;
}

/**
A structure containing pointers to wininet.dll functions that can be used if
they are found but programs do not have a hard dependency on.
Expand Down
148 changes: 148 additions & 0 deletions lib/osver.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,154 @@ YoriLibGetOsVersion(
*BuildNumber = LocalBuildNumber;
}

/**
Return the OS edition as a string. On newer systems this is obtained
directly from the system's branding provider, on older systems it needs to
be emulated, and on really old systems it's just a string literal.
@param Edition On successful completion, updated to contain a newly allocated
string containing the system edition.
@return TRUE to indicate success, FALSE to indicate failure.
*/
__success(return)
BOOL
YoriLibLoadOsEdition(
__out PYORI_STRING Edition
)
{
YORI_OS_VERSION_INFO_EX OsVersionInfoEx;
LPWSTR BrandingString;
DWORD Length;

YoriLibLoadWinBrandFunctions();

//
// If the operating system supports asking for its brand, use that.
// This should exist on Vista+.
//

if (DllWinBrand.pBrandingFormatString != NULL) {
BrandingString = DllWinBrand.pBrandingFormatString(L"%WINDOWS_LONG%");
if (BrandingString == NULL) {
return FALSE;
}

Length = wcslen(BrandingString);

if (!YoriLibAllocateString(Edition, Length + 1)) {
return FALSE;
}

Edition->LengthInChars = YoriLibSPrintf(Edition->StartOfString, _T("%s"), BrandingString);
GlobalFree(BrandingString);
return TRUE;
}

//
// Query the suite mask and system version. This should only be needed
// for systems that predate version lies, so this can be a little
// careless.
//

OsVersionInfoEx.Core.dwOsVersionInfoSize = sizeof(OsVersionInfoEx);
if (DllKernel32.pGetVersionExW == NULL ||
!DllKernel32.pGetVersionExW(&OsVersionInfoEx.Core)) {
BrandingString = _T("Windows NT");
} else {
DWORD WinVer;

WinVer = OsVersionInfoEx.Core.dwMajorVersion << 16 | OsVersionInfoEx.Core.dwMinorVersion;

switch(WinVer) {
case 0x40000:
if (OsVersionInfoEx.wSuiteMask & VER_SUITE_SMALLBUSINESS ||
OsVersionInfoEx.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED) {
BrandingString = _T("Small Business Server 4.x");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_ENTERPRISE) {
BrandingString = _T("Windows NT 4.0 Enterprise Edition");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_BACKOFFICE) {
BrandingString = _T("BackOffice Server 4.x");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_TERMINAL) {
BrandingString = _T("Windows NT 4.0 Terminal Server Edition");
} else if (OsVersionInfoEx.wProductType == VER_NT_SERVER ||
OsVersionInfoEx.wProductType == VER_NT_DOMAIN_CONTROLLER) {
BrandingString = _T("Windows NT 4.0 Server");
} else if (OsVersionInfoEx.wProductType == VER_NT_WORKSTATION) {
BrandingString = _T("Windows NT 4.0 Workstation");
} else {
BrandingString = _T("Windows NT 4.0 Unknown");
}
break;
case 0x50000:
if (OsVersionInfoEx.wSuiteMask & VER_SUITE_SMALLBUSINESS ||
OsVersionInfoEx.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED) {
BrandingString = _T("Small Business Server 2000");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_ENTERPRISE) {
BrandingString = _T("Windows 2000 Advanced Server");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_DATACENTER) {
BrandingString = _T("Windows 2000 DataCenter Server");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_BACKOFFICE) {
BrandingString = _T("BackOffice 2000");
} else if (OsVersionInfoEx.wProductType == VER_NT_SERVER ||
OsVersionInfoEx.wProductType == VER_NT_DOMAIN_CONTROLLER) {
BrandingString = _T("Windows 2000 Server");
} else if (OsVersionInfoEx.wProductType == VER_NT_WORKSTATION) {
BrandingString = _T("Windows 2000 Professional");
} else {
BrandingString = _T("Windows 2000 Unknown");
}
break;
case 0x50001:
if (OsVersionInfoEx.wSuiteMask & VER_SUITE_EMBEDDEDNT) {
BrandingString = _T("Windows XP Embedded");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_PERSONAL) {
BrandingString = _T("Windows XP Home");
} else {
BrandingString = _T("Windows XP Professional");
}
break;
case 0x50002:
if (OsVersionInfoEx.wSuiteMask & VER_SUITE_SMALLBUSINESS ||
OsVersionInfoEx.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED) {
BrandingString = _T("Small Business Server 2003");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_ENTERPRISE) {
BrandingString = _T("Windows Server 2003 Enterprise Edition");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_DATACENTER) {
BrandingString = _T("Windows Server 2003 Datacenter Edition");
} else if (OsVersionInfoEx.wSuiteMask & VER_SUITE_BLADE) {
BrandingString = _T("Windows Server 2003 Web Edition");
} else if (OsVersionInfoEx.wProductType == VER_NT_SERVER ||
OsVersionInfoEx.wProductType == VER_NT_DOMAIN_CONTROLLER) {
BrandingString = _T("Windows Server 2003");
} else if (OsVersionInfoEx.wProductType == VER_NT_WORKSTATION) {
BrandingString = _T("Windows XP 64 bit edition");
} else {
BrandingString = _T("Windows Server 2003 Unknown");
}
break;
default:

//
// WinBrand.dll should be available on Vista+, and SuiteMask
// is not available before NT 4.0 SP6, so this fallback
// should be somewhat accurate.
//

BrandingString = _T("Unknown Windows");
break;
}
}

YoriLibInitEmptyString(Edition);
YoriLibYPrintf(Edition, _T("%s"), BrandingString);
if (Edition->StartOfString == NULL) {
return FALSE;
}

return TRUE;
}

/**
Return TRUE to indicate the target process is 32 bit, or FALSE if the target
process is 64 bit.
Expand Down
172 changes: 171 additions & 1 deletion lib/yoricmpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Yori shell header file to define OS things that the compilation environment
* doesn't support.
*
* Copyright (c) 2017-2020 Malcolm J. Smith
* Copyright (c) 2017-2021 Malcolm J. Smith
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -1091,6 +1091,143 @@ typedef struct _YORI_OS_VERSION_INFO {
TCHAR szCSDVersion[128];
} YORI_OS_VERSION_INFO, *PYORI_OS_VERSION_INFO;

/**
An implementation of the OSVERSIONINFOEX structure.
*/
typedef struct _YORI_OS_VERSION_INFO_EX {

/**
The base form of this structure.
*/
YORI_OS_VERSION_INFO Core;

/**
On successful completion, the service pack major version.
*/
WORD wServicePackMajor;

/**
On successful completion, the service pack minor version.
*/
WORD wServicePackMinor;

/**
On successful completion, a set of capability flags indicating the
capabilities of the edition.
*/
WORD wSuiteMask;

/**
On successful completion, indicates the broad class of product.
*/
BYTE wProductType;

/**
Reserved for future use.
*/
BYTE wReserved;
} YORI_OS_VERSION_INFO_EX, *PYORI_OS_VERSION_INFO_EX;

#ifndef VER_SUITE_SMALLBUSINESS
/**
Definition of the suite mask flag for small business server for compilation
environments which don't provide it.
*/
#define VER_SUITE_SMALLBUSINESS 0x0001
#endif

#ifndef VER_SUITE_ENTERPRISE
/**
Definition of the suite mask flag for enterprise edition for compilation
environments which don't provide it.
*/
#define VER_SUITE_ENTERPRISE 0x0002
#endif

#ifndef VER_SUITE_BACKOFFICE
/**
Definition of the suite mask flag for backoffice server for compilation
environments which don't provide it.
*/
#define VER_SUITE_BACKOFFICE 0x0004
#endif

#ifndef VER_SUITE_TERMINAL
/**
Definition of the suite mask flag for terminal server for compilation
environments which don't provide it.
*/
#define VER_SUITE_TERMINAL 0x0010
#endif

#ifndef VER_SUITE_SMALLBUSINESS_RESTRICTED
/**
Definition of the suite mask flag for small business server for compilation
environments which don't provide it.
*/
#define VER_SUITE_SMALLBUSINESS_RESTRICTED 0x0020
#endif

#ifndef VER_SUITE_EMBEDDEDNT
/**
Definition of the suite mask flag for embedded for compilation environments
which don't provide it.
*/
#define VER_SUITE_EMBEDDEDNT 0x0040
#endif

#ifndef VER_SUITE_DATACENTER
/**
Definition of the suite mask flag for datacenter server for compilation
environments which don't provide it.
*/
#define VER_SUITE_DATACENTER 0x0080
#endif

#ifndef VER_SUITE_PERSONAL
/**
Definition of the suite mask flag for home edition for compilation
environments which don't provide it.
*/
#define VER_SUITE_PERSONAL 0x0200
#endif

#ifndef VER_SUITE_BLADE
/**
Definition of the suite mask flag for web server for compilation environments
which don't provide it.
*/
#define VER_SUITE_BLADE 0x0400
#endif

#ifndef VER_NT_WORKSTATION
/**
Definition of the product type flag for a workstation for compilation
environments which don't provide it.
*/
#define VER_NT_WORKSTATION 0x0001
#endif

#ifndef VER_NT_DOMAIN_CONTROLLER
/**
Definition of the product type flag for a domain controller for compilation
environments which don't provide it.
*/
#define VER_NT_DOMAIN_CONTROLLER 0x0002
#endif

#ifndef VER_NT_SERVER
/**
Definition of the product type flag for a server for compilation environments
which don't provide it.
*/
#define VER_NT_SERVER 0x0003
#endif





/**
Output from the GetSystemInfo system call. This is defined here so that it
can contain newer fields than older compilers include, which may be returned
Expand Down Expand Up @@ -7471,6 +7608,39 @@ typedef struct _YORI_VIRTDISK_FUNCTIONS {

extern YORI_VIRTDISK_FUNCTIONS DllVirtDisk;

/**
A prototype for the BrandingFormatString function.
*/
typedef
LPWSTR WINAPI
BRANDING_FORMAT_STRING(LPCWSTR);

/**
A prototype for a pointer to the BrandingFormatString function.
*/
typedef BRANDING_FORMAT_STRING *PBRANDING_FORMAT_STRING;

/**
A structure containing optional function pointers to winbrand.dll exported
functions which programs can operate without having hard dependencies on.
*/
typedef struct _YORI_WINBRAND_FUNCTIONS {

/**
A handle to the Dll module.
*/
HINSTANCE hDll;

/**
If it's available on the current system, a pointer to
BrandingFormatString.
*/
PBRANDING_FORMAT_STRING pBrandingFormatString;

} YORI_WINBRAND_FUNCTIONS, *PYORI_WINBRAND_FUNCTIONS;

extern YORI_WINBRAND_FUNCTIONS DllWinBrand;

/**
A prototype for the InternetOpenA function.
*/
Expand Down
Loading

0 comments on commit b2a884d

Please sign in to comment.