1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/audio_device/win/audio_device_utility_win.h"
12
13#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
14#include "webrtc/system_wrappers/interface/trace.h"
15
16#include <windows.h>
17#include <tchar.h>
18#include <strsafe.h>
19
20#define STRING_MAX_SIZE 256
21
22typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
23typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
24
25namespace webrtc
26{
27
28// ============================================================================
29//                            Construction & Destruction
30// ============================================================================
31
32// ----------------------------------------------------------------------------
33//  AudioDeviceUtilityWindows() - ctor
34// ----------------------------------------------------------------------------
35
36AudioDeviceUtilityWindows::AudioDeviceUtilityWindows(const int32_t id) :
37    _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
38    _id(id),
39    _lastError(AudioDeviceModule::kAdmErrNone)
40{
41    WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, "%s created", __FUNCTION__);
42}
43
44// ----------------------------------------------------------------------------
45//  AudioDeviceUtilityWindows() - dtor
46// ----------------------------------------------------------------------------
47
48AudioDeviceUtilityWindows::~AudioDeviceUtilityWindows()
49{
50    WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", __FUNCTION__);
51    {
52        CriticalSectionScoped lock(&_critSect);
53
54        // free stuff here...
55    }
56
57    delete &_critSect;
58}
59
60// ============================================================================
61//                                     API
62// ============================================================================
63
64// ----------------------------------------------------------------------------
65//  Init()
66// ----------------------------------------------------------------------------
67
68int32_t AudioDeviceUtilityWindows::Init()
69{
70
71    TCHAR szOS[STRING_MAX_SIZE];
72
73    if (GetOSDisplayString(szOS))
74    {
75#ifdef _UNICODE
76        char os[STRING_MAX_SIZE];
77        if (WideCharToMultiByte(CP_UTF8, 0, szOS, -1, os, STRING_MAX_SIZE, NULL, NULL) == 0)
78        {
79            strncpy(os, "Could not get OS info", STRING_MAX_SIZE);
80        }
81        WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, _id, "  OS info: %s", os);
82#else
83        WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, _id, "  OS info: %s", szOS);
84#endif
85    }
86
87    return 0;
88}
89
90// ============================================================================
91//                                 Private Methods
92// ============================================================================
93
94BOOL AudioDeviceUtilityWindows::GetOSDisplayString(LPTSTR pszOS)
95{
96    OSVERSIONINFOEX osvi;
97    SYSTEM_INFO si;
98    PGNSI pGNSI;
99    BOOL bOsVersionInfoEx;
100
101    ZeroMemory(&si, sizeof(SYSTEM_INFO));
102    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
103
104    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
105
106    // Retrieve information about the current operating system
107    //
108    bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi);
109    if (!bOsVersionInfoEx)
110        return FALSE;
111
112    // Parse our OS version string
113    //
114    if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4)
115    {
116        StringCchCopy(pszOS, STRING_MAX_SIZE, TEXT("Microsoft "));
117
118        // Test for the specific product
119        //
120        //  Operating system	    Version number
121        //  --------------------------------------
122        //  Windows 7	            6.1
123        //  Windows Server 2008 R2	6.1
124        //  Windows Server 2008	    6.0
125        //  Windows Vista	        6.0
126        //  - - - - - - - - - - - - - - - - - - -
127        //  Windows Server 2003 R2	5.2
128        //  Windows Server 2003	    5.2
129        //  Windows XP	            5.1
130        //  Windows 2000	        5.0
131        //
132        //  see http://msdn.microsoft.com/en-us/library/ms724832(VS.85).aspx for details
133        //
134        if (osvi.dwMajorVersion == 6)
135        {
136            if (osvi.dwMinorVersion == 0)
137            {
138                // Windows Vista or Server 2008
139                if (osvi.wProductType == VER_NT_WORKSTATION)
140                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Vista "));
141                else
142                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Server 2008 " ));
143            }
144
145            if (osvi.dwMinorVersion == 1)
146            {
147                // Windows 7 or Server 2008 R2
148                if (osvi.wProductType == VER_NT_WORKSTATION)
149                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows 7 "));
150                else
151                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Server 2008 R2 " ));
152            }
153        }
154
155        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
156        {
157            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Server 2003"));
158        }
159
160        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
161        {
162            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows XP "));
163            if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
164                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Home Edition" ));
165            else
166                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Professional" ));
167        }
168
169        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
170        {
171            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows 2000 "));
172
173            if (osvi.wProductType == VER_NT_WORKSTATION )
174            {
175                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Professional" ));
176            }
177            else
178            {
179                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
180                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Datacenter Server" ));
181                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
182                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Advanced Server" ));
183                else StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Server" ));
184            }
185        }
186
187        // Include service pack (if any)
188        //
189        if (_tcslen(osvi.szCSDVersion) > 0)
190        {
191            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT(" "));
192            StringCchCat(pszOS, STRING_MAX_SIZE, osvi.szCSDVersion);
193        }
194
195        TCHAR buf[80];
196
197        // Include build number
198        //
199        StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);
200        StringCchCat(pszOS, STRING_MAX_SIZE, buf);
201
202        // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise
203        //
204        pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
205        if (NULL != pGNSI)
206            pGNSI(&si);
207        else
208            GetSystemInfo(&si);
209
210        // Add 64-bit or 32-bit for OS versions "later than" Vista
211        //
212        if (osvi.dwMajorVersion >= 6)
213        {
214            if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||
215                (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64))
216                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( ", 64-bit" ));
217            else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
218                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT(", 32-bit"));
219        }
220
221        return TRUE;
222    }
223    else
224    {
225        return FALSE;
226   }
227}
228
229}  // namespace webrtc
230