BradyPrintSdk (BradyCorp.Desktop.SDK)
(c) 2026 Brady Worldwide, Inc. All Rights Reserved
The BradyPrintSdk is a C library designed for direct interaction with Brady printers. It provides a low-level interface to connect to printers, send print jobs, and retrieve bi-directional (BiDi) status information.
This SDK is ideal for developers who need to integrate Brady printing capabilities directly into their custom applications without relying on a traditional printer driver.
This document provides an overview of the SDK's features and a guide to its usage. For detailed information on specific functions, please refer to the BradyPrintSdk.h umbrella header (or the individual domain headers for finer-grained includes), or the included Doxygen documentation.
Features
- Multiple Connectivity Options:
- Connect to printers via TCP/IP.
- Enumerate and connect to printers via USB.
- Check connection status, disconnect, and reconnect using stored parameters.
- Bi-Directional Communication:
- Query the printer for real-time status and settings.
- Retrieve information like serial number, firmware version, and installed supply details (name, percentage remaining, dimensions).
- Check printer feature support (cut options, post-print accessories).
- Query post-print accessory configuration and RFID capabilities.
- Comprehensive Print Job Management:
- Create and manage print jobs programmatically.
- Customize job settings such as page orientation, mirror printing, rotation, and number of copies.
- Send raw monochrome (1-bit per pixel) bitmap data for printing.
- Configure cut options for printers with cutting capabilities.
- RFID Support:
- Write data to RFID tags (EPC, User, AFI memory banks).
- Set access and kill passwords.
- Lock/unlock RFID memory banks.
- Permanent lock/write operations.
- Configure RFID transmit and receive power levels.
- Logging: Configure detailed logging for easier troubleshooting and debugging.
Supported Printers
The current version of the BradyPrintSdk supports only the i7500 printer. Future SDK releases will add support for more printer models.
Concepts: Printer Features vs. Printer Settings
The SDK exposes two distinct categories of printer information. Understanding the difference is important for writing correct integration code.
Printer Features (Model Capabilities)
Printer features represent what the printer model and firmware are capable of. They are resolved from the model's built-in configuration and firmware version.
Use CheckFeatureSupport() to query features. A feature answers the question: "Can this printer model ever do X?"
Printer Settings (Live Device State)
Printer settings represent the real-time state of the specific connected device. They are populated by querying the printer (triggered by RefreshPrinterSettings()). A setting answers the question: "What is this specific unit's current state right now?"
How They Relate
Some settings are gated by a corresponding feature. If the feature is not supported by the model, attempting to read the gated setting returns BRADY_SDK_ERROR_FEATURE_NOT_SUPPORTED.
| Feature (Model Capability) | Gated Setting (Live State) | What the Setting Reports |
|---|---|---|
PRINTER_FEATURE_RFID_ENCODING |
PRINTER_SETTING_IS_RFID_CAPABLE |
Whether this unit's RFID encoder hardware is present and enabled |
PRINTER_FEATURE_RFID_ENCODING |
PRINTER_SETTING_SUPPLY_IS_RFID |
Whether the currently loaded supply is RFID-enabled |
PRINTER_FEATURE_POST_PRINT_ACCESSORIES |
PRINTER_SETTING_POST_PRINT_ACCESSORY |
Which post-print accessory is physically installed |
PRINTER_FEATURE_CUT_OPTIONS |
JOB_SETTING_CUTTER_MODE |
Which cutter mode to use (validated via GetSupportedCutterModes()) |
PRINTER_FEATURE_CUT_AFTER_SET |
JOB_SETTING_CUT_AFTER_SET_LENGTH |
Number of labels between full cuts when using CutAfterSet or PerfAndFullCutAfterSet |
PRINTER_FEATURE_CUT_AFTER_SET |
JOB_SETTING_PERF_AFTER_SET_LENGTH |
Number of labels between perforated cuts when using PerfCutAfterSet or PerfAndFullCutAfterSet |
Recommended Workflow
// 1. Check the model-level capability (does this model's firmware support RFID?)
bool rfidCapable = false;
CheckFeatureSupport(printerHandle, PRINTER_FEATURE_RFID_ENCODING, &rfidCapable);
if (rfidCapable) {
// 2. Refresh live state from the connected device
RefreshPrinterSettings(printerHandle);
// 3. Query the device-level state (does this unit have RFID hardware?)
bool rfidHardware = false;
GetPrinterSettingBool(printerHandle, PRINTER_SETTING_IS_RFID_CAPABLE, &rfidHardware);
// 4. Query whether the loaded supply is RFID-enabled
bool supplyIsRfid = false;
GetPrinterSettingBool(printerHandle, PRINTER_SETTING_SUPPLY_IS_RFID, &supplyIsRfid);
if (rfidHardware && supplyIsRfid) {
// Safe to add RFID operations to print jobs
}
}
Example: Cutting
Cutting follows the same pattern, with GetSupportedCutterModes() acting as a convenience function that collapses the feature check and accessory state into a single actionable bitmask:
// Check model capability
bool cutSupported = false;
CheckFeatureSupport(printerHandle, PRINTER_FEATURE_CUT_OPTIONS, &cutSupported);
if (cutSupported) {
// GetSupportedCutterModes accounts for feature support AND the
// installed post-print accessory, returning only modes that are
// valid for the current device configuration.
RefreshPrinterSettings(printerHandle);
int supportedModes = 0;
GetSupportedCutterModes(printerHandle, &supportedModes);
}
Getting Started: Basic Usage Workflow
The following steps outline the typical workflow for using the BradyPrintSdk, from initialization to sending a print job.
For a full example, refer to the included sample application BradyPrintSdkSample.cpp.
1. Initialize the SDK
Before making any other calls, you must initialize the SDK. This sets up necessary resources and data paths. You can also optionally configure logging.
#include "BradyPrintSdk.h"
// Initialize the SDK, providing a path for its data.
BradySdkStatus status = InitializeBradySdk("C:\\Temp\\MyPrintApp\\SdkData");
if (status != BRADY_SDK_SUCCESS) {
// Handle initialization error
}
// Optionally, configure the log file path and verbosity level.
SetLogPath("C:\\Temp\\MyPrintApp\\Logs", "SdkLog.txt", LOG_PRODUCTION);
2. Create a Printer Instance
Create a printer instance by specifying the printer model and a unique name for the instance. This returns a PrinterHandle that you will use for all subsequent operations.
const char* model = "i7500";
const char* instanceName = "My_i7500_Printer";
PrinterHandle printerHandle = CreatePrinter(model, instanceName);
if (!printerHandle) {
// Handle instance creation error
}
3. Connect to the Printer
You can connect via USB or TCP.
Connecting via USB
To connect via USB, you must first enumerate the connected devices for your printer model to get a unique devicePath.
// Define a callback function to receive device information.
void UsbDeviceFoundCallback(const char* serialNumber, const char* devicePath, const char* usbPortInfo, void* userData) {
// In a real application, you would store this information.
// For this example, we'll just print it.
printf("Found USB Device: SN=%s, Path=%s\n", serialNumber, devicePath);
}
// Enumerate devices for the specified model.
EnumerateUsbDevices(model, UsbDeviceFoundCallback, nullptr);
// Once you have the device path from the callback...
const char* myDevicePath = "..."; // The devicePath from the callback
status = ConnectUsbPrinter(printerHandle, myDevicePath);
Connecting via TCP/IP
For network printers, connect using the IP address and port (usually 9100).
const char* ipAddress = "192.168.1.100";
int port = 9100;
status = ConnectTcpPrinter(printerHandle, ipAddress, port);
4. Retrieve Printer Information (BiDi)
After connecting, you can query the printer for its current state and supply information. It's good practice to refresh the settings first.
// Fetch the latest settings from the printer.
status = RefreshPrinterSettings(printerHandle);
if (status == BRADY_SDK_SUCCESS) {
// Retrieve the printer's serial number (a string value).
char serialBuffer[256];
size_t bytesCopied = 0;
GetPrinterSettingString(printerHandle, PRINTER_SETTING_SERIAL_NUMBER, serialBuffer, sizeof(serialBuffer), &bytesCopied);
printf("Printer Serial: %s\n", serialBuffer);
// Retrieve the remaining supply percentage (an integer value).
int supplyRemaining = 0;
GetPrinterSettingInt(printerHandle, PRINTER_SETTING_SUPPLY_REMAINING_PERCENT, &supplyRemaining);
printf("Supply Remaining: %d%%\n", supplyRemaining);
// Get the dimensions of the installed supply.
int supplyWidth = 0;
int supplyHeight = 0;
GetPrinterSettingInt(printerHandle, PRINTER_SETTING_SUPPLY_WIDTH, &supplyWidth);
GetPrinterSettingInt(printerHandle, PRINTER_SETTING_SUPPLY_HEIGHT, &supplyHeight);
// Check if RFID is enabled on this unit (requires feature support).
bool rfidCapable = false;
CheckFeatureSupport(printerHandle, PRINTER_FEATURE_RFID_ENCODING, &rfidCapable);
if (rfidCapable) {
bool isRfidCapable = false;
GetPrinterSettingBool(printerHandle, PRINTER_SETTING_IS_RFID_CAPABLE, &isRfidCapable);
printf("RFID Capable: %s\n", isRfidCapable ? "Yes" : "No");
bool supplyIsRfid = false;
GetPrinterSettingBool(printerHandle, PRINTER_SETTING_SUPPLY_IS_RFID, &supplyIsRfid);
printf("Supply is RFID: %s\n", supplyIsRfid ? "Yes" : "No");
}
// Query which cutter modes are valid for this printer and installed accessory.
int supportedModes = 0;
GetSupportedCutterModes(printerHandle, &supportedModes);
printf("NoCut supported: %s\n",
(supportedModes & (1 << static_cast<int>(CutterMode::NoCut))) ? "Yes" : "No");
printf("EndOfLabel supported: %s\n",
(supportedModes & (1 << static_cast<int>(CutterMode::EndOfLabel))) ? "Yes" : "No");
}
5. Create and Configure a Print Job
Create a print job and configure its settings.
#include "BradyPrintJobConsts.h"
using namespace BradyPrintJobConsts;
PrintJobHandle jobHandle;
status = CreatePrintJob(printerHandle, "My Test Job", jobHandle);
if (status == BRADY_SDK_SUCCESS) {
// Set the page orientation to Landscape.
SetPrintJobSettingEnum(printerHandle, jobHandle, JOB_SETTING_PAGE_ORIENTATION, static_cast<int>(PageOrientation::Landscape));
// Set the number of copies.
SetPrintJobSettingInt(printerHandle, jobHandle, JOB_SETTING_NUMBER_OF_COPIES, 3);
// Enable mirror printing.
SetPrintJobSettingBool(printerHandle, jobHandle, JOB_SETTING_MIRROR_PRINT, true);
// Configure cut options using the supported modes bitmask.
int supportedModes = 0;
GetSupportedCutterModes(printerHandle, &supportedModes);
if (supportedModes & (1 << static_cast<int>(CutterMode::EndOfLabel))) {
// Cut after each label.
SetPrintJobSettingEnum(printerHandle, jobHandle, JOB_SETTING_CUTTER_MODE, static_cast<int>(CutterMode::EndOfLabel));
} else if (supportedModes & (1 << static_cast<int>(CutterMode::PerfAndFullCutAfterSet))) {
// Full cut every 10 labels, perforated cut every 5 labels.
SetPrintJobSettingEnum(printerHandle, jobHandle, JOB_SETTING_CUTTER_MODE, static_cast<int>(CutterMode::PerfAndFullCutAfterSet));
SetPrintJobSettingInt(printerHandle, jobHandle, JOB_SETTING_CUT_AFTER_SET_LENGTH, 10);
SetPrintJobSettingInt(printerHandle, jobHandle, JOB_SETTING_PERF_AFTER_SET_LENGTH, 5);
} else if (supportedModes & (1 << static_cast<int>(CutterMode::CutAfterSet))) {
// Or full cut after every 5 labels.
SetPrintJobSettingEnum(printerHandle, jobHandle, JOB_SETTING_CUTTER_MODE, static_cast<int>(CutterMode::CutAfterSet));
SetPrintJobSettingInt(printerHandle, jobHandle, JOB_SETTING_CUT_AFTER_SET_LENGTH, 5);
}
}
6. Add Page Data to the Job
Load a complete 1-bit-per-pixel monochrome BMP file into memory and add its data to the print job. The buffer must contain the full file structure, including the standard BITMAPFILEHEADER and BITMAPINFOHEADER structures.
// In a real application, you would load your full .bmp file into a byte array.
// This example assumes 'bitmapBuffer' is a pointer to the complete file data in memory
// and 'fileSize' is the size of that buffer in bytes.
const unsigned char* bitmapBuffer = /* ... your complete .bmp file data ... */;
size_t fileSize = /* ... size of your file in bytes ... */;
status = AddPageToPrintJob(printerHandle, jobHandle, bitmapBuffer, fileSize);
7. Add RFID Operations (Optional)
If your printer supports RFID and you're using RFID-enabled supplies, you can add RFID operations to each page.
// Check model capability, then device state
bool rfidCapable = false;
CheckFeatureSupport(printerHandle, PRINTER_FEATURE_RFID_ENCODING, &rfidCapable);
bool isRfidCapable = false;
bool supplyIsRfid = false;
if (rfidCapable) {
GetPrinterSettingBool(printerHandle, PRINTER_SETTING_IS_RFID_CAPABLE, &isRfidCapable);
GetPrinterSettingBool(printerHandle, PRINTER_SETTING_SUPPLY_IS_RFID, &supplyIsRfid);
}
if (isRfidCapable && supplyIsRfid) {
// Example: Complete RFID encoding sequence
// 1. Update the access password (mandatory step before locking)
unsigned int newPassword = 0x12345678;
AddRfidWritePassword(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::AccessPassword),
newPassword);
// 2. Update the memory bank data
unsigned char epcData[] = {0x30, 0x74, 0x25, 0x7B, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
AddRfidWriteData(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::ElectronicProductCode),
0, epcData, sizeof(epcData)); // Offset 0 updates PC word length automatically
// 3. Lock the updated memory banks with the new password
AddRfidLock(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::ElectronicProductCode),
newPassword);
// 4. Lock the access password bank itself to prevent further unauthorized changes
AddRfidLock(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::AccessPassword),
newPassword);
// Set RFID transmit power (1-30, where 30 is highest)
AddRfidSetTxPower(printerHandle, jobHandle, 25);
}
8. Send the Print Job
Once the job is configured and has page data, send it to the printer.
status = SendPrintJob(printerHandle, jobHandle);
if (status == BRADY_SDK_SUCCESS) {
printf("Print job sent successfully!\n");
}
9. Connection Management
You can check whether a printer is connected, disconnect it, and reconnect using stored connection parameters. You must call DisconnectPrinter before establishing a new connection with ConnectTcpPrinter or ConnectUsbPrinter; calling them while already connected returns BRADY_SDK_ERROR_EXISTING_CONNECTION.
// Check if the printer is still reachable.
bool connected = false;
IsPrinterConnected(printerHandle, &connected);
if (!connected) {
printf("Printer is not reachable.\n");
}
// Disconnect the printer. Active print jobs are preserved.
status = DisconnectPrinter(printerHandle);
// Reconnect using the same connection parameters from the last
// successful ConnectTcpPrinter or ConnectUsbPrinter call.
status = ReconnectPrinter(printerHandle);
if (status == BRADY_SDK_SUCCESS) {
printf("Reconnected successfully!\n");
}
// To switch to a different printer, disconnect first, then connect
// to the new address.
status = DisconnectPrinter(printerHandle);
status = ConnectTcpPrinter(printerHandle, "10.0.0.50", 9100);
10. Clean Up Resources
After you are finished, destroy the print job and the printer instance to release memory and resources. DestroyPrinter automatically disconnects the printer if it is still connected.
// Destroy the print job first.
DestroyPrintJob(printerHandle, jobHandle);
// Then destroy the printer instance. This disconnects automatically.
DestroyPrinter(printerHandle);
API Overview
The public API is accessible via the umbrella header BradyPrintSdk.h, or through individual domain headers for finer-grained control:
- SDK Management & Printer Lifecycle (
BradyPrintSdkCore.h): InitializeBradySdk()SetLogPath()CreatePrinter()DestroyPrinter()EnableAnalytics()- Connection (
BradyPrintSdkConnection.h): EnumerateUsbDevices()ConnectUsbPrinter()ConnectTcpPrinter()IsPrinterConnected()DisconnectPrinter()ReconnectPrinter()- Bi-Directional (BiDi) & Settings (
BradyPrintSdkSettings.h): RefreshPrinterSettings()CheckFeatureSupport()GetSupportedCutterModes()GetPrinterSettingString()GetPrinterSettingInt()GetPrinterSettingEnum()GetPrinterSettingBool()SetPrintJobSettingString(),SetPrintJobSettingInt(),SetPrintJobSettingEnum(),SetPrintJobSettingBool()GetPrintJobSettingString(),GetPrintJobSettingInt(),GetPrintJobSettingEnum(),GetPrintJobSettingBool()- Print Job Management (
BradyPrintSdkPrintJob.h): CreatePrintJob()DestroyPrintJob()AddPageToPrintJob()SendPrintJob()- RFID Operations (
BradyPrintSdkRfid.h): AddRfidWriteData()AddRfidWritePassword()AddRfidWriteAfi()AddRfidLock()/AddRfidUnlock()AddRfidPermaLock()/AddRfidPermaWrite()AddRfidBlockPermaLock()AddRfidSetTxPower()/AddRfidSetRxPower()- Status Codes (
BradySdkStatus.h): BradySdkStatusenumSdkLogLevelenum
Enums and Constants
The BradyPrintJobConsts.h header defines several useful enums:
- PageOrientation:
Portrait,Landscape - CutterMode:
NoCut,EndOfLabel,EndOfJob,CutAfterSet,PerfCutEndOfJob,PerfCutAfterSet,PerfAndFullCutAfterSet - PostPrintAccessory:
TearBar,AutoCutter,PeelWithoutLabelTakenSensor,PeelWithLabelTakenSensor,PerfCutter,Rewinder - RfidMemoryLocation:
ElectronicProductCode,ApplicationFamilyIdentifier,TagIdentifier,User,AccessPassword,KillPassword
Error Handling
Most SDK functions return a BradySdkStatus enum. A return value of BRADY_SDK_SUCCESS (0) indicates success. Any other value indicates an error. Always check the return status of each function call to handle potential issues gracefully.
Advanced Features
Post-Print Accessories
For printers that support multiple post-print accessories (tear bar, auto-cutter, peeler, perforated cutter, rewinder), you can query which accessory is currently installed. The installed accessory determines which cut modes are available:
- AutoCutter: Supports
EndOfLabel,EndOfJob, andCutAfterSetmodes. - PerfCutter: Supports the AutoCutter modes, along with
PerfCutEndOfJob,PerfCutAfterSet, andPerfAndFullCutAfterSet. - All others (TearBar, Peel, Rewinder): Only
NoCutis valid.
Use GetSupportedCutterModes to retrieve a bitmask of the CutterMode values that are valid for the connected printer given its current accessory configuration. This avoids the need to query the accessory type and apply the mapping yourself.
// Refresh settings first to ensure the accessory state is current.
RefreshPrinterSettings(printerHandle);
int supportedModes = 0;
GetSupportedCutterModes(printerHandle, &supportedModes);
// Check whether a specific mode is supported before setting it.
if (supportedModes & (1 << static_cast<int>(CutterMode::EndOfLabel))) {
SetPrintJobSettingEnum(printerHandle, jobHandle, JOB_SETTING_CUTTER_MODE, static_cast<int>(CutterMode::EndOfLabel));
}
// Or iterate over all supported modes:
for (int mode = 0; mode <= static_cast<int>(CutterMode::PerfAndFullCutAfterSet); ++mode) {
if (supportedModes & (1 << mode)) {
// CutterMode(mode) is valid for this printer and accessory.
}
}
Checking Feature Support
Use CheckFeatureSupport to test whether a printer capability is available before attempting to use it. This is useful for features that vary by printer model, such as cut-after-set support.
// Check whether the printer supports cutting after a set number of labels.
bool cutAfterSetSupported = false;
BradySdkStatus status = CheckFeatureSupport(printerHandle, PRINTER_FEATURE_CUT_AFTER_SET, &cutAfterSetSupported);
if (status == BRADY_SDK_SUCCESS && cutAfterSetSupported) {
// Safe to use CutAfterSet mode and JOB_SETTING_CUT_AFTER_SET_LENGTH.
SetPrintJobSettingEnum(printerHandle, jobHandle, JOB_SETTING_CUTTER_MODE, static_cast<int>(CutterMode::CutAfterSet));
SetPrintJobSettingInt(printerHandle, jobHandle, JOB_SETTING_CUT_AFTER_SET_LENGTH, 5);
}
RFID Memory Management
The SDK provides comprehensive RFID support for tags with multiple memory banks:
- EPC (Electronic Product Code): Primary identifier for the tagged item
- User Memory: Application-specific data storage
- TID (Tag Identifier): Read-only tag manufacturer information
- AFI (Application Family Identifier): ISO 15693 application identifier
- Access Password: Required for locked operations
- Kill Password: Used to permanently disable the tag
Not all tags support all memory banks. Attempting to perform RFID operations that require user memory on tags that do not support this feature will result in an error.
Command Sequence Guideline
Assigning a non-zero access password does not, in itself, prevent reading or changing data on the tag. It only requires that future users must provide the access password to change the lock state. Only the reserved memory bank (access and kill passwords) can be both read and write-locked; all others (EPC, TID, User) can be write-locked only.
Follow this sequence to ensure successful RFID operations:
- Unlock Access Password: Unlock access password bank with existing password if locked (optional).
- Update Access Password: Update the access password (mandatory).
- Unlock Banks: Unlock each memory bank (EPC, User, Kill password) with new password (optional).
- Update Bank Data: Update each memory bank data with new password (mandatory).
- Lock Banks: Lock each memory bank (EPC, User, Kill Password) with new password (optional).
- Lock Access Password: Lock the access password bank itself to prevent further changes (optional).
EPC Memory Offset Behavior
When using AddRfidWriteData to write to the ElectronicProductCode memory bank, the offset parameter dictates how the printer updates the PC word (which contains the EPC length information):
- Offset 0: The printer automatically updates the EPC length in the PC word.
- Offset 1: Overwrites the PC word memory content directly with the provided data. This may result in an error if the written length information is incorrect.
- Offset 2+: The printer writes to the EPC memory only and does NOT update the EPC length information in the PC word.
Ensure the correct offset and data are used during EPC write operations to maintain data integrity.
Example of a comprehensive RFID encoding sequence following the recommended flow:
// Example: Complete RFID encoding sequence
// 1. (Optional) Unlock access password bank with existing password if it was previously locked.
// unsigned int oldPassword = 0x00000000;
// AddRfidUnlock(printerHandle, jobHandle,
// static_cast<int>(RfidMemoryLocation::AccessPassword),
// oldPassword);
// 2. Update the access password (mandatory step before locking)
unsigned int newPassword = 0x12345678;
AddRfidWritePassword(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::AccessPassword),
newPassword);
// 3. (Optional) Unlock the memory banks you intend to write to using the new password
// AddRfidUnlock(printerHandle, jobHandle, static_cast<int>(RfidMemoryLocation::ElectronicProductCode), newPassword);
// AddRfidUnlock(printerHandle, jobHandle, static_cast<int>(RfidMemoryLocation::User), newPassword);
// 4. Update the memory bank data
unsigned char epcData[] = {0x30, 0x74, 0x25, 0x7B, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
AddRfidWriteData(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::ElectronicProductCode),
0, epcData, sizeof(epcData)); // Offset 0 updates PC word length automatically
unsigned char userData[] = {0xDE, 0xAD, 0xBE, 0xEF};
AddRfidWriteData(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::User),
0, userData, sizeof(userData));
// 5. Lock the updated memory banks with the new password
AddRfidLock(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::ElectronicProductCode),
newPassword);
AddRfidLock(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::User),
newPassword);
// 6. Lock the access password bank itself to prevent further unauthorized changes
AddRfidLock(printerHandle, jobHandle,
static_cast<int>(RfidMemoryLocation::AccessPassword),
newPassword);