[DCOMLAUNCH] Add a DcomLaunch service stub
[reactos.git] / base / services / dcomlaunch / network.c
1 /*
2 * PROJECT: ReactOS RPC Subsystem Service
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: UUID initialization.
5 * COPYRIGHT: Copyright 2019 Pierre Schweitzer
6 */
7
8 /* INCLUDES *****************************************************************/
9
10 /* PSDK/NDK Headers */
11 #define WIN32_NO_STATUS
12 #include <windef.h>
13 #include <winbase.h>
14 #include <winreg.h>
15 #include <winsvc.h>
16 #include <ntddndis.h>
17
18 #include <ndk/exfuncs.h>
19 #include <ntsecapi.h>
20
21 #define NDEBUG
22 #include <debug.h>
23
24 #define SEED_BUFFER_SIZE 6
25
26 /* FUNCTIONS ****************************************************************/
27
28 static BOOLEAN
29 getMacAddress(UCHAR * MacAddress)
30 {
31 /* FIXME: query NDIS for all the interfaces */
32 UNIMPLEMENTED;
33 return FALSE;
34 }
35
36 static VOID
37 CookupNodeId(UCHAR * NodeId)
38 {
39 CHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
40 CHAR * CurrentChar;
41 DWORD Size;
42 LARGE_INTEGER PerformanceCount;
43 PDWORD NodeBegin, NodeMiddle;
44 DWORD dwValue;
45 MEMORYSTATUS MemoryStatus;
46 LUID Luid;
47 DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
48
49 /* Initialize node id */
50 memset(NodeId, 0x11, SEED_BUFFER_SIZE * sizeof(UCHAR));
51
52 /* Randomize it with computer name */
53 Size = MAX_COMPUTERNAME_LENGTH + 1;
54 if (GetComputerNameA(ComputerName, &Size))
55 {
56 Size = 0;
57 CurrentChar = &ComputerName[0];
58 while (*CurrentChar != ANSI_NULL)
59 {
60 NodeId[Size] ^= *CurrentChar;
61 ++CurrentChar;
62
63 /* Don't overflow our NodeId */
64 if (++Size >= SEED_BUFFER_SIZE)
65 {
66 Size = 0;
67 }
68 }
69 }
70
71 /* Now, we'll work directly on DWORD values */
72 NodeBegin = (DWORD *)&NodeId[0];
73 NodeMiddle = (DWORD *)&NodeId[2];
74
75 /* Randomize with performance counter */
76 if (QueryPerformanceCounter(&PerformanceCount))
77 {
78 *NodeMiddle = *NodeMiddle ^ PerformanceCount.u.HighPart ^ PerformanceCount.u.LowPart;
79
80 dwValue = PerformanceCount.u.HighPart ^ PerformanceCount.u.LowPart ^ *NodeBegin;
81 }
82 else
83 {
84 dwValue = *NodeBegin;
85 }
86
87 *NodeBegin = *NodeBegin ^ dwValue;
88 *NodeMiddle = *NodeMiddle ^ *NodeBegin;
89
90 /* Then, with memory status */
91 MemoryStatus.dwLength = sizeof(MemoryStatus);
92 GlobalMemoryStatus(&MemoryStatus);
93
94 *NodeBegin = *NodeBegin ^ MemoryStatus.dwMemoryLoad;
95 *NodeMiddle = *NodeMiddle ^ MemoryStatus.dwTotalPhys;
96 *NodeBegin = *NodeBegin ^ MemoryStatus.dwTotalPageFile ^ MemoryStatus.dwAvailPhys;
97 *NodeMiddle = *NodeMiddle ^ MemoryStatus.dwTotalVirtual ^ MemoryStatus.dwAvailPageFile;
98 *NodeBegin = *NodeBegin ^ MemoryStatus.dwAvailVirtual;
99
100 /* With a LUID */
101 if (AllocateLocallyUniqueId(&Luid))
102 {
103 *NodeBegin = *NodeBegin ^ Luid.LowPart;
104 *NodeMiddle = *NodeMiddle ^ Luid.HighPart;
105 }
106
107 /* And finally with free disk space */
108 if (GetDiskFreeSpaceA("c:\\", &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters))
109 {
110 *NodeMiddle = *NodeMiddle ^ TotalNumberOfClusters * BytesPerSector * SectorsPerCluster;
111 *NodeBegin = *NodeBegin ^ NumberOfFreeClusters * BytesPerSector * SectorsPerCluster;
112 }
113
114 /*
115 * Because it was locally generated, force the seed to be local
116 * setting this, will trigger the check for validness in the kernel
117 * and make the seed local
118 */
119 NodeId[0] |= 0x80u;
120 }
121
122 VOID DealWithDeviceEvent(VOID)
123 {
124 NTSTATUS Status;
125 UCHAR UuidSeed[SEED_BUFFER_SIZE];
126
127 /* First, try to get a multicast MAC address */
128 if (!getMacAddress(UuidSeed))
129 {
130 DPRINT1("Failed finding a proper MAC address, will generate seed\n");
131 CookupNodeId(UuidSeed);
132 }
133
134 /* Seed our UUID generator */
135 Status = NtSetUuidSeed(UuidSeed);
136 if (!NT_SUCCESS(Status))
137 {
138 DPRINT1("NtSetUuidSeed failed with status: %lx\n", Status);
139 }
140 }