The situation in a VDM is slightly more complex, since it required the JFN to be compatible with DOS and therefore an 8-bit entity. Furthermore, the JFN_table in DOS is traditionally imbedded or chained from the DOS PDB (or PSP). For this reason a second level of indirection is employed.
The JFN returned from a VDM open indexes the byte array of virtual system file number (VSFNs). The VSFN ranges from 0 - 255. The high 47 (from 0xd0 though 0xfe) are used as real mode device handles. 0xff indicates an unused handle. When a VDM is created the initial PDB contains the default array of 20 handles at label PDB_JFN_table (PDB + 0x18). This current array's far segment address is at PDB_JFN_pointer (PDB + 0x34) and the size of the array is a word at PDB_JFN_Length (PDB + 0x32). The PDB lies on a paragraph boundary (16-byte boundary) and its segment address is saved in the PTDA at CurrentPDB (PTDA +0x2ea) Once again the usual precaution applies when referencing PTDA fields: their symbols are publicly defined for the current system context only. Therefore, to reference a CurrentPDB out-of-context must be done relative to the PTDA address for that context.
These points are illustrated in the following example:
##.p 46 Slot Pid Ppid Csid Ord Sta Pri pTSD pPTDA pTCB Disp SG Name 0046 001d 0007 001d 0001 blk 0200 7b732000 7b8c9a04 7b8af720 1f08 17 *vdm ##.s 46 >>> Slot 46 is a VDM but not the current context, so we locate the PDB >>> relative to the PTDA (otherwise we could have just used >>> dw currentpdb l1) ##dw %7b8c9a04+currentpdb-ptda_start l1 0030:0000fd16 0e01 >>> This is a segment address so use the & operator to display the >>> PDB. ##db &e01:0 &0e01:00000000 cd 20 00 a0 00 9a f0 fe-1d f0 f5 01 99 0d 08 02 M . ..p~.pu..... &0e01:00000010 28 08 65 07 28 08 99 0d-d1 d1 d1 d0 d2 ff ff ff (.e.(...QQQPR... &0e01:00000020 ff ff ff ff ff ff ff ff-ff ff ff ff d7 00 e4 03 ............W.d. &0e01:00000030 11 0e 30 00 00 00 40 09-ff ff ff ff 00 00 00 00 ..0...@......... &0e01:00000040 14 0b 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ &0e01:00000050 cd 21 cb 72 6e 6c 20 2d-20 4e 6f 74 00 20 20 20 M!Krnl - Not. &0e01:00000060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 ..... &0e01:00000070 20 20 20 20 20 20 20 20-00 00 00 00 e7 08 50 03 ....g.P. >>> Word at PDB+0x32 is 0030. This is the number of file handles >>> supported in this VDM. The default is 0014. So the PDB_JFN_table >>> has been expanded. >>> Far pointer at PDB+34 is &0940:0000. This is the current >>> PDB_JFN_table address. (By default this would have pointed to >>> PDB+0x18, but the table has been expanded.) >>> Now dump the current PDB_JFN_table. ##db &940:0 &0940:00000000 d1 d1 d1 d0 d2 00 01 02-03 04 05 06 07 08 09 ff QQQPR........... &0940:00000010 0b ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ &0940:00000020 ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ &0940:00000030 4d 00 00 08 00 00 00 00-00 00 00 00 00 00 00 00 M............... &0940:00000040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ &0940:00000050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ &0940:00000060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ &0940:00000070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ >>> JFNs 0 - 4 correspond to VSFNs d1, d1, d1, d0 and d2. Each of these >>> is greater than 0xcf and therefore a real mode device handle >>> and not managed by the protect mode file system. >>> JFN 5 is the first open file in this VDM. It has VSFN 00. This >>> may be used as an index into the protect mode JFN_table to >>> find the corresponding SFT, MFT and file name. The technique from >>> this point is the same as in the preceding section. >>> Dump the JFN_table from the PTDA. ##dw %7b8c9a04 jfn_ptable-ptda_start l2 0030:0000ffbc 0000 1ea8 >>> We are no longer based on selector 30 so the JFN table has been >>> expanded. Now dump the current table... ##dw #1ea8:0 1ea8:00000000 006a 0069 0075 008c 008b 005e 0089 0088 1ea8:00000010 008a 0097 ffff 008d ffff ffff ffff ffff 1ea8:00000020 ffff ffff ffff ffff ffff ffff ffff ffff 1ea8:00000030 ffff ffff ffff ffff ffff ffff ffff ffff 1ea8:00000040 ffff ffff ffff ffff ffff ffff ffff ffff 1ea8:00000050 ffff ffff ffff ffff ffff ffff ffff ffff 1ea8:00000060 Past end of segment: 1ea8:00000060 >>> VSFN 00 corresponds to SFN 006a. Now dump the SFT... ##.d sft 438:(8+(83*6a)) sf_ref_count: 0001 sfi_mode: 00a0 sf_usercnt: 0000 sfi_hVPB: 0012 reserved: 00 sfi_ctime: 0000 sf_flags(2): 0000:0000 sfi_cdate: 0000 sf_devptr: #0000:0000 sfi_atime: 0000 sf_FSC: #00c8:0008 sfi_adate: 0000 sf_chain: #0000:0000 sfi_mtime: 0000 sf_MFT: fe7c8b54 sfi_mdate: 0000 sfdFAT_firFILEclus: 4d58 sfi_size: 00000594 sfTrap 13 (0DH) - General Protection Fault 0000 - In Debugger eax=90000000 ebx=ffdd55ba ecx=00000000 edx=013c0000 esi=00006373 edi=ffff2940 eip=000054ae esp=00003b0a ebp=00003b14 iopl=0 rf -- -- nv up di pl zr na pe nc cs=0120 ss=0128 ds=0128 es=0128 fs=0168 gs=0000 cr2=16ea2000 cr3=001d9000 0120:000054ae ff56fe call word ptr [bp-02] ss:3b12=b23b >>> Oops! the debugger had a problem. Not to worry, he told us >>> the MFT address, so dump that ... (this also appears at SFT+0x19) >>> the SFT again ... ##dw 438:(8+(83*6a)) 0438:00003646 0001 0000 0000 0000 0000 0000 0800 c800 0438:00003656 0000 0000 0000 0000 5400 7c8b 58fe 484d 0438:00003666 001f 0000 0000 0000 0000 0000 0000 0000 0438:00003676 0000 0000 0000 0000 0000 0000 0000 0000 0438:00003686 0000 7830 007a 0000 0000 0000 0000 a000 0438:00003696 0000 1200 0000 0000 0000 0000 0000 0000 0438:000036a6 9400 0005 9400 0005 0000 1d00 0100 6a0e 0438:000036b6 0000 0000 0000 0000 0020 0000 0000 0000 >>> MFT ##db %fe7c8b54 %fe7c8b54 4b 53 45 4d 01 02 00 00-00 00 00 00 00 00 00 00 KSEM............ %fe7c8b64 00 00 46 36 38 04 00 00-00 00 4b 53 45 4d 01 02 ..F68.....KSEM.. %fe7c8b74 00 00 00 00 00 00 00 00-00 00 00 00 ba 0f 00 00 ............:... %fe7c8b84 6d 46 12 00 43 3a 5c 4f-53 32 5c 4d 44 4f 53 5c mF..C:\OS2\MDOS\ %fe7c8b94 57 49 4e 4f 53 32 5c 53-59 53 54 45 4d 5c 4b 42 WINOS2\SYSTEM\KB %fe7c8ba4 44 55 4b 2e 44 4c 4c 00-52 8b 7c fe 3c 00 7d ff DUK.DLL.R.|~<.}. %fe7c8bb4 00 00 00 00 00 00 00 00-f0 8b 7c fe 20 f7 8a 7b ........p.|~ w.{ %fe7c8bc4 f0 f1 f9 78 00 04 00 00-48 4f 4f 4b 60 bf f9 ff pqyx....HOOK`?y. >>> The file name is: C:\OS2\MDOS\WINOS2\SYSTEM\KBDUK.DLL