Skip to main content

What is WinPR?

WinPR (Windows Portable Runtime) is a portability library that implements a broad subset of the Win32 API on non-Windows operating systems. FreeRDP is written against Win32 APIs internally — HANDLE, CreateThread, WaitForSingleObject, CreateMutex, and friends — and WinPR provides those APIs everywhere else. This means the same FreeRDP source code compiles and runs on Linux, macOS, Android, and BSD without #ifdef sprawl scattered through every file.
WinPR can also be used as a standalone library in any C/C++ project that wants portable Win32-style primitives without pulling in the full FreeRDP stack.

Why it exists

The Win32 API has well-understood, widely-documented primitives for threading, synchronization, file I/O, networking, cryptography, and more. Rather than replacing those concepts with yet another abstraction layer, WinPR maps them to their POSIX or platform-native equivalents at compile time. The result is:
  • FreeRDP source stays readable to Windows developers.
  • Platform-specific bugs are isolated inside WinPR, not spread across the codebase.
  • Applications built on FreeRDP inherit portability for free.

Key modules

Each module lives under winpr/libwinpr/ and exposes its public API through a header in winpr/include/winpr/.
Process and thread management: CreateThread, ExitThread, GetCurrentThread, GetCurrentThreadId, WaitForSingleObject, TerminateThread, and the STARTUPINFO / PROCESS_INFORMATION structures used by CreateProcess.
Synchronization primitives mirroring the Win32 kernel object model:
  • MutexCreateMutexA, CreateMutexW, ReleaseMutex
  • SemaphoreCreateSemaphoreA, ReleaseSemaphore
  • EventCreateEventA, SetEvent, ResetEvent
  • Critical SectionInitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection
  • Wait functionsWaitForSingleObject, WaitForMultipleObjects
  • Condition variablesInitializeConditionVariable, SleepConditionVariableCS
  • Slim Reader/Writer locksInitializeSRWLock, AcquireSRWLockExclusive, ReleaseSRWLockExclusive
  • One-time initInitOnceExecuteOnce
  • Interlocked operationsInterlockedIncrement, InterlockedCompareExchange
Win32 file I/O constants (FILE_ATTRIBUTE_*, GENERIC_READ, GENERIC_WRITE), CreateFileA, ReadFile, WriteFile, CloseHandle, DeleteFileA, MoveFileExA, directory functions, and FindFirstFileA / FindNextFileA.
wStream, a lightweight byte-buffer abstraction used pervasively inside FreeRDP for encoding and decoding RDP PDUs. Provides Stream_New, Stream_Free, read/write helpers with automatic endian conversion, and wStreamPool for reuse.
Security Support Provider Interface implementation covering NTLM, Kerberos, Negotiate, and Schannel. Used by FreeRDP for RDP authentication.
Wrappers around OpenSSL (or platform CNG on Windows) providing digest, cipher, HMAC, and certificate functions under the familiar BCrypt* / NCrypt* naming.
Emulated Windows registry backed by an INI-style file on non-Windows platforms. Supports RegOpenKeyExA, RegQueryValueExA, RegSetValueExA, and friends.
GetTimeZoneInformation and GetDynamicTimeZoneInformation mapped to the platform’s tzdata database.
GetSystemInfo, GetNativeSystemInfo, GetComputerNameA, GetComputerNameExA, GetTickCount64, GetSystemTime, GetLocalTime, and processor architecture constants.
GetEnvironmentVariableA, SetEnvironmentVariableA, ExpandEnvironmentStringsA.
Generic data structures: wArrayList, wQueue, wStack, wHashTable, wLinkedList, wCountdownEvent, wMessageQueue, and wPubSub.
LoadLibraryA, GetProcAddress, FreeLibrary mapped to dlopen / dlsym / dlclose on POSIX.
CreatePipe and CreateNamedPipeA for anonymous and named pipes.
Thin compatibility layer over BSD sockets that lets code written against winsock2.h compile unchanged.
WinPR’s own structured logging framework with hierarchical loggers, multiple appenders (console, file, syslog, journald, UDP, binary, callback), and environment-variable configuration. See the WLog reference for full details.

Using WinPR

As part of FreeRDP

WinPR is built and linked automatically when you build FreeRDP. No extra steps are needed — just include the relevant header.
#include <winpr/thread.h>
#include <winpr/synch.h>
#include <winpr/wlog.h>

As a standalone library

WinPR can be built and installed independently:
cmake -S . -B build -DBUILD_SHARED_LIBS=ON
cmake --build build
cmake --install build
Then link against winpr3 (CMake target) or use pkg-config:
pkg-config --cflags --libs winpr3
CMake projects can consume it with:
find_package(WinPR REQUIRED)
target_link_libraries(myapp PRIVATE winpr)

Include pattern

Every WinPR header is self-contained and guarded against multiple inclusion:
#include <winpr/thread.h>   /* CreateThread, ExitThread, ... */
#include <winpr/synch.h>    /* CreateMutex, WaitForSingleObject, ... */
#include <winpr/file.h>     /* CreateFileA, ReadFile, ... */
#include <winpr/stream.h>   /* wStream */
#include <winpr/wlog.h>     /* WLog_Get, WLog_Print, ... */

Build options

CMake optionDefaultDescription
WITH_WINPR_TOOLSONBuild WinPR command-line utilities
WITH_WINPR_DEPRECATEDOFFExpose deprecated API symbols
WITH_OPENSSLdetectedUse OpenSSL for crypto
WITH_MBEDTLSOFFUse mbedTLS instead of OpenSSL
WITH_SWSCALEdetectedEnable image scaling support
CHANNEL_URBDRCdetectedUSB redirection channel (requires libudev)
On Linux, installing the -dev / -devel packages for openssl, libusb, and libsystemd before running CMake will automatically enable the most useful optional features.

Platform support

PlatformStatus
Linux (x86_64, aarch64, armv7)Fully supported
macOS (x86_64, arm64)Fully supported
Android (NDK)Fully supported
FreeBSD / OpenBSDSupported
WindowsWinPR headers thin-wrap the native Win32 API — no emulation needed