reactos/base/services/dcomlaunch/network.c
2020-05-17 17:45:56 +09:00

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);
}
}