mirror of
https://github.com/reactos/reactos.git
synced 2024-09-06 02:37:06 +00:00
147 lines
4 KiB
C
147 lines
4 KiB
C
/*
|
|
* 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 <windef.h>
|
|
#include <winbase.h>
|
|
#include <winreg.h>
|
|
#include <winsvc.h>
|
|
#include <ntddndis.h>
|
|
|
|
#include <ndk/exfuncs.h>
|
|
#include <ntsecapi.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
#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);
|
|
}
|
|
}
|