/* * PROJECT: ReactOS RPC Subsystem Service * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: UUID initialization. * COPYRIGHT: Copyright 2019 Pierre Schweitzer */ /* INCLUDES *****************************************************************/ /* PSDK/NDK Headers */ #define WIN32_NO_STATUS #include #include #include #include #include #include #include #define NDEBUG #include #define SEED_BUFFER_SIZE 6 /* FUNCTIONS ****************************************************************/ static BOOLEAN getMacAddress(UCHAR * MacAddress) { /* FIXME: query NDIS for all the interfaces */ UNIMPLEMENTED; return FALSE; } static VOID CookupNodeId(UCHAR * NodeId) { CHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1]; CHAR * CurrentChar; DWORD Size; LARGE_INTEGER PerformanceCount; PDWORD NodeBegin, NodeMiddle; DWORD dwValue; MEMORYSTATUS MemoryStatus; LUID Luid; WCHAR szSystem[MAX_PATH]; ULARGE_INTEGER FreeBytesToCaller, TotalBytes, TotalFreeBytes; /* Initialize node id */ memset(NodeId, 0x11, SEED_BUFFER_SIZE * sizeof(UCHAR)); /* Randomize it with computer name */ Size = MAX_COMPUTERNAME_LENGTH + 1; if (GetComputerNameA(ComputerName, &Size)) { Size = 0; CurrentChar = &ComputerName[0]; while (*CurrentChar != ANSI_NULL) { NodeId[Size] ^= *CurrentChar; ++CurrentChar; /* Don't overflow our NodeId */ if (++Size >= SEED_BUFFER_SIZE) { Size = 0; } } } /* Now, we'll work directly on DWORD values */ NodeBegin = (DWORD *)&NodeId[0]; NodeMiddle = (DWORD *)&NodeId[2]; /* Randomize with performance counter */ if (QueryPerformanceCounter(&PerformanceCount)) { *NodeMiddle = *NodeMiddle ^ PerformanceCount.u.HighPart ^ PerformanceCount.u.LowPart; dwValue = PerformanceCount.u.HighPart ^ PerformanceCount.u.LowPart ^ *NodeBegin; } else { dwValue = *NodeBegin; } *NodeBegin = *NodeBegin ^ dwValue; *NodeMiddle = *NodeMiddle ^ *NodeBegin; /* Then, with memory status */ MemoryStatus.dwLength = sizeof(MemoryStatus); GlobalMemoryStatus(&MemoryStatus); *NodeBegin = *NodeBegin ^ MemoryStatus.dwMemoryLoad; *NodeMiddle = *NodeMiddle ^ MemoryStatus.dwTotalPhys; *NodeBegin = *NodeBegin ^ MemoryStatus.dwTotalPageFile ^ MemoryStatus.dwAvailPhys; *NodeMiddle = *NodeMiddle ^ MemoryStatus.dwTotalVirtual ^ MemoryStatus.dwAvailPageFile; *NodeBegin = *NodeBegin ^ MemoryStatus.dwAvailVirtual; /* With a LUID */ if (AllocateLocallyUniqueId(&Luid)) { *NodeBegin = *NodeBegin ^ Luid.LowPart; *NodeMiddle = *NodeMiddle ^ Luid.HighPart; } /* Get system directory */ GetSystemDirectoryW(szSystem, ARRAYSIZE(szSystem)); /* And finally with free disk space */ if (GetDiskFreeSpaceExW(szSystem, &FreeBytesToCaller, &TotalBytes, &TotalFreeBytes)) { *NodeMiddle ^= FreeBytesToCaller.LowPart ^ TotalFreeBytes.HighPart; *NodeMiddle ^= FreeBytesToCaller.HighPart ^ TotalFreeBytes.LowPart; *NodeBegin ^= TotalBytes.LowPart ^ TotalFreeBytes.LowPart; *NodeBegin ^= TotalBytes.HighPart ^ TotalFreeBytes.HighPart; } /* * Because it was locally generated, force the seed to be local * setting this, will trigger the check for validness in the kernel * and make the seed local */ NodeId[0] |= 0x80u; } VOID DealWithDeviceEvent(VOID) { NTSTATUS Status; UCHAR UuidSeed[SEED_BUFFER_SIZE]; /* First, try to get a multicast MAC address */ if (!getMacAddress(UuidSeed)) { DPRINT1("Failed finding a proper MAC address, will generate seed\n"); CookupNodeId(UuidSeed); } /* Seed our UUID generator */ Status = NtSetUuidSeed(UuidSeed); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetUuidSeed failed with status: %lx\n", Status); } }