PageRenderTime 296ms CodeModel.GetById 111ms app.highlight 61ms RepoModel.GetById 120ms app.codeStats 0ms

/indra/newview/llmachineid.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 263 lines | 162 code | 44 blank | 57 comment | 17 complexity | 323e4f6d8d814a26e9ec239bbdf32a51 MD5 | raw file
  1/** 
  2 * @file llmachineid.cpp
  3 * @brief retrieves unique machine ids
  4 *
  5 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28#include "lluuid.h"
 29#include "llmachineid.h"
 30#if	LL_WINDOWS
 31#define _WIN32_DCOM
 32#include <iostream>
 33using namespace std;
 34#include <comdef.h>
 35#include <Wbemidl.h>
 36#endif
 37unsigned char static_unique_id[] =  {0,0,0,0,0,0};
 38bool static has_static_unique_id = false;
 39
 40// get an unique machine id.
 41// NOT THREAD SAFE - do before setting up threads.
 42// MAC Address doesn't work for Windows 7 since the first returned hardware MAC address changes with each reboot,  Go figure??
 43
 44S32 LLMachineID::init()
 45{
 46    memset(static_unique_id,0,sizeof(static_unique_id));
 47    S32 ret_code = 0;
 48#if	LL_WINDOWS
 49# pragma comment(lib, "wbemuuid.lib")
 50        size_t len = sizeof(static_unique_id);
 51
 52        // algorithm to detect BIOS serial number found at:
 53        // http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx
 54        // we can't use the MAC address since on Windows 7, the first returned MAC address changes with every reboot.
 55
 56
 57        HRESULT hres;
 58
 59        // Step 1: --------------------------------------------------
 60        // Initialize COM. ------------------------------------------
 61
 62        hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
 63        if (FAILED(hres))
 64        {
 65            LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x"   << hex << hres << LL_ENDL;
 66            return 1;                  // Program has failed.
 67        }
 68
 69        // Step 2: --------------------------------------------------
 70        // Set general COM security levels --------------------------
 71        // Note: If you are using Windows 2000, you need to specify -
 72        // the default authentication credentials for a user by using
 73        // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
 74        // parameter of CoInitializeSecurity ------------------------
 75
 76        hres =  CoInitializeSecurity(
 77            NULL, 
 78            -1,                          // COM authentication
 79            NULL,                        // Authentication services
 80            NULL,                        // Reserved
 81            RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
 82            RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
 83            NULL,                        // Authentication info
 84            EOAC_NONE,                   // Additional capabilities 
 85            NULL                         // Reserved
 86            );
 87
 88                          
 89        if (FAILED(hres))
 90        {
 91            LL_DEBUGS("AppInit") << "Failed to initialize security. Error code = 0x"  << hex << hres << LL_ENDL;
 92            CoUninitialize();
 93            return 1;                    // Program has failed.
 94        }
 95        
 96        // Step 3: ---------------------------------------------------
 97        // Obtain the initial locator to WMI -------------------------
 98
 99        IWbemLocator *pLoc = NULL;
100
101        hres = CoCreateInstance(
102            CLSID_WbemLocator,             
103            0, 
104            CLSCTX_INPROC_SERVER, 
105            IID_IWbemLocator, (LPVOID *) &pLoc);
106     
107        if (FAILED(hres))
108        {
109            LL_DEBUGS("AppInit") << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << LL_ENDL;
110            CoUninitialize();
111            return 1;                 // Program has failed.
112        }
113
114        // Step 4: -----------------------------------------------------
115        // Connect to WMI through the IWbemLocator::ConnectServer method
116
117        IWbemServices *pSvc = NULL;
118    	
119        // Connect to the root\cimv2 namespace with
120        // the current user and obtain pointer pSvc
121        // to make IWbemServices calls.
122        hres = pLoc->ConnectServer(
123             _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
124             NULL,                    // User name. NULL = current user
125             NULL,                    // User password. NULL = current
126             0,                       // Locale. NULL indicates current
127             NULL,                    // Security flags.
128             0,                       // Authority (e.g. Kerberos)
129             0,                       // Context object 
130             &pSvc                    // pointer to IWbemServices proxy
131             );
132        
133        if (FAILED(hres))
134        {
135            LL_DEBUGS("AppInit") << "Could not connect. Error code = 0x"  << hex << hres << LL_ENDL;
136            pLoc->Release();     
137            CoUninitialize();
138            return 1;                // Program has failed.
139        }
140
141        LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL;
142
143
144        // Step 5: --------------------------------------------------
145        // Set security levels on the proxy -------------------------
146
147        hres = CoSetProxyBlanket(
148           pSvc,                        // Indicates the proxy to set
149           RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
150           RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
151           NULL,                        // Server principal name 
152           RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
153           RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
154           NULL,                        // client identity
155           EOAC_NONE                    // proxy capabilities 
156        );
157
158        if (FAILED(hres))
159        {
160            LL_DEBUGS("AppInit") << "Could not set proxy blanket. Error code = 0x"   << hex << hres << LL_ENDL;
161            pSvc->Release();
162            pLoc->Release();     
163            CoUninitialize();
164            return 1;               // Program has failed.
165        }
166
167        // Step 6: --------------------------------------------------
168        // Use the IWbemServices pointer to make requests of WMI ----
169
170        // For example, get the name of the operating system
171        IEnumWbemClassObject* pEnumerator = NULL;
172        hres = pSvc->ExecQuery(
173            bstr_t("WQL"), 
174            bstr_t("SELECT * FROM Win32_OperatingSystem"),
175            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
176            NULL,
177            &pEnumerator);
178        
179        if (FAILED(hres))
180        {
181            LL_DEBUGS("AppInit") << "Query for operating system name failed." << " Error code = 0x"  << hex << hres << LL_ENDL;
182            pSvc->Release();
183            pLoc->Release();
184            CoUninitialize();
185            return 1;               // Program has failed.
186        }
187
188        // Step 7: -------------------------------------------------
189        // Get the data from the query in step 6 -------------------
190     
191        IWbemClassObject *pclsObj = NULL;
192        ULONG uReturn = 0;
193       
194        while (pEnumerator)
195        {
196            HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
197                &pclsObj, &uReturn);
198
199            if(0 == uReturn)
200            {
201                break;
202            }
203
204            VARIANT vtProp;
205
206            // Get the value of the Name property
207            hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
208            LL_DEBUGS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL;
209            // use characters in the returned Serial Number to create a byte array of size len
210            BSTR serialNumber ( vtProp.bstrVal);
211            unsigned int j = 0;
212            while( vtProp.bstrVal[j] != 0)
213            {
214                for (unsigned int i = 0; i < len; i++)
215                {
216                    if (vtProp.bstrVal[j] == 0)
217                        break;
218                    
219                    static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
220                    j++;
221                }
222            }
223            VariantClear(&vtProp);
224
225            pclsObj->Release();
226            pclsObj = NULL;
227            break;
228        }
229
230        // Cleanup
231        // ========
232        
233        if (pSvc)
234            pSvc->Release();
235        if (pLoc)
236            pLoc->Release();
237        if (pEnumerator)
238            pEnumerator->Release();
239        CoUninitialize();
240        ret_code=0;
241#else
242        unsigned char * staticPtr = (unsigned char *)(&static_unique_id[0]);
243        ret_code = LLUUID::getNodeID(staticPtr);
244#endif
245        has_static_unique_id = true;
246        return ret_code;
247}
248
249
250S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
251{
252    if (has_static_unique_id)
253    {
254        memcpy ( unique_id, &static_unique_id, len);
255        LL_DEBUGS("AppInit") << "UniqueID: " << unique_id[0] << unique_id[1]<< unique_id[2] << unique_id[3] << unique_id[4] << unique_id [5] << LL_ENDL;
256        return 1;
257    }
258    return 0;
259}
260
261
262
263