[W32TIME] Improve w32time setup
authorEric Kohl <eric.kohl@reactos.org>
Mon, 6 Dec 2021 22:24:51 +0000 (23:24 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 6 Dec 2021 22:24:51 +0000 (23:24 +0100)
- Remove w32time from hivesys.inf
- Implement DllRegisterServer
- Add DllUnregisterServer stub
- Register w32time at the end of setup phase 2

base/services/w32time/CMakeLists.txt
base/services/w32time/lang/de-DE.rc [new file with mode: 0644]
base/services/w32time/lang/en-US.rc [new file with mode: 0644]
base/services/w32time/register.c [new file with mode: 0644]
base/services/w32time/resource.h [new file with mode: 0644]
base/services/w32time/w32time.h
base/services/w32time/w32time.rc [new file with mode: 0644]
base/services/w32time/w32time.spec
boot/bootdata/hivesys.inf
media/inf/syssetup.inf

index 080d1fd..f1d25b4 100644 (file)
@@ -4,9 +4,11 @@ spec2def(w32time.dll w32time.spec ADD_IMPORTLIB)
 add_library(w32time MODULE
     w32time.c
     ntpclient.c
+    register.c
+    w32time.rc
     ${CMAKE_CURRENT_BINARY_DIR}/w32time.def)
 
 set_module_type(w32time win32dll UNICODE)
 
-add_importlibs(w32time ws2_32 advapi32 msvcrt kernel32 ntdll)
+add_importlibs(w32time ws2_32 advapi32 msvcrt user32 kernel32 ntdll)
 add_cd_file(TARGET w32time DESTINATION reactos/system32 FOR all)
diff --git a/base/services/w32time/lang/de-DE.rc b/base/services/w32time/lang/de-DE.rc
new file mode 100644 (file)
index 0000000..b4b7f2f
--- /dev/null
@@ -0,0 +1,7 @@
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_DISPLAYNAME "Zeitgeberdienst"
+    IDS_DESCRIPTION "Verwaltet die Datum- und Uhrzeitsynchronisation auf allen Clients und Servern im Netzwerk."
+END
diff --git a/base/services/w32time/lang/en-US.rc b/base/services/w32time/lang/en-US.rc
new file mode 100644 (file)
index 0000000..3aef0f2
--- /dev/null
@@ -0,0 +1,7 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+    IDS_DISPLAYNAME "Time Service"
+    IDS_DESCRIPTION "Maintains date and time synchronization on all clients and servers on the network."
+END
diff --git a/base/services/w32time/register.c b/base/services/w32time/register.c
new file mode 100644 (file)
index 0000000..205a288
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * PROJECT:     ReactOS W32Time Service
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Service Registration
+ * COPYRIGHT:   Copyright 2021 Eric Kohl <ekohl@reactos.org>
+ */
+
+#include "w32time.h"
+#include <debug.h>
+#include <strsafe.h>
+
+#include "resource.h"
+
+static
+PWSTR
+ReadString(
+    _In_ UINT uID)
+{
+    HINSTANCE hInstance;
+    int nLength;
+    PWSTR pszString, pszPtr;
+
+    hInstance = GetModuleHandleW(L"w32time");
+    if (hInstance == NULL)
+        return NULL;
+
+    nLength = LoadStringW(hInstance, uID, (LPWSTR)&pszPtr, 0);
+    if (nLength == 0)
+        return NULL;
+
+    pszString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
+    if (pszString == NULL)
+        return NULL;
+
+    wcsncpy(pszString, pszPtr, nLength);
+
+    return pszString;
+}
+
+
+static
+HRESULT
+RegisterService(VOID)
+{
+    SC_HANDLE hServiceManager = NULL;
+    SC_HANDLE hService = NULL;
+    HKEY hKey = NULL;
+    PWSTR pszValue;
+    PWSTR pszDisplayName = NULL, pszDescription = NULL;
+    DWORD dwDisposition, dwError;
+    SERVICE_DESCRIPTIONW ServiceDescription;
+    HRESULT hresult = S_OK;
+
+    DPRINT("RegisterService()\n");
+
+    hServiceManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+    if (hServiceManager == NULL)
+    {
+        DPRINT1("OpenSCManager() failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+    pszDisplayName = ReadString(IDS_DISPLAYNAME);
+    if (pszDisplayName == NULL)
+    {
+        DPRINT1("ReadString(IDS_DISPLAYNAME) failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+    pszDescription = ReadString(IDS_DESCRIPTION);
+    if (pszDescription == NULL)
+    {
+        DPRINT1("ReadString(IDS_DESCRIPTION) failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+    hService = CreateServiceW(hServiceManager,
+                              L"W32Time",
+                              pszDisplayName,
+                              GENERIC_WRITE,
+                              SERVICE_WIN32_SHARE_PROCESS,
+                              SERVICE_AUTO_START,
+                              SERVICE_ERROR_NORMAL,
+                              L"%SystemRoot%\\system32\\svchost.exe -k netsvcs",
+                              L"Time", NULL, NULL, L"LocalSystem", NULL);
+    if (hService == NULL)
+    {
+        DPRINT1("CreateService() failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+    ServiceDescription.lpDescription = pszDescription;
+    if (ChangeServiceConfig2W(hService,
+                              SERVICE_CONFIG_DESCRIPTION,
+                              &ServiceDescription) == FALSE)
+    {
+        DPRINT1("ChangeServiceConfig2() failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+    dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+                              L"System\\CurrentControlSet\\Services\\W32Time\\Parameters",
+                              0,
+                              NULL,
+                              REG_OPTION_NON_VOLATILE,
+                              KEY_WRITE,
+                              NULL,
+                              &hKey,
+                              &dwDisposition);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("RegCreateKeyEx() failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+    pszValue = L"%SystemRoot%\\system32\\w32time.dll";
+    dwError = RegSetValueExW(hKey,
+                             L"ServiceDll",
+                             0,
+                             REG_EXPAND_SZ,
+                             (LPBYTE)pszValue,
+                             (wcslen(pszValue) + 1) * sizeof(WCHAR));
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("RegSetValueEx() failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+    pszValue = L"SvchostEntry_W32Time";
+    dwError = RegSetValueExW(hKey,
+                             L"ServiceMain",
+                             0,
+                             REG_SZ,
+                             (LPBYTE)pszValue,
+                             (wcslen(pszValue) + 1) * sizeof(WCHAR));
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("RegSetValueEx() failed!\n");
+        hresult = E_FAIL;
+        goto done;
+    }
+
+done:
+    if (hKey)
+        RegCloseKey(hKey);
+
+    if (hService)
+        CloseServiceHandle(hService);
+
+    if (hServiceManager)
+        CloseServiceHandle(hServiceManager);
+
+    if (pszDescription)
+        HeapFree(GetProcessHeap(), 0, pszDescription);
+
+    if (pszDisplayName)
+        HeapFree(GetProcessHeap(), 0, pszDisplayName);
+
+    return hresult;
+}
+
+
+static
+HRESULT
+SetParametersValues(VOID)
+{
+    HKEY hKey = NULL;
+    PWSTR pszValue;
+    DWORD dwDisposition, dwError;
+    HRESULT hresult = S_OK;
+
+    dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+                              L"System\\CurrentControlSet\\Services\\W32Time\\Parameters",
+                              0,
+                              NULL,
+                              REG_OPTION_NON_VOLATILE,
+                              KEY_WRITE,
+                              NULL,
+                              &hKey,
+                              &dwDisposition);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("RegCreateKeyEx() failed!\n");
+        goto done;
+    }
+
+    pszValue = L"NTP";
+    dwError = RegSetValueExW(hKey,
+                             L"Type",
+                             0,
+                             REG_SZ,
+                             (LPBYTE)pszValue,
+                             (wcslen(pszValue) + 1) * sizeof(WCHAR));
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("RegSetValueEx() failed!\n");
+        goto done;
+    }
+
+done:
+    if (hKey)
+        RegCloseKey(hKey);
+
+    return hresult;
+}
+
+
+static
+HRESULT
+SetNtpClientValues(VOID)
+{
+    HKEY hKey = NULL;
+    DWORD dwValue;
+    DWORD dwDisposition, dwError;
+    HRESULT hresult = S_OK;
+
+    dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+                              L"System\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\NtpClient",
+                              0,
+                              NULL,
+                              REG_OPTION_NON_VOLATILE,
+                              KEY_WRITE,
+                              NULL,
+                              &hKey,
+                              &dwDisposition);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("RegCreateKeyEx() failed!\n");
+        goto done;
+    }
+
+    dwValue = 0x00093a80;
+    dwError = RegSetValueExW(hKey,
+                             L"SpecialPollInterval",
+                             0,
+                             REG_DWORD,
+                             (LPBYTE)&dwValue,
+                             sizeof(dwValue));
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("RegSetValueEx() failed!\n");
+        goto done;
+    }
+
+done:
+    if (hKey)
+        RegCloseKey(hKey);
+
+    return hresult;
+}
+
+
+HRESULT
+WINAPI
+DllRegisterServer(VOID)
+{
+    HRESULT hresult;
+
+    hresult = RegisterService();
+    if (FAILED(hresult))
+        return hresult;
+
+    hresult = SetParametersValues();
+    if (FAILED(hresult))
+        return hresult;
+
+    hresult = SetNtpClientValues();
+
+    return hresult;
+}
+
+
+HRESULT
+WINAPI
+DllUnregisterServer(VOID)
+{
+    DPRINT1("DllUnregisterServer()\n");
+    return S_OK;
+}
diff --git a/base/services/w32time/resource.h b/base/services/w32time/resource.h
new file mode 100644 (file)
index 0000000..d3049b4
--- /dev/null
@@ -0,0 +1,4 @@
+#pragma once
+
+#define IDS_DISPLAYNAME 200
+#define IDS_DESCRIPTION 201
index 87be3d0..0bd729e 100644 (file)
@@ -12,6 +12,7 @@
 #include <winnls.h>
 #include <winreg.h>
 #include <winsvc.h>
+#include <winuser.h>
 
 #define MAX_VALUE_NAME 16383
 #define NTPPORT 123
diff --git a/base/services/w32time/w32time.rc b/base/services/w32time/w32time.rc
new file mode 100644 (file)
index 0000000..4b0b320
--- /dev/null
@@ -0,0 +1,20 @@
+#include <windef.h>
+#include <winuser.h>
+
+#include "resource.h"
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION  "Time Service"
+#define REACTOS_STR_INTERNAL_NAME     "w32time"
+#define REACTOS_STR_ORIGINAL_FILENAME "w32time.dll"
+#include <reactos/version.rc>
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+#ifdef LANGUAGE_DE_DE
+    #include "lang/de-DE.rc"
+#endif
+#ifdef LANGUAGE_EN_US
+    #include "lang/en-US.rc"
+#endif
index 32d25bf..6e08500 100644 (file)
@@ -1,3 +1,5 @@
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
 6 stdcall SvchostEntry_W32Time(long ptr) W32TmServiceMain
 18 stdcall W32TimeSyncNow(wstr long long)
 21 stdcall W32TmServiceMain(long ptr)
index fa6c21b..4f20247 100644 (file)
@@ -2072,20 +2072,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","ObjectName",0x00000000,"LocalS
 HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Start",0x00010001,0x00000002
 HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Type",0x00010001,0x00000110
 
-; W32TIME service
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","DisplayName",0x00000000,%W32TIME_SERVICE%
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","Description",0x00000000,%W32TIME_SERVICE_DESCRIPTION%
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","ErrorControl",0x00010001,0x00000001
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","Group",0x00000000,"Time"
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","ImagePath",0x00020000,"%SystemRoot%\system32\svchost.exe -k netsvcs"
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","ObjectName",0x00000000,"LocalSystem"
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","Start",0x00010001,0x00000002
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time","Type",0x00010001,0x00000020
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\w32time.dll"
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time\Parameters","ServiceMain",0x00000000,"SvchostEntry_W32Time"
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time\Parameters","Type",0x00010000,"NTP"
-HKLM,"SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient","SpecialPollInterval",0x00010001,0x00093a80
-
 ; Simple TCP services
 HKLM,"SYSTEM\CurrentControlSet\Services\tcpsvcs","Description",0x00000000,%TCPSVCS_SERVICE_DECRIPTION%
 HKLM,"SYSTEM\CurrentControlSet\Services\tcpsvcs","DisplayName",0x00000000,%TCPSVCS_SERVICE%
@@ -2317,9 +2303,6 @@ WINMGMT_SERVICE_DESCRIPTION="Provides interface to system management information
 WLANSVC_SERVICE="WLAN Service"
 WLANSVC_SERVICE_DESCRIPTION="WLAN Service"
 
-W32TIME_SERVICE="Time Service"
-W32TIME_SERVICE_DESCRIPTION="ReactOS Time Service"
-
 WORKSTATION_SERVICE="Workstation"
 WORKSTATION_SERVICE_DESCRIPTION="Responsible for creating and maintaining network connections to servers."
 
@@ -2474,9 +2457,6 @@ WINMGMT_SERVICE_DESCRIPTION="Dostarcza interfejs w celu uzyskiwania dostępu do
 WLANSVC_SERVICE="Usługa WLAN"
 WLANSVC_SERVICE_DESCRIPTION="Usługa WLAN"
 
-W32TIME_SERVICE="Usługa Czas"
-W32TIME_SERVICE_DESCRIPTION="Usługa Czas systemu ReactOS"
-
 WORKSTATION_SERVICE="Stacja robocza"
 WORKSTATION_SERVICE_DESCRIPTION="Tworzy i zachowuje połączenia sieciowe klientów z serwerami."
 
@@ -2936,9 +2916,6 @@ WINMGMT_SERVICE_DESCRIPTION="Proporciona una interfaz para la gestión de la inf
 WLANSVC_SERVICE="Servicio de WLAN"
 WLANSVC_SERVICE_DESCRIPTION="Servicio de redes inalámbricas WLAN."
 
-W32TIME_SERVICE="Servicio de hora"
-W32TIME_SERVICE_DESCRIPTION="Servicio de hora para ReactOS"
-
 WORKSTATION_SERVICE="Estación de trabajo"
 WORKSTATION_SERVICE_DESCRIPTION="Es el responsable de crear y mantener las conexiones de redes LAN a los servidores."
 
@@ -3092,9 +3069,6 @@ WINMGMT_SERVICE_DESCRIPTION="Sistem yönetim bilgisine arayüz sağlar."
 WLANSVC_SERVICE="WLAN Hizmeti"
 WLANSVC_SERVICE_DESCRIPTION="WLAN Hizmeti"
 
-W32TIME_SERVICE="Zaman Hizmeti"
-W32TIME_SERVICE_DESCRIPTION="ReactOS Zaman Hizmeti"
-
 WORKSTATION_SERVICE="İş İstasyonu"
 WORKSTATION_SERVICE_DESCRIPTION="Sunuculara ağ bağlantılarını oluşturmaktan ve yönetmekten sorumludur."
 
index 2a53753..0196d9b 100644 (file)
@@ -113,6 +113,7 @@ AddReg=Classes
 11,,stobject.dll,1
 11,,urlmon.dll,3
 11,,vbscript.dll,1
+11,,w32time.dll,1
 11,,windowscodecs.dll,1
 11,,winhttp.dll,1
 11,,wininet.dll,2