License Keys
FEX.Core.dll requires a license key issued by GetData Forensics. The key is
passed to InitLibrary() once per process before any image can be opened.
This page covers everything you need to install and use your key. If you do not yet have one, see Obtaining a key below.
What your key looks like
Keys are strings that start with the literal prefix FEX2- followed by
roughly 120–470 opaque characters (newer keys that embed the licence holder's
details are longer). Schematically:
FEX2-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX…XXXX
Your actual key is delivered by GetData via your sales email. Treat it as opaque: don't reformat it, split it across lines, or hand-edit it. Copy it verbatim from the email or secret store you received it from.
Installing your key
The recommended way to provide a key is the FEX_LICENSE_KEY environment
variable. The bundled C# example (FexViewer) reads it automatically when
no --license flag is given.
Windows (PowerShell):
$env:FEX_LICENSE_KEY = "FEX2-...your-key..."
.\FexViewer.exe info --image C:\images\sample.dd
Windows (cmd):
set FEX_LICENSE_KEY=FEX2-...your-key...
FexViewer.exe info --image C:\images\sample.dd
Linux / macOS:
export FEX_LICENSE_KEY="FEX2-...your-key..."
python fex_viewer.py info --image /images/sample.dd
For long-running services and CI pipelines, store the key in a secret manager (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault, GitHub Actions secrets) and inject it as an environment variable at start-up.
Calling InitLibrary from code
If you are writing your own integration rather than using one of the
examples, call InitLibrary once at process start:
Python:
import os
from core import FexCore
from core.loader import load_library
key = os.environ["FEX_LICENSE_KEY"]
lib, _ = load_library()
fex = FexCore(lib)
rc = fex.init_library(key)
if rc != 0:
raise RuntimeError(f"License initialization failed (code {rc})")
C#:
string key = Environment.GetEnvironmentVariable("FEX_LICENSE_KEY")
?? throw new InvalidOperationException("FEX_LICENSE_KEY not set");
int rc = NativeMethods.InitLibrary(key);
if (rc != NativeMethods.RESULT_OK)
throw new InvalidOperationException($"License initialization failed (code {rc})");
C++:
const char* key = std::getenv("FEX_LICENSE_KEY");
if (!key) { /* report missing key and exit */ }
int rc = InitLibrary(key);
if (rc != RESULT_OK) { /* report failure and exit */ }
InitLibrary is also accepted with a null argument; the DLL will then read
FEX_LICENSE_KEY from the environment itself. Passing the key explicitly is
preferred so your application controls the lookup and error handling.
CWD requirement (Windows): the DLL resolves an internal sidecar path relative to the host process's current working directory, so the process CWD must be the same directory as
FEX.Core.dllwhenInitLibraryis called. The bundled examples handle this for you. If you loadFEX.Core.dllfrom a custom location,chdirinto the DLL's directory before callingInitLibrary, then restore your previous CWD afterwards.
Reading your license details
After InitLibrary succeeds, the library can return the details embedded in
your key — useful for displaying who a build is licensed to, or for warning
when a key is close to expiry. The result is a UTF-8 JSON document with these
keys:
| Key | Meaning |
|---|---|
version |
Key format version (2 or 3). |
cid |
Customer ID. |
name |
Licence holder name. Empty on older (v2) keys. |
company |
Licence holder company. Empty on older (v2) keys. |
email |
Licence holder email. Empty on older (v2) keys. |
features |
Enabled-feature bitmask, as a hex string (e.g. "0xFFFFFFFFFFFFFFFF"). |
issued |
Issue date, yyyy-mm-dd. |
expires |
Expiry date, yyyy-mm-dd. |
daysRemaining |
Whole days until expiry. |
Older keys that do not embed a holder return empty strings for name,
company, and email. Call this only after a successful InitLibrary;
before initialisation it returns RESULT_INVALIDKEY (-20).
Python:
info = fex.get_license_info()
print(f"Licensed to {info['name']} ({info['company']}); expires {info['expires']}")
C#:
int rc = NativeMethods.GetLicenseInfoAsJSON(out IntPtr buffer, out uint size);
if (rc == NativeMethods.RESULT_OK && buffer != IntPtr.Zero)
{
try
{
string json = Marshal.PtrToStringUTF8(buffer, (int)size)!;
using var doc = JsonDocument.Parse(json);
Console.WriteLine($"Expires {doc.RootElement.GetProperty("expires").GetString()}");
}
finally
{
NativeMethods.FreeAllocatedBuffer(buffer);
}
}
C / C++:
uint8_t* buffer = nullptr;
uint32_t size = 0;
if (GetLicenseInfoAsJSON(&buffer, &size) == RESULT_OK && buffer) {
std::string json(reinterpret_cast<char*>(buffer), size);
// parse json with your JSON library of choice ...
FreeAllocatedBuffer(buffer); // always free the DLL-allocated buffer
}
Obtaining a key
Production keys are issued by GetData Forensics. To request a key — or renew, replace, or extend an existing one — contact **sales@getdata.com**. Evaluation keys for proofs-of-concept are also available on request.
You will receive a FEX2-... string by email. Store it like an API
token — in a secret manager or environment variable, not in source control.
Common failures
| Return | Meaning | What to check |
|---|---|---|
RESULT_OK (0) |
Key accepted; the DLL is initialised. | — |
RESULT_INVALIDKEY (-20) |
Key was rejected. | Key is missing, copy-pasted with extra whitespace, expired, or for the wrong build. Verify the key string is intact and contact support@getdata.com if the problem persists. |
RESULT_INVALID_UTF8 (-21) |
The key string isn't valid UTF-8. | Most often a code-page issue at the FFI layer — make sure your binding marshals the string as UTF-8 before calling InitLibrary. |
If you get -20 with a key you know is valid, the most common cause on
Windows is the CWD requirement noted above.
Security notes
- Never log keys. Mask to first-4 / last-4 characters if you must display one for support purposes.
- Don't bundle keys into client-side packages, desktop installers, or container images pushed to public registries. Treat them like API tokens.
- Clock skew matters. Key expiry is compared against the host's UTC system time. If a host clock is hours or days off, a freshly-issued key may be rejected.
- Rotating a key requires restarting your process. The DLL caches its
initialised state after
InitLibrarysucceeds; to switch keys, exit and start a new process with the new key.