FEX Core SDK
  • Documentation
  • C# Reference
Search Results for

    V2 API Reference

    The V2 API is the recommended surface for FEX.Core.dll. Every function returns an int32 result code, every string crosses the boundary as UTF-8, and every variable-sized output is a DLL-allocated buffer the caller frees with FreeAllocatedBuffer.

    This page documents one function at a time with the Pascal signature, the canonical C# [DllImport], parameters, return codes, and a worked example. For the underlying types, see types-and-constants.md. For result-code diagnostics, see error-codes.md. For buffer ownership rules, see memory-management.md. For the column-windowed extraction surface used on huge datasets, see v3-api.md.

    • Concepts at a glance
    • Lifecycle
      • InitLibrary
      • OpenImage
      • CloseImage
      • CloseAllImages
      • ReadFileSystem
    • Image metadata
      • GetVersionAsJSON
      • GetLicenseInfoAsJSON
      • GetImageTypeByFilename
      • GetImageTypeAsString
      • CheckImageTypeLogical
      • GetImageInfoByFilenameAsJSON
      • GetImageInfoByIdAsJSON
      • GetPartitionInfoAsJSON
      • GetImageSize
    • File records
      • GetFileSystemRecords_V2
      • GetFilePath
      • GetItemInfo
    • File data
      • GetFileSize
      • ReadFileData
      • ReadImageData
    • File properties
      • GetAvailableProperties
      • GetFilePropertiesFromPathAsJSON
      • GetFilePropertiesAsJSON
    • Buffer cleanup
      • FreeAllocatedBuffer
    • Handle-based streaming

    Concepts at a glance

    Topic Detail
    Calling convention cdecl
    String encoding UTF-8, both directions
    Result type int32 — 0 = RESULT_OK, negative = error, positive = function-specific (e.g. OpenImage returns image ID)
    V2 buffer pattern DLL allocates; caller frees with FreeAllocatedBuffer(IntPtr)
    Thread safety Full — concurrent calls against the same ImageID are safe
    Library load FEX.Core.dll (Windows), libFEX.Core.so (Linux), libFEX.Core.dylib (macOS)

    The C# bindings shown below are the canonical pattern used by the FexViewer example. They use [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)] on every entry point and [MarshalAs(UnmanagedType.LPStr)] for UTF-8 string inputs.


    Lifecycle

    InitLibrary

    Verifies the license key and unlocks the rest of the API. Must be called exactly once per process before any other export.

    Pascal signature:

    function InitLibrary(licenseKey: PAnsiChar): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int InitLibrary([MarshalAs(UnmanagedType.LPStr)] string? licenseKey);
    

    Parameters:

    Name Type Dir Purpose
    licenseKey UTF-8 string in GetData license key (FEX2-…). Pass null to read from the FEX_LICENSE_KEY environment variable.

    Returns: RESULT_OK (0) on success, RESULT_INVALIDKEY (-20) if rejected.

    Example:

    string? key = Environment.GetEnvironmentVariable("FEX_LICENSE_KEY");
    int rc = NativeMethods.InitLibrary(key);
    if (rc != NativeMethods.RESULT_OK)
    {
        Console.Error.WriteLine($"License initialization failed (code {rc}).");
        Environment.Exit(2);
    }
    

    Pass the license key issued by GetData (the FEX2-… string). Contact sales@getdata.com for evaluation keys; see License Keys for installation guidance.


    OpenImage

    Opens a forensic image and returns an image-session ID for use in subsequent calls.

    Pascal signature:

    function OpenImage(filename: PAnsiChar; optionsString: PAnsiChar;
                       callback: TCallbackFunction; userData: Pointer): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int OpenImage(
        [MarshalAs(UnmanagedType.LPStr)] string filename,
        [MarshalAs(UnmanagedType.LPStr)] string? optionsString,
        IntPtr callback,
        IntPtr userData);
    

    Parameters:

    Name Type Dir Purpose
    filename UTF-8 string in Absolute path to the first image segment (.E01, .001, .dd, etc.). Multi-segment images are auto-detected from this path.
    optionsString UTF-8 JSON or null in JSON options object — currently used to pass passwords. Pass null for unencrypted images.
    callback function pointer in Optional progress callback (TCallbackFunction). Pass IntPtr.Zero to disable.
    userData pointer in Opaque value forwarded to the callback. Pass IntPtr.Zero if unused.

    Returns: Positive integer image-session ID on success. Negative on failure — most commonly:

    Code Meaning
    RESULT_NOFILEFOUND (-3) File doesn't exist
    RESULT_IMAGENOTSUPPORTED (-4) Format not recognised
    RESULT_COULDNOTOPENIMAGE (-6) Generic open failure (corrupt / locked)
    RESULT_PASSWORD_REQUIRED (-31) Encrypted image, password not supplied
    RESULT_PASSWORD_INCORRECT (-32) Password supplied but wrong

    optionsString JSON shape:

    {
      "Password": "MyVolumePassword"
    }
    

    For BitLocker recovery-key files, pass the path to the .bek file in Password — the DLL detects key-file format. Multiple credentials can be tried by closing and re-opening; the FexViewer manifest format wraps this loop and is documented in sdk/examples/csharp/README.md.

    Example:

    int imageId = NativeMethods.OpenImage(
        @"C:\evidence\disk.E01",
        optionsString: null,
        callback: IntPtr.Zero,
        userData: IntPtr.Zero);
    
    if (imageId < 0)
        throw new FexCoreException($"OpenImage failed", imageId);
    
    try
    {
        // ... use imageId for queries ...
    }
    finally
    {
        NativeMethods.CloseImage(imageId);
    }
    

    When OpenImage returns RESULT_PASSWORD_REQUIRED or RESULT_PASSWORD_INCORRECT, no session is allocated — do not call CloseImage. Retry with optionsString set instead.


    CloseImage

    Releases the resources associated with an image-session ID. Safe to call while reads are still in flight on other threads — destruction is deferred until the last reader returns.

    Pascal signature:

    function CloseImage(ImageID: int32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int CloseImage(int imageId);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in ID returned by OpenImage.

    Returns: RESULT_OK on success, RESULT_IMAGEIDNOTFOUND (-5) if the ID is unknown.

    Example:

    int rc = NativeMethods.CloseImage(imageId);
    if (rc != NativeMethods.RESULT_OK)
        Console.Error.WriteLine($"CloseImage warned: {rc}");
    

    A close failure is informational — the session is gone either way.


    CloseAllImages

    Closes every open image session in the current process. Useful at shutdown or on a process-wide reset.

    Pascal signature:

    function CloseAllImages: int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int CloseAllImages();
    

    Returns: RESULT_OK.


    ReadFileSystem

    Parses the filesystem of an open image and reports the discovered file count. Must be called once before GetFileSystemRecords_V2, GetFileSystemRecordsCustom_V2, GetFileSystemRecordsCustom_V3, or any indexed read like ReadFileData.

    Pascal signature:

    function ReadFileSystem(ImageID: int32; out FileCount: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int ReadFileSystem(int imageId, out uint fileCount);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID.
    fileCount uint32 out Total number of filesystem records discovered.

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_NOFILESYSTEM, RESULT_UNSUPPORTED_FILESYSTEM, RESULT_CORRUPTED_FILESYSTEM.

    Example:

    int rc = NativeMethods.ReadFileSystem(imageId, out uint count);
    if (rc != NativeMethods.RESULT_OK)
        throw new FexCoreException("ReadFileSystem", rc);
    
    Console.WriteLine($"Discovered {count} filesystem records.");
    

    Image metadata

    GetVersionAsJSON

    Returns DLL version information as a UTF-8 JSON document.

    Pascal signature:

    function GetVersionAsJSON(out Buffer: PByte; out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetVersionAsJSON(out IntPtr buffer, out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    buffer IntPtr out DLL-allocated UTF-8 string. Caller must free with FreeAllocatedBuffer.
    bufferSize uint32 out Byte count including the null terminator.

    Returns: RESULT_OK, RESULT_ERROR, RESULT_BUFFER_OVERFLOW.

    JSON output:

    {
      "App Author": "GetData Forensics",
      "App Name": "FEXCore",
      "OEM App Name": "",
      "Major": 1,
      "Minor": 4,
      "ReleaseNo": 0,
      "BuildNo": 1234,
      "Flags": 0,
      "OEMFlags": 0
    }
    

    The version JSON uses descriptive labels rather than the camelCase keys seen elsewhere in the SDK; this output is informational and intended for display rather than programmatic parsing.

    Example:

    IntPtr buffer = IntPtr.Zero;
    try
    {
        int rc = NativeMethods.GetVersionAsJSON(out buffer, out uint size);
        if (rc != NativeMethods.RESULT_OK)
            throw new FexCoreException("GetVersionAsJSON", rc);
    
        string json = Marshal.PtrToStringUTF8(buffer, (int)size)?.TrimEnd('\0') ?? "";
        Console.WriteLine(json);
    }
    finally
    {
        if (buffer != IntPtr.Zero) NativeMethods.FreeAllocatedBuffer(buffer);
    }
    

    GetLicenseInfoAsJSON

    Returns the active licence details — including the holder name, company, and email embedded in newer keys — as a UTF-8 JSON document. Only valid after a successful InitLibrary; before that it returns RESULT_INVALIDKEY.

    Pascal signature:

    function GetLicenseInfoAsJSON(out Buffer: PByte; out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetLicenseInfoAsJSON(out IntPtr buffer, out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    buffer IntPtr out DLL-allocated UTF-8 string. Caller must free with FreeAllocatedBuffer.
    bufferSize uint32 out Byte count including the null terminator.

    Returns: RESULT_OK, RESULT_INVALIDKEY (library not initialized), RESULT_ERROR.

    JSON output:

    {
      "version": 3,
      "cid": 110,
      "name": "Jane Examiner",
      "company": "Example Forensics Ltd",
      "email": "jane@example.com",
      "features": "0xFFFFFFFFFFFFFFFF",
      "issued": "2026-06-04",
      "expires": "2026-12-31",
      "daysRemaining": 210
    }
    

    Keys issued before holder embedding return empty name, company, and email strings (with "version": 2). features is a hex string to avoid 64-bit precision loss in JSON consumers; dates are yyyy-mm-dd.

    Example:

    IntPtr buffer = IntPtr.Zero;
    try
    {
        int rc = NativeMethods.GetLicenseInfoAsJSON(out buffer, out uint size);
        if (rc != NativeMethods.RESULT_OK)
            throw new FexCoreException("GetLicenseInfoAsJSON", rc);
    
        string json = Marshal.PtrToStringUTF8(buffer, (int)size)?.TrimEnd('\0') ?? "";
        Console.WriteLine(json);
    }
    finally
    {
        if (buffer != IntPtr.Zero) NativeMethods.FreeAllocatedBuffer(buffer);
    }
    

    See License keys for the end-to-end licensing guide.


    GetImageTypeByFilename

    Returns the integer image-type code for a file based on extension and header sniffing. Cheap — does not open the image.

    Pascal signature:

    function GetImageTypeByFilename(filename: PAnsiChar; out ImageType: int32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetImageTypeByFilename(
        [MarshalAs(UnmanagedType.LPStr)] string filename,
        out int imageType);
    

    Parameters:

    Name Type Dir Purpose
    filename UTF-8 string in Absolute path.
    imageType int32 out Numeric type code. Pass to GetImageTypeAsString for the human-readable name.

    Returns: RESULT_OK on detection, RESULT_NOFILEFOUND, RESULT_IMAGENOTSUPPORTED.

    Example:

    int rc = NativeMethods.GetImageTypeByFilename(@"C:\evidence\disk.E01", out int code);
    if (rc == NativeMethods.RESULT_OK)
        Console.WriteLine($"Type code: {code}");
    

    GetImageTypeAsString

    Translates an image-type code (from GetImageTypeByFilename) to a human-readable name like "E01" or "DMG".

    Pascal signature:

    function GetImageTypeAsString(anImageType: int32; out Buffer: PByte;
                                  out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetImageTypeAsString(
        int imageType,
        out IntPtr buffer,
        out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    imageType int32 in Code from GetImageTypeByFilename.
    buffer IntPtr out DLL-allocated UTF-8 string. Free with FreeAllocatedBuffer.
    bufferSize uint32 out Bytes including null.

    Returns: RESULT_OK, RESULT_ERROR, RESULT_BUFFER_OVERFLOW.


    CheckImageTypeLogical

    Tests whether a given image-type code represents a logical image (file-list container like L01 / Lx01 / AD1) versus a physical disk image (E01 / DD).

    Pascal signature:

    function CheckImageTypeLogical(anImageType: int32; out IsLogical: int32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int CheckImageTypeLogical(int imageType, out int isLogical);
    

    Parameters:

    Name Type Dir Purpose
    imageType int32 in Code from GetImageTypeByFilename.
    isLogical int32 out 1 if logical, 0 if physical.

    Returns: RESULT_OK, RESULT_IMAGENOTSUPPORTED.


    GetImageInfoByFilenameAsJSON

    Returns image metadata as JSON without keeping the image open. Useful for fast inventory passes.

    Pascal signature:

    function GetImageInfoByFilenameAsJSON(filename: PUTF8Char;
                                          out Buffer: PByte;
                                          out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int GetImageInfoByFilenameAsJSON(
        [MarshalAs(UnmanagedType.LPStr)] string filename,
        out IntPtr buffer,
        out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    filename UTF-8 string in Absolute image path.
    buffer IntPtr out DLL-allocated UTF-8 JSON. Free with FreeAllocatedBuffer.
    bufferSize uint32 out Byte count incl. null.

    Returns: RESULT_OK, RESULT_NOFILEFOUND, RESULT_COULDNOTOPENIMAGE, RESULT_INVALID_UTF8, RESULT_PATH_TRAVERSAL, RESULT_BUFFER_OVERFLOW, RESULT_PASSWORD_REQUIRED, RESULT_PASSWORD_INCORRECT. The encryption codes mean the format-recognition succeeded but the metadata block requires a password — use OpenImage with credentials and switch to GetImageInfoByIdAsJSON for those.

    JSON shape (camelCase per current convention):

    {
      "deviceName": "Samsung SSD 860 EVO 250GB",
      "deviceDescription": "Internal HDD #2",
      "deviceSize": 250059350016,
      "imageType": "E01",
      "segmentCount": 12,
      "isLogical": false,
      "filename": "disk.E01",
      "md5":  "5d41402abc4b2a76b9719d911017c592",
      "sha1": "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d",
      "encaseInformation": {
        "caseName": "OPS-2026-001",
        "evidenceNumber": "2",
        "examiner": "L. Investigator"
      }
    }
    

    Format-specific blocks like encaseInformation are present when the format carries acquisition metadata; absent otherwise.

    Example:

    IntPtr buf = IntPtr.Zero;
    try
    {
        int rc = NativeMethods.GetImageInfoByFilenameAsJSON(
            @"C:\evidence\disk.E01", out buf, out uint size);
        if (rc != NativeMethods.RESULT_OK)
            throw new FexCoreException("GetImageInfoByFilenameAsJSON", rc);
    
        string json = Marshal.PtrToStringUTF8(buf, (int)size)?.TrimEnd('\0') ?? "";
        var meta = JsonSerializer.Deserialize<ImageMetadata>(json);
        Console.WriteLine($"Device: {meta?.DeviceName}, size: {meta?.DeviceSize:N0} bytes");
    }
    finally
    {
        if (buf != IntPtr.Zero) NativeMethods.FreeAllocatedBuffer(buf);
    }
    

    GetImageInfoByIdAsJSON

    Returns metadata for an already-opened image session. Equivalent JSON shape to GetImageInfoByFilenameAsJSON, plus runtime-only fields populated after parsing (e.g. confirmed filesystem type).

    Pascal signature:

    function GetImageInfoByIdAsJSON(ImageID: int32;
                                    out Buffer: PByte;
                                    out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int GetImageInfoByIdAsJSON(int imageId, out IntPtr buffer, out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID.
    buffer IntPtr out DLL-allocated UTF-8 JSON. Free with FreeAllocatedBuffer.
    bufferSize uint32 out Bytes incl. null.

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_IMAGENODATA, RESULT_BUFFER_OVERFLOW.

    Use this in preference to GetImageInfoByFilenameAsJSON whenever you've already opened the image — it skips re-parsing the headers.


    GetPartitionInfoAsJSON

    Returns a JSON array describing every partition in the image (location, size, partition-table style, filesystem type, VBR fingerprint).

    Pascal signature:

    function GetPartitionInfoAsJSON(ImageID: int32;
                                    out Buffer: PByte;
                                    out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetPartitionInfoAsJSON(int imageId, out IntPtr buffer, out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID.
    buffer IntPtr out DLL-allocated UTF-8 JSON array. Free with FreeAllocatedBuffer.
    bufferSize uint32 out Bytes incl. null.

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_IMAGENODATA, RESULT_BUFFER_OVERFLOW.


    GetImageSize

    Returns the logical size of an opened image in bytes — i.e. the size of the acquired device, not the on-disk size of the segment files.

    Pascal signature:

    function GetImageSize(ImageID: int32; out Size: int64): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetImageSize(int imageId, out long size);
    

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND.


    File records

    GetFileSystemRecords_V2

    Returns every filesystem record in the image as a flat array of TFileRecord structs. The single allocation owns all contained pointers (filenames, children lists). Free with one call to FreeAllocatedBuffer.

    Pascal signature:

    function GetFileSystemRecords_V2(ImageID: int32;
                                     out FileCount: uint32;
                                     out Records: PFileRecord;
                                     out RecordArraySize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetFileSystemRecords_V2(
        int imageId,
        out uint fileCount,
        out IntPtr records,
        out uint recordArraySize);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID. Must already have had ReadFileSystem called.
    fileCount uint32 out Number of records in the array.
    records IntPtr out DLL-allocated array of TFileRecord. Free with FreeAllocatedBuffer.
    recordArraySize uint32 out Total byte size of the array allocation.

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_OUT_OF_MEMORY, RESULT_BUFFER_OVERFLOW (datasets so large that count × sizeof overflows uint32 — switch to V3 in that case).

    Example:

    NativeMethods.ReadFileSystem(imageId, out _);
    
    IntPtr records = IntPtr.Zero;
    try
    {
        int rc = NativeMethods.GetFileSystemRecords_V2(
            imageId, out uint count, out records, out _);
        if (rc != NativeMethods.RESULT_OK)
            throw new FexCoreException("GetFileSystemRecords_V2", rc);
    
        int stride = Marshal.SizeOf<FileRecordNative>();
        IntPtr cur = records;
        for (int i = 0; i < count; i++)
        {
            var native = Marshal.PtrToStructure<FileRecordNative>(cur);
            string name = native.filename != IntPtr.Zero
                ? Marshal.PtrToStringUTF8(native.filename) ?? ""
                : "";
    
            bool isFolder  = (native.status & StatusFlags.FILESTATUS_FOLDER)  != 0;
            bool isDeleted = (native.status & StatusFlags.FILESTATUS_DELETED) != 0;
    
            Console.WriteLine($"{native.fileBatesId,8}  {(isFolder ? "D" : "F")}{(isDeleted ? "x" : " ")}  {native.logicalSize,12:N0}  {name}");
    
            cur = IntPtr.Add(cur, stride);
        }
    }
    finally
    {
        if (records != IntPtr.Zero) NativeMethods.FreeAllocatedBuffer(records);
    }
    

    FileRecordNative and StatusFlags are defined in types-and-constants.md. Resolve every filename to a managed string before you call FreeAllocatedBuffer — the pointers are dangling after the free.


    GetFilePath

    Returns the full hierarchical path of a single record by walking parent pointers from the root.

    Pascal signature:

    function GetFilePath(ImageID: int32; FileIndex: int32;
                         out Buffer: PByte; out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetFilePath(
        int imageId, int fileIndex, out IntPtr buffer, out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID.
    fileIndex int32 in Index into the record array (matches parentIndex semantics).
    buffer IntPtr out DLL-allocated UTF-8 path string. Free with FreeAllocatedBuffer.
    bufferSize uint32 out Bytes incl. null.

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_FILEINDEXNOTFOUND, RESULT_BUFFER_OVERFLOW.

    For most use cases it's faster to reconstruct paths in C# from the flat record array rather than calling GetFilePath per record. See the PathBuilder class in sdk/examples/csharp/Models/ for the pattern.


    GetItemInfo

    Returns metadata for a single record as JSON, with selectable detail level.

    Pascal signature:

    function GetItemInfo(ImageID: int32; FileIndex: int32; InfoType: int32;
                         out Buffer: PByte; out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetItemInfo(
        int imageId, int fileIndex, int infoType,
        out IntPtr buffer, out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID.
    fileIndex int32 in Index into the record array.
    infoType int32 in 0 = full (dates + hashes), 1 = basic (dates only), 2 = minimal (id / size / status).
    buffer IntPtr out DLL-allocated UTF-8 JSON. Free with FreeAllocatedBuffer.
    bufferSize uint32 out Bytes incl. null.

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_FILEINDEXNOTFOUND, RESULT_NOFILESYSTEM, RESULT_BUFFER_OVERFLOW.


    File data

    GetFileSize

    Returns the size of a single file in the filesystem. Note: this returns the physical size (cluster-rounded). For logical size use the logicalSize field on the record.

    Pascal signature:

    function GetFileSize(ImageID: int32; FileIndex: int32; out Size: uint64): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetFileSize(int imageId, int fileIndex, out ulong fileSize);
    

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_FILEINDEXNOTFOUND, RESULT_FILENOSIZE.

    When extracting files, always truncate writes to the logicalSize from the record; otherwise you will write cluster-slack bytes past the end of the real content.


    ReadFileData

    Reads a range of bytes from a single filesystem entry into a caller-allocated buffer. This is a caller-allocated function (Pattern 3 in memory-management.md) — there's no FreeAllocatedBuffer here.

    Pascal signature:

    function ReadFileData(ImageID: int32; FileIndex: int32; Offset: int64;
                          Buffer: Pointer; BufferSize: int32;
                          out BytesRead: int32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int ReadFileData(
        int imageId, int fileIndex, long offset,
        IntPtr buffer, int bufferSize, out int bytesRead);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID.
    fileIndex int32 in Record index.
    offset int64 in Byte offset within the file.
    buffer IntPtr in/out Caller-allocated unmanaged buffer.
    bufferSize int32 in Capacity of buffer in bytes.
    bytesRead int32 out Bytes actually read (may be less than bufferSize near EOF).

    Returns: RESULT_OK plus partial read possible, RESULT_INCOMPLETEREAD near EOF, RESULT_FILEINDEXNOTFOUND, RESULT_FILENOSIZE, RESULT_ENCRYPTED_DATA.

    Example (1 MB chunked extraction):

    const int CHUNK = 1024 * 1024;
    IntPtr scratch = Marshal.AllocHGlobal(CHUNK);
    try
    {
        long offset = 0;
        while (offset < logicalSize)
        {
            int want = (int)Math.Min(CHUNK, logicalSize - offset);
            int rc = NativeMethods.ReadFileData(
                imageId, fileIndex, offset, scratch, want, out int got);
            if (rc != NativeMethods.RESULT_OK || got <= 0) break;
    
            var slice = new byte[got];
            Marshal.Copy(scratch, slice, 0, got);
            outputStream.Write(slice, 0, got);
    
            offset += got;
        }
    }
    finally
    {
        Marshal.FreeHGlobal(scratch);
    }
    

    ReadImageData

    Reads raw bytes from anywhere in the underlying image (not a single file). Useful for low-level analysis — partition tables, filesystem boot sectors, unallocated space.

    Pascal signature:

    function ReadImageData(ImageID: int32; Offset: int64;
                           Buffer: Pointer; BufferSize: int32;
                           out BytesRead: int32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int ReadImageData(
        int imageId, long offset,
        IntPtr buffer, int bufferSize,
        out int bytesRead);
    

    Parameters:

    Name Type Dir Purpose
    imageId int32 in Image-session ID.
    offset int64 in Byte offset within the image.
    buffer IntPtr in/out Caller-allocated buffer.
    bufferSize int32 in Capacity.
    bytesRead int32 out Actual bytes read.

    Returns: RESULT_OK, RESULT_INCOMPLETEREAD, RESULT_IMAGEIDNOTFOUND, RESULT_ENCRYPTED_DATA.


    File properties

    The properties API exposes the rich format-specific metadata that file-type drivers extract — JPEG EXIF tags, PDF metadata, ZIP entry lists, etc.

    GetAvailableProperties

    Returns the set of properties available for each filesystem record. Use this to discover what column names are valid for V3 custom extraction.

    Pascal signature:

    function GetAvailableProperties(out Buffer: PByte; out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetAvailableProperties(out IntPtr buffer, out uint bufferSize);
    

    Parameters:

    Name Type Dir Purpose
    buffer IntPtr out DLL-allocated UTF-8 JSON array. Free with FreeAllocatedBuffer.
    bufferSize uint32 out Bytes incl. null.

    Returns: RESULT_OK, RESULT_BUFFER_OVERFLOW.

    JSON shape:

    [
      {"name": "EntryName",   "type": "String",   "typeKind": "tkUString"},
      {"name": "LogicalSize", "type": "Int64",    "typeKind": "tkInt64"},
      {"name": "Modified",    "type": "DateTime", "typeKind": "tkFloat"},
      ...
    ]
    

    GetFilePropertiesFromPathAsJSON

    Inspects a file on the host filesystem (not inside an image) using the DLL's file-type drivers. Returns the property tree as JSON.

    Pascal signature:

    function GetFilePropertiesFromPathAsJSON(Filename: PUTF8Char;
                                             out Buffer: PByte;
                                             out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int GetFilePropertiesFromPathAsJSON(
        [MarshalAs(UnmanagedType.LPStr)] string filename,
        out IntPtr buffer, out uint bufferSize);
    

    Returns: RESULT_OK, RESULT_INVALID_UTF8, RESULT_PATH_TRAVERSAL, RESULT_NOFILEFOUND, RESULT_IMAGENOTSUPPORTED (no driver matched the extension), RESULT_BUFFER_OVERFLOW.


    GetFilePropertiesAsJSON

    Same as the path variant, but for a file inside an opened image session.

    Pascal signature:

    function GetFilePropertiesAsJSON(ImageID: int32; FileIndex: int32;
                                     out Buffer: PByte;
                                     out BufferSize: uint32): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetFilePropertiesAsJSON(
        int imageId, int fileIndex,
        out IntPtr buffer, out uint bufferSize);
    

    Returns: RESULT_OK, RESULT_IMAGEIDNOTFOUND, RESULT_FILEINDEXNOTFOUND, RESULT_NOFILESYSTEM, RESULT_IMAGENOTSUPPORTED, RESULT_COULDNOTOPENIMAGE, RESULT_BUFFER_OVERFLOW.


    Buffer cleanup

    FreeAllocatedBuffer

    Releases any V2 buffer the DLL allocated for the caller. Safe to call with IntPtr.Zero — it returns RESULT_OK without doing anything.

    Pascal signature:

    function FreeAllocatedBuffer(Buffer: PByte): int32; cdecl;
    

    C# binding:

    [DllImport("FEX.Core.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int FreeAllocatedBuffer(IntPtr buffer);
    

    Returns: RESULT_OK, RESULT_ERROR (only if the underlying free itself raised an exception).

    Pair this with every V2 export that has an out IntPtr Buffer parameter. For V3 spec arrays use FreePropertySpecArray instead — see v3-api.md.


    Handle-based streaming

    A separate streaming surface exists for callers that want to read very large files without per-call setup overhead:

    • RequestFileStream(imageId, fileIndex, out streamHandle)
    • ReadFileStream(streamHandle, offset, buffer, bufferSize, out bytesRead)
    • ReleaseFileStream(streamHandle)

    This is functionally equivalent to ReadFileData but caches the underlying stream object across reads. Most callers should start with ReadFileData and only adopt the handle-based variant if profiling shows per-call overhead is a bottleneck. Documentation for these will be expanded in a future release.

    In this article
    Back to top © GetData Forensics