
  0. Contents

  1.    About
  2.    Requirements
  3.    Win32 Emulation Notes
   3.1  Shared File Access
   3.2  Time Zones
   3.3  Structured Exception Handling (SEH)
   3.4  Long Filenames (LFN)
   3.5  Threads
   3.6  Pipes
   3.7  File Mapping
   3.8  Debugging API
   3.9  Virtual Memory
   3.10 Devices
   3.11 Detecting DKRNL32
  4.    Environment Variables known by DKRNL32
   4.1  Variable DKRNL32
   4.2  Variable TZ
   4.3  Variables DKRNLLOG and DKRNLDBG
  5.    Function List
  6.    License


  1. About

  DKRNL32.DLL is the main part of HX DOS extender's Win32 emulation.
  It will be loaded by PE loader DPMILD32.EXE instead of KERNEL32.DLL.


  2. Requirements

  DKRNL32 expects to find the following environment:

  þ CPU: 80386+, FPU optional. 
  þ DOS: version >= 5. FAT32 and LFN support optional.
  þ DPMI: version 0.9, full API translation for int 21h,
    CS,SS,DS,ES=flat, FS=unused. Version 1.0 optional.
  þ DPMILD32: version >= 3.3, used for dynamic link support, optional.
  þ Keyboard: KB controller 8042 at IRQ 1, direct hardware access
    + keyboard BIOS variable in segment 0040h.
  þ Mouse: int 33h (optional)
  þ Video: VGA (text mode only), direct hardware access
    + video BIOS variable in segment 0040h.
  þ Timer: RTC timer at IRQ 8, direct hardware access
    + PIT timer BIOS variable in segment 0040h (optional).
  þ Serial: DOS device AUX/COMx (optional)
  þ Printer: DOS devices PRN/LPTx (optional)
  þ ASPI: DOS device SCSIMGR$ (optional)

  When DKRNL32.DLL is loaded, it requires about 96 kB memory.


  3. Win32 Emulation Notes

  3.1 Shared File Access

  The Win32 file access API is implemented, of course, but when running
  in plain DOS there may be no SHARE.EXE installed, because AFAIK there
  is none available for versions of MS-DOS supporting FAT32. This may
  cause an application to behave differently if a file is accessed by more
  than one handle (it needn't be a file on a network drive!). For FreeDOS
  there is a SHARE.COM available which works with FAT32, but some versions
  are buggy.

  3.2 Time Zones

  To ensure that the time functions work properly you should set
  environment variable TZ. Please note that DKRNL32 currently ignores
  the daylight saving rules.

  3.3 Structured Exception Handling (SEH)

  SEH is supported, but due to some differences between Win32 and DOS
  memory organization there may exist Win32 apps which cannot run in DOS.
  The most remarkable difference is that linear address region 0-FFFFh
  is committed memory in DOS and will not cause a page exception.

  If FPU error conditions cause an exception 10h in the DPMI client, they
  are fully compatible with SEH as implemented by DKRNL32. Regretably most
  servers don't do it that way, instead they report FPU errors by IRQ 13
  (interrupt 75h), even if this interrupt is masked - thus causing the
  machine to hang. HDPMI since version 1.8.7 by default set the NE bit
  in CR0, which is required to generate FPU exception 10h.

  3.4 Long Filenames (LFN)

  DKRNL32 will always try to use the LFN versions of DOS file functions.
  If these calls return with an error indicating LFN is not installed, 
  the older, non-LFN versions are used. 
   When running on NT platforms, the situation is slightly different. Here
  LFN support is installed, but no translation services for protected mode
  applications are implemented. For DKRNL32 versions < 2.8.16 this meant
  that LFN didn't work on NT/2K/XP. Since version 2.8.16 DKRNL32 will 
  install its own translation services in this case (NTLFNHLP) and thus
  LFN works.

  3.5 Threads

  The thread API implementation in DKRNL32 requires the DPMI server to
  preserve the TF flag when switching back from the locked stack. This is
  true for the Windows 9x built-in server, HDPMI and DPMIONE. It doesn't
  work with NT/2K/XP's DOSX, though, but this may be not too relevant
  because the binary usually will run as Win32 app and DKRNL32 isn't
  involved then. For DOSEMU it will possibly work with versions > 1.3.3 only.

  Some thread functions are non-functional, setting the thread priority
  will possibly not make any difference.

  Furthermore, the dispatcher is implemented in ring 3. So if some code
  stores values below current ESP (i.e. at [esp-4]), it may be destroyed
  if threads are switched. 

  3.6 Pipes

  There is some very basic support for anonymous pipes in DKRNL32. 
  CreatePipe will create a file in the temp directory and open 2 handles,
  one with read-only, the other with write-only access to this file. 
  The handles returned by CreatePipe may be used inside the process or
  by CreateProcess to redirect the childs output to the "pipe". Presumably
  this requires shared file access to be installed (see note 3.1). 
   This support is very limited, but since there is currently no support for
  multiple processes in HX, pipes cannot be used as in Win32.

  3.7 File Mapping

  The File Mapping API is implemented, but if it is to be used as
  interprocess communication means it will possibly not work as expected,
  since processes will not run concurrently. Furthermore, if a file is 
  mapped more than once, support for shared file access should be installed
  to make this work as expected (see note 3.1).
  
  3.8 Debugging API

  The Win32 debugging API is implemented as dummies. So Win32 debuggers
  running in console mode (TD32, some versions of GDB) will not run with
  DKRNL32. Since HX supports the Open Watcom full screen debugger WD,
  there are currently no plans to implement this API.

  3.9 Virtual Memory

  The virtual memory API is supported, but the DPMI 0.9 specification 
  doesn't define calls for allocating uncommitted memory or to allocate
  memory at a given linear address. This may result in some Win32 API
  calls to fail or increased committed memory consumption if DKRNL32 is
  running on 0.9 hosts not installing these functions.

  3.10 Devices

  The CreateFile() implementation knows these "devices":

  - "\\.\VWIN32" : Win9x VWIN32 device to access certain DOS interrupts
  - "\\.\APIX"   : Win9x APIX device for ASPI interface access
  - "\\.\PhysicalDriveX": WinNT way to access physical disks
  - "\\.\X:"            : WinNT way to access drives

  The DeviceIoControl() implementation knows these NT control codes:

  -  IOCTL_DISK_GET_DRIVE_GEOMETRY
  -  IOCTL_DISK_GET_DRIVE_GEOMETRY_EX

  if used for physical disks handles.

  The APIX device usually isn't accessed directly, but through WNASPI32.DLL,
  a dll located in the windows system directory. There exist quite some
  versions of this dll and some may not work with HX. The versions included
  in Windows 95b/98 do work, the version from Adaptec is using unknown
  control codes and therefore doesn't work!
  The APIX emulation requires a DOS ASPI driver (ASPI.SYS) to be loaded
  in config.sys, which must install a DOS device named "SCSIMGR$".
  Due to restrictions of the DOS driver model one may get problems burning
  CDs with high speed. In any case there should be no HD cache (SMARTDRV,
  LBACACHE,...) active when burning. OTOH, installing tools like UDMA/XDMA
  should improve things and is recommended.

  3.11 Detecting DKRNL32

  To detect that DKRNL32.DLL is running a program may use Win32 API
  GetVersionExA. DKRNL32 will return 2222 in low word of 
  OSVERSIONINFO.dwBuildNumber - this is the same as Windows 98 SE - and 
  OSVERSIONINFO.szCSDVersion[0] will be 0.
  Since version 2.8.28 one can detect DKRNL32 by calling GetProcAddress
  with string "GetDKrnl32Version". If this call returns with EAX != 0,
  DKRNL32 is installed, and calling this address will return the current
  DKRNL32 version, the major version no in AL, the minor version no in AH 
  and any subminor version no in HIWORD(EAX).


  4. Environment Variables known by DKRNL32

  4.1 Variable DKRNL32

  When initializing DKRNL32.DLL will read environment variable DKRNL32.
  The value must be a number (for example, DKRNL32=1), which consists of
  individual bits (or flags). The following flags are currently known:

  0001: 1=DKRNL32 remains active when a new process is starting. If set 
        to 0 (the default), DKRNL32 disables its IRQ handlers just before
        a new process is launched and reenables them when the process has
        finished. This avoids possible conflicts, but may be unwanted if
        the launching Win32 application shall provide services for the
        new process (kind of a "Win32 TSR") or must stay active for other
        reasons.
  0002: 1=DKRNL32 does not hook exceptions 1 and 3. This might be useful
        if the application is to run under a debugger. Note that this switch
        isn't needed if the debugger makes itself visible thru int 41h.
  0004: 1=threads will get full default stack size. 0=threads get a
        default stack size of 96 kB.
  0008: not used.
  0016: 1=DKRNL32 will always use the RTC for GetTickCount, the PIT timer
        isn't used at all then.
  0032: 1=DKRNL32 will hook no exceptions (for debugging).

  4.2 Variable TZ

  With this variable the time zone is set.

  4.3 Variables DKRNLLOG and DKRNLDBG

  DKRNLLOG is only useful if a debug version of a Win32 dll must
  be tested. It will redirect debug output of this dll to the file defined
  with this variable, for example:

  SET DKRNLLOG=C:\TEMP\DKRNL32.LOG

  DKRNLDBG are various flags for fine-tuning debug output. It is useful
  only if a debug version of DKRNL32 itself is tested.


  5. Function List

  The following functions are currently exported by DKRNL32.DLL. The
  behaviour is not always exactly identical compared with their Win32
  conterparts. Some procs are just dummies. For more details you will
  need HXSRC package, which contains the full MASM source code.


  Function                       Comment
 ---------------------------------------------------------------------------
  AddAtomA
  AllocConsole
  AreFileApisANSI
  AttachConsole
  BackupRead                     dummy
  BackupSeek                     dummy
  BackupWrite                    dummy
  Beep
  Borland32
  BuildCommDCB
  BuildCommDCBAndTimeouts
  CancelIo
  CancelWaitableTimer
  ClearCommBreak
  ClearCommError
  CloseHandle
  CmdBatNotification             dummy
  CompareFileTime
  CompareStringA
  CompareStringW
  ContinueDebugEvent             dummy 
  CopyFileA
  CopyFileW
  CreateConsoleScreenBuffer
  CreateDirectoryA
  CreateDirectoryW
  CreateDirectoryExA
  CreateDirectoryExW
  CreateEventA
  CreateEventW
  CreateFileA
  CreateFileW
  CreateFileMappingA 
  CreateFileMappingW
  CreateMailslotA                dummy
  CreateMutexA
  CreateMutexW
  CreateNamedPipeA               dummy
  CreatePipe
  CreateProcessA
  CreateProcessW
  CreateSemaphoreA
  CreateSemaphoreW
  CreateSocketHandle
  CreateTapePartition            dummy
  CreateThread
  CreateToolhelp32Snapshot
  CreateWaitableTimerA
  DebugActiveProcess             dummy 
  DebugBreak
  DefineDosDeviceA               dummy
  DeleteAtom
  DeleteCriticalSection
  DeleteFileA
  DeleteFileW
  DeviceIoControl
  DisableThreadLibraryCalls
  DosDateTimeToFileTime
  DuplicateHandle                file handles only
  EnterCriticalSection
  EnumCalendarInfoA              dummy 
  EnumResourceLanguagesA
  EnumResourceNamesA
  EnumResourceTypesA
  EnumSystemLocalesA             dummy
  EnumSystemLocalesW             dummy
  EraseTape                      dummy
  EscapeCommFunction
  ExitProcess
  ExitThread
  ExpandEnvironmentStringsA
  ExpandEnvironmentStringsW
  FatalAppExitA
  FileTimeToDosDateTime
  FileTimeToLocalFileTime
  FileTimeToSystemTime
  FillConsoleOutputAttribute
  FillConsoleOutputCharacterA
  FillConsoleOutputCharacterW
  FindAtomA
  FindClose
  FindFirstFileA
  FindFirstFileExA
  FindFirstFileExW
  FindFirstFileW
  FindNextFileA
  FindNextFileW
  FindResourceA
  FindResourceW
  FindResourceExA
  FindResourceExW
  FlushConsoleInputBuffer
  FlushFileBuffers
  FlushViewOfFile
  FormatMessageA
  FormatMessageW
  FreeConsole
  FreeEnvironmentStringsA
  FreeEnvironmentStringsW
  FreeLibrary
  FreeResource
  GenerateConsoleCtrlEvent
  GetACP
  GetAtomNameA
  GetBinaryTypeA
  GetBinaryTypeW
  GetCPInfo
  GetCommConfig
  GetCommMask
  GetCommProperties
  GetCommState
  GetCommTimeouts
  GetCommandLineA
  GetCommandLineW
  GetCommModemStatus
  GetCompressedFileSizeA
  GetComputerNameA
  GetConsoleCP
  GetConsoleCursorInfo
  GetConsoleMode
  GetConsoleOutputCP
  GetConsoleScreenBufferInfo
  GetConsoleTitleA               dummy
  GetConsoleTitleW               dummy
  GetCurrentDirectoryA
  GetCurrentDirectoryW
  GetCurrentProcess
  GetCurrentProcessId
  GetCurrentThread
  GetCurrentThreadId
  GetDateFormatA
  GetDateFormatW
  GetDiskFreeSpaceA
  GetDiskFreeSpaceW
  GetDiskFreeSpaceExA
  GetDiskFreeSpaceExW
  GetDriveTypeA                  
  GetDriveTypeW
  GetEnvironmentStrings
  GetEnvironmentStringsA
  GetEnvironmentStringsW
  GetEnvironmentVariableA
  GetEnvironmentVariableW
  GetExitCodeProcess
  GetExitCodeThread
  GetFileAttributesA
  GetFileAttributesW
  GetFileAttributesExA
  GetFileAttributesExW
  GetFileInformationByHandle
  GetFileSize
  GetFileSizeEx
  GetFileTime
  GetFileType
  GetFullPathNameA
  GetFullPathNameW  
  GetLargestConsoleWindowSize
  GetLastError
  GetLocaleInfoA
  GetLocaleInfoW
  GetLocalTime
  GetLogicalDrives
  GetLogicalDriveStringsA
  GetMailslotInfo                dummy
  GetModuleFileNameA
  GetModuleFileNameW
  GetModuleHandleA
  GetModuleHandleExA
  GetModuleHandleExW
  GetModuleHandleW
  GetNamedPipeHandleStateA       dummy
  GetNumberFormatA               dummy
  GetNumberFormatW               dummy
  GetNumberOfConsoleInputEvents
  GetNumberOfConsoleMouseButtons
  GetOEMCP
  GetOverlappedResult
  GetPrivateProfileIntA
  GetPrivateProfileSectionA
  GetPrivateProfileSectionNamesA
  GetPrivateProfileStringA
  GetProcAddress
  GetProcessHeap
  GetProcessTimes                dummy
  GetProcessVersion
  GetProcessAffinityMask         dummy
  GetProcessWorkingSetSize       dummy
  GetShortPathNameA
  GetShortPathNameW
  GetStartupInfoA
  GetStartupInfoW
  GetStdHandle
  GetStringTypeA
  GetStringTypeExA
  GetStringTypeExW
  GetStringTypeW
  GetSystemDefaultLangID
  GetSystemDefaultLCID
  GetSystemDefaultUILanguage
  GetSystemDirectoryA
  GetSystemDirectoryW
  GetSystemInfo
  GetSystemTime
  GetSystemTimeAdjustment
  GetSystemTimeAsFileTime
  GetSystemWindowsDirectoryA
  GetSystemWindowsDirectoryW
  GetTapeParameters              dummy
  GetTapePosition                dummy
  GetTapeStatus                  dummy
  GetTempFileNameA
  GetTempFileNameW
  GetTempPathA
  GetTempPathW
  GetThreadContext
  GetThreadLocale
  GetThreadPriority
  GetThreadSelectorEntry
  GetTickCount
  GetTickCount64
  GetTimeFormatA
  GetTimeFormatW
  GetTimeZoneInformation
  GetUserDefaultLangID
  GetUserDefaultLCID
  GetUserDefaultUILanguage
  GetVDMCurrentDirectories       dummy
  GetVersion
  GetVersionExA
  GetVolumeInformationA
  GetVolumeInformationW
  GetWindowsDirectoryA
  GetWindowsDirectoryW
  GlobalAddAtomA
  GlobalAddAtomW
  GlobalAlloc
  GlobalCompact                  dummy
  GlobalFlags                    dummy
  GlobalFree
  GlobalGetAtomNameA
  GlobalGetAtomNameW
  GlobalHandle
  GlobalLock
  GlobalMemoryStatus
  GlobalReAlloc
  GlobalSize
  GlobalUnlock
  Heap32First                    dummy
  Heap32ListFirst                dummy
  Heap32ListNext                 dummy
  Heap32Next                     dummy
  HeapAlloc
  HeapCompact
  HeapCreate
  HeapDestroy
  HeapFree
  HeapLock
  HeapReAlloc
  HeapSize
  HeapUnlock
  HeapValidate
  HeapWalk
  InitializeCriticalSection
  InitializeCriticalSectionAndSpinCount
  InitializeSListHead            dummy
  InterlockedCompareExchange
  InterlockedDecrement
  InterlockedExchange
  InterlockedIncrement
  IsBadCodePtr
  IsBadReadPtr
  IsBadStringPtrA
  IsBadStringPtrW
  IsBadWritePtr
  IsDBCSLeadByte
  IsDBCSLeadByteEx
  IsDebuggerPresent
  IsProcessorFeaturePresent
  IsValidCodePage
  IsValidLocale
  LCMapStringA
  LCMapStringW
  LeaveCriticalSection
  LoadLibraryA
  LoadLibraryExA
  LoadLibraryExW
  LoadLibraryW
  LoadResource
  LocalAlloc
  LocalFileTimeToFileTime
  LocalFlags                     dummy
  LocalFree
  LocalLock
  LocalReAlloc
  LocalSize
  LocalUnlock
  LockFile
  LockFileEx                     dummy
  LockResource
  MapViewOfFile
  MapViewOfFileEx
  Module32First
  Module32Next
  MoveFileA
  MoveFileExA
  MoveFileExW
  MoveFileW
  MulDiv
  MultiByteToWideChar
  NtCurrentTeb
  OpenEventA
  OpenEventW
  OpenFile
  OpenFileMappingA
  OpenFileMappingW
  OpenMutexA                     dummy
  OpenMutexW                     dummy
  OpenProcess                    dummy
  OpenSemaphoreA
  OpenWaitableTimerA
  OutputDebugStringA
  OutputDebugStringW
  PeekConsoleInputA
  PeekConsoleInputW
  PeekNamedPipe
  PrepareTape                    dummy
  Process32First
  Process32Next                  dummy 
  PulseEvent
  PurgeComm
  QueueUserAPC
  QueryDosDeviceA                dummy
  QueryPerformanceCounter
  QueryPreformanceFrequency      dummy
  RaiseException
  ReadConsoleA
  ReadConsoleW
  ReadConsoleInputA
  ReadConsoleInputW
  ReadConsoleOutputA
  ReadConsoleOutputW
  ReadConsoleOutputAttribute
  ReadConsoleOutputCharacterA
  ReadConsoleOutputCharacterW
  ReadFile
  ReadProcessMemory
  ReleaseMutex
  ReleaseSemaphore
  RemoveDirectoryA
  RemoveDirectoryW
  RequestWakeupLatency
  ResetEvent
  ResumeThread
  RtlExAllocateHeap
  RtlExFreeHeap
  RtlExReAllocateHeap
  RtlFillMemory
  RtlGetNtVersionNumbers
  RtlMoveMemory
  RtlUnwind
  RtlZeroMemory
  ScrollConsoleScreenBufferA
  ScrollConsoleScreenBufferW
  SearchPathA
  SearchPathW
  SetCommBreak
  SetCommConfig
  SetCommMask
  SetCommState
  SetCommTimeouts
  SetConsoleActiveScreenBuffer
  SetConsoleCP
  SetConsoleCtrlHandler
  SetConsoleCursorInfo
  SetConsoleCursorPosition
  SetConsoleMode
  SetConsoleOutputCP
  SetConsoleScreenBufferSize
  SetConsoleTextAttribute
  SetConsoleTitleA               dummy
  SetConsoleTitleW               dummy
  SetConsoleWindowInfo
  SetCurrentDirectoryA
  SetCurrentDirectoryW
  SetEndOfFile
  SetEnvironmentVariableA
  SetEnvironmentVariableW
  SetErrorMode
  SetEvent
  SetFileApisToANSI              dummy
  SetFileApisToOEM               dummy
  SetFileAttributesA
  SetFileAttributesW
  SetFilePointer
  SetFilePointerEx
  SetFileTime
  SetHandleCount
  SetHandleInformation           dummy
  SetLastError
  SetLocalTime                   dummy
  SetMailslotInfo                dummy
  SetNamedPipeHandleState        dummy
  SetPriorityClass               dummy
  SetProcessAffinityMask         dummy
  SetProcessWorkingSetSize       dummy
  SetStdHandle
  SetSystemTime                  dummy
  SetTapeParameters              dummy
  SetTapePosition                dummy
  SetThreadAffinityMask          dummy
  SetThreadContext
  SetThreadLocale                dummy
  SetThreadPriority
  SetUnhandledExceptionFilter
  SetupComm
  SetVolumeLabelA                dummy
  SetWaitableTimer
  SizeofResource
  Sleep
  SuspendThread
  SwitchToThread
  SystemTimeToFileTime
  SystemTimeToTzSpecificLocalTime
  TerminateProcess               dummy
  TerminateThread
  Thread32First                  dummy  
  Thread32Next                   dummy
  TlsAlloc                       maximum 64 slots
  TlsFree
  TlsGetValue
  TlsSetValue
  TransmitCommChar
  TryEnterCriticalSection
  UnhandledExceptionFilter
  UnlockFile
  UnlockFileEx                   dummy
  UnmapViewOfFile
  VirtualAlloc
  VirtualFree
  VirtualLock
  VirtualProtect
  VirtualQuery                   
  VirtualQueryEx                 dummy
  VirtualUnlock
  WaitCommEvent
  WaitForDebugEvent              dummy
  WaitForMultipleObjects
  WaitForMultipleObjectsEx
  WaitForSingleObject
  WaitForSingleObjectEx
  WaitNamedPipeA                 dummy
  WideCharToMultiByte
  WinExec
  WriteConsoleA
  WriteConsoleW
  WriteConsoleInputA
  WriteConsoleOutputA
  WriteConsoleOutputAttribute
  WriteConsoleOutputCharacterA
  WriteConsoleOutputCharacterW
  WriteConsoleOutputW
  WriteFile
  WriteFileEx
  WritePrivateProfileStringA
  WriteProfileStringA            dummy
  WriteProcessMemory
  WriteTapemark                  dummy
  _lclose
  _lcreat
  _llseek
  _lopen
  _lread
  _lwrite
  lstrcat
  lstrcatA
  lstrcatW
  lstrcmp
  lstrcmpA
  lstrcmpW
  lstrcmpi
  lstrcmpiA
  lstrcmpiW
  lstrcpy
  lstrcpyA
  lstrcpyn
  lstrcpynA
  lstrcpynW
  lstrcpyW
  lstrlen
  lstrlenA
  lstrlenW


  6. License

  DKRNL32.DLL is part of HX DOS extender. This extender is freeware. 
  View HXRT.TXT for license details and copyrights.

  Japheth

