libpci: i386-io-windows.h: Enable I/O access via native NT ProcessUserModeIOPL syscall
libpci uses WinIo library from http://www.internals.com/ which is archived
at https://web.archive.org/web/
20151005172744/http://www.internals.com/
This external WinIo library has two big issues:
1. Library license is incompatible with pciutils license.
2. It silently and automatically installs 3rd-party NT kernel module
WinIo.sys which is bundled in WinIO.dll binary.
That NT kernel module creates a device file "\\.\WinIo" which can be opened
by any running process. Via this device file can any process (including
unprivileged or those running under Guest account) ask that kernel module
to configure x86 TSS I/O port permissions for access to any I/O port. That
NT kernel module does not implement any permission checks and automatically
accept all requests.
Change in this commit replaces insecure WinIO.dll library and WinIo.sys
kernel module by proper NT system solution: Usage of ProcessUserModeIOPL
syscall (equivalent of iopl(3) on Linux) which is supported directly by NT
kernel. It does not require any external 3rd-party library or NT kernel
module.
This syscall can be invoked by NtSetInformationProcess() function from
ntdll.dll library (which is part of NT system) and for privileged processes
kernel changes x86 IOPL to 3.
Privileged process is that which has SeTcbPrivilege (Act as part of the
operating system privilege) or is running under account from local
Administrators group with SeImpersonatePrivilege (Impersonate a client
after authentication privilege). SeImpersonatePrivilege is enabled by
default for accounts from local Administrators group.
Usage of privileges is not easy operation and needs to call lot of
functions to gain required permissions, achieve thread-safety and follow
suggested guidelines. Hence code is quite long.
Privileges (including SeTcbPrivilege) can be enabled / disabled in User
Accounts settings by local Administrators and change takes effect after
next login, not immediately.