Notes about Windows 3.x+ and FreeDOS compatibility and related stuff: int 2f.1607.bx=0015.cx=function (DOSMGR interface DOS/Win386 taskstuff) 0, DX=0: return instanced (cx nonzero) / dx = DOS driver seg, 0->0x70 es:bx -> patch table: dw version h.l, saveds_off, savebx_off, user_id_off, critical_section_patch_table_off (below!), umb_head_off (all words in DOS ds, umb_head is word with seg of last non-UMB MCB) 1, bitmask DX: set patches, return ax=b97c dx=a2ab bx=bit mask ack (bits: 0 criticalsectionenable 1 nopoutuserid 2 makeint213fstdinpoll 3 trapwin386sysinitstackfault 4 trapdjmechansimorbios) 2, bitmask DX: remove 1 patch specified by DX, returns (ignored) CX 0 3, bitmask DX: get DOS structure size of 1 structure (bit 0: CurrDirS) returns CX=0 (unsupported request) or: CX=size/by AX=b97c DX=a2ab 4, get instance bitmask: return ax=b97c dx=a2ab bx=bitmask instanced items, bits: 0 CDS 1 SFT 2 devicelist 3 SDA (swappable data area) 5, get driver size of driver at ES: return ax=b97c dx=a2ab bx:cx=size (in bytes) or dx=ax=0 if no driver segment. Mini alternative to 2f.1607.0015: 2f.1603 -> returns AX=5248, DS:SI -> RM Nimbus MS DOS 3.3 ... used by Win3.x/3 DOSMGR if no 2f.1607.0015, which happens for all DOS < 5.0 ... Data structure format: dw io sys seg (0 means default 0x70), STACKS struc offset in IO or 0 (non-0 for DOS 3.2), count_instance_areas, then: instance area array with for each (max 32) entry: dw segment (2 = kernel), offset, size. *** If even 2f.1603 not supported, Win3.x uses hardcoded list!? *** (list is based on MS DOS version number, no list for non-MS?) Criticalsection: int 2a.800x enters critical section, handlers can hook this to avoid interrupting. Each c.s. may be active max. once. DOS 3.1+ has [SDA-11] list of offsets in DOS DS; they must be C3->50 (ret->pushax, DOS 3.x only) or 00->nonzero (DOS 4+) to activate. For DOS 4+, all words are 0d0c. Kernel calls 2a.80/2a.81, Win usu. grabs this and does not reflect unless [386Enh] ReflectDOSInt2A=1 or ModifyDOSInt2A=0 ... 2a.800x leaves critical section. Numbers x: >> 1 kernel / share / dosmgr (dos/share/net structure integrity prot.) >> 2 kernel / dosmgr (to block task switch while calling device driver) 5 network redirector / 6 IFSFUNC / 8 ASSIGN >> A MSCDEX, ... 2a.82 ends crit.sect. 0-7: called by proc.exit. / 21.c+ except 21.59 *** Also 2f.1681 / 2f.1682 disable / enable task switching *** (i.e. enter/leave crit. section, nestable; Win 2.x just uses InDOS) Instance data = areas which change over time and must be kept separate between different Windows DOS boxes. MS DeviceDevelKit Q90796 tells: VMM has 0x10F pages per box, of which are usually shared: all TSRs (which were loaded before Win), BIOS, DOS code. Usually local: All neither global (shared) nor instanced. Instanced: Shared except for instanced areas (to keep RAM usage low, not whole page is local). Unless SFT is instanced, you must not touch files which were open when Win/386 started from within Win... when Win exits, instanced areas are restored to state at Win start. Between call int 2f.1609 and 2f.1606, DOS is active but buffers not restored -> a TSR can save some data at 2f.1606 and restore at 2f.1609, to make Win stuff persistent. MS'es NeilSa "grepped through the sources" and lists: 40[13]w (memsize), "DOS memory arena", "selfmodifying code from DOS loader conspirative patch #14", 50[4]b (dj mechanism), 0[0]/400 (IDT), "internal DOS tables", "BIOS data from internal DOS tables" (2f.13??), SDA (Swappable Data Area), CDS (Current Directory String), System File Table (SFT), DOS stack(s), "last link in SFT table" (Win's own VM uses a bigger SFT, the VMs for DOS boxes do not), device header list (Win can locally add drivers), Win-devices which are local=* but not global. Extra instances, not using int 2f.1603 / 2f.1607.0015 to bootstrap: VKB keyboard: 40[15]/28, 40[80]/4, 40[96]/0b (keyb state). VCOMM: 40[0]/8, 40[fc]/4 (ports, timeouts). VPRINTER: 40[78]/3 (timeouts). VNETWARE: redirector table. VMD mouse: int 33 handler area. Graphics driver: various. Virtual EMM: segment which contains XMS handler entry. LOADHI VxD: manages AddInstanceItem stuff for UMB/ROM cases. int 2f.1605: DOSX/WIN386 init broadcast (allows programs to veto/note) -> esbx=0 dssi=0 cx=0 dx=even/odd for WIN386/DOSX. DI=h.l version. Return cx=-1 if Win/286 running, cx=0 if okay for Win to load, other CX to veto. ESBX=infostructure DSSI=v86 toggle callback or 0. Infostructures are chained: Handler calls previoushandler to fill in "next" field of structure... if DSSI is already non-0, no other TSR may set v86 callback. DOS 5+ EMM386 renames EMMQXXX0->EMMXXXX0 during windows if NOEMS active. *** for instanceable TSRs *** (other TSRs will exist in all VMs "simultaneously", kind of!?) Infostructure format: dw version h.l of structure, then dd: next-pointer or 0, VxD filename pointer or 0, VxD details if VxD instance list or 0, [if structure version 4+] optional-instance list or 0. Instance lists are 0-terminated array {pointer,size}. VxD details are ??? (EMM386 uses this). Callback can be called with CLI, AX=0/1 to disable/enable v86, returns CF clear if ok. int 2f.1606: DOSX/WIN386 exit broadcast (DX as above), called when system is already back in real mode. DOSX (Win 3.00/286 DOS extender bug): Int 21.00 not supported. (PS: if PSP is own parent, RAM is not freed. Exit jumps to int 22 ...cleanup is restoring int 22..24 from caller CS (=PSP) etc ...) Other bug: FCB open/close/find (21.0f/21.10/21.14..15) and FCB create (21.16), read/write/stat/seek/readblock/writeblock (21.21..24,27/28) not supported either. > http://support.microsoft.com/support/kb/articles/Q87/2/90.asp > Win 3.1 clean boot -> SHELL=PROGMAN, no LOAD/RUN, no non-* VxD > ... files=45 buffers=20 stacks=9,256, himem, shell, path, temp set. > (keep harddisk drivers / partition managers / compressed FS drivers) Means: NO usage of emm386, share, fastopen, umb, ramdisk, join, graphics, print, subst, append, mode-tsr, mouse, >1 PATH line, TSRs, antivirus, scanner/fax drivers, cdrom/network drivers, tape drivers, keyboard accel/buffers. > I think FreeDOS could return "IDT, BIOS data, ... at 0:0", > "DOS system data at 70:0" or even "everything up to but excluding > the first MCB" as "to be instanced" area. Do test without: shell XMS swap, EMS, UMB, HMA: DOS=LOW,NOUMB ... ... and without TSRs/drivers, except HIMEM. Try w/ & w/o STACKS. ... or even tell that you are pre-DOS-5, e.g. DOS 3.xx!? FDSHIELD can provide int 2f.13 (int 13 hooker helper). User ID stuff is only for by PC / by user "commit" API (n/a)!? No HMA also ensures only 1 kernel segment -> better for 2f.1603. When STACKS is non-0, the default IRQ handlers of MS/PC DOS do IBM interrupt sharing protocol...: each handler starts with eb 10, dd next_in_chain, dw 424b, db 0/80 (wont/will issue EOI), dw eb ?? (to hardware reset routine which ends in / is RETF), db 7 zero bytes. To chain: handler must use next_in_chain (prior handler). Allows to insert handlers at any point in chain. (#02568) DOS 3.2 STACKS structure is at 70:190 - dw ?, stackcount, itemsize (8*n), sizeperstack, dd stacksds pointer, dw offset control block array, offset last element control block array, current element (initially last, less if already stacks in use). For DOS 3.3, use IRQ handler segments and search. For DOS 4+, look for "S" type sub-segment in DOS system data segment. Each control block is: dw status, oldSP, oldSS, newSP (word at new top of stack points back to control block, status low byte = 0 free, 1 used, 3 cannot be used - following stack chunk overflowed into this one... DOS system data is segmented with control blocks: db type, dw nextsegment, size_in_paras, db 3 reserved bytes, db name (8 bytes, for D/I type, else unused). Types: D device, E device appended data (e.g. drive info data area for block devices), I IFS DDT array, F FILES area, X FCBS area, B BUFFERS area, L LASTDRIVE / CurrentDirectoryStructure array, T INSTALL TSR. (tables: DOS 4+ data segment -> 01633, STACKS -> 01634). Minimal driver list: http://www.logicalsky.com/Windows31_FAQ.htm Q&A: http://support.microsoft.com/support/kb/articles/q85/1/94.asp http://support.microsoft.com/default.aspx?scid=kb;EN-US;127139 -> win.ini [Windows] SafeMode=1 or even SafeMode=2 to disable VGA accel? http://www.tnweb.com/support/gpf.php -> no ramdisks, only MS emm386 if any, try allocating more breakpoints: [386Enh] MaxBPS=768 ... Plain Windows loading already places 150 of default 200 breakpoints! clean system.ini for Win3.0 is [boot] only progman/system/keyboard/ mouse/vga/comm/mmsound, and clean win.ini is [windows] only empty load= and run= ... stacks=9,256 is only for 3.1, 3.0 works without... Looks like MS also offers a vshare.386 which works better than SHARE, use SHARE only if really needed (-> e.g. for Word?)... http://www.infokomp.no/techinfo/doc/Wintips.htm Win3.x: /D:X -> EMMExclude=A000-EFFF /D:S -> SystemRomBreakpoint=OFF /D:F -> 32BitDiskAccess=OFF /D:V -> VirtualHDIrq=OFF /D:C -> no 32 bit FILE access (WfW 3.11 only) /D:T no VxDs (3.11) /B log boot progress to text file Win3.x stabilizing hints: http://www.google.com/search? q=cache:KRyROWjjId0J:www.eeng.brad.ac.uk/help/.dos/.winstab.html WIN /D:SFVX or WIN /D:TFC /N (for 3.1 / WfW3.11 respectively) (but /D:T is only for testing, will mean no DOS boxes / VMs avail) It is also recommended to disable all A20 / shadow ROM stuff, because that could remap memory in some way which might confuse Win/DMA. int 2f.1607.0006 A20 change query (called by Win?) -> if AX still 1607 on return, A20 unchanged. Else 0 local / 1 global state change. int 2f.1608 / 2f.1609: Win386 (Win enhanced mode) broadcasts... *** int 2f.160a query Win version AX=0 BH.BL CX=n for n86 mode *** int 2f.160b for Win-aware TSRs ... int 2f.1680 tell DPMI host (e.g. Win) that we are idle (Win 3.0 bug: can cause VM sleep if called often without screen I/O) *** int 2f.1686 returns AX=0 if DPMI int 31 available. Version check: *** int 2f.1687 -> returns AX=0 BX=odd_if_32bit CL=n for n86 CPU, DH.DL version (binary), SI = number of paras of private DOS ext data ES:DI -> pointer to mode switch entry point, call with ES=privdataseg AX=odd_if_32bit, returns CY if error (AX=8011 *DT full, 8021 no32), NC if okay -> CS/SS/DS translated to prot/16, ES=PSP/prot, FS=GS=0 *** int 2f.168E Win95+ VM/app title stuff, functions e.g.: *** DX=2 ESDI=buf CX=bufsize "get app title" (80 char buf is enough) DX=3 ESDI=buf CX=bufsize "get VM title" (30 char buf is enough) DX=0/1 as 2/3 but SET title (ASCIIZ, no CX). Returns AX=1=ok. *** int 2f.168f close awareness: DX=0/1 disable/enable close menu item (AX=0 if worked), DX=100 query close (returns AX=unchanged if no pending close, 0 if pending close, 1 if acknowledged close), DX=200 acknowledge the close (app. gets no keyboard input while Win is in "waiting for ack" state at pending close), DX=300 nACK close ((even?) after ACKing)... all 168f stuff is Win95+ only, though. int 2f.1700 WinOldAp: clipboard interface for text mode apps ... int 2f.13: DSDX "int 13 to be called by DOS", ESBX "int 13 to be used during DOS reboot", returns previous values in DSDX / ESBX. Used to retarget DOS to a new int 13 handler later, and used by malware to get the initial int 13 handler and bypass DOS hookers. Initial int 13 handler can be BIOS or "BIOS plus DMA wrap avoidance for floppy plus floppy change detection" (placed there by DOS). Win3.1 WDCTRL,386 driver insists on using - else it aborts with "Invalid DOS version" (replaces handler by dummy, probably to find out which int 13 drive is behind which drive letter!?). Win3.1 DOSX calls int 2f.4a01, query free HMA space: BX = 0 = no HMA, else BX = available bytes, ES:DI -> start of free, or -1 = no HMA. Win3.1 DOSX also calls int 2f.4a02 if DOS=HIGH, alloc BX bytes, returns ES:DI -> start alloc or -1, BX = actual alloc, DOS 5/6 rounds up to paras. Both 2f.4a0x ALREADY IMPLEMENTED in FreeDOS. (But MEM should have /A flag to *show* HMA usage information...) [Collected 7/2004 by Eric Auer]