summaryrefslogtreecommitdiff
path: root/materialsystem/shaderapidx9/wmi.cpp
blob: 1b0644f5b8319811f871f473bf6275baf6335cd7 (plain) (blame)
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================

#include "resource.h"

// Avoid conflicts with MSVC headers and memdbgon.h
#undef PROTECTED_THINGS_ENABLE
#include "basetypes.h"

#define _WIN32_DCOM
#include <comdef.h>
#pragma warning( disable : 4127 ) // VS 2010 warning?
#pragma warning( disable : 4805 ) // VS 2013 warning: warning C4805: '==' : unsafe mix of type 'INT' and type 'bool' in operation
#include <atlcomtime.h>
#pragma warning( default : 4805 )
#pragma warning( default : 4127 )
#include <wbemidl.h>

// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"


# pragma comment(lib, "wbemuuid.lib")

uint64 GetVidMemBytes( void )
{
	static int bBeenHere = false;
	static uint64 nBytes = 0;

	if( bBeenHere )
	{
		return nBytes;
	}

	bBeenHere = true;

	// Initialize COM
    HRESULT hr =  CoInitialize( NULL ); 
    if ( FAILED( hr ) )
    {
		OutputDebugString ( "GetWMIDeviceStats - Unable to initialize COM library.\n");
        return 0;
    }

    // Obtain the initial locator to WMI
    IWbemLocator *pLoc = NULL;

    hr = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);
 
    if ( FAILED( hr ) )
    {
		OutputDebugString ( "GetWMIDeviceStats - Failed to create IWbemLocator object.\n");
        CoUninitialize();
        return 0;
    }

    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices *pSvc = NULL;
	
    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hr = pLoc->ConnectServer(
         _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
         NULL,                    // User name. NULL = current user
         NULL,                    // User password. NULL = current
         0,                       // Locale. NULL indicates current
         NULL,                    // Security flags.
         0,                       // Authority (e.g. Kerberos)
         0,                       // Context object 
         &pSvc                    // pointer to IWbemServices proxy
         );
    
    if ( FAILED( hr ) )
    {
		OutputDebugString ( "GetWMIDeviceStats - Could not connect.\n");
        pLoc->Release();     
        CoUninitialize();
        return 0;
    }

//	OutputDebugString ( L"GetWMIDeviceStats - Connected to ROOT\\CIMV2 WMI namespace\n");


    // Set security levels on the proxy

    hr = CoSetProxyBlanket(
       pSvc,                        // Indicates the proxy to set
       RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
       RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
       NULL,                        // Server principal name 
       RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
       RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
       NULL,                        // client identity
       EOAC_NONE                    // proxy capabilities 
    );

    if ( FAILED( hr ) )
    {
		OutputDebugString ( "GetWMIDeviceStats - Could not set proxy blanket.\n");
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return 0;
    }


    // Use the IWbemServices pointer to make requests of WMI

	//
	// --- Win32_VideoController --------------------------------------------------
	//

    IEnumWbemClassObject* pEnumerator = NULL;
    hr = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_VideoController"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);

    if ( FAILED( hr ) )
    {
		OutputDebugString ( "GetWMIDeviceStats - Query for Win32_VideoController failed.\n");

		pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 0;
    }


    // Get the data from the above query
    IWbemClassObject *pclsObj = NULL;
    ULONG uReturn = 0;
   
    while ( pEnumerator )
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

        if(0 == uReturn)
        {
            break;
        }

        VARIANT vtProp;
        VariantInit(&vtProp);

		// Pluck a series of properties out of the query from Win32_VideoController

//        hr = pclsObj->Get(L"Description", 0, &vtProp, 0, 0);		// Basically the same as "VideoProcessor"
//		if ( SUCCEEDED( hr ) )
//		{
//			wsprintf( pAdapter->m_szPrimaryAdapterDescription, vtProp.bstrVal );
//		}

        hr = pclsObj->Get(L"AdapterRAM", 0, &vtProp, 0, 0);
		if ( SUCCEEDED( hr ) )
		{
			nBytes = vtProp.ulVal; // Video RAM in bytes, AdatperRam is returned as the I4 type so we read it out as unsigned int, 
								   // see http://msdn.microsoft.com/en-us/library/windows/desktop/aa394512(v=vs.85).aspx
		}

        VariantClear(&vtProp);
    }

    // Cleanup
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
	if ( pclsObj )
	{
		pclsObj->Release();
	}
    CoUninitialize();

	return nBytes;
}