How can i solve SQLITE_IOERR_SEEK on Unreal UWP application on MS Hololens2

Hello Community

I have a question regarding the usage of SQLite with Unreal Engine 5.0.3 c++ for deployment on Microsoft HoloLens 2 as Universal Windows Platform (UWP) application.

Initial situation

I have an own written library integrated in my Unreal Project as Module, which is dependent on SQLite (https://www.sqlite.org/), which allow me besides some business logics to read and write data to and from an SQLite database. In my own written library, I’m using the SQLite functionality through including the <sqlite/sqlite3.h> Header. To resolve the dependency, I’m using the official SQLite Plugin from Epic Games, Inc…
Further, I have extensive own written Unit-Tests, to test the functionality of my own written library, which are succeeding when I run the tests through the “Session Frontend” in the Unreal-Editor on my Local Windows machine. The database can be created, written, readen without any problem, as expected.

Problem

The application can be builded and tested on my local machine, without problems. The application can be build for Microsoft Hololens 2, deployed and run.

However, when running the application and the library on Microsoft Hololens 2 and the application wants to simply create a table in my database, I am receiving an “disk I/O error” with extended error code 5642: SQLITE_IOERR_SEEK. If I’m looking to the file directory (LocalState directory in project specific Appdata), I see the created database with 0kb data volume.

Specifications

  • Unreal Engine 5.0.3
  • SQLite Plugin of Epic Games, Inc.
  • Windows SDK Version 10.0.18362.0
  • C++17
  • Microsoft HoloLens 2: Windows Holographic for Business with Build 22621.1266 and Development functionality enabled
  • Host Machine with Windows 11

If anyone can help me, I would be really delighted, as I’m stuck on this Bug since a few days. If further informations are usefull, please don’t hesitate to ask!

Meanwhile tried approaches to solve or evaluate the problem:

  • Write a simple text file to the same directory with some content to check if I can write to the specified directory. → Succeded
  • Integrate the “SQLite for Universal Windows Platform” package (SQLite for Universal Windows Platform - Visual Studio Marketplace) as Third-Party library to use the sqlite3.lib binaries for UWP. → Failed: SQLITE_IOERR_SEEK
  • Use an external storage device (SSD) connected to the Microsoft Hololens2 to write the database. → Failed: SQLITE_IOERR_SEEK
  • Using the Unreal SQLite FSQLiteDatabase class and functionalities as described in https://www.youtube.com/watch?v=8Nsqz_AMOCI. → Failed: SQLITE_IOERR_SEEK
  • Enable as many UWP capabilities as possible. → Failed: SQLITE_IOERR_SEEK

+CapabilityList=internetClientServer
+CapabilityList=privateNetworkClientServer
+CapabilityList=internetClient
+CapabilityList=AllJoyn
+CapabilityList=codeGeneration
+DeviceCapabilityList=microphone
+DeviceCapabilityList=webcam
+DeviceCapabilityList=gazeInput
+DeviceCapabilityList=wiFiControl
+DeviceCapabilityList=proximity
+DeviceCapabilityList=location
+DeviceCapabilityList=Bluetooth
+UapCapabilityList=musicLibrary
+UapCapabilityList=picturesLibrary
+UapCapabilityList=videosLibrary
+UapCapabilityList=blockedChatMessages
+UapCapabilityList=chat
+UapCapabilityList=enterpriseAuthentication
+UapCapabilityList=objects3D
+UapCapabilityList=phoneCall
+UapCapabilityList=removableStorage
+UapCapabilityList=sharedUserCertificates
+UapCapabilityList=userAccountInformation
+UapCapabilityList=voipCall
+Uap2CapabilityList=spatialPerception
+UapCapabilityList=appointments
+Uap3CapabilityList=backgroundMediaPlayback
+UapCapabilityList=contacts
+Uap6CapabilityList=graphicsCapture
+IotCapabilityList=lowLevelDevices
+Uap6CapabilityList=offlineMapsManagement
+Uap2CapabilityList=phoneCallHistoryPublic
+Uap3CapabilityList=remoteSystem
+IotCapabilityList=systemManagement
+Uap4CapabilityList=userDataTasks
+Uap3CapabilityList=userNotificationListener
+DeviceCapabilityList=lowLevel
+DeviceCapabilityList=pointOfService
+RescapCapabilityList=developmentModeNetwork

Considered Forums/Repositories for help:

ISSUE SOLVED!

The bug is located in the Read function in the SQLiteEmbeddedPlatform.cpp of the UE SQLiteCore Plugin by calling the Seek() function in HoloLensPlatformFile.cpp when building for Microsoft HoloLens platform. Diving into the Seek() function of the FileHandle implementation for Microsoft HoloLens Platform, the error occurs in the FileSeek() function which calls the function SetFilePointerEx() from the Windows SDK 10.0.18362.0 located at Windows Kits\10\Include\10.0.18362.0\um\fileapi.h. For some unknown reason, the function returns false. The corresponding Seek() function in WindowsPlatformFile.cpp for the Windows platform does not check the return value and always returns true.

The issue could be solved through building the SQLite library from source by a custom integrated Unreal Plugin named SQLiteZ. The source code for the SQLite library (sqlite3.h, sqlite3.c) is used from SQLite amalgamation.

To use the library in the UE Plugin, in the SQLiteZ.Build.cs file, the appropriated preprocessor statements must be properly set to build the SQLite library for Unreal UWP to use on Microsoft HoloLense 2.
For detailed information, refer to the code block below of the SQLiteZ.Build.cs.

using UnrealBuildTool;

public class SQLiteZ : ModuleRules
{
    public SQLiteZ(ReadOnlyTargetRules Target)
        : base(Target)
    {
        PublicIncludePaths.AddRange(
            new string[] {
                // ... add public include paths required here ...
            });

        PrivateIncludePaths.AddRange(
            new string[] {
                // ... add other private include paths required here ...
            });

        PublicDependencyModuleNames.AddRange(
            new string[] {
                "Core",
                // ... add other public dependencies that you statically link with here ...
            });

        PrivateDependencyModuleNames.AddRange(
            new string[] {
                "CoreUObject",
                "Engine",
                "Slate",
                "SlateCore",
                // ... add private dependencies that you statically link with here ...
            });

        DynamicallyLoadedModuleNames.AddRange(
            new string[] {
                // ... add any modules that your module loads dynamically here ...
            });

        PrivateDefinitions.Add("SQLITE_API=__declspec(dllexport)");
        PrivateDefinitions.Add("SQLITE_HAVE_ISNAN=1");
        // Enable FTS
        PrivateDefinitions.Add("SQLITE_ENABLE_FTS4");
        PrivateDefinitions.Add("SQLITE_ENABLE_FTS5");

        // Enable Deserialization and RTree Subsystem
        PrivateDefinitions.Add("SQLITE_ENABLE_DESERIALIZE");
        PrivateDefinitions.Add("SQLITE_ENABLE_RTREE");

        // Enable Json extension
        PrivateDefinitions.Add("SQLITE_ENABLE_JSON1");

        if (Target.Platform == UnrealTargetPlatform.HoloLens) {
            PrivateDefinitions.Add("SQLITE_OS_WINRT=1");
        }
        PrivateDefinitions.Add("SQLITE_OS_WIN=1");
        PrivateDefinitions.Add("NDEBUG");
        PrivateDefinitions.Add("SQLITE_THREADSAFE=1");
        PrivateDefinitions.Add("SQLITE_TEMP_STORE=0");
        PrivateDefinitions.Add("SQLITE_ENABLE_RTREE=1");
        PrivateDefinitions.Add("SQLITE_ENABLE_GEOPOLY=1");
        PrivateDefinitions.Add("SQLITE_ENABLE_JSON1=1");
        PrivateDefinitions.Add("SQLITE_ENABLE_STMTVTAB=1");
        PrivateDefinitions.Add("SQLITE_ENABLE_DBPAGE_VTAB=1");
        PrivateDefinitions.Add("SQLITE_ENABLE_DBSTAT_VTAB=1");
        PrivateDefinitions.Add("SQLITE_INTROSPECTION_PRAGMAS=1");
        PrivateDefinitions.Add("SQLITE_ENABLE_COLUMN_METADATA=1");
        PrivateDefinitions.Add("SQLITE_MAX_TRIGGER_DEPTH=100");
        PrivateDefinitions.Add("SQLITE_THREAD_OVERRIDE_LOCK=-1");

        bEnableUndefinedIdentifierWarnings = false; // The embedded SQLite implementation generates a lot of these warnings
        bUseUnity = false; // Ensure the embedded SQLite implementation is always compiled in isolation
    }
}

The directory structure to integrate the library as plugin is shown here.

SQLiteZ_Plugin_Directory_Structure

1 Like