diff --git a/base/services/CMakeLists.txt b/base/services/CMakeLists.txt index 977b5edf681..64cd7346906 100644 --- a/base/services/CMakeLists.txt +++ b/base/services/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(audiosrv) +add_subdirectory(dcomlaunch) add_subdirectory(dhcpcsvc) add_subdirectory(eventlog) add_subdirectory(nfsd) diff --git a/base/services/dcomlaunch/CMakeLists.txt b/base/services/dcomlaunch/CMakeLists.txt new file mode 100644 index 00000000000..6759d029aad --- /dev/null +++ b/base/services/dcomlaunch/CMakeLists.txt @@ -0,0 +1,11 @@ +spec2def(dcomlaunch.dll dcomlaunch.spec ADD_IMPORTLIB) + +add_library(dcomlaunch SHARED + dcomlaunch.c + network.c + dcomlaunch.rc + ${CMAKE_CURRENT_BINARY_DIR}/dcomlaunch.def) + +set_module_type(dcomlaunch win32dll UNICODE) +add_importlibs(dcomlaunch advapi32 msvcrt kernel32 ntdll) +add_cd_file(TARGET dcomlaunch DESTINATION reactos/system32 FOR all) diff --git a/base/services/dcomlaunch/dcomlaunch.c b/base/services/dcomlaunch/dcomlaunch.c new file mode 100644 index 00000000000..280dbff3ebb --- /dev/null +++ b/base/services/dcomlaunch/dcomlaunch.c @@ -0,0 +1,142 @@ +/* + * PROJECT: ReactOS RPC Subsystem Service + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: DCOMLAUNCH service + * COPYRIGHT: Copyright 2019 Pierre Schweitzer + */ + +/* INCLUDES *****************************************************************/ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* GLOBALS ******************************************************************/ + +static WCHAR ServiceName[] = L"dcomlaunch"; + +static SERVICE_STATUS_HANDLE ServiceStatusHandle; +static SERVICE_STATUS ServiceStatus; + +/* FUNCTIONS *****************************************************************/ + +static VOID +UpdateServiceStatus(DWORD dwState) +{ + ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStatus.dwCurrentState = dwState; + ServiceStatus.dwControlsAccepted = 0; + ServiceStatus.dwWin32ExitCode = 0; + ServiceStatus.dwServiceSpecificExitCode = 0; + ServiceStatus.dwCheckPoint = 0; + + if (dwState == SERVICE_START_PENDING || + dwState == SERVICE_STOP_PENDING || + dwState == SERVICE_PAUSE_PENDING || + dwState == SERVICE_CONTINUE_PENDING) + ServiceStatus.dwWaitHint = 10000; + else + ServiceStatus.dwWaitHint = 0; + + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); +} + +static DWORD WINAPI +ServiceControlHandler(DWORD dwControl, + DWORD dwEventType, + LPVOID lpEventData, + LPVOID lpContext) +{ + DPRINT1("ServiceControlHandler() called\n"); + + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + DPRINT1(" SERVICE_CONTROL_STOP received\n"); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_PAUSE: + DPRINT1(" SERVICE_CONTROL_PAUSE received\n"); + UpdateServiceStatus(SERVICE_PAUSED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_CONTINUE: + DPRINT1(" SERVICE_CONTROL_CONTINUE received\n"); + UpdateServiceStatus(SERVICE_RUNNING); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_INTERROGATE: + DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n"); + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_SHUTDOWN: + DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n"); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + default : + DPRINT1(" Control %lu received\n"); + return ERROR_CALL_NOT_IMPLEMENTED; + } +} + +VOID DealWithDeviceEvent(); + +VOID WINAPI +ServiceMain(DWORD argc, LPTSTR *argv) +{ + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + DPRINT("ServiceMain() called\n"); + + ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, + ServiceControlHandler, + NULL); + if (!ServiceStatusHandle) + { + DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); + return; + } + + DealWithDeviceEvent(); + + UpdateServiceStatus(SERVICE_RUNNING); + + do + { + Sleep(1); + } while (1); + + UpdateServiceStatus(SERVICE_STOPPED); +} + +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} diff --git a/base/services/dcomlaunch/dcomlaunch.rc b/base/services/dcomlaunch/dcomlaunch.rc new file mode 100644 index 00000000000..f98315df2dd --- /dev/null +++ b/base/services/dcomlaunch/dcomlaunch.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "DcomLaunch Service" +#define REACTOS_STR_INTERNAL_NAME "dcomlaunch" +#define REACTOS_STR_ORIGINAL_FILENAME "dcomlaunch.dll" +#include diff --git a/base/services/dcomlaunch/dcomlaunch.spec b/base/services/dcomlaunch/dcomlaunch.spec new file mode 100644 index 00000000000..1b27fe53864 --- /dev/null +++ b/base/services/dcomlaunch/dcomlaunch.spec @@ -0,0 +1 @@ +@ stdcall ServiceMain(long ptr) diff --git a/base/services/dcomlaunch/network.c b/base/services/dcomlaunch/network.c new file mode 100644 index 00000000000..c6475c85e23 --- /dev/null +++ b/base/services/dcomlaunch/network.c @@ -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 +#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; + 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); + } +} diff --git a/boot/bootdata/hivesft.inf b/boot/bootdata/hivesft.inf index 5f78d8f1df4..efd5c0833e1 100644 --- a/boot/bootdata/hivesft.inf +++ b/boot/bootdata/hivesft.inf @@ -1775,7 +1775,7 @@ HKLM,"SOFTWARE\Microsoft\Ole","EnableRemoteConnect",0x00000000,"N" ; SvcHost services HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost",,0x00000012 -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost","DcomLaunch",0x00010000,"PlugPlay" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost","DcomLaunch",0x00010000,"DcomLaunch","PlugPlay" HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost","netsvcs",0x00010000,"DHCP","BITS","lanmanserver","lanmanworkstation","Schedule","Themes","winmgmt" ; Win32 config diff --git a/boot/bootdata/hivesys.inf b/boot/bootdata/hivesys.inf index aa85d6ccdb2..c8cd1821f82 100644 --- a/boot/bootdata/hivesys.inf +++ b/boot/bootdata/hivesys.inf @@ -2058,6 +2058,17 @@ HKLM,"SYSTEM\CurrentControlSet\Services\wuauserv","Start",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\wuauserv","Type",0x00010001,0x00000020 HKLM,"SYSTEM\CurrentControlSet\Services\wuauserv\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\wuauserv.dll" +; DCOMLAUNCH Service +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","DisplayName",0x00000000,%DCOMLAUNCH_SERVICE% +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","Description",0x00000000,%DCOMLAUNCH_SERVICE_DESCRIPTION% +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","Group",0x00000000,"Event log" +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","ImagePath",0x00020000,"%SystemRoot%\system32\svchost.exe -k DcomLaunch" +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","ObjectName",0x00000000,"LocalSystem" +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","Start",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch","Type",0x00010001,0x00000020 +HKLM,"SYSTEM\CurrentControlSet\Services\DcomLaunch\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\dcomlaunch.dll" + ; Sound Blaster (NT4) ;HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Description",0x00000000,"Sound Blaster (NT4)" ;HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ErrorControl",0x00010001,0x00000001 @@ -2178,6 +2189,9 @@ AUDIO_SERVICE_DESCRIPTION="Provides audio facilities to applications" BITS_SERVICE="Background Intelligent Transfer Service" BITS_SERVICE_DESCRIPTION="Transfers files in the background using idle network bandwidth." +DCOMLAUNCH_SERVICE="DcomLaunch service" +DCOMLAUNCH_SERVICE_DESCRIPTION="DcomLaunch service stub." + EVENTLOG_SERVICE="Event Logger" EVENTLOG_SERVICE_DESCRIPTION="Logs events or messages sent by the operating system in a database accessible via the event log viewer." @@ -2320,6 +2334,9 @@ AUDIO_SERVICE_DESCRIPTION="Zapewnia aplikacjom dostęp do urządzeń audio." BITS_SERVICE="Usługa inteligentnego transferu w tle" BITS_SERVICE_DESCRIPTION="Przenosi dane pomiędzy klientami a serwerami w tle." +DCOMLAUNCH_SERVICE="DcomLaunch service" +DCOMLAUNCH_SERVICE_DESCRIPTION="DcomLaunch service stub." + EVENTLOG_SERVICE="Dziennik zdarzeń" EVENTLOG_SERVICE_DESCRIPTION="Zapisuje zdarzenia lub wiadomości wysyłane przez system operacyjny do bazy danych dostępnej za pomocą podglądu zdarzeń." @@ -2459,6 +2476,9 @@ AUDIO_SERVICE_DESCRIPTION="Oferă aplicațiilor funcționalități audio." BITS_SERVICE="Serviciu de transfer inteligent în fundal" BITS_SERVICE_DESCRIPTION="Transferă fișiere în fundal utilizând lățimea de bandă nefolosită a rețelei." +DCOMLAUNCH_SERVICE="DcomLaunch service" +DCOMLAUNCH_SERVICE_DESCRIPTION="DcomLaunch service stub." + EVENTLOG_SERVICE="Jurnal de evenimente" EVENTLOG_SERVICE_DESCRIPTION="Jurnalizează mesajele sau evenimentele transmise de sistemul de operare într-o bază de date accesibilă cu instrumentul „observator de evenimente”." @@ -2598,6 +2618,9 @@ AUDIO_SERVICE_DESCRIPTION="Обеспечивает звуковыми устр BITS_SERVICE="Фоновая интеллектуальная служба передачи (BITS)" BITS_SERVICE_DESCRIPTION="Обеспечивает передачу данных между клиентами и серверами в фоновом режиме с использованием пропускной способности простаивающей сети." +DCOMLAUNCH_SERVICE="DcomLaunch service" +DCOMLAUNCH_SERVICE_DESCRIPTION="DcomLaunch service stub." + EVENTLOG_SERVICE="Журнал событий" EVENTLOG_SERVICE_DESCRIPTION="Регистрирует события или сообщения, отправленные операционной системой в базе данных, доступной через средство просмотра журнала событий."