https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7f248437e88d0d5cd011b7c68e61e15edcecb05d

commit 7f248437e88d0d5cd011b7c68e61e15edcecb05d
Author:     Eric Kohl <eric.k...@reactos.org>
AuthorDate: Sat Mar 1 15:43:34 2025 +0100
Commit:     Eric Kohl <eric.k...@reactos.org>
CommitDate: Sat Mar 1 15:43:34 2025 +0100

    [NETCFGX] Simple implementation of INetCfgClassSetup.Install()
    
    Import device installer code from syssetup.dll.
    This is the first step to move the network component installer code from 
syssetup.dll to netcfgx.dll and netshell.dll.
---
 dll/win32/netcfgx/CMakeLists.txt      |   1 +
 dll/win32/netcfgx/netcfgclass_iface.c |   2 +
 dll/win32/netcfgx/netinstall.c        | 627 ++++++++++++++++++++++++++++++++++
 dll/win32/netcfgx/precomp.h           |   4 +
 4 files changed, 634 insertions(+)

diff --git a/dll/win32/netcfgx/CMakeLists.txt b/dll/win32/netcfgx/CMakeLists.txt
index 3e4dfb3f8b8..5f499a2e0fd 100644
--- a/dll/win32/netcfgx/CMakeLists.txt
+++ b/dll/win32/netcfgx/CMakeLists.txt
@@ -8,6 +8,7 @@ list(APPEND SOURCE
     netcfgx.c
     classfactory.c
     installer.c
+    netinstall.c
     netcfg_iface.c
     netcfgbindinginterface_iface.c
     netcfgbindingpath_iface.c
diff --git a/dll/win32/netcfgx/netcfgclass_iface.c 
b/dll/win32/netcfgx/netcfgclass_iface.c
index 10eda26cad6..667f36df07c 100644
--- a/dll/win32/netcfgx/netcfgclass_iface.c
+++ b/dll/win32/netcfgx/netcfgclass_iface.c
@@ -77,6 +77,8 @@ INetCfgClassSetup_fnInstall(
     if (ppComponent)
         *ppComponent = NULL;
 
+    InstallNetworkComponent(pszwComponentId);
+
     return S_OK;
 }
 
diff --git a/dll/win32/netcfgx/netinstall.c b/dll/win32/netcfgx/netinstall.c
new file mode 100644
index 00000000000..1d167d81d03
--- /dev/null
+++ b/dll/win32/netcfgx/netinstall.c
@@ -0,0 +1,627 @@
+/*
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS system libraries
+ * PURPOSE:           Network configuration
+ * FILE:              dll/win32/netcfgx/netinstall.c
+ * PROGRAMER:         Eric Kohl
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "precomp.h"
+#include <rpc.h>
+
+
+typedef struct _COMPONENT_INFO
+{
+    PWSTR pszFullInfPath;
+    PWSTR pszInfPath;
+    PWSTR pszInfSection;
+    PWSTR pszComponentId;
+    PWSTR pszDescription;
+    PWSTR pszClassGuid;
+    DWORD dwCharacteristics;
+} COMPONENT_INFO, *PCOMPONENT_INFO;
+
+
+/* GLOBALS ******************************************************************/
+
+
+/* FUNCTIONS ****************************************************************/
+
+static
+BOOL
+InstallInfSections(
+    _In_ HWND hWnd,
+    _In_ HKEY hKey,
+    _In_ LPCWSTR InfFile,
+    _In_ LPCWSTR InfSection)
+{
+    WCHAR Buffer[MAX_PATH];
+    HINF hInf = INVALID_HANDLE_VALUE;
+    UINT BufferSize;
+    PVOID Context = NULL;
+    BOOL ret = FALSE;
+
+    TRACE("InstallInfSections()\n");
+
+    if (InfSection == NULL)
+        return FALSE;
+
+    /* Get Windows directory */
+    BufferSize = ARRAYSIZE(Buffer) - 5 - wcslen(InfFile);
+    if (GetWindowsDirectoryW(Buffer, BufferSize) > BufferSize)
+    {
+        /* Function failed */
+        SetLastError(ERROR_GEN_FAILURE);
+        goto cleanup;
+    }
+
+    /* We have enough space to add some information in the buffer */
+    if (Buffer[wcslen(Buffer) - 1] != '\\')
+        wcscat(Buffer, L"\\");
+    wcscat(Buffer, L"Inf\\");
+    wcscat(Buffer, InfFile);
+
+    /* Install specified section */
+    hInf = SetupOpenInfFileW(Buffer, NULL, INF_STYLE_WIN4, NULL);
+    if (hInf == INVALID_HANDLE_VALUE)
+        goto cleanup;
+
+    Context = SetupInitDefaultQueueCallback(hWnd);
+    if (Context == NULL)
+        goto cleanup;
+
+    ret = SetupInstallFromInfSectionW(
+                hWnd, hInf,
+                InfSection, SPINST_ALL,
+                hKey, NULL, SP_COPY_NEWER,
+                SetupDefaultQueueCallbackW, Context,
+                NULL, NULL);
+    if (ret == FALSE)
+    {
+        ERR("SetupInstallFromInfSectionW(%S) failed (Error %lx)\n", 
InfSection, GetLastError());
+        goto cleanup;
+    }
+
+    wcscpy(Buffer, InfSection);
+    wcscat(Buffer, L".Services");
+
+    ret = SetupInstallServicesFromInfSectionW(hInf, Buffer, 0);
+    if (ret == FALSE)
+    {
+        ERR("SetupInstallServicesFromInfSectionW(%S) failed (Error %lx)\n", 
Buffer, GetLastError());
+        goto cleanup;
+    }
+
+cleanup:
+    if (Context)
+        SetupTermDefaultQueueCallback(Context);
+
+    if (hInf != INVALID_HANDLE_VALUE)
+        SetupCloseInfFile(hInf);
+
+    TRACE("InstallInfSections() done %u\n", ret);
+
+    return ret;
+}
+
+
+static
+BOOL
+CreateInstanceKey(
+    _In_ PCOMPONENT_INFO pComponentInfo,
+    _Out_ PHKEY pInstanceKey)
+{
+    WCHAR szKeyBuffer[128];
+    LPWSTR UuidString = NULL;
+    UUID Uuid;
+    RPC_STATUS RpcStatus;
+    HKEY hInstanceKey;
+    DWORD rc;
+    BOOL ret = FALSE;
+
+    TRACE("CreateInstanceKey()\n");
+
+    *pInstanceKey = NULL;
+
+    wcscpy(szKeyBuffer, L"SYSTEM\\CurrentControlSet\\Control\\Network\\");
+    wcscat(szKeyBuffer, pComponentInfo->pszClassGuid);
+    wcscat(szKeyBuffer, L"\\{");
+
+    /* Create a new UUID */
+    RpcStatus = UuidCreate(&Uuid);
+    if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY)
+    {
+        ERR("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus);
+        goto done;
+    }
+
+    RpcStatus = UuidToStringW(&Uuid, &UuidString);
+    if (RpcStatus != RPC_S_OK)
+    {
+        ERR("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus);
+        goto done;
+    }
+
+    wcscat(szKeyBuffer, UuidString);
+    wcscat(szKeyBuffer, L"}");
+
+    RpcStringFreeW(&UuidString);
+
+    TRACE("szKeyBuffer %S\n", szKeyBuffer);
+
+    rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+                         szKeyBuffer,
+                         0,
+                         NULL,
+                         REG_OPTION_NON_VOLATILE,
+                         KEY_CREATE_SUB_KEY | KEY_SET_VALUE,
+                         NULL,
+                         &hInstanceKey,
+                         NULL);
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc);
+        goto done;
+    }
+
+    rc = RegSetValueExW(hInstanceKey,
+                        L"Characteristics",
+                        0,
+                        REG_DWORD,
+                        (LPBYTE)&pComponentInfo->dwCharacteristics,
+                        sizeof(DWORD));
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("RegSetValueExW() failed with error 0x%lx\n", rc);
+        goto done;
+    }
+
+    rc = RegSetValueExW(hInstanceKey,
+                        L"ComponentId",
+                        0,
+                        REG_SZ,
+                        (LPBYTE)pComponentInfo->pszComponentId,
+                        (wcslen(pComponentInfo->pszComponentId) + 1) * 
sizeof(WCHAR));
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("RegSetValueExW() failed with error 0x%lx\n", rc);
+        goto done;
+    }
+
+    rc = RegSetValueExW(hInstanceKey,
+                        L"Description",
+                        0,
+                        REG_SZ,
+                        (LPBYTE)pComponentInfo->pszDescription,
+                        (wcslen(pComponentInfo->pszDescription) + 1) * 
sizeof(WCHAR));
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("RegSetValueExW() failed with error 0x%lx\n", rc);
+        goto done;
+    }
+
+    rc = RegSetValueExW(hInstanceKey,
+                        L"InfPath",
+                        0,
+                        REG_SZ,
+                        (LPBYTE)pComponentInfo->pszInfPath,
+                        (wcslen(pComponentInfo->pszInfPath) + 1) * 
sizeof(WCHAR));
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("RegSetValueExW() failed with error 0x%lx\n", rc);
+        goto done;
+    }
+
+    rc = RegSetValueExW(hInstanceKey,
+                        L"InfSection",
+                        0,
+                        REG_SZ,
+                        (LPBYTE)pComponentInfo->pszInfSection,
+                        (wcslen(pComponentInfo->pszInfSection) + 1) * 
sizeof(WCHAR));
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("RegSetValueExW() failed with error 0x%lx\n", rc);
+        goto done;
+    }
+
+    *pInstanceKey = hInstanceKey;
+    ret = TRUE;
+
+done:
+    if (ret == FALSE)
+        RegCloseKey(hInstanceKey);
+
+    TRACE("CreateInstanceKey() done %u\n", ret);
+
+    return ret;
+}
+
+
+static
+BOOL
+CheckInfFile(
+    _In_ PWSTR pszFullInfName,
+    _In_ PCWSTR pszComponentId,
+    _In_ PCOMPONENT_INFO pComponentInfo)
+{
+    WCHAR szLineBuffer[MAX_PATH];
+    HINF hInf = INVALID_HANDLE_VALUE;
+    INFCONTEXT MfgContext, DevContext, MiscContext;
+    DWORD dwLength;
+
+    hInf = SetupOpenInfFileW(pszFullInfName,
+                             NULL,
+                             INF_STYLE_WIN4,
+                             NULL);
+    if (hInf == INVALID_HANDLE_VALUE)
+    {
+        ERR("\n");
+        return FALSE;
+    }
+
+    if (!SetupFindFirstLineW(hInf,
+                             L"Manufacturer",
+                             NULL,
+                             &MfgContext))
+    {
+        ERR("No Manufacurer section found!\n");
+        goto done;
+    }
+
+    for (;;)
+    {
+        if (!SetupGetStringFieldW(&MfgContext,
+                                  1,
+                                  szLineBuffer,
+                                  MAX_PATH,
+                                  NULL))
+            break;
+
+        TRACE("Manufacturer: %S\n", szLineBuffer);
+        if (!SetupFindFirstLineW(hInf,
+                                 szLineBuffer,
+                                 NULL,
+                                 &DevContext))
+            break;
+
+        for (;;)
+        {
+            if (!SetupGetStringFieldW(&DevContext,
+                                      2,
+                                      szLineBuffer,
+                                      MAX_PATH,
+                                      NULL))
+                break;
+
+            TRACE("Device: %S\n", szLineBuffer);
+            if (_wcsicmp(szLineBuffer, pszComponentId) == 0)
+            {
+                TRACE("Found it!\n");
+
+                /* Get the section name*/
+                SetupGetStringFieldW(&DevContext,
+                                     1,
+                                     NULL,
+                                     0,
+                                     &dwLength);
+
+                pComponentInfo->pszInfSection = HeapAlloc(GetProcessHeap(),
+                                                          0,
+                                                          dwLength * 
sizeof(WCHAR));
+                if (pComponentInfo->pszInfSection)
+                {
+                    SetupGetStringFieldW(&DevContext,
+                                         1,
+                                         pComponentInfo->pszInfSection,
+                                         dwLength,
+                                         &dwLength);
+                }
+
+                /* Get the description*/
+                SetupGetStringFieldW(&DevContext,
+                                     0,
+                                     NULL,
+                                     0,
+                                     &dwLength);
+
+                pComponentInfo->pszDescription = HeapAlloc(GetProcessHeap(),
+                                                           0,
+                                                           dwLength * 
sizeof(WCHAR));
+                if (pComponentInfo->pszDescription)
+                {
+                    SetupGetStringFieldW(&DevContext,
+                                         0,
+                                         pComponentInfo->pszDescription,
+                                         dwLength,
+                                         &dwLength);
+                }
+
+                /* Get the class GUID */
+                if (SetupFindFirstLineW(hInf,
+                                        L"Version",
+                                        L"ClassGuid",
+                                        &MiscContext))
+                {
+                    SetupGetStringFieldW(&MiscContext,
+                                         1,
+                                         NULL,
+                                         0,
+                                         &dwLength);
+
+                    pComponentInfo->pszClassGuid = HeapAlloc(GetProcessHeap(),
+                                                             0,
+                                                             dwLength * 
sizeof(WCHAR));
+                    if (pComponentInfo->pszInfSection)
+                    {
+                        SetupGetStringFieldW(&MiscContext,
+                                             1,
+                                             pComponentInfo->pszClassGuid,
+                                             dwLength,
+                                             &dwLength);
+                    }
+                }
+
+                /* Get the Characteristics value */
+                if (SetupFindFirstLineW(hInf,
+                                        pComponentInfo->pszInfSection,
+                                        L"Characteristics",
+                                        &MiscContext))
+                {
+                    SetupGetIntField(&MiscContext,
+                                     1,
+                                     (PINT)&pComponentInfo->dwCharacteristics);
+                }
+
+                SetupCloseInfFile(hInf);
+                return TRUE;
+            }
+
+            if (!SetupFindNextLine(&DevContext, &DevContext))
+                break;
+        }
+
+        if (!SetupFindNextLine(&MfgContext, &MfgContext))
+            break;
+    }
+
+done:
+    if (hInf != INVALID_HANDLE_VALUE)
+        SetupCloseInfFile(hInf);
+
+    return FALSE;
+}
+
+
+static
+BOOL
+ScanForInfFile(
+    _In_ PCWSTR pszComponentId,
+    _In_ PCOMPONENT_INFO pComponentInfo)
+{
+    WCHAR szInfPath[MAX_PATH];
+    WCHAR szFullInfName[MAX_PATH];
+    WCHAR szPathBuffer[MAX_PATH];
+    WIN32_FIND_DATAW fdw;
+    HANDLE hFindFile = INVALID_HANDLE_VALUE;
+    BOOL bFound = FALSE;
+
+    GetWindowsDirectoryW(szInfPath, MAX_PATH);
+    wcscat(szInfPath, L"\\inf");
+
+    wcscpy(szPathBuffer, szInfPath);
+    wcscat(szPathBuffer, L"\\*.inf");
+
+    hFindFile = FindFirstFileW(szPathBuffer, &fdw);
+    if (hFindFile == INVALID_HANDLE_VALUE)
+        return FALSE;
+
+    for (;;)
+    {
+        if (wcscmp(fdw.cFileName, L".") == 0 ||
+            wcscmp(fdw.cFileName, L"..") == 0)
+            continue;
+
+        TRACE("FileName: %S\n", fdw.cFileName);
+
+        wcscpy(szFullInfName, szInfPath);
+        wcscat(szFullInfName, L"\\");
+        wcscat(szFullInfName, fdw.cFileName);
+
+        TRACE("Full Inf Name: %S\n", szFullInfName);
+        if (CheckInfFile(szFullInfName,
+                         pszComponentId,
+                         pComponentInfo))
+        {
+            pComponentInfo->pszFullInfPath = HeapAlloc(GetProcessHeap(),
+                                                       0,
+                                                       (wcslen(szFullInfName) 
+ 1) * sizeof(WCHAR));
+            if (pComponentInfo->pszFullInfPath)
+                wcscpy(pComponentInfo->pszFullInfPath, szFullInfName);
+
+            pComponentInfo->pszInfPath = HeapAlloc(GetProcessHeap(),
+                                                   0,
+                                                   (wcslen(fdw.cFileName) + 1) 
* sizeof(WCHAR));
+            if (pComponentInfo->pszInfPath)
+                wcscpy(pComponentInfo->pszInfPath, fdw.cFileName);
+
+            pComponentInfo->pszComponentId = HeapAlloc(GetProcessHeap(),
+                                                       0,
+                                                       (wcslen(pszComponentId) 
+ 1) * sizeof(WCHAR));
+            if (pComponentInfo->pszComponentId)
+                wcscpy(pComponentInfo->pszComponentId, pszComponentId);
+
+            bFound = TRUE;
+            break;
+        }
+
+        if (!FindNextFileW(hFindFile, &fdw))
+            break;
+    }
+
+    if (hFindFile != INVALID_HANDLE_VALUE)
+        FindClose(hFindFile);
+
+    return bFound;
+}
+
+static
+VOID
+StartNetworkServices(
+    _In_ PCOMPONENT_INFO pComponentInfo)
+{
+    WCHAR szServiceName[64];
+    HINF hInf = INVALID_HANDLE_VALUE;
+    INFCONTEXT Context;
+    PWSTR pServiceSection = NULL;
+
+    SC_HANDLE hManager = NULL;
+    SC_HANDLE hService = NULL;
+
+    hManager = OpenSCManagerW(NULL,
+                              NULL,
+                              SC_MANAGER_ALL_ACCESS);
+    if (hManager == NULL)
+    {
+        ERR("\n");
+        goto done;
+    }
+
+    hInf = SetupOpenInfFileW(pComponentInfo->pszFullInfPath,
+                             NULL,
+                             INF_STYLE_WIN4,
+                             NULL);
+    if (hInf == INVALID_HANDLE_VALUE)
+    {
+        ERR("\n");
+        goto done;
+    }
+
+    pServiceSection = HeapAlloc(GetProcessHeap(), 0,
+                                (wcslen(pComponentInfo->pszInfSection) + 
wcslen(L".Service") + 1) * sizeof(WCHAR));
+    if (pServiceSection == NULL)
+    {
+        ERR("\n");
+        goto done;
+    }
+
+    wcscpy(pServiceSection, pComponentInfo->pszInfSection);
+    wcscat(pServiceSection, L".Service");
+
+    TRACE("ServiceSection: %S\n", pServiceSection);
+
+    if (!SetupFindFirstLineW(hInf,
+                             pServiceSection,
+                             L"AddService",
+                             &Context))
+    {
+        ERR("\n");
+        goto done;
+    }
+
+    for (;;)
+    {
+        SetupGetStringFieldW(&Context,
+                             1,
+                             szServiceName,
+                             64,
+                             NULL);
+
+        hService = OpenServiceW(hManager,
+                                szServiceName,
+                                SERVICE_START);
+        if (hService)
+        {
+            if (!StartService(hService, 0, NULL))
+            {
+                ERR("StartService() %S failed %lu\n", szServiceName, 
GetLastError());
+            }
+
+            CloseServiceHandle(hService);
+        }
+
+        if (!SetupFindNextLine(&Context, &Context))
+            break;
+    }
+
+done:
+    if (pServiceSection)
+        HeapFree(GetProcessHeap(), 0, pServiceSection);
+
+    if (hInf != INVALID_HANDLE_VALUE)
+        SetupCloseInfFile(hInf);
+
+    if (hManager != NULL)
+        CloseServiceHandle(hManager);
+}
+
+
+BOOL
+InstallNetworkComponent(
+    _In_ PCWSTR pszComponentId)
+{
+    COMPONENT_INFO ComponentInfo;
+    HKEY hInstanceKey = NULL;
+    BOOL bResult = FALSE;
+
+    TRACE("InstallNetworkComponent(%S)\n", pszComponentId);
+
+    ZeroMemory(&ComponentInfo, sizeof(COMPONENT_INFO));
+
+    if (!ScanForInfFile(pszComponentId, &ComponentInfo))
+        goto done;
+
+    TRACE("Characteristics: 0x%lx\n", ComponentInfo.dwCharacteristics);
+    TRACE("ComponentId: %S\n", ComponentInfo.pszComponentId);
+    TRACE("Description: %S\n", ComponentInfo.pszDescription);
+    TRACE("InfPath: %S\n", ComponentInfo.pszInfPath);
+    TRACE("InfSection: %S\n", ComponentInfo.pszInfSection);
+    TRACE("ClassGuid: %S\n", ComponentInfo.pszClassGuid);
+
+    if (!CreateInstanceKey(&ComponentInfo,
+                           &hInstanceKey))
+    {
+        ERR("CreateInstanceKey() failed (Error %lx)\n", GetLastError());
+        goto done;
+    }
+
+    if (!InstallInfSections(NULL,
+                            hInstanceKey,
+                            ComponentInfo.pszInfPath,
+                            ComponentInfo.pszInfSection))
+    {
+        ERR("InstallInfSections() failed (Error %lx)\n", GetLastError());
+        goto done;
+    }
+
+    bResult = TRUE;
+
+    StartNetworkServices(&ComponentInfo);
+
+done:
+    if (hInstanceKey != NULL)
+        RegCloseKey(hInstanceKey);
+
+    if (ComponentInfo.pszFullInfPath)
+        HeapFree(GetProcessHeap(), 0, ComponentInfo.pszFullInfPath);
+
+    if (ComponentInfo.pszInfPath)
+        HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfPath);
+
+    if (ComponentInfo.pszInfSection)
+        HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfSection);
+
+    if (ComponentInfo.pszComponentId)
+        HeapFree(GetProcessHeap(), 0, ComponentInfo.pszComponentId);
+
+    if (ComponentInfo.pszDescription)
+        HeapFree(GetProcessHeap(), 0, ComponentInfo.pszDescription);
+
+    if (ComponentInfo.pszClassGuid)
+        HeapFree(GetProcessHeap(), 0, ComponentInfo.pszClassGuid);
+
+    return bResult;
+}
+
+/* EOF */
diff --git a/dll/win32/netcfgx/precomp.h b/dll/win32/netcfgx/precomp.h
index e8551f7c43f..4823576c483 100644
--- a/dll/win32/netcfgx/precomp.h
+++ b/dll/win32/netcfgx/precomp.h
@@ -14,6 +14,7 @@
 #include <windef.h>
 #include <winbase.h>
 #include <winreg.h>
+#include <winsvc.h>
 #include <windowsx.h>
 #include <objbase.h>
 #include <netcfgx.h>
@@ -76,6 +77,9 @@ HRESULT WINAPI IEnumNetCfgBindingPath_Constructor(IUnknown 
*pUnkOuter, REFIID ri
 /* netcfgclass_iface.c */
 HRESULT WINAPI INetCfgClass_Constructor(IUnknown *pUnkOuter, REFIID riid, 
LPVOID *ppv, const GUID *pguidClass, INetCfg *pNetCfg);
 
+/* netinstall.c */
+BOOL InstallNetworkComponent(_In_ PCWSTR pszComponentId);
+
 /* tcpipconf_notify.c */
 HRESULT WINAPI TcpipConfigNotify_Constructor (IUnknown * pUnkOuter, REFIID 
riid, LPVOID * ppv);
 

Reply via email to