[DCOMLAUNCH] Add a DcomLaunch service stub

This stub is responsible for providing the UUID seed to the kernel.
For now, it generates a purely random seed - MAC address support
is to be added.
Because it's purely random seed and local the machine (not tied
to the MAC address) it's made so that ExUuidCreate keeps returning
RPC_NT_UUID_LOCAL_ONLY. It won't fix failing test for now.

Nota: this service shouldn't exist as it. It should be implemented
though rpcss DLL for both rpcss service (network service) and
dcomlaunch service (local system service).
Because rpcss is EXE based and wine-synced for now, I prefered
stubbing a new service. This will have to be changed at some point.
This commit is contained in:
Pierre Schweitzer 2019-03-03 14:21:46 +01:00
parent 1d7287288d
commit 2ab289a34a
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
8 changed files with 324 additions and 1 deletions

View file

@ -0,0 +1,140 @@
/*
* 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;
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
/* 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;
}
/* And finally with free disk space */
if (GetDiskFreeSpaceA("c:\\", &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters))
{
*NodeMiddle = *NodeMiddle ^ TotalNumberOfClusters * BytesPerSector * SectorsPerCluster;
*NodeBegin = *NodeBegin ^ NumberOfFreeClusters * BytesPerSector * SectorsPerCluster;
}
/*
* 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);
}
}