| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <windows.h> | |
| 6 #include <Sddl.h> // For ConvertSidToStringSidW. | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/string16.h" | |
| 11 #include "rlz/lib/assert.h" | |
| 12 | |
| 13 namespace rlz_lib { | |
| 14 | |
| 15 namespace { | |
| 16 | |
| 17 bool GetSystemVolumeSerialNumber(int* number) { | |
| 18 if (!number) | |
| 19 return false; | |
| 20 | |
| 21 *number = 0; | |
| 22 | |
| 23 // Find the system root path (e.g: C:\). | |
| 24 wchar_t system_path[MAX_PATH + 1]; | |
| 25 if (!GetSystemDirectoryW(system_path, MAX_PATH)) | |
| 26 return false; | |
| 27 | |
| 28 wchar_t* first_slash = wcspbrk(system_path, L"\\/"); | |
| 29 if (first_slash != NULL) | |
| 30 *(first_slash + 1) = 0; | |
| 31 | |
| 32 DWORD number_local = 0; | |
| 33 if (!GetVolumeInformationW(system_path, NULL, 0, &number_local, NULL, NULL, | |
| 34 NULL, 0)) | |
| 35 return false; | |
| 36 | |
| 37 *number = number_local; | |
| 38 return true; | |
| 39 } | |
| 40 | |
| 41 bool GetComputerSid(const wchar_t* account_name, SID* sid, DWORD sid_size) { | |
| 42 static const DWORD kStartDomainLength = 128; // reasonable to start with | |
| 43 | |
| 44 scoped_array<wchar_t> domain_buffer(new wchar_t[kStartDomainLength]); | |
| 45 DWORD domain_size = kStartDomainLength; | |
| 46 DWORD sid_dword_size = sid_size; | |
| 47 SID_NAME_USE sid_name_use; | |
| 48 | |
| 49 BOOL success = ::LookupAccountNameW(NULL, account_name, sid, | |
| 50 &sid_dword_size, domain_buffer.get(), | |
| 51 &domain_size, &sid_name_use); | |
| 52 if (!success && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { | |
| 53 // We could have gotten the insufficient buffer error because | |
| 54 // one or both of sid and szDomain was too small. Check for that | |
| 55 // here. | |
| 56 if (sid_dword_size > sid_size) | |
| 57 return false; | |
| 58 | |
| 59 if (domain_size > kStartDomainLength) | |
| 60 domain_buffer.reset(new wchar_t[domain_size]); | |
| 61 | |
| 62 success = ::LookupAccountNameW(NULL, account_name, sid, &sid_dword_size, | |
| 63 domain_buffer.get(), &domain_size, | |
| 64 &sid_name_use); | |
| 65 } | |
| 66 | |
| 67 return success != FALSE; | |
| 68 } | |
| 69 | |
| 70 std::wstring ConvertSidToString(SID* sid) { | |
| 71 std::wstring sid_string; | |
| 72 #if _WIN32_WINNT >= 0x500 | |
| 73 wchar_t* sid_buffer = NULL; | |
| 74 if (ConvertSidToStringSidW(sid, &sid_buffer)) { | |
| 75 sid_string = sid_buffer; | |
| 76 LocalFree(sid_buffer); | |
| 77 } | |
| 78 #else | |
| 79 SID_IDENTIFIER_AUTHORITY* sia = ::GetSidIdentifierAuthority(sid); | |
| 80 | |
| 81 if(sia->Value[0] || sia->Value[1]) { | |
| 82 base::SStringPrintf( | |
| 83 &sid_string, L"S-%d-0x%02hx%02hx%02hx%02hx%02hx%02hx", | |
| 84 SID_REVISION, (USHORT)sia->Value[0], (USHORT)sia->Value[1], | |
| 85 (USHORT)sia->Value[2], (USHORT)sia->Value[3], (USHORT)sia->Value[4], | |
| 86 (USHORT)sia->Value[5]); | |
| 87 } else { | |
| 88 ULONG authority = 0; | |
| 89 for (int i = 2; i < 6; ++i) { | |
| 90 authority <<= 8; | |
| 91 authority |= sia->Value[i]; | |
| 92 } | |
| 93 base::SStringPrintf(&sid_string, L"S-%d-%lu", SID_REVISION, authority); | |
| 94 } | |
| 95 | |
| 96 int sub_auth_count = *::GetSidSubAuthorityCount(sid); | |
| 97 for(int i = 0; i < sub_auth_count; ++i) | |
| 98 base::StringAppendF(&sid_string, L"-%lu", *::GetSidSubAuthority(sid, i)); | |
| 99 #endif | |
| 100 | |
| 101 return sid_string; | |
| 102 } | |
| 103 | |
| 104 } // namespace | |
| 105 | |
| 106 bool GetRawMachineId(string16* sid_string, int* volume_id) { | |
| 107 // Calculate the Windows SID. | |
| 108 | |
| 109 wchar_t computer_name[MAX_COMPUTERNAME_LENGTH + 1] = {0}; | |
| 110 DWORD size = arraysize(computer_name); | |
| 111 | |
| 112 if (GetComputerNameW(computer_name, &size)) { | |
| 113 char sid_buffer[SECURITY_MAX_SID_SIZE]; | |
| 114 SID* sid = reinterpret_cast<SID*>(sid_buffer); | |
| 115 if (GetComputerSid(computer_name, sid, SECURITY_MAX_SID_SIZE)) { | |
| 116 *sid_string = ConvertSidToString(sid); | |
| 117 } | |
| 118 } | |
| 119 | |
| 120 // Get the system drive volume serial number. | |
| 121 *volume_id = 0; | |
| 122 if (!GetSystemVolumeSerialNumber(volume_id)) { | |
| 123 ASSERT_STRING("GetMachineId: Failed to retrieve volume serial number"); | |
| 124 *volume_id = 0; | |
| 125 } | |
| 126 | |
| 127 return true; | |
| 128 } | |
| 129 | |
| 130 } // namespace rlz_lib | |
| OLD | NEW |