mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-28 03:17:31 +09:00
134 lines
4 KiB
C++
134 lines
4 KiB
C++
|
|
// Copyright 2011 Google Inc. All Rights Reserved.
|
||
|
|
// Use of this source code is governed by an Apache-style license that can be
|
||
|
|
// found in the COPYING file.
|
||
|
|
|
||
|
|
#include <windows.h>
|
||
|
|
#include <sddl.h> // For ConvertSidToStringSidW.
|
||
|
|
#include <string>
|
||
|
|
#include <vector>
|
||
|
|
#include "mozilla/ArrayUtils.h"
|
||
|
|
|
||
|
|
#include "rlz/lib/assert.h"
|
||
|
|
|
||
|
|
namespace rlz_lib {
|
||
|
|
|
||
|
|
namespace {
|
||
|
|
|
||
|
|
bool GetSystemVolumeSerialNumber(int* number) {
|
||
|
|
if (!number)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
*number = 0;
|
||
|
|
|
||
|
|
// Find the system root path (e.g: C:\).
|
||
|
|
wchar_t system_path[MAX_PATH + 1];
|
||
|
|
if (!GetSystemDirectoryW(system_path, MAX_PATH))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
wchar_t* first_slash = wcspbrk(system_path, L"\\/");
|
||
|
|
if (first_slash != NULL)
|
||
|
|
*(first_slash + 1) = 0;
|
||
|
|
|
||
|
|
DWORD number_local = 0;
|
||
|
|
if (!GetVolumeInformationW(system_path, NULL, 0, &number_local, NULL, NULL,
|
||
|
|
NULL, 0))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
*number = (int)number_local;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool GetComputerSid(const wchar_t* account_name, SID* sid, DWORD sid_size) {
|
||
|
|
static const DWORD kStartDomainLength = 128; // reasonable to start with
|
||
|
|
|
||
|
|
std::vector<wchar_t> domain_buffer(kStartDomainLength, 0);
|
||
|
|
DWORD domain_size = kStartDomainLength;
|
||
|
|
DWORD sid_dword_size = sid_size;
|
||
|
|
SID_NAME_USE sid_name_use;
|
||
|
|
|
||
|
|
BOOL success = ::LookupAccountNameW(NULL, account_name, sid,
|
||
|
|
&sid_dword_size, &domain_buffer.front(),
|
||
|
|
&domain_size, &sid_name_use);
|
||
|
|
if (!success && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||
|
|
// We could have gotten the insufficient buffer error because
|
||
|
|
// one or both of sid and szDomain was too small. Check for that
|
||
|
|
// here.
|
||
|
|
if (sid_dword_size > sid_size)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
if (domain_size > kStartDomainLength)
|
||
|
|
domain_buffer.resize(domain_size);
|
||
|
|
|
||
|
|
success = ::LookupAccountNameW(NULL, account_name, sid, &sid_dword_size,
|
||
|
|
&domain_buffer.front(), &domain_size,
|
||
|
|
&sid_name_use);
|
||
|
|
}
|
||
|
|
|
||
|
|
return success != FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::vector<uint8_t> ConvertSidToBytes(SID* sid) {
|
||
|
|
std::wstring sid_string;
|
||
|
|
#if _WIN32_WINNT >= 0x500
|
||
|
|
wchar_t* sid_buffer = NULL;
|
||
|
|
if (ConvertSidToStringSidW(sid, &sid_buffer)) {
|
||
|
|
sid_string = sid_buffer;
|
||
|
|
LocalFree(sid_buffer);
|
||
|
|
}
|
||
|
|
#else
|
||
|
|
SID_IDENTIFIER_AUTHORITY* sia = ::GetSidIdentifierAuthority(sid);
|
||
|
|
|
||
|
|
if(sia->Value[0] || sia->Value[1]) {
|
||
|
|
base::SStringPrintf(
|
||
|
|
&sid_string, L"S-%d-0x%02hx%02hx%02hx%02hx%02hx%02hx",
|
||
|
|
SID_REVISION, (USHORT)sia->Value[0], (USHORT)sia->Value[1],
|
||
|
|
(USHORT)sia->Value[2], (USHORT)sia->Value[3], (USHORT)sia->Value[4],
|
||
|
|
(USHORT)sia->Value[5]);
|
||
|
|
} else {
|
||
|
|
ULONG authority = 0;
|
||
|
|
for (int i = 2; i < 6; ++i) {
|
||
|
|
authority <<= 8;
|
||
|
|
authority |= sia->Value[i];
|
||
|
|
}
|
||
|
|
base::SStringPrintf(&sid_string, L"S-%d-%lu", SID_REVISION, authority);
|
||
|
|
}
|
||
|
|
|
||
|
|
int sub_auth_count = *::GetSidSubAuthorityCount(sid);
|
||
|
|
for(int i = 0; i < sub_auth_count; ++i)
|
||
|
|
base::StringAppendF(&sid_string, L"-%lu", *::GetSidSubAuthority(sid, i));
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// Get the contents of the string as a bunch of bytes.
|
||
|
|
return std::vector<uint8_t>(
|
||
|
|
reinterpret_cast<uint8_t*>(&sid_string[0]),
|
||
|
|
reinterpret_cast<uint8_t*>(&sid_string[sid_string.size()]));
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace
|
||
|
|
|
||
|
|
bool GetRawMachineId(std::vector<uint8_t>* sid_bytes, int* volume_id) {
|
||
|
|
// Calculate the Windows SID.
|
||
|
|
|
||
|
|
wchar_t computer_name[MAX_COMPUTERNAME_LENGTH + 1] = {0};
|
||
|
|
DWORD size = mozilla::ArrayLength(computer_name);
|
||
|
|
|
||
|
|
if (!GetComputerNameW(computer_name, &size)) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
char sid_buffer[SECURITY_MAX_SID_SIZE];
|
||
|
|
SID* sid = reinterpret_cast<SID*>(sid_buffer);
|
||
|
|
if (GetComputerSid(computer_name, sid, SECURITY_MAX_SID_SIZE)) {
|
||
|
|
*sid_bytes = ConvertSidToBytes(sid);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get the system drive volume serial number.
|
||
|
|
*volume_id = 0;
|
||
|
|
if (!GetSystemVolumeSerialNumber(volume_id)) {
|
||
|
|
ASSERT_STRING("GetMachineId: Failed to retrieve volume serial number");
|
||
|
|
*volume_id = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace rlz_lib
|