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

commit d7c1d220b550c3cd8373f1c16bd929dc6a8368cd
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Fri Nov 22 21:45:06 2024 +0100
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Mon Dec 2 23:05:38 2024 +0100

    [SETUPLIB][REACTOS][USETUP] Turn setuplib into a DLL shared between TUI and 
GUI 1st-stage setups (#7523)
    
    CORE-13525
    
    Notes:
    - Most of the exported functions have been turned from default cdecl to 
explicit stdcall / "NTAPI".
    - The two InitializeSetup() phases have been collapsed to make the 
initialization simpler.
    
    Average reductions (percentages; see PR #7523 for actual numbers):
    
    x86 Debug builds:
    reactos.exe: 35.1%
    smss.exe   : 39.8%
    Total (including setuplib.dll): 17.9%
    
    x86 Release builds:
    reactos.exe: 22.3%
    smss.exe   : 25.0%
    Total (including setuplib.dll): 10.6%
    
    x64 Debug builds:
    reactos.exe: 40.6%
    smss.exe   : 41.6%
    Total (including setuplib.dll): 20.0%
    
    x64 Release builds:
    reactos.exe: 22.8%
    smss.exe   : 22.3%
    Total (including setuplib.dll): 10.1%
---
 base/setup/lib/CMakeLists.txt                      |  14 +-
 base/setup/lib/bootsup.c                           |   4 +-
 base/setup/lib/bootsup.h                           |   2 +
 base/setup/lib/fsutil.c                            |  10 ++
 base/setup/lib/fsutil.h                            |   8 +
 base/setup/lib/install.c                           |   4 +-
 base/setup/lib/install.h                           |   2 +
 base/setup/lib/precomp.h                           |   7 +-
 base/setup/lib/setuplib.c                          | 169 +++++++++++++--------
 base/setup/lib/setuplib.h                          |  36 ++++-
 base/setup/lib/setuplib.rc                         |  16 ++
 base/setup/lib/setuplib.spec                       |  83 ++++++++++
 base/setup/lib/spapisup/fileqsup.c                 |  11 +-
 base/setup/lib/spapisup/fileqsup.h                 |  33 ++--
 base/setup/lib/spapisup/infsupp.c                  |  15 +-
 base/setup/lib/spapisup/infsupp.h                  |  61 ++++----
 base/setup/lib/utils/genlist.c                     |   9 ++
 base/setup/lib/utils/genlist.h                     |   9 ++
 base/setup/lib/utils/osdetect.c                    |  17 ++-
 base/setup/lib/utils/osdetect.h                    |  12 +-
 base/setup/lib/utils/partinfo.h                    |   4 +-
 base/setup/lib/utils/partlist.c                    |   8 +
 base/setup/lib/utils/partlist.h                    |   8 +
 base/setup/reactos/CMakeLists.txt                  |   5 +-
 base/setup/reactos/reactos.c                       |   9 +-
 base/setup/reactos/reactos.h                       |   2 -
 base/setup/reactos/spapisup/fileqsup.c             |  15 +-
 base/setup/reactos/spapisup/infsupp.c              |  23 +--
 base/setup/usetup/CMakeLists.txt                   |   4 +-
 base/setup/usetup/spapisup/fileqsup.c              |  15 +-
 base/setup/usetup/spapisup/infsupp.c               |  23 +--
 base/setup/usetup/usetup.c                         |  54 +++----
 base/setup/usetup/usetup.h                         |   1 -
 modules/rostests/unittests/setuplib/CMakeLists.txt |   3 +-
 .../unittests/setuplib/IsValidInstallDirectory.c   |  22 +--
 35 files changed, 459 insertions(+), 259 deletions(-)

diff --git a/base/setup/lib/CMakeLists.txt b/base/setup/lib/CMakeLists.txt
index 836c9ef5967..eb8ef7925a8 100644
--- a/base/setup/lib/CMakeLists.txt
+++ b/base/setup/lib/CMakeLists.txt
@@ -3,9 +3,12 @@ add_definitions(${I18N_DEFS})
 if(_WINKD_)
     add_definitions(-D_WINKD_)
 endif()
+add_definitions(-D_SETUPLIB_)
 
 include_directories(spapisup utils)
 
+spec2def(setuplib.dll setuplib.spec ADD_IMPORTLIB)
+
 list(APPEND SOURCE
     spapisup/fileqsup.c
     spapisup/infsupp.c
@@ -32,6 +35,15 @@ list(APPEND SOURCE
     setuplib.c
     precomp.h)
 
-add_library(setuplib ${SOURCE})
+add_library(setuplib SHARED
+    ${SOURCE}
+    setuplib.rc
+    ${CMAKE_CURRENT_BINARY_DIR}/setuplib.def)
+
 add_pch(setuplib precomp.h SOURCE)
 add_dependencies(setuplib xdk) # psdk
+
+set_module_type(setuplib nativedll)
+target_link_libraries(setuplib ext2lib vfatlib btrfslib ${PSEH_LIB})
+add_importlibs(setuplib ntdll)
+add_cd_file(TARGET setuplib DESTINATION reactos/system32 NO_CAB FOR bootcd 
regtest)
diff --git a/base/setup/lib/bootsup.c b/base/setup/lib/bootsup.c
index 030ffd6e54c..4c57fc8218b 100644
--- a/base/setup/lib/bootsup.c
+++ b/base/setup/lib/bootsup.c
@@ -19,7 +19,7 @@
 #include "bootcode.h"
 #include "fsutil.h"
 
-#include "setuplib.h" // HAXX for IsUnattendedSetup!!
+#include "setuplib.h" // HACK for IsUnattendedSetup
 
 #include "bootsup.h"
 
@@ -1658,6 +1658,7 @@ GetDeviceInfo(
  * @return  An NTSTATUS code indicating success or failure.
  **/
 NTSTATUS
+NTAPI
 InstallBootManagerAndBootEntries(
     _In_ ARCHITECTURE_TYPE ArchType,
     _In_ PCUNICODE_STRING SystemRootPath,
@@ -1813,6 +1814,7 @@ Quit:
 }
 
 NTSTATUS
+NTAPI
 InstallBootcodeToRemovable(
     _In_ ARCHITECTURE_TYPE ArchType,
     _In_ PCUNICODE_STRING RemovableRootPath,
diff --git a/base/setup/lib/bootsup.h b/base/setup/lib/bootsup.h
index faacff7fbb1..abbc20f0594 100644
--- a/base/setup/lib/bootsup.h
+++ b/base/setup/lib/bootsup.h
@@ -8,6 +8,7 @@
 #pragma once
 
 NTSTATUS
+NTAPI
 InstallBootManagerAndBootEntries(
     _In_ ARCHITECTURE_TYPE ArchType,
     _In_ PCUNICODE_STRING SystemRootPath,
@@ -16,6 +17,7 @@ InstallBootManagerAndBootEntries(
     _In_ ULONG_PTR Options);
 
 NTSTATUS
+NTAPI
 InstallBootcodeToRemovable(
     _In_ ARCHITECTURE_TYPE ArchType,
     _In_ PCUNICODE_STRING RemovableRootPath,
diff --git a/base/setup/lib/fsutil.c b/base/setup/lib/fsutil.c
index 875e8ec7f9d..2f4c99129c2 100644
--- a/base/setup/lib/fsutil.c
+++ b/base/setup/lib/fsutil.c
@@ -179,6 +179,7 @@ static FILE_SYSTEM RegisteredFileSystems[] =
 
 /** QueryAvailableFileSystemFormat() **/
 BOOLEAN
+NTAPI
 GetRegisteredFileSystems(
     IN ULONG Index,
     OUT PCWSTR* FileSystemName)
@@ -241,6 +242,7 @@ GetFileSystemByName(
 
 /** ChkdskEx() **/
 NTSTATUS
+NTAPI
 ChkdskFileSystem_UStr(
     _In_ PUNICODE_STRING DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -284,6 +286,7 @@ ChkdskFileSystem_UStr(
 }
 
 NTSTATUS
+NTAPI
 ChkdskFileSystem(
     _In_ PCWSTR DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -308,6 +311,7 @@ ChkdskFileSystem(
 
 /** FormatEx() **/
 NTSTATUS
+NTAPI
 FormatFileSystem_UStr(
     _In_ PUNICODE_STRING DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -373,6 +377,7 @@ FormatFileSystem_UStr(
 }
 
 NTSTATUS
+NTAPI
 FormatFileSystem(
     _In_ PCWSTR DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -754,6 +759,7 @@ Quit:
 //
 
 NTSTATUS
+NTAPI
 ChkdskVolume(
     _In_ PVOLINFO Volume,
     _In_ BOOLEAN FixErrors,
@@ -778,6 +784,7 @@ ChkdskVolume(
 }
 
 NTSTATUS
+NTAPI
 ChkdskPartition(
     _In_ PPARTENTRY PartEntry,
     _In_ BOOLEAN FixErrors,
@@ -801,6 +808,7 @@ ChkdskPartition(
 }
 
 NTSTATUS
+NTAPI
 FormatVolume(
     _In_ PVOLINFO Volume,
     _In_ PCWSTR FileSystemName,
@@ -839,6 +847,7 @@ FormatVolume(
 }
 
 NTSTATUS
+NTAPI
 FormatPartition(
     _In_ PPARTENTRY PartEntry,
     _In_ PCWSTR FileSystemName,
@@ -1084,6 +1093,7 @@ GetNextUnformattedVolume(
 }
 
 BOOLEAN
+NTAPI
 FsVolCommitOpsQueue(
     _In_ PPARTLIST PartitionList,
     _In_ PVOLENTRY SystemVolume,
diff --git a/base/setup/lib/fsutil.h b/base/setup/lib/fsutil.h
index 5af0a4265f5..a72ef381cc9 100644
--- a/base/setup/lib/fsutil.h
+++ b/base/setup/lib/fsutil.h
@@ -12,6 +12,7 @@
 
 /** QueryAvailableFileSystemFormat() **/
 BOOLEAN
+NTAPI
 GetRegisteredFileSystems(
     IN ULONG Index,
     OUT PCWSTR* FileSystemName);
@@ -19,6 +20,7 @@ GetRegisteredFileSystems(
 
 /** ChkdskEx() **/
 NTSTATUS
+NTAPI
 ChkdskFileSystem_UStr(
     _In_ PUNICODE_STRING DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -29,6 +31,7 @@ ChkdskFileSystem_UStr(
     _In_opt_ PFMIFSCALLBACK Callback);
 
 NTSTATUS
+NTAPI
 ChkdskFileSystem(
     _In_ PCWSTR DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -41,6 +44,7 @@ ChkdskFileSystem(
 
 /** FormatEx() **/
 NTSTATUS
+NTAPI
 FormatFileSystem_UStr(
     _In_ PUNICODE_STRING DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -51,6 +55,7 @@ FormatFileSystem_UStr(
     _In_opt_ PFMIFSCALLBACK Callback);
 
 NTSTATUS
+NTAPI
 FormatFileSystem(
     _In_ PCWSTR DriveRoot,
     _In_ PCWSTR FileSystemName,
@@ -109,6 +114,7 @@ InstallNtfsBootCode(
 //
 
 NTSTATUS
+NTAPI
 ChkdskPartition(
     _In_ PPARTENTRY PartEntry,
     _In_ BOOLEAN FixErrors,
@@ -118,6 +124,7 @@ ChkdskPartition(
     _In_opt_ PFMIFSCALLBACK Callback);
 
 NTSTATUS
+NTAPI
 FormatPartition(
     _In_ PPARTENTRY PartEntry,
     _In_ PCWSTR FileSystemName,
@@ -200,6 +207,7 @@ typedef FSVOL_OP
     _In_ ULONG_PTR Param2);
 
 BOOLEAN
+NTAPI
 FsVolCommitOpsQueue(
     _In_ PPARTLIST PartitionList,
     _In_ PVOLENTRY SystemVolume,
diff --git a/base/setup/lib/install.c b/base/setup/lib/install.c
index 72f3ea92181..a9bc1828db4 100644
--- a/base/setup/lib/install.c
+++ b/base/setup/lib/install.c
@@ -13,7 +13,7 @@
 #include "filesup.h"
 #include "infsupp.h"
 
-#include "setuplib.h" // HAXX for USETUP_DATA!!
+#include "setuplib.h" // HACK for USETUP_DATA
 
 #include "install.h"
 
@@ -681,6 +681,7 @@ PrepareCopyInfFile(
 // #define USE_CABINET_INF
 
 BOOLEAN // ERROR_NUMBER
+NTAPI
 PrepareFileCopy(
     IN OUT PUSETUP_DATA pSetupData,
     IN PFILE_COPY_STATUS_ROUTINE StatusRoutine OPTIONAL)
@@ -823,6 +824,7 @@ PrepareFileCopy(
 }
 
 BOOLEAN
+NTAPI
 DoFileCopy(
     IN OUT PUSETUP_DATA pSetupData,
     IN PSP_FILE_CALLBACK_W MsgHandler,
diff --git a/base/setup/lib/install.h b/base/setup/lib/install.h
index 8c3e84b3257..5b58a497726 100644
--- a/base/setup/lib/install.h
+++ b/base/setup/lib/install.h
@@ -27,11 +27,13 @@ PrepareCopyInfFile(
 #endif
 
 BOOLEAN // ERROR_NUMBER
+NTAPI
 PrepareFileCopy(
     IN OUT PUSETUP_DATA pSetupData,
     IN PFILE_COPY_STATUS_ROUTINE StatusRoutine OPTIONAL);
 
 BOOLEAN
+NTAPI
 DoFileCopy(
     IN OUT PUSETUP_DATA pSetupData,
     IN PSP_FILE_CALLBACK_W MsgHandler,
diff --git a/base/setup/lib/precomp.h b/base/setup/lib/precomp.h
index f347044d865..2195c55a9e6 100644
--- a/base/setup/lib/precomp.h
+++ b/base/setup/lib/precomp.h
@@ -29,10 +29,14 @@
 
 #include <ntstrsafe.h>
 
-
 /* Filesystem headers */
 #include <reactos/rosioctl.h>   // For extra partition IDs
 
+
+#ifndef SPLIBAPI
+#define SPLIBAPI
+#endif
+
 //
 ///* Internal Headers */
 //#include "interface/consup.h"
@@ -51,7 +55,6 @@
 //#include "filesup.h"
 //#include "genlist.h"
 
-
 extern HANDLE ProcessHeap;
 
 #include "errorcode.h"
diff --git a/base/setup/lib/setuplib.c b/base/setup/lib/setuplib.c
index 632db24ec29..862c9020719 100644
--- a/base/setup/lib/setuplib.c
+++ b/base/setup/lib/setuplib.c
@@ -22,9 +22,13 @@
 
 /* GLOBALS ******************************************************************/
 
+HANDLE ProcessHeap;
+BOOLEAN IsUnattendedSetup = FALSE;
+
 /* FUNCTIONS ****************************************************************/
 
 VOID
+NTAPI
 CheckUnattendedSetup(
     IN OUT PUSETUP_DATA pSetupData)
 {
@@ -199,6 +203,7 @@ Quit:
 }
 
 VOID
+NTAPI
 InstallSetupInfFile(
     IN OUT PUSETUP_DATA pSetupData)
 {
@@ -669,6 +674,7 @@ LoadSetupInf(
  * @brief   Find or set the active system partition.
  **/
 BOOLEAN
+NTAPI
 InitSystemPartition(
     /**/_In_ PPARTLIST PartitionList,       /* HACK HACK! */
     /**/_In_ PPARTENTRY InstallPartition,   /* HACK HACK! */
@@ -768,6 +774,7 @@ InitSystemPartition(
  * Each path component must be a valid 8.3 name.
  **/
 BOOLEAN
+NTAPI
 IsValidInstallDirectory(
     _In_ PCWSTR InstallDir)
 {
@@ -852,6 +859,7 @@ IsValidInstallDirectory(
 
 
 NTSTATUS
+NTAPI
 InitDestinationPaths(
     _Inout_ PUSETUP_DATA pSetupData,
     _In_ PCWSTR InstallationDir,
@@ -1007,92 +1015,91 @@ InitDestinationPaths(
 
 // NTSTATUS
 ERROR_NUMBER
+NTAPI
 InitializeSetup(
-    IN OUT PUSETUP_DATA pSetupData,
-    IN ULONG InitPhase)
+    _Inout_ PUSETUP_DATA pSetupData,
+    _In_opt_ PSETUP_ERROR_ROUTINE ErrorRoutine,
+    _In_ PSPFILE_EXPORTS pSpFileExports,
+    _In_ PSPINF_EXPORTS pSpInfExports)
 {
-    if (InitPhase == 0)
-    {
-        RtlZeroMemory(pSetupData, sizeof(*pSetupData));
+    ERROR_NUMBER Error;
+    NTSTATUS Status;
 
-        /* Initialize error handling */
-        pSetupData->LastErrorNumber = ERROR_SUCCESS;
-        pSetupData->ErrorRoutine = NULL;
+    IsUnattendedSetup = FALSE;
+    RtlZeroMemory(pSetupData, sizeof(*pSetupData));
 
-        /* Initialize global unicode strings */
-        RtlInitUnicodeString(&pSetupData->SourcePath, NULL);
-        RtlInitUnicodeString(&pSetupData->SourceRootPath, NULL);
-        RtlInitUnicodeString(&pSetupData->SourceRootDir, NULL);
-        RtlInitUnicodeString(&pSetupData->DestinationArcPath, NULL);
-        RtlInitUnicodeString(&pSetupData->DestinationPath, NULL);
-        RtlInitUnicodeString(&pSetupData->DestinationRootPath, NULL);
-        RtlInitUnicodeString(&pSetupData->SystemRootPath, NULL);
+    /* Initialize error handling */
+    pSetupData->LastErrorNumber = ERROR_SUCCESS;
+    pSetupData->ErrorRoutine = ErrorRoutine;
 
-        // FIXME: This is only temporary!! Must be removed later!
-        /***/RtlInitUnicodeString(&pSetupData->InstallPath, NULL);/***/
+    /* Initialize global unicode strings */
+    RtlInitUnicodeString(&pSetupData->SourcePath, NULL);
+    RtlInitUnicodeString(&pSetupData->SourceRootPath, NULL);
+    RtlInitUnicodeString(&pSetupData->SourceRootDir, NULL);
+    RtlInitUnicodeString(&pSetupData->DestinationArcPath, NULL);
+    RtlInitUnicodeString(&pSetupData->DestinationPath, NULL);
+    RtlInitUnicodeString(&pSetupData->DestinationRootPath, NULL);
+    RtlInitUnicodeString(&pSetupData->SystemRootPath, NULL);
 
-        //
-        // TODO: Load and start SetupDD, and ask it for the information
-        //
+    // FIXME: This is only temporary!! Must be removed later!
+    /***/RtlInitUnicodeString(&pSetupData->InstallPath, NULL);/***/
+
+    /* Initialize SpFile and SpInf support */
+    RtlCopyMemory(&SpFileExports, pSpFileExports, sizeof(SpFileExports));
+    RtlCopyMemory(&SpInfExports, pSpInfExports, sizeof(SpInfExports));
 
-        return ERROR_SUCCESS;
+    //
+    // TODO: Load and start SetupDD, and ask it for the information
+    //
+
+    /* Get the source path and source root path */
+    Status = GetSourcePaths(&pSetupData->SourcePath,
+                            &pSetupData->SourceRootPath,
+                            &pSetupData->SourceRootDir);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("GetSourcePaths() failed (Status 0x%08lx)\n", Status);
+        return ERROR_NO_SOURCE_DRIVE;
     }
-    else
-    if (InitPhase == 1)
+    DPRINT1("SourcePath (1): '%wZ'\n", &pSetupData->SourcePath);
+    DPRINT1("SourceRootPath (1): '%wZ'\n", &pSetupData->SourceRootPath);
+    DPRINT1("SourceRootDir (1): '%wZ'\n", &pSetupData->SourceRootDir);
+
+    /* Set up default values */
+    pSetupData->DestinationDiskNumber = 0;
+    pSetupData->DestinationPartitionNumber = 1;
+    pSetupData->BootLoaderLocation = 2; // Default to "System partition"
+    pSetupData->FormatPartition = 0;
+    pSetupData->AutoPartition = 0;
+    pSetupData->FsType = 0;
+
+    /* Load 'txtsetup.sif' from the installation media */
+    Error = LoadSetupInf(pSetupData);
+    if (Error != ERROR_SUCCESS)
     {
-        ERROR_NUMBER Error;
-        NTSTATUS Status;
+        DPRINT1("LoadSetupInf() failed (Error 0x%lx)\n", Error);
+        return Error;
+    }
+    DPRINT1("SourcePath (2): '%wZ'\n", &pSetupData->SourcePath);
+    DPRINT1("SourceRootPath (2): '%wZ'\n", &pSetupData->SourceRootPath);
+    DPRINT1("SourceRootDir (2): '%wZ'\n", &pSetupData->SourceRootDir);
 
-        /* Get the source path and source root path */
-        Status = GetSourcePaths(&pSetupData->SourcePath,
-                                &pSetupData->SourceRootPath,
-                                &pSetupData->SourceRootDir);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("GetSourcePaths() failed (Status 0x%08lx)\n", Status);
-            return ERROR_NO_SOURCE_DRIVE;
-        }
-        DPRINT1("SourcePath (1): '%wZ'\n", &pSetupData->SourcePath);
-        DPRINT1("SourceRootPath (1): '%wZ'\n", &pSetupData->SourceRootPath);
-        DPRINT1("SourceRootDir (1): '%wZ'\n", &pSetupData->SourceRootDir);
-
-        /* Set up default values */
-        pSetupData->DestinationDiskNumber = 0;
-        pSetupData->DestinationPartitionNumber = 1;
-        pSetupData->BootLoaderLocation = 2; // Default to "System partition"
-        pSetupData->FormatPartition = 0;
-        pSetupData->AutoPartition = 0;
-        pSetupData->FsType = 0;
-
-        /* Load 'txtsetup.sif' from the installation media */
-        Error = LoadSetupInf(pSetupData);
-        if (Error != ERROR_SUCCESS)
-        {
-            DPRINT1("LoadSetupInf() failed (Error 0x%lx)\n", Error);
-            return Error;
-        }
-        DPRINT1("SourcePath (2): '%wZ'\n", &pSetupData->SourcePath);
-        DPRINT1("SourceRootPath (2): '%wZ'\n", &pSetupData->SourceRootPath);
-        DPRINT1("SourceRootDir (2): '%wZ'\n", &pSetupData->SourceRootDir);
-
-        /* Retrieve the target machine architecture type */
-        // FIXME: This should be determined at runtime!!
-        // FIXME: Allow for (pre-)installing on an architecture
-        //        different from the current one?
+    /* Retrieve the target machine architecture type */
+    // FIXME: This should be determined at runtime!!
+    // FIXME: Allow for (pre-)installing on an architecture
+    //        different from the current one?
 #if defined(SARCH_XBOX)
-        pSetupData->ArchType = ARCH_Xbox;
+    pSetupData->ArchType = ARCH_Xbox;
 // #elif defined(SARCH_PC98)
 #else // TODO: Arc, UEFI
-        pSetupData->ArchType = (IsNEC_98 ? ARCH_NEC98x86 : ARCH_PcAT);
+    pSetupData->ArchType = (IsNEC_98 ? ARCH_NEC98x86 : ARCH_PcAT);
 #endif
 
-        return ERROR_SUCCESS;
-    }
-
     return ERROR_SUCCESS;
 }
 
 VOID
+NTAPI
 FinishSetup(
     IN OUT PUSETUP_DATA pSetupData)
 {
@@ -1143,6 +1150,7 @@ FinishSetup(
  *  Calls SetMountedDeviceValues
  */
 ERROR_NUMBER
+NTAPI
 UpdateRegistry(
     IN OUT PUSETUP_DATA pSetupData,
     /**/IN BOOLEAN RepairUpdateFlag,     /* HACK HACK! */
@@ -1396,4 +1404,31 @@ Cleanup:
     return ErrorNumber;
 }
 
+
+/* ENTRY-POINT ***************************************************************/
+
+/* Declared in ndk/umfuncs.h */
+NTSTATUS
+NTAPI
+LdrDisableThreadCalloutsForDll(
+    _In_ PVOID BaseAddress);
+
+BOOL
+NTAPI
+DllMain(
+    _In_ HINSTANCE hDll,
+    _In_ ULONG dwReason,
+    _In_opt_ PVOID pReserved)
+{
+    UNREFERENCED_PARAMETER(pReserved);
+
+    if (dwReason == DLL_PROCESS_ATTACH)
+    {
+        LdrDisableThreadCalloutsForDll(hDll);
+        ProcessHeap = RtlGetProcessHeap();
+    }
+
+    return TRUE;
+}
+
 /* EOF */
diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h
index a69f7bba877..d969e894e8a 100644
--- a/base/setup/lib/setuplib.h
+++ b/base/setup/lib/setuplib.h
@@ -7,6 +7,16 @@
 
 #pragma once
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _SETUPLIB_
+#define SPLIBAPI DECLSPEC_IMPORT
+#else
+#define SPLIBAPI
+#endif
+
 /* INCLUDES *****************************************************************/
 
 /* Needed PSDK headers when using this library */
@@ -20,9 +30,9 @@
 
 #endif
 
-/* NOTE: Please keep the header inclusion order! */
+extern SPLIBAPI BOOLEAN IsUnattendedSetup; // HACK
 
-extern HANDLE ProcessHeap;
+/* NOTE: Please keep the header inclusion order! */
 
 #include "errorcode.h"
 #include "spapisup/fileqsup.h"
@@ -153,19 +163,17 @@ typedef struct _USETUP_DATA
 #include "install.h"
 
 
-// HACK!!
-extern BOOLEAN IsUnattendedSetup;
-
-
 /* FUNCTIONS ****************************************************************/
 
 #include "substset.h"
 
 VOID
+NTAPI
 CheckUnattendedSetup(
     IN OUT PUSETUP_DATA pSetupData);
 
 VOID
+NTAPI
 InstallSetupInfFile(
     IN OUT PUSETUP_DATA pSetupData);
 
@@ -182,6 +190,7 @@ LoadSetupInf(
 #define ERROR_SYSTEM_PARTITION_NOT_FOUND    (ERROR_LAST_ERROR_CODE + 1)
 
 BOOLEAN
+NTAPI
 InitSystemPartition(
     /**/_In_ PPARTLIST PartitionList,       /* HACK HACK! */
     /**/_In_ PPARTENTRY InstallPartition,   /* HACK HACK! */
@@ -200,10 +209,12 @@ InitSystemPartition(
     (isalnum(c) || (c) == L'.' || (c) == L'\\' || (c) == L'-' || (c) == L'_')
 
 BOOLEAN
+NTAPI
 IsValidInstallDirectory(
     _In_ PCWSTR InstallDir);
 
 NTSTATUS
+NTAPI
 InitDestinationPaths(
     _Inout_ PUSETUP_DATA pSetupData,
     _In_ PCWSTR InstallationDir,
@@ -211,11 +222,15 @@ InitDestinationPaths(
 
 // NTSTATUS
 ERROR_NUMBER
+NTAPI
 InitializeSetup(
-    IN OUT PUSETUP_DATA pSetupData,
-    IN ULONG InitPhase);
+    _Inout_ PUSETUP_DATA pSetupData,
+    _In_opt_ PSETUP_ERROR_ROUTINE ErrorRoutine,
+    _In_ PSPFILE_EXPORTS pSpFileExports,
+    _In_ PSPINF_EXPORTS pSpInfExports);
 
 VOID
+NTAPI
 FinishSetup(
     IN OUT PUSETUP_DATA pSetupData);
 
@@ -236,6 +251,7 @@ typedef VOID
 (__cdecl *PREGISTRY_STATUS_ROUTINE)(IN REGISTRY_STATUS, ...);
 
 ERROR_NUMBER
+NTAPI
 UpdateRegistry(
     IN OUT PUSETUP_DATA pSetupData,
     /**/IN BOOLEAN RepairUpdateFlag,     /* HACK HACK! */
@@ -245,4 +261,8 @@ UpdateRegistry(
     IN PREGISTRY_STATUS_ROUTINE StatusRoutine OPTIONAL,
     IN PFONTSUBSTSETTINGS SubstSettings OPTIONAL);
 
+#ifdef __cplusplus
+}
+#endif
+
 /* EOF */
diff --git a/base/setup/lib/setuplib.rc b/base/setup/lib/setuplib.rc
new file mode 100644
index 00000000000..072bfd23722
--- /dev/null
+++ b/base/setup/lib/setuplib.rc
@@ -0,0 +1,16 @@
+/*
+ * PROJECT:     ReactOS Setup Library
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Resources
+ * COPYRIGHT:   Copyright 2003-2024 ReactOS Team
+ */
+
+#include <windef.h>
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION    "ReactOS Setup Library DLL"
+#define REACTOS_STR_INTERNAL_NAME       "setuplib"
+#define REACTOS_STR_ORIGINAL_FILENAME   "setuplib.dll"
+#include <reactos/version.rc>
diff --git a/base/setup/lib/setuplib.spec b/base/setup/lib/setuplib.spec
new file mode 100644
index 00000000000..a2809a06b0a
--- /dev/null
+++ b/base/setup/lib/setuplib.spec
@@ -0,0 +1,83 @@
+
+@ extern IsUnattendedSetup
+@ extern MbrPartitionTypes
+@ extern GptPartitionTypes
+
+;; fileqsup and infsupp function pointers to be initialized by the user of 
this library
+;;@ extern SpFileExports
+;;@ extern SpInfExports
+
+;; infsupp
+@ cdecl INF_GetDataField(ptr long ptr)  ## -private
+
+
+;; filesup
+@ cdecl ConcatPathsV(ptr long long ptr)
+@ cdecl CombinePathsV(ptr long long ptr)
+@ varargs ConcatPaths(ptr long long)
+@ varargs CombinePaths(ptr long long)
+@ cdecl SetupCopyFile(wstr wstr long)
+@ cdecl SetupDeleteFile(wstr long)
+@ cdecl SetupMoveFile(wstr wstr long)
+
+;; genlist
+@ stdcall CreateGenericList()
+@ stdcall DestroyGenericList(ptr long)
+@ stdcall GetCurrentListEntry(ptr)
+@ stdcall GetFirstListEntry(ptr)
+@ stdcall GetNextListEntry(ptr)
+@ stdcall GetListEntryData(ptr)
+@ stdcall GetNumberOfListEntries(ptr)
+@ stdcall SetCurrentListEntry(ptr ptr)
+
+;; partlist
+@ stdcall CreatePartitionList()
+@ stdcall CreatePartition(ptr ptr int64 ptr)
+@ stdcall DeletePartition(ptr ptr ptr)
+@ stdcall DestroyPartitionList(ptr)
+@ stdcall GetNextPartition(ptr ptr)
+@ stdcall GetPrevPartition(ptr ptr)
+@ stdcall GetAdjUnpartitionedEntry(ptr long)
+@ stdcall PartitionCreateChecks(ptr int64 ptr)
+@ cdecl -ret64 RoundingDivide(int64 int64)
+;;;;
+@ cdecl IsPartitionActive(ptr)          ## -private
+@ cdecl SelectPartition(ptr long long)
+
+;; osdetect
+@ stdcall CreateNTOSInstallationsList(ptr)
+@ stdcall FindSubStrI(wstr wstr)
+
+;; settings
+@ cdecl CreateComputerTypeList(ptr)
+@ cdecl CreateDisplayDriverList(ptr)
+@ cdecl CreateKeyboardDriverList(ptr)
+@ cdecl CreateKeyboardLayoutList(ptr wstr ptr)
+@ cdecl CreateLanguageList(ptr ptr)
+@ cdecl GetDefaultLanguageIndex()
+
+;; mui
+@ cdecl MUIDefaultKeyboardLayout(wstr)
+@ cdecl MUIGetOEMCodePage(wstr)         ## -private
+
+;; setuplib
+@ stdcall CheckUnattendedSetup(ptr)
+@ stdcall FinishSetup(ptr)
+@ stdcall IsValidInstallDirectory(wstr)
+@ stdcall InitDestinationPaths(ptr wstr ptr)
+@ stdcall InitializeSetup(ptr ptr ptr ptr)
+@ stdcall InitSystemPartition(ptr ptr ptr ptr ptr)
+@ stdcall InstallSetupInfFile(ptr)
+@ stdcall UpdateRegistry(ptr long ptr long wstr ptr ptr)
+
+;; fsutil
+@ stdcall FsVolCommitOpsQueue(ptr ptr ptr ptr ptr)
+@ stdcall GetRegisteredFileSystems(long ptr)
+
+;; install
+@ stdcall PrepareFileCopy(ptr ptr)
+@ stdcall DoFileCopy(ptr ptr ptr)
+
+;; bootsup
+@ stdcall InstallBootManagerAndBootEntries(long ptr ptr ptr ptr)
+@ stdcall InstallBootcodeToRemovable(long ptr ptr ptr)
diff --git a/base/setup/lib/spapisup/fileqsup.c 
b/base/setup/lib/spapisup/fileqsup.c
index 34da6a45803..6b095fc5960 100644
--- a/base/setup/lib/spapisup/fileqsup.c
+++ b/base/setup/lib/spapisup/fileqsup.c
@@ -20,15 +20,6 @@
  * These externs should be defined by the user of this library.
  * They are kept there for reference and ease of usage.
  */
-#if 0
-
-pSpFileQueueOpen   SpFileQueueOpen   = NULL;
-pSpFileQueueClose  SpFileQueueClose  = NULL;
-pSpFileQueueCopy   SpFileQueueCopy   = NULL;
-pSpFileQueueDelete SpFileQueueDelete = NULL;
-pSpFileQueueRename SpFileQueueRename = NULL;
-pSpFileQueueCommit SpFileQueueCommit = NULL;
-
-#endif
+SPFILE_EXPORTS SpFileExports = {NULL};
 
 /* EOF */
diff --git a/base/setup/lib/spapisup/fileqsup.h 
b/base/setup/lib/spapisup/fileqsup.h
index c6cc3839c1b..ffa41efe334 100644
--- a/base/setup/lib/spapisup/fileqsup.h
+++ b/base/setup/lib/spapisup/fileqsup.h
@@ -51,7 +51,7 @@
 #define FILEOP_NEWPATH                  4
 
 
-/* TYPES ********************************************************************/
+/* TYPES *********************************************************************/
 
 typedef PVOID HSPFILEQ;
 
@@ -72,21 +72,17 @@ typedef UINT (CALLBACK* PSP_FILE_CALLBACK_W)(
 #endif
 
 
-/* FUNCTIONS ****************************************************************/
+/* FUNCTIONS *****************************************************************/
 
 // #define SetupOpenFileQueue
 typedef HSPFILEQ
 (WINAPI* pSpFileQueueOpen)(VOID);
 
-extern pSpFileQueueOpen SpFileQueueOpen;
-
 // #define SetupCloseFileQueue
 typedef BOOL
 (WINAPI* pSpFileQueueClose)(
     IN HSPFILEQ QueueHandle);
 
-extern pSpFileQueueClose SpFileQueueClose;
-
 // #define SetupQueueCopyW
 typedef BOOL
 (WINAPI* pSpFileQueueCopy)(
@@ -101,8 +97,6 @@ typedef BOOL
     IN PCWSTR TargetFileName OPTIONAL,
     IN ULONG CopyStyle);
 
-extern pSpFileQueueCopy SpFileQueueCopy;
-
 // #define SetupQueueDeleteW
 typedef BOOL
 (WINAPI* pSpFileQueueDelete)(
@@ -110,8 +104,6 @@ typedef BOOL
     IN PCWSTR PathPart1,
     IN PCWSTR PathPart2 OPTIONAL);
 
-extern pSpFileQueueDelete SpFileQueueDelete;
-
 // #define SetupQueueRenameW
 typedef BOOL
 (WINAPI* pSpFileQueueRename)(
@@ -121,8 +113,6 @@ typedef BOOL
     IN PCWSTR TargetPath OPTIONAL,
     IN PCWSTR TargetFileName);
 
-extern pSpFileQueueRename SpFileQueueRename;
-
 // #define SetupCommitFileQueueW
 typedef BOOL
 (WINAPI* pSpFileQueueCommit)(
@@ -131,6 +121,23 @@ typedef BOOL
     IN PSP_FILE_CALLBACK_W MsgHandler,
     IN PVOID Context OPTIONAL);
 
-extern pSpFileQueueCommit SpFileQueueCommit;
+typedef struct _SPFILE_EXPORTS
+{
+    pSpFileQueueOpen   SpFileQueueOpen;
+    pSpFileQueueClose  SpFileQueueClose;
+    pSpFileQueueCopy   SpFileQueueCopy;
+    pSpFileQueueDelete SpFileQueueDelete;
+    pSpFileQueueRename SpFileQueueRename;
+    pSpFileQueueCommit SpFileQueueCommit;
+} SPFILE_EXPORTS, *PSPFILE_EXPORTS;
+
+extern /*SPLIBAPI*/ SPFILE_EXPORTS SpFileExports;
+
+#define SpFileQueueOpen     (SpFileExports.SpFileQueueOpen)
+#define SpFileQueueClose    (SpFileExports.SpFileQueueClose)
+#define SpFileQueueCopy     (SpFileExports.SpFileQueueCopy)
+#define SpFileQueueDelete   (SpFileExports.SpFileQueueDelete)
+#define SpFileQueueRename   (SpFileExports.SpFileQueueRename)
+#define SpFileQueueCommit   (SpFileExports.SpFileQueueCommit)
 
 /* EOF */
diff --git a/base/setup/lib/spapisup/infsupp.c 
b/base/setup/lib/spapisup/infsupp.c
index 65bdbd23e6a..fdf3e35664f 100644
--- a/base/setup/lib/spapisup/infsupp.c
+++ b/base/setup/lib/spapisup/infsupp.c
@@ -21,20 +21,7 @@
  * These externs should be defined by the user of this library.
  * They are kept there for reference and ease of usage.
  */
-#if 0
-
-pSpInfCloseInfFile  SpInfCloseInfFile  = NULL;
-pSpInfFindFirstLine SpInfFindFirstLine = NULL;
-pSpInfFindNextLine  SpInfFindNextLine  = NULL;
-pSpInfGetFieldCount SpInfGetFieldCount = NULL;
-pSpInfGetBinaryField  SpInfGetBinaryField  = NULL;
-pSpInfGetIntField     SpInfGetIntField     = NULL;
-pSpInfGetMultiSzField SpInfGetMultiSzField = NULL;
-pSpInfGetStringField  SpInfGetStringField  = NULL;
-pSpInfGetField    SpInfGetField    = NULL;
-pSpInfOpenInfFile SpInfOpenInfFile = NULL;
-
-#endif
+SPINF_EXPORTS SpInfExports = {NULL};
 
 /* HELPER FUNCTIONS **********************************************************/
 
diff --git a/base/setup/lib/spapisup/infsupp.h 
b/base/setup/lib/spapisup/infsupp.h
index c5d24ca6b71..0a2adef49fd 100644
--- a/base/setup/lib/spapisup/infsupp.h
+++ b/base/setup/lib/spapisup/infsupp.h
@@ -29,6 +29,8 @@ typedef struct _INFCONTEXT
 
 #endif
 
+C_ASSERT(sizeof(INFCONTEXT) == 2 * sizeof(HINF) + 2 * sizeof(UINT));
+
 /* Lower the MAX_INF_STRING_LENGTH value in order to avoid too much stack 
usage */
 #undef MAX_INF_STRING_LENGTH
 #define MAX_INF_STRING_LENGTH   1024 // Still larger than in infcommon.h
@@ -41,27 +43,14 @@ typedef struct _INFCONTEXT
 #define INF_STYLE_WIN4  0x00000002
 #endif
 
-#if 0
-typedef PVOID HINF;
-typedef struct _INFCONTEXT
-{
-    HINF Inf;
-    HINF CurrentInf;
-    UINT Section;
-    UINT Line;
-} INFCONTEXT, *PINFCONTEXT;
-#endif
-
-C_ASSERT(sizeof(INFCONTEXT) == 2 * sizeof(HINF) + 2 * sizeof(UINT));
 
+/* FUNCTIONS *****************************************************************/
 
 // #define SetupCloseInfFile InfCloseFile
 typedef VOID
 (WINAPI* pSpInfCloseInfFile)(
     IN HINF InfHandle);
 
-extern pSpInfCloseInfFile SpInfCloseInfFile;
-
 // #define SetupFindFirstLineW InfpFindFirstLineW
 typedef BOOL
 (WINAPI* pSpInfFindFirstLine)(
@@ -70,23 +59,17 @@ typedef BOOL
     IN PCWSTR Key,
     IN OUT PINFCONTEXT Context);
 
-extern pSpInfFindFirstLine SpInfFindFirstLine;
-
 // #define SetupFindNextLine InfFindNextLine
 typedef BOOL
 (WINAPI* pSpInfFindNextLine)(
     IN  PINFCONTEXT ContextIn,
     OUT PINFCONTEXT ContextOut);
 
-extern pSpInfFindNextLine SpInfFindNextLine;
-
 // #define SetupGetFieldCount InfGetFieldCount
 typedef ULONG
 (WINAPI* pSpInfGetFieldCount)(
     IN PINFCONTEXT Context);
 
-extern pSpInfGetFieldCount SpInfGetFieldCount;
-
 // #define SetupGetBinaryField InfGetBinaryField
 typedef BOOL
 (WINAPI* pSpInfGetBinaryField)(
@@ -96,8 +79,6 @@ typedef BOOL
     IN  ULONG ReturnBufferSize,
     OUT PULONG RequiredSize);
 
-extern pSpInfGetBinaryField SpInfGetBinaryField;
-
 // #define SetupGetIntField InfGetIntField
 typedef BOOL
 (WINAPI* pSpInfGetIntField)(
@@ -105,8 +86,6 @@ typedef BOOL
     IN ULONG FieldIndex,
     OUT INT *IntegerValue); // PINT
 
-extern pSpInfGetIntField SpInfGetIntField;
-
 // #define SetupGetMultiSzFieldW InfGetMultiSzField
 typedef BOOL
 (WINAPI* pSpInfGetMultiSzField)(
@@ -116,8 +95,6 @@ typedef BOOL
     IN  ULONG ReturnBufferSize,
     OUT PULONG RequiredSize);
 
-extern pSpInfGetMultiSzField SpInfGetMultiSzField;
-
 // #define SetupGetStringFieldW InfGetStringField
 typedef BOOL
 (WINAPI* pSpInfGetStringField)(
@@ -127,16 +104,12 @@ typedef BOOL
     IN  ULONG ReturnBufferSize,
     OUT PULONG RequiredSize);
 
-extern pSpInfGetStringField SpInfGetStringField;
-
 // #define pSetupGetField
 typedef PCWSTR
 (WINAPI* pSpInfGetField)(
     IN PINFCONTEXT Context,
     IN ULONG FieldIndex);
 
-extern pSpInfGetField SpInfGetField;
-
 /* A version of SetupOpenInfFileW with support for a user-provided LCID */
 // #define SetupOpenInfFileExW InfpOpenInfFileW
 typedef HINF
@@ -147,8 +120,32 @@ typedef HINF
     IN LCID LocaleId,
     OUT PUINT ErrorLine);
 
-extern pSpInfOpenInfFile SpInfOpenInfFile;
-
+typedef struct _SPINF_EXPORTS
+{
+    pSpInfCloseInfFile    SpInfCloseInfFile;
+    pSpInfFindFirstLine   SpInfFindFirstLine;
+    pSpInfFindNextLine    SpInfFindNextLine;
+    pSpInfGetFieldCount   SpInfGetFieldCount;
+    pSpInfGetBinaryField  SpInfGetBinaryField;
+    pSpInfGetIntField     SpInfGetIntField;
+    pSpInfGetMultiSzField SpInfGetMultiSzField;
+    pSpInfGetStringField  SpInfGetStringField;
+    pSpInfGetField        SpInfGetField;
+    pSpInfOpenInfFile     SpInfOpenInfFile;
+} SPINF_EXPORTS, *PSPINF_EXPORTS;
+
+extern /*SPLIBAPI*/ SPINF_EXPORTS SpInfExports;
+
+#define SpInfCloseInfFile       (SpInfExports.SpInfCloseInfFile)
+#define SpInfFindFirstLine      (SpInfExports.SpInfFindFirstLine)
+#define SpInfFindNextLine       (SpInfExports.SpInfFindNextLine)
+#define SpInfGetFieldCount      (SpInfExports.SpInfGetFieldCount)
+#define SpInfGetBinaryField     (SpInfExports.SpInfGetBinaryField)
+#define SpInfGetIntField        (SpInfExports.SpInfGetIntField)
+#define SpInfGetMultiSzField    (SpInfExports.SpInfGetMultiSzField)
+#define SpInfGetStringField     (SpInfExports.SpInfGetStringField)
+#define SpInfGetField           (SpInfExports.SpInfGetField)
+#define SpInfOpenInfFile        (SpInfExports.SpInfOpenInfFile)
 
 /* HELPER FUNCTIONS **********************************************************/
 
diff --git a/base/setup/lib/utils/genlist.c b/base/setup/lib/utils/genlist.c
index 79a4895075c..c204eacb1bf 100644
--- a/base/setup/lib/utils/genlist.c
+++ b/base/setup/lib/utils/genlist.c
@@ -17,6 +17,7 @@
 /* FUNCTIONS ****************************************************************/
 
 PGENERIC_LIST
+NTAPI
 CreateGenericList(VOID)
 {
     PGENERIC_LIST List;
@@ -33,6 +34,7 @@ CreateGenericList(VOID)
 }
 
 VOID
+NTAPI
 DestroyGenericList(
     IN OUT PGENERIC_LIST List,
     IN BOOLEAN FreeData)
@@ -59,6 +61,7 @@ DestroyGenericList(
 }
 
 BOOLEAN
+NTAPI
 AppendGenericListEntry(
     IN OUT PGENERIC_LIST List,
     IN PVOID Data,
@@ -84,6 +87,7 @@ AppendGenericListEntry(
 }
 
 VOID
+NTAPI
 SetCurrentListEntry(
     IN PGENERIC_LIST List,
     IN PGENERIC_LIST_ENTRY Entry)
@@ -94,6 +98,7 @@ SetCurrentListEntry(
 }
 
 PGENERIC_LIST_ENTRY
+NTAPI
 GetCurrentListEntry(
     IN PGENERIC_LIST List)
 {
@@ -101,6 +106,7 @@ GetCurrentListEntry(
 }
 
 PGENERIC_LIST_ENTRY
+NTAPI
 GetFirstListEntry(
     IN PGENERIC_LIST List)
 {
@@ -111,6 +117,7 @@ GetFirstListEntry(
 }
 
 PGENERIC_LIST_ENTRY
+NTAPI
 GetNextListEntry(
     IN PGENERIC_LIST_ENTRY Entry)
 {
@@ -123,6 +130,7 @@ GetNextListEntry(
 }
 
 PVOID
+NTAPI
 GetListEntryData(
     IN PGENERIC_LIST_ENTRY Entry)
 {
@@ -137,6 +145,7 @@ GetListEntryUiData(
 }
 
 ULONG
+NTAPI
 GetNumberOfListEntries(
     IN PGENERIC_LIST List)
 {
diff --git a/base/setup/lib/utils/genlist.h b/base/setup/lib/utils/genlist.h
index ea3c7473bf5..d8ccd64260e 100644
--- a/base/setup/lib/utils/genlist.h
+++ b/base/setup/lib/utils/genlist.h
@@ -24,37 +24,45 @@ typedef struct _GENERIC_LIST
 
 
 PGENERIC_LIST
+NTAPI
 CreateGenericList(VOID);
 
 VOID
+NTAPI
 DestroyGenericList(
     IN OUT PGENERIC_LIST List,
     IN BOOLEAN FreeData);
 
 BOOLEAN
+NTAPI
 AppendGenericListEntry(
     IN OUT PGENERIC_LIST List,
     IN PVOID Data,
     IN BOOLEAN Current);
 
 VOID
+NTAPI
 SetCurrentListEntry(
     IN PGENERIC_LIST List,
     IN PGENERIC_LIST_ENTRY Entry);
 
 PGENERIC_LIST_ENTRY
+NTAPI
 GetCurrentListEntry(
     IN PGENERIC_LIST List);
 
 PGENERIC_LIST_ENTRY
+NTAPI
 GetFirstListEntry(
     IN PGENERIC_LIST List);
 
 PGENERIC_LIST_ENTRY
+NTAPI
 GetNextListEntry(
     IN PGENERIC_LIST_ENTRY Entry);
 
 PVOID
+NTAPI
 GetListEntryData(
     IN PGENERIC_LIST_ENTRY Entry);
 
@@ -63,6 +71,7 @@ GetListEntryUiData(
     IN PGENERIC_LIST_ENTRY Entry);
 
 ULONG
+NTAPI
 GetNumberOfListEntries(
     IN PGENERIC_LIST List);
 
diff --git a/base/setup/lib/utils/osdetect.c b/base/setup/lib/utils/osdetect.c
index 1a4abd5cb6a..2d5ccd4a2dc 100644
--- a/base/setup/lib/utils/osdetect.c
+++ b/base/setup/lib/utils/osdetect.c
@@ -209,12 +209,16 @@ EnumerateInstallations(
     return STATUS_SUCCESS;
 }
 
-/*
- * FindSubStrI(PCWSTR str, PCWSTR strSearch) :
- *    Searches for a sub-string 'strSearch' inside 'str', similarly to what
- *    wcsstr(str, strSearch) does, but ignores the case during the comparisons.
- */
-PCWSTR FindSubStrI(PCWSTR str, PCWSTR strSearch)
+/**
+ * @brief
+ * Finds the first occurrence of a sub-string 'strSearch' inside 'str',
+ * using case-insensitive comparisons.
+ **/
+PCWSTR
+NTAPI
+FindSubStrI(
+    _In_ PCWSTR str,
+    _In_ PCWSTR strSearch)
 {
     PCWSTR cp = str;
     PCWSTR s1, s2;
@@ -760,6 +764,7 @@ FindNTOSInstallations(
  **/
 // EnumerateNTOSInstallations
 PGENERIC_LIST
+NTAPI
 CreateNTOSInstallationsList(
     _In_ PPARTLIST PartList)
 {
diff --git a/base/setup/lib/utils/osdetect.h b/base/setup/lib/utils/osdetect.h
index e329b1c32f4..fc30aec6367 100644
--- a/base/setup/lib/utils/osdetect.h
+++ b/base/setup/lib/utils/osdetect.h
@@ -30,14 +30,14 @@ typedef struct _NTOS_INSTALLATION
 
 // EnumerateNTOSInstallations
 PGENERIC_LIST
+NTAPI
 CreateNTOSInstallationsList(
     _In_ PPARTLIST PartList);
 
-/*
- * FindSubStrI(PCWSTR str, PCWSTR strSearch) :
- *    Searches for a sub-string 'strSearch' inside 'str', similarly to what
- *    wcsstr(str, strSearch) does, but ignores the case during the comparisons.
- */
-PCWSTR FindSubStrI(PCWSTR str, PCWSTR strSearch);
+PCWSTR
+NTAPI
+FindSubStrI(
+    _In_ PCWSTR str,
+    _In_ PCWSTR strSearch);
 
 /* EOF */
diff --git a/base/setup/lib/utils/partinfo.h b/base/setup/lib/utils/partinfo.h
index d1c598aba90..dac7af89158 100644
--- a/base/setup/lib/utils/partinfo.h
+++ b/base/setup/lib/utils/partinfo.h
@@ -16,7 +16,7 @@ typedef struct _MBR_PARTITION_TYPE
 } MBR_PARTITION_TYPE, *PMBR_PARTITION_TYPE;
 
 #define NUM_MBR_PARTITION_TYPES 153
-extern const MBR_PARTITION_TYPE MbrPartitionTypes[NUM_MBR_PARTITION_TYPES];
+extern SPLIBAPI const MBR_PARTITION_TYPE 
MbrPartitionTypes[NUM_MBR_PARTITION_TYPES];
 
 /* GPT PARTITION TYPES ******************************************************/
 
@@ -27,6 +27,6 @@ typedef struct _GPT_PARTITION_TYPE
 } GPT_PARTITION_TYPE, *PGPT_PARTITION_TYPE;
 
 #define NUM_GPT_PARTITION_TYPES 177
-extern const GPT_PARTITION_TYPE GptPartitionTypes[NUM_GPT_PARTITION_TYPES];
+extern SPLIBAPI const GPT_PARTITION_TYPE 
GptPartitionTypes[NUM_GPT_PARTITION_TYPES];
 
 /* EOF */
diff --git a/base/setup/lib/utils/partlist.c b/base/setup/lib/utils/partlist.c
index b138c9abdca..59ad7843c46 100644
--- a/base/setup/lib/utils/partlist.c
+++ b/base/setup/lib/utils/partlist.c
@@ -1984,6 +1984,7 @@ GetActiveDiskPartition(
 }
 
 PPARTLIST
+NTAPI
 CreatePartitionList(VOID)
 {
     PPARTLIST List;
@@ -2069,6 +2070,7 @@ CreatePartitionList(VOID)
 }
 
 VOID
+NTAPI
 DestroyPartitionList(
     IN PPARTLIST List)
 {
@@ -2288,6 +2290,7 @@ SelectPartition(
 }
 
 PPARTENTRY
+NTAPI
 GetNextPartition(
     IN PPARTLIST List,
     IN PPARTENTRY CurrentPart OPTIONAL)
@@ -2380,6 +2383,7 @@ GetNextPartition(
 }
 
 PPARTENTRY
+NTAPI
 GetPrevPartition(
     IN PPARTLIST List,
     IN PPARTENTRY CurrentPart OPTIONAL)
@@ -2783,6 +2787,7 @@ UpdateDiskLayout(
  * @return  The adjacent unpartitioned region, if it exists, or NULL.
  **/
 PPARTENTRY
+NTAPI
 GetAdjUnpartitionedEntry(
     _In_ PPARTENTRY PartEntry,
     _In_ BOOLEAN Direction)
@@ -2872,6 +2877,7 @@ MBRPartitionCreateChecks(
 }
 
 ERROR_NUMBER
+NTAPI
 PartitionCreateChecks(
     _In_ PPARTENTRY PartEntry,
     _In_opt_ ULONGLONG SizeBytes,
@@ -2900,6 +2906,7 @@ PartitionCreateChecks(
 // (see VDS::CREATE_PARTITION_PARAMETERS and PPARTITION_INFORMATION_MBR/GPT 
for example)
 // So far we only use it as the optional type of the partition to create.
 BOOLEAN
+NTAPI
 CreatePartition(
     _In_ PPARTLIST List,
     _Inout_ PPARTENTRY PartEntry,
@@ -2990,6 +2997,7 @@ DismountPartition(
 }
 
 BOOLEAN
+NTAPI
 DeletePartition(
     _In_ PPARTLIST List,
     _In_ PPARTENTRY PartEntry,
diff --git a/base/setup/lib/utils/partlist.h b/base/setup/lib/utils/partlist.h
index 71b9eb99181..03d7999d11b 100644
--- a/base/setup/lib/utils/partlist.h
+++ b/base/setup/lib/utils/partlist.h
@@ -283,9 +283,11 @@ IsPartitionActive(
     IN PPARTENTRY PartEntry);
 
 PPARTLIST
+NTAPI
 CreatePartitionList(VOID);
 
 VOID
+NTAPI
 DestroyPartitionList(
     IN PPARTLIST List);
 
@@ -323,27 +325,32 @@ SelectPartition(
     _In_ ULONG PartitionNumber);
 
 PPARTENTRY
+NTAPI
 GetNextPartition(
     IN PPARTLIST List,
     IN PPARTENTRY CurrentPart OPTIONAL);
 
 PPARTENTRY
+NTAPI
 GetPrevPartition(
     IN PPARTLIST List,
     IN PPARTENTRY CurrentPart OPTIONAL);
 
 PPARTENTRY
+NTAPI
 GetAdjUnpartitionedEntry(
     _In_ PPARTENTRY PartEntry,
     _In_ BOOLEAN Direction);
 
 ERROR_NUMBER
+NTAPI
 PartitionCreateChecks(
     _In_ PPARTENTRY PartEntry,
     _In_opt_ ULONGLONG SizeBytes,
     _In_opt_ ULONG_PTR PartitionInfo);
 
 BOOLEAN
+NTAPI
 CreatePartition(
     _In_ PPARTLIST List,
     _Inout_ PPARTENTRY PartEntry,
@@ -351,6 +358,7 @@ CreatePartition(
     _In_opt_ ULONG_PTR PartitionInfo);
 
 BOOLEAN
+NTAPI
 DeletePartition(
     _In_ PPARTLIST List,
     _In_ PPARTENTRY PartEntry,
diff --git a/base/setup/reactos/CMakeLists.txt 
b/base/setup/reactos/CMakeLists.txt
index 23adc345081..92dbb317904 100644
--- a/base/setup/reactos/CMakeLists.txt
+++ b/base/setup/reactos/CMakeLists.txt
@@ -17,9 +17,10 @@ list(APPEND SOURCE
 file(GLOB reactos_rc_deps res/*.*)
 add_rc_deps(reactos.rc ${reactos_rc_deps})
 add_executable(reactos ${SOURCE} reactos.rc)
+
 add_pch(reactos reactos.h SOURCE)
 set_module_type(reactos win32gui UNICODE)
-target_link_libraries(reactos uuid setuplib ext2lib vfatlib btrfslib 
${PSEH_LIB})
+target_link_libraries(reactos uuid)
 target_link_libraries(reactos zlib_solo) ## We use USETUP's cabinet 
implementation
-add_importlibs(reactos advapi32 gdi32 user32 comctl32 shlwapi setupapi msvcrt 
kernel32 ntdll)
+add_importlibs(reactos advapi32 gdi32 user32 comctl32 shlwapi setupapi 
setuplib msvcrt kernel32 ntdll)
 add_cd_file(TARGET reactos DESTINATION reactos NO_CAB FOR bootcd)
diff --git a/base/setup/reactos/reactos.c b/base/setup/reactos/reactos.c
index 3909f104e20..fe169bd3ee9 100644
--- a/base/setup/reactos/reactos.c
+++ b/base/setup/reactos/reactos.c
@@ -38,7 +38,6 @@
 /* GLOBALS ******************************************************************/
 
 HANDLE ProcessHeap;
-BOOLEAN IsUnattendedSetup = FALSE;
 SETUPDATA SetupData;
 
 /* The partition where to perform the installation */
@@ -2826,11 +2825,9 @@ _tWinMain(HINSTANCE hInst,
     /* Initialize the NT to Win32 path prefix mapping list */
     InitNtToWin32PathMappingList(&SetupData.MappingList);
 
-    /* Initialize Setup, phase 0 */
-    InitializeSetup(&SetupData.USetupData, 0);
-
-    /* Initialize Setup, phase 1 */
-    Error = InitializeSetup(&SetupData.USetupData, 1);
+    /* Initialize Setup */
+    Error = InitializeSetup(&SetupData.USetupData, NULL,
+                            &SpFileExports, &SpInfExports);
     if (Error != ERROR_SUCCESS)
     {
         //
diff --git a/base/setup/reactos/reactos.h b/base/setup/reactos/reactos.h
index 8beffc4c86a..286a303034c 100644
--- a/base/setup/reactos/reactos.h
+++ b/base/setup/reactos/reactos.h
@@ -163,8 +163,6 @@ typedef struct _SETUPDATA
 } SETUPDATA, *PSETUPDATA;
 
 extern HANDLE ProcessHeap;
-extern BOOLEAN IsUnattendedSetup;
-
 extern SETUPDATA SetupData;
 
 extern PPARTENTRY InstallPartition;
diff --git a/base/setup/reactos/spapisup/fileqsup.c 
b/base/setup/reactos/spapisup/fileqsup.c
index 95c789de085..334290a17be 100644
--- a/base/setup/reactos/spapisup/fileqsup.c
+++ b/base/setup/reactos/spapisup/fileqsup.c
@@ -173,12 +173,15 @@ SpFileQueueRename_NtToWin32(
 
 /* GLOBALS *******************************************************************/
 
-pSpFileQueueOpen   SpFileQueueOpen   = SetupOpenFileQueue;
-pSpFileQueueClose  SpFileQueueClose  = SetupCloseFileQueue;
-pSpFileQueueCopy   SpFileQueueCopy   = SpFileQueueCopy_NtToWin32;
-pSpFileQueueDelete SpFileQueueDelete = SpFileQueueDelete_NtToWin32;
-pSpFileQueueRename SpFileQueueRename = SpFileQueueRename_NtToWin32;
-pSpFileQueueCommit SpFileQueueCommit = SetupCommitFileQueueW;
+SPFILE_EXPORTS SpFileExports =
+{
+    SetupOpenFileQueue,
+    SetupCloseFileQueue,
+    SpFileQueueCopy_NtToWin32,
+    SpFileQueueDelete_NtToWin32,
+    SpFileQueueRename_NtToWin32,
+    SetupCommitFileQueueW
+};
 
 #endif
 
diff --git a/base/setup/reactos/spapisup/infsupp.c 
b/base/setup/reactos/spapisup/infsupp.c
index 98e48b07bb3..0e2586e1ee1 100644
--- a/base/setup/reactos/spapisup/infsupp.c
+++ b/base/setup/reactos/spapisup/infsupp.c
@@ -83,16 +83,19 @@ SetupOpenInfFileExW(
 
 /* GLOBALS *******************************************************************/
 
-pSpInfCloseInfFile  SpInfCloseInfFile  = SetupCloseInfFile;
-pSpInfFindFirstLine SpInfFindFirstLine = SetupFindFirstLineW;
-pSpInfFindNextLine  SpInfFindNextLine  = SetupFindNextLine;
-pSpInfGetFieldCount SpInfGetFieldCount = SetupGetFieldCount;
-pSpInfGetBinaryField  SpInfGetBinaryField  = SetupGetBinaryField;
-pSpInfGetIntField     SpInfGetIntField     = SetupGetIntField;
-pSpInfGetMultiSzField SpInfGetMultiSzField = SetupGetMultiSzFieldW;
-pSpInfGetStringField  SpInfGetStringField  = SetupGetStringFieldW;
-pSpInfGetField    SpInfGetField    = pSetupGetField;
-pSpInfOpenInfFile SpInfOpenInfFile = SetupOpenInfFileExW;
+SPINF_EXPORTS SpInfExports =
+{
+    SetupCloseInfFile,
+    SetupFindFirstLineW,
+    SetupFindNextLine,
+    SetupGetFieldCount,
+    SetupGetBinaryField,
+    SetupGetIntField,
+    SetupGetMultiSzFieldW,
+    SetupGetStringFieldW,
+    pSetupGetField,
+    SetupOpenInfFileExW
+};
 
 
 /* HELPER FUNCTIONS **********************************************************/
diff --git a/base/setup/usetup/CMakeLists.txt b/base/setup/usetup/CMakeLists.txt
index 21d2bdcf646..ba47a8a9822 100644
--- a/base/setup/usetup/CMakeLists.txt
+++ b/base/setup/usetup/CMakeLists.txt
@@ -35,6 +35,6 @@ endif()
 
 add_pch(usetup usetup.h SOURCE)
 set_module_type(usetup nativecui)
-target_link_libraries(usetup inflib setuplib zlib_solo ext2lib vfatlib 
btrfslib chkstk ${PSEH_LIB})
-add_importlibs(usetup ntdll)
+target_link_libraries(usetup inflib zlib_solo chkstk)
+add_importlibs(usetup setuplib ntdll)
 add_cd_file(TARGET usetup DESTINATION reactos/system32 NO_CAB NAME_ON_CD 
smss.exe FOR bootcd regtest)
diff --git a/base/setup/usetup/spapisup/fileqsup.c 
b/base/setup/usetup/spapisup/fileqsup.c
index 10fc5d335ac..77a14e531c9 100644
--- a/base/setup/usetup/spapisup/fileqsup.c
+++ b/base/setup/usetup/spapisup/fileqsup.c
@@ -997,11 +997,14 @@ Quit:
 
 /* GLOBALS *******************************************************************/
 
-pSpFileQueueOpen   SpFileQueueOpen   = SetupOpenFileQueue;
-pSpFileQueueClose  SpFileQueueClose  = SetupCloseFileQueue;
-pSpFileQueueCopy   SpFileQueueCopy   = SetupQueueCopyWithCab;
-pSpFileQueueDelete SpFileQueueDelete = SetupQueueDeleteW;
-pSpFileQueueRename SpFileQueueRename = SetupQueueRenameW;
-pSpFileQueueCommit SpFileQueueCommit = SetupCommitFileQueueW;
+SPFILE_EXPORTS SpFileExports =
+{
+    SetupOpenFileQueue,
+    SetupCloseFileQueue,
+    SetupQueueCopyWithCab,
+    SetupQueueDeleteW,
+    SetupQueueRenameW,
+    SetupCommitFileQueueW
+};
 
 /* EOF */
diff --git a/base/setup/usetup/spapisup/infsupp.c 
b/base/setup/usetup/spapisup/infsupp.c
index 012b29b9e63..4a4ace20ac0 100644
--- a/base/setup/usetup/spapisup/infsupp.c
+++ b/base/setup/usetup/spapisup/infsupp.c
@@ -228,16 +228,19 @@ SetupOpenInfFileExW(
 
 /* GLOBALS *******************************************************************/
 
-pSpInfCloseInfFile  SpInfCloseInfFile  = SetupCloseInfFile;
-pSpInfFindFirstLine SpInfFindFirstLine = SetupFindFirstLineW;
-pSpInfFindNextLine  SpInfFindNextLine  = SetupFindNextLine;
-pSpInfGetFieldCount SpInfGetFieldCount = SetupGetFieldCount;
-pSpInfGetBinaryField  SpInfGetBinaryField  = SetupGetBinaryField;
-pSpInfGetIntField     SpInfGetIntField     = SetupGetIntField;
-pSpInfGetMultiSzField SpInfGetMultiSzField = SetupGetMultiSzFieldW;
-pSpInfGetStringField  SpInfGetStringField  = SetupGetStringFieldW;
-pSpInfGetField    SpInfGetField    = pSetupGetField;
-pSpInfOpenInfFile SpInfOpenInfFile = SetupOpenInfFileExW;
+SPINF_EXPORTS SpInfExports =
+{
+    SetupCloseInfFile,
+    SetupFindFirstLineW,
+    SetupFindNextLine,
+    SetupGetFieldCount,
+    SetupGetBinaryField,
+    SetupGetIntField,
+    SetupGetMultiSzFieldW,
+    SetupGetStringFieldW,
+    pSetupGetField,
+    SetupOpenInfFileExW
+};
 
 
 /* HELPER FUNCTIONS **********************************************************/
diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c
index 10d133eb560..13b4238aa46 100644
--- a/base/setup/usetup/usetup.c
+++ b/base/setup/usetup/usetup.c
@@ -40,7 +40,6 @@
 /* GLOBALS & LOCALS *********************************************************/
 
 HANDLE ProcessHeap;
-BOOLEAN IsUnattendedSetup = FALSE;
 
 static USETUP_DATA USetupData;
 
@@ -534,6 +533,28 @@ GetNTOSInstallationName(
 }
 
 
+// PSETUP_ERROR_ROUTINE
+static VOID
+__cdecl
+USetupErrorRoutine(
+    IN PUSETUP_DATA pSetupData,
+    ...)
+{
+    INPUT_RECORD Ir;
+    va_list arg_ptr;
+
+    va_start(arg_ptr, pSetupData);
+
+    if (pSetupData->LastErrorNumber >= ERROR_SUCCESS &&
+        pSetupData->LastErrorNumber <  ERROR_LAST_ERROR_CODE)
+    {
+        // Note: the "POPUP_WAIT_ENTER" actually depends on the 
LastErrorNumber...
+        MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, 
arg_ptr);
+    }
+
+    va_end(arg_ptr);
+}
+
 /*
  * Start page
  *
@@ -566,8 +587,9 @@ SetupStartPage(PINPUT_RECORD Ir)
 
     MUIDisplayPage(SETUP_INIT_PAGE);
 
-    /* Initialize Setup, phase 1 */
-    Error = InitializeSetup(&USetupData, 1);
+    /* Initialize Setup */
+    Error = InitializeSetup(&USetupData, USetupErrorRoutine,
+                            &SpFileExports, &SpInfExports);
     if (Error != ERROR_SUCCESS)
     {
         MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER);
@@ -3037,28 +3059,6 @@ InitInstallDir:
 }
 
 
-// PSETUP_ERROR_ROUTINE
-static VOID
-__cdecl
-USetupErrorRoutine(
-    IN PUSETUP_DATA pSetupData,
-    ...)
-{
-    INPUT_RECORD Ir;
-    va_list arg_ptr;
-
-    va_start(arg_ptr, pSetupData);
-
-    if (pSetupData->LastErrorNumber >= ERROR_SUCCESS &&
-        pSetupData->LastErrorNumber <  ERROR_LAST_ERROR_CODE)
-    {
-        // Note: the "POPUP_WAIT_ENTER" actually depends on the 
LastErrorNumber...
-        MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, 
arg_ptr);
-    }
-
-    va_end(arg_ptr);
-}
-
 /*
  * Displays the PrepareCopyPage.
  *
@@ -4034,10 +4034,6 @@ RunUSetup(VOID)
         return STATUS_APP_INIT_FAILURE;
     }
 
-    /* Initialize Setup, phase 0 */
-    InitializeSetup(&USetupData, 0);
-    USetupData.ErrorRoutine = USetupErrorRoutine;
-
     /* Hide the cursor and clear the screen and keyboard buffer */
     CONSOLE_SetCursorType(TRUE, FALSE);
     CONSOLE_ClearScreen();
diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h
index 91b94ac9699..e0d7f7face8 100644
--- a/base/setup/usetup/usetup.h
+++ b/base/setup/usetup/usetup.h
@@ -70,7 +70,6 @@
 
 
 extern HANDLE ProcessHeap;
-extern BOOLEAN IsUnattendedSetup;
 extern PCWSTR SelectedLanguageId;
 
 typedef enum _PAGE_NUMBER
diff --git a/modules/rostests/unittests/setuplib/CMakeLists.txt 
b/modules/rostests/unittests/setuplib/CMakeLists.txt
index de454898e67..8ac15930dad 100644
--- a/modules/rostests/unittests/setuplib/CMakeLists.txt
+++ b/modules/rostests/unittests/setuplib/CMakeLists.txt
@@ -11,8 +11,7 @@ list(APPEND SOURCE
     precomp.h)
 
 add_executable(setuplib_unittest ${SOURCE})
-target_link_libraries(setuplib_unittest setuplib ${PSEH_LIB})
 set_module_type(setuplib_unittest win32cui)
-add_importlibs(setuplib_unittest msvcrt kernel32 ntdll)
+add_importlibs(setuplib_unittest setuplib msvcrt kernel32)
 #add_pch(setuplib_unittest precomp.h SOURCE)
 add_rostests_file(TARGET setuplib_unittest)
diff --git a/modules/rostests/unittests/setuplib/IsValidInstallDirectory.c 
b/modules/rostests/unittests/setuplib/IsValidInstallDirectory.c
index c7f3a599271..9456ab16a7e 100644
--- a/modules/rostests/unittests/setuplib/IsValidInstallDirectory.c
+++ b/modules/rostests/unittests/setuplib/IsValidInstallDirectory.c
@@ -7,24 +7,8 @@
 
 #include "precomp.h"
 
-//
-// FIXME: Temporary symbols defined to make linking work.
-// They will be defined to something once INF file testing is implemented.
-//
-pSpInfCloseInfFile  SpInfCloseInfFile  = NULL;
-pSpInfFindFirstLine SpInfFindFirstLine = NULL;
-pSpInfFindNextLine  SpInfFindNextLine  = NULL;
-pSpInfGetFieldCount SpInfGetFieldCount = NULL;
-pSpInfGetBinaryField  SpInfGetBinaryField  = NULL;
-pSpInfGetIntField     SpInfGetIntField     = NULL;
-pSpInfGetMultiSzField SpInfGetMultiSzField = NULL;
-pSpInfGetStringField  SpInfGetStringField  = NULL;
-pSpInfGetField    SpInfGetField    = NULL;
-pSpInfOpenInfFile SpInfOpenInfFile = NULL;
-
-BOOLEAN IsUnattendedSetup = FALSE;
-HANDLE ProcessHeap;
-
+// SPFILE_EXPORTS SpFileExports = {NULL};
+// SPINF_EXPORTS SpInfExports = {NULL};
 
 START_TEST(IsValidInstallDirectory)
 {
@@ -93,8 +77,6 @@ START_TEST(IsValidInstallDirectory)
 
 #define BOOL_TO_STR(b) ((b) ? "TRUE" : "FALSE")
 
-    ProcessHeap = GetProcessHeap();
-
     UINT i;
     for (i = 0; i < _countof(tests); ++i)
     {

Reply via email to