Skip to content

Limitations

Dennis Duda edited this page Apr 20, 2022 · 17 revisions

A lot of APIs have limitations on older systems - refer to old MSDN Libraries (e.g. from VS 2005, the last one to have full information about 9x/ME compatibility and proper system requirements per API) and various old KB articles for more information.

Compiling, Linking, Runtime

In order to support linking the Microsoft Layer for Unicode (also known as unicows.lib/.dll) correctly, that means before supported/wrapped system libraries, the code that emits linker arguments is modified not to emit native libraries that are supported by Unicows. You'll have to emit those yourself, after unicows.lib.

List of skipped libraries:

kernel32
advapi32
user32
gdi32
shell32
comdlg32
version
mpr
rasapi32
winmm
winspool
vfw32
secur32
oleacc
oledlg
sensapi

Panic handling

  • Backtraces are currently unavailable. In the future, a limited backtrace implementation based on dbghelp.dll and/or imagehlp.dll might be possible.
  • Panic unwinding only seems to work with the VC8 (Visual C++ 2005) toolset and newer. Note that this toolset raises the minimum supported Windows version to Windows 98 (unclear about the minimum NT version, but NT 4.0 at the very least, because of the IsDebuggerPresent call).

Standard library

File handling

  • std::fs::canonicalize uses GetFinalPathNameByHandleW, which is only supported starting with Vista/Server 2008. Systems that don't support this function also don't support symlinks, so a fallback to GetFullPathName is used. Note that this changes the documented behavior of this function (does not check for existence, does not convert into extended length syntax).
  • std::fs::soft_link uses CreateSymbolicLinkW and will Err on systems before Vista/Server 2008.
  • std::fs::hard_link uses CreateHardLinkW and will Err on systems before Windows 2000.
  • std::fs::File::set_permissions will Err on systems before Vista/Server 2008.
    • This needs SetFileInformationByHandle. See notes on fileextd.lib above.
    • The easy workaround is to use std::fs::set_permissions instead.
  • The recursive directory removal implementation falls back to the old one if the necessary APIs are not available (NtCreateFile, GetFileInformationByHandleEx, SetFileInformationByHandle). The APIs are available on Vista/Server 2008.
  • OpenOptions:
    • 9x/ME only supports a limited number of access rights. This means that we can't use the special append-only behavior (atomic appends). Additionally, files opened with append(true) will be able to seek back and overwrite existing data on these systems.
      • The fallback impl will seek to the end of the file on open.
    • 9x/ME does not support FILE_SHARE_DELETE. Opened files cannot be opened to request a delete at the same time (if that even existed back then).
  • 9x/ME does not support FILE_FLAG_BACKUP_SEMANTICS and symbolic links, so stat/fs::metatada, try_exists, and remove_dir_all have various fallback implementations, working around the limitation of not being able to open folders as files.

Processes/Environment

  • TLS: The number of TLS indices is limited:
    • Windows 2000 and newer: 1088 indices per process
    • Windows Me/98: 80 indices per process
    • Windows NT and Windows 95: 64 indices per process
  • If CompareStringOrdinal is not available (before Vista/Server 2008) the impl falls back to old env arg behavior
  • FreeEnvironmentStringsW doesn't exist on NT 3.1, so env::vars and env::vars_os leak the OS-allocated buffers.

Networking

  • As WinSock 2 is not supported on NT 3.51 and below, networking is entirely unsupported on those systems.
    • Socket handles would be inherited on NT versions before 3.51, as neither WSA_FLAG_NO_HANDLE_INHERIT nor SetHandleInformation are supported.
    • On 9X/ME, socket handles are non-inheritable by default.
  • SockAddr resolution is limited to IPv4 on systems older than Windows XP/Server 2003. If you have installed the "IPv6 Technology Preview for Windows 2000", it should also be supported (wship6.dll).

Synchronization

  • std::thread::park is currently unsupported on systems before Windows XP/Server 2003.
    • A fallback to the generic parker should be possible.

Mutex, CondVar and RwLock have fallback implementations for every windows version.

  • Mutex: SRW locks (Win 7+), critical sections (NT4+), CreateMutex (all)
    • As the stdlib-internal StaticMutex type doesn't need try_lock, it uses the critical section fallback on all Windows versions that don't support SRW locks (same with StaticRWLock).
  • CondVar: CondVarSRW (Win 7+), CreateEvent (all)
    • Limitation: the CreateEvent-based fallback implementation always wakes up all waiting threads.
    • SAFETY LIMITATION: The CreateEvent-based fallback implementation uses PulseEvent, which may cause deadlocks. See Old New Thing and the MSDN docs for more information.
      • If anyone can think of how to improve the fallback implementation while still being compatible with all mutex fallbacks on their respective systems, please reach out/create an issue!
  • RwLock: SRWLocks (Win 7+), Mutex (all; based on mutex impl above)
    • Limitation: fallback impl does not actually allow mutliple readers at the same time, so there is no performance benefit over a Mutex

Other

  • hash_map::RandomState initialization: If both BCryptGenRandom and RtlGenRandom/SystemFunction036 (>= XP/Server 2003) are not available, the two seed u64s are filled with data from GetTickCount, GetSystemTimeAsFileTime and GetCurrentThreadId. This is not random data!
Clone this wiki locally