C++ library guide
Use the official System Locker C++ library
Use the official C++20 client, then choose source embedding for the recommended integration or a static package when speed matters more.
By System Locker 6 min read
If you are starting a new C++ integration, use the official System Locker C++ library on GitHub. It is the preferred option over hand-writing Quicksilver HTTP requests: it owns response validation, runs the heartbeat session for you, and exposes the supported System Locker APIs through one C++20 client.
1. Choose your integration path
The official repository supports two paths. Both use the same public C++ API, validate Quicksilver responses, and maintain the heartbeat session. For production applications, we recommend source embedding: compile the System Locker implementation as part of your own build instead of linking a prebuilt syslocker.lib.
| Choose | When it fits | Tradeoff |
|---|---|---|
| Source embed | Production builds, which need stronger obfuscation, optimization, and overall protection against attackers. | Requires adding the source files to your project. |
| Static package | A quick Windows Visual Studio proof of concept or multiple projects sharing the same known-good binary. | Easier to patch than source embedding. |
Clone or download systemlocker/System-Locker-CPP. Use a C++20 project and build your application and dependencies for the same architecture, normally x64.
2. Add the code (source embed only)
Copy or vendor include/syslocker/ and src/ into your solution, then add every .cpp file under src/ to the Visual Studio project. Keep the private headers in src/ beside those implementation files. This is the recommended route: your application compiles the client implementation directly instead of linking syslocker.lib.
The client still uses libcurl. Add third_party/curl/include/ to C/C++ > General > Additional Include Directories, third_party/curl/lib/ to Linker > General > Additional Library Directories, and set these Linker > Input dependencies:
C/C++ > General > Additional Include Directories
path\to\include
path\to\third_party\curl\include
Linker > General > Additional Library Directories
path\to\third_party\curl\lib
Linker > Input > Additional Dependencies
libcurl.lib;bcrypt.lib;advapi32.lib;crypt32.lib;
secur32.lib;ws2_32.lib;iphlpapi.lib
ws2_32.lib comes from the Windows SDK, so do not redistribute it. The repository README lists the complete source layout and every implementation file to add.
or, use the static package
If you need the fastest Windows setup, the static/ package is available. Add static/include/ to your include directories, static/lib/ to your library directories, and add syslocker.lib before libcurl.lib and the same Windows dependencies shown above. Its setup details are in static/README.md.
3. Authenticate with a key
Create one syslocker::Client for the system and authenticated user. Configure it with the System ID from your developer dashboard, the application version, and a stable hardware identifier. A fixed HWID value disables device locking; for production, use a privacy-conscious identifier that is stable for the device.
#include <syslocker/syslocker.hpp>
#include <iostream>
int main()
{
syslocker::Config cfg;
cfg.systemId = "YOUR_SYSTEM_ID";
cfg.version = "1.0.0";
cfg.hwid = GetStableHashedHardwareId();
cfg.beatRate = std::chrono::seconds{30};
syslocker::Client client(cfg);
const auto result = client.authenticateWithKey("YOUR_LICENSE_KEY");
if (!result) {
std::cerr << result.error() << '\n';
return 1;
}
// Enable protected features only after authentication succeeds.
RunProtectedApplication(client);
}
For account-based Quicksilver systems, call authenticateWithPassword(username, password) instead. The client validates the initialization response before it reports success, so application code does not need to parse the token response itself.
4. Respond to a lost session
After a successful authentication, the library starts and maintains the background heartbeat session. Install a failure hook before or after authenticating so your application can close protected features, save work, or show an access message when the session can no longer continue. Keep the hook quick and do not throw from it.
client.onHeartbeatFailure([](auto code, auto beatError, const std::string& message) {
// Switch to your UI thread if your framework requires it.
DisableProtectedFeatures();
ShowAccessError(message);
});
if (!client.isAuthenticated()) {
DisableProtectedFeatures();
}
The default beat rate is 30 seconds and can be configured from 25 to 3,600 seconds. The library rotates the server token internally, including the state needed for the next heartbeat. Call shutdown() when your protected session ends; it is safe to call more than once and also runs during destruction.
5. Keep production configuration deliberate
The client can use a pinned public-key hash through pinnedPublicKeySha256Base64 when your release process is ready to maintain the pin. Test failures and revoked keys as carefully as successful launches.
For Linux and macOS, use a C++20 compiler, CMake 3.20 or later, and a platform-native libcurl. The bundled curl artifact is Windows-only; Linux and macOS builds also need -ldl when linking.
When your project grows
The same client provides Variables and, when configured with an API key, Management API access. Review the repository README for the full setup and API surface, then make each protected feature depend on the live authenticated session rather than on a one-time startup check.
Ready to use System Locker in your C++ app?
Create a system, download the official library, and protect a small C++20 application before scaling up.