Function for getting operating system.

I found this function at: http://msdn.microsoft.com/en-us/library/ms724429%28v=vs.85%29.aspx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <windows.h>
#include <string>
#include <sstream>
#include <iostream>

using namespace std;

typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
#define PRODUCT_PROFESSIONAL	0x00000030
#define VER_SUITE_WH_SERVER	0x00008000



bool windowsVersionName(wchar_t* str, int bufferSize)
{
    OSVERSIONINFOEX osvi;
    SYSTEM_INFO si;
    BOOL bOsVersionInfoEx;
    DWORD dwType; ZeroMemory(&si, sizeof(SYSTEM_INFO));
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);
    if(bOsVersionInfoEx == 0)
        return false; // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
    PGNSI pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
    if(NULL != pGNSI)
        pGNSI(&si);
    else GetSystemInfo(&si); // Check for unsupported OS
    if (VER_PLATFORM_WIN32_NT != osvi.dwPlatformId || osvi.dwMajorVersion <= 4 )
        return false;

    //std::wstringstream os;
    std::stringstream os;


    os << L"Microsoft "; // Test for the specific product. if ( osvi.dwMajorVersion == 6 )
        {
            if( osvi.dwMinorVersion == 0 )
                {
                    if( osvi.wProductType == VER_NT_WORKSTATION )
                        os << "Windows Vista ";
                    else os << "Windows Server 2008 ";
                }
            if ( osvi.dwMinorVersion == 1 )
                {
                    if( osvi.wProductType == VER_NT_WORKSTATION )
                        os << "Windows 7 ";
                    else os << "Windows Server 2008 R2 ";
                }
            PGPI pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
            pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
            cout << "dwType = " << dwType << endl;
            /*switch( dwType )
                {
                    case PRODUCT_ULTIMATE:
                    //the rest of the switch statement would have went here. 


            */
                }
    if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
        {
            if( GetSystemMetrics(SM_SERVERR2) )
                os <<  "Windows Server 2003 R2, ";
            else if ( osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER )
                os <<  "Windows Storage Server 2003";
            else if ( osvi.wSuiteMask & VER_SUITE_WH_SERVER )
                os <<  "Windows Home Server";
            else if( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
                {
                    os <<  "Windows XP Professional x64 Edition";
                }
            else os << "Windows Server 2003, ";  // Test for the server type.
            if ( osvi.wProductType != VER_NT_WORKSTATION )
                {
                    if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )
                        {
                            if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
                                os <<  "Datacenter Edition for Itanium-based Systems";
                            else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
                                os <<  "Enterprise Edition for Itanium-based Systems";
                        }
                    else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
                        {
                            if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
                                os <<  "Datacenter x64 Edition";
                            else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
                                os <<  "Enterprise x64 Edition";
                            else os <<  "Standard x64 Edition";
                        }
                    else
                        {
                            if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
                                os <<  "Compute Cluster Edition";
                            else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
                                os <<  "Datacenter Edition";
                            else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
                                os <<  "Enterprise Edition";
                            else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
                                os <<  "Web Edition";
                            else os <<  "Standard Edition";
                        }
                }
        }
    if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
        {
            os << "Windows XP ";
            if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
                os <<  "Home Edition";
            else os <<  "Professional";
        }
    if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
        {
            os << "Windows 2000 ";
            if ( osvi.wProductType == VER_NT_WORKSTATION )
                {
                    os <<  "Professional";
                }
            else
                {
                    if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
                        os <<  "Datacenter Server";
                    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
                        os <<  "Advanced Server";
                    else os <<  "Server";
                }
        }  // Include service pack (if any) and build number.
//    if(wcslen(osvi.szCSDVersion) > 0)   debugging important
        {
            os << " " << osvi.szCSDVersion;
        }
    os << L" (build " << osvi.dwBuildNumber << L")";
    if ( osvi.dwMajorVersion >= 6 )
        {
            if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
                os <<  ", 64-bit";
            else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
                os << ", 32-bit";
        }
//    wcscpy_s(str, bufferSize, os.str().c_str());    
    cout << os.str().c_str() << endl;
    return true;
}


int main()
{
    wchar_t* winstr; int buffer = 0;
    //cout << windowsVersionName(wchar_t* str, int bufferSize)
    cout << windowsVersionName(winstr, buffer);
    return 0;
}

Not only did I have to comment out the switch statement, I also had to comment out lines 128 and 140, because they would not compile. I had to totally reformat the code to because it was not readable (not in any whatchamacallit recognizable programming format. )

The way it is now it outputs:

dwType = 4
0x446022Windows 7 0x44627876010x44628a, 32-bit
1

Anyone know where the probably enums for PRODUCT_ULTIMATE would be defined?

Or anyone know where the functions wscpy_s()

or what can I do to if(wcslen(osvi.szCSDVersion) > 0)?

ps: I also had to change:
1
2
//std::wstringstream os;   
std::stringstream os;
Last edited on
edit: I also found this function much nicer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <windows.h>
#include <stdio.h>

int main()
{
    OSVERSIONINFO osvi;
    BOOL bIsWindowsXPorLater;

    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    GetVersionEx(&osvi);

    bIsWindowsXPorLater =
       ( (osvi.dwMajorVersion > 5) ||
       ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));

    if(bIsWindowsXPorLater)
        printf("The system meets the requirements.\n");
    else printf("The system does not meet the requirements.\n");
}

main was originally void. Why or why is there so much outdated code on msdn.microsoft.com?
what i'm trying to do is check to see if I can run in full screen mode, because for some annoying reason windows 7, and i think vista also have disabled this feature and I don't want users to have to see the warning that 'full screen mode' is disabled on that OS.

Isn't there a way to run the console program in full screen mode anyway even if the OS doesn't support it?

Please note: I'm assuming that readers will paraphrase that last question into their own words so that it won't sound silly.
Anyone know where the probably enums for PRODUCT_ULTIMATE would be defined?


Yes, in a Windows header. It is returned by GetProductInfo(), so naturally you can find them explained in the function's page @ MSDN Online: http://msdn.microsoft.com/en-us/library/ms724358(VS.85).aspx . Note that this function is available for Windows Vista and above only. This means you need to #define _WIN32_WINNT to 0x0600, if I recall correctly. Otherwise the Windows header will not include the function definition, and maybe not even the constants. This is why the code you found calls this function via a function pointer: So the same binary can be used in earlier OS's and so it doesn't fail to load.

Or anyone know where the functions wscpy_s()


Assuming you meant wcscpy_s(), here: http://msdn.microsoft.com/en-us/library/td1esda9(VS.80).aspx . I think this function might be Microsoft-specific. Not sure.

or what can I do to if(wcslen(osvi.szCSDVersion) > 0)?


What do you mean with "what can I do"? MSDN Online (http://msdn.microsoft.com/en-us/library/ms724833(VS.85).aspx) states clearly that if its length is greater than zero, a service pack is installed and the contents of the string represent the latest one. Do you want to do something else with this? Display it on screen? Go for it. Unless that is, I misunderstood.


ps: I also had to change:
1
2
//std::wstringstream os;
std::stringstream os;


Unfortunately, you'll find many ill-written code out there. You had to switch because you are compiling for ANSI, not Unicode. The code sample I suppose assumes that you are compiling for Unicode.

@Everyone that says code like this is correct: See what Disch and I mean when we say the following?

MessageBox() takes macro-enclosed string literals and TCHAR pointers.
MessageBoxA() takes simple string literals and char pointers.
MessageBoxW() takes L-prepended string literals and wchar_t pointers.

ANY OTHER COMBINATION IS INCORRREEEEEEECTTTT.


Example: http://www.cplusplus.com/forum/windows/47869/

Disagree with us all you want, but it doesn't change this fact. :-) I hope our point is clearer now.

Why or why is there so much outdated code on msdn.microsoft.com?


Ask Microsoft, not us. :-D
Topic archived. No new replies allowed.