2

What were the programming interfaces used to access "raw" devices on Windows 95~ME? Specifically GPUs, but I'm also curious about other device types in general.

For example, on modern Linux (after the era of direct userspace PCI access, ugh), /dev/dri/card0 is the device node through all GPU access is done (mainly via ioctl and mmap file operations). On Windows NT, I believe it would be \\.\Display0 or something similar to that in the NT device namespace.

What did e.g. 3D-accelerated games in Windows 98 use to achieve the same thing? Were there DOS-style device names akin to COM1: for graphics cards, or NT-ish device names, or some other OS-provided interface, or did such programs mostly bypass the kernel entirely (i.e. having userspace DLLs directly poke at I/O ports)?

(Specifically, I'm curious about the layer below "programmer uses Direct3D functions", i.e. about what d3d*.dll itself or its equivalents would have used under the hood.)

5
  • 2
    A bit broad, isn't it. Short Version: Windows has no user accessible drivers (VxD/WDM). DirectX is the low level API provided to access functionality. It already bypasses the GDI parts, giving a short/fast path to hardware. It is the equivalent of GPU drivers in Linux. Also, GPUs are a later development than Direc3D (and WinG). It's about giving a 3D pipeline way before 3D accelerators became GPUs.
    – Raffzahn
    Jan 29 at 8:54
  • 2
    Depends on the device, I think. I don’t know about graphics drivers, but I know raw block device access is performed by opening a handle to VWIN32.VXD and calling DeviceIoControl to invoke an interrupt handler at the DOS layer (!). Yes, really, even when there is no real-mode mapper active. This is the official guidance found in MSDN. I would imagine DirectX does something similar: open a handle to a VXD and invoke some ioctls. Jan 29 at 11:02
  • if you are asking about Win95, Glide was common, as was necessary for the 3dfx voodoo cards. D3D came later. WinNT supported openGl, no D3D or Glide. Glide is of course a 3dfx manufacturer specific api
    – camelccc
    Jan 29 at 12:33
  • 1
    I can confirm using ioctl for accessing a floppy drive at the sector level in Win9x.
    – DmytroL
    Jan 29 at 14:59
  • If someone knew a tool like strace on Linux it would perhaps be possible to identify how a program communicates with the kernel.
    – zomega
    Feb 7 at 15:22

2 Answers 2

3

The low-level Win32 userspace device access API in Windows 9x is actually not all that different from the one in Windows NT: given a path pointing to a device node (which starts with \\.\), you can open a handle to the driver and use it to perform calls like DeviceIoControl. The catch is mostly in what devices are actually available.

For example, where in Windows NT one would open a block device node like \\.\PhysicalDrive0 or \\.\C: to perform raw disk I/O, to do the same in Windows 9x one would instead open a handle to \\.\VWIN32, which is to say, to the VWin32 virtual device driver, and use that handle to perform a DeviceIoControl call, which in turn invokes… a software interrupt call one would find familiar from DOS programming. Yes, this was the official way to do it, even with only 32-bit drivers in use. This is described in KB articles like Q125712, Q163920 and in MSDN documentation. (Not the contemporary online version, of course, but you should be able to dig it out from the CHM files on a MSDN CD from the period.) Several other VxDs allow obtaining a handle to themselves in this way in order to invoke driver functions, although VWIN32 ioctls are the only ones I could find any documentation for. Windows NT, of course, has no VxDs.

But some devices were shared between the two families. In particular, display device nodes like \\.\Display1 appear both in Windows 9x and NT, and Win32 calls like EnumDisplayDevices will return them. Likewise COM and LPT communication ports.

How exactly DirectX specifically ends up using those APIs, I cannot say, but it seems at least some driver traffic does end up going through VxD entry points like \\.\DDRAW.VXD and \\.\DSOUND.VXD. You can see for yourself by analysing DirectX 6 binaries bundled with Windows 98 SE.

16-bit programs could also use device access APIs inherited from Windows 3.x Enhanced mode, with which Windows 9x remained fully compatible; APIs like interrupt 0x2f service 0x1684. KERNEL32 even provided undocumented, ordinal-only exports allowing to directly perform VxDCall invocations from user space, that were normally available only to VxD drivers themselves. But NT-style \\.\ device paths were indubitably the intended, official API for Win32 applications.

3
  • Thanks – so I guess this whole concept was "down-ported" from NT3.x, in a sense.
    – grawity
    Feb 7 at 15:32
  • 1
    @grawity Which is quite expected because Win32 API as such first originated on NT 3.x Please note, though, that the device path (think IOCTL)-style \\.\Display1 interface serves a very limited purpose when it comes to graphics and rendering. As I mentioned in my reply below, it was done through other, dedicated APIs.
    – DmytroL
    Feb 8 at 15:08
  • I wrote this with the assumption that graphics rendering was only mentioned as an example, and not as a specific area of interest. But yes, this is worth keeping in mind. Feb 18 at 20:33
4

For 3D rendering specifically, Windows display drivers expose a so called Direct3D Device Driver Interface (https://learn.microsoft.com/en-us/windows-hardware/drivers/display/direct3d). DDI did exist at least for Windows 98, and quite likely on Windows 95 as well.

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .