The ZwXxx routines for accessing disk files don't work in the retail release of Windows 98 because of two basic problems—one from the architecture of Windows and the other from what looks like an ordinary bug.
The first problem with file access has to do with the order in which Windows 98 initializes various virtual device drivers. The Configuration Manager (CONFIGMG.VXD) initializes before the Installable File System Manager (IFSMGR.VXD). WDM drivers for devices that exist at startup time receive their IRP_MN_START_DEVICE requests during CONFIGMG's initialization phase. But, since IFSMGR hasn't initialized at that point, it's not possible to perform file I/O operations by using ZwCreateFile and the other functions discussed earlier in the chapter. Furthermore, there's no way for a WDM driver to defer handling IRP_MN_START_DEVICE until file system functionality becomes available. If you don't have a debugger like Soft-Ice/W running, the symptom you will see is a blue screen complaining of a Windows Protection Error while initializing CONFIGMG.
The second and more crippling problem with file access has to do with the validity checking that ZwReadFile, ZwWriteFile, and ZwQueryInformationFile do on their arguments. If you supply an IO_STATUS_BLOCK in kernel-mode memory (and there's basically no way to do anything else), these functions probe a virtual address that doesn't exist. The resulting page fault gets caught by a structured exception handler and results in you getting back STATUS_ACCESS_VIOLATION even when you've done everything right. There is no workaround for this problem in the July 1998 retail release of Windows 98.
The FILEIO sample on the companion disc illustrates a way past these Windows 98 difficulties. FILEIO makes a run-time decision whether to call the ZwXxx functions or instead to call VxD services to perform file operations.