home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / books / wdvirref.db < prev    next >
Encoding:
Text File  |  1991-03-01  |  780.2 KB  |  19,901 lines

  1. %@1@%%@AB@%Microsoft  Windows  - Virtual Device Adaptation Guide%@AE@%%@EH@%%@NL@%
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11.         %@AB@%Microsoft (R) Windows (tm) - Virtual Device Adaptation Guide%@AE@%%@NL@%
  12.  
  13.       %@AB@%development tools for providing Microsoft Windows device support
  14.                                 %@AB@%VERSION 3.0%@AE@%
  15. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16.  
  17.  
  18. for the MS-DOS (R) or PC-DOS Operating System%@NL@%
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26. Microsoft Corporation %@NL@%
  27.  
  28. Information in this document is subject to change without notice and does
  29. not represent a commitment on the part of Microsoft Corporation. The
  30. software described in this document is furnished under a license agreement
  31. or nondisclosure agreement. The software may be used or copied only in
  32. accordance with the terms of the agreement. It is against the law to copy
  33. the software on any medium except as specifically allowed in the license or
  34. nondisclosure agreement. No part of this manual may be reproduced or
  35. transmitted in any form or by any means, electronic or mechanical, including
  36. photocopying and recording, for any purpose without the express written
  37. permission of Microsoft.   U.S. Government Restricted Rights  The SOFTWARE
  38. and documentation are provided with RESTRICTED RIGHTS. Use, duplication, or
  39. disclosure by the Government is subject to restrictions as set forth in
  40. subparagraph (c) (1) (ii) of the Rights in Technical Data and Computer
  41. Software clause at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of
  42. the Commercial Computer Software ─ Restricted Rights at 48 CFR 52.227-19, as
  43. applicable. Contractor/manufacturer is Microsoft Corporation/One Microsoft
  44. Way/Redmond, WA 98052-6399.  (C) Copyright Microsoft Corporation, 1990. All
  45. rights reserved. Simultaneously published in the U.S. and Canada.  
  46. Printed and bound in the United States of America.%@NL@%
  47.  
  48.  
  49. Microsoft, MS, MS-DOS, GW-BASIC, QuickC, CodeView, the 
  50. Microsoft logo, and XENIX are registered trademarks and Windows,
  51. Windows/286, 
  52. and Windows/386 are trademarks of Microsoft Corporation.%@NL@%
  53.  
  54. Paintbrush is a registered trademark of Zsoft Corporation.%@NL@%
  55.  
  56. IBM, AT, and PS/2 are registered trademarks and PC/XT, 
  57. 386, and Micro Channel are trademarks of International Business Machines 
  58. Corporation.%@NL@%
  59.  
  60. Intel is a registered trademark and i486 is a trademark 
  61. of Intel Corporation.%@NL@%
  62.  
  63. COMPAQ is a registered trademark of Compaq Computer Corporation.%@NL@%
  64.  
  65. Document No. SY0329C-300-R00-1089%@NL@%
  66.  
  67. %@NL@%
  68.  
  69.  
  70.  
  71.  
  72. %@1@%%@AB@%Table of Contents%@AE@%%@EH@%%@NL@%
  73. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  74.  
  75.  
  76.  
  77. %@AB@%Introduction to Virtual Devices%@AE@%%@BO:        72e9@%
  78.      What You Should Know Before You Start%@BO:        7584@%
  79.      Organization of This Document%@BO:        7df3@%
  80.      Notational Conventions%@BO:        8842@%
  81.  
  82.  
  83. %@AB@%PART III%@AE@%%@BO:        8fdc@%  %@AB@%Writing Virtual Devices%@AE@%
  84. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  85.  
  86.  
  87. %@AB@%Chapter 16%@AE@%%@BO:        93c3@%  %@AB@%Overview of Windows in 386 Enhanced Mode%@AE@%
  88.  
  89.      16.1%@BO:        9bc9@%  The Operating Environment
  90.      16.2%@BO:        a358@%  Virtual Machines
  91.             16.2.1%@BO:        ab0e@%    The Privilege Rings of a VM
  92.             16.2.2%@BO:        b0f0@%    VM Handles
  93.             16.2.3%@BO:        b24c@%    The Client Register Structure 
  94.      16.3%@BO:        b408@%  The Virtual Machine Manager
  95.      16.4%@BO:        b7c0@%  Virtual Devices
  96.             16.4.1%@BO:        bb6d@%    VxD Components
  97.             16.4.2%@BO:        be3f@%    The Device Control Procedure
  98.             16.4.3%@BO:        c1ab@%    The Device Descriptor Block
  99.             16.4.4%@BO:        c42d@%    VxD IDs
  100.             16.4.5%@BO:        c72e@%    VxD Initialization Order
  101.      16.5%@BO:        ca4f@%  How VxDs Work
  102.             16.5.1%@BO:        cd21@%    Enhanced Windows Execution Scheduling 
  103.             16.5.2%@BO:        e287@%    Memory Models
  104.             16.5.3%@BO:        f27f@%    Services
  105.             16.5.4%@BO:        f914@%    Callback Procedures
  106.             16.5.5%@BO:        fd06@%    I/O Port Hooks
  107.             16.5.6%@BO:       10002@%    Interrupt Hooks
  108.             16.5.7%@BO:       10335@%    Loading Sequence
  109.      16.6%@BO:       10c9e@%  VxD Examples
  110.  
  111. %@AB@%Chapter 17%@AE@%%@BO:       10e80@%  %@AB@%Virtual Device Programming Topics%@AE@%
  112.  
  113.      17.1%@BO:       1147d@%  Writing VxDs
  114.             17.1.1%@BO:       1196b@%    VxD Memory Model
  115.             17.1.2%@BO:       11f78@%    VxD Segmentation
  116.             17.1.3%@BO:       126f1@%    VxD Declaration
  117.             17.1.4%@BO:       13db0@%    VxD Services
  118.             17.1.5%@BO:       158bb@%    VxD APIs (Call-Ins)
  119.             17.1.6%@BO:       16090@%    VxD INT 2F Usage
  120.      17.2%@BO:       162a7@%  Building a VxD
  121.             17.2.1%@BO:       16a37@%    MASM5.10B
  122.             17.2.2%@BO:       16ed1@%    LINK386
  123.             17.2.3%@BO:       17b8f@%    ADDHDR
  124.             17.2.4%@BO:       17d35@%    MAPSYM32
  125.             17.2.5%@BO:       17edf@%    Installing a VxD
  126.      17.3%@BO:       1803c@%  Initializing a VxD
  127.             17.3.1%@BO:       1818e@%    Real-Mode Initialization
  128.             17.3.2%@BO:       19b91@%    Protected-Mode Initialization
  129.      17.4%@BO:       1a2ac@%  Tracking the VM States
  130.             17.4.1%@BO:       1a411@%    VM Creation and Initialization
  131.             17.4.2%@BO:       1a8c3@%    VM State Changes
  132.             17.4.3%@BO:       1b649@%    VM Termination
  133.      17.5%@BO:       1bed8@%  Exiting Windows
  134.      17.6%@BO:       1c2bd@%  Debugging a VxD
  135.             17.6.1%@BO:       1c4ca@%    Entering WDEB386
  136.             17.6.2%@BO:       1c7a5@%    Tracing Paths of Execution
  137.             17.6.3%@BO:       1cfc1@%    Querying the VxD State
  138.  
  139. %@AB@%Chapter 18%@AE@%%@BO:       1d1eb@%  %@AB@%The VDD and Grabber DLL%@AE@%
  140.  
  141.      18.1%@BO:       1d4d5@%  Introduction to VDDs and the Grabber DLL
  142.             18.1.1%@BO:       1d7e5@%    VDD Interaction with WINOLDAP
  143.             18.1.2%@BO:       1e393@%    VDD User Messages
  144.             18.1.3%@BO:       1e73f@%    VDD I/O Trapping and Hooked Pages
  145.             18.1.4%@BO:       1eb13@%    Grabber Naming Conventions
  146.      18.2%@BO:       1ec5c@%  VDD Programming
  147.             18.2.1%@BO:       1f1da@%    VDD Efficiency
  148.             18.2.2%@BO:       1f7f2@%    Converting Your 2.x VDD
  149.             18.2.3%@BO:       2078a@%    Environment State Change Requirements for a VDD
  150.             18.2.4%@BO:       21cb7@%    Grabber API
  151.      18.3%@BO:       222db@%  Grabber DLL Interfaces
  152.             18.3.1%@BO:       22837@%    On-Screen Selection Functions
  153.             18.3.2%@BO:       23485@%    Selection Functions
  154.             AdjustInitEndPt%@BO:       23544@%
  155.             BeginSelection%@BO:       2392d@%
  156.             ConsSelecRec%@BO:       23b70@%
  157.             EndSelection%@BO:       23d87@%
  158.             InvertSelection%@BO:       23f1d@%
  159.             KeySelection%@BO:       24105@%
  160.             MakeSelctRect%@BO:       24740@%
  161.             RenderSelection%@BO:       24c1f@%
  162.             GetDisplayUpd%@BO:       25029@%
  163.             CheckGRBVersion%@BO:       25611@%
  164.             CursorOff%@BO:       25824@%
  165.             CursorOn%@BO:       259d5@%
  166.             CursorPosit%@BO:       25b90@%
  167.             GetFontList%@BO:       25daa@%
  168.             GrabComplete%@BO:       25f92@%
  169.             GrabEvent%@BO:       262aa@%
  170.             GrbUnLockApp%@BO:       265c0@%
  171.             InitGrabber%@BO:       2676f@%
  172.             PaintScreen%@BO:       269be@%
  173.             ScreenFree%@BO:       26d11@%
  174.             SetPaintFnt%@BO:       26efa@%
  175.             UpdateScreen%@BO:       2750d@%
  176.  
  177.  
  178. %@AB@%PART IV%@AE@%%@BO:       277ac@%  %@AB@%Virtual Device Services%@AE@%
  179. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  180.  
  181.  
  182. %@AB@%Chapter 19%@AE@%%@BO:       279b6@%  %@AB@%Memory Management Services%@AE@%
  183.  
  184.      19.1%@BO:       288e4@%  System Data Object Management
  185.             Allocate_Device_CB_Area%@BO:       28f06@%
  186.             Allocate_Global_V86_Data_Area%@BO:       29cec@%
  187.             Allocate_Temp_V86_Data_Area%@BO:       2bcdc@%
  188.             Free_Temp_V86_Data_Area%@BO:       2c762@%
  189.             Device V86 Page Management%@BO:       2cd13@%
  190.             Assign_Device_V86_Pages Assign_Device_V86_Pages service%@BO:       2dad8@%
  191.             Deassign_Device_V86_Pages%@BO:       2e2ad@%
  192.             Get_Device_V86_Pages_Array%@BO:       2e987@%
  193.             Hook_V86_Page%@BO:       2f2bb@%
  194.             GDT/LDT Management%@BO:       2fad1@%
  195.             Allocate_GDT_Selector%@BO:       2fe1e@%
  196.             Allocate_LDT_Selector%@BO:       3084b@%
  197.             BuildDescDWORDs%@BO:       31a18@%
  198.             Free_GDT_Selector%@BO:       3239b@%
  199.             Free_LDT_Selector%@BO:       32730@%
  200.             GetDescriptor%@BO:       32afb@%
  201.             SetDescriptor%@BO:       33094@%
  202.             System Heap Allocator%@BO:       337a4@%
  203.             HeapAllocate%@BO:       342d7@%
  204.             HeapFree%@BO:       349bc@%
  205.             HeapGetSize%@BO:       34cd3@%
  206.             HeapReAllocate%@BO:       34ff3@%
  207.             System Page Allocator%@BO:       35d18@%
  208.             CopyPageTable%@BO:       36409@%
  209.             GetDemandPageInfo%@BO:       36ff7@%
  210.             GetFreePageCount%@BO:       378bd@%
  211.             GetSetPageOutCount%@BO:       38049@%
  212.             GetSysPageCount%@BO:       386b2@%
  213.             GetVMPgCount%@BO:       389aa@%
  214.             MapIntoV86%@BO:       38ebe@%
  215.             ModifyPageBits%@BO:       3a7cc@%
  216.             PageAllocate%@BO:       3b597@%
  217.             PageFree%@BO:       3d946@%
  218.             PageGetAllocInfo%@BO:       3df3f@%
  219.             PageGetSizeAddr%@BO:       3e7c5@%
  220.             PageLock%@BO:       3eca6@%
  221.             PageOutDirtyPages%@BO:       3f8aa@%
  222.             PageReAllocate%@BO:       404a2@%
  223.             PageUnLock%@BO:       41768@%
  224.             PhysIntoV86%@BO:       4236e@%
  225.             TestGlobalV86Mem%@BO:       42f47@%
  226.             Looking At Physical Device Memory From a VxD%@BO:       439cc@%
  227.             MapPhysToLinear%@BO:       43f3f@%
  228.             Data Access Services%@BO:       4470f@%
  229.             GetFirstV86Page%@BO:       44890@%
  230.             GetNulPageHandle%@BO:       44aa1@%
  231.             GetAppFlatDSAlias()%@BO:       44bd9@%
  232.             Special Services For Protected Mode APIs%@BO:       4549a@%
  233.             GetV86PageableArray%@BO:       45898@%
  234.             LinMapIntoV86%@BO:       4601b@%
  235.             LinPageLock%@BO:       47793@%
  236.             LinPageUnLock%@BO:       47ee7@%
  237.             PageCheckLinRange%@BO:       48805@%
  238.             PageDiscardPages%@BO:       48de9@%
  239.             SelectorMapFlat%@BO:       496fb@%
  240.             SetResetV86Pageable%@BO:       49d15@%
  241.             Instance Data Management%@BO:       4b809@%
  242.             AddInstanceItem%@BO:       4bf0b@%
  243.             MMGR_Toggle_HMA%@BO:       4d018@%
  244.             Looking At V86 Address Space%@BO:       4e0b6@%
  245.             CB_High_Linear%@BO:       4e253@%
  246.  
  247. %@AB@%Chapter 20%@AE@%%@BO:       4e66d@%  %@AB@%I/O Services and Macros%@AE@%
  248.  
  249.      20.1%@BO:       4ec75@%  Handling Different I/O Types
  250.      20.2%@BO:       4fcff@%  I/O Macros
  251.      20.3%@BO:       501ec@%  I/O Services
  252.             Enable_Global_Trapping, Disable_Global_Trapping%@BO:       5041d@%
  253.             Enable_Local_Trapping, Disable_Local_Trapping%@BO:       50747@%
  254.             Install_IO_Handler (Initialization only)%@BO:       509df@%
  255.             Install_Mult_IO_Handlers (Initialization only)%@BO:       50f55@%
  256.             Simulate_IO%@BO:       51469@%
  257.  
  258. %@AB@%Chapter 21%@AE@%%@BO:       52402@%  %@AB@%VM Interrupt and Call Services%@AE@%
  259.  
  260.             Build_Int_Stack_Frame%@BO:       52921@%
  261.             Call_When_Idle%@BO:       52e17@%
  262.             Call_When_VM_Ints_Enabled%@BO:       534ee@%
  263.             Disable_VM_Ints%@BO:       539e5@%
  264.             Enable_VM_Ints%@BO:       53c12@%
  265.             Get_PM_Int_Type%@BO:       53f8b@%
  266.             Get_V86_Int_Vector, Get_PM_Int_Vector%@BO:       54478@%
  267.             Hook_V86_Int_Chain (Initialization only)%@BO:       54a5a@%
  268.             Set_PM_Int_Type%@BO:       557b1@%
  269.             Set_V86_Int_Vector, Set_PM_Int_Vector%@BO:       55c9f@%
  270.             Simulate_Far_Call%@BO:       56108@%
  271.             Simulate_Far_Jmp%@BO:       56541@%
  272.             Simulate_Far_Ret%@BO:       56800@%
  273.             Simulate_Far_Ret_N%@BO:       56a8f@%
  274.             Simulate_Int%@BO:       56d7b@%
  275.             Simulate_Iret%@BO:       5743c@%
  276.  
  277. %@AB@%Chapter 22%@AE@%%@BO:       5774c@%  %@AB@%Nested Execution Services%@AE@%
  278.  
  279.             Begin_Nest_Exec%@BO:       57b4b@%
  280.             Begin_Nest_V86_Exec%@BO:       58713@%
  281.             Begin_Use_Locked_PM_Stack%@BO:       58b97@%
  282.             End_Nest_Exec%@BO:       590a6@%
  283.             End_Use_Locked_PM_Stack%@BO:       5954c@%
  284.             Exec_Int%@BO:       59882@%
  285.             Exec_VxD_Int%@BO:       59ccb@%
  286.             Restore_Client_State%@BO:       5ae31@%
  287.             Resume_Exec%@BO:       5b3f0@%
  288.             Save_Client_State%@BO:       5c014@%
  289.             Set_PM_Exec_Mode%@BO:       5ca27@%
  290.             Set_V86_Exec_Mode%@BO:       5ce84@%
  291.  
  292. %@AB@%Chapter 23%@AE@%%@BO:       5d2a4@%  %@AB@%Break Point and Callback Services%@AE@%
  293.  
  294.             Allocate_V86_Call_Back, Allocate_PM_Call_Back%@BO:       5d61c@%
  295.             Call_When_Idle%@BO:       5dd2e@%
  296.             Call_When_VM_Returns%@BO:       5e3a0@%
  297.             Install_V86_Break_Point%@BO:       5ed32@%
  298.             Remove_V86_Break_Point%@BO:       5fa7b@%
  299.  
  300. %@AB@%Chapter 24%@AE@%%@BO:       5fd77@%  %@AB@%Primary Scheduler Services%@AE@%
  301.  
  302.             Adjust_Exec_Priority%@BO:       60c1f@%
  303.             Begin_Critical_Section%@BO:       618bc@%
  304.             Call_When_Not_Critical%@BO:       624e8@%
  305.             Call_When_Task_Switched%@BO:       62a5b@%
  306.             Claim_Critical_Section%@BO:       62fa5@%
  307.             Create_Semaphore%@BO:       632cc@%
  308.             Destroy_Semaphore%@BO:       633f1@%
  309.             End_Crit_And_Suspend%@BO:       63517@%
  310.             End_Critical_Section%@BO:       63e19@%
  311.             Get_Crit_Section_Status%@BO:       6414b@%
  312.             No_Fail_Resume_VM%@BO:       6454f@%
  313.             Nuke_VM%@BO:       648fd@%
  314.             Release_Critical_Section%@BO:       64cb5@%
  315.             Resume_VM%@BO:       64f35@%
  316.             Signal_Semaphore%@BO:       653d3@%
  317.             Suspend_VM%@BO:       654e5@%
  318.             Wait_Semaphore%@BO:       65c53@%
  319.  
  320. %@AB@%Chapter 25%@AE@%%@BO:       65d54@%  %@AB@%Time-Slice Scheduler Services%@AE@%
  321.  
  322.             Adjust_Execution_Time%@BO:       67376@%
  323.             Call_When_Idle%@BO:       67a48@%
  324.             Get_Execution_Focus%@BO:       68125@%
  325.             Get_Time_Slice_Granularity%@BO:       6837f@%
  326.             Get_Time_Slice_Info%@BO:       6861e@%
  327.             Get_Time_Slice_Priority%@BO:       68919@%
  328.             Release_Time_Slice%@BO:       68dd6@%
  329.             Set_Execution_Focus%@BO:       69226@%
  330.             Set_Time_Slice_Granularity%@BO:       6961a@%
  331.             Set_Time_Slice_Priority%@BO:       69949@%
  332.             Wake_Up_VM%@BO:       69e64@%
  333.  
  334. %@AB@%Chapter 26%@AE@%%@BO:       6a0b8@%  %@AB@%Event Services%@AE@%
  335.  
  336.             Call_Global_Event%@BO:       6aa71@%
  337.             Call_Priority_VM_Event%@BO:       6aebf@%
  338.             Call_VM_Event%@BO:       6c218@%
  339.             Cancel_Global_Event%@BO:       6c692@%
  340.             Cancel_Priority_VM_Event%@BO:       6cc38@%
  341.             Cancel_VM_Event%@BO:       6d34f@%
  342.             Hook_NMI_Event%@BO:       6d9b1@%
  343.             Schedule_Global_Event%@BO:       6dc88@%
  344.             Schedule_VM_Event%@BO:       6e001@%
  345.  
  346. %@AB@%Chapter 27%@AE@%%@BO:       6e4a6@%  %@AB@%Timing Services%@AE@%
  347.  
  348.             Cancel_Time_Out%@BO:       6e848@%
  349.             Get_Last_Updated_System_Time%@BO:       6ed71@%
  350.             Get_Last_Updated_VM_Exec_Time%@BO:       6ef86@%
  351.             Get_System_Time%@BO:       6f189@%
  352.             Get_VM_Exec_Time%@BO:       6f4b2@%
  353.             Set_Global_Time_Out%@BO:       6f850@%
  354.             Set_VM_Time_Out%@BO:       6fead@%
  355.             Update_System_Clock%@BO:       70662@%
  356.  
  357. %@AB@%Chapter 28%@AE@%%@BO:       70a3b@%  %@AB@%Processor Fault and Interrupt Services%@AE@%
  358.  
  359.             Get_Fault_Hook_Addrs%@BO:       70d9a@%
  360.             Get_NMI_Handler_Addr%@BO:       71178@%
  361.             Hook_NMI_Event%@BO:       71ace@%
  362.             Hook_V86_Fault, Hook_PM_Fault, Hook_VMM_Fault%@BO:       71e00@%
  363.             Hook_V86_Page%@BO:       7295c@%
  364.             Set_NMI_Handler_Addr%@BO:       731cb@%
  365.  
  366. %@AB@%Chapter 29%@AE@%%@BO:       733e5@%  %@AB@%Information Services%@AE@%
  367.  
  368.             Get_Cur_VM_Handle%@BO:       73862@%
  369.             Get_Next_VM_Handle%@BO:       73a98@%
  370.             Get_Sys_VM_Handle%@BO:       73f7c@%
  371.             Get_VMM_Reenter_Count%@BO:       7419f@%
  372.             Get_VMM_Version%@BO:       7457f@%
  373.             GetSet_HMA_Info%@BO:       747b1@%
  374.             Test_Cur_VM_Handle%@BO:       74cdc@%
  375.             Test_Debug_Installed%@BO:       74f66@%
  376.             Test_Sys_VM_Handle%@BO:       751b3@%
  377.             Validate_VM_Handle%@BO:       75442@%
  378.  
  379. %@AB@%Chapter 30%@AE@%%@BO:       756a3@%  %@AB@%Initialization Information Services%@AE@%
  380.  
  381.             Convert_Boolean_String (Initialization only)%@BO:       75c03@%
  382.             Convert_Decimal_String (Initialization only)%@BO:       76007@%
  383.             Convert_Fixed_Point_String (Initialization only)%@BO:       7654d@%
  384.             Convert_Hex_String (Initialization only)%@BO:       76afc@%
  385.             Get_Config_Directory (Initialization only)%@BO:       76f58@%
  386.             Get_Environment_String (Initialization only)%@BO:       7725e@%
  387.             Get_Exec_Path (Initialization only)%@BO:       777ef@%
  388.             GetDOSVectors (Initialization only)%@BO:       77b5e@%
  389.             Get_Machine_Info (Initialization only)%@BO:       77f06@%
  390.             Get_Next_Profile_String (Initialization only)%@BO:       783fa@%
  391.             Get_Profile_Boolean (Initialization only)%@BO:       78841@%
  392.             Get_Profile_Decimal_Int (Initialization only)%@BO:       78e36@%
  393.             Get_Profile_Fixed_Point (Initialization only)%@BO:       793e3@%
  394.             Get_Profile_Hex_Int (Initialization only)%@BO:       79a0b@%
  395.             Get_Profile_String (Initialization only)%@BO:       7a047@%
  396.             Get_PSP_Segment (Initialization only)%@BO:       7a45d@%
  397.             OpenFile (Initialization only)%@BO:       7a7b5@%
  398.  
  399. %@AB@%Chapter 31%@AE@%%@BO:       7ac4d@%  %@AB@%Linked List Services%@AE@%
  400.  
  401.             List_Allocate%@BO:       7aff8@%
  402.             List_Attach%@BO:       7b3b8@%
  403.             List_Attach_Tail%@BO:       7b71a@%
  404.             List_Create%@BO:       7ba66@%
  405.             List_Deallocate%@BO:       7c58d@%
  406.             List_Destroy%@BO:       7c854@%
  407.             List_Get_First%@BO:       7cada@%
  408.             List_Get_Next%@BO:       7cd85@%
  409.             List_Insert%@BO:       7d24c@%
  410.             List_Remove%@BO:       7d6dd@%
  411.             List_Remove_First%@BO:       7da23@%
  412.  
  413. %@AB@%Chapter 32%@AE@%%@BO:       7dd75@%  %@AB@%Error Condition Services%@AE@%
  414.  
  415.             Crash_Cur_VM%@BO:       7e0b1@%
  416.             Fatal_Error_Handler%@BO:       7e39f@%
  417.             Fatal_Memory_Error%@BO:       7e9b8@%
  418.  
  419. %@AB@%Chapter 33%@AE@%%@BO:       7ed78@%  %@AB@%Miscellaneous Services%@AE@%
  420.  
  421.             Begin_Reentrant_Execution%@BO:       7f1c7@%
  422.             End_Reentrant_Execution%@BO:       7f689@%
  423.             Hook_Device_Service%@BO:       7f8d6@%
  424.             Hook_Device_V86_API, Hook_PM_Device_API%@BO:       80399@%
  425.             Map_Flat%@BO:       80984@%
  426.             MMGR_SetNULPageAddr%@BO:       8162b@%
  427.             Set_System_Exit_Code%@BO:       81935@%
  428.             Simulate_Pop%@BO:       81cc7@%
  429.             Simulate_Push%@BO:       81f44@%
  430.             System_Control%@BO:       821d7@%
  431.  
  432. %@AB@%Chapter 34%@AE@%%@BO:       82ce5@%  %@AB@%Shell Services%@AE@%
  433.  
  434.             SHELL_Event%@BO:       82fac@%
  435.             SHELL_Get_Version%@BO:       83589@%
  436.             SHELL_Message%@BO:       8379b@%
  437.             SHELL_Resolve_Contention%@BO:       83d5f@%
  438.             SHELL_SYSMODAL_Message%@BO:       8408e@%
  439.  
  440. %@AB@%Chapter 35%@AE@%%@BO:       84418@%  %@AB@%Virtual Display Device (VDD) Services%@AE@%
  441.  
  442.      35.1%@BO:       847f8@%  Displaying a VM's Video Memory in a Window
  443.      35.2%@BO:       84f36@%  Message Mode Services
  444.             VDD_Msg_BakColor%@BO:       850fd@%
  445.             VDD_Msg_ClrScrn%@BO:       85336@%
  446.             VDD_Msg_ForColor%@BO:       85692@%
  447.             VDD_Msg_SetCursPos%@BO:       858cb@%
  448.             VDD_Msg_TextOut%@BO:       85ae9@%
  449.             Miscellaneous VDD Services%@BO:       85d7d@%
  450.             VDD_Get_GrabRtn%@BO:       85eef@%
  451.             VDD_Get_ModTime%@BO:       861fa@%
  452.             VDD_Get_Version%@BO:       86455@%
  453.             VDD_Hide_Cursor%@BO:       866a1@%
  454.             VDD_PIF_State%@BO:       869e4@%
  455.             VDD_Query_Access%@BO:       86bd8@%
  456.             VDD_Set_HCurTrk%@BO:       86f33@%
  457.             VDD_Set_VMType%@BO:       871b9@%
  458.             VDD_Query_Access%@BO:       875ad@%
  459.  
  460. %@AB@%Chapter 36%@AE@%%@BO:       877fe@%  %@AB@%Virtual Keyboard Device (VKD) Services%@AE@%
  461.  
  462.             VKD_Cancel_Hot_Key_State%@BO:       87d3e@%
  463.             VKD_Cancel_Paste%@BO:       87f2d@%
  464.             VKD_Define_Hot_Key%@BO:       88122@%
  465.             VKD_Define_Paste_Mode%@BO:       88f68@%
  466.             VKD_Flush_Msg_Key_Queue%@BO:       8937b@%
  467.             VKD_Force_Keys%@BO:       89587@%
  468.             VKD_Get_Kbd_Owner%@BO:       89892@%
  469.             VKD_Get_Msg_Key%@BO:       89a88@%
  470.             VKD_Get_Version%@BO:       89de7@%
  471.             VKD_Local_Disable_Hot_Key%@BO:       89fdd@%
  472.             VKD_Local_Enable_Hot_Key%@BO:       8a22b@%
  473.             VKD_Peek_Msg_Key%@BO:       8a477@%
  474.             VKD_Reflect_Hot_Key%@BO:       8a7bf@%
  475.             VKD_Remove_Hot_Key%@BO:       8abec@%
  476.             VKD_Start_Paste%@BO:       8adcd@%
  477.  
  478. %@AB@%Chapter 37%@AE@%%@BO:       8b715@%  %@AB@%Virtual PIC Device (VPICD) Services%@AE@%
  479.  
  480.      37.1%@BO:       8baf9@%  Default Interrupt Handling
  481.      37.2%@BO:       8c121@%  Virtualizing an IRQ
  482.      37.3%@BO:       8c751@%  Virtualized IRQ Callback Procedures
  483.             VID_Hw_Int_Proc%@BO:       8cb57@%
  484.             VID_EOI_Proc%@BO:       8d140@%
  485.             VID_Virt_Int_Proc%@BO:       8d63e@%
  486.             VID_IRET_Proc%@BO:       8da51@%
  487.             VID_Mask_Change_Proc%@BO:       8e499@%
  488.             VPICD Services%@BO:       8e71d@%
  489.             VPICD_Call_When_Hw_Int%@BO:       8e82f@%
  490.             VPICD_Clear_Int_Request%@BO:       8eef7@%
  491.             VPICD_Convert_Handle_To_IRQ%@BO:       8f242@%
  492.             VPICD_Convert_Int_To_IRQ%@BO:       8f461@%
  493.             VPICD_Convert_IRQ_To_Int%@BO:       8f7cc@%
  494.             VPICD_Get_Complete_Status%@BO:       8fb2c@%
  495.             VPICD_Get_IRQ_Complete_Status%@BO:       8fc2a@%
  496.             VPICD_Get_Status%@BO:       90083@%
  497.             VPICD_Get_Version%@BO:       90683@%
  498.             VPICD_Phys_EOI%@BO:       90995@%
  499.             VPICD_Physically_Mask%@BO:       90cbd@%
  500.             VPICD_Physically_Unmask%@BO:       90f33@%
  501.             VPICD_Set_Auto_Masking%@BO:       911b1@%
  502.             VPICD_Set_Int_Request%@BO:       9151a@%
  503.             VPICD_Test_Phys_Request%@BO:       91c78@%
  504.             VPICD_Virtualize_IRQ%@BO:       91eb8@%
  505.  
  506. %@AB@%Chapter 38%@AE@%%@BO:       924f0@%  %@AB@%Virtual Sound Device (VSD) Services%@AE@%
  507.  
  508.             VSD_Bell%@BO:       92713@%
  509.             VSD_Get_Version%@BO:       929af@%
  510.  
  511. %@AB@%Chapter 39%@AE@%%@BO:       92bb6@%  %@AB@%Virtual Timer Device (VTD) Services%@AE@%
  512.  
  513.             VTD_Begin_Min_Int_Period%@BO:       92ece@%
  514.             VTD_Disable_Trapping%@BO:       935b2@%
  515.             VTD_Enable_Trapping%@BO:       93c00@%
  516.             VTD_End_Min_Int_Period%@BO:       93ed1@%
  517.             VTD_Get_Interrupt_Period%@BO:       94257@%
  518.             VTD_Get_Version%@BO:       94453@%
  519.             VTD_Update_System_Clock%@BO:       94739@%
  520.  
  521. %@AB@%Chapter 40%@AE@%%@BO:       9496e@%  %@AB@%V86 Mode Memory Manager Device Services%@AE@%
  522.  
  523.      40.1%@BO:       9512a@%  Initialization Services
  524.             V86MMGR_Get_Version%@BO:       9521f@%
  525.             V86MMGR_Allocate_V86_Pages%@BO:       95434@%
  526.             V86MMGR_Set_EMS_XMS_Limits%@BO:       95a01@%
  527.             V86MMGR_Get_EMS_XMS_Limits%@BO:       95e97@%
  528.             API Translation and Mapping%@BO:       9623c@%
  529.             V86MMGR_Set_Mapping_Info%@BO:       999ba@%
  530.             V86MMGR_Xlat_API%@BO:       9a02a@%
  531.             V86MMGR_Load_Client_Ptr%@BO:       9c979@%
  532.             V86MMGR_Allocate_Buffer%@BO:       9cf27@%
  533.             V86MMGR_Free_Buffer%@BO:       9d580@%
  534.             V86MMGR_Get_Xlat_Buff_State%@BO:       9d9a4@%
  535.             V86MMGR_Set_Xlat_Buff_State%@BO:       9de0a@%
  536.             V86MMGR_Get_VM_Flat_Sel%@BO:       9e238@%
  537.             V86MMGR_Get_Mapping_Info%@BO:       9e633@%
  538.             V86MMGR_Map_Pages%@BO:       9e85f@%
  539.             V86MMGR_Free_Page_Map_Region%@BO:       9ebe1@%
  540.  
  541. %@AB@%Chapter 41%@AE@%%@BO:       9ee33@%  %@AB@%Virtual DMA Device (VDMAD) Services%@AE@%
  542.  
  543.             VDMAD_Copy_From_Buffer%@BO:       9f7a8@%
  544.             VDMAD_Copy_To_Buffer%@BO:       9fb9d@%
  545.             VDMAD_Default_Handler%@BO:       9ff72@%
  546.             VDMAD_Disable_Translation%@BO:       a0311@%
  547.             VDMAD_Enable_Translation%@BO:       a06b3@%
  548.             VDMAD_Get_EISA_Adr_Mode%@BO:       a09e5@%
  549.             VDMAD_Get_Region_Info%@BO:       a0d9a@%
  550.             VDMAD_Get_Version%@BO:       a113c@%
  551.             VDMAD_Get_Virt_State%@BO:       a13eb@%
  552.             VDMAD_Lock_DMA_Region%@BO:       a1a2a@%
  553.             VDMAD_Mask_Channel%@BO:       a24fd@%
  554.             VDMAD_Release_Buffer%@BO:       a270a@%
  555.             VDMAD_Request_Buffer%@BO:       a2a35@%
  556.             VDMAD_Reserve_Buffer_Space%@BO:       a2d5d@%
  557.             VDMAD_Scatter_Lock%@BO:       a3230@%
  558.             VDMAD_Scatter_Unlock%@BO:       a3776@%
  559.             VDMAD_Set_EISA_Adr_Mode%@BO:       a3c37@%
  560.             VDMAD_Set_Phys_State%@BO:       a3ee6@%
  561.             VDMAD_Set_Region_Info%@BO:       a41dc@%
  562.             VDMAD_Set_Virt_State%@BO:       a44ca@%
  563.             VDMAD_Unlock_DMA_Region%@BO:       a49ff@%
  564.             VDMAD_UnMask_Channel%@BO:       a4cfc@%
  565.             VDMAD_Virtualize_Channel%@BO:       a4f01@%
  566.  
  567. %@AB@%Chapter 42%@AE@%%@BO:       a5473@%  %@AB@%Virtual DOSNET Device Services%@AE@%
  568.  
  569.             DOSNET_Get_Version%@BO:       a574f@%
  570.             DOSNET_Do_PSP_Adjust%@BO:       a5979@%
  571.             DOSNET_Send_FILESYSCHANGE%@BO:       a6315@%
  572.  
  573. %@AB@%Appendix A%@AE@%%@BO:       a6a17@%  %@AB@%Appendix A Terms and Acronyms%@AE@%
  574.  
  575.  
  576. %@AB@%Appendix B%@AE@%%@BO:       a9f7c@%  %@AB@%Understanding Modes%@AE@%
  577.  
  578.      B.1%@BO:       aa0bd@%   Windows Modes
  579.      B.2%@BO:       aa501@%   Microprocessor Modes
  580.  
  581. %@AB@%Appendix C%@AE@%%@BO:       ab0dd@%  %@AB@%Creating Distribution Disks for Drivers%@AE@%
  582.  
  583.      C.1%@BO:       ab621@%   What is an Information File?
  584.      C.2%@BO:       abc72@%   Different Types of Information Files
  585.      C.3%@BO:       ac123@%   General Format and Syntax for Information Files
  586.      C.4%@BO:       acd59@%   File Location Information
  587.      C.5%@BO:       ad64e@%   Creating .INF File Entries
  588.             C.5.1%@BO:       ad999@%    Display Device
  589.             C.5.2%@BO:       af434@%    Mouse or Other Pointing Device
  590.             C.5.3%@BO:       af7f2@%    Network Device
  591.             C.5.4%@BO:       b0351@%    Keyboard Device
  592.             C.5.5%@BO:       b0af2@%    Machine-Dependent Configuration
  593.      C.6%@BO:       b1bae@%   Creating .INF File Entries for Printer Drivers
  594.             C.6.1%@BO:       b1eeb@%    .INF File Entries
  595.             C.6.2%@BO:       b2ff4@%    Driver Description (.DEF) File
  596.             C.6.3%@BO:       b3892@%    Special Considerations
  597.      C.7%@BO:       b3a75@%   Testing the Installation of Your .INF File
  598.             C.7.1%@BO:       b3d81@%    Testing with Setup
  599.             C.7.2%@BO:       b459f@%    Testing with Control Panel
  600.      C.8%@BO:       b4c43@%   Informing Microsoft About the Availability of Your Driver 
  601.        and/or Virtual Device
  602.      C.9%@BO:       b4fde@%   Error Messages When Running Debug Setup
  603.  
  604. %@AB@%Appendix D%@AE@%%@BO:       b5a78@%  %@AB@%Windows INT 2FH API%@AE@%
  605.  
  606.      D.1%@BO:       b5f96@%   Call-In Interfaces
  607.             D.1.1%@BO:       b6176@%    Enhanced Windows Installation Check (AX=1600H)
  608.             D.1.2%@BO:       b67b2@%    Releasing Current Virtual Machine's Time-Slice 
  609.               (AX=1680h)
  610.             D.1.3%@BO:       b6f59@%    Begin Critical Section (AX=1681h)
  611.             D.1.4%@BO:       b711a@%    End Critical Section (AX=1682h)
  612.             D.1.5%@BO:       b725a@%    Get Current Virtual Machine ID (AX=1683h)
  613.             D.1.6%@BO:       b7434@%    Get Device API Entry Point (AX=1684h)
  614.             D.1.7%@BO:       b7986@%    Switch VMs and CallBack (AX=1685h)
  615.             D.1.8%@BO:       b7e26@%    Detect Presence of INT 31H Services (AX=1686h)
  616.             Call Out Interfaces%@BO:       b8097@%
  617.             Windows/386 Version 2.xx API Compatibility%@BO:       baca8@%
  618.  
  619. %@AB@%Index%@AE@%%@BO:       bc2f7@%
  620.  
  621.  
  622.  
  623.  
  624. %@CR:C6A-Intro   @%%@1@%%@AB@%Introduction to Virtual Devices%@AE@%%@EH@%%@NL@%
  625. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  626.  
  627. This document explains how to modify existing device drivers or create new
  628. virtual devices that will work with Microsoft(R) Windows(tm) 3.0 when
  629. running in 386(tm) enhanced mode.  %@NL@%
  630.  
  631. This introduction provides some background information that you should
  632. review before using this documentation. The topics are presented in the
  633. following order:  %@NL@%
  634.  
  635.  
  636.   ■   What you should know before you start%@NL@%
  637.  
  638.   ■   Organization of this document%@NL@%
  639.  
  640.   ■   Notational conventions
  641. %@NL@%
  642.  
  643.  
  644.  
  645. %@2@%%@CR:C6A00000001 @%%@AB@%What You Should Know Before You Start%@AE@%%@EH@%%@NL@%
  646.  
  647. To program virtual devices for Windows when running in 386 enhanced mode,
  648. you should be familiar with Chapter 1, "Overview of Windows," in the
  649. %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% and the following topics.
  650. Suggested reference materials are shown by topic:  %@NL@%
  651.  
  652. %@TH:  25  1549 02 40 40 @%
  653. Topic                                   Reference
  654. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  655. Intel(R) 80386 and 80486 architecture   Introduction to the 80386, Intel 
  656.                                         Literature Sales P.O. Box 58130 Santa 
  657.                                         Clara, CA 95052-8130 Order Number: 
  658.                                         231252-001 ISBN 0-917017-38-2
  659.  
  660.                                         i486(tm) Microprocessor Programmer's 
  661.                                         Reference Manual, Intel Literature 
  662.                                         Sales P.O. Box 58130 Santa Clara, CA 
  663.                                         95052-8130 Order Number: 240486-001 
  664.                                         ISBN 1-5512-101-2
  665.  
  666. MS-DOS(R)                               Duncan, Ray. %@AI@%Advanced MS-DOS%@AE@%. 
  667.                                         Microsoft Press, P.O. Box 97017, 
  668.                                         Redmond WA. 98073-9717. ISBN Number: 
  669.                                         0-914845-77-2
  670.  
  671.                                         %@AI@%MS-DOS Encyclopedia%@AE@%. Microsoft Press, 
  672.                                         P.O. Box 97017, Redmond WA. 98073-9717.
  673.                                         ISBN Number: 1-5565-174-8
  674.  
  675. Microsoft Windows 3.0 (especially the   %@AI@%Microsoft Windows Software Development%@AE@%
  676. Memory Management topics)               %@AI@%Kit%@AE@%, %@AI@%Programming Topics%@AE@%
  677.  
  678. %@TE:  25  1549 02 40 40 @%
  679.  
  680. To obtain the DOS Protected Mode Interface (DPMI) specification, contact
  681. Intel at 1-800-548-4725. For the Virtual DMA Services (VDS) specification,
  682. submit a service request via Microsoft OnLine.  %@NL@%
  683.  
  684.  
  685. %@2@%%@CR:C6A00000002 @%%@AB@%Organization of This Document%@AE@%%@EH@%%@NL@%
  686.  
  687. This document is divided into the following parts and chapters:  %@NL@%
  688.  
  689. Part 3, "Writing Virtual Devices," describes the requirements of a virtual
  690. device and the environment of Windows when running in 386 enhanced mode. It
  691. contains the following chapters:  %@NL@%
  692.  
  693.  
  694.   ■   Chapter 16, "Overview of Windows in 386 Enhanced Mode," which provides
  695.       the conceptual foundation of the Windows virtual machine environment.%@NL@%
  696.  
  697.   ■   Chapter 17, "Virtual Device Programming Topics," which provides a more
  698.       in-depth look at various programming topics.%@NL@%
  699.  
  700.   ■   Chapter 18, "The VDD and Grabber DLL," which describes the development
  701.       of a Virtual Display Driver (VDD) and the dynamic-link library (DLL)
  702.       needed to support a video adapter.%@NL@%
  703.  
  704.  
  705. Part 4, "Virtual Device Services," provides detailed descriptions of all the
  706. available services. It consists of the following 24 chapters:  %@NL@%
  707.  
  708.  
  709.   ■   Chapter 19, "Memory Management Services"%@NL@%
  710.  
  711.   ■   Chapter 20, "I/O Services and Macros"%@NL@%
  712.  
  713.   ■   Chapter 21, "VM Interrupt and Call Services"%@NL@%
  714.  
  715.   ■   Chapter 22, "Nested Execution Services"%@NL@%
  716.  
  717.   ■   Chapter 23, "Break Point and Callback Services"%@NL@%
  718.  
  719.   ■   Chapter 24, "Primary Scheduler Services"%@NL@%
  720.  
  721.   ■   Chapter 25, "Time-Slice Scheduler Services"%@NL@%
  722.  
  723.   ■   Chapter 26, "Event Services"%@NL@%
  724.  
  725.   ■   Chapter 27, "Timing Services"%@NL@%
  726.  
  727.   ■   Chapter 28, "Processor Fault and Interrupt Services"%@NL@%
  728.  
  729.   ■   Chapter 29, "Information Services"%@NL@%
  730.  
  731.   ■   Chapter 30, "Initialization Information Services"%@NL@%
  732.  
  733.   ■   Chapter 31, "Linked List Services"%@NL@%
  734.  
  735.   ■   Chapter 32, "Error Condition Services"%@NL@%
  736.  
  737.   ■   Chapter 33, "Miscellaneous Services"%@NL@%
  738.  
  739.   ■   Chapter 34, "Shell Services"%@NL@%
  740.  
  741.   ■   Chapter 35, "Virtual Display Device (VDD) Services"%@NL@%
  742.  
  743.   ■   Chapter 36, "Virtual Keyboard Device (VKD) Services"%@NL@%
  744.  
  745.   ■   Chapter 37, "Virtual PIC Device (VPICD) Services"%@NL@%
  746.  
  747.   ■   Chapter 38, "Virtual Sound Device (VSD) Services"%@NL@%
  748.  
  749.   ■   Chapter 39, "Virtual Timer Device (VTD) Services"%@NL@%
  750.  
  751.   ■   Chapter 40, "V86 Mode Memory Manager Device Services"%@NL@%
  752.  
  753.   ■   Chapter 41, "Virtual DMA Device (VDMAD) Services"%@NL@%
  754.  
  755.   ■   Chapter 42, "Virtual DOSNET Device Services"%@NL@%
  756.  
  757.  
  758. Part 5, "Appendixes," provides the following supplemental reference
  759. material:  %@NL@%
  760.  
  761.  
  762.   ■   Appendix A, "Terms and Acronyms"%@NL@%
  763.  
  764.   ■   Appendix B, "Understanding Modes"%@NL@%
  765.  
  766.   ■   Appendix C, "Creating Distribution Disks for Drivers"%@NL@%
  767.  
  768.   ■   Appendix D, "Windows INT 2FH API"%@NL@%
  769.  
  770.  
  771.  
  772. %@2@%%@CR:C6A00000003 @%%@AB@%Notational Conventions%@AE@%%@EH@%%@NL@%
  773.  
  774. The following notational conventions are used throughout the DDK
  775. documentation set.  %@NL@%
  776.  
  777. %@TH:  29  1747 02 34 44 @%
  778. Convention                        Meaning
  779. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  780. %@AB@%bold%@AE@%                              Bold is used for keywords, such as 
  781.                                   function, register, macro, and data 
  782.                                   structure field names. These names are 
  783.                                   spelled exactly as they should appear in 
  784.                                   source programs. Notice the bold in the 
  785.                                   following example:
  786.  
  787.                                   %@AB@%Disable%@AE@% (%@AI@%lpDestDev%@AE@%)
  788.  
  789.                                   Here, %@AB@%Disable%@AE@% is bold to indicate that it 
  790.                                   is the name of a function.
  791.  
  792. %@AI@%italics%@AE@%                           Italics are used to indicate a placeholder
  793.                                   that should be replaced by an actual 
  794.                                   argument. In the preceding example, %@AI@%%@AE@%
  795.                                   %@AI@%lpDestDev%@AE@% is italic to indicate that it 
  796.                                   should be replaced by an argument.
  797.  
  798. (parentheses)                     Parentheses enclose the parameter or 
  799.                                   parameters that are to be passed to a 
  800.                                   function. In the preceding example, %@AI@%%@AE@%
  801.                                   %@AI@%lpDestDev%@AE@% is the parameter.
  802.  
  803. %@AS@%Monospace%@AE@%                         Monospace type is used for program code 
  804.                                   fragments and to illustrate the syntax of 
  805.                                   data structures.
  806.  
  807. %@TE:  29  1747 02 34 44 @%
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814. %@CR:C6A-Part 03 @%%@1@%%@AB@%PART III  Writing Virtual Devices%@AE@%%@EH@%%@NL@%
  815. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  816.  
  817. Microsoft Windows 3.0, while running in 386 enhanced mode, is a
  818. single-threaded multitasking environment. It can run unmodified,
  819. singletasking non-Windows applications by virtualizing system resources. A
  820. resource should be virtualized when multiple applications might use the
  821. resource. The software that does this, the %@AI@%virtual device%@AE@%, can also be used
  822. to provide other services, both to applications and other virtual devices.  %@NL@%
  823.  
  824. This part describes the enhanced Windows environment and details the writing
  825. of virtual devices. Part 4, "Virtual Device Services," describes the
  826. services provided by virtual devices. Chapter 1, "Overview of Windows," in
  827. the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% also contains material
  828. of general interest to the virtual device author.  %@NL@%
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835. %@CR:C6A00160001 @%%@1@%%@AB@%Chapter 16  Overview of Windows in 386 Enhanced Mode%@AE@%%@EH@%%@NL@%
  836. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  837.  
  838. When Microsoft Windows 3.0 is loaded and invoked on an appropriately
  839. configured system, it runs in an "enhanced" mode designed to capitalize on
  840. the power of the Intel 80386/80486 microprocessors. The 80386 and 80486
  841. chips, support multiple, independent memory regions. Enhanced Windows uses
  842. this to build multiple, independent virtual machines, each capable of
  843. running an application program.  %@NL@%
  844.  
  845. Enhanced Windows supports this multitasking virtual machine environment with
  846. a sophisticated set of services that are provided by the virtual devices
  847. (VxDs). Virtual devices provide access to all the system resources,
  848. including memory management, scheduling, and all the hardware devices.  %@NL@%
  849.  
  850. By writing a VxD for a particular hardware device, the author integrates
  851. that device into the powerful, enhanced Windows environment. For instance, a
  852. properly implemented virtual printer device will, by serializing access to
  853. the hardware port, enable multiple applications to share a single printer.  %@NL@%
  854.  
  855. This chapter provides a general description of the virtual machine
  856. environment and introduces the components of a virtual device. However,
  857. detailed programming instructions for the 80386 and 80486 are not provided.
  858. Therefore, a VxD programmer should already be familiar with the topics
  859. described in the preceding "Introduction to Virtual Devices."  %@NL@%
  860.  
  861. In the September, 1987, issue of the %@AI@%Microsoft Systems Journal%@AE@%, the article
  862. entitled "Microsoft Windows/386: Creating a Virtual Machine Environment,"
  863. discusses the structure of Windows/386(tm) version 2.x. It also contains an
  864. excellent description of the four modes of the Intel 80386 microprocessor. A
  865. portion of that discussion is included in Appendix B, "Understanding Modes,"
  866. to help you understand the current version of Windows when running in 386
  867. enhanced mode.  %@NL@%
  868.  
  869.  
  870. %@2@%%@CR:C6A00160002 @%%@AB@%16.1  The Operating Environment%@AE@%%@EH@%%@NL@%
  871.  
  872. Windows in 386 enhanced mode has a virtual machine (VM) architecture that
  873. provides preemptive multitasking for DOS applications on the 80386 and 80486
  874. processor.  %@NL@%
  875.  
  876. The following three major components are also shown graphically in Figure
  877. 16.1:  %@NL@%
  878.  
  879.  
  880.   ■   Virtual machines%@NL@%
  881.  
  882.   ■   Virtual Machine Manager%@NL@%
  883.  
  884.   ■   Virtual devices%@NL@%
  885.  
  886.  
  887. Windows 3.0 virtual machines (VMs) consist of a virtual 8086 (V86) mode
  888. portion and, a optional protected-mode (PM) portion and a control block used
  889. by the environment. The first VM created is called the System VM. This is
  890. the virtual machine in which the Windows graphical user interface runs.
  891. Non-Windows applications run in VMs of their own.%@CR:C6A00160003 @%%@CR:C6A00160004 @%%@CR:C6A00160005 @%%@CR:C6A00160006 @%%@NL@%
  892.  
  893. The Virtual Machine Manager (VMM) functions as a multitasking operating
  894. environment. The VMM provides services that control the main memory, the CPU
  895. execution time, and the peripheral devices. It runs, along with all the
  896. VxDs, in one, flat-model, 32-bit memory segment.%@CR:C6A00160007 @%%@CR:C6A00160008 @%%@NL@%
  897.  
  898. The virtual devices (VxDs) either virtualize a peripheral device, provide
  899. services for the VMM and VxDs, or both. The "x" in VxD stands for an
  900. arbitrary device. In an actual device name, the "x" is replaced with the
  901. name of the virtualized device, e.g., VDD for Virtual Display Device and
  902. VDMAD for Virtual DMA Device.%@CR:C6A00160009 @%%@CR:C6A00160010 @%%@NL@%
  903.  
  904. Internal hardware devices (e.g., the Programmable Interrupt Controller) and
  905. peripheral devices (e.g., a printer) are shown outside of the enhanced
  906. Windows environment in Figure 16.1. However, this is a simplified drawing
  907. since software routines such as BIOS may also be considered part of the
  908. peripheral device.  %@NL@%
  909.  
  910. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  911.  
  912.  
  913. %@2@%%@CR:C6A00160011 @%%@AB@%16.2  Virtual Machines%@AE@%%@EH@%%@NL@%
  914.  
  915. When Windows is running in 386 enhanced mode, it creates memory partitions
  916. that have a remarkable characteristic: programs that run within these
  917. partitions execute as though they were running on an 80386 in real mode.
  918. Each partition, called a %@AI@%virtual machine%@AE@%, comes complete with its own
  919. address space, I/0 port space, and interrupt vector table. Multiple virtual
  920. machines can be running simultaneously, with each under the illusion that it
  921. is in complete control of the computer.  %@NL@%
  922.  
  923. A VM initially runs in the %@AI@%Virtual-86 (V86) mode%@AE@% of the processor. In this
  924. mode, the application running in the VM can make use of all the functions
  925. associated with 8086 emulation and additional privileged instructions
  926. provided by the 80386. The application can also use the %@AI@%protected mode%@AE@%
  927. features of the 80386, but should do so via the DPMI (DOS Protected Mode
  928. Interface) specification (available from Intel at 1-800-548-4725).  %@NL@%
  929.  
  930. A virtual machine (VM) is a complete description of the state of an
  931. application. Each VM includes the following:%@CR:C6A00160012 @%%@NL@%
  932.  
  933.  
  934.   ■   The memory associated with the application%@NL@%
  935.  
  936.   ■   The processor registers%@NL@%
  937.  
  938.   ■   The data structures associated with virtualization%@NL@%
  939.  
  940.  
  941. The data is used by the VMM and VxDs to virtualize the hardware and to
  942. provide services. It is maintained in a data structure called the Control
  943. Block. The processor registers are maintained on the VMM stack and can be
  944. accessed via the Client Register Structure. The memory can be accessed and
  945. manipulated by means of a number of VMM memory manager services.%@CR:C6A00160013 @%%@NL@%
  946.  
  947. The code for MS-DOS and the Windows portion common to the three product
  948. modes (real, standard, and 386 enhanced) runs in the System VM. Most of
  949. MS-DOS, including all the MS-DOS device drivers and TSRs, is usually shared
  950. globally among the VMs.  %@NL@%
  951.  
  952.  
  953. %@3@%%@CR:C6A00160014 @%%@AB@%16.2.1  The Privilege Rings of a VM%@AE@%%@EH@%%@NL@%
  954.  
  955. A VM can have more than one privilege ring. Code executing in one privilege
  956. ring can only have access to memory in the same privilege ring or one with a
  957. higher number (i.e., lower privilege level).%@CR:C6A00160015 @%%@NL@%
  958.  
  959. The virtual-8086 (V86) mode portion, shown in Figure 16.2, runs in privilege
  960. ring 3. This is the code and data most typically associated with MS-DOS
  961. applications.%@CR:C6A00160016 @%%@NL@%
  962.  
  963. The second part is a protected-mode (PM) portion that runs at privilege ring
  964. 1, 2, or 3. This portion can be used by applications running under enhanced
  965. Windows. In the System VM (SYS VM), this portion is used to run the Windows
  966. graphical interface.%@CR:C6A00160017 @%%@NL@%
  967.  
  968. The third part is code and data utilized by the VMM and the VxDs running at
  969. privilege ring 0.  %@NL@%
  970.  
  971. The ring 0 data has three subparts, each associated with a particular VM
  972. (per VM):  %@NL@%
  973.  
  974.  
  975.   1.  The stack, which contains the Client Register Structure (CRS). The
  976.       ring 0 stack is used by the VMM and VxDs when a VM is running.%@NL@%
  977.  
  978.   2.  The control block, which contains other data (i.e., values associated
  979.       with the virtualization of hardware for a VM) local to a VM. %@NL@%
  980.  
  981.   3.  Data owned by a VxD, which contains information that maintains the
  982.       state, such as the state of the physical hardware, across all VMs.%@NL@%
  983.  
  984. %@STUB@%      %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  985.  
  986.  
  987.  
  988. %@3@%%@CR:C6A00160018 @%%@AB@%16.2.2  VM Handles%@CR:C6A00160019 @%%@AE@%%@EH@%%@NL@%
  989.  
  990. Enhanced Windows virtual devices refer to specific VMs by VM handles. By
  991. convention, VM handles are usually stored in the %@AB@%EBX%@AE@% register. A VM handle
  992. is actually a 32-bit linear address of the virtual machine's control block
  993. data structure.  %@NL@%
  994.  
  995.  
  996. %@3@%%@CR:C6A00160020 @%%@AB@%16.2.3  The Client Register Structure %@CR:C6A00160021 @%%@AE@%%@EH@%%@NL@%
  997.  
  998. The Client Register Structure (CRS), as shown in Figure 16.3, contains the
  999. virtual machine processor state including all the virtual machine's
  1000. registers and flags. When a device wants to look at or modify a virtual
  1001. machine's registers, it must modify the CRS.  %@NL@%
  1002.  
  1003. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1004.  
  1005.  
  1006. %@2@%%@CR:C6A00160022 @%%@AB@%16.3  The Virtual Machine Manager%@CR:C6A00160023 @%%@AE@%%@EH@%%@NL@%
  1007.  
  1008. The Virtual Machine Manager (VMM) is a device-independent layer of code that
  1009. provides a framework upon which the virtual devices build virtualizations of
  1010. physical devices or provide services for each of the VMs. In this sense, the
  1011. VMM lies between the VMs and the VxDs. All interaction between the software
  1012. running in the VMs and the VxDs occurs via the interface provided by the
  1013. VMM.  %@NL@%
  1014.  
  1015. The VMM also provides a set of services that allows for creating,
  1016. destroying, running, synchronizing, and altering the state of the VMs. The
  1017. VMM, as shown in Figure 16.4, handles all the privilege ring transitions of
  1018. VMs to privilege ring 0, provides scheduling services, manages memory, and
  1019. provides services for such activities as trapping I/O and hooking software
  1020. interrupts.  %@NL@%
  1021.  
  1022. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1023.  
  1024.  
  1025. %@2@%%@CR:C6A00160024 @%%@AB@%16.4  Virtual Devices%@AE@%%@EH@%%@NL@%
  1026.  
  1027. Enhanced Windows virtual devices (VxDs) are the interfaces between
  1028. application software and the hardware. Most VxDs correspond to a hardware
  1029. device, though not all do. For example, the VxDs for printers and displays
  1030. simulate actual hardware interfaces, but the VxD called Shell provides
  1031. access to the Windows graphical user interface. VxDs use services provided
  1032. by the VMM and other VxDs.%@CR:C6A00160025 @%%@CR:C6A00160026 @%%@NL@%
  1033.  
  1034. VxDs can provide control functions, service functions, API functions, and
  1035. callback procedures that are used to virtualize, synchronize, and maintain
  1036. the state of the hardware for the VMs. A callback procedure is a request for
  1037. notification when a specified event occurs in the normal execution of the
  1038. application code.  %@NL@%
  1039.  
  1040. There must be a VxD for each piece of hardware that can have a different
  1041. state in each of the VMs.  %@NL@%
  1042.  
  1043.  
  1044. %@3@%%@CR:C6A00160027 @%%@AB@%16.4.1  VxD Components%@AE@%%@EH@%%@NL@%
  1045.  
  1046. Installable virtual devices have the following five, distinct parts, which
  1047. are shown graphically in Figure 16.5:  %@NL@%
  1048.  
  1049.  
  1050.   1.  Real-mode initialization code and data, which is discarded after
  1051.       loading parts 2 - 5 %@NL@%
  1052.  
  1053.   2.  Protected-mode (PM) initialization code, which is discarded after
  1054.       initialization %@NL@%
  1055.  
  1056.   3.  Protected-mode (PM) initialization data, which is discarded after
  1057.       initialization %@NL@%
  1058.  
  1059.   4.  PM code, which contains the Device Control Procedure, API and callback
  1060.       procedures, and services%@NL@%
  1061.  
  1062.   5.  PM data, which contains the Device Descriptor Block, Service Table,
  1063.       and Global Data%@NL@%
  1064.  
  1065.  
  1066.  
  1067. %@3@%%@CR:C6A00160028 @%%@AB@%16.4.2  The Device Control Procedure%@AE@%%@EH@%%@NL@%
  1068.  
  1069. The Device Control Procedure (DCP) is the dispatch point for most of the VMM
  1070. interaction with the VxD. Besides the initialization of the system, there
  1071. are device control calls for creating, initializing, and destroying VMs; for
  1072. setting the device focus to a VM; and for indicating a change in the state
  1073. of the VM.%@CR:C6A00160029 @%%@CR:C6A00160030 @%%@CR:C6A00160031 @%%@NL@%
  1074.  
  1075. The VMM broadcasts messages to all VxD DCPs indicating changes in the state
  1076. of the system or of a VM. The DCP can then modify the device's data
  1077. structure or the VM's state. The address of the DCP is specified in a
  1078. special data structure called a Device Descriptor Block that all virtual
  1079. devices must have. See Chapter 17, "Virtual Device Programming Topics," for
  1080. details on messages passed to the DCP.  %@NL@%
  1081.  
  1082.  
  1083. %@3@%%@CR:C6A00160032 @%%@AB@%16.4.3  The Device Descriptor Block%@AE@%%@EH@%%@NL@%
  1084.  
  1085. The Device Descriptor Block (DDB) is a VxD-unique data structure containing
  1086. the VxD's name, version IDs, and entry points for the three code areas: the
  1087. Device Control Procedure, V86-mode API procedure, and the PM API procedure.
  1088. In addition, the DDB can contain a pointer to a table of services provided
  1089. by the VxD. See Chapter 17, "Virtual Device Programming Topics, " for a
  1090. detailed description of a DDB.%@CR:C6A00160033 @%%@CR:C6A00160034 @%%@CR:C6A00160035 @%%@CR:C6A00160036 @%%@NL@%
  1091.  
  1092. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1093.  
  1094.  
  1095. %@3@%%@CR:C6A00160037 @%%@AB@%16.4.4  VxD IDs%@AE@%%@EH@%%@NL@%
  1096.  
  1097. VxD IDs uniquely identify a VxD. They are a 16-bit combination of the OEM
  1098. number and the device number in the form:  %@NL@%
  1099.  
  1100. %@AS@%  xOOOOOOOOOODDDDD%@AE@%
  1101.  
  1102. The high bit of the VxD ID is reserved for future use. The next 10 bits are
  1103. the OEM number, which should be requested from Microsoft. The last 5 bits
  1104. are the VxD number. This enables each OEM to create 32 unique VxDs. If an
  1105. OEM is creating a replacement for a standard VxD, then it should re-use the
  1106. standard ID. VxDs that do not provide services or APIs or that do INT 2FH
  1107. callouts should use the equate Undefined_Device_ID. See VMM.INC for other
  1108. examples of device IDs. Microsoft has reserved the first 16 OEM numbers (0
  1109. through 0FH).  %@NL@%
  1110.  
  1111.  
  1112. %@3@%%@CR:C6A00160038 @%%@AB@%16.4.5  VxD Initialization Order%@AE@%%@EH@%%@NL@%
  1113.  
  1114. VxDs are initialized in order from the %@AI@%lowest%@AE@% to the %@AI@%highest%@AE@% initialization
  1115. order value. If two or more VxDs have the same initialization order value,
  1116. then they are initialized in their order of occurence. Therefore, a specific
  1117. order is not guaranteed. You should use the initialization order equates in
  1118. VMM.INC to specify the initialization order for your VxD. If you want your
  1119. VxD to be initialized slightly before or after a defined initialization
  1120. order, use the equate plus an increment or minus a decrement.%@CR:C6A00160039 @%%@CR:C6A00160040 @%%@NL@%
  1121.  
  1122. Most likely your VxD will not have any initialization ordering dependencies.
  1123. In this case use the Undefined_Init_Order equate.  %@NL@%
  1124.  
  1125.  
  1126. %@2@%%@CR:C6A00160041 @%%@AB@%16.5  How VxDs Work%@AE@%%@EH@%%@NL@%
  1127.  
  1128. The following sections contain general explanations of how VxDs work and
  1129. provide information on the following topics:  %@NL@%
  1130.  
  1131.  
  1132.   ■   Scheduling%@NL@%
  1133.  
  1134.   ■   Memory use%@NL@%
  1135.  
  1136.   ■   Services%@NL@%
  1137.  
  1138.   ■   Callback procedures%@NL@%
  1139.  
  1140.   ■   I/O port hooks%@NL@%
  1141.  
  1142.   ■   Interrupt hooks%@NL@%
  1143.  
  1144.   ■   Loading %@NL@%
  1145.  
  1146.  
  1147. The following related topics are covered in Appendix D, "Windows INT 2FH
  1148. API:"%@CR:C6A00160042 @%%@NL@%
  1149.  
  1150.  
  1151.   ■   Getting the address of a VxD API procedure%@NL@%
  1152.  
  1153.   ■   How a VxD calls out to a TSR or an MS-DOS device driver%@NL@%
  1154.  
  1155.   ■   How a TSR or MS-DOS device driver specifies a VxD to load when
  1156.       starting enhanced Windows
  1157. %@NL@%
  1158.  
  1159.  
  1160.  
  1161. %@3@%%@CR:C6A00160043 @%%@AB@%16.5.1  Enhanced Windows Execution Scheduling %@CR:C6A00160044 @%%@AE@%%@EH@%%@NL@%
  1162.  
  1163. The following is a brief description of how events are scheduled and
  1164. processed. The concepts are also described graphically in Figure 16.6.  %@NL@%
  1165.  
  1166.  
  1167. %@4@%%@AB@%Events%@CR:C6A00160045 @%%@AE@%%@EH@%%@NL@%
  1168.  
  1169. The enhanced Windows VMM is a single-threaded, non-reentrant operating
  1170. system. Because it is non-reentrant, virtual devices that hook interrupts
  1171. must have some method of synchronizing their calls to the VMM. For this
  1172. reason, enhanced Windows uses the concept of event processing.%@CR:C6A00160046 @%%@NL@%
  1173.  
  1174. Event procedures are registered asynchronously and, then, called back just
  1175. before the VMM returns to the application. At this point, the event
  1176. procedure can use all the VMM services.  %@NL@%
  1177.  
  1178. VxDs can also use event procedures to perform some action on a VM that is
  1179. not the current VM. Examples of this include restoring the display to a VM
  1180. when the display focus changes or simulating an interrupt into a VM the next
  1181. time the VM is scheduled.  %@NL@%
  1182.  
  1183. There are two types of events: global and VM specific. Global events are
  1184. processed before returning to a virtual machine regardless of which VM is
  1185. about to run. VM-specific events are only processed when the specified
  1186. virtual machine is about to run.  %@NL@%
  1187.  
  1188.  
  1189. %@4@%%@AB@%Scheduler%@AE@%%@EH@%%@NL@%
  1190.  
  1191. When Windows is running in 386 enhanced mode, each application runs in it
  1192. own VM. Each VM can be given a share of the CPU time. To assign priority
  1193. among the VMs, the VMM has a Scheduler.%@CR:C6A00160047 @%%@NL@%
  1194.  
  1195. The Scheduler is the part of the VMM that determines which VM gets CPU time.
  1196. It is divided into two parts. At the lowest level, the Primary Scheduler
  1197. maintains execution priorities, and the VM with the highest priority is
  1198. allowed to run. VxDs will raise and lower the execution priorities to affect
  1199. task switching among the VMs. The second level of scheduling is handled by
  1200. the Time Slicer, which boosts a VM's execution priority for a given time
  1201. slice.%@CR:C6A00160048 @%%@CR:C6A00160049 @%%@NL@%
  1202.  
  1203. With the Primary Scheduler, there are specific values assigned to execution
  1204. priorities to accomplish task switching, without violating the need for some
  1205. sections of code to execute exclusively until completion. Additionally,
  1206. high-priority device events, such as interrupts that must be serviced in a
  1207. timely manner, will boost execution priorities of VMs that need to be
  1208. serviced. The VMM provides services and defines execution priorities to
  1209. handle these cases.%@CR:C6A00160050 @%%@NL@%
  1210.  
  1211. The enhanced Windows Time Slicer is the preemptive multitasking portion of
  1212. the Scheduler. It relies on time-slice priorities and flags to determine how
  1213. much CPU time should be allocated to various virtual machines.  %@NL@%
  1214.  
  1215. Every VM has a foreground and a background time-slice priority. These should
  1216. be distinguished from a VM's %@AI@%execution%@AE@% priority. The VM with the largest
  1217. execution priority will run, preventing other VMs from executing. The VM
  1218. with the largest time-slice priority will run more often than other VMs but
  1219. it will not necessarily prevent other VMs from executing.  %@NL@%
  1220.  
  1221.  
  1222. %@4@%%@AB@%Transitions Into and Out of the VMM and VxDs%@AE@%%@EH@%%@NL@%
  1223.  
  1224. The enhanced Windows VMM uses the protection mechanism of the 80386 to force
  1225. privilege ring transitions, as shown in Figure 16.6, whenever an application
  1226. program issues a software interrupt or causes a protection fault. One
  1227. example is when a VM performs I/O to a hooked port. The exact mechanisms
  1228. used to make the transition into the VMM are not important to a virtual
  1229. device developer. It is almost never necessary to directly intercept a
  1230. processor fault or hardware interrupt. The only device that handles hardware
  1231. interrupts directly is the Virtual PIC (Programmable Interrupt Controller)
  1232. Device. Callback procedures have been provided to signal a calling routine
  1233. when a specific event occurs. (See Section 16.5.4, "Callback Procedures,"
  1234. for more information.)  %@NL@%
  1235.  
  1236. Programmers familiar with the 80386 architecture may assume that, to hook an
  1237. interrupt, a virtual device will hook the protected-mode Interrupt
  1238. Descriptor Table (IDT) directly. However, this is not true for Windows in
  1239. 386 enhanced mode. Services to hook interrupts at this level are provided by
  1240. the VMM.%@CR:C6A00160051 @%%@CR:C6A00160052 @%%@CR:C6A00160053 @%%@NL@%
  1241.  
  1242. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1243. %@AU@%WARNING%@AE@%
  1244.  
  1245. VxDs must never modify the actual IDT. To do so will cause enhanced Windows
  1246. to crash.
  1247. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1248.  
  1249. The sequence of events for entering the VMM from a virtual machine because
  1250. of an interrupt is as follows:  %@NL@%
  1251.  
  1252.  
  1253.   1.  The VM performs an operation that generates a fault.%@NL@%
  1254.  
  1255.   2.  A ring transition occurs, and the appropriate IDT interrupt handler is
  1256.       called. %@NL@%
  1257.  
  1258.   3.  The VMM dispatches the interrupt to the appropriate handler by a CALL.
  1259.       %@NL@%
  1260.  
  1261.   4.  The protected-mode handler processes the fault and executes a near
  1262.       RET. %@NL@%
  1263.  
  1264.   5.  The VMM processes any outstanding events. %@NL@%
  1265.  
  1266.   6.  An IRET is executed that causes a ring transition back to the VM.%@NL@%
  1267.  
  1268.  
  1269. Notice that the VMM looks at the interrupt before any virtual devices and
  1270. immediately before returning to the virtual machine.  %@NL@%
  1271.  
  1272. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1273.  
  1274.  
  1275. %@3@%%@CR:C6A00160054 @%%@AB@%16.5.2  Memory Models%@AE@%%@EH@%%@NL@%
  1276.  
  1277. Windows in 386 enhanced mode makes use of the 80386's ability to run within
  1278. different memory models. Some devices may have initialization code that is
  1279. run in real mode. See Section 16.5.7, "Loading Sequence," for the loading
  1280. sequence description. After that code is run successfully, a transition is
  1281. made to protected mode (using selector:offset addressing) in which the VMM
  1282. is installed and begins executing. The VMM creates a separate VM that
  1283. consists of a V86-mode portion and an optional, protected-mode (PM) portion
  1284. for each application.  %@NL@%
  1285.  
  1286. The VMM and all the enhanced Windows VxDs run in a 32-bit, flat-model
  1287. protected mode segment. This means that every VxD has complete access to 4
  1288. gigabytes of linear address space. A VxD can access any VM's memory at any
  1289. time.  %@NL@%
  1290.  
  1291. Because enhanced Windows is flat model, virtual devices cannot change the
  1292. %@AB@%CS%@AE@%, %@AB@%DS%@AE@%, %@AB@%ES%@AE@%, or %@AB@%SS%@AE@% segment registers. These segment registers always contain
  1293. a selector that has a base of 0 and a limit of 4 gigabytes. Devices can use
  1294. the %@AB@%FS%@AE@% and %@AB@%GS%@AE@% segment registers, but there usually is no reason to do so.
  1295. VMM services will not modify the %@AB@%FS%@AE@% or %@AB@%GS%@AE@% segment registers. Pointers are
  1296. always 32-bit linear addresses unless otherwise specified.  %@NL@%
  1297.  
  1298. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1299. NOTE
  1300.  
  1301. %@AI@%Since the VMM (privilege ring 0 code) resides in a single, flat memory
  1302. %@AI@%segment, the selector of the selector:offset PM addressing for the VMM and
  1303. %@AI@%VxDs never changes.%@AE@%
  1304.  
  1305. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1306.  
  1307.  
  1308. %@4@%%@AB@%Modes%@AE@%%@EH@%%@NL@%
  1309.  
  1310. Application programs typically run in a V86-mode portion of the enhanced
  1311. Windows operating environment.%@CR:C6A00160055 @%%@CR:C6A00160056 @%%@NL@%
  1312.  
  1313. As described in Appendix B, "Understanding Modes," V86 mode is similar to
  1314. real mode. The crucial difference between the two is that memory protection,
  1315. virtual memory, and privilege-checking mechanisms are in effect when code
  1316. runs in V86 mode. Therefore, a program executing in V86 mode cannot
  1317. interfere with the operating environment or damage other processes. If the
  1318. program reads or writes memory addresses that have not been mapped into its
  1319. VM or manipulates I/O ports to which it has not been allowed access, an
  1320. exception (fault) is generated, and the operating environment regains
  1321. control.  %@NL@%
  1322.  
  1323. An application may also run in protected mode (also described in Appendix
  1324. B). An example of this is the the Windows graphical interface.  %@NL@%
  1325.  
  1326. However, non-Windows applications %@AI@%must use%@AE@% DPMI when using protected-mode
  1327. features. The DPMI (DOS Protected Mode Interface) specification is available
  1328. from Intel at 1-800-548-4725. By using DPMI, applications gain access to
  1329. extended memory, the ability to run in a 16-bit or a 32-bit memory model,
  1330. and other features of the 80386 protected mode.  %@NL@%
  1331.  
  1332.  
  1333. %@4@%%@AB@%Privilege Rings%@AE@%%@EH@%%@NL@%
  1334.  
  1335. By running in ring 0, the VMM and all the VxDs have the most privileges.
  1336. Protected-mode applications, such as Windows itself, run in rings 1, 2, or 3
  1337. and have lower privileges. Least privileged are MS-DOS and the applications
  1338. running in V86 mode, which run only in ring 3.  %@NL@%
  1339.  
  1340. Figure 16.7 shows each of these components within there respective rings.
  1341. Also shown are the Control Block and the Client Register Structure.%@CR:C6A00160057 @%%@NL@%
  1342.  
  1343. Since all virtual devices run at ring 0, they have the ability to execute
  1344. any 80386 instruction without producing a protection violation. However,
  1345. devices should not execute protected instructions as they will usually cause
  1346. Windows to crash immediately. The only exception to this is the Virtual Math
  1347. Coprocessor Device, which is allowed to change the 80387 bits in the %@AB@%CR0%@AE@%
  1348. register.%@CR:C6A00160058 @%%@CR:C6A00160059 @%%@CR:C6A00160060 @%%@NL@%
  1349.  
  1350. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1351.  
  1352.  
  1353. %@3@%%@CR:C6A00160061 @%%@AB@%16.5.3  Services%@AE@%%@EH@%%@NL@%
  1354.  
  1355. Services are the shared routines of the VMM and VxDs. VxDs use services to
  1356. handle interrupts, to initiate callback procedures, and to process
  1357. exceptions/faults.%@CR:C6A00160062 @%%@NL@%
  1358.  
  1359. Notice that there are some VxD services that the VMM requires. Most notable
  1360. of these are the services provided by the Virtual Programmable Interrupt
  1361. Controller Device (VPICD), which virtualizes the PIC for the VxDs (for
  1362. requesting interrupts) and the VMs.  %@NL@%
  1363.  
  1364. Detailed descriptions of each service are provided in Part 4, "Virtual
  1365. Device Services." The services are also categorized there as follows:  %@NL@%
  1366.  
  1367.  
  1368.   ■   Memory Management services%@NL@%
  1369.  
  1370.   ■   I/O services and macros%@NL@%
  1371.  
  1372.   ■   VM Interrupt and Call services%@NL@%
  1373.  
  1374.   ■   Nested Execution services%@NL@%
  1375.  
  1376.   ■   Break Point and Callback services%@NL@%
  1377.  
  1378.   ■   Primary Scheduler services%@NL@%
  1379.  
  1380.   ■   Time-Slice Scheduler services%@NL@%
  1381.  
  1382.   ■   Event services%@NL@%
  1383.  
  1384.   ■   Timing services%@NL@%
  1385.  
  1386.   ■   Processor Fault and Interrupt services%@NL@%
  1387.  
  1388.   ■   Information services%@NL@%
  1389.  
  1390.   ■   Initialization Information services%@NL@%
  1391.  
  1392.   ■   Linked List services%@NL@%
  1393.  
  1394.   ■   Error Condition services%@NL@%
  1395.  
  1396.   ■   Miscellaneous services%@NL@%
  1397.  
  1398.   ■   Shell services%@NL@%
  1399.  
  1400.   ■   Virtual Display Device (VDD) services%@NL@%
  1401.  
  1402.   ■   Virtual Keyboard Device (VKD) services%@NL@%
  1403.  
  1404.   ■   Virtual PIC Device (VPICD) services%@NL@%
  1405.  
  1406.   ■   Virtual Sound Device (VSD) services%@NL@%
  1407.  
  1408.   ■   Virtual Timer Device (VTD) services%@NL@%
  1409.  
  1410.   ■   V86 Mode Memory Manager Device services%@NL@%
  1411.  
  1412.   ■   Virtual DMA Device (VDMAD) services%@NL@%
  1413.  
  1414.   ■   Virtual DOSNET Device services%@NL@%
  1415.  
  1416.  
  1417.  
  1418. %@3@%%@CR:C6A00160063 @%%@AB@%16.5.4  Callback Procedures%@AE@%%@EH@%%@NL@%
  1419.  
  1420. Some services enable a calling routine to register a procedure that will be
  1421. called back when a particular event occurs. Callback procedures are used for
  1422. maintaining the VM state via I/O and interrupt trapping, and for
  1423. synchronizing with the VMM via the event services.  %@NL@%
  1424.  
  1425. The VMM includes services that enable virtual devices to install callback
  1426. procedures to do the following:%@CR:C6A00160064 @%%@NL@%
  1427.  
  1428.  
  1429.   ■   Trap interrupts from virtual machines %@NL@%
  1430.  
  1431.   ■   Trap I/O to specific ports %@NL@%
  1432.  
  1433.   ■   Trap access to memory %@NL@%
  1434.  
  1435.   ■   Schedule per-VM or global time-outs %@NL@%
  1436.  
  1437.   ■   Schedule per-VM or global events %@NL@%
  1438.  
  1439.   ■   Detect when a VM returns from an interrupt or FAR call %@NL@%
  1440.  
  1441.   ■   Detect when a VM executes a particular piece of V86 code %@NL@%
  1442.  
  1443.   ■   Detect the release of the critical section %@NL@%
  1444.  
  1445.   ■   Detect changes to the VM's interrupt enable flag %@NL@%
  1446.  
  1447.   ■   Detect task switches%@NL@%
  1448.  
  1449.  
  1450.  
  1451. %@3@%%@CR:C6A00160065 @%%@AB@%16.5.5  I/O Port Hooks%@AE@%%@EH@%%@NL@%
  1452.  
  1453. The VMM provides a service called %@AB@%Install_IO_Handler%@AE@%. The service takes two
  1454. parameters: the port to be hooked, and the address of the procedure to be
  1455. called whenever the port is accessed.%@CR:C6A00160066 @%%@NL@%
  1456.  
  1457. When a VxD calls %@AB@%Install_IO_Handler%@AE@%, the VMM sets the appropriate bit in the
  1458. I/O permission map (IOPM) and registers the procedure. When a virtual
  1459. machine executes an instruction that reads or writes data from an I/O port,
  1460. the 80386 looks up the port number in the I/O permission map. If the
  1461. corresponding bit in the IOPM is set, then the instruction will cause a
  1462. protection fault that results in calling the registered procedure. %@AB@%  %@AE@%%@NL@%
  1463.  
  1464.  
  1465. %@3@%%@CR:C6A00160067 @%%@AB@%16.5.6  Interrupt Hooks%@AE@%%@EH@%%@NL@%
  1466.  
  1467. The Virtual Programmable Interrupt Controller Device (VPICD) routes hardware
  1468. interrupts to other virtual devices, provides services that enable virtual
  1469. devices to request interrupts, and simulates hardware interrupts into
  1470. virtual machines.%@CR:C6A00160068 @%%@NL@%
  1471.  
  1472. When a virtual device needs to hook a specific IRQ, it must ask VPICD for
  1473. permission. If another device has already virtualized the IRQ, then VPICD
  1474. will refuse. Chapter 37, "Virtual PIC Device (VPICD) Services," details the
  1475. workings of the VPICD.  %@NL@%
  1476.  
  1477. For services used in hooking software interrupts and supporting software
  1478. interrupt hooks, see Chapter 21, "VM Interrupt and Call Services."%@CR:C6A00160069 @%%@CR:C6A00160070 @%%@CR:C6A00160071 @%%@CR:C6A00160072 @%%@NL@%
  1479.  
  1480.  
  1481. %@3@%%@CR:C6A00160073 @%%@AB@%16.5.7  Loading Sequence%@AE@%%@EH@%%@NL@%
  1482.  
  1483. The following is a generalized description of the loading sequence. Figures
  1484. 16.8 and 16.9 are an example of a specific loading sequence.%@CR:C6A00160074 @%%@NL@%
  1485.  
  1486. When Windows in 386 enhanced mode is first started, the following happens:  %@NL@%
  1487.  
  1488.  
  1489.   1.  The loader allocates extended memory via the XMS driver, loads the VMM
  1490.       and all the specified virtual devices into extended memory.%@NL@%
  1491.  
  1492.   2.  The system switches to protected mode.%@NL@%
  1493.  
  1494.   3.  The loader passes control to the VMM initialization routine.%@NL@%
  1495.  
  1496.   4.  The initialization routine completes the initialization of the VMM and
  1497.       calls all the VxD initialization routines.%@NL@%
  1498.  
  1499.   5.  The System VM is created and initialized.%@NL@%
  1500.  
  1501.   6.  The Shell VxD executes WINSTART.BAT and, then, Windows.%@NL@%
  1502.  
  1503.  
  1504. Each VxD can have different sections of code that are executed during
  1505. various phases of initialization and normal program execution, as shown in
  1506. Figure 16.8.  %@NL@%
  1507.  
  1508. The first phase of initialization is load time. During load time, the
  1509. virtual device can abort the loading of the device, abort the loading of
  1510. enhanced Windows, specify instance data, and exclude pages of memory from
  1511. utilization by enhanced Windows. This load time code is in its own segment
  1512. and is run in real mode and, then, discarded. See Chapter 17, "Virtual
  1513. Device Programming Topics," for details on real-mode initialization.  %@NL@%
  1514.  
  1515. The rest of the virtual device is run in 32-bit, flat-model protected mode
  1516. and is divided into the following four parts:  %@NL@%
  1517.  
  1518.  
  1519.   ■   Initialization code%@NL@%
  1520.  
  1521.   ■   Initialization data%@NL@%
  1522.  
  1523.   ■   Code%@NL@%
  1524.  
  1525.   ■   Data%@NL@%
  1526.  
  1527.  
  1528. The initialization code and data are purged from memory after
  1529. initialization, as shown in Figure 16.9. These segments contain services and
  1530. data that are accessed only during the three phases of enhanced Windows
  1531. system initialization: %@AB@%Sys_Critical_Init%@AE@%, %@AB@%Device_Init%@AE@%, and %@AB@%Init_Complete%@AE@%.
  1532. Some of the enhanced Windows VMM services are available only during
  1533. initialization.  %@NL@%
  1534.  
  1535. The sections of code and data that are not specifically for initialization
  1536. perform the device virtualization and can provide services for other
  1537. devices.  %@NL@%
  1538.  
  1539. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1540.  
  1541. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1542.  
  1543.  
  1544. %@2@%%@CR:C6A00160075 @%%@AB@%16.6  VxD Examples%@AE@%%@EH@%%@NL@%
  1545.  
  1546. Often, new VxDs are actually modifications of existing ones. To help with
  1547. your VxD development, Microsoft includes with the DDK the source code for
  1548. fully operational VxDs. We encourage you to use them as examples whenever
  1549. convenient. See the DDK %@AI@% Installation and Update Guide%@AE@% for more detailed
  1550. descriptions and a complete list of the source samples provided for this
  1551. version of Windows.  %@NL@%
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558. %@CR:C6A00170001 @%%@1@%%@AB@%Chapter 17  Virtual Device Programming Topics%@AE@%%@EH@%%@NL@%
  1559. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1560.  
  1561. This chapter presents details on writing and installing VxDs. You should be
  1562. familiar with Chapter 16, "Overview of Windows in 386 Enhanced Mode," before
  1563. proceeding with this material. For explanations on specific types of
  1564. services provided by the Virtual Machine Manager (VMM), see the appropriate
  1565. chapters in Part 4, "Virtual Device Services." This chapter is divided into
  1566. the following general topics:  %@NL@%
  1567.  
  1568.  
  1569.   ■   Writing VxDs%@NL@%
  1570.  
  1571.   ■   Building a VxD%@NL@%
  1572.  
  1573.   ■   Initializing a VxD%@NL@%
  1574.  
  1575.   ■   Tracking the VM states%@NL@%
  1576.  
  1577.   ■   Exiting Windows%@NL@%
  1578.  
  1579.  
  1580. We recommend that you scan all the topics before beginning a VxD project.
  1581. You should also review the sample VxDs supplied on the %@AI@%Microsoft Windows
  1582. %@AI@%Device Development Kit%@AE@% (DDK) disks for examples of how to accomplish
  1583. specific tasks. The following table suggests some VxDs to study when
  1584. investigating specific service topics.  %@NL@%
  1585.  
  1586. %@TH:   8   396 02 34 42 @%
  1587. Service topic                     Sample VxD
  1588. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1589. Memory management                 VDD
  1590. Hardware interrupts               VKD
  1591. I/O                               VPD
  1592. Scheduler                         VKD
  1593. Events                            VKD
  1594. Timeouts                          VKD
  1595. %@TE:   8   396 02 34 42 @%
  1596.  
  1597.  
  1598. %@2@%%@CR:C6A00170002 @%%@AB@%17.1  Writing VxDs%@AE@%%@EH@%%@NL@%
  1599.  
  1600. Enhanced Windows virtual devices are not "Windows" programs. You do not need
  1601. to know anything about Windows programming to write a VxD.%@CR:C6A00170003 @%%@NL@%
  1602.  
  1603. Often, new VxDs are simply modifications of existing ones. To help with your
  1604. VxD development, Microsoft includes the code for many, fully operational
  1605. VxDs in the %@AI@%Microsoft Windows Device Development Kit%@AE@%. We encourage you to
  1606. use them as examples whenever convenient.  %@NL@%
  1607.  
  1608. However, some VxDs will require a significant effort to develop. The
  1609. following can be used as a guideline when writing a complex VxD.  %@NL@%
  1610.  
  1611.  
  1612.   1.  Build a skeleton. Using the supplied sources as a guide, build a
  1613.       skeleton of the VxD with the device control procedure, the services,
  1614.       and the API procedures defined but not functional. %@NL@%
  1615.  
  1616.   2.  Add the initialization functionality, including the control block and
  1617.       global memory allocation, physical page hooking, I/O hooking, and
  1618.       interrupt hooking.%@NL@%
  1619.  
  1620.   3.  Fill out the procedures that handle the various hooks.%@NL@%
  1621.  
  1622.   4.  Test the procedures.%@NL@%
  1623.  
  1624.   5.  Implement the APIs and services, if there are any.%@NL@%
  1625.  
  1626.   6.  Test the APIs and services.
  1627. %@NL@%
  1628.  
  1629.  
  1630.  
  1631. %@3@%%@CR:C6A00170004 @%%@AB@%17.1.1  VxD Memory Model%@AE@%%@EH@%%@NL@%
  1632.  
  1633. The part of the enhanced Windows environment containing the VMM and all the
  1634. VxDs (ring 0), is one, flat-model, 32-bit segment. This means that all the
  1635. code and data belong to the same group. Two selectors are created: one for
  1636. code and one for data. Both have a base of zero and a limit of four
  1637. gigabytes, so all the segment registers point to the same address space (the
  1638. entire virtual address space provided by the 80386 processor).%@CR:C6A00170005 @%%@NL@%
  1639.  
  1640. When a VxD is loaded, all the offsets are fixed according to the the VxD's
  1641. actual position. This is different from MS-DOS's loading of .EXE files, in
  1642. which segments are fixed up and offsets are left untouched.  %@NL@%
  1643.  
  1644. All procedures are NEAR, and data pointers are 32-bit offsets.  %@NL@%
  1645.  
  1646. VxDs do not export routines or data. To access VMM or VxD services, a
  1647. dynamic-link mechanism is employed using macros contained in VMM.INC. The
  1648. VMM services are available with the %@AB@%VMMcall%@AE@% macro, and the VxD services with
  1649. the %@AB@%VxDcall%@AE@% macro. Data is shared via declared services only.  %@NL@%
  1650.  
  1651. You must use the %@AB@%OFFSET32%@AE@% macro in your flat-model, 32-bit segments anywhere
  1652. you would normally use the %@AB@%OFFSET%@AE@% assembler directive. That is, in all
  1653. segments except for the real-mode initialization segment. This macro
  1654. correctly defines all the offsets so that LINK386 will produce the correct
  1655. offset fixup information. For example:  %@NL@%
  1656.  
  1657. %@AS@%  mov   esi, OFFSET32 My_Data%@AE@%
  1658.  
  1659.  
  1660. %@3@%%@CR:C6A00170006 @%%@AB@%17.1.2  VxD Segmentation%@AE@%%@EH@%%@NL@%
  1661.  
  1662. As discussed in Chapter 16, "Overview of Windows in 386 Enhanced Mode," VxDs
  1663. have five functional parts. Each of these parts exists as a separate
  1664. segment. Macros have been created to define segments for each of the parts.%@CR:C6A00170007 @%%@NL@%
  1665.  
  1666. Each macro name consists of a segment name followed by "_SEG," which means
  1667. that this macro begins the segment. A segment descriptor terminated by
  1668. "_ENDS" is used for macros that end the segment. For example, macros used
  1669. for defining a segment for real-mode load-time initialization would appear
  1670. as %@AB@%VxD_REAL_INIT_SEG%@AE@% and %@AB@%VxD_REAL_INIT_ENDS%@AE@%.  %@NL@%
  1671.  
  1672. In some enhanced Windows installations, it is possible to demand page
  1673. portions of VxDs. These installations require a dedicated swap device or a
  1674. fully virtualized hard disk with a dedicated swap partition. This way,
  1675. paging can be done without concern for reentering portions of MS-DOS, device
  1676. drivers, or BIOS. To support paging, a VxD must place the following in
  1677. locked memory:  %@NL@%
  1678.  
  1679.  
  1680.   ■   Device Control Procedure (DCP)%@NL@%
  1681.  
  1682.   ■   Device Descriptor Block (DDB)%@NL@%
  1683.  
  1684.   ■   Hardware interrupt procedures (and the data accessed by them)%@NL@%
  1685.  
  1686.   ■   Asynchronous (Async) services that can be called from hardware
  1687.       interrupt procedures%@NL@%
  1688.  
  1689.  
  1690. Some of the macros supplied in VMM.INC (e.g., %@AB@%Declare_Virtual_Device%@AE@%)
  1691. correctly place code and data objects in locked segments. The following are
  1692. the different segment descriptor types:  %@NL@%
  1693.  
  1694. %@AS@%  VxD_REAL_INIT  - Real-mode load-time initialization
  1695. %@AS@%  VxD_ICODE  - Protected mode initialization code
  1696. %@AS@%  VxD_IDATA  - Protected mode initialization data
  1697. %@AS@%  VxD_LOCKED_CODE  - Code that cannot be paged
  1698. %@AS@%  VxD_LOCKED_DATA  - Data that cannot be paged
  1699. %@AS@%  VxD_CODE   - Pageable code
  1700. %@AS@%  VxD_DATA   - Pageable data%@AE@%
  1701.  
  1702.  
  1703. %@3@%%@CR:C6A00170008 @%%@AB@%17.1.3  VxD Declaration%@AE@%%@EH@%%@NL@%
  1704.  
  1705. A VxD's first few lines of code must always be the assembler directive
  1706. (".386p"), the INCLUDE files, and the Device Descriptor Block declaration.%@CR:C6A00170009 @%%@NL@%
  1707.  
  1708.  
  1709. %@4@%%@AB@%Assembler Directive%@AE@%%@EH@%%@NL@%
  1710.  
  1711. Every VxD must inform the assembler that the code is 80386 protected-mode
  1712. code. This is done by including the following directive:  %@NL@%
  1713.  
  1714. %@AS@%  .386p%@AE@%
  1715.  
  1716.  
  1717. %@4@%%@AB@%INCLUDE Files%@AE@%%@EH@%%@NL@%
  1718.  
  1719. INCLUDE files enable VxDs to use code located in other parts of enhanced
  1720. Windows. The following INCLUDE files may be included:  %@NL@%
  1721.  
  1722. %@TH:  38  2531 02 34 44 @%
  1723. Filename                          Description
  1724. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1725. VMM.INC                           (Required) Contains definitions of all the
  1726.                                   enhanced Window services, as well as 
  1727.                                   required macros and equates. 
  1728.  
  1729. DEBUG.INC                         (Optional) Contains useful macros for 
  1730.                                   dumping messages to a 
  1731.                                   debugging terminal and performing checks 
  1732.                                   on various data. The macros provided by 
  1733.                                   this file produce code only when the VxD 
  1734.                                   is assembled with the DEBUG switch. See 
  1735.                                   the %@AI@%Microsoft Windows Software Development%@AE@%
  1736.                                   %@AI@%Kit%@AE@% (SDK) for information on the Windows 
  1737.                                   debugging services.
  1738.  
  1739. VPICD.INC                         (Optional) Contains equates and service 
  1740.                                   declarations for the 
  1741.                                   Virtual Programmable Interrupt Controller 
  1742.                                   Device (VPICD). All enhanced Windows 
  1743.                                   interrupts are handled by the VPICD. Most 
  1744.                                   VxDs will require VPICD services. For 
  1745.                                   example, the VPD uses the services to hook
  1746.                                   all the printer port's hardware interrupts.
  1747.  
  1748. SHELL.INC                         (Optional) Contains definitions of the 
  1749.                                   public services provided by the Shell VxD.
  1750.                                   The Shell device provides the VxDs with 
  1751.                                   access to the Windows graphical user 
  1752.                                   interface, thus giving the VxDs the 
  1753.                                   ability to display dialog boxes to the 
  1754.                                   user. For example, if two VMs attempted 
  1755.                                   simultaneously to use the same peripheral 
  1756.                                   device, the VxD could call %@AB@%%@AE@%
  1757.                                   %@AB@%Resolve_Contention%@AE@%, which would display a 
  1758.                                   dialog box asking the user to choose 
  1759.                                   between the two VM applications.
  1760.  
  1761. %@TE:  38  2531 02 34 44 @%
  1762.  
  1763.  
  1764. %@4@%%@AB@%Device Descriptor Block%@AE@%%@EH@%%@NL@%
  1765.  
  1766. The declaration of the VxD is accomplished by its Device Descriptor Block
  1767. (DDB). The DDB is generated automatically by the %@AB@%Declare_Virtual_Device%@AE@%
  1768. macro. The following example is from the VPD sample provided with the DDK.  %@NL@%
  1769.  
  1770. %@AS@%  DECLARE_VIRTUAL_DEVICE VPD,3,0,VPD_Control, VPD_Device_ID,
  1771. %@AS@%VPD_Init_Order,, VPD_PM_API_Handler,, %@AE@%
  1772.  
  1773. The table in Figure 17.1 describes each of the parameters:%@CR:C6A00170010 @%%@CR:C6A00170011 @%%@CR:C6A00170012 @%%@CR:C6A00170013 @%%@CR:C6A00170014 @%%@CR:C6A00170015 @%%@NL@%
  1774.  
  1775. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1776.  
  1777.  
  1778. %@4@%%@AB@%VxD IDs%@AE@%%@EH@%%@NL@%
  1779.  
  1780. To ensure cooperation with current and future versions of enhanced Windows
  1781. environment components, VxDs need to have unique ID numbers assigned. If you
  1782. are directly replacing an existing VxD, use the previous ID. Otherwise, if
  1783. you are creating a new VxD that provides any of the following:  %@NL@%
  1784.  
  1785.  
  1786.   ■   Service(s)%@NL@%
  1787.  
  1788.   ■   V86 mode API (see Appendix D, Section D.1.6, "Get Device API Entry
  1789.       Point")%@NL@%
  1790.  
  1791.   ■   Protected Mode API (see Appendix D, Section D.2.3, "Device Call Out
  1792.       API")%@NL@%
  1793.  
  1794.  
  1795. or if the VxD needs to call an MS-DOS device (listed in .SYS) or TSR, the
  1796. VxD will need a new ID. Device IDs are a 16-bit combination of the OEM
  1797. number and the device number in the form:  %@NL@%
  1798.  
  1799. %@AS@%  xOOOOOOOOOODDDDD%@AE@%
  1800.  
  1801. The high bit of the VxD ID is reserved for future use. The next ten bits are
  1802. the OEM number that is assigned by Microsoft. The last five bits are the
  1803. device number. This enables each OEM to create 32 unique VxDs. VxDs that do
  1804. not provide services or APIs or that do INT 2FH call-outs should use the
  1805. equate Undefined_Device_ID.  %@NL@%
  1806.  
  1807. See VMM.INC for other examples of device IDs. Microsoft reserves the first
  1808. 16 OEM numbers (0 through 0FH).  %@NL@%
  1809.  
  1810.  
  1811. %@4@%%@AB@%Initialization Order%@AE@%%@EH@%%@NL@%
  1812.  
  1813. VxDs are initialized in order from the %@AI@%lowest%@AE@% to the %@AI@%highest%@AE@% initialization
  1814. order value. If two or more devices have the same initialization order
  1815. value, then they are initialized in their order of occurence. Therefore, a
  1816. specific order is not guaranteed. You should use the initialization order
  1817. equates in VMM.INC to specify the initialization order for your VxD. If you
  1818. want your VxD to be initialized slightly before or after a defined
  1819. initialization order, use the equate plus an increment or minus a decrement.
  1820. Most likely, your VxD will not have any initialization ordering
  1821. dependencies. In this case, use the Undefined_Init_Order equate.  %@NL@%
  1822.  
  1823.  
  1824. %@3@%%@CR:C6A00170016 @%%@AB@%17.1.4  VxD Services%@AE@%%@EH@%%@NL@%
  1825.  
  1826. The functionality a VxD provides, if either directly to the VMM or other
  1827. VxDs, or through them to applications, is always via services. The services
  1828. use a dynamic-linking mechanism using INT 20H. (This mechanism is not the
  1829. same as the DLL protocol.) An example of a service call is shown below.  %@NL@%
  1830.  
  1831. This section contains descriptions on how to declare and call services, how
  1832. to verify the presence of a VxD, and a comparison of standard vs.
  1833. asynchronous services.%@CR:C6A00170017 @%%@NL@%
  1834.  
  1835.  
  1836. %@4@%%@AB@%Service Calling Conventions%@AE@%%@EH@%%@NL@%
  1837.  
  1838. All the enhanced Windows services use either a register-based calling
  1839. convention or a 32-bit C-type calling convention. In general, all the memory
  1840. manager calls use C calling conventions, and all other services are register
  1841. based.%@CR:C6A00170018 @%%@NL@%
  1842.  
  1843. The C convention services all begin with an underscore (_) in front of the
  1844. service name. They are similar to the standard C conventions: all parameters
  1845. are passed on the stack, and results are returned in the %@AB@%EAX%@AE@% and %@AB@%EDX%@AE@%
  1846. registers.  %@NL@%
  1847.  
  1848. Unlike the standard C conventions, the %@AB@%EBX%@AE@%, %@AB@%ES%@AE@%, %@AB@%FS%@AE@%, and %@AB@%GS%@AE@% registers are
  1849. preserved as well as the %@AB@%ESI%@AE@% and %@AB@%EDI%@AE@% registers. Only the flags and the %@AB@%EAX%@AE@%,
  1850. %@AB@%ECX%@AE@%, and %@AB@%EDX%@AE@% registers are modified.  %@NL@%
  1851.  
  1852. The %@AB@%VMMcall%@AE@% and %@AB@%VxDcall%@AE@% macros support stack parameter passing like the
  1853. standard C macro package. For example:  %@NL@%
  1854.  
  1855. %@AS@%  VMMcall _HeapAllocate, <<SIZE Data_Node>, 0>>%@AE@%
  1856.  
  1857. will generate the following code:  %@NL@%
  1858.  
  1859. %@AS@%  push 0
  1860. %@AS@%  push SIZE Data_Node
  1861. %@AS@%  int 20h
  1862. %@AS@%  dd _HeapAllocate
  1863. %@AS@%  add esp, 2*4%@AE@%
  1864.  
  1865. Notice that the parameters are pushed on the stack from right to left as in
  1866. the standard convention.  %@NL@%
  1867.  
  1868. All the Windows services for running in 386 enhanced mode that do not begin
  1869. with an underscore (_) are register-based services. All the parameters to
  1870. the services are passed in registers and all the results are returned in
  1871. registers. If a service does not explicitly return a result in a register,
  1872. than that register will be preserved.  %@NL@%
  1873.  
  1874.  
  1875. %@4@%%@AB@%Declaring Services%@AE@%%@EH@%%@NL@%
  1876.  
  1877. Virtual devices use two macros, %@AB@%Begin_Service_Table%@AE@% and %@AB@%End_Service_Table%@AE@%,
  1878. that are declared in VMM.INC to export services. The service table is
  1879. normally declared in an INCLUDE file that other VxDs can include to import
  1880. the services. For example, a typical service table declaration would look
  1881. something like this for the Virtual "FOO" Device:  %@NL@%
  1882.  
  1883. %@AS@%  Begin_Service_Table VFooD%@AE@%
  1884.  
  1885. %@AS@%  VFooD_Service vFooD_Get_Version, LOCAL
  1886. %@AS@%   VFooD_Service vFooD_Do_Something
  1887. %@AS@%   VFooD_Service vFooD_Do_Somthing_Else
  1888. %@AS@%   VFooD_Service vFooD_Do_Yet_Another_Thing, VxD_ICODE%@AE@%
  1889.  
  1890. %@AS@%  End_Service_Table VFooD%@AE@%
  1891.  
  1892. The %@AB@%Begin_Service_Table%@AE@% macro uses a single argument to generate the macro
  1893. used to declare individual services. %@AB@%Begin_Service_Table%@AE@% names the macro by
  1894. taking the name of the device and appending "_Service" to it. In the
  1895. preceding example, %@AB@%VFooD_Service%@AE@% is the name of the macro.  %@NL@%
  1896.  
  1897. The %@AB@%Device_Service%@AE@% macro can take one or two parameters. The first parameter
  1898. is the name of the service (e.g., %@AB@%Get_Version%@AE@%). This must match the name of
  1899. a procedure that was declared with the %@AB@%BeginProc%@AE@% macro using the "%@AB@%Service%@AE@%"
  1900. or "%@AB@%Async_Service%@AE@%" options. The second parameter is optional. If it is
  1901. omitted, then the service procedure is declared as an external reference in
  1902. the VxD_CODE segment.  %@NL@%
  1903.  
  1904. If the special value "LOCAL" is used as the second parameter (as in the
  1905. VFooD_Get_Version declaration), then the procedure is not declared as
  1906. external. This option is used when the service is declared in the same file
  1907. in which the service table will be created. If, in this case, it were to be
  1908. declared external, then MASM would generate an error.  %@NL@%
  1909.  
  1910. If the service procedure is not in the same file as the one used to create
  1911. the service table, and not in the VxD_CODE segment, then you must supply the
  1912. name of the segment it resides in so that the proper external declaration
  1913. can be made. In the above example, the %@AB@%VFooD_Do_Yet_Another_Thing%@AE@% service is
  1914. declared to be in the VxD_INIT code segment. All others are left in the
  1915. default VxD_CODE segment.  %@NL@%
  1916.  
  1917. The first service for every device %@AI@%must%@AE@% be a %@AB@%Get_Version%@AE@% service. This
  1918. service must return with %@AB@%AX%@AE@%  0 and the Carry flag clear. See the following
  1919. section, "%@AB@%VxD Presence Verification%@AE@%," for more details.  %@NL@%
  1920.  
  1921. Once the table of services has been created, you must force the table to be
  1922. generated in one of the VxD source files by defining a special equate (EQU)
  1923. called "%@AB@%Create_xxx_Service_Table%@AE@%," where %@AI@%xxx%@AE@% is the name of the device
  1924. before including the service declaration INCLUDE file. For example, the main
  1925. source file of the VFooD service table would contain the following INCLUDE
  1926. statements:%@AB@%  %@AE@%%@NL@%
  1927.  
  1928. %@AS@%  INCLUDE VMM.INC
  1929. %@AS@%  INCLUDE Debug.INC
  1930. %@AS@%  Create_VFooD_Service_Table EQU true
  1931. %@AS@%  INCLUDE VFooD.INC%@AE@%
  1932.  
  1933. This must be done in the same source file that contains the device
  1934. declaration. This table is automatically generated and the pointer to the
  1935. table is stored in the device's DDB.  %@NL@%
  1936.  
  1937. Notice that, since the macros generate equates, you will now want to add
  1938. service declarations to the end of the INCLUDE file. That is, never change
  1939. the order of the declarations. Adding, removing, or changing the order of
  1940. services changes the service numbering and all the VxDs that call these
  1941. services will need to be rebuilt.  %@NL@%
  1942.  
  1943.  
  1944. %@4@%%@AB@%VxD Presence Verification%@AE@%%@EH@%%@NL@%
  1945.  
  1946. Many VxDs will not load under certain circumstances. For example the EBIOS
  1947. device will not load when the machine does not have an extended BIOS data
  1948. area. Before calling VxD services, you should make sure that the VxD is
  1949. loaded by calling the VxD %@AB@%Get_Version%@AE@% service. %@AB@%Get_Version%@AE@% for a VxD will
  1950. return with %@AB@%AX%@AE@% = 0 and the Carry flag set if the VxD is not installed.  %@NL@%
  1951.  
  1952.  
  1953. %@4@%%@AB@%Standard Vs. Asynchronous Services%@AE@%%@EH@%%@NL@%
  1954.  
  1955. Most services are not reentrant. This means they cannot be called from
  1956. hardware interrupt procedures. However, a select group of services is
  1957. declared as "Async" services and can be called from hardware interrupt
  1958. procedures. You may declare services that can be called from interrupt
  1959. handlers by using the "%@AB@%Async_Service%@AE@%" option for the %@AB@%BeginProc%@AE@% macro.  %@NL@%
  1960.  
  1961. When writing async services, do not call non-async services, and be sure the
  1962. routine can handle reentrancy.  %@NL@%
  1963.  
  1964.  
  1965. %@3@%%@CR:C6A00170019 @%%@AB@%17.1.5  VxD APIs (Call-Ins)%@AE@%%@EH@%%@NL@%
  1966.  
  1967. While VxD services are used to communicate with other enhanced Windows
  1968. virtual devices, APIs are used to communicate with software running in a
  1969. virtual machine. For example, the Shell device supports an API that is used
  1970. to communicate with WinOldAp (the Windows support program for non-Windows
  1971. applications) that runs in the System VM.%@CR:C6A00170020 @%%@CR:C6A00170021 @%%@NL@%
  1972.  
  1973. A VxD can support API for V86-mode code, protected-mode code, or both. The
  1974. procedure entry point(s) for the API is specified in the device declaration
  1975. macro (see Section 17.1.3, "VxD Declaration," for more details on
  1976. %@AB@%Declare_Virtual_Device%@AE@%). The VM software issues an INT 2FH with %@AB@%AX%@AE@% = 1684H
  1977. and %@AB@%BX%@AE@% = Device_ID to get the address to call to access the API. See
  1978. Appendix D, "Windows INT 2FH API," for more information.%@CR:C6A00170022 @%%@NL@%
  1979.  
  1980. The application can then call this address, passing appropriate information
  1981. in registers. The same address is used to call all API functions provided by
  1982. a single VxD.  %@NL@%
  1983.  
  1984. When such a call is made, the VMM will in turn call the VxD's API procedure
  1985. with the following parameters:  %@NL@%
  1986.  
  1987. %@AS@%  EBX = Current VM handle
  1988. %@AS@%  EBP = Client register structure
  1989. %@AS@%  Client_CS:IP = Instruction following API call%@AE@%
  1990.  
  1991. API procedures must examine the client registers (through the client
  1992. register structure) to determine which API call was made. The normal calling
  1993. convention uses %@AB@%AH%@AE@% = Major function number and %@AB@%AL%@AE@% = Minor function number.
  1994. Other registers are used for parameters to the functions. However, a device
  1995. can use any calling convention that is appropriate. If you want to return a
  1996. value to the caller, then the API procedure should modify the client
  1997. registers.  %@NL@%
  1998.  
  1999. API procedures may modify the %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, and %@AB@%EDI%@AE@% registers.  %@NL@%
  2000.  
  2001.  
  2002. %@3@%%@CR:C6A00170023 @%%@AB@%17.1.6  VxD INT 2F Usage%@AE@%%@EH@%%@NL@%
  2003.  
  2004. Appendix E, "The Windows INT 2F API," includes several INT 2F functions that
  2005. are of interest to VxD writers. Specifically, there is an INT 2F to get the
  2006. address for calling the VxD API procedure, an INT 2F for a VxD to call out
  2007. to a T&SR or a DOS device driver, and an INT 2F by which a T&SR or DOS
  2008. device driver can specify a VxD to load when starting enhanced mode Windows.
  2009. If your VxD interacts with global software, be sure to study this appendix.
  2010. %@NL@%
  2011.  
  2012.  
  2013. %@2@%%@CR:C6A00170024 @%%@AB@%17.2  Building a VxD%@AE@%%@EH@%%@NL@%
  2014.  
  2015. This section describes in general the steps necessary to build and install a
  2016. VxD into the enhanced Windows environment. These steps are typically
  2017. specified and executed from the MAKE file. Detailed examples are also
  2018. included in a MAKE files located on the supplied DDK disks.%@CR:C6A00170025 @%%@NL@%
  2019.  
  2020. There are three required steps for building a VxD, with each requiring a
  2021. specific software tool:  %@NL@%
  2022.  
  2023.  
  2024.   1.  Assemble the VxD code with MASM5.10B, which is the special version of
  2025.       the assembler used to handle a new pseudo group, FLAT. (%@AB@%.ASM  %@AE@%.OBJ)%@NL@%
  2026.  
  2027.   2.  Link the .OBJ files utilizing a .DEF file, with LINK386. LINK386 is
  2028.       the linker used to create the special 32-bit .EXEs.(%@AB@%.OBJ %@AE@% %@AB@%.386%@AE@%, %@AB@%.MAP%@AE@%)%@NL@%
  2029.  
  2030.   3.  Declare the code to be a VxD with ADDHDR, which adds special VxD
  2031.       information into the .EXE produced with LINK386.(%@AB@%.386 %@AE@% %@AB@%.386%@AE@%)%@NL@%
  2032.  
  2033. %@STUB@%      An optional fourth step, is available for debugging:%@NL@%
  2034.  
  2035.   4.  Generate symbol files with MAPSYM32, which generates 32-bit symbol
  2036.       (.SYM) files for debugging.(%@AB@%.MAP  .%@AE@%SYM)%@NL@%
  2037.  
  2038.  
  2039. These four tools are included in this version of the DDK. See the following
  2040. sections for detailed invocation instructions.  %@NL@%
  2041.  
  2042. The following MAKE file sample is from the Virtual Printer Device (VPD). The
  2043. complete source for building the VPD is included on the DDK disks.  %@NL@%
  2044.  
  2045. %@AS@%  vpd.obj: vpd.asm
  2046. %@AS@%           masm5 -p -w2 vpd;
  2047. %@AS@%  
  2048. %@AS@%  vpd.386: vpd.obj vpd.def
  2049. %@AS@%           link386 vpd, vpd.386/NOI /NOD /NOP,/MAP,,vpd.def
  2050. %@AS@%           addhdr vpd.386
  2051. %@AS@%           mapsym32 vpd%@AE@%
  2052.  
  2053. The MAKE file assumes that the four tools are included in the MS-DOS %@AB@%PATH%@AE@%
  2054. command. If they are not, then you must modify the MAKE file to specify
  2055. their exact locations.  %@NL@%
  2056.  
  2057.  
  2058. %@3@%%@CR:C6A00170026 @%%@AB@%17.2.1  MASM5.10B%@AE@%%@EH@%%@NL@%
  2059.  
  2060. This is a special version of MASM that supports 32-bit, flat-model code. It
  2061. has been named MASM5 to differentiate it from other versions of MASM you may
  2062. already have. It has the same command-line options and format as MASM 5.1,
  2063. so you can refer to version 5.1 documentation for information on this
  2064. program.%@CR:C6A00170027 @%%@NL@%
  2065.  
  2066. It is recommended that the %@AB@%-p%@AE@% and %@AB@%-w2%@AE@% options be used when assembling
  2067. virtual devices. The %@AB@%-p%@AE@% option specifies that impure code segment references
  2068. should generate warning messages. This is desirable, because it is illegal
  2069. to write data with a %@AB@%CS%@AE@% override. The %@AB@%-w2%@AE@% option sets the warning level to
  2070. 2, so that warning messages are generated for such things as jumps that are
  2071. within SHORT range and for data size mismatches.  %@NL@%
  2072.  
  2073. MASM5 will look for INCLUDE files in the current directory and the INCLUDE
  2074. path specified by the environment variable INCLUDE. Therefore, the DDK
  2075. INCLUDE files (e.g., VMM.INC, VPICD.INC, and VDD.INC) should be either in
  2076. the current directory or located along the INCLUDE path.  %@NL@%
  2077.  
  2078.  
  2079. %@3@%%@CR:C6A00170028 @%%@AB@%17.2.2  LINK386%@AE@%%@EH@%%@NL@%
  2080.  
  2081. The LINK386 command line is as follows:%@CR:C6A00170029 @%%@NL@%
  2082.  
  2083. %@AS@%  LINK386 <object file>, <output file> {<options>}, <map file>, <def file>%@AE@%
  2084.  
  2085. For example:  %@NL@%
  2086.  
  2087. %@AS@%  link386 vpd, vpd.386/NOI /NOD /NOP, /MAP,,vpd.def%@AE@%
  2088.  
  2089. LINK386 links into one device file the individual object (OBJ) files that
  2090. make up a virtual device. By convention, Windows devices have the extension
  2091. .386. The command line specifies the object files(s), the desired output
  2092. file, option switches, and definition file. The following list describes the
  2093. option switches used to link a VxD.  %@NL@%
  2094.  
  2095. %@TH:  17   929 02 12 24 40 @%
  2096. Option      Full Name               Description
  2097. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2098. %@AB@%/NOI%@AE@%        NOIGNORECASE            Specifies that case should not be 
  2099.                                     ignored.
  2100.  
  2101. %@AB@%/NOD%@AE@%        NODEFAULTLIBRARYSEARCH  Specifies that LINK386 should not 
  2102.                                     search for default libraries.
  2103.  
  2104. %@AB@%/NOP%@AE@%        NOPACKEDCODE            Specifies that code segments should 
  2105. %@AB@%%@AE@%                                    not be packed into one code segment in
  2106.                                     the .EXE file.
  2107.  
  2108. %@AB@%/MAP%@AE@%                                Specifies that all public symbols 
  2109.                                     should be included in the MAP file.
  2110.  
  2111. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2112.  
  2113. %@TE:  17   929 02 12 24 40 @%
  2114.  
  2115. Definition (DEF) files are used by LINK386 to identify the device descriptor
  2116. block within the device and the types of segments. DEF files for virtual
  2117. devices all look similar to the following example:  %@NL@%
  2118.  
  2119. %@AS@%  LIBRARY VPD%@AE@%
  2120.  
  2121. %@AS@%  DESCRIPTION 'Win386 VPD Device (Version 2.0)'%@AE@%
  2122.  
  2123. %@AS@%  EXETYPE DEV386%@AE@%
  2124.  
  2125. %@AS@%  SEGMENTS
  2126. %@AS@%   _LTEXT PRELOAD NONDISCARDABLE
  2127. %@AS@%   _LDATA PRELOAD NONDISCARDABLE
  2128. %@AS@%   _ITEXT CLASS 'ICODE' DISCARDABLE
  2129. %@AS@%   _IDATA CLASS 'ICODE' DISCARDABLE
  2130. %@AS@%   _TEXT CLASS 'PCODE'   NONDISCARDABLE
  2131. %@AS@%   _DATA CLASS 'PCODE'   NONDISCARDABLE%@AE@%
  2132.  
  2133. %@AS@%  EXPORTS
  2134. %@AS@%   VPD_DDB @1%@AE@%
  2135.  
  2136. The LIBRARY line is required to identify the device as a module that is part
  2137. of a system rather than an executable application. The DESCRIPTION line is
  2138. optional and simply records the text string into the .386 file. The EXETYPE
  2139. line is required to identify the .386 file as an enhanced Windows device
  2140. file.  %@NL@%
  2141.  
  2142. The SEGMENTS section is identical for all devices, because it identifies the
  2143. six possible types of protected-mode segments that can be part of a device.
  2144. (If a device has a real-mode initialization section, then it can have seven
  2145. types of segments. However, the real-mode section does not need any special
  2146. identification in the DEF file.)  %@NL@%
  2147.  
  2148. The EXPORTS section is also required; it identifies the name and location of
  2149. the device descriptor block for the virtual device. It must match the name
  2150. used in the %@AB@%Declare_Virtual_Device%@AE@% statement in the device source, with _DDB
  2151. appended to the end. It must also be identified as ordinal number 1 with the
  2152. @ symbol.  %@NL@%
  2153.  
  2154.  
  2155. %@3@%%@CR:C6A00170030 @%%@AB@%17.2.3  ADDHDR%@AE@%%@EH@%%@NL@%
  2156.  
  2157. The ADDHDR command line is as follows:%@CR:C6A00170031 @%%@NL@%
  2158.  
  2159. %@AS@%  addhdr <filename>%@AE@%
  2160.  
  2161. For example:  %@NL@%
  2162.  
  2163. %@AS@%  addhdr vpd.386%@AE@%
  2164.  
  2165. ADDHDR simply reads the specified 32-bit .EXE file, performs some validation
  2166. checks, and writes some additional header information needed by the enhanced
  2167. Windows loader into the file's .EXE header.  %@NL@%
  2168.  
  2169.  
  2170. %@3@%%@CR:C6A00170032 @%%@AB@%17.2.4  MAPSYM32%@AE@%%@EH@%%@NL@%
  2171.  
  2172. The MAPSYM32 command line is as follows:%@CR:C6A00170033 @%%@NL@%
  2173.  
  2174. %@AS@%  mapsym32 <device name>%@AE@%
  2175.  
  2176. For example:  %@NL@%
  2177.  
  2178. %@AS@%  mapsym32 vpd%@AE@%
  2179.  
  2180. MAPSYM32 reads a MAP file and creates a 32-bit .SYM file for use with the
  2181. Windows debugger, WDEB386. The %@AB@%/MAP%@AE@% option must be specified for LINK386 to
  2182. generate the necessary MAP file.  %@NL@%
  2183.  
  2184.  
  2185. %@3@%%@CR:C6A00170034 @%%@AB@%17.2.5  Installing a VxD%@AE@%%@EH@%%@NL@%
  2186.  
  2187. In order to install the newly created VxD with the rest of enhanced Windows,
  2188. edit the SYSTEM.INI file. in the %@AB@%[386ENH]%@AE@% section by inserting %@AB@%DEVICE%@AE@% =
  2189. <your VxD file name> and put your file in the Windows SYSTEM subdirectory.%@CR:C6A00170035 @%%@NL@%
  2190.  
  2191.  
  2192. %@2@%%@CR:C6A00170036 @%%@AB@%17.3  Initializing a VxD%@AE@%%@EH@%%@NL@%
  2193.  
  2194. As described in Chapter 16, "Overview of Windows in 386 Enhanced Mode," VxDs
  2195. are initialized along with the enhanced Windows environment. Both real-mode
  2196. and protected-mode code may be used and are described in the following
  2197. subsections.%@CR:C6A00170037 @%%@NL@%
  2198.  
  2199.  
  2200. %@3@%%@CR:C6A00170038 @%%@AB@%17.3.1  Real-Mode Initialization%@AE@%%@EH@%%@NL@%
  2201.  
  2202. Each VxD can have a portion that is run in real mode at load time. This
  2203. capability is provided to enable a VxD to determine whether or not it can
  2204. operate in the current environment and to provide information to the loader
  2205. about how it should vary the environment. This portion is only executed at
  2206. load time and, then is discarded.%@CR:C6A00170039 @%%@CR:C6A00170040 @%%@NL@%
  2207.  
  2208. A real-mode portion is included in the same binary file as the rest of the
  2209. VxD code and data, but is located in a special 16-bit sement. It has a
  2210. single entry point, declared as a NEAR procedure. At load time, if the
  2211. loader determines that a real-mode portion is present, it loads it and calls
  2212. its entry point as specified by the END statement at the end of the file
  2213. (%@AB@%CS%@AE@%:0 if no entry point is found). Upon entry %@AB@%CS%@AE@% = %@AB@%DS%@AE@% = %@AB@%ES%@AE@%, so code and data
  2214. must be mixed in the same segment. The code can then perform the checks that
  2215. are necessary and return an exit code back to the loader.  %@NL@%
  2216.  
  2217. Valid exit codes are as follows (see VMM.INC for equates):  %@NL@%
  2218.  
  2219.  
  2220.   ■   0 - Everything is fine, and the loader should continue loading the
  2221.       protected-mode portion and the rest of the VxDs.%@NL@%
  2222.  
  2223.   ■   1 - This device is not compatible with the current environment and
  2224.       will not be loaded, but the loader can continue to load other VxDs.%@NL@%
  2225.  
  2226.   ■   2 - Something is wrong and the loader should abort the Windows load
  2227.       completely.%@NL@%
  2228.  
  2229.  
  2230. If 1 or 2 is returned, then the loader will normally print an appropriate
  2231. error message naming the VxD that failed. If the real-mode portion has
  2232. already handled the message reporting or does not want any default error
  2233. message, then it should set the high bit of the return code in %@AB@%AX%@AE@% (i.e.,
  2234. 8001H or 8002H.)  %@NL@%
  2235.  
  2236. The real-mode portion can also inform the loader to do the following:  %@NL@%
  2237.  
  2238.  
  2239.   ■   Pass a DWORD of reference data to the protected-mode portion of the
  2240.       device.%@NL@%
  2241.  
  2242.   ■   Pass a table of pages in low memory (0-1Mb) that should be excluded
  2243.       from general use by the enhanced Windows memory manager.%@NL@%
  2244.  
  2245.   ■   Pass a table of pointers to data that should be instanced for each
  2246.       virtual machine. %@NL@%
  2247.  
  2248.  
  2249. It is possible for a VxD to exclude pages and/or declare instance data
  2250. without actually having a protected-mode portion; it should return 8001H as
  2251. the return code, so that the loader will attempt no further loading of the
  2252. device and will not display the default error message.  %@NL@%
  2253.  
  2254. The real-mode portion can perform most BIOS or MS-DOS interrupts and examine
  2255. memory to check the environment of the machine. It cannot attempt to perform
  2256. any type of MS-DOS exit calls because these will halt the loader in an
  2257. unclean state, and it will be necessary to reboot the machine. Also, any
  2258. open files should be closed before returning since they will not be closed
  2259. by the loader.  %@NL@%
  2260.  
  2261. The following is a summary of entry assumption:  %@NL@%
  2262.  
  2263. CS = DS = ES = segment of loaded code and data IP = specified entry point or
  2264. 0. SI = environment segment, passed to the loader from MS-DOS AX = VMM
  2265. version number BX = flags    bit 0: duplicate device ID already loaded
  2266. bit 1: duplicate ID was from the INT 2F device list    bit 2: this device is
  2267. from the INT 2F device list %@AB@%EDX%@AE@% = reference data from INT 2F response, or 0
  2268. %@NL@%
  2269.  
  2270. %@AB@%SS:SP%@AE@% point to loader's stack.  %@NL@%
  2271.  
  2272. The following is a summary of exit assumptions:  %@NL@%
  2273.  
  2274. Must return with a NEAR return %@AB@%AX%@AE@% = return code (see above) %@AB@%BX%@AE@% = ptr to list
  2275. of pages to exclude (0, if none), where:    list is = one or more words in
  2276. the range 1 to 9FH (terminated) by a word of zero %@AB@%SI%@AE@% = ptr to list of
  2277. Instance data items (0, if none), where:     list is = one or more instance
  2278. data items followed by three words   of zero (note that 0-3FF, the interrupt
  2279. vectors are   always instanced). instance data item = pointer to   data
  2280. (word segment, word offset),word length of data  %@NL@%
  2281.  
  2282. %@AB@%EDX%@AE@% = DWORD of reference data to be passed to the protected-mode portion.
  2283. (This can be a linear pointer to ROM data, a constant, etc. that will affect
  2284. the way the protected portion might operate. For example, an EBIOS device
  2285. can pass the EBIOS page number, so that the protected-mode portion does not
  2286. have to look for the page again.)  %@NL@%
  2287.  
  2288. All the other registers except SS:SP can be modified.  %@NL@%
  2289.  
  2290. The macros %@AB@%VxD_REAL_INIT_SEG%@AE@% and %@AB@%VxD_REAL_INIT_ENDS%@AE@% are defined in VMM.INC
  2291. to facilitate creating a real-mode portion of a device driver. The real-mode
  2292. portion cannot access code or data outside of its segment. If this is
  2293. attempted, the linker will generate warnings and a corrupt .386 file. Fixed
  2294. segments such as the BIOS (40H) segments are an exception to this. It is
  2295. possible to have declared in multiple source files real-mode portions that
  2296. will all be linked together (e.g., separating message text from the code).  %@NL@%
  2297.  
  2298. The following is an example of real-mode initialization code:  %@NL@%
  2299.  
  2300. %@AS@%  VxD_REAL_INIT_SEG
  2301. %@AS@%  BeginProc ebios_init
  2302. %@AS@%   mov ah, 0C0h
  2303. %@AS@%   int 15h
  2304. %@AS@%   test es:[bx.SD_feature1], EBIOS_allocated
  2305. %@AS@%   jz short no_ebios_fnd
  2306. %@AS@%   mov ah, 0C1h      ; get segment adr of EBIOS
  2307. %@AS@%   int 15h
  2308. %@AS@%  
  2309. %@AS@%   jc short no_ebios_fnd
  2310. %@AS@%   mov ax, es    ; get EBIOS segment address
  2311. %@AS@%   shr ax, 8    ; convert to a page #
  2312. %@AS@%   movzx edx, ax     ; return EBIOS pg as ref 
  2313. %@AS@%        ; data
  2314. %@AS@%   mov bx, OFFSET exc_ebios_page  ; ptr to exclusion table
  2315. %@AS@%   mov [bx], ax    ; exclude EBIOS page
  2316. %@AS@%        ; from memory manager use
  2317. %@AS@%   xor si, si    ; no instance data to 
  2318. %@AS@%        ; declare
  2319. %@AS@%   mov ax, Device_Load_Ok  ; go ahead and load the 
  2320. %@AS@%        ; device
  2321. %@AS@%   jmp short init_exit   ; return to loader
  2322. %@AS@%  
  2323. %@AS@%  no_ebios_fnd:
  2324. %@AS@%   mov ah, 9
  2325. %@AS@%   mov dx, OFFSET no_ebios_msg    ; print message thru DOS
  2326. %@AS@%   int 21h
  2327. %@AS@%   xor bx, bx    ; no exclusion table
  2328. %@AS@%   xor si, si    ; no instance data table
  2329. %@AS@%   xor edx, edx    ; no reference data
  2330. %@AS@%   mov ax, Abort_Device_Load + No_Fail_Message
  2331. %@AS@%        ; don't load pmode portion 
  2332. %@AS@%        ; and don't display an 
  2333. %@AS@%        ; error msg
  2334. %@AS@%  
  2335. %@AS@%  init_exit:
  2336. %@AS@%   ret
  2337. %@AS@%  exc_ebios_page dw 0, 0
  2338. %@AS@%  no_ebios_msg db 'PS/2 type EBIOS not detected', 13, 10, '$'
  2339. %@AS@%  EndProc ebios_init
  2340. %@AS@%  VxD_REAL_INIT_ENDS
  2341. %@AS@%  END ebios_init     ; specify real mode 
  2342. %@AS@%        ; initialization entry point%@AE@%
  2343.  
  2344.  
  2345. %@3@%%@CR:C6A00170041 @%%@AB@%17.3.2  Protected-Mode Initialization%@AE@%%@EH@%%@NL@%
  2346.  
  2347. The enhanced Windows environment has a three-phase, protected-mode
  2348. initialization. Returning a carry during any of the phases will abort the
  2349. VxD load.%@CR:C6A00170042 @%%@NL@%
  2350.  
  2351.  
  2352. %@4@%%@AB@%Phase 1. Sys_Critical_Init%@AE@%%@EH@%%@NL@%
  2353.  
  2354. During the first phase of initialization, interrupts are not yet enabled.
  2355. Therefore, this phase should accomplish the following tasks as quickly as
  2356. possible.  %@NL@%
  2357.  
  2358.  
  2359.   ■   Initialization of critical functions necessary when interrupts are
  2360.       enabled. %@NL@%
  2361.  
  2362.   ■   Claiming a particular range of V86 pages if necessary (such as the
  2363.       video memory for the VDD).%@NL@%
  2364.  
  2365.   ■   Initialization of data needed by the services provided by the VxD.%@NL@%
  2366.  
  2367.   ■   During this phase, the System VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% commands
  2368.       must not be used.%@NL@%
  2369.  
  2370.  
  2371.  
  2372. %@4@%%@AB@%Phase 2. Device_Init%@AE@%%@EH@%%@NL@%
  2373.  
  2374. During this phase most VxDs do the bulk of their initialization. They will:
  2375. %@NL@%
  2376.  
  2377.  
  2378.   ■   Allocate their Control Block area%@NL@%
  2379.  
  2380.   ■   Allocate other required memory areas%@NL@%
  2381.  
  2382.   ■   Hook interrupts%@NL@%
  2383.  
  2384.   ■   Hook I/O ports%@NL@%
  2385.  
  2386.   ■   Specify instance data%@NL@%
  2387.  
  2388.   ■   Initialize themselves%@NL@%
  2389.  
  2390.  
  2391. The System VM's Control Block should be set up with the inital state of the
  2392. VxD. Since the System VM has already been created, calls such as
  2393. Simulate_Int or Exec_Int is allowed.  %@NL@%
  2394.  
  2395.  
  2396. %@4@%%@AB@%Phase 3. Init_Complete%@AE@%%@EH@%%@NL@%
  2397.  
  2398. This is the final phase of %@AB@%Device_Init%@AE@% that is called just before the WIN386
  2399. INIT pages are released and the instance snapshot is taken. VxDs that want
  2400. to search for a region of V86 memory to use should do so during this phase.
  2401. Most devices, though, will not need to do anything here.  %@NL@%
  2402.  
  2403.  
  2404. %@2@%%@CR:C6A00170043 @%%@AB@%17.4  Tracking the VM States%@AE@%%@EH@%%@NL@%
  2405.  
  2406. Most likely, the VxD that you are writing needs to keep track of the status
  2407. of the different VMs that may need your VxD. This includes VM creation,
  2408. initialization, and termination. The following subsections describe these
  2409. and other possible VM states.%@CR:C6A00170044 @%%@NL@%
  2410.  
  2411.  
  2412. %@3@%%@CR:C6A00170045 @%%@AB@%17.4.1  VM Creation and Initialization%@AE@%%@EH@%%@NL@%
  2413.  
  2414. Like the initialization of the enhanced Windows environment, a VM's go
  2415. through a multi-phase initialization process.%@CR:C6A00170046 @%%@NL@%
  2416.  
  2417.  
  2418. %@4@%%@AB@%Phase 1. Create_VM%@AE@%%@EH@%%@NL@%
  2419.  
  2420. This call creates a new VM. %@AB@%EBX%@AE@% = VM handle of the new VM. Returning Carry
  2421. will fail the %@AB@%Create_VM%@AE@%. VxDs should initialize data associated with the VM,
  2422. especially the control block.  %@NL@%
  2423.  
  2424.  
  2425. %@4@%%@AB@%Phase 2. VM_Critical_Init%@AE@%%@EH@%%@NL@%
  2426.  
  2427. %@AB@%EBX%@AE@% = VM handle of the new VM. Returning Carry will cause the VM to
  2428. %@AB@%VM_Not_Executeable%@AE@%, then be destroyed (see Section 17.4.3). VM %@AB@%Simulate_Int%@AE@%
  2429. or %@AB@%Exec_Int%@AE@% activity is not allowed.  %@NL@%
  2430.  
  2431.  
  2432. %@4@%%@AB@%Phase 3. VM_Init and Sys_VM_Init%@AE@%%@EH@%%@NL@%
  2433.  
  2434. The VxD interacts with the VM in order to initialize the state of the
  2435. software in the VM (e.g., the VDD does an INT 10H to set the initial display
  2436. mode.  %@NL@%
  2437.  
  2438. System VM initialization is the same as other VM initializations except its
  2439. Phase 1 and 2 are done at Device_Init and if Carry is returned, all of
  2440. enhanced Windows will exit.  %@NL@%
  2441.  
  2442.  
  2443. %@3@%%@CR:C6A00170047 @%%@AB@%17.4.2  VM State Changes%@AE@%%@EH@%%@NL@%
  2444.  
  2445. During the normal execution of enhanced Windows, VMs will go through state
  2446. changes. Most state changes may be ignored by VxDs. However, depending on
  2447. the purpose of the VxD, some may require VxD response. The following calls
  2448. describe the possible VM state changes.  %@NL@%
  2449.  
  2450.  
  2451. %@4@%%@AB@%VM_Suspend%@AE@%%@EH@%%@NL@%
  2452.  
  2453. The VM is not runnable until a resume. %@AB@%EBX%@AE@% = VM handle. The call cannot be
  2454. failed. The VxD should unlock any resources associated with the VM.  %@NL@%
  2455.  
  2456. The VM_Suspend message is sent only once each time the VM is suspended. Note
  2457. that there is a bit the the control block CB_VM_Status flags indicating the
  2458. current state. See VMM.INC for details.  %@NL@%
  2459.  
  2460.  
  2461. %@4@%%@AB@%VM_Resume%@AE@%%@EH@%%@NL@%
  2462.  
  2463. The VM is leaving a suspended state. %@AB@%EBX%@AE@% = VM handle. Returning a carry
  2464. fails and backs out of the resume. Lock any resources and otherwise prepare
  2465. internal data structures for the VM to start running again.  %@NL@%
  2466.  
  2467. The VM_Resume message is sent only once after a VM_Suspend message has been
  2468. sent.  %@NL@%
  2469.  
  2470.  
  2471. %@4@%%@AB@%Set_Device_Focus%@AE@%%@EH@%%@NL@%
  2472.  
  2473. This sets the focus of the specified VxD to the specified VM. %@AB@%EBX%@AE@% = VM
  2474. handle of desired VM. %@AB@%EDX%@AE@% = VxD ID. For VxD specific set focus, %@AB@%EDX%@AE@% = 0 for
  2475. device critical set focus (all devices).  %@NL@%
  2476.  
  2477. This call cannot be failed. Restore the hardware associated with the device
  2478. to the state of the specified VM. As much as possible, remove VxD
  2479. interaction with VM (such as disabling I/O trapping) so that VM can run as
  2480. fast as possible.  %@NL@%
  2481.  
  2482.  
  2483. %@4@%%@AB@%Begin_Message_Mode%@AE@%%@EH@%%@NL@%
  2484.  
  2485. This call prepares the device for message processing. This is only of
  2486. interest to the keyboard, mouse, and display. When in message mode, special
  2487. services provided by the display and keyboard are used to interact with the
  2488. user. Message mode is used for the ALT+TAB screen and for message boxes when
  2489. Windows is not available to process a message box. EBX = VM handle going
  2490. into message mode. This call cannot be failed.  %@NL@%
  2491.  
  2492.  
  2493. %@4@%%@AB@%End_Message_Mode%@AE@%%@EH@%%@NL@%
  2494.  
  2495. %@AB@%EBX%@AE@% = VM handle leaving message mode. This call cannot be failed.  %@NL@%
  2496.  
  2497.  
  2498. %@4@%%@AB@%Reboot_Processor%@AE@%%@EH@%%@NL@%
  2499.  
  2500. This call requests a machine reboot. The device (usually the keyboard
  2501. device) that knows how to reboot the machine does the necessary operations.
  2502. %@NL@%
  2503.  
  2504.  
  2505. %@4@%%@AB@%Query_Destroy%@AE@%%@EH@%%@NL@%
  2506.  
  2507. This call asks if it can destroy the running VM. %@AB@%Query_Destroy%@AE@% is an
  2508. information call made by the Shell device before an attempt is made to
  2509. initiate a destroy VM sequence on a running VM that has not exited normally.
  2510. %@AB@%EBX%@AE@% = VM handle. Returning Carry indicates that a VxD has a problem with
  2511. allowing this. It is recommended that the VxD returning the Carry indicating
  2512. a problem call %@AB@%SHELL_Message%@AE@% to post an informational dialog about the
  2513. reason for the problem.  %@NL@%
  2514.  
  2515.  
  2516. %@4@%%@AB@%Debug_Query%@AE@%%@EH@%%@NL@%
  2517.  
  2518. %@AB@%Debug_Query%@AE@% is a special call for device-specific DEBUG information display
  2519. and activity. This call is made in response to the user typing a period
  2520. followed by the VxD name in response to the WDEB386 prompt. The VxD name is
  2521. declared with the %@AB@%Declare_Virtual_Device%@AE@% macro (see Section 17.1.3, "VxD
  2522. Declaration"). Use conditional assembly to remove this call from the final
  2523. VxD.  %@NL@%
  2524.  
  2525.  
  2526. %@3@%%@CR:C6A00170048 @%%@AB@%17.4.3  VM Termination%@AE@%%@EH@%%@NL@%
  2527.  
  2528. Graceful termination of a VM occurs in the following three steps:%@CR:C6A00170049 @%%@NL@%
  2529.  
  2530.  
  2531. %@4@%%@AB@%Phase 1. VM_Terminate%@AE@%%@EH@%%@NL@%
  2532.  
  2533. During this phase of normal VM termination. %@AB@%EBX%@AE@% = VM handle. Call cannot be
  2534. failed. VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is allowed.  %@NL@%
  2535.  
  2536.  
  2537. %@4@%%@AB@%Sys_VM_Terminate%@AE@%%@EH@%%@NL@%
  2538.  
  2539. Same as %@AB@%VM_Terminate%@AE@%, except terminates the System VM. System VM
  2540. %@AB@%Simulate_Int%@AE@%, %@AB@%Exec_Int%@AE@% activity is allowed. System VM will always be the
  2541. last VM terminated, and thereby indicates that enhanced Windows is
  2542. terminating. This call is only made during a normal exit, during a crash
  2543. exit this call is not made.  %@NL@%
  2544.  
  2545.  
  2546. %@4@%%@AB@%Phase 2. VM_Not_Executeable%@AE@%%@EH@%%@NL@%
  2547.  
  2548. During the second phase of VM termination. %@AB@%EBX%@AE@% = VM handle, %@AB@%EDX%@AE@% = Flags (see
  2549. VMM.INC). Notice that in the case of destroying a running VM, this is the
  2550. first call made (i.e., the %@AB@%VM_Terminate%@AE@% call does not occur). Call cannot be
  2551. failed. VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is %@AI@%not%@AE@% allowed. Flags for
  2552. %@AB@%VM_Not_Executeable%@AE@% control call (passed in %@AB@%EDX%@AE@%) are as follows:  %@NL@%
  2553.  
  2554. %@TH:   7   501 02 22 54 @%
  2555. Flag                  Meaning
  2556. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2557. %@AB@%VNE_Crashed%@AE@%           VM has crashed.
  2558. %@AB@%VNE_Nuked%@AE@%             VM was destroyed while active.
  2559. %@AB@%VNE_CreateFail%@AE@%        Some device failed %@AB@%Create_VM%@AE@%.
  2560. %@AB@%VNE_CrInitFail%@AE@%        Some device failed %@AB@%VM_Critical_Init%@AE@%.
  2561. %@AB@%VNE_InitFail%@AE@%          Some device failed %@AB@%VM_Init%@AE@%.
  2562. %@TE:   7   501 02 22 54 @%
  2563.  
  2564.  
  2565. %@4@%%@AB@%Phase 3. Destroy_VM%@AE@%%@EH@%%@NL@%
  2566.  
  2567. During this final phase of VM termination. %@AB@%EBX%@AE@% = VM handle. Notice that
  2568. considerable time can elapse between the %@AB@%VM_Not_Executeable%@AE@% call and this
  2569. call. Call cannot be failed. VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is not
  2570. allowed.  %@NL@%
  2571.  
  2572.  
  2573. %@2@%%@CR:C6A00170050 @%%@AB@%17.5  Exiting Windows%@AE@%%@EH@%%@NL@%
  2574.  
  2575. There are two calls that can alert a VxD that enhanced Windows is exiting:
  2576. %@AB@%System_Exit%@AE@% and %@AB@%Sys_Critical_Exit%@AE@%. They both come after %@AB@%Sys_VM_Terminate%@AE@%, is
  2577. Windows is exiting normally.  %@NL@%
  2578.  
  2579.  
  2580. %@4@%%@AB@%System_Exit%@AE@%%@EH@%%@NL@%
  2581.  
  2582. This call is made when Windows is exiting either normally or via a crash.
  2583. Interrupts are enabled. System VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is not
  2584. allowed. However, the VxD may modify the System VM memory to restore the
  2585. system state to allow a graceful exiting of Windows.  %@NL@%
  2586.  
  2587.  
  2588. %@4@%%@AB@%Sys_Critical_Exit%@AE@%%@EH@%%@NL@%
  2589.  
  2590. This call is made when enhanced Windows is exiting either normally or via a
  2591. crash. Interrupts are disabled. %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is not
  2592. allowed. VxDs should reset their associated hardware to a quiescent state to
  2593. allow a graceful return to real mode.  %@NL@%
  2594.  
  2595.  
  2596. %@2@%%@CR:C6A00170051 @%%@AB@%17.6  Debugging a VxD%@AE@%%@EH@%%@NL@%
  2597.  
  2598. Their are a number of features built into the WDEB386 debugger and the
  2599. debugging version of the 386 enhanced mode environment to aid you in
  2600. debugging your VxD. These features require a terminal hooked up to a COM
  2601. port, as described in the WDEB386 documentation in the Microsoft SDK. When
  2602. making use of these features in your code, be sure to remove them from your
  2603. final product. See DEBUG.INC for useful macros and the sample source for
  2604. usage.  %@NL@%
  2605.  
  2606.  
  2607. %@3@%%@CR:C6A00170052 @%%@AB@%17.6.1  Entering WDEB386%@AE@%%@EH@%%@NL@%
  2608.  
  2609. There are four ways to initially enter the debugger:  %@NL@%
  2610.  
  2611.  
  2612.   1.  Type CTL+ALT+SYSREQ.%@NL@%
  2613.  
  2614.   2.  Generate a non-maskable interrupt (this can be disabled with the "V2"
  2615.       command).%@NL@%
  2616.  
  2617.   3.  Place an "INT 1" instruction in your code. This method should be used
  2618.       when debugging the real-mode portion of your VxD. An "INT 3" may also
  2619.       be used but the debugger will not automatically pass over it. %@NL@%
  2620.  
  2621.   4.  Specify "\b" as a command line parameter to WDEB386. This will pass
  2622.       control to the debugger just prior to VMM initialization, after all
  2623.       VxDs have been loaded and the processor is running in protected mode.%@NL@%
  2624.  
  2625.  
  2626.  
  2627. %@3@%%@CR:C6A00170053 @%%@AB@%17.6.2  Tracing Paths of Execution%@AE@%%@EH@%%@NL@%
  2628.  
  2629. You can dump strings of text and registers in hexadecimal to the debug
  2630. terminal utilizing the %@AB@%TRACE_OUT%@AE@% and %@AB@%DEBUG_OUT%@AE@% macros.  %@NL@%
  2631.  
  2632. The %@AB@%Queue_out%@AE@% macro allows you to dump the same information to a trace
  2633. queue. You can also send VMM entry and exit information to the queue by
  2634. using the ".t" command, and send procedure logging information with the .VMM
  2635. command.  %@NL@%
  2636.  
  2637. %@AB@%Trace_Out%@AE@% and %@AB@%Debug_Out%@AE@% strings have the following special characters
  2638. defined:  %@NL@%
  2639.  
  2640. %@AS@%  #<register>, where 
  2641. %@AS@%  <register> is a 32 bit register, a 16 bit register
  2642. %@AS@%      or AL, BL, CL or DL. This will insert the hex value for
  2643. %@AS@%      the indicated register into the string that is output at
  2644. %@AS@%      the location where #<register> appears. 
  2645. %@AS@%  ?[<16 bit register>:]<32 bit register>, where the 16 bit register is
  2646. %@AS@%      a selector and the 32 bit register is an offset within
  2647. %@AS@%      that selector. If the 16 bit register is not specified,
  2648. %@AS@%      then 28h, the VxD code segment, is assumed. This will insert
  2649. %@AS@%      the symbol table name of the closest previous symbol
  2650. %@AS@%      corresponding to the address specified. If no symbol is
  2651. %@AS@%      found, nothing is printed (e.g. ?AX:EBX).%@AE@%
  2652.  
  2653. Additionally, a VxD can put data into the trace queue that is listed with
  2654. the .LQ command. To do this use the %@AB@%Queue_Out%@AE@% macro:  %@NL@%
  2655.  
  2656. %@AS@%  Queue_Out "<string>"[,<reg1>[,<reg2>»%@AE@%
  2657.  
  2658. where reg1 and reg2 are 32-bit registers. Reg1 will be in the %@AB@%EAX%@AE@% register
  2659. when the string is printed and Reg2 will be in the %@AB@%EBX%@AE@% register. You can use
  2660. the special "#" and "?" characters in the string, identifying %@AB@%EAX%@AE@% (or a
  2661. subset of E%@AB@%AX%@AE@%) and %@AB@%EBX%@AE@% (or a subset) to insert the values of reg1 and reg2
  2662. in the string. By default, reg1=%@AB@%EAX%@AE@% and reg2=%@AB@%EBX%@AE@%. The default is used if you
  2663. do not specify the parameters to the macro.  %@NL@%
  2664.  
  2665.  
  2666. %@3@%%@CR:C6A00170054 @%%@AB@%17.6.3  Querying the VxD State%@AE@%%@EH@%%@NL@%
  2667.  
  2668. As described previously, one of the messages sent to the %@AB@%VxD_Control%@AE@% routine
  2669. is %@AB@%Debug_Query%@AE@%. This message is passed when you type ". name" to WDEB386.
  2670. See the sample sources for examples on how to use trace-out and the
  2671. %@AB@%In_Debug_Chr%@AE@% service to generate useful debugging information.  %@NL@%
  2672.  
  2673. The .VMM command will give you a menu of useful information on the state of
  2674. the system as well as a way to toggle procedure logging.  %@NL@%
  2675.  
  2676.  
  2677.  
  2678.  
  2679.  
  2680.  
  2681. %@CR:C6A00180001 @%%@1@%%@AB@%Chapter 18  The VDD and Grabber DLL%@AE@%%@EH@%%@NL@%
  2682. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2683.  
  2684. This chapter describes the Virtual Display Device (VDD) and the Grabber DLL,
  2685. a Microsoft Windows dynamic-link library. Software writers should be
  2686. familiar with the terms and concepts covered in Chapter 16, "Overview of
  2687. Windows in 386 Enhanced Mode," and Chapter 17, "Virtual Device Programming
  2688. Topics," before continuing with this chapter.  %@NL@%
  2689.  
  2690. The topics in this chapter are presented in the following order:  %@NL@%
  2691.  
  2692.  
  2693.   ■   Introduction to VDDs and the Grabber DLL%@NL@%
  2694.  
  2695.   ■   VDD programming and the Grabber API%@NL@%
  2696.  
  2697.   ■   Grabber DLL interfaces
  2698. %@NL@%
  2699.  
  2700.  
  2701.  
  2702. %@2@%%@CR:C6A00180002 @%%@AB@%18.1  Introduction to VDDs and the Grabber DLL%@AE@%%@EH@%%@NL@%
  2703.  
  2704. The VDD and Grabber DLL are used by Windows when running in enhanced mode to
  2705. support a video adapter. The %@AI@%VDD%@AE@% is the virtual device that emulates display
  2706. hardware for applications running in virtual machines. The %@AI@%Grabber%@AE@%, like all
  2707. dynamic-link libraries, provides a library of routines available to
  2708. application programs. In this case, the application is the Windows WINOLDAP
  2709. program, and the routines are used primarily for rendering the video display
  2710. of a non-Windows application into a format that Windows can use.  %@NL@%
  2711.  
  2712. The Windows 3.0 DDK provides source code for a variety of VDDs and Grabbers.
  2713. These should prove valuable as stubs and examples.  %@NL@%
  2714.  
  2715.  
  2716. %@3@%%@CR:C6A00180003 @%%@AB@%18.1.1  VDD Interaction with WINOLDAP%@AE@%%@EH@%%@NL@%
  2717.  
  2718. When Windows detects the user starting a non-Windows application, it runs
  2719. the Windows program called WINOLDAP and passes the name of the application
  2720. to it. WINOLDAP searches for a .PIF file and, then, makes a call to the
  2721. Shell device with all the parameters necessary to execute the application in
  2722. a new VM. The Shell makes a series of system control calls with the
  2723. appropriate messages to create and start the VM. It also calls the
  2724. %@AB@%VDD_PIF_State%@AE@% and %@AB@%VDD_Set_VM_Type%@AE@% services to let the VDD know the user
  2725. preferences for this VM.  %@NL@%
  2726.  
  2727. WINOLDAP also loads the Grabber DLL, which it uses for rendering the VM's
  2728. display into the Windows display driver's bitmap format. The rendering is
  2729. done both for a full screen grab into the Clipboard (the VDD's grab routine
  2730. is called when this is done), and for displaying the VM in a window. This
  2731. rendering occurs in response to changes in video state caused by either the
  2732. VM's application or the user.  %@NL@%
  2733.  
  2734. %@TH:  29  1667 02 27 27 27 @%
  2735. Cause of video state                                  
  2736. change                     Example                    Effect
  2737. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2738. Application Program        Updating displayed         VDD sends WINOLDAP a 
  2739.                            information                screen update message.
  2740.  
  2741.                                                       WINOLDAP calls the 
  2742.                                                       Grabber to update the 
  2743.                                                       window.
  2744.  
  2745.                                                       Grabber calls the VDD to 
  2746.                                                       render the video state 
  2747.                                                       into the application's 
  2748.                                                       window.
  2749.  
  2750. User Action                Resizing a window          Windows sends WINOLDAP a 
  2751.                                                       paint message.
  2752.  
  2753.                                                       WINOLDAP calls the 
  2754.                                                       Grabber to paint the 
  2755.                                                       window.
  2756.  
  2757.                                                       Grabber calls the VDD to 
  2758.                                                       render the video state 
  2759.                                                       into the application's 
  2760.                                                       window.
  2761.  
  2762. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2763.  
  2764. %@TE:  29  1667 02 27 27 27 @%
  2765.  
  2766. Notice that the Grabber can be reentered. WINOLDAP may be in the process of
  2767. handling a paint message when it receives an update message. Care must be
  2768. exercised to ensure the correct handling of all the possible cases.  %@NL@%
  2769.  
  2770.  
  2771. %@3@%%@CR:C6A00180004 @%%@AB@%18.1.2  VDD User Messages%@AE@%%@EH@%%@NL@%
  2772.  
  2773. When the VDD encounters a situation that requires a user's choice or
  2774. interaction, it uses the Shell message services to print messages. For
  2775. example, when there is not enough memory to save and restore a VM's video
  2776. state, the user is informed of the problem and that a portion of the display
  2777. may be lost.  %@NL@%
  2778.  
  2779. Messages are sent while in %@AI@%message mode%@AE@%, which is instigated with the
  2780. %@AB@%Begin_Message_Mode%@AE@% control call. Message mode enables the Shell device to
  2781. use the VDD message services to output text to the screen without changing
  2782. the VM's video state. When the message is complete, an %@AB@%End_Message_Mode%@AE@%
  2783. control call is made that restores the focus VM to the hardware. See Section
  2784. 18.2.3, "Environment State Change Requirements for a VDD," for a description
  2785. of the message mode services.%@CR:C6A00180005 @%%@AI@%  %@AE@%%@NL@%
  2786.  
  2787.  
  2788. %@3@%%@CR:C6A00180006 @%%@AB@%18.1.3  VDD I/O Trapping and Hooked Pages%@AE@%%@EH@%%@NL@%
  2789.  
  2790. When an application is running in the background, the VDD traps all the
  2791. video I/O, saving the output port values and emulating the input port
  2792. values. In some cases, the detection of a mode change can result. In this
  2793. case, the memory should be disabled and hooked to enable the page fault
  2794. service to remap the memory.  %@NL@%
  2795.  
  2796. A VDD should detect mode changes and illegal memory accesses. This is done
  2797. by disabling and hooking page faults that occur when the video memory is
  2798. accessed by the VM. The page fault service determines how to map the
  2799. accessed memory by both determining whether or not the VM has the display
  2800. focus and by examining the VM's virtual controller state. The page fault
  2801. service can also be used to demand page the video memory. It restores and
  2802. maps the video pages needed to create the physical display and to satisfy
  2803. the application's video memory accesses.  %@NL@%
  2804.  
  2805.  
  2806. %@3@%%@CR:C6A00180007 @%%@AB@%18.1.4  Grabber Naming Conventions%@AE@%%@EH@%%@NL@%
  2807.  
  2808. The names of the various supplied grabbers indicate in which mode they are
  2809. designed to run. For real and standard mode Windows, grabbers are named
  2810. %@AI@%FOO.GR2%@AE@%. For 386 enhanced mode Windows, they are named %@AI@%FOO.GR3.  %@AE@%%@NL@%
  2811.  
  2812.  
  2813. %@2@%%@CR:C6A00180008 @%%@AB@%18.2  VDD Programming%@AE@%%@EH@%%@NL@%
  2814.  
  2815. In addition to Chapter 17, "Virtual Device Programming Topics," which
  2816. discusses the general requirements for writing a VxD, valuable information
  2817. for the VDD author is located in Chapter 35, "Virtual Display Device (VDD)
  2818. Services."  %@NL@%
  2819.  
  2820. The following are the recommended steps for developing a VDD:  %@NL@%
  2821.  
  2822.  
  2823.   1.  Build a skeleton. Using the supplied sources as a guide, build a
  2824.       skeleton of the VDD with all the services and API procedures defined
  2825.       but not functional.%@NL@%
  2826.  
  2827.   2.  Add the initialization functionality, including the control block
  2828.       allocation, global memory needed, physical page hooking, I/O hooking,
  2829.       and interrupt hooking.%@NL@%
  2830.  
  2831.   3.  Fill out the services that handle the various hooks.%@NL@%
  2832.  
  2833.   4.  Test it while running Windows and other VMs, full screen.%@NL@%
  2834.  
  2835.   5.  Implement the Grabber API, including the procedures that report
  2836.       controller state, return video memory structures, and report video
  2837.       state modifications.%@NL@%
  2838.  
  2839.   6.  Test it while running VMs in a window. Do a thorough test, running
  2840.       many different applications in all the different states (i.e.,
  2841.       exclusive, background, and windowed), while using ALT+TAB and directed
  2842.       hot keys to switch VMs. Be sure to test various error conditions such
  2843.       as being out of memory.%@AI@%%@AE@%%@NL@%
  2844.  
  2845.  
  2846.  
  2847. %@3@%%@CR:C6A00180009 @%%@AB@%18.2.1  VDD Efficiency%@AE@%%@EH@%%@NL@%
  2848.  
  2849. To maximize the efficiency of Windows, a VDD is, in many cases, tightly
  2850. coupled with the Windows 3.0 display driver. For instance, the EGA display
  2851. would normally have to be trapped at all times to maintain the controller
  2852. state properly. Instead, an API has been defined for communications between
  2853. the Windows display driver and the VDD. Additionally, the EGA Windows
  2854. display driver uses a special portion of video memory and a special
  2855. algorithm that allows for a subset of the video controller state to be saved
  2856. and restored without explicitly saving away the current register values.
  2857. When adapting a VDD to new displays, it is a good idea to look at
  2858. alternatives to trapping all the display adapter access to maintain the
  2859. video state. Notice also that the Grabber is usually tightly coupled to the
  2860. Windows display driver, specifically to the display-dependent bitmap format.
  2861. %@NL@%
  2862.  
  2863. There are three PIF bits that the user can specify to disable trapping in
  2864. VMs where the applications running in the VMs only modify registers that can
  2865. be read. The VDD designer should use these PIF bits, if possible. There are
  2866. additional PIF bits by which the user can specify the amount of video memory
  2867. a VM will need. See the %@AI@%Microsoft Windows User's Guide%@AE@% for more information
  2868. on PIF files.  %@NL@%
  2869.  
  2870. Another good area in which to consider optimizing is the API emulation,
  2871. especially the INT 10H %@AB@%Write TTY%@AE@% function. The user can specify this
  2872. emulation with a PIF bit.  %@NL@%
  2873.  
  2874.  
  2875. %@3@%%@CR:C6A00180010 @%%@AB@%18.2.2  Converting Your 2.x VDD%@AE@%%@EH@%%@NL@%
  2876.  
  2877. Even though the general structure of Windows 3.0 VxDs is significantly
  2878. different from 2.x versions, the low-level VDD routines of previous
  2879. versions, such as the saving, restoring, and trapping routines, should work
  2880. with little modification. However, significant changes have occured in how
  2881. VxDs interact with the operating environment. For example, the VDD is now a
  2882. separate .386 file linked dynamically to 386 enhanced mode Windows.
  2883. Therefore, a recommended development strategy is to insert the 2.x routines
  2884. into one of the supplied 3.0 VDD sources.  %@NL@%
  2885.  
  2886. The 3.0 Grabber's interface with WINOLDAP and the VDD is also different. The
  2887. most significant change is that in version 2.x the Grabber was not a DLL.
  2888. See Section 18.3, "Grabber DLL Interfaces," for more detailed information.  %@NL@%
  2889.  
  2890. The following topics describe areas of a 2.x VDD that will require
  2891. modification.  %@NL@%
  2892.  
  2893.  
  2894. %@4@%%@AB@%INCLUDE Files%@AE@%%@EH@%%@NL@%
  2895.  
  2896. Most of the modules only need VMM.INC, VDD.INC, DEBUG.INC, and a device
  2897. specific INCLUDE file (e.g., EGA.INC). Some modules also require a file
  2898. describing the interface between them and some external user of their
  2899. functions (e.g., VMDAEGA.INC for the Grabber). By changing over to the new
  2900. INCLUDE files, you will generate several undefined references. Modifying the
  2901. references to use the equivalent Windows 3.0 functionality is a first step
  2902. in creating your Windows 3.0 VDD.  %@NL@%
  2903.  
  2904.  
  2905. %@4@%%@AB@%System Interface%@AE@%%@EH@%%@NL@%
  2906.  
  2907. Examine the parts of the supplied Windows 3.0 VDD to understand the new
  2908. system interface. You will need the %@AB@%VDD_Init%@AE@%, %@AB@%VDD_New%@AE@%, %@AB@%VDD_Exit%@AE@%,
  2909. %@AB@%VDD_Destroy%@AE@%, %@AB@%VDD_SetType%@AE@%, and %@AB@%VDD_SetFocus%@AE@% services to use the new device
  2910. control interface. The functionality of %@AB@%VDD_Install%@AE@% should be handled by
  2911. scheduling VM events. The %@AB@%VDD_Mem_Check%@AE@% service is replaced by the VDD
  2912. specifically calling the Shell to give the user a message. %@AB@%VDD_CHK_Device%@AE@% is
  2913. also replaced by sending WINOLDAP a message when the display needs to be
  2914. updated and by scheduling time outs to do the detection. The register values
  2915. and what you can and cannot do in an I/O trap, page fault, and interrupt
  2916. trap are also changed. Mostly, there is much more flexibility allowed, and
  2917. there are changes in register save/restore and parameter passing
  2918. conventions.  %@NL@%
  2919.  
  2920. Previously, VDD provided a single %@AB@%VDD_Control%@AE@% with various subfunctions.
  2921. Most of the %@AB@%VDD_Control%@AE@% calls are replaced by the device API mechanism.  %@NL@%
  2922.  
  2923. Notice that the definition of %@AI@%exclusive%@AE@% is different for Windows 3.0 and
  2924. that the %@AB@%SetFocus%@AE@% service takes into account whether or not the VM is
  2925. running in a window (i.e., VDD will get a %@AB@%SetFocus%@AE@% call for the System VM on
  2926. a VM that is running in a window, instead of a %@AB@%SetFocus%@AE@% call to the VM
  2927. itself).  %@NL@%
  2928.  
  2929.  
  2930. %@4@%%@AB@%Shell%@AE@%%@EH@%%@NL@%
  2931.  
  2932. The Shell device requires a number of new functions that are implemented as
  2933. device services. Additionally, the old ID call is device service 0.  %@NL@%
  2934.  
  2935.  
  2936. %@4@%%@AB@%Grabber%@AE@%%@EH@%%@NL@%
  2937.  
  2938. Notice that the way that the services retrieve the Grabber DLL's registers
  2939. is different (i.e., by using %@AB@%EBP%@AE@% and the %@AB@%Client_Reg%@AE@% definitions). Also
  2940. notice the increased number of functions and other changes in the
  2941. functionality of the Grabber DLL interface.  %@NL@%
  2942.  
  2943.  
  2944. %@4@%%@AB@%Memory Access%@AE@%%@EH@%%@NL@%
  2945.  
  2946. Use the %@AB@%_MapPhysToLinear%@AE@% function rather than adding %@AB@%PhysToLinr%@AE@% to the
  2947. physical addresses. You should also add the control block value
  2948. %@AB@%CB_High_Linear%@AE@% to the BIOS memory address for accessing those memory
  2949. locations.  %@NL@%
  2950.  
  2951. Since memory in the control block is allocated dynamically, the address of
  2952. your portion of the control block must be formed at run time, not compile
  2953. time.  %@NL@%
  2954.  
  2955.  
  2956. %@3@%%@CR:C6A00180011 @%%@AB@%18.2.3  Environment State Change Requirements for a VDD%@AE@%%@EH@%%@NL@%
  2957.  
  2958. During Windows initialization, VM creation and termination, and other status
  2959. changes of the Windows environment, there are certain programming
  2960. requirements for display devices. The following includes descriptions of
  2961. typical requirements for various states. Use the EGA/VGA and CGA sources as
  2962. examples. Specific interfaces to the described routines are included in
  2963. Section 17.1, "Writing VxDs."  %@NL@%
  2964.  
  2965.  
  2966. %@4@%%@AB@%Real Mode Initialization%@AB@%%@AE@%%@AE@%%@EH@%%@NL@%
  2967.  
  2968. Most video adapters will not need any real-mode code to be functional.
  2969. However, a few developers will want to add some real-mode code to query
  2970. device state or to reserve portions of memory that may not be touched during
  2971. the initialization of other devices or used for general system purposes. For
  2972. example, you may have a memory-mapped interface that will be harmed by other
  2973. code reading and writing at those addresses (Windows in 386 enhanced mode
  2974. searches the area between C0000H and EFFFFH for the existence of RAM or
  2975. ROM). If the VDD supports multiple display adapters, display-adapter
  2976. detection can be done here by passing the result of the detection in the %@AB@%EDX%@AE@%
  2977. register to the protected-mode initialization.  %@NL@%
  2978.  
  2979.  
  2980. %@4@%%@AB@%Sys_Critical_Init%@AE@%%@EH@%%@NL@%
  2981.  
  2982. During %@AB@%Sys_Critical_Init%@AE@%, a VDD should allocate its control block data area,
  2983. allocate V86 address space, allocate memory needed globally, and initialize
  2984. any pointers or other data that are required for the VDD functionality.
  2985. Remember that interrupts are disabled during this call, so keep it as short
  2986. as possible.  %@NL@%
  2987.  
  2988.  
  2989. %@4@%%@AB@%Device_Init%@AE@%%@EH@%%@NL@%
  2990.  
  2991. During %@AB@%Device_Init%@AE@%, a VDD should finish initializing its global state, set
  2992. up the I/O and interrupt trapping needed, and specify instance data. As
  2993. noted in Chapter 16, "Overview of Windows in 386 Enhanced Mode," this
  2994. initialization call is equivalent to %@AB@%VMCreate%@AE@% for the System VM, along with
  2995. the global device initialization. Finally, the VDD should set the display
  2996. focus to the system VM internally.  %@NL@%
  2997.  
  2998.  
  2999. %@4@%%@AB@%Init_Complete%@AE@%%@EH@%%@NL@%
  3000.  
  3001. During %@AB@%Init_Complete%@AE@%, a VDD should do any consistency checks that have to be
  3002. done after all the other devices have completed their initialization.
  3003. Normally, a VDD will not need to do anything with this control call.  %@NL@%
  3004.  
  3005.  
  3006. %@4@%%@AB@%Sys_VM_Init%@AE@%%@EH@%%@NL@%
  3007.  
  3008. During %@AB@%Sys_VM_Init%@AE@%, a VDD should initialize the rest of the control block
  3009. data for the system VM, and set the display focus to the system VM.  %@NL@%
  3010.  
  3011.  
  3012. %@4@%%@AB@%VM_Create%@AE@%%@EH@%%@NL@%
  3013.  
  3014. During creation, initialize the control block and allocate any VM specific
  3015. memory. If the allocation fails, return the Carry flag set to abort the VM
  3016. creation.  %@NL@%
  3017.  
  3018.  
  3019. %@4@%%@AB@%VM_Init%@AE@%%@EH@%%@NL@%
  3020.  
  3021. During initialization, set the video state of the VM, typically by making
  3022. calls to the Video BIOS and trapping the I/O to set up the video state
  3023. structure.  %@NL@%
  3024.  
  3025.  
  3026. %@4@%%@AB@%Destroy_VM%@AE@%%@EH@%%@NL@%
  3027.  
  3028. During destruction, deallocate any memory allocated for the VM and make sure
  3029. that there are no pointers left that refer to the destroyed VM.  %@NL@%
  3030.  
  3031.  
  3032. %@4@%%@AB@%Set_Device_Focus%@AE@%%@EH@%%@NL@%
  3033.  
  3034. The %@AB@%SetFocus%@AE@% service is responsible for giving the specified VM the physical
  3035. display. Notice that there is display %@AB@%SetFocus%@AE@% and critical %@AB@%SetFocus%@AE@%. Both
  3036. should give the physical display to the indicated VM. Also notice that the
  3037. actual restoring of the physical display should occur by executing the
  3038. %@AB@%VDD_Restore%@AE@% service as an event.  %@NL@%
  3039.  
  3040.  
  3041. %@4@%%@AB@%VM_Suspend%@AE@%%@EH@%%@NL@%
  3042.  
  3043. During %@AB@%VM_Suspend%@AE@%, a VDD should unlock any memory associated with the VM,
  3044. such as the memory used to save and restore the video state.  %@NL@%
  3045.  
  3046.  
  3047. %@4@%%@AB@%VM_Resume%@AE@%%@EH@%%@NL@%
  3048.  
  3049. During %@AB@%VM_Resume%@AE@%, a VDD should lock the memory unlocked during suspend.  %@NL@%
  3050.  
  3051.  
  3052. %@4@%%@AB@%System_Exit%@AE@%%@EH@%%@NL@%
  3053.  
  3054. During %@AB@%System_Exit%@AE@%, a VDD should return the display to the state it should
  3055. be in when Windows returns to MS-DOS.  %@NL@%
  3056.  
  3057.  
  3058. %@4@%%@AB@%Sys_Critical_Exit%@AE@%%@EH@%%@NL@%
  3059.  
  3060. During %@AB@%Sys_Critical_Exit%@AE@%, a VDD should restore any hooks remaining in the
  3061. V86 memory.  %@NL@%
  3062.  
  3063.  
  3064. %@4@%%@AB@%Begin_Message_Mode%@AE@%%@EH@%%@NL@%
  3065.  
  3066. After saving the current VM's video state, the VDD should put the display
  3067. adapter into a known text mode. If this is called prior to the point in
  3068. initialization (System VM Initialization) at which a known text mode has
  3069. been saved, call the video BIOS to set up the correct mode.  %@NL@%
  3070.  
  3071. The message mode services, %@AB@%VDD_Msg_ClrScrn%@AE@%, %@AB@%VDD_Msg_ForColor%@AE@%,
  3072. %@AB@%VDD_Msg_BakColor%@AE@%, %@AB@%VDD_Msg_TextOut%@AE@%, and %@AB@%VDD_Msg_SetCursPos%@AE@% are only used
  3073. after the %@AB@%Begin_Message_Mode%@AE@% message has been received. See Chapter 35,
  3074. "Virtual Display Device (VDD) Services," for details.  %@NL@%
  3075.  
  3076.  
  3077. %@4@%%@AB@%End_Message_Mode%@AE@%%@EH@%%@NL@%
  3078.  
  3079. During %@AB@%End_Message_Mode%@AE@%, a VDD should restore the focus VM's video state.  %@NL@%
  3080.  
  3081.  
  3082. %@4@%%@AB@%Debug_Query%@AE@%%@EH@%%@NL@%
  3083.  
  3084. In a debug version of your VDD, use the %@AB@%Trace_Out%@AE@% macro to list the current
  3085. display owner, other potentially interesting global data, and the video
  3086. state for each VM.  %@NL@%
  3087.  
  3088.  
  3089. %@3@%%@CR:C6A00180012 @%%@AB@%18.2.4  Grabber API%@AE@%%@EH@%%@NL@%
  3090.  
  3091. The Grabber uses the VDD's %@AB@%Get_Version%@AE@% service to verify that it is matched
  3092. with the correct VDD. Whenever the Grabber needs access to the video memory
  3093. or the video controller state, it queries the VDD. The VDD returns a data
  3094. structure describing the requested memory or controller state.  %@NL@%
  3095.  
  3096. %@AB@%Get_Mem%@AE@% is used to get the current contents of the video memory while
  3097. updating the windowed display. %@AB@%Get_GrbMem%@AE@% is used to get a snapshot of the
  3098. entire screen in response to an ALT + PRTSCN command from the user in a full
  3099. screen VM. %@AB@%Free_Mem%@AE@% and %@AB@%Free_Grab%@AE@% are used to tell the VDD that the grabber
  3100. is no longer using this memory. %@AB@%Get_State%@AE@% and %@AB@%Get_GrbState%@AE@% return the
  3101. current and grabbed controller states, respectively.  %@NL@%
  3102.  
  3103. %@AB@%Get_Mod%@AE@% is used to update the windowed display incrementally. %@AB@%Get_Mod%@AE@%
  3104. returns a data structure that indicates modifications to the current
  3105. display. The Grabber DLL modifies only those parts of the window that have
  3106. changed and, then, issues a %@AB@%Clear_Mod%@AE@% call to inform the VDD that the
  3107. modifications have been carried out.  %@NL@%
  3108.  
  3109. To make sure that the video memory or state will not change when the Grabber
  3110. is accessing the memory, the VM should not be running after a %@AB@%Get_Mem%@AE@% or
  3111. %@AB@%Get_Mod%@AE@% call. The VM can continue to run only after a %@AB@%Free_Mem%@AE@% call or an
  3112. explicit %@AB@%Unlock_App%@AE@% call from the Grabber.  %@NL@%
  3113.  
  3114.  
  3115. %@2@%%@CR:C6A00180013 @%%@AB@%18.3  Grabber DLL Interfaces%@AE@%%@EH@%%@NL@%
  3116.  
  3117. The Grabber is a dynamic-link library (DLL) primarily responsible for
  3118. representing the VM's display state to the Windows display driver. It is the
  3119. library of functions used by WINOLDAP, the Windows program responsible for
  3120. creating, destroying, and changing the state of VMs. WINOLDAP makes private
  3121. calls to the Shell device, which in turn calls the necessary VMM services.
  3122. Therefore, it is WINOLDAP, using the Grabber (and through it the Windows
  3123. display driver), that is actually responsible for windowing the display
  3124. state of a VM.  %@NL@%
  3125.  
  3126. Each of the Grabber functions is a %@AB@%cProc%@AE@% and has to be exported. The
  3127. function code can be shared by several instances of WINOLDAP, and therefore,
  3128. the placement of VM-specific data must be deliberate. The Grabber DLL
  3129. functions provide support for the following:  %@NL@%
  3130.  
  3131.  
  3132.   ■   Screen grabbing%@NL@%
  3133.  
  3134.   ■   Marking and selecting%@NL@%
  3135.  
  3136.   ■   Painting non-Windows applications in a window%@NL@%
  3137.  
  3138.   ■   Doing other miscellaneous functions%@NL@%
  3139.  
  3140.  
  3141. The Grabber generates data in the following situations:  %@NL@%
  3142.  
  3143.  
  3144.   ■   When an Extended Paint structure (EXTPAINTSTRUC) is passed from
  3145.       WINOLDAP%@NL@%
  3146.  
  3147.   ■   When a procedure requires local data. (Local data is maintained on the
  3148.       stack.)%@CR:C6A00180014 @%%@CR:C6A00180015 @%%@NL@%
  3149.  
  3150.  
  3151.  
  3152. %@3@%%@CR:C6A00180016 @%%@AB@%18.3.1  On-Screen Selection Functions%@AE@%%@EH@%%@NL@%
  3153.  
  3154. The user can make on-screen selections with either the keyboard or mouse, or
  3155. through a hot key. The keyboard or mouse are used only while in a window; a
  3156. hot key (ALT+PRTSCRN) is used while in full-screen or windowed mode.  %@NL@%
  3157.  
  3158. The functions that handle on-screen selections are as follows:  %@NL@%
  3159.  
  3160.  
  3161.   ■   %@AB@%BeginSelection%@AE@%%@NL@%
  3162.  
  3163.   ■   %@AB@%EndSelection%@AE@%%@NL@%
  3164.  
  3165.   ■   %@AB@%KeySelection%@AE@%%@NL@%
  3166.  
  3167.   ■   %@AB@%AdjustInitEndPt%@AE@%%@NL@%
  3168.  
  3169.   ■   %@AB@%MakeSelctRect%@AE@%%@NL@%
  3170.  
  3171.  
  3172. To perform a selection by using the keyboard, the user performs the
  3173. following steps:  %@NL@%
  3174.  
  3175.  
  3176.   1.  Choose the Mark command.%@NL@%
  3177.  
  3178.   2.  Move the cursor to the start point of the selection.%@NL@%
  3179.  
  3180.   3.  Sweep through a selection using SHIFT + DIRECTION keys.%@NL@%
  3181.  
  3182.   4.  Press ENTER to end a selection and copy it to the Clipboard (or press
  3183.       ESC to end the selection without a copy).%@NL@%
  3184.  
  3185.  
  3186. On choosing Mark from the menu, %@AB@%BeginSelection%@AE@% gets called with argument
  3187. <0,0>.  %@NL@%
  3188.  
  3189. During the first phase, the cursor is moved to the actual start point.
  3190. %@AB@%KeySelection%@AE@% handles the cursor movement. It returns the new start point
  3191. every time a DIRECTION key is pressed. Notice that the selection could
  3192. potentially begin at each cursor position. Therefore, every time the start
  3193. point is changed, %@AB@%EndSelection%@AE@% is called to cancel the previous selection,
  3194. and %@AB@%BeginSelection%@AE@% is called with the new start point.  %@NL@%
  3195.  
  3196. Once the cursor is positioned at the actual start point, the user sweeps
  3197. through a selection area using SHIFT+DIRECTION keys. %@AB@%KeySelection%@AE@% handles
  3198. the cursor movement. It returns the new end point of the selection. Now each
  3199. call to %@AB@%KeySelection%@AE@% is followed by a call to %@AB@%MakeSelctRect%@AE@% to record the
  3200. current selection rectangle. On pressing ENTER, the actual end point and the
  3201. final selection rectangle are established.  %@NL@%
  3202.  
  3203. Therefore, the last call to %@AB@%BeginSelection%@AE@% establishes the actual start
  3204. point, the last call to %@AB@%KeySelection%@AE@% returns the actual end point, and the
  3205. final call to %@AB@%MakeSelctRect%@AE@% records the actual selection rectangle. If only
  3206. DIRECTION keys are pressed, the user is shifting the start point. If
  3207. SHIFT+DIRECTION keys are pressed, the user is changing the active end point.
  3208. %@NL@%
  3209.  
  3210. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3211. NOTE
  3212.  
  3213. %@AI@%The start point and the end point of a selection have to be aligned on
  3214. %@AI@%character boundaries in text mode. In graphics mode, the Grabber chooses
  3215. %@AI@%some granularity for cursor movement (e.g., DWORD of pixels).%@AE@%
  3216. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3217.  
  3218. The coordinates of the start point and the end point are given in screen
  3219. coordinates ─ a window client area position corrected by the scroll bar
  3220. position. Client area coordinate = <0,0> corresponds to the screen
  3221. coordinate <ColOrg,RowOrg>. (ColOrg and RowOrg are available in the extended
  3222. paint structure.)  %@NL@%
  3223.  
  3224.  
  3225. %@3@%%@CR:C6A00180017 @%%@AB@%18.3.2  Selection Functions%@AE@%%@EH@%%@NL@%
  3226.  
  3227. This section presents descriptions of the selection functions in
  3228. alphabetical order.  %@NL@%
  3229.  
  3230. %@CR:C6A00180018 @%
  3231. %@2@%%@CR:C6A00180019 @%%@AB@%AdjustInitEndPt%@CR:C6A00180020 @%%@AE@%%@EH@%%@NL@%
  3232. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3233.  
  3234.  
  3235. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3236.  
  3237. This function adjusts the initial selection end point. To start off, the
  3238. start point and the end point are the same. (This is how %@AB@%BeginSelection%@AE@%
  3239. records them). On the first SHIFT + DIRECTION key call to %@AB@%KeySelection%@AE@%,
  3240. notice that %@AB@%KeySelection%@AE@% returns the wrong end point. This function returns
  3241. the correct end point. It returns (X+DELTAx, Y+DELTAy) where <X,Y > is the
  3242. given end point. DELTAx and DELTAy are as defined in %@AB@%KeySelection%@AE@%.  %@NL@%
  3243.  
  3244.  
  3245. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3246.  
  3247. lpPntStruct = EXTPAINTSTRUC  %@NL@%
  3248.  
  3249. YCoOrd,XCoOrd = (Y,X) point to be adjusted  %@NL@%
  3250.  
  3251.  
  3252. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3253.  
  3254. %@AB@%DX%@AE@%,%@AB@%AX%@AE@% = (Y,X) end point adjust down and to right for initial selection.  %@NL@%
  3255.  
  3256. %@CR:C6A00180021 @%
  3257. %@2@%%@CR:C6A00180022 @%%@AB@%BeginSelection%@CR:C6A00180023 @%%@AE@%%@EH@%%@NL@%
  3258. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3259.  
  3260.  
  3261. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3262.  
  3263. This function starts the selection at the indicated point.  %@NL@%
  3264.  
  3265.  
  3266. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3267.  
  3268. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3269.  
  3270. YCoOrd,XCoOrd = (Y,X) screen coord of start pt  %@NL@%
  3271.  
  3272.  
  3273. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3274.  
  3275. [lpPntStruc.SelStruc.SelctSRect] Display rectangle in the EXTPAINTSTRUC
  3276. selection structure set  %@NL@%
  3277.  
  3278. %@CR:C6A00180024 @%
  3279. %@2@%%@CR:C6A00180025 @%%@AB@%ConsSelecRec%@CR:C6A00180026 @%%@AE@%%@EH@%%@NL@%
  3280. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3281.  
  3282.  
  3283. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3284.  
  3285. This function makes the display rectangle consistent with the selection.  %@NL@%
  3286.  
  3287.  
  3288. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3289.  
  3290. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3291.  
  3292.  
  3293. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3294.  
  3295. [lpPntStruc.SelStruc.SelctSRect] Display rectangle in the EXTPAINTSTRUC
  3296. selection structure set  %@NL@%
  3297.  
  3298. %@CR:C6A00180027 @%
  3299. %@2@%%@CR:C6A00180028 @%%@AB@%EndSelection%@CR:C6A00180029 @%%@AE@%%@EH@%%@NL@%
  3300. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3301.  
  3302.  
  3303. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3304.  
  3305. This function stops the selection.  %@NL@%
  3306.  
  3307.  
  3308. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3309.  
  3310. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3311.  
  3312.  
  3313. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3314.  
  3315. None  %@NL@%
  3316.  
  3317. %@CR:C6A00180030 @%
  3318. %@2@%%@CR:C6A00180031 @%%@AB@%InvertSelection%@CR:C6A00180032 @%%@AE@%%@EH@%%@NL@%
  3319. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3320.  
  3321.  
  3322. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3323.  
  3324. This function inverts the selection.  %@NL@%
  3325.  
  3326.  
  3327. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3328.  
  3329. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3330.  
  3331.  
  3332. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3333.  
  3334. %@AB@%DX%@AE@%,%@AB@%AX%@AE@% = (Y,X) screen CoOrd of "active" selection endpoint  %@NL@%
  3335.  
  3336. %@CR:C6A00180033 @%
  3337. %@2@%%@CR:C6A00180034 @%%@AB@%KeySelection%@CR:C6A00180035 @%%@AE@%%@EH@%%@NL@%
  3338. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3339.  
  3340.  
  3341. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3342.  
  3343. This function is for keyboard selection.  %@NL@%
  3344.  
  3345.  
  3346. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3347.  
  3348. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3349.  
  3350. StartType = 0 if SHIFT key UP  != 0 if SHIFT key DOWN  %@NL@%
  3351.  
  3352. %@TH:  11   479 01 34 42 @%
  3353. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3354. MFunc                             = 0 To Right
  3355.                                   = 1 To Left
  3356.                                   = 2 Down
  3357.                                   = 3 Up
  3358.  
  3359. MFunc                             = 0 To Right
  3360.                                   = 1 To Left
  3361.                                   = 2 Down
  3362.                                   = 3 Up
  3363.  
  3364. %@TE:  11   479 01 34 42 @%
  3365.  
  3366.  
  3367. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3368.  
  3369. %@AB@%DX%@AE@%,%@AB@%AY%@AE@% = (Y,X) screen CoOrd of new select end pt  %@NL@%
  3370.  
  3371. KeySelection responds to DIRECTION keys and SHIFT+DIRECTION keys.  %@NL@%
  3372.  
  3373. DIRECTION key response: (SHIFT key UP)  %@NL@%
  3374.  
  3375. if (LEFT Key)  return (X-DELTAx, Y) else if (RIGHT Key)  return (X+DELTAx,
  3376. Y) else if (DOWN Key)  return (X, Y+DELTAy) else if (UP Key)  return (X,
  3377. Y-DELTAy);  %@NL@%
  3378.  
  3379. where <X,Y> is current end point.  %@NL@%
  3380.  
  3381. DELTAx DELTAy are the font width and height in text mode and some
  3382. appropriate value in graphics mode.  %@NL@%
  3383.  
  3384. SHIFT+DIRECTION key response:  %@NL@%
  3385.  
  3386. Similar to above except <X,Y> is current end point.  %@NL@%
  3387.  
  3388. %@CR:C6A00180036 @%
  3389. %@2@%%@CR:C6A00180037 @%%@AB@%MakeSelctRect%@CR:C6A00180038 @%%@AE@%%@EH@%%@NL@%
  3390. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3391.  
  3392.  
  3393. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3394.  
  3395. This function sets a new selection. It is called after every call to
  3396. %@AB@%KeySelection%@AE@% in response to SHIFT+DIRECTION key. Given a new end point, it
  3397. adjusts the new end point to be character-aligned in text mode (and on a
  3398. convenient boundary in the video memory in graphics mode). It also adjusts
  3399. for screen maxima. It sets the Selection rectangle based on the current
  3400. start point and end point.  %@NL@%
  3401.  
  3402.  
  3403. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3404.  
  3405. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3406.  
  3407. YCoOrd,XCoOrd = (Y,X) screen CoOrd of new end point  %@NL@%
  3408.  
  3409.  
  3410. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3411.  
  3412. [lpPntStruc.SelStruc.SelctSRect], Display rect in extended paint selection
  3413. structure set  %@NL@%
  3414.  
  3415. %@AB@%AX%@AE@% == 0, if no change was made to selection parameters  %@NL@%
  3416.  
  3417. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3418. NOTE 
  3419.  
  3420. %@AI@%[lpPntStruc.SelStruc.SelctSRect] must still be set in this case.%@AE@%
  3421. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3422.  
  3423. %@CR:C6A00180039 @%
  3424. %@2@%%@CR:C6A00180040 @%%@AB@%RenderSelection%@CR:C6A00180041 @%%@AE@%%@EH@%%@NL@%
  3425. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3426.  
  3427.  
  3428. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3429.  
  3430. This function renders the selection into the Clipboard format.  %@NL@%
  3431.  
  3432.  
  3433. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3434.  
  3435. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3436.  
  3437. %@TH:   3   255 01 10 66 @%
  3438. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3439. wParam    Parameter from VDD message (= -1 if VMDOSAPP origin
  3440. lParam    Parameter from VDD message (=0 if VMDOSAPP origin) Event ID
  3441. %@TE:   3   255 01 10 66 @%
  3442.  
  3443.  
  3444. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3445.  
  3446. if (DX < 0)  Error else if (DX = 0)  No Selection else if (DX > 0)  DX =
  3447. format, (CF_OEMTEXT or CF_BITMAP)  AX = Handle, (Memory Handle or Bitmap
  3448. Handle)  %@NL@%
  3449.  
  3450.  
  3451. %@3@%%@AB@%18.4.1  Application Painting Function%@AE@%%@EH@%%@NL@%
  3452.  
  3453. This section presents a description of the non-Windows application painting
  3454. function.  %@NL@%
  3455.  
  3456. %@CR:C6A00180042 @%
  3457. %@2@%%@CR:C6A00180043 @%%@AB@%GetDisplayUpd%@CR:C6A00180044 @%%@AE@%%@EH@%%@NL@%
  3458. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3459.  
  3460.  
  3461. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3462.  
  3463. This function calls the VDD to get a display update (if any) and stores it
  3464. in the PAINT structure.  %@NL@%
  3465.  
  3466. It prevents any further changes from occurring in the application. The
  3467. application restarts after a call to one of the following; %@AB@%UpdateScreen%@AE@%,
  3468. %@AB@%PaintScreen%@AE@%, or %@AB@%GrbUnLockApp%@AE@%.  %@NL@%
  3469.  
  3470.  
  3471. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3472.  
  3473. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3474.  
  3475. %@TH:   3   256 01 10 66 @%
  3476. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3477. wParam    Parameter from VDD message (= -1 if VMDOSAPP origin)
  3478. lParam    Parameter from VDD message (=0 if VMDOSAPP origin) Event ID
  3479. %@TE:   3   256 01 10 66 @%
  3480.  
  3481.  
  3482. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3483.  
  3484. %@AB@%AX%@AE@% = Display update flags (see grabpnt.inc for fDisp_ flags)  %@NL@%
  3485.  
  3486.  
  3487. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  3488.  
  3489. This call "locks" the application (prevents further changes from occuring).
  3490. The application can be started again by a call to one of the following:  %@NL@%
  3491.  
  3492.  
  3493.   ■   %@AB@%UpdateScreen%@AE@%%@NL@%
  3494.  
  3495.   ■   %@AB@%PaintScreen%@AE@%%@NL@%
  3496.  
  3497.   ■   %@AB@%GrgUnLockApp%@AE@%%@NL@%
  3498.  
  3499.  
  3500.  
  3501. %@3@%%@AB@%18.4.1  Miscellaneous Functions%@AE@%%@EH@%%@NL@%
  3502.  
  3503. This section presents descriptions of miscellaneous functions in
  3504. alphabetical order.  %@NL@%
  3505.  
  3506. %@CR:C6A00180045 @%
  3507. %@2@%%@CR:C6A00180046 @%%@AB@%CheckGRBVersion%@CR:C6A00180047 @%%@AE@%%@EH@%%@NL@%
  3508. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3509.  
  3510.  
  3511. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3512.  
  3513. This function checks out the VDD version.  %@NL@%
  3514.  
  3515.  
  3516. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3517.  
  3518. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3519.  
  3520.  
  3521. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3522.  
  3523. If (AX == 0)  OK AX == 1  Version # error AX == 2  Display type mismatch
  3524. (VDD and Grabber are not compatible)  DX = Grabber Version number  %@NL@%
  3525.  
  3526.  
  3527. %@2@%%@CR:C6A00180048 @%%@AB@%CursorOff%@CR:C6A00180049 @%%@CR:C6A00180050 @%%@AE@%%@EH@%%@NL@%
  3528. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3529.  
  3530.  
  3531. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3532.  
  3533. This function destroys the cursor for an application.  %@NL@%
  3534.  
  3535.  
  3536. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3537.  
  3538. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3539.  
  3540.  
  3541. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3542.  
  3543. Caret destroyed  %@NL@%
  3544.  
  3545.  
  3546. %@2@%%@CR:C6A00180051 @%%@AB@%CursorOn%@CR:C6A00180052 @%%@CR:C6A00180053 @%%@AE@%%@EH@%%@NL@%
  3547. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3548.  
  3549.  
  3550. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3551.  
  3552. This function creates the cursor for an application if it has one.  %@NL@%
  3553.  
  3554.  
  3555. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3556.  
  3557. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3558.  
  3559.  
  3560. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3561.  
  3562. Caret created  %@NL@%
  3563.  
  3564.  
  3565. %@2@%%@CR:C6A00180054 @%%@AB@%CursorPosit%@CR:C6A00180055 @%%@CR:C6A00180056 @%%@AE@%%@EH@%%@NL@%
  3566. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3567.  
  3568.  
  3569. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3570.  
  3571. This function returns the position of the cursor on the display.  %@NL@%
  3572.  
  3573.  
  3574. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3575.  
  3576. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3577.  
  3578.  
  3579. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3580.  
  3581. %@AB@%DX%@AE@%,%@AB@%AX%@AE@% = (Y,X) screen CoOrd of upper left of cursor  %@NL@%
  3582.  
  3583.  = (-1,-1) if no cursor  %@NL@%
  3584.  
  3585.  
  3586. %@2@%%@CR:C6A00180057 @%%@AB@%GetFontList%@CR:C6A00180058 @%%@CR:C6A00180059 @%%@AE@%%@EH@%%@NL@%
  3587. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3588.  
  3589.  
  3590. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3591.  
  3592. This function returns a pointer to the list of extra fonts you want loaded.
  3593. %@NL@%
  3594.  
  3595.  
  3596. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3597.  
  3598. lpFontBuf -> Buffer for font info  %@NL@%
  3599.  
  3600.  
  3601. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3602.  
  3603. Font Buffer filled in  %@NL@%
  3604.  
  3605. %@CR:C6A00180060 @%
  3606. %@2@%%@CR:C6A00180061 @%%@AB@%GrabComplete%@CR:C6A00180062 @%%@AE@%%@EH@%%@NL@%
  3607. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3608.  
  3609.  
  3610. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3611.  
  3612. This function signals that you are finished with the grab. This is called
  3613. after the grab is complete. It is time to call the VDD and have it free the
  3614. grab memory.  %@NL@%
  3615.  
  3616.  
  3617. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3618.  
  3619. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3620.  
  3621. %@TH:   3   248 01 12 64 @%
  3622. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3623. wParam %@AI@%%@AE@%     Parameter from VDD message (= -1 if VMDOSAPP origin)
  3624. lParam      Parameter from VDD message EVENT ID
  3625. %@TE:   3   248 01 12 64 @%
  3626.  
  3627.  
  3628. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3629.  
  3630. None  %@NL@%
  3631.  
  3632.  
  3633. %@2@%%@CR:C6A00180063 @%%@AB@%GrabEvent%@CR:C6A00180064 @%%@CR:C6A00180065 @%%@AE@%%@EH@%%@NL@%
  3634. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3635.  
  3636.  
  3637. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3638.  
  3639. This function provides a private channel of event communication between the
  3640. VDD and the Grabber to perform a hot key screen grab.  %@NL@%
  3641.  
  3642.  
  3643. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3644.  
  3645. lpPntStruc Extended paint structure  %@NL@%
  3646.  
  3647. %@TH:   3   235 01 18 58 @%
  3648. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3649. wParam %@AI@%%@AE@%           Parameter from VDD message 
  3650. lParam            Parameter from VDD message EVENT ID
  3651. %@TE:   3   235 01 18 58 @%
  3652.  
  3653.  
  3654. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3655.  
  3656. None  %@NL@%
  3657.  
  3658. %@CR:C6A00180066 @%
  3659. %@2@%%@CR:C6A00180067 @%%@AB@%GrbUnLockApp%@CR:C6A00180068 @%%@AE@%%@EH@%%@NL@%
  3660. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3661.  
  3662.  
  3663. %@3@%%@AB@%Descripton%@AE@%%@EH@%%@NL@%
  3664.  
  3665. This function undoes the implied application lock of %@AB@%GetDisplayUpd%@AE@%.  %@NL@%
  3666.  
  3667.  
  3668. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3669.  
  3670. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3671.  
  3672.  
  3673. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3674.  
  3675. None  %@NL@%
  3676.  
  3677.  
  3678. %@2@%%@CR:C6A00180069 @%%@AB@%InitGrabber%@CR:C6A00180070 @%%@CR:C6A00180071 @%%@AE@%%@EH@%%@NL@%
  3679. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3680.  
  3681.  
  3682. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3683.  
  3684. This is the library initialization function.  %@NL@%
  3685.  
  3686.  
  3687. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3688.  
  3689. %@AB@%DI%@AE@% = Module handle of the library  %@NL@%
  3690.  
  3691. %@AB@%CX%@AE@% = Size of local heap (should be 0)  %@NL@%
  3692.  
  3693. %@AB@%DS%@AE@% = Seg addr of library data segment (isn't one)  %@NL@%
  3694.  
  3695.  
  3696. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3697.  
  3698. AX == 0  Init Error AX != 0  OK  %@NL@%
  3699.  
  3700.  
  3701. %@2@%%@CR:C6A00180072 @%%@AB@%PaintScreen%@CR:C6A00180073 @%%@CR:C6A00180074 @%%@AE@%%@EH@%%@NL@%
  3702. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3703.  
  3704.  
  3705. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3706.  
  3707. This function paints the indicated region of the screen.  %@NL@%
  3708.  
  3709. This procedure paints the non-Windows application screen into a window. The
  3710. origin of this is a Windows paint as opposed to a display update, which is
  3711. handled at %@AB@%UpdateScreen%@AE@%. When a non-Windows application receives a Windows
  3712. paint message, %@AB@%Paint Screen%@AE@% gets called.  %@NL@%
  3713.  
  3714.  
  3715. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3716.  
  3717. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3718.  
  3719.  
  3720. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3721.  
  3722. %@AB@%AX%@AE@% != 0 Screen Painted  %@NL@%
  3723.  
  3724. %@AB@%AX%@AE@% == 0 Screen not painted, probably insufficient Windows memory problem  %@NL@%
  3725.  
  3726.  
  3727. %@2@%%@CR:C6A00180075 @%%@AB@%ScreenFree%@CR:C6A00180076 @%%@CR:C6A00180077 @%%@AE@%%@EH@%%@NL@%
  3728. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3729.  
  3730.  
  3731. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3732.  
  3733. This function frees anything associated with this application.  %@NL@%
  3734.  
  3735.  
  3736. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3737.  
  3738. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3739.  
  3740.  
  3741. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3742.  
  3743. Any allocated stuff associated with the application is freed.  %@NL@%
  3744.  
  3745.  
  3746. %@2@%%@CR:C6A00180078 @%%@AB@%SetPaintFnt%@CR:C6A00180079 @%%@CR:C6A00180080 @%%@AE@%%@EH@%%@NL@%
  3747. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3748.  
  3749.  
  3750. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3751.  
  3752. This function sets the font for painting in the extended paint structure so
  3753. that WINOLDAP can compute the paint rectangle for use on %@AB@%PaintScreen%@AE@% calls.
  3754. This is called right before a call to %@AB@%PaintScreen%@AE@%. It is also called right
  3755. before a call to %@AB@%UpdateScreen%@AE@%.  %@NL@%
  3756.  
  3757.  
  3758. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3759.  
  3760. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3761.  
  3762. %@TH:   3   234 01 25 51 @%
  3763. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3764. lpWidFullScr             Word pointer for width return
  3765. lpHeightFullScr          Word pointer for height return
  3766. %@TE:   3   234 01 25 51 @%
  3767.  
  3768.  
  3769. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3770.  
  3771. FntHgt and FntWid values in EXTPAINTSTRUC set  %@NL@%
  3772.  
  3773. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3774. NOTE
  3775.  
  3776. %@AI@%Values are set to 0 if it is a graphics screen.%@AE@%
  3777. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3778.  
  3779. [lpWidFullScr] = Width of full screen in pix (Text or Graphics)  %@NL@%
  3780.  
  3781. [lpHeightFullScr] = Height of full screen in pix (Text or Graphics)  %@NL@%
  3782.  
  3783. %@AB@%DX%@AE@% is height of full screen in scan lines if Graphics, in text lines if
  3784. Text.  %@NL@%
  3785.  
  3786. %@AB@%AX%@AE@% is width of full screen in pix if Graphics, in chars if Text.  %@NL@%
  3787.  
  3788. %@CR:C6A00180081 @%
  3789. %@2@%%@CR:C6A00180082 @%%@AB@%UpdateScreen%@CR:C6A00180083 @%%@AE@%%@EH@%%@NL@%
  3790. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3791.  
  3792.  
  3793. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3794.  
  3795. This function updates changed portions of the screen. When a non-Windows
  3796. application modifies the display on its own, %@AB@%UpdateScreen%@AE@% is called.  %@NL@%
  3797.  
  3798.  
  3799. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3800.  
  3801. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3802.  
  3803.  
  3804. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3805.  
  3806. %@AB@%AX%@AE@% == 1 if Screen Paint, unless fGrbProb bit set in EPStatusFlags  %@NL@%
  3807.  
  3808. %@AB@%AX%@AE@% == 0 if Screen not painted, probably low Windows memory problem  %@NL@%
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815. %@CR:C6A-Part 04 @%%@1@%%@AB@%PART IV  Virtual Device Services%@AE@%%@EH@%%@NL@%
  3816. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3817.  
  3818. This part documents all the enhanced Windows virtual machine environment
  3819. services. They are grouped by service type and presented in the order shown
  3820. on the following page.  %@NL@%
  3821.  
  3822. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  3823. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  3824.  
  3825.  
  3826.  
  3827.  
  3828.  
  3829.  
  3830. %@CR:C6A00190001 @%%@1@%%@AB@%Chapter 19  Memory Management Services%@AE@%%@EH@%%@NL@%
  3831. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3832.  
  3833. Enhanced Windows supplies a rich set of memory management services. Since
  3834. many of the services are unnecessary for most VxD development, only a
  3835. commonly used subset is listed in this introduction. However, all the memory
  3836. management services are documented in either this chapter or in Chapter 40,
  3837. "V86 Mode Memory Manager Device Services."  %@NL@%
  3838.  
  3839. See also Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter
  3840. 17, "Virtual Device Programming Topics," for general environment
  3841. discussions. Memory management is also discussed in the %@AI@%Microsoft Windows
  3842. %@AI@%Software Development Kit, Programming Tools%@AE@% and in Chapter 6, "Network
  3843. Support," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@%.  %@NL@%
  3844.  
  3845. The enhanced Windows environment uses a virtual memory scheme capable of
  3846. overcoming the limits of actual physical memory. Though it may not be
  3847. physically present, a virtual memory of 4 gigabytes is theoretically
  3848. addressable. This is done by swapping (paging) code and data to and from RAM
  3849. and a secondary storage device. Since VxDs reside within the 32-bit
  3850. protected-mode portion of the environment, they can directly access all of
  3851. the memory, but should only access memory whose address was obtained through
  3852. the memory management services.  %@NL@%
  3853.  
  3854. Windows determines the amount of virtual memory actually available based on
  3855. the total amount of physical memory on the system and the amount of disk
  3856. space available. This can be changed (downward) by modifying the swap file
  3857. size specified in the SYSTEM.INI file, or by running the SWAPFILE program
  3858. (documented in the %@AI@%Microsoft Windows User Guide%@AE@%).  %@NL@%
  3859.  
  3860. The memory manager will continue to allocate physical memory until it has
  3861. been used up. Then, it will begin moving 4-kilobyte pages of code and data
  3862. from physical memory to disk to make additional physical memory available.
  3863. Windows pages in 4-kilobyte blocks, rather than unequal-sized code and data
  3864. segments. The swapped 4-kilobyte block may be only part of a given code or
  3865. data segment, or it may cross over two or more code or data segments.  %@NL@%
  3866.  
  3867. This memory paging is transparent to a program. If an attempt is made to
  3868. access a code or data segment of which some part has been paged out to disk,
  3869. the 80386 issues a page fault interrupt. The memory manager then swaps other
  3870. pages out of memory and restores the pages that the program needs.  %@NL@%
  3871.  
  3872. The Windows memory management services are presented in the following
  3873. categories. The services listed comprise the commonly used subset.  %@NL@%
  3874.  
  3875.  
  3876.   ■   System Data Object Management%@NL@%
  3877.  
  3878. %@STUB@%      Allocate_Device_CB_Area%@AB@%%@AE@%%@NL@%
  3879.  
  3880.   ■   Device V86 Page Management %@NL@%
  3881.  
  3882. %@STUB@%      Assign_Device_V86_Pages%@AB@%%@AE@%%@NL@%
  3883.  
  3884.   ■   GDT/LDT Management %@NL@%
  3885.  
  3886.   ■   System Heap Allocator %@NL@%
  3887.  
  3888. %@STUB@%      HeapAllocate%@AB@%%@AE@%%@NL@%
  3889.  
  3890. %@STUB@%      HeapFree%@AB@%%@AE@%%@NL@%
  3891.  
  3892.   ■   System Page Allocator %@NL@%
  3893.  
  3894. %@STUB@%      CopyPageTable%@AB@%%@AE@%%@NL@%
  3895.  
  3896. %@STUB@%      MapIntoV86%@AB@%%@AE@%%@NL@%
  3897.  
  3898. %@STUB@%      ModifyPageBits%@AB@%%@AE@%%@NL@%
  3899.  
  3900. %@STUB@%      PageAllocate%@AB@%%@AE@%%@NL@%
  3901.  
  3902. %@STUB@%      PageFree%@AB@%%@AE@%%@NL@%
  3903.  
  3904. %@STUB@%      PageLock%@AB@%%@AE@%%@NL@%
  3905.  
  3906. %@STUB@%      PageUnlock%@AB@%%@AE@%%@NL@%
  3907.  
  3908. %@STUB@%      PageGetAllocInfo%@AB@%%@AE@%%@NL@%
  3909.  
  3910. %@STUB@%      PhysIntoV86%@AB@%%@AE@%%@NL@%
  3911.  
  3912.   ■   Looking at Physical Device Memory in Protected Mode %@NL@%
  3913.  
  3914. %@STUB@%      MapPhysToLinear %@AB@%%@AE@%%@NL@%
  3915.  
  3916.   ■   Data Access Services%@NL@%
  3917.  
  3918. %@STUB@%      GetFirstV86Page%@AB@%%@AE@%%@NL@%
  3919.  
  3920.   ■   Special Services for Protected Mode APIs %@NL@%
  3921.  
  3922.   ■   Instance Data Management %@NL@%
  3923.  
  3924.   ■   Looking at V86 Address Space 
  3925. %@NL@%
  3926.  
  3927.  
  3928.  
  3929. %@2@%%@CR:C6A00190002 @%%@AB@%19.1  System Data Object Management%@AE@%%@EH@%%@NL@%
  3930.  
  3931. These services provide support for allocating special system areas. The two
  3932. areas managed are the Control Block and the Global V86 Addressable Area.  %@NL@%
  3933.  
  3934. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3935. NOTE
  3936.  
  3937. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  3938. %@AI@%procedure has an underscore in front (i.e., %@AB@%Allocate_Device_CB_Area%@AE@%%@AI@% is
  3939. %@AI@%actually %@AE@%%@AI@%%@AB@%_Allocate_Device_CB_Area%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to
  3940. %@AI@%left (unlike the PL/M calling convention used by Windows, which is left to
  3941. %@AI@%right). The return value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the
  3942. %@AI@%responsibility of the caller%@AE@%%@AI@%to clear the arguments off the stack. Registers
  3943. %@AI@%%@AE@%%@AI@%%@AB@%EAX%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ECX%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EDX%@AE@%%@AE@%%@AI@% are changed by calls. Registers %@AE@%%@AI@%%@AB@%DS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ES%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%
  3944. %@AI@%%@AB@%FS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%GS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EBP%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EDI%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ESI%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved. 
  3945. %@AI@%%@AE@%%@AE@%
  3946. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3947. %@CR:C6A00190003 @%%@CR:C6A00190004 @%
  3948. %@2@%%@CR:C6A00190005 @%%@AB@%Allocate_Device_CB_Area%@AE@%%@EH@%%@NL@%
  3949. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3950.  
  3951. %@AS@%  unsigned Allocate_Device_CB_Area(nBytes,flags) 
  3952. %@AS@%  unsigned nBytes; 
  3953. %@AS@%  unsigned flags;%@AE@%
  3954.  
  3955. This call is used to allocate a region of the Control Block data structure
  3956. to a particular device. Devices typically want some data that is "per VM".
  3957. For example, a device which is virtualizing a particular set of I/O ports
  3958. for the VM needs a place to store each VMs "instance" of the I/O port state.
  3959. This is done by allocating a region of the VM Control Block large enough to
  3960. hold a device specific data structure which contains the state. For example,
  3961. if the device specific data structure looks like this:  %@NL@%
  3962.  
  3963. %@AS@%  FooDeviceCB Struc 
  3964. %@AS@%   FooDevReg1  db ? ; Dev I/O register 1 
  3965. %@AS@%   FooDevReg2  db ? ; Dev I/O register 2 
  3966. %@AS@%   FooDevReg3  db ? ; Dev I/O register 3 
  3967. %@AS@%   FooDevReg4  db ? ; Dev I/O register 4 
  3968. %@AS@%   FooDevState  dd ? ; State flags for device 
  3969. %@AS@%  FooDeviceCB Ends%@AE@%
  3970.  
  3971. Space in the VM Control Block would be allocated like this:  %@NL@%
  3972.  
  3973. %@AS@%  VxD_DATA_SEG 
  3974. %@AS@%  FooDevCBOffset dd ? 
  3975. %@AS@%  VxD_DATA_ENDS 
  3976. %@AS@%  VxD_ICODE_SEG 
  3977. %@AS@%  ; 
  3978. %@AS@%  ; Allocate the Control Block space. This is in Foo's INIT routine 
  3979. %@AS@%  ; 
  3980. %@AS@%   VMMCall _Allocate_Device_CB_Area,<<SIZE FooDeviceCB>,0>
  3981. %@AS@%    or eax,eax
  3982. %@AS@%    jz short No_CB_Space_Error ; Probably FATAL error
  3983. %@AS@%    mov [FooDevCBOffset],eax
  3984. %@AS@%  
  3985. %@AS@%  VxD_ICODE_ENDS
  3986. %@AS@%  
  3987. %@AS@%  VxD_CODE_SEG 
  3988. %@AS@%  ; 
  3989. %@AS@%  ; In VxD procedures the Control Block pointer is passed 
  3990. %@AS@%  ;   in EBX the control block may be pointed to like this. 
  3991. %@AS@%  ; 
  3992. %@AS@%   mov edx,ebx
  3993. %@AS@%    add edx,[FooDevCBOffset]
  3994. %@AS@%    mov al,[edx.FooDevReg1]
  3995. %@AS@%    ...
  3996. %@AS@%  
  3997. %@AS@%  VxD_CODE_ENDS%@AE@%
  3998.  
  3999. The %@AI@%nBytes%@AE@% parameter specifies the number of bytes of space to be allocated.
  4000. There are currently no bits defined in the flags, this parameter must be set
  4001. to 0.  %@NL@%
  4002.  
  4003.  
  4004. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4005.  
  4006. Returns nonzero Control Block Offset of the block allocated if successful,
  4007. returns zero if the space could not be allocated (This is probably a fatal
  4008. error, it is up to the caller to decide what is to be done in this case).  %@NL@%
  4009.  
  4010.  
  4011. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4012.  
  4013. Control block Offsets returned from this call will be DWORD aligned. The
  4014. %@AI@%nBytes%@AE@% parameter does not have to be a multiple of 4, but if it isn't, it
  4015. will currently be rounded up to a multiple of 4. This may change in a later
  4016. releases, so do no depending one rounding.  %@NL@%
  4017.  
  4018. The above code sample is not the only way to do things. There are many other
  4019. ways the control block offset value can be used to access your devices
  4020. specific region of the control block.  %@NL@%
  4021.  
  4022. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4023. NOTE 
  4024.  
  4025. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  4026. %@AI@%therefore only be called during system initialization. Trying to call it
  4027. %@AI@%after system initialization and the system INIT segment space has been
  4028. %@AI@%reclaimed will result in a fatal page fault.%@AE@%
  4029. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4030.  
  4031. When Control Block regions are allocated they are initialized with value 0
  4032. in all bytes. When new VMs are created, all bytes of the Control Block are
  4033. set to 0.  %@NL@%
  4034.  
  4035. %@CR:C6A00190006 @%%@CR:C6A00190007 @%
  4036. %@2@%%@CR:C6A00190008 @%%@AB@%Allocate_Global_V86_Data_Area%@AE@%%@EH@%%@NL@%
  4037. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4038.  
  4039. %@AS@%  unsigned Allocate_Global_V86_Data_Area(nBytes,flags) 
  4040. %@AS@%  unsigned nBytes; 
  4041. %@AS@%  unsigned flags;%@AE@%
  4042.  
  4043. This call is used to allocate a region of the Global V86 Addressable Area to
  4044. a particular device. This area is used for device specific objects which
  4045. must also be addressable by the Virtual mode code running in the Virtual
  4046. Machine.  %@NL@%
  4047.  
  4048. An example is a Virtual mode software interrupt which is trapped by the
  4049. device and causes the return of a Virtual mode pointer to some data
  4050. associated with the device. The data must be in the VM's V86 address space
  4051. since a Virtual mode pointer to it is returned. In this case there is no
  4052. reason for the interrupt hook code to also be in the Global V86 Addressable
  4053. Area, that can all be in the protected mode device.  %@NL@%
  4054.  
  4055. The %@AI@%nBytes%@AE@% parameter specifies the number of bytes of space to be allocated.
  4056. Current flags bits:  %@NL@%
  4057.  
  4058. %@AS@%  GVDAWordAlign EQU 00000000000000000000000000000001B GVDADWordAlign EQU
  4059. %@AS@%00000000000000000000000000000010B GVDAParaAlign EQU
  4060. %@AS@%00000000000000000000000000000100B GVDAPageAlign EQU
  4061. %@AS@%00000000000000000000000000001000B GVDAInstance EQU
  4062. %@AS@%00000000000000000000000100000000B GVDAZeroInit EQU
  4063. %@AS@%00000000000000000000001000000000B GVDAReclaim EQU
  4064. %@AS@%00000000000000000000010000000000B%@AE@%
  4065.  
  4066. All unused bits must be zero. %@AB@%GVDA%@AE@%xxxx%@AB@%Align%@AE@% bits specify the indicated
  4067. alignment (WORD, DWORD, PARAGRAPH, PAGE) for the start of the block. If none
  4068. are set, BYTE alignment is assumed. %@AB@%GVDAInstance%@AE@%, if set, indicates that the
  4069. block is an item of VM instance data for which each different VM has its own
  4070. private values. If %@AB@%GVDAInstance%@AE@% is clear, the block is global data and all
  4071. VMs share the same value setting. %@AB@%GVDAZeroInit%@AE@%, if set, indicates that the
  4072. block is to initialized with value 0 in all bytes of the block. If
  4073. %@AB@%GVDAZeroInit%@AE@% is clear, the block will have random values in it.  %@NL@%
  4074.  
  4075. %@AB@%GVDAReclaim%@AE@% is only valid if %@AB@%GVDAPageAlign%@AE@% is set. IF %@AB@%GVDAReclaim%@AE@% is set,
  4076. then the physical pages of the region should be "reclaimed" by the MMGR
  4077. (memory manager) and placed on the free list, and the NUL page should be
  4078. mapped in the region.  %@NL@%
  4079.  
  4080.  
  4081. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4082.  
  4083. Returns nonzero linear address of the block allocated if successful, returns
  4084. zero if the space could not be allocated. This is probably a fatal error; it
  4085. is up to the caller to decide what is to be done in this case.  %@NL@%
  4086.  
  4087.  
  4088. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4089.  
  4090. The Flag bit equates are defined by including VMM.INC. The equates should be
  4091. used.  %@NL@%
  4092.  
  4093. For blocks allocated with %@AB@%GVDAInstance%@AE@% set, the %@AB@%AddInstanceItem%@AE@% call is made
  4094. by this routine for you.  %@NL@%
  4095.  
  4096. Note the interaction with %@AB@%Allocate_Temp_V86_Data_Area%@AE@%.  %@NL@%
  4097.  
  4098. Specifying multiple %@AB@%GVDA%@AE@%xxxx%@AB@%Align%@AE@% bits will result in random behavior. At
  4099. most ONE of these bits must be set.  %@NL@%
  4100.  
  4101. The returned linear address is a ring 0 linear address. It is up to the
  4102. caller to convert this into a Virtual mode SEG:OFFSET form if that is
  4103. needed.  %@NL@%
  4104.  
  4105. The linear addresses returned by this call will be %@NL@%
  4106.  
  4107. Generally only data needs to be placed in these blocks, but code can be
  4108. placed if desired.  %@NL@%
  4109.  
  4110. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4111. %@AU@%WARNING%@AE@%
  4112.  
  4113. You must be %@AI@%very careful%@AE@% if allocating two blocks, one for code which is %@AI@%not
  4114. %@AI@%%@AE@% instanced, and one for data which %@AI@%is%@AE@% Instanced because you %@AI@%cannot%@AE@% assume
  4115. that the two blocks will be within 64K of each other and thus addressable
  4116. with the same segment register in virtual-80 mode.
  4117. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4118.  
  4119. If the VxD desires the values of Instance fields allocated with this call to
  4120. have a set initial value whenever a new VM is created, the field must be
  4121. initialized with the desired values immediately after making this call. The
  4122. contents of the instance blocks at the time VxD initialization is completed
  4123. is what each new VM is created with.  %@NL@%
  4124.  
  4125. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4126. NOTE 
  4127.  
  4128. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  4129. %@AI@%therefore only be called during system initialization. Trying to call it
  4130. %@AI@%after system initialization and the system INIT segment space has been
  4131. %@AI@%reclaimed will result in a fatal page fault.%@AE@%
  4132. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4133.  
  4134.  
  4135. %@3@%%@AB@%Special notes for GVDAPageAlign%@AE@%%@EH@%%@NL@%
  4136.  
  4137. This type of allocation is intended to support Vxds which need a global page
  4138. aligned piece of V86 address space where they can %@AB@%MapIntoV86%@AE@% data. The best
  4139. example of such a VxD is the %@AB@%PageSwap%@AE@% device.  %@NL@%
  4140.  
  4141. The %@AI@%nBytes%@AE@% parameter should be a multiple of 4096 (page size).  %@NL@%
  4142.  
  4143. Note that this page is global but that %@AB@%MapIntoV86%@AE@%, %@AB@%PhysIntoV86%@AE@%, and
  4144. %@AB@%LinMapIntoV86%@AE@% are calls which are local to a specific VM. This means that a
  4145. VxD which wishes to globally change the mapping of this region must traverse
  4146. the VM list with %@AB@%Get_Next_VM_Handle%@AE@% and perform the map in each VM
  4147. individually.  %@NL@%
  4148.  
  4149. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4150. %@AU@%WARNING%@AE@%
  4151.  
  4152. Do not issue any of the map calls on this region before SYS_VM_Init device
  4153. call time. Failure to follow this rule can cause the page type bits in the
  4154. page table to get set improperly.
  4155. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4156.  
  4157. VxDs using this should set the correct initial VM state in their %@AB@%Create_VM%@AE@%
  4158. device call code. The initial state of the region is actually a copy of the
  4159. current state of %@AB@%SYS_VM_Handle%@AE@%, but you should not rely on this. Set the
  4160. initial state you want explicitly by making a %@AB@%MapIntoV86,%@AE@% or %@AB@%PhysIntoV86%@AE@%
  4161. call.  %@NL@%
  4162.  
  4163. The physical page(s) which are mapped into this region at the time you
  4164. allocate it are not pages that the MMGR worries about. It is up to the VxD
  4165. to put the physical pages to good use. The addresses of these physical
  4166. pages(s) is found by doing a %@AB@%CopyPageTable%@AE@% call on the %@AB@%SYS_VM_Handle%@AE@% and
  4167. looking at the physical address in the page table entries.  %@NL@%
  4168.  
  4169. Do not assume that the physical addresses of these pages equals the linear
  4170. address returned. This will be true on most machines, but not on some. These
  4171. pages by using are mapped with %@AB@%PhysIntoV86%@AE@%.  %@NL@%
  4172.  
  4173. If %@AB@%GVDAReclaim%@AE@% is set, then the physical pages that currently are mapped in
  4174. the region will be reclaimed by the MMGR and placed on the free list. The
  4175. NUL page will then be mapped in the region.  %@NL@%
  4176.  
  4177. If %@AB@%GVDAReclaim%@AE@% is clear, the %@AI@%physical%@AE@% page(s) which are mapped into this
  4178. region at the time you allocate it are not pages that the MMGR worries
  4179. about. It is up to the VxD to use these physical pages for something useful.
  4180. Avoid wasting them. The addresses of these %@AI@%physical%@AE@% pages(s) is found by
  4181. doing a %@AB@%CopyPageTable%@AE@% call on the %@AB@%SYS_VM_Handle%@AE@% and looking at the physical
  4182. address in the page table entries.  %@NL@%
  4183.  
  4184. It is invalid to assume that the physical addresses of these pages = the
  4185. linear address returned. This will be true on most machines, but on some it
  4186. will not. These pages are mapped using %@AB@%PhysIntoV86%@AE@%.  %@NL@%
  4187.  
  4188. You will not be able to %@AB@%Assign_Device_V86_Pages%@AE@% the pages of this region.
  4189. They are already marked as globally owned because they are below
  4190. %@AB@%FirstV86Page%@AE@%.  %@NL@%
  4191.  
  4192. You cannot set both %@AB@%GVDAReclaim%@AE@% and %@AB@%GVDAInstance%@AE@%. Attempting to do so will
  4193. result in an error.  %@NL@%
  4194.  
  4195. %@CR:C6A00190009 @%%@CR:C6A00190010 @%
  4196. %@2@%%@CR:C6A00190011 @%%@AB@%Allocate_Temp_V86_Data_Area%@AE@%%@EH@%%@NL@%
  4197. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4198.  
  4199. %@AS@%  unsigned Allocate_Temp_V86_Data_Area(nBytes,flags)
  4200. %@AS@%  unsigned nBytes; 
  4201. %@AS@%  unsigned flags;%@AE@%
  4202.  
  4203. This call is used to allocate a region of the Global V86 Addressable Area to
  4204. a particular device during system initialization.  %@NL@%
  4205.  
  4206. The primary reason for allocating this area is to create a buffer into which
  4207. data associated with some %@AB@%Simulate_Int%@AE@% activity (like an INT 21H MS-DOS
  4208. system call) can be placed. The area allocated with this call only exists
  4209. for a short period of time during initialization. The %@AI@%nBytes%@AE@% parameter
  4210. specifies the number of bytes of space to be allocated. There are currently
  4211. no bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4212.  
  4213.  
  4214. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4215.  
  4216. Returns nonzero linear address of the block allocated if successful, returns
  4217. zero if the space could not be allocated (insufficient memory, or temp area
  4218. already allocated).  %@NL@%
  4219.  
  4220.  
  4221. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4222.  
  4223. There is only one Temp area, therefore only one allocation will be allowed
  4224. to be outstanding at a time. Attempts to allocate the Temp area when it is
  4225. already allocated will result in an error.  %@NL@%
  4226.  
  4227. The %@AB@%Allocate_Global_V86_Data_Area%@AE@% call does not function while the Temp Area
  4228. is allocated. The Temp Area must be released with %@AB@%Free_Temp_V86_Data_Area%@AE@%
  4229. before the%@AB@% Allocate_Global_V86_Data_Area%@AE@% call can be made again.  %@NL@%
  4230.  
  4231. Make sure you %@AB@%Free_Temp_V86_Data_Area%@AE@% the temp area as soon as possible.  %@NL@%
  4232.  
  4233. The returned linear address is a ring 0 linear address. It is up to the
  4234. caller to convert this into a Virtual mode SEG:OFFSET form if that is
  4235. needed.  %@NL@%
  4236.  
  4237. The linear address returned by this call will be %@NL@%
  4238.  
  4239. Since this area exists only temporarily, it doesn't make sense to instance
  4240. any of it.  %@NL@%
  4241.  
  4242. The linear address returned from this call is paragraph aligned.  %@NL@%
  4243.  
  4244. The contents of the block will always be zero initialized by this call.  %@NL@%
  4245.  
  4246. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4247. NOTE 
  4248.  
  4249. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  4250. %@AI@%therefore only be called during system initialization. Trying to call it
  4251. %@AI@%after system initialization and the system INIT segment space has been
  4252. %@AI@%reclaimed will result in a fatal page fault.%@AE@%
  4253. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4254.  
  4255. %@CR:C6A00190012 @%%@CR:C6A00190013 @%
  4256. %@2@%%@CR:C6A00190014 @%%@AB@%Free_Temp_V86_Data_Area%@AE@%%@EH@%%@NL@%
  4257. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4258.  
  4259. %@AS@%  unsigned Free_Temp_V86_Data_Area()%@AE@%
  4260.  
  4261. This call is used to free the %@AB@%Temp_V86_Data_Area%@AE@% allocated with
  4262. %@AB@%Allocate_Temp_V86_Data_Area.%@AE@%  %@NL@%
  4263.  
  4264.  
  4265. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4266.  
  4267. Returns nonzero if successful, returns zero if unsuccessful (Temp Area not
  4268. allocated).  %@NL@%
  4269.  
  4270.  
  4271. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4272.  
  4273. The %@AB@%Allocate_Global_V86_Data_Area%@AE@% call does not function while the Temp Area
  4274. is allocated. The Temp Area must be released with%@AB@% Free_Temp_V86_Data_Area%@AE@%
  4275. before the %@AB@%Allocate_Global_V86_Data_Area%@AE@% call can be made again.  %@NL@%
  4276.  
  4277. Once this call is issued, the Linear Address that was returned from
  4278. %@AB@%Allocate_Temp_V86_Data_Area%@AE@% can no longer be used for anything. The system
  4279. will probably crash if this is attempted.  %@NL@%
  4280.  
  4281. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4282. NOTE 
  4283.  
  4284. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  4285. %@AI@%therefore only be called during system initialization. Trying to call it
  4286. %@AI@%after system initialization and the system INIT segment space has been
  4287. %@AI@%reclaimed will result in a fatal page fault. %@AE@%
  4288. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4289.  
  4290.  
  4291. %@2@%%@CR:C6A00190015 @%%@AB@%19.2  Device V86 Page Management%@AE@%%@EH@%%@NL@%
  4292. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4293.  
  4294. Certain types of VxDs may want to take control of certain regions of the
  4295. VM's virtual-86 address space for use by the VxD. The best examples of this
  4296. are as follows:  %@NL@%
  4297.  
  4298.  
  4299.   ■   The display device (VDD), which wants to reserve those areas of the
  4300.       A0H to BFH page address range that are used by the display device.%@NL@%
  4301.  
  4302.   ■   The EMM device (part of V86MMGR), which wants to use a region of VM
  4303.       V86 address space between pages A0H and 100H for the high memory EMM
  4304.       3.20 Mapping Window.%@NL@%
  4305.  
  4306.   ■   The device responsible for management of the EBIOS page, page 9FH, on
  4307.       machines like the IBM PS/2(R) Model 80. %@NL@%
  4308.  
  4309.  
  4310. The following calls enable VxDs to allocate VM V86 address ranges for such
  4311. purposes and cooperate with other VxDs that also might want to use them.
  4312. There are two types of assignment that can be used: global, which applies to
  4313. all VMs in the system, and local, which applies to only one VM. The VDD
  4314. video and EBIOS page assignments are examples of global assignment (although
  4315. these could be local depending on the specifics of the implementation). The
  4316. EMM assignments are an example of local assignments. The EMM driver does not
  4317. want to take over VM V86 page assignment in VMs that are not using EMM
  4318. because then all those pages cannot be used by any other device. Thus, it
  4319. waits until a specific VM makes an EMM call of a certain type at which point
  4320. the EMM driver %@AI@%may%@AE@% do a local page assignment in that particular VM to
  4321. assign the EMM pages of the V86 address space to the EMM device. The global
  4322. versus local assignment is specified via the %@AI@%VMHandle%@AE@% parameter on the
  4323. calls. If the handle is nonzero, it is local; if the handle is zero, it is
  4324. global.  %@NL@%
  4325.  
  4326. No protection is provided with this mechanism; all that is provided is
  4327. information so that devices can cooperate. There is nothing to prevent a VxD
  4328. from mapping pages that it does not own or a page owned by some other VxD. A
  4329. device that does these things is simply uncooperative and not correctly
  4330. implemented.  %@NL@%
  4331.  
  4332. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4333. NOTE
  4334.  
  4335. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  4336. %@AI@%procedure has an underscore in front (i.e., %@AB@%Assign_Device _V86_Pages%@AE@%%@AI@% is
  4337. %@AI@%actually %@AE@%%@AI@%%@AB@%_Assign_Device_V86_Pages%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to
  4338. %@AI@%left (unlike the PL/M calling convention used by Windows, which is left to
  4339. %@AI@%right). The return value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the
  4340. %@AI@%responsibility of the caller%@AE@%%@AI@% to clear the arguments off the stack. Registers
  4341. %@AI@%%@AE@%%@AI@%%@AB@%EAX%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ECX%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EDX%@AE@%%@AE@%%@AI@% are changed by calls. Registers %@AE@%%@AI@%%@AB@%DS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ES%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%
  4342. %@AI@%%@AB@%FS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%GS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EBP%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EDI%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ESI%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved.%@AE@%
  4343. %@AE@%
  4344. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4345. %@CR:C6A00190016 @%
  4346. %@2@%%@CR:C6A00190017 @%%@AB@%Assign_Device_V86_Pages Assign_Device_V86_Pages service%@AE@%%@EH@%%@NL@%
  4347. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4348.  
  4349. %@AS@%  unsigned Assign_Device_V86_Pages(VMLinrPage,nPages,VMHandle,flags)
  4350. %@AS@%  unsigned VMLinrPage; 
  4351. %@AS@%  unsigned nPages; 
  4352. %@AS@%  unsigned VMHandle; 
  4353. %@AS@%  unsigned flags;%@AE@%
  4354.  
  4355. This call is used to assign a region of VM V86 address space to a device.
  4356. %@AI@%VMLinrPage%@AE@% specifies the linear page number (>=0, <=10Fh) of the first page
  4357. of V86 address space to be assigned. %@AI@%nPages%@AE@% specifies the number of pages to
  4358. be assigned starting at %@AI@%VMLinrPage%@AE@%. The entire specified range must be >=0,
  4359. <=10Fh, an error will occur if it is not. All of the specified pages must be
  4360. un-assigned, or an error will occur. %@AI@%VMHandle%@AE@% specifies the VM to Local
  4361. assign the pages in, if this parameter is 0, it means the pages are to be
  4362. Global assigned. There are currently no bits defined in the %@AI@%flags%@AE@%, this
  4363. parameter must be set to 0.  %@NL@%
  4364.  
  4365.  
  4366. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4367.  
  4368. Returns nonzero if the assignment was successful, returns zero if the
  4369. assignment failed (at least one page in the specified range is already
  4370. assigned, or invalid page range).  %@NL@%
  4371.  
  4372.  
  4373. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4374.  
  4375. During device initialization only Global Assignments are allowed, and there
  4376. are restrictions on the pages which can be assigned. Pages between
  4377. %@AB@%FirstV86Page%@AE@% and page 0A0h can only be top down, in order assigned during
  4378. device initialization. Local Assignments, and General assignment between
  4379. %@AB@%FirstV86Page%@AE@% and page 0A0h must wait until device initialization is
  4380. complete.  %@NL@%
  4381.  
  4382. Note that Global Assignment of a page that is already assigned, either Local
  4383. to any VM, or Global assigned will fail. Global assignment can only work on
  4384. pages which are not currently assigned in any VM.  %@NL@%
  4385.  
  4386. %@CR:C6A00190018 @%%@CR:C6A00190019 @%
  4387. %@2@%%@CR:C6A00190020 @%%@AB@%Deassign_Device_V86_Pages%@AE@%%@EH@%%@NL@%
  4388. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4389.  
  4390. %@AS@%  unsigned DeAssign_Device_V86_Pages(VMLinrPage,nPages,VMHandle,flags)
  4391. %@AS@%  unsigned VMLinrPage; 
  4392. %@AS@%  unsigned nPages; 
  4393. %@AS@%  unsigned VMHandle; 
  4394. %@AS@%  unsigned flags;%@AE@%
  4395.  
  4396. This call is used to deassign a region of VM V86 address which was
  4397. previously assigned with %@AB@%Assign_Device_V86_Pages%@AE@%. %@AI@%VMLinrPage%@AE@% specifies the
  4398. linear page number (>=0, <=10Fh) of the first page to be deassigned. %@AI@%nPage%@AE@%s
  4399. specifies the number of pages to be deassigned starting at %@AI@%VMLinrPage%@AE@%. The
  4400. entire specified range must be >=0, <=10Fh, an error will occur if it is
  4401. not. All of the specified pages must be assigned, or an error will occur.
  4402. %@AI@%VMHandle%@AE@% specifies the VM to Local deassign the pages in, if this parameter
  4403. is 0, it means the pages are to be Global deassigned. There are currently no
  4404. bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4405.  
  4406.  
  4407. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4408.  
  4409. Returns nonzero if the deassignment was successful, returns zero if the
  4410. deassignment failed (at least one page in the specified range is already
  4411. deassigned, or invalid page range).  %@NL@%
  4412.  
  4413.  
  4414. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4415.  
  4416. During device initialization this call will always fail. This call only
  4417. works after device initialization is complete.  %@NL@%
  4418.  
  4419. An extreme amount of chaos will occur if someone Global DeAssigns a range
  4420. which is actually Local Assigned, or DeAssigns a region which was not
  4421. obtained via a successful%@AB@% Assign_Device_V86_Pages. %@AE@%  %@NL@%
  4422.  
  4423. %@CR:C6A00190021 @%%@CR:C6A00190022 @%
  4424. %@2@%%@CR:C6A00190023 @%%@AB@%Get_Device_V86_Pages_Array%@AE@%%@EH@%%@NL@%
  4425. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4426.  
  4427. %@AS@%  unsigned Get_Device_V86_Pages_Array(VMHandle,ArrayBufPTR,flags)
  4428. %@AS@%  unsigned VMHandle; 
  4429. %@AS@%  unsigned ArrayBufPTR; 
  4430. %@AS@%  unsigned flags;%@AE@%
  4431.  
  4432. This call is used to obtain a copy of the assignment bit map array for
  4433. %@AB@%Device_V86_Pages%@AE@%. This allows the caller to determine which regions of the
  4434. VM V86 address space are currently assigned, and which are available.
  4435. %@AI@%VMHandle%@AE@% specifies the VM to get the assignment bit map of, if this
  4436. parameter is 0, it means to get the Global assignment array. %@AI@%ArrayBufPTR%@AE@%
  4437. points to a buffer large enough to contain the array. The assignment array
  4438. is an array of 110h bits, one bit for each page in the range 0-10Fh. Thus
  4439. the size of the array is ((110h/8)+3)/4 = 9 DWORDS.  %@NL@%
  4440.  
  4441. Bits in the array which are set (=1) indicate pages which are assigned, bits
  4442. which are clear (=0) indicate pages which are not assigned. Thus to test the
  4443. bit for page number N (0 N 10Fh) you could use code like this:  %@NL@%
  4444.  
  4445. %@AS@%  mov ebx, N MOD 32   ; Bit number in DWORD
  4446. %@AS@%    mov eax, N / 32  ; DWORD index into array
  4447. %@AS@%    bt dword ptr ArrayBufPTR[eax*4],ebx ; Test bit for page N
  4448. %@AS@%    jnc short PageUnAssigned      PageAssigned:%@AE@%
  4449.  
  4450. Note that this code is mearly intended to illustrate how the bit array
  4451. works. This code is not the most efficient, or the only way to implement
  4452. this test. There are currently no bits defined in the %@AI@%flags%@AE@%, this parameter
  4453. must be set to 0.  %@NL@%
  4454.  
  4455.  
  4456. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4457.  
  4458. Returns nonzero if successful, returns zero if the bit array could not be
  4459. returned (Invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  4460.  
  4461.  
  4462. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4463.  
  4464. The Global Bit Array only indicates those pages which are currently Globally
  4465. owned. Bits with 0 in them do not necessarily indicate pages which can be
  4466. %@AB@%Global Assign_Device_V86_Paged%@AE@%. The reason is that one of the VMs in the
  4467. system may have that page Local %@AB@%Assign_Device_V86_Paged%@AE@%. In order to
  4468. determine if a page can be globally assigned, the Global array must be
  4469. examined, AND all of the VM Local arrays must be examined.  %@NL@%
  4470.  
  4471. %@CR:C6A00190024 @%%@CR:C6A00190025 @%
  4472. %@2@%%@CR:C6A00190026 @%%@AB@%Hook_V86_Page%@AE@%%@EH@%%@NL@%
  4473. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4474.  
  4475. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4476. NOTE
  4477.  
  4478. %@AI@%This service does not use the C-calling Convention%@AE@%
  4479.  
  4480. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4481.  
  4482.  
  4483. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  4484.  
  4485. This service allows VxDs to intercept page faults in portions of the V86
  4486. address space of every virtual machine. It is used by devices such as the
  4487. Virtual Display Device to detect when particular address ranges are
  4488. accessed.  %@NL@%
  4489.  
  4490. You must specify a page number and address of a call-back routine to this
  4491. service. If it is installed successfully, your "hook" will be called every
  4492. time a page fault occurs in ANY VM on that page. See the memory manager
  4493. _Modify_Pages documentation for making hooked pages not present and for
  4494. registering ownership of pages.  %@NL@%
  4495.  
  4496. The callback routine is responsible for mapping an memory at the location of
  4497. the page fault or crashing the VM. In unusual circumstances it may be
  4498. appropriate to map a null page at the faulting faulting address page. See
  4499. the memory manager documentation for details on mapping memory and mapping
  4500. null pages.  %@NL@%
  4501.  
  4502. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4503. NOTE
  4504.  
  4505. %@AI@%Do not rely on the contents of the CR2 (page fault) register. Use the value
  4506. %@AI@%passed to your call-back in EAX.%@AE@%
  4507. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4508.  
  4509.  
  4510. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  4511.  
  4512. EAX = Page number (A0h - 0FFh) ESI = Address of trap routine  %@NL@%
  4513.  
  4514.  
  4515. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  4516.  
  4517. If carry flag set then ERROR: Invalid page number or page already hooked
  4518. else Page hooked  %@NL@%
  4519.  
  4520.  
  4521. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  4522.  
  4523. Flags  %@NL@%
  4524.  
  4525.  
  4526. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  4527.  
  4528. EAX = Faulting page number EBX = Current VM handle EBP does NOT point to the
  4529. client register structure.  %@NL@%
  4530.  
  4531.  
  4532. %@2@%%@CR:C6A00190027 @%%@AB@%19.3  GDT/LDT Management%@AE@%%@EH@%%@NL@%
  4533. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4534.  
  4535. These services provide a way for VxDs to allocate Global Descriptor Table
  4536. (GDT) selectors and set up a Local Descriptor Table (LDT) for protected-mode
  4537. execution. Notice that the intent of these services is to support segmented
  4538. environments in protected mode. In general, VxDs should never need to
  4539. allocate GDT selectors or set up an LDT. The only reason these services are
  4540. needed is to support protected-mode applications. Notice that the LDT is a
  4541. per-VM object; each VM may have its own LDT. Since enhanced Windows is a
  4542. flat model system, do not create multiple segments.%@CR:C6A00190028 @%%@CR:C6A00190029 @%%@CR:C6A00190030 @%%@NL@%
  4543.  
  4544. %@CR:C6A00190031 @%%@CR:C6A00190032 @%
  4545. %@2@%%@CR:C6A00190033 @%%@AB@%Allocate_GDT_Selector%@AE@%%@EH@%%@NL@%
  4546. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4547.  
  4548. %@AS@%  unsigned Allocate_GDT_Selector(DescDWORD1,DescDWORD2,flags)
  4549. %@AS@%  unsigned DescDWORD1; 
  4550. %@AS@%  unsigned DescDWORD2; 
  4551. %@AS@%  unsigned flags;%@AE@%
  4552.  
  4553. This call is used to create a new GDT selector. %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@%
  4554. form the 8 bytes of information to be placed in the new descriptor.
  4555. %@AI@%DescDWORD1%@AE@% is the high order 4 bytes of the descriptor containing the high
  4556. 16 bits of the base, the high 4 bits of the limit and the status and type
  4557. bits. %@AI@%DescDWORD2%@AE@% is the low order 4 bytes for the descriptor containing the
  4558. low 16 bits of the base and limit. Use %@AB@%BuildDescDWORDs%@AE@% to help you set up
  4559. these arguments. There are currently no bits defined in the %@AI@%flags%@AE@%, this
  4560. parameter must be set to 0.  %@NL@%
  4561.  
  4562.  
  4563. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4564.  
  4565. Returns a 64 bit long which is actually two 32 bit DWORDs. The low DWORD
  4566. (%@AB@%EAX%@AE@%) is the non-zero selector if succesfull. The high DWORD (%@AB@%EDX%@AE@%) is split
  4567. into two 16 bit word returns. The low 16 bits of %@AB@%EDX%@AE@% is the GDT descriptor
  4568. which describes the GDT itself. Unlike the LDT, it is strongly recommended
  4569. that this selector %@AI@%not %@AE@%be used to edit the GDT. If you mess up editing the
  4570. LDT, you will probably just crash one app, but if you mess up editing the
  4571. GDT, you will crash the whole system. The high 16 bits of %@AB@%EDX%@AE@% is the number
  4572. of selectors currently in the GDT (the "limit" of the GDT expressed as a
  4573. number of selectors, (LIMIT+1)/8). Both DWORDS have value 0 if the
  4574. allocation failed (Bad DescDWORD arguments, GDT is full, insufficient memory
  4575. to grow GDT).  %@NL@%
  4576.  
  4577.  
  4578. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4579.  
  4580. The RPL of the selector returned from this call will be set to the DPL of
  4581. the selector set in %@AI@%DescDWORD1%@AE@%.  %@NL@%
  4582.  
  4583. The low 16 bits of the %@AB@%EDX%@AE@% return does not change, but it is safest to save
  4584. the value of the GDT selector after each %@AB@%Allocate_GDT_Selector%@AE@% call. This
  4585. selector will have DPL = RPL = 0, and the TI bit (bit 2) will be clear.  %@NL@%
  4586.  
  4587. The high 16 bits of the %@AB@%EDX%@AE@% return must be saved after each call, if its
  4588. value is important, because the size of the GDT may change on each call.  %@NL@%
  4589.  
  4590. The prefered method of changing a GDT descriptor is to use %@AB@%SetDescriptor%@AE@%,
  4591. rather than using the GDT selector which is returned by this call.  %@NL@%
  4592.  
  4593. %@CR:C6A00190034 @%%@CR:C6A00190035 @%
  4594. %@2@%%@CR:C6A00190036 @%%@AB@%Allocate_LDT_Selector%@AE@%%@EH@%%@NL@%
  4595. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4596.  
  4597. %@AS@%  unsigned long
  4598. %@AS@%  Allocate_LDT_Selector(VMHandle,DescDWORD1,DescDWORD2,Count,flags)
  4599. %@AS@%  unsigned VMHandle; 
  4600. %@AS@%  unsigned DescDWORD1; 
  4601. %@AS@%  unsigned DescDWORD2; 
  4602. %@AS@%  unsigned Count; 
  4603. %@AS@%  unsigned flags;%@AE@%
  4604.  
  4605. This call is used to create new LDT selector(s) in the specified VM context.
  4606. %@AI@%VMHandle%@AE@% is a valid VM handle and indicates the VM context for which the
  4607. selector(s) will be valid. %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@% form the 8 bytes of
  4608. information to be placed in the new descriptor(s). %@AI@%DescDWORD1%@AE@% is the high
  4609. order 4 bytes of the descriptor containing the high 16 bits of the base, the
  4610. high 4 bits of the limit and the status and type bits. %@AI@%DescDWORD2%@AE@% is the low
  4611. order 4 bytes for the descriptor containing the low 16 bits of the base and
  4612. limit. Use %@AB@%BuildDescDWORDs%@AE@% to help you set up these arguments. The %@AI@%Count
  4613. %@AI@%%@AE@%parameter specifies the number of contiguous LDT selectors to allocate. This
  4614. parameter supports Block Selector Assignment strategies. USE16 segmented
  4615. applications cannot address objects larger than 64K Bytes in size without
  4616. having multiple selectors that describe the sequential 64K Byte blocks of
  4617. the object. For an object <=64K bytes in size, or instances where it is
  4618. inappropriate, Count = 1. For an object >64K bytes in size, Count = (Size +
  4619. (64K - 1))/64K. Notice that the selectors allocated for count >1 all have
  4620. the same descriptor DWORDs in them. It is up to the caller to edit the base
  4621. and limits of the individual selectors in a Block Selector Assignment using
  4622. the LDT selector returned in the low 16 bits of %@AB@%EDX%@AE@%. There are currently no
  4623. bits defined in the flags, this parameter must be set to 0.  %@NL@%
  4624.  
  4625.  
  4626. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4627.  
  4628. Returns a 64 bit long which is actually two 32 bit DWORDs. The low DWORD
  4629. (%@AB@%EAX%@AE@%) is the nonzero selector if successful, if Count was >1, this is the
  4630. FIRST selector, the second is %@AB@%EAX%@AE@%+8, the third %@AB@%EAX%@AE@%+16, etc. The high DWORD
  4631. (%@AB@%EDX%@AE@%) is split into two 16 bit word returns. The low 16 bits of %@AB@%EDX%@AE@% is the
  4632. LDT descriptor which describes the LDT itself. The allows the caller to do
  4633. things such as change the present bit of LDT selectors and change the base
  4634. and limit. The high 16 bits of %@AB@%EDX%@AE@% is the number of selectors currently in
  4635. the LDT (the "limit" of the LDT expressed as a number of selectors,
  4636. (LIMIT+1)/8). Both DWORDS have value 0 if the allocation failed (Bad
  4637. DescDWORD arguments, LDT is full, invalid %@AI@%VMHandle%@AE@% insufficient memory to
  4638. grow LDT).  %@NL@%
  4639.  
  4640.  
  4641. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4642.  
  4643. The RPL of the selector returned from this call will be set to the DPL of
  4644. the selector set in %@AI@%DescDWORD1%@AE@% and the TI bit (bit 2) will be set.  %@NL@%
  4645.  
  4646. The high 16 bits of the %@AB@%EAX%@AE@% return are zero since selectors are 16 bit
  4647. quantities.  %@NL@%
  4648.  
  4649. Note that LDT selectors are PER VM and only valid in that VM context (VM
  4650. must be current VM for selector to be valid). Use %@AB@%SelectorMapFlat%@AE@% to look at
  4651. regions described by LDT selectors in VMs which are not the current VM.  %@NL@%
  4652.  
  4653. The low 16 bits of the %@AB@%EDX%@AE@% return does not change once the LDT of a
  4654. particular VM is created, but it is safest to save the value of the LDT
  4655. selector after each %@AB@% Allocate_LDT_Selector call.%@AE@% This selector will have DPL
  4656. = RPL = Protected Mode Application Privilege, and the TI bit (bit 2) will be
  4657. set.  %@NL@%
  4658.  
  4659. The high 16 bits of the %@AB@%EDX%@AE@% return %@AI@%must be saved%@AE@% after each call, if its
  4660. value is important, because the size of the LDT may change on each call.  %@NL@%
  4661.  
  4662. The multiple selectors allocated with Count >1 must be individually freed.
  4663. %@AB@%_Free_LDT_Selector%@AE@% does not have a count.  %@NL@%
  4664.  
  4665. The prefered method of changing an LDT descriptor is to use %@AB@%SetDescriptor%@AE@%.  %@NL@%
  4666.  
  4667. Use of ALDTSpecSel is not advised. Reliance on specific "hard coded" LDT
  4668. selectors is contrary to good system design principals. Note that a bit like
  4669. this does not exist for %@AB@%Allocate_GDT_Selector%@AE@%, this is intentional. A call
  4670. with this bit set may always fail for some values of the Count parameter,
  4671. and it may start failing for all values of the Count parameter in a later
  4672. release of the product.  %@NL@%
  4673.  
  4674. %@CR:C6A00190037 @%%@CR:C6A00190038 @%
  4675. %@2@%%@CR:C6A00190039 @%%@AB@%BuildDescDWORDs%@AE@%%@EH@%%@NL@%
  4676. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4677.  
  4678. %@AS@%  unsigned  long BuildDescDWORDs(DESCBase,DESCLimit,DESCType,DESCSize,flags)
  4679. %@AS@%  unsigned  DESCBase; 
  4680. %@AS@%  unsigned  DESCLimit; 
  4681. %@AS@%  unsigned  DESCType; 
  4682. %@AS@%  unsigned  DESCSize;
  4683. %@AS@%  unsigned Flags%@AE@%
  4684.  
  4685. This call is used to help you build the %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@% arguments
  4686. for calls to %@AB@%Allocate_LDT/GDT_Selector%@AE@%. DESCBase is the 32 bit BASE for the
  4687. descriptor. DESCLimit is the 20 bit LIMIT for the descriptor. %@AI@%DESCType%@AE@%
  4688. specifies the type BYTE (Only low 8 bits of the parameter are valid, other
  4689. bits must be 0) for the descriptor. This is the byte that occupies bits 8-15
  4690. of the high DWORD of the descriptor (Present bit, DPL and TYPE fields).
  4691. %@AI@%DESCSize%@AE@% specifies bits 20-23 of the high DWORD of the descriptor
  4692. (Granularity, Big/Default). Notice that these bits occupy bits 4-7 of the
  4693. %@AI@%DESCSize%@AE@% parameter, other bits must be 0. In other words %@AI@%DESCSize%@AE@% specifies
  4694. a byte just like DESCType where only the high 4 bits of the byte are
  4695. specified.  %@NL@%
  4696.  
  4697. Current flags bits:  %@NL@%
  4698.  
  4699. %@AS@%  BDDExplicitDPL EQU 00000000000000000000000000000001B%@AE@%
  4700.  
  4701. All unused bits must be zero. BDDExplicitDPL, if set, indicates that the DPL
  4702. value specified in the DESCType field is to be used. If this bit is clear,
  4703. then the DPL specified in the DESCType field is ignored and the DPL returned
  4704. will be set to the protected mode application RPL. Since most selectors are
  4705. built for the use by protected mode applications, this provides a
  4706. convienient way to build descriptors without having to actually know which
  4707. ring protected mode applications run in.  %@NL@%
  4708.  
  4709.  
  4710. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4711.  
  4712. Returns the low DWORD of the descriptor (%@AI@%DescDWORD2%@AE@%) in %@AB@%EAX%@AE@%, and the high
  4713. DWORD of the descriptor (%@AI@%DescDWORD1%@AE@%) in %@AB@%EDX%@AE@%.  %@NL@%
  4714.  
  4715.  
  4716. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4717.  
  4718. If you are building selectors for use by Protected Mode applications use the
  4719. built-in capability provided by not setting the BDDExplicitDPL bit. Do not
  4720. make assumptions about which ring protected mode applications run in. The
  4721. selection of a ring for PM applications will be changed in future revs of
  4722. Windows.  %@NL@%
  4723.  
  4724. %@CR:C6A00190040 @%%@CR:C6A00190041 @%
  4725. %@2@%%@CR:C6A00190042 @%%@AB@%Free_GDT_Selector%@AE@%%@EH@%%@NL@%
  4726. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4727.  
  4728. %@AS@%  unsigned Free_GDT_Selector(Selector,flags) 
  4729. %@AS@%  unsigned Selector; 
  4730. %@AS@%  unsigned flags;%@AE@%
  4731.  
  4732. This call is used to free a GDT selector allocated with a previous
  4733. %@AB@%Allocate_GDT_Selector%@AE@% call. %@AI@%Selector%@AE@% is the return from a previous
  4734. %@AB@%Allocate_GDT_Selector%@AE@% call. There are currently no bits defined in the
  4735. %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4736.  
  4737.  
  4738. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4739.  
  4740. Returns nonzero value if successful, returns zero if the free failed
  4741. (invalid %@AI@%Selector%@AE@%).  %@NL@%
  4742.  
  4743.  
  4744. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4745.  
  4746. Certain system selectors cannot be freed since they are required for
  4747. operation of enhanced Windows.  %@NL@%
  4748.  
  4749. %@CR:C6A00190043 @%%@CR:C6A00190044 @%
  4750. %@2@%%@CR:C6A00190045 @%%@AB@%Free_LDT_Selector%@AE@%%@EH@%%@NL@%
  4751. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4752.  
  4753. %@AS@%  unsigned Free_LDT_Selector(VMHandle,Selector,flags) 
  4754. %@AS@%  unsigned VMHandle; 
  4755. %@AS@%  unsigned Selector; 
  4756. %@AS@%  unsigned flags;%@AE@%
  4757.  
  4758. This call is used to free a LDT selector allocated with a previous
  4759. %@AB@%Allocate_LDT_Selector%@AE@% call. %@AI@%VMHandle%@AE@% indicates the VM context of the
  4760. selector. %@AI@%Selector%@AE@% is the return from a previous %@AB@%Allocate_LDT_Selector%@AE@% call.
  4761. There are currently no bits defined in the %@AI@%flags%@AE@%, this parameter must be set
  4762. to 0.  %@NL@%
  4763.  
  4764.  
  4765. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4766.  
  4767. Returns nonzero value if successful, returns zero if the free failed
  4768. (invalid %@AI@%Selector%@AE@%, invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  4769.  
  4770.  
  4771. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4772.  
  4773. The RPL bits of the passed Selector are ignored by this call.  %@NL@%
  4774.  
  4775.  
  4776. %@2@%%@CR:C6A00190046 @%%@AB@%GetDescriptor%@AE@%%@EH@%%@NL@%
  4777. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4778.  
  4779. %@AS@%  unsigned long GetDescriptor(Selector,VMHandle,flags) unsigned Selector;
  4780. %@AS@%  unsigned VMHandle;
  4781. %@AS@%  unsigned flags;%@AE@%
  4782.  
  4783. This call is used to get a copy of the two descriptor DWORDs associated with
  4784. the given LDT or GDT Selector. Selector is a GDT or LDT selector value to
  4785. get the descriptor of. The %@AI@%VMHandle%@AE@% parameter is ignored if Selector is a
  4786. GDT selector. If Selector is an LDT selector, then %@AI@%VMHandle%@AE@% indicates the
  4787. appropriate VM context for the Selector. There are currently no bits defined
  4788. in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4789.  
  4790.  
  4791. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4792.  
  4793. Returns the low DWORD of the descriptor (%@AI@%DescDWORD2%@AE@%) in %@AB@%EAX%@AE@%, and the high
  4794. DWORD of the descriptor (%@AI@%DescDWORD1%@AE@%) in %@AB@%EDX%@AE@%. Returns zero in both DWORDs if
  4795. there was an error (invalid selector, invalid VM handle).  %@NL@%
  4796.  
  4797.  
  4798. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4799.  
  4800. The high 16 bits of the Selector argument are ignored (this is because the
  4801. 80386 CPU often sets them to somewhat random values when DWORD operations
  4802. are performed on segment registers).  %@NL@%
  4803.  
  4804. The RPL bits of Selector are ignored.  %@NL@%
  4805.  
  4806. The %@AI@%VMHandle%@AE@% parameter must be valid for LDT selectors.  %@NL@%
  4807.  
  4808.  
  4809. %@2@%%@CR:C6A00190047 @%%@AB@%SetDescriptor%@AE@%%@EH@%%@NL@%
  4810. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4811.  
  4812. %@AS@%  unsigned SetDescriptor(Selector,VMHandle,DescDWORD1,DescDWORD2,flags)
  4813. %@AS@%unsigned Selector;
  4814. %@AS@%  unsigned VMHandle;
  4815. %@AS@%  unsigned DescDWORD1;
  4816. %@AS@%  unsigned DescDWORD2;
  4817. %@AS@%  unsigned flags;%@AE@%
  4818.  
  4819. This call is used to set (change) the descriptor of the given Selector.
  4820. Selector is a GDT or LDT selector value to set the descriptor of. The
  4821. %@AI@%VMHandle%@AE@% parameter is ignored if Selector is a GDT selector. If Selector is
  4822. an LDT selector, then VMHandle indicates the appropriate VM context for the
  4823. Selector. %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@% form the 8 bytes of information to be
  4824. placed in the descriptor. %@AI@%DescDWORD1%@AE@% is the high ORDER 4 bytes of the
  4825. descriptor containing the high 16 bits of the base, the high 4 bits of the
  4826. limit and the status and type bits. %@AI@%DescDWORD2%@AE@% is the low ORDER 4 bytes for
  4827. the descriptor containing the low 16 bits of the base and limit. Use
  4828. %@AB@%BuildDescriptorDWORDs%@AE@% to help you set up these arguments. There are
  4829. currently no bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4830.  
  4831.  
  4832. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4833.  
  4834. Returns non-zero value if succesfull, returns zero if it failed (invalid
  4835. %@AI@%Selector%@AE@%, invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  4836.  
  4837.  
  4838. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4839.  
  4840. The high 16 bits of the Selector argument are ignored (this is because the
  4841. 80386 CPU often sets them to somewhat random values when DWORD operations
  4842. are performed on segment registers).  %@NL@%
  4843.  
  4844. The RPL bits of Selector are ignored.  %@NL@%
  4845.  
  4846. The %@AI@%VMHandle%@AE@% parameter must be valid for LDT selectors.  %@NL@%
  4847.  
  4848.  
  4849. %@2@%%@CR:C6A00190048 @%%@AB@%19.4  System Heap Allocator%@AE@%%@EH@%%@NL@%
  4850. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4851.  
  4852. The purpose of the heap allocator is to provide a memory manager service to
  4853. system components to allocate small (i.e., less than a page size) blocks of
  4854. memory for long term or short term use.  %@NL@%
  4855.  
  4856. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4857. NOTE
  4858.  
  4859. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  4860. %@AI@%procedure has an underscore in front (i.e., %@AB@%HeapAllocate%@AE@%%@AI@% is actually
  4861. %@AI@%%@AE@%%@AI@%%@AB@%_HeapAllocate%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to left (unlike the PL/M
  4862. %@AI@%calling convention used by Windows, which is left to right). The return
  4863. %@AI@%value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the responsibility of the
  4864. %@AI@%caller%@AE@%%@AI@%to clear the arguments off the stack. Registers %@AE@%%@AI@%%@AB@%EAX%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ECX%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EDX%@AE@%%@AE@%%@AI@% are
  4865. %@AI@%changed by calls. Registers %@AE@%%@AI@%%@AB@%DS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ES%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%FS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%GS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EBP%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EDI
  4866. %@AB@%%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ESI%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved.%@AE@%%@AE@%
  4867. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4868. The heap uses a boundary tag allocation scheme similar to the one used by
  4869. the MS-DOS operating system. This has the benefit of not placing some fixed
  4870. limit on the total number of heap blocks. It has the disadvantage of having
  4871. a fixed overhead of extra space per block. The heap overhead is about 16
  4872. bytes per block. Users should keep this in mind when allocating lots of
  4873. objects of small size. Try to combine such needs into larger heap blocks to
  4874. cut down on the overhead.  %@NL@%
  4875.  
  4876. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4877. %@AU@%WARNING %@AE@%
  4878.  
  4879. You are strongly warned against making assumptions about the placement and
  4880. size of the heap boundary tag structures. Future versions of enhanced
  4881. Windows may change this behavior of the heap.
  4882. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4883.  
  4884. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4885. NOTE
  4886.  
  4887. %@AI@%4 byte (DWORD) alignment is maintained on heap blocks. This could be
  4888. %@AI@%increased in a later version, but at least DWORD alignment is guaranteed. %@AE@%
  4889. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4890.  
  4891. %@CR:C6A00190049 @%%@CR:C6A00190050 @%
  4892. %@2@%%@CR:C6A00190051 @%%@AB@%HeapAllocate%@AE@%%@EH@%%@NL@%
  4893. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4894.  
  4895. %@AS@%  unsigned HeapAllocate(nbytes,flags) 
  4896. %@AS@%     unsigned nbytes;
  4897. %@AS@%     unsigned flags;%@AE@%
  4898.  
  4899. This is the call to allocate a block from the heap. %@AI@%nbytes%@AE@% is a 32 bit
  4900. unsigned integer which is the size, in bytes, of the block. Current flags
  4901. bits:  %@NL@%
  4902.  
  4903. %@AS@%  HeapZeroInit EQU  00000000000000000000000000000001B%@AE@%
  4904.  
  4905. All unused bits %@AI@%must be zero%@AE@%. HeapZeroInit, if set, indicates that if the
  4906. allocation is succesful, the memory is to be initialized with value 0 in all
  4907. bytes of the block. If HeapZeroInit is clear, the block will have completely
  4908. random values in it.  %@NL@%
  4909.  
  4910.  
  4911. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4912.  
  4913. The return value is the 32 bit RING 0 address (offset relative to standard
  4914. enhanced Windows RING 0 DS) of the block. Value is 0 if the allocation
  4915. failed (insufficient memory).  %@NL@%
  4916.  
  4917.  
  4918. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4919.  
  4920. Blocks are DWORD aligned as noted, but sizes do not have to be a multiple of
  4921. 4.  %@NL@%
  4922.  
  4923. There is no "protection" of the heap. Care must be taken not to overrun the
  4924. size of your block. Failure to do this will result in odd behavior and
  4925. crashes.  %@NL@%
  4926.  
  4927. There is no "motion" of blocks in the heap (heap blocks are all fixed),
  4928. except via %@AB@% HeapReAllocate%@AE@%, and therefore no compaction. You are advised not
  4929. to use the heap in such a way as to severely fragment it. You will end up
  4930. wasting lots of memory by doing this.  %@NL@%
  4931.  
  4932. The Flag bit equates are defined by including VMM.INC, please use the
  4933. equates.  %@NL@%
  4934.  
  4935. Allocation of 0 length heap blocks is not allowed.  %@NL@%
  4936.  
  4937. %@CR:C6A00190052 @%%@CR:C6A00190053 @%
  4938. %@2@%%@CR:C6A00190054 @%%@AB@%HeapFree%@AE@%%@EH@%%@NL@%
  4939. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4940.  
  4941. %@AS@%  unsigned HeapFree(hAddress,flags) 
  4942. %@AS@%     unsigned hAddress;
  4943. %@AS@%     unsigned flags;%@AE@%
  4944.  
  4945. This call is used to free an existing block of heap. %@AI@%hAddress%@AE@% is the value
  4946. returned from a previous call to %@AB@%HeapAllocate%@AE@% or %@AB@%HeapReAllocate%@AE@% and
  4947. indicates the block to be freed. There are currently no bits defined in the
  4948. %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4949.  
  4950.  
  4951. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4952.  
  4953. Returns nonzero value if the block was succesfully freed, zero if the free
  4954. was unsuccesful (invalid %@AI@%hAddress%@AE@%).  %@NL@%
  4955.  
  4956. %@CR:C6A00190055 @%%@CR:C6A00190056 @%
  4957. %@2@%%@CR:C6A00190057 @%%@AB@%HeapGetSize%@AE@%%@EH@%%@NL@%
  4958. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4959.  
  4960. %@AS@%  unsigned HeapGetSize(hAddress,flags)
  4961. %@AS@%     unsigned hAddress;
  4962. %@AS@%     unsigned flags;%@AE@%
  4963.  
  4964. This call is used to get the size of an existing block of heap.%@AI@% hAddress%@AE@% is
  4965. the value returned from a previous call to %@AB@%HeapAllocate%@AE@% or %@AB@%HeapReAllocate%@AE@%
  4966. and indicates the block to get the size of. There are currently no bits
  4967. defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4968.  
  4969.  
  4970. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4971.  
  4972. Returns the size, in bytes, of the block. Returns zero if there was an error
  4973. (invalid %@AI@%hAddress%@AE@%).  %@NL@%
  4974.  
  4975. %@CR:C6A00190058 @%%@CR:C6A00190059 @%
  4976. %@2@%%@CR:C6A00190060 @%%@AB@%HeapReAllocate%@AE@%%@EH@%%@NL@%
  4977. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4978.  
  4979. %@AS@%  unsigned HeapReAllocate(hAddress,nbytes,flags)
  4980. %@AS@%     unsigned hAddress;
  4981. %@AS@%     unsigned nbytes;
  4982. %@AS@%     unsigned flags;%@AE@%
  4983.  
  4984. This call is used to grow or shrink or reinitialize an existing block of
  4985. heap. %@AI@%hAddress%@AE@% is the value returned from a previous %@AB@%HeapAllocate%@AE@% or
  4986. %@AB@%HeapReAllocate%@AE@% call and indicates the block to be reallocated. %@AI@%nbytes%@AE@% is a
  4987. 32 bit unsigned integer which is the new size in bytes of the block. Current
  4988. flags bits:  %@NL@%
  4989.  
  4990. %@AS@%  HeapZeroInit  EQU 00000000000000000000000000000001B HeapZeroReInit  EQU
  4991. %@AS@%00000000000000000000000000000010B HeapNoCopy  EQU
  4992. %@AS@%00000000000000000000000000000100B%@AE@%
  4993.  
  4994. All unused bits %@AI@%must be zero.%@AE@% %@AB@%HeapZeroInit%@AE@%, if set, indicates that if the
  4995. reallocation is succesful, and the reallocation is growing the size of the
  4996. block, the "grow area" of the block is to be initialized with value 0 in all
  4997. bytes. This bit is ignored on a reallocation which is not growing the size
  4998. of the block. %@AB@%HeapZeroReInit%@AE@%, if set, indicates that the ENTIRE block is to
  4999. be reinitialized with value zero in all bytes of the block. HeapNoCopy, if
  5000. set, indicates that the previous contents of the block are irrelevant, and
  5001. don't need to be copied into the newly sized block. There is no reason that
  5002. more than one of these bits should be set. If none of the bits are set, the
  5003. previous contents of the block are copied into the new block, up to the
  5004. lesser of the size of the new block, and the size of the old block, and the
  5005. "grow area", if any, is not initialized with anything.  %@NL@%
  5006.  
  5007.  
  5008. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5009.  
  5010. The return value is the 32 bit RING 0 address (offset relative to standard
  5011. enhanced Windows RING 0 DS) of the new block. Value is 0 if the reallocation
  5012. failed (insufficient memory, or invalid %@AI@%hAddress%@AE@%).  %@NL@%
  5013.  
  5014.  
  5015. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5016.  
  5017. Do not make assumptions about the relationship between the passed in
  5018. %@AI@%hAddress%@AE@% and the %@AI@%hAddress%@AE@% returned. Assume that the returned%@AI@% hAddress%@AE@% is
  5019. always different than the passed in %@AI@%hAddress%@AE@%.  %@NL@%
  5020.  
  5021. In the case where this call fails, the passed in %@AI@%hAddress%@AE@% block remains
  5022. valid. In the case where this call works and returns a new %@AI@%hAddress%@AE@%, the
  5023. passed in %@AI@%hAddress%@AE@% is no longer valid (old block has been HeapFreed).  %@NL@%
  5024.  
  5025. There is no "protection" of the heap. Care must be taken not to overrun the
  5026. size of your block. Failure to do this will result in odd behavior and
  5027. crashes.  %@NL@%
  5028.  
  5029. There is no "motion" of blocks in the heap (heap blocks are all fixed), and
  5030. therefore no compaction. You are advised not to use the heap in such a way
  5031. as to severely fragment it. You will end up wasting lots of memory by doing
  5032. this.  %@NL@%
  5033.  
  5034. Note that this call can be used to reset the contents of an existing heap
  5035. block to 0 by setting nbytes to the current size of the block and setting
  5036. %@AB@%HeapZeroReInit%@AE@%.  %@NL@%
  5037.  
  5038. You cannot %@AB@%HeapReAllocate%@AE@% a block to size 0, use %@AB@%HeapFree%@AE@%.  %@NL@%
  5039.  
  5040. The Flag bit equates are defined by including VMM.INC, please use the
  5041. equates.  %@NL@%
  5042.  
  5043.  
  5044. %@2@%%@CR:C6A00190061 @%%@AB@%19.5  System Page Allocator%@AE@%%@EH@%%@NL@%
  5045. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5046.  
  5047. The page allocator is the set of services by which system memory is
  5048. allocated and mapped into a VM's linear address space. VxD's can also
  5049. examine and modify the status of mapped pages and lock or unlock pages into
  5050. physical memory. VxD's can also allocate pages for the VxD's exclusive use.
  5051. For example, the current state of the video memory can be saved for
  5052. clipboard operations.  %@NL@%
  5053.  
  5054. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5055. NOTE
  5056.  
  5057. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  5058. %@AI@%procedure has an underscore in front (i.e., %@AB@%PageAllocate%@AE@%%@AI@% is actually
  5059. %@AI@%%@AE@%%@AI@%%@AB@%_PageAllocate%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to left (unlike the PL/M
  5060. %@AI@%calling convention used by Windows, which is left to right). The return
  5061. %@AI@%value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the responsibility of the
  5062. %@AI@%caller%@AE@%%@AI@%to clear the arguments off the stack. Registers %@AE@%%@AI@%%@AB@%EAX%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ECX%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EDX%@AE@%%@AE@%%@AI@% are
  5063. %@AI@%changed by calls. Registers %@AE@%%@AI@%%@AB@%DS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ES%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EBP%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EDI%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ESI%@AE@%%@AE@%%@AI@%, and
  5064. %@AI@%@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved.%@AE@%%@AE@%
  5065. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5066.  
  5067. %@CR:C6A00190062 @%%@CR:C6A00190063 @%
  5068. %@2@%%@CR:C6A00190064 @%%@AB@%CopyPageTable%@AE@%%@EH@%%@NL@%
  5069. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5070.  
  5071. %@AS@%  unsigned CopyPageTable(LinPgNum,nPages,PageBufPTR,flags)
  5072. %@AS@%     unsigned LinPgNum;
  5073. %@AS@%     unsigned nPages;
  5074. %@AS@%     unsigned *PageBufPTR;
  5075. %@AS@%     unsigned flags;%@AE@%
  5076.  
  5077. This call is used to obtain a copy of an enhanced Windows page table. This
  5078. call is intended as an assist to enhanced Windows system components that
  5079. need to analyze the linear to physical mapping (such as DMA devices).
  5080. %@AI@%LinPgNum%@AE@% is the page number of the first page of the range. This can be
  5081. anything in the range 0 - 0FFFFFh. Thus addresses in the range 0-3FFh refer
  5082. to addresses in the 1M V86 address space of the current VM. To compute the
  5083. page number of any region simply take the address relative to the standard
  5084. enhanced Windows RING 0 DS and shift it right by 12 bits. For example, the
  5085. linear address 60001AB6h is in page number 60001h. Alignment considerations
  5086. of this address (beyond 4K alignment) are the responsibility of the caller.
  5087. %@AI@%nPages%@AE@% is the number of page table entries to copy. %@AI@%PageBufPTR%@AE@% is a 32 bit
  5088. RING 0 offset relative to the standard RING 0 DS which is the address of a
  5089. buffer where the page table will be copied. Caller must insure that this
  5090. buffer is large enough. Each page table entry is a DWORD, so the buffer must
  5091. be at least nPages*4 bytes long. There are currently no bits defined in the
  5092. %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5093.  
  5094.  
  5095. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5096.  
  5097. Returns a nonzero value if the copy is succesful, returns 0 value if the
  5098. copy was succesful, %@AI@%but%@AE@% at least a part of the range overlapped a region
  5099. where the corresponding page directory entry is not present.  %@NL@%
  5100.  
  5101.  
  5102. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5103.  
  5104. You get a copy of the page table; writing to your buffer has no effect.  %@NL@%
  5105.  
  5106. Note that V86 page tables stop at page 10Fh.  %@NL@%
  5107.  
  5108. To look at the page table of a VM that is not the current VM simply use the
  5109. high linear address of the VM. For instance, to look at the page table
  5110. starting at V86 address 0A000:0 of a VM which is not the current VM:  %@NL@%
  5111.  
  5112. %@AS@%  mov eax,0A0000h   ; V86 linear adress of 0A000:0 
  5113. %@AS@%  add eax,[ebx.CB_High_Linear] ; High linear address
  5114. %@AS@%  shr eax,12   ; Convert to page number%@AE@%
  5115.  
  5116. Note that the above sequence always works correctly (works if the VM is the
  5117. current VM as well). So simply doing this in all cases avoids the
  5118. complication of worrying about whether the VM is the current VM.  %@NL@%
  5119.  
  5120. The intent of this call is for you to look at the physical addresses in the
  5121. high 20 bits of the entries. The low 12 bits of system information may be
  5122. examined however.  %@NL@%
  5123.  
  5124. You are warned to be careful about keeping this buffer for any length of
  5125. time. The actual page table entries can change while the copy you have
  5126. won't. The information in the copy should be analyzed quickly.  %@NL@%
  5127.  
  5128. %@CR:C6A00190065 @%%@CR:C6A00190066 @%
  5129. %@2@%%@CR:C6A00190067 @%%@AB@%GetDemandPageInfo%@AE@%%@EH@%%@NL@%
  5130. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5131.  
  5132. %@AS@%  void GetDemandPageInfo(BufPtr,flags)
  5133. %@AS@%     DemandInfoStruc *BufPtr;
  5134. %@AS@%     unsigned flags;%@AE@%
  5135.  
  5136. This call is for use by the demand paging device. It provides information
  5137. for the demand pager.  %@NL@%
  5138.  
  5139. %@AS@%  DemandInfoStruc struc
  5140. %@AS@%    DILin_Total_Count  dd ?   ; Size of linear address space in pages
  5141. %@AS@%    DIPhys_Count   dd ?   ; Count of phys pages
  5142. %@AS@%    DIFree_Count   dd ?   ; Count of free phys pages
  5143. %@AS@%    DIUnlock_Count   dd ?   ; Count of unlocked phys Pages
  5144. %@AS@%    DILinear_Base_Addr  dd ?   ; Base of pageable address space
  5145. %@AS@%    DILin_Total_Free  dd ?   ; Total free linear pages
  5146. %@AS@%    DIReserved   dd 12 DUP(?) ; Reserved 
  5147. %@AS@%  DemandInfoStruc ends%@AE@%
  5148.  
  5149. DILin_Total_Count is the size in pages of the linear address space subject
  5150. to demand paging. DILinear_Base_Addr is the linear address of the start of
  5151. the demand pageable region. Thus there are DILin_Total_Count pages starting
  5152. at address DILinear_Base_Addr which are subject to demand paging.
  5153. DILin_Total_Free is the number of the DILin_Total_Count pages which are
  5154. currently free. Notice that this space may not be allocatable in a single
  5155. block, it is the total free, not the size of the largest free block. Note
  5156. that if DILinear_Base_Addr == 0, this means that the demand pageable region
  5157. of the system is not contiguous. DIPhys_Count is the total number of
  5158. physical pages under the control of the memory manager. DIFree_Count is the
  5159. number of pages currently on the free list. DIUnlock_Count is the count of
  5160. pages which are currently unlocked, notice that free pages are unlocked.
  5161. There are currently no bits defined in the flags, this parameter must be set
  5162. to 0.  %@NL@%
  5163.  
  5164.  
  5165. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5166.  
  5167. This call does not have a return value. It simply fills in the structure
  5168. pointed to by %@AI@%BufPtr%@AE@%.  %@NL@%
  5169.  
  5170.  
  5171. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5172.  
  5173. The reserved field is exactly that, reserved. Do not make any assumptions
  5174. about what is in this region. Behavior will change in later releases.  %@NL@%
  5175.  
  5176. %@CR:C6A00190068 @%%@CR:C6A00190069 @%
  5177. %@2@%%@CR:C6A00190070 @%%@AB@%GetFreePageCount%@AE@%%@EH@%%@NL@%
  5178. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5179.  
  5180. %@AS@%  unsigned long (flags)
  5181. %@AS@%     unsigned flags;%@AE@%
  5182.  
  5183. This call is used to obtain the count of free 4K pages. And the count of
  5184. pages that can be allocated as PageLocked. There are currently no bits
  5185. defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5186.  
  5187.  
  5188. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5189.  
  5190. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5191. Low DWORD (%@AB@%EAX%@AE@%) is the 32 bit count of free 4K pages in the system which
  5192. could be allocated with the %@AB@%PageAllocate%@AE@% call. The High DWORD (%@AB@%EDX%@AE@%) is the
  5193. 32 bit count of pages available for allocation as PageLocked pages at the
  5194. current time.  %@NL@%
  5195.  
  5196.  
  5197. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5198.  
  5199. You should be careful about making assumptions about being able to turn
  5200. around and issue a call to allocate all of the pages returned by this call.
  5201. Besides any alignment considerations, it is possible someone could get in
  5202. and allocate some or all of the pages before you. This call is intended to
  5203. be advisory in nature.  %@NL@%
  5204.  
  5205. Note that, in a demand paged virtual memory system such as enhanced Windows,
  5206. the free pages count is usually very close to 0. It is more relevant to use
  5207. the %@AB@%EDX%@AE@% return to make judgements about allocation possibility. %@AB@%EDX%@AE@% contains
  5208. the count of pages currently available for allocation as %@AB@%PageLocked%@AE@% pages.
  5209. Note that many assumptions are not valid. %@AB@%EAX%@AE@%<=%@AB@%EDX%@AE@% is %@AI@%not%@AE@% a valid assumption
  5210. for instance.  %@NL@%
  5211.  
  5212. Note that in a virtual memory environment it is not a good idea to go
  5213. soaking up tons of virtual address space. Start with some, then
  5214. %@AB@%PageReAllocate%@AE@% it to make it bigger if needed.  %@NL@%
  5215.  
  5216. %@CR:C6A00190071 @%%@CR:C6A00190072 @%
  5217. %@2@%%@CR:C6A00190073 @%%@AB@%GetSetPageOutCount%@AE@%%@EH@%%@NL@%
  5218. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5219.  
  5220. %@AS@%  unsigned GetSetPageOutCount(NewCount,flags)
  5221. %@AS@%     unsigned NewCount;
  5222. %@AS@%     unsigned flags;%@AE@%
  5223.  
  5224. This call is for use by the demand paging device. It allows the paging
  5225. device to manipulate a memory manager parameter associated with demand
  5226. paging. This parameter is the "page out ahead" count. Whenever a page is
  5227. paged out to satisfy a page in, an additional PageOutCount-1 pages are also
  5228. paged out and put on the free list (if possible).There is one bit in the
  5229. flags:  %@NL@%
  5230.  
  5231. %@AS@%  GSPOC_F_Get  equ   00000000000000000000000000000001B%@AE@%
  5232.  
  5233. All other bits must be zero. If GSPOC_F_Get is set, the call returns the
  5234. current value of the page out count in %@AB@%EAX%@AE@%, and the %@AI@%NewCount%@AE@% parameter is
  5235. ignored. If GSPOC_F_Get is not set, the call sets the value of the page out
  5236. count to %@AI@%NewCount%@AE@%.  %@NL@%
  5237.  
  5238.  
  5239. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5240.  
  5241. Returns the page out count if GSPOC_F_Get is set, else it has no return.  %@NL@%
  5242.  
  5243. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5244. %@AU@%WARNING%@AE@%
  5245.  
  5246. This call is intended for use by the PageSwap device, others should not be
  5247. calling it. Others making this call can disturb the operation of the
  5248. PageSwap device.
  5249. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5250.  
  5251.  
  5252. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5253.  
  5254. There is an equate for the flag bit in VMM.INC, use the equate.  %@NL@%
  5255.  
  5256. %@CR:C6A00190074 @%%@CR:C6A00190075 @%
  5257. %@2@%%@CR:C6A00190076 @%%@AB@%GetSysPageCount%@AE@%%@EH@%%@NL@%
  5258. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5259.  
  5260. %@AS@%  unsigned GetSysPageCount(flags)
  5261. %@AS@%     unsigned flags;%@AE@%
  5262.  
  5263. This call is used to obtain the current count of system (PG_SYS) 4K pages.
  5264. There are currently no bits defined in the %@AI@%flags%@AE@%, and this parameter must be
  5265. set to 0.  %@NL@%
  5266.  
  5267.  
  5268. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5269.  
  5270. The return value is the 32 bit count of 4K pages allocated as PG_SYS pages
  5271. in the system.  %@NL@%
  5272.  
  5273.  
  5274. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5275.  
  5276.  It is generally true that this number is the size of enhanced Windows.
  5277. However, this is the general case only.  %@NL@%
  5278.  
  5279. %@CR:C6A00190077 @%%@CR:C6A00190078 @%
  5280. %@2@%%@CR:C6A00190079 @%%@AB@%GetVMPgCount%@AE@%%@EH@%%@NL@%
  5281. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5282.  
  5283. %@AS@%  unsigned long GetVMPgCount(VMHandle,flags)
  5284. %@AS@%     unsigned VMHandle;
  5285. %@AS@%     unsigned flags;%@AE@%
  5286.  
  5287. This call is used to get the current count of 4K pages allocated to a
  5288. particular VM. The %@AI@%VMHandle%@AE@% parameter must be a valid VM handle and
  5289. indicates the VM to get the allocated page count of. There are currently no
  5290. bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5291.  
  5292.  
  5293. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5294.  
  5295. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5296. Low DWORD (%@AB@%EAX%@AE@%) is the total count of pages (of all types but PG_SYS) in the
  5297. system allocated for this VM. The High DWORD (%@AB@%EDX%@AE@%) is the count of pages
  5298. which are allocated to this VM, but which are not mapped into the VM's 1Meg
  5299. address space at the current time. Value (both dwords) is 0 if the call
  5300. failed (invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  5301.  
  5302.  
  5303. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5304.  
  5305. You should be careful about assuming that %@AB@%EAX-EDX%@AE@% is the size of the VM. It
  5306. is in one sense, but not in the standard MS-DOS senses.  %@NL@%
  5307.  
  5308. %@CR:C6A00190080 @%%@CR:C6A00190081 @%
  5309. %@2@%%@CR:C6A00190082 @%%@AB@%MapIntoV86%@AE@%%@EH@%%@NL@%
  5310. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5311.  
  5312. %@AS@%  unsigned MapIntoV86(hMem,VMHandle,VMLinPgNum,nPages,PageOff,flags)
  5313. %@AS@%     unsigned hMem;
  5314. %@AS@%     unsigned VMHandle;
  5315. %@AS@%     unsigned VMLinPgNum;
  5316. %@AS@%     unsigned nPages;
  5317. %@AS@%     unsigned PageOff;
  5318. %@AS@%     unsigned flags;%@AE@%
  5319.  
  5320. This call is used to map some or all of the pages of a memory block into a
  5321. specific VM's Virtual 8086 address space.%@AI@% hMem%@AE@% is the value returned from a
  5322. previous call to %@AB@%PageAllocate%@AE@% or %@AB@%PageReAllocate%@AE@% and indicates the block to
  5323. be mapped. %@AI@%VMHandle%@AE@% parameter must be a valid VM handle and indicates the VM
  5324. into which the map is to occur. %@AI@%VMLinPgNum%@AE@% is the address in the 1M V86
  5325. address space where the map will start (this is a page number, thus linear
  5326. address 60000h = page 60h). Alignment considerations of this address (beyond
  5327. 4K alignment) are the responsibility of the caller. Map addresses below page
  5328. 10h, or above 10Fh will cause an error. %@AI@%nPages%@AE@% is the number of pages to
  5329. map. %@AI@%PageOff %@AE@%is the number of pages into the %@AI@%hMem%@AE@% block to the first page of
  5330. the block which is to be mapped at %@AI@%VMLinPgNum%@AE@% (thus PageOff is 0 to map the
  5331. first page of %@AI@%hMem%@AE@% at VMLinPgNum). %@AI@%nPages%@AE@% and %@AI@%PageOff%@AE@% allow one %@AI@%hMem%@AE@% block
  5332. to be scatter mapped into different VM locations. An error will occur if
  5333. %@AI@%PageOff%@AE@% +%@AI@% nPages%@AE@% is greater than the size of %@AI@%hMem%@AE@%.  %@NL@%
  5334.  
  5335. Current flags bits:  %@NL@%
  5336.  
  5337. %@AS@%  PageDEBUGNulFault  EQU 00000000000000000000000000010000B%@AE@%
  5338.  
  5339. All unused bits must be zero. PageDEBUGNulFault, if set, indicates that if
  5340. %@AI@%hMem%@AE@% is the handle of the NUL system page, and this is the DEBUG version of
  5341. enhanced Windows, access to these pages should cause a page fault DEBUG
  5342. exception. This bit is ignored if %@AI@%hMem%@AE@% is not the system NUL page handle, or
  5343. this is not enhanced Windows DEBUG.  %@NL@%
  5344.  
  5345. It is generally true that %@AI@%hMem%@AE@% blocks mapped with this call should not be
  5346. composed of PG_SYS pages. This is not disallowed, but is not advised.  %@NL@%
  5347.  
  5348. There is a special %@AI@%hMem%@AE@% handle that can be used with this call. The value of
  5349. this handle is obtained by calling the routine %@AB@%GetNulPageHandle%@AE@% (actual name
  5350. %@AB@%_GetNulPageHandle%@AE@%) which will return you this special %@AI@%hMem%@AE@% handle in %@AB@%EAX%@AE@%.
  5351. This is the %@AI@%hMem %@AE@%of the system NUL page. This page is used to occupy regions
  5352. of the address space which are "unused" but for which it is not desirable to
  5353. cause a page fault if they are accessed. The NUL page is multiply mapped at
  5354. many locations in the system, so its contents are always random. Under
  5355. enhanced Windows DEBUG, a fault occurs if the NUL page is touched and the
  5356. PageDEBUGNulFault bit was set on the call which mapped the page.  %@NL@%
  5357.  
  5358. If the %@AB@%PageSwap%@AE@% device is type one (%@AI@%not%@AE@% direct to hardware), there is an
  5359. %@AI@%implied%@AE@% PageLock on the pages mapped with this call, and an %@AI@%implied%@AE@%
  5360. %@AB@%PageUnlock%@AE@% on the pages which this call is mapping over. This is consistent
  5361. with the fact that pages mapped into V86 address space must be locked (V86
  5362. memory cannot be demand paged). If the %@AB@%PageSwap%@AE@% device is type two (direct
  5363. to hardware) than the implied lock and unlock done by this call are disabled
  5364. because in the case of a type two %@AB@%PageSwap%@AE@% device V86 memory CAN be demand
  5365. paged. See the %@AB@%PageAllocate%@AE@% documentation for a description of the different
  5366. %@AB@%PageSwap%@AE@% device types and their relevance.  %@NL@%
  5367.  
  5368.  
  5369. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5370.  
  5371. Returns a nonzero value if the map is succesful, returns 0 value if the map
  5372. was unsuccesful (invalid %@AI@%hMem,%@AE@% invalid %@AI@%VMHandle%@AE@%, map range illegal, size
  5373. discrepancy, insufficient memory on implied PageLock).  %@NL@%
  5374.  
  5375.  
  5376. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5377.  
  5378. The implied %@AB@%PageLock%@AE@%, which is performed on all of the pages mapped if the
  5379. %@AB@%PageSwap%@AE@% device is type oneAg, is consistent with the fact that V86 memory
  5380. cannot be Demand Paged while the VM is in a runable state. Whenever the V86
  5381. memory mapping is changed via %@AB@%MapIntoV86%@AE@%, the previous memory that was
  5382. mapped in that region of the VM is unlocked. The correct way to think of
  5383. this is that there is an implied %@AB@%PageLock%@AE@% whenever memory is mapped into a
  5384. V86 context, and an implied %@AB@%PageUnlock%@AE@% whenever it is "unmapped" from the
  5385. V86 context. This "unmapping" can occur when: A different handle (including
  5386. the NulPageHandle) is %@AB@%MapIntoV86ed %@AE@%or %@AB@%LinMapIntoV86ed%@AE@% to the region, or a
  5387. %@AB@%PhysIntoV86%@AE@% is performed to the region.  %@NL@%
  5388.  
  5389. There is nothing to prevent you from mapping the same block, or piece of a
  5390. block, into multiple places in a VM, or into multiple VMs. Such operations
  5391. are not particularly advisable though. For one thing, the reporting of
  5392. memory owned by a VM will be disturbed. For this reason it is also not
  5393. generally a good idea to map pages that were allocated as belonging to one
  5394. VM into a different VM. The one exception to this general rule is the
  5395. request for a map by one VM to look at the memory of a different VM. Such
  5396. maps should be of a relatively short duration.  %@NL@%
  5397.  
  5398. The page attributes for these pages will be P_USER+P_PRES+P_WRITE. P_DIRTY
  5399. and P_ACC will be cleared by the call. PG_TYPE will be set to whatever the
  5400. type of the hMem pages are.  %@NL@%
  5401.  
  5402. The Flag bit equates are defined by including VMM.INC, please use the
  5403. equates.  %@NL@%
  5404.  
  5405. The intent of %@AB@%MapIntoV86 %@AE@%support for pages between page 10h and FirstV86Page
  5406. is to support WIN386 devices which have %@AB@%Allocate_Global_V86_Data_Area%@AE@% a
  5407. %@AB@%GVDAPageAlign%@AE@% region. Use of mapping in this region to other addresses can
  5408. easily crash the system and should be avoided.  %@NL@%
  5409.  
  5410. Regions which span across %@AB@%FirstV86Page%@AE@% are not allowed.  %@NL@%
  5411.  
  5412. The reason for the page 10h limitation is that on most versions of the Intel
  5413. 80386 CPU there is an errata which prevents you from setting up a Linear !=
  5414. Physical address mapping in the first 64K of the address space.  %@NL@%
  5415.  
  5416. %@CR:C6A00190083 @%%@CR:C6A00190084 @%
  5417. %@2@%%@CR:C6A00190085 @%%@AB@%ModifyPageBits%@AE@%%@EH@%%@NL@%
  5418. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5419.  
  5420. %@AS@%  unsigned
  5421. %@AS@%ModifyPageBits(VMHandle,VMLinPgNum,nPages,bitAND,bitOR,pType,flags)
  5422. %@AS@%     unsigned VMHandle;
  5423. %@AS@%     unsigned VMLinPgNum;
  5424. %@AS@%     unsigned nPages;
  5425. %@AS@%     unsigned bitAND;
  5426. %@AS@%     unsigned bitOR;
  5427. %@AS@%     unsigned pType;
  5428. %@AS@%     unsigned flags;%@AE@%
  5429.  
  5430. This call is used to modify the page protection bits associated with
  5431. PG_HOOKED pages in the V86 address space of a VM. It allows the P_PRES,
  5432. P_WRITE, and P_USER bits of the pages to be modified along with PG_TYPE if
  5433. appropriate. The %@AI@%VMHandle %@AE@%parameter must be a valid VM Handle and indicates
  5434. the VM whose page bits are to be modified. %@AI@%VMLinPgNum%@AE@% is the page number in
  5435. the 1M V86 VM address space where the modification will start (this is a
  5436. page number, thus linear address A0000h = page A0h). When clearing the
  5437. P_PRES bit (making pages not present), all of the pages specified (%@AI@%nPages%@AE@%
  5438. starting at %@AI@%VMLinPgNum%@AE@%) must be PG_HOOKED pages for which a HOOK Page Fault
  5439. handler has been registered, and %@AI@%pType%@AE@% must be PG_HOOKED. %@AI@%nPages%@AE@% is the
  5440. number of pages to modify the bits of. Addresses below the start of VM
  5441. specific memory, or above 10Fh will cause an error. %@AI@%bitAND%@AE@% is an AND mask
  5442. for the bits, %@AI@%bitOR%@AE@% is an OR mask. Thus to clear P_PRES, P_WRITE, and
  5443. P_USER, %@AI@%bitAND%@AE@% would be (%@AI@%not%@AE@% P_PRES+P_WRITE+P_USER), and %@AI@%bitOR%@AE@% would be
  5444. zero. To set P_USER, and clear P_WRITE, leaving P_PRES unchanged, bitAND
  5445. would be (NOT P_WRITE), and %@AI@%bitOR%@AE@% would be P_USER. Having bits other than
  5446. P_WRITE, and P_USER set in %@AI@%bitOR%@AE@% will cause an error. Having bits other than
  5447. P_PRES, P_WRITE, and P_USER clear in %@AI@%bitAND%@AE@% will cause an error.  %@NL@%
  5448.  
  5449. This call always has the side effect of clearing P_DIRTY and P_ACC. Thus to
  5450. just clear these two bits, give a %@AI@%bitAND%@AE@% of 0FFFFFFFFh, and a %@AI@%bitOR%@AE@% of 0.%@AI@%
  5451. %@AI@%pType%@AE@% indicates a value to be placed in the PG_TYPE field. The allowed
  5452. values are:  %@NL@%
  5453.  
  5454. %@AS@%  PG_HOOKED   EQU 7
  5455. %@AS@%  PG_IGNORE   EQU -1 (0FFFFFFFFh)%@AE@%
  5456.  
  5457. Any other value will cause an error. PG_IGNORE indicates that the PG_TYPE
  5458. field is not to be modified by the call. This is the value that %@AI@%must%@AE@% be set
  5459. if P_PRES bit is being set (or being left set). PG_HOOKED must be specified
  5460. if the P_PRES bit is being cleared by the call. Recall that making a
  5461. PhysIntoVM call sets the type field for the physical pages to PG_SYS. This
  5462. parameter is provided so that the page types can be reset to PG_HOOKED when
  5463. the mapping is changed to not present. Recall that MapIntoVM also resets the
  5464. PG_TYPE field to the type of the pages of %@AI@%hMem.%@AE@% There are currently no bits
  5465. defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5466.  
  5467.  
  5468. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5469.  
  5470. Returns a nonzero value if successful, returns 0 value if unsuccessful
  5471. (invalid %@AI@%VMHandle,%@AE@% invalid bits in %@AI@%bitAND%@AE@% or %@AI@%bitOR,%@AE@% invalid %@AI@%pType,%@AE@% page
  5472. range bad).  %@NL@%
  5473.  
  5474.  
  5475. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5476.  
  5477. You cannot use this call to set the Present bit. You may either clear the
  5478. present bit, or leave it unaffected. Use %@AB@%MapIntoV86 %@AE@%or %@AB@%PhysIntoV86%@AE@% to make
  5479. pages present.  %@NL@%
  5480.  
  5481. %@CR:C6A00190086 @%%@CR:C6A00190087 @%
  5482. %@2@%%@CR:C6A00190088 @%%@AB@%PageAllocate%@AE@%%@EH@%%@NL@%
  5483. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5484.  
  5485. %@AS@%  unsigned PageAllocate(nPages,pType,VMHandle,AlignMask,minPhys,
  5486. %@AS@%maxPhys,PhysAddrPTR,flags)
  5487. %@AS@%    unsigned nPages;
  5488. %@AS@%    unsigned pType;
  5489. %@AS@%    unsigned VMHandle;
  5490. %@AS@%    unsigned AlignMask;
  5491. %@AS@%    unsigned minPhys;
  5492. %@AS@%    unsigned maxPhys;
  5493. %@AS@%    unsigned *PhysAddrPTR;
  5494. %@AS@%    unsigned flags;%@AE@%
  5495.  
  5496. This is the call to allocate a block of memory. The memory allocated is
  5497. actually just linear address space, whether there is actually physical
  5498. memory mapped for this block as part of the allocation is specified by the
  5499. flags.%@AI@% nPages%@AE@% is a 32 bit unsigned integer which is the size in 4K pages of
  5500. the block. %@AI@%pType%@AE@% indicates the type of page(s) being allocated:  %@NL@%
  5501.  
  5502. %@AS@%  PG_VM  EQU  0 
  5503. %@AS@%  PG_SYS  EQU  1 
  5504. %@AS@%  PG_HOOKED EQU  7 %@AE@%
  5505.  
  5506. PG_VM pages are pages which are specific to a particular VM context. The
  5507. handle of PG_VM memory blocks will typically be placed in the VM Control
  5508. Block someplace. PG_HOOKED pages are pages which will be mapped into the VM
  5509. at locations where the component has registered a HookPageFault handler.
  5510. Like PG_VM pages, PG_HOOKED pages are specific to a particular VM context.
  5511. The %@AI@%VMHandle%@AE@% parameter must be a valid VM Handle for all page types except
  5512. PG_SYS. PG_SYS pages are global system pages which are valid in all VM
  5513. contexts (pages are specific to the enhanced Windows system component which
  5514. allocates them, rather than to a VM). The %@AI@%VMHandle%@AE@% parameter is not relevant
  5515. to PG_SYS pages and it %@AI@%must%@AE@% be set to 0 when allocating PG_SYS pages.  %@NL@%
  5516.  
  5517. Current flags bits:  %@NL@%
  5518.  
  5519. %@AS@%  PageZeroInit  EQU 00000000000000000000000000000001B 
  5520. %@AS@%  PageUseAlign  EQU 00000000000000000000000000000010B
  5521. %@AS@%  PageContig  EQU 00000000000000000000000000000100B
  5522. %@AS@%  PageFixed  EQU 00000000000000000000000000001000B
  5523. %@AS@%  PageLocked  EQU 00000000000000000000000010000000B PageLockedIfDP  EQU
  5524. %@AS@%00000000000000000000000100000000B%@AE@%
  5525.  
  5526. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLocked%@AE@%, if set, indicates that a %@AB@%PageLock%@AE@%
  5527. is implied as part of the %@AB@%PageAllocate%@AE@% operation. This forces the allocate
  5528. to make all pages of the handle present when the handle is allocated
  5529. consistent with the implied %@AB@%PageLock%@AE@%. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that
  5530. a %@AB@%PageLock%@AE@% is implied as part of the %@AB@%PageAllocate%@AE@% %@AI@%only if the%@AE@% %@AB@%PageSwap
  5531. %@AS@%%@AE@%%@AI@%device is not direct to hardware%@AE@%. There are two basic behavior types for the
  5532. %@AB@%PageSwap%@AE@% device. Type one pages through MS-DOS and/or the ROM BIOS. This
  5533. type of %@AB@%PageSwap%@AE@% device places restrictions on the ability to demand page
  5534. certain types of system memory because of the fact that it runs partly in
  5535. V86 mode as part of its operation. %@AB@%PageSwap%@AE@% type two pages by talking
  5536. directly to the disk hardware. This second type of %@AB@%PageSwap%@AE@% device removes
  5537. some of the restrictions because it runs completely in protected mode when
  5538. accessing the paging device. %@AB@%PageLocked%@AE@% indicates that the memory should be
  5539. locked regardless of which type of %@AB@%PageSwap%@AE@% device is present.
  5540. %@AB@%PageLockedIfDP%@AE@% indicates that this memory only needs to be locked if the
  5541. %@AB@%PageSwap%@AE@% device is type one. PageFixed, if set, indicates behavior similar
  5542. to %@AB@%PageLocked%@AE@% as far as the implied %@AB@%PageLock%@AE@% is concerned, and in addition a
  5543. Fixed handle can %@AI@%never%@AE@% be unlocked, and its linear address will %@AI@%never %@AE@%change
  5544. (via %@AB@%PageReAllocate%@AE@%). Note that ReAllocation of a Fixed handle will
  5545. generally not succeed due to the Fixed restriction on the ability to change
  5546. the linear address of the handle. Note that an allocation without an implied
  5547. %@AB@%PageLock%@AE@% via %@AB@%PageLocked%@AE@%, %@AB@%PageLockedIfDP%@AE@%, or %@AB@%PageFixed%@AE@% will simply allocate
  5548. linear address space. The pages of such a handle will be made present "on
  5549. demand" when the address space is touched. If it is desired to make part of
  5550. the handle present to perform some function, use %@AB@%PageLock%@AE@% to force the
  5551. contents to be loaded. PageUseAlign, if set, indicates that the %@AI@%AlignMask%@AE@%,
  5552. %@AI@%minPhys%@AE@%, %@AI@%maxPhys%@AE@%, and %@AI@%PhysAddrPTR%@AE@% parameters are specified. If PageUseAlign
  5553. is clear, the %@AI@%AlignMask%@AE@%, %@AI@%minPhys%@AE@%, %@AI@%maxPhys%@AE@%, and %@AI@%PhysAddrPTR%@AE@% parameters are
  5554. set to 0 and ignored. Note that if PageUseAlign is set, PageFixed must also
  5555. be specified. It makes no sense to have an aligned memory handle which is
  5556. not fixed. PageZeroInit, if set, indicates that if the allocation is
  5557. succesful, the memory is to be initialized with value 0 in all bytes of the
  5558. block. If PageZeroInit is clear, the block will have completely random
  5559. values in it. PageContig, if set, indicates that the Physical memory pages
  5560. of the block are to occupy sequential Physical memory addresses (memory is
  5561. "physically contiguous"). %@AI@%PageContig is ignored if PageUseAlign is not set.%@AE@%
  5562. %@NL@%
  5563.  
  5564. PageUseAlign is provided to assist device drivers that wish to allocate
  5565. buffers for use by the device which have additional alignment restrictions
  5566. enforced by the hardware (such as 64K and 128K alignment for DMA). If the
  5567. PageUseAlign bit is set, AlignMask specifies an alignment (power of 2> 4k)
  5568. requirement for the first physical page of the block. Physical page numbers
  5569. are the physical address of the page shifted right by 12. Correct alignment
  5570. is tested for by ANDing %@AI@%AlignMask%@AE@% with the first physical page number and
  5571. testing for zero. If the AND is zero, the page has the correct alignment.
  5572. Thus:  %@NL@%
  5573.  
  5574. %@AS@%  00000000h    =       4K alignment (ignore AlignMask)
  5575. %@AS@%  00000001h    =       8K alignment
  5576. %@AS@%  00000003h    =      16K alignment
  5577. %@AS@%  00000007h    =      32K alignment
  5578. %@AS@%  0000000Fh    =      64K alignment
  5579. %@AS@%  0000001Fh    =     128K alignment%@AE@%
  5580.  
  5581. Remember that you will probably also want to set the PageContig bit. %@AI@%minPhys%@AE@%
  5582. and %@AI@%maxPhys%@AE@% place additional physical address restrictions on the physical
  5583. pages of the memory block. These specify the minimum and maximum allowed
  5584. physical page numbers. All physical page numbers of the block must be
  5585. >=minPhys, and <maxPhys. For instance, for setting up a DMA buffer for an
  5586. 80386 accelerator card in a PC XT, the buffer needs to be physically
  5587. restricted to pages less than 1 MB since the XT DMA controller cannot DMA
  5588. into pages above 1 MB. In this case, minPhys would be 0, and maxPhys would
  5589. be 100h.  If you don't want to specify this (i.e. you just want %@AI@%AlignMask%@AE@%),
  5590. set %@AI@%minPhys%@AE@% to 0, and maxPhys to 0FFFFFFFFh. Note that when PageUseAlign is
  5591. set, the physical page address (physical page number shifted left by 12) of
  5592. the start of the block will be returned via the %@AI@%PhysAddrPTR%@AE@% pointer
  5593. parameter.  %@NL@%
  5594.  
  5595. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5596. NOTE
  5597.  
  5598. %@AI@%PageUseAlign PageAllocations can only be performed during device
  5599. %@AI@%initialization. Aligned PageAllocations will fail if done after device
  5600. %@AI@%initialization.%@AE@%
  5601.  
  5602. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5603.  
  5604.  
  5605. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5606.  
  5607. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5608. Low DWORD (%@AB@%EAX%@AE@%) is the memory handle of the block. The High DWORD (%@AB@%EDX%@AE@%) is
  5609. the 32 bit RING 0 address (offset relative to standard enhanced Windows Ring
  5610. 0 DS) of the block. If %@AB@%PageUseAlign%@AE@% was specified, the physical address of
  5611. the start of the block is placed in the DWORD pointed to by %@AB@%PhysAddrPTR%@AE@%.
  5612. Value (both DWORDs) is 0 if the allocation failed (insufficient memory).  %@NL@%
  5613.  
  5614.  
  5615. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5616.  
  5617. You should be careful about making assumptions about any apparent
  5618. relationship between the memory handle and the blocks RING 0 or physical
  5619. address. Any such apparent relationship is subject to change in a later
  5620. release.  %@NL@%
  5621.  
  5622. PhysAddrPTR had better point somewhere reasonable when PageUseAlign is
  5623. specified. There is no way to check its validity, if it's garbage you'll
  5624. either cause a page fault or stomp on something you shouldn't.  %@NL@%
  5625.  
  5626. %@AB@%PageAllocation%@AE@% of 0 length blocks is not allowed.  %@NL@%
  5627.  
  5628. %@AB@%PageLocked%@AE@% and %@AB@%PageLockedIfDP%@AE@% should not both be set. Only one, or the
  5629. other, or neither are valid settings. %@AI@%Note also that%@AE@% %@AB@%PageLockedIfDP%@AE@% %@AI@%cannot
  5630. %@AI@%be set on calls made before the init complete system control call is made%@AE@%.
  5631. This is because it is not possible to ask the %@AB@%PageSwap%@AE@% device what type it
  5632. is before it has been initialized.  %@NL@%
  5633.  
  5634. The Flag bit equates are defined by including VMM.INC, please use the
  5635. equates.  %@NL@%
  5636.  
  5637. %@CR:C6A00190089 @%%@CR:C6A00190090 @%
  5638. %@2@%%@CR:C6A00190091 @%%@AB@%PageFree%@AE@%%@EH@%%@NL@%
  5639. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5640.  
  5641. %@AS@%  unsigned PageFree(hMem,flags)
  5642. %@AS@%     unsigned hMem;
  5643. %@AS@%     unsigned flags;%@AE@%
  5644.  
  5645. This call is used to free an existing block of pages. %@AI@%hMem%@AE@% is the value
  5646. returned from a previous call to %@AB@%PageAllocate%@AE@% or %@AB@%PageReAllocate%@AE@% and
  5647. indicates the block to be freed. There are currently no bits defined in the
  5648. flags, this parameter must be set to 0.  %@NL@%
  5649.  
  5650.  
  5651. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5652.  
  5653. Returns nonzero value if the block was succesfully freed, zero if the free
  5654. was unsuccesful (invalid %@AI@%hMem%@AE@%).  %@NL@%
  5655.  
  5656.  
  5657. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5658.  
  5659. It is the responsibility of the enhanced Windows system components which
  5660. allocate non-PG_SYS pages to free them when the VM they are associated with
  5661. is destroyed. There is no "automatic" freeing of such memory done by the
  5662. memory manager. PG_SYS pages do not need to be freed before enhanced Windows
  5663. exits.  %@NL@%
  5664.  
  5665. It is not an error to %@AB@%PageFree%@AE@% a handle which is all or partially locked.  %@NL@%
  5666.  
  5667. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5668. %@AU@%WARNING%@AE@%
  5669.  
  5670. Be very careful about PageFreeing blocks which are currently MapIntoV86ed to
  5671. some VM context. Doing this can result in a crash.
  5672. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5673.  
  5674. %@CR:C6A00190092 @%%@CR:C6A00190093 @%
  5675. %@2@%%@CR:C6A00190094 @%%@AB@%PageGetAllocInfo%@AE@%%@EH@%%@NL@%
  5676. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5677.  
  5678. %@AS@%  unsigned long PageGetAllocInfo(flags)
  5679. %@AS@%   unsigned flags;%@AE@%
  5680.  
  5681. This call is used to obtain information prior to a %@AB@%PageAllocate%@AE@% or
  5682. %@AB@%PageReallocate%@AE@% call. It returns the largest block of linear address space
  5683. that could be allocated, together with information relating to allocation of
  5684. Locked or Fixed memory. There are currently no bits defined in the flags,
  5685. this parameter must be set to 0.  %@NL@%
  5686.  
  5687.  
  5688. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5689.  
  5690. The return value is a 64 bit long which is actually two 32 bit DWORDs. The
  5691. Low DWORD (%@AB@%EAX%@AE@%) is the 32 bit count of free 4K pages in the system which
  5692. could be allocated with the %@AB@%PageAllocate%@AE@% as %@AI@%not %@AE@%%@AB@%PageLocked%@AE@% or %@AB@%PageFixed%@AE@%
  5693. memory. The High DWORD (%@AB@%EDX%@AE@%) is the 32 bit count of pages available for
  5694. allocation as %@AB@%PageLocked%@AE@% pages at the current time.  %@NL@%
  5695.  
  5696.  
  5697. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5698.  
  5699. You should be careful about making assumptions about being able to turn
  5700. around and issue a call to allocate all of the pages returned by this call.
  5701. Besides any alignment considerations, it is possible someone could get in
  5702. and allocate some or all of the pages before you. This call is intended to
  5703. be advisory in nature.  %@NL@%
  5704.  
  5705. %@AB@%EAX%@AE@% contains the size of the largest available region of linear address
  5706. space. %@AB@%EDX%@AE@% contains the count of pages currently available for allocation as
  5707. %@AB@%PageLocked%@AE@% pages. Notice that many assumptions are not valid. %@AB@%EAX%@AE@% >= %@AB@%EDX%@AE@% is
  5708. %@AI@%not%@AE@% a valid assumption for instance.  %@NL@%
  5709.  
  5710. You should be very careful about turning around and doing a %@AB@%PageAllocate%@AE@%
  5711. with the %@AB@%EAX%@AE@% return from this call. You can cause all sorts of odd behavior
  5712. if you take up all of the linear address space. You should allocate memory
  5713. on an as needed basis instead of allocating huge blocks of memory most of
  5714. which you do not use.  %@NL@%
  5715.  
  5716. %@CR:C6A00190095 @%%@CR:C6A00190096 @%
  5717. %@2@%%@CR:C6A00190097 @%%@AB@%PageGetSizeAddr%@AE@%%@EH@%%@NL@%
  5718. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5719.  
  5720. %@AS@%  unsigned long PageGetSizeAddr(hMem,flags)
  5721. %@AS@%     unsigned hMem;
  5722. %@AS@%     unsigned flags;%@AE@%
  5723.  
  5724. This call is used to get the size and linear address of an existing block of
  5725. pages. %@AI@%hMem%@AE@% is the value returned from a previous call to %@AB@%PageAllocate%@AE@% or
  5726. %@AB@%PageReAllocate%@AE@% and indicates the block to get the size and address of. There
  5727. are currently no bits defined in the flags, this parameter must be set to 0.
  5728. %@NL@%
  5729.  
  5730.  
  5731. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5732.  
  5733. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5734. Low DWORD (%@AB@%EAX%@AE@%) is the size in 4K pages of the block. The High DWORD (%@AB@%EDX%@AE@%)
  5735. is the 32 bit RING 0 address (offset relative to standard enhanced Windows
  5736. Ring 0 DS) of the block. Value (both DWORDs) is 0 if the call failed
  5737. (invalid %@AI@%hMem%@AE@%).  %@NL@%
  5738.  
  5739.  
  5740. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5741.  
  5742. Note that the size of a handle is the total size of the handle and has
  5743. nothing to do with what pieces of the handle may or may not be present.  %@NL@%
  5744.  
  5745. %@CR:C6A00190098 @%%@CR:C6A00190099 @%
  5746. %@2@%%@CR:C6A00190100 @%%@AB@%PageLock%@AE@%%@EH@%%@NL@%
  5747. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5748.  
  5749. %@AS@%  unsigned PageLock(hMem,nPages,PageOff,flags)
  5750. %@AS@%     unsigned hMem;
  5751. %@AS@%     unsigned nPages;
  5752. %@AS@%     unsigned PageOff;
  5753. %@AS@%     unsigned flags;%@AE@%
  5754.  
  5755. This call is used to lock (make present) all or part of an existing memory
  5756. handle. %@AI@%hMem%@AE@% is the value returned from a previous call to %@AB@%PageAllocate%@AE@% or
  5757. %@AB@%PageReAllocate%@AE@% and indicates the block to be locked. %@AI@%nPages%@AE@% specifies the
  5758. count of pages to be locked. %@AI@%PageOff%@AE@% specifies the page offset from the
  5759. start of the block of the first page to be locked. %@AI@%nPages%@AE@% together with
  5760. %@AI@%PageOff%@AE@% allow all or only part of the%@AI@% hMem%@AE@% block to be locked. An error will
  5761. occur if %@AI@%PageOff%@AE@%+%@AI@%nPages%@AE@% is greater than the size of %@AI@%hMem%@AE@%. There are
  5762. currently no bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5763.  
  5764. Current flags bits:  %@NL@%
  5765.  
  5766. %@AS@%  PageLockedIfDP EQU 00000000000000000000000100000000B%@AE@%
  5767.  
  5768. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  5769. lock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to hardware.
  5770. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to hardware),
  5771. calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively NOPs. See the
  5772. %@AB@%PageAllocate%@AE@% documentation for a description of the different %@AB@%PageSwap
  5773. %@AB@%%@AE@%device types and their relevance.  %@NL@%
  5774.  
  5775.  
  5776. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5777.  
  5778. Returns nonzero value if the block was succesfully locked, zero if the lock
  5779. was unsuccesful (invalid %@AI@%hMem%@AE@%, insufficient memory).  %@NL@%
  5780.  
  5781.  
  5782. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5783.  
  5784. This call may be issued on %@AI@%hMem%@AE@% blocks which are %@AB@%PageFixed%@AE@%, but this is a
  5785. wasted call since %@AB@%PageFixed%@AE@% blocks are always locked (present).  %@NL@%
  5786.  
  5787. Because of the overcommit associated with demand paging, callers must be
  5788. prepared for this call to fail due to unavailability of sufficient memory to
  5789. make the region present.  %@NL@%
  5790.  
  5791. %@AI@%Note that%@AE@% %@AB@%PageLockedIfDP%@AE@% %@AI@%cannot be set on calls made before the init
  5792. %@AI@%complete system control call is made%@AE@%. This is because it is not possible to
  5793. ask the %@AB@%PageSwap%@AE@% device what type it is before it has been initialized.  %@NL@%
  5794.  
  5795. Each Page of a handle has an individual lock count. Each lock increments the
  5796. counter. The counter must go to 0 for the page to be unlocked. This means
  5797. that if the handle is locked 5 times, it has to be unlocked 5 times.  %@NL@%
  5798.  
  5799. Do not leave handles locked when they don't need to be, unlock handles as
  5800. soon as possible to make the physical memory associated available for use by
  5801. demand paging.  %@NL@%
  5802.  
  5803. The Flag bit equates are defined by including VMM.INC, please use the
  5804. equates.  %@NL@%
  5805.  
  5806. %@CR:C6A00190101 @%%@CR:C6A00190102 @%
  5807. %@2@%%@CR:C6A00190103 @%%@AB@%PageOutDirtyPages%@AE@%%@EH@%%@NL@%
  5808. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5809.  
  5810. %@AS@%  unsigned PageOutDirtyPages(nPages,flags)
  5811. %@AS@%     unsigned nPages;
  5812. %@AS@%     unsigned flags;%@AE@%
  5813.  
  5814. This call is for use by the demand paging device. It allows the paging
  5815. device to periodically "flush" out dirty pages to prevent a large number of
  5816. dirty pages from accumulating in the system. %@AI@%nPages%@AE@% is the maximum number of
  5817. dirty pages to flush at this time.  %@NL@%
  5818.  
  5819. Current flags bits:  %@NL@%
  5820.  
  5821. %@AS@%  PagePDPSetBase  EQU 00000000000000000100000000000000B 
  5822. %@AS@%  PagePDPClearBase  EQU 00000000000000001000000000000000B 
  5823. %@AS@%  PagePDPQueryDirty  EQU 00000000000000100000000000000000B%@AE@%
  5824.  
  5825. All unused bits %@AI@%must be zero%@AE@%. The %@AB@%PageSwap%@AE@% device may wish to flush out all
  5826. dirty pages in the system as part of a "background" activity ("write out
  5827. ahead"). These two bits allow this to be done, it allows the caller to
  5828. manipulate a variable associated with the page out scan which will cause the
  5829. scan to stop. This "base" page number that is set allows the %@AB@%PageSwap%@AE@% device
  5830. to tell when the %@AB@%PageOutDirtyPages%@AE@% call has completed a scan of the entire
  5831. address space looking for dirty pages. %@AB@%PagePDPSetBase%@AE@% tells
  5832. %@AB@%PageOutDirtyPages%@AE@% to set the base page number to the current scan start
  5833. point. %@AB@%PagePDPClearBase%@AE@% tells %@AB@%PageOutDirtyPages%@AE@% to clear the base page
  5834. number, setting it to NONE. A return value of 0 is used to detect when a
  5835. %@AB@%PageOutDirtyPages%@AE@% call has stoped because it has hit the base page. This is
  5836. not totally reliable, but is a reasonable approximation, since
  5837. %@AB@%PageOutDirtyPages%@AE@% can return 0 because there are no dirty pages (this is
  5838. rather unlikely). %@AB@%PagePDPQueryDirty%@AE@%, if set, indicates that the call is to
  5839. return the current count of DIRTY demand pageable pages, the %@AI@%nPages %@AE@%argument
  5840. and all other flags are ignored if this bit is set (call returns the count
  5841. of dirty pages as its sole function).  %@NL@%
  5842.  
  5843.  
  5844. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5845.  
  5846. Returns the actual count of dirty pages flushed by the call (0 is valid).  %@NL@%
  5847.  
  5848. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5849. %@AU@%WARNING%@AE@%
  5850.  
  5851. This call is intended for use by the PageSwap device, others should not be
  5852. calling it. Others making this call can disturb the operation of the
  5853. PageSwap device.
  5854. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5855.  
  5856.  
  5857. %@3@%%@AB@%Notes%@AE@%%@EH@%%@NL@%
  5858.  
  5859. This call functions something like a partial "commit" of the dirty pages in
  5860. the system. Note that ALL of the dirty demand pages can be flushed by
  5861. specifying a large value for %@AI@%nPages%@AE@% (like 0FFFFFFFFh).  %@NL@%
  5862.  
  5863. This call operates only on current page out candidates.  %@NL@%
  5864.  
  5865. The Flag bit equates are defined by including VMM.INC, please use the
  5866. equates.  %@NL@%
  5867.  
  5868. %@CR:C6A00190104 @%%@CR:C6A00190105 @%
  5869. %@2@%%@CR:C6A00190106 @%%@AB@%PageReAllocate%@AE@%%@EH@%%@NL@%
  5870. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5871.  
  5872. %@AS@%  unsigned PageReAllocate(hMem,nPages,flags)
  5873. %@AS@%     unsigned hMem;
  5874. %@AS@%     unsigned nPages;
  5875. %@AS@%     unsigned flags;%@AE@%
  5876.  
  5877. This call is used to grow or shrink or reinitialize an existing block of
  5878. memory. %@AI@%hMem%@AE@% is the value returned from a previous %@AB@%PageAllocate%@AE@% or
  5879. %@AB@%PageReAllocate%@AE@% call and indicates the block to be reallocated. %@AI@%Note that
  5880. %@AI@%handles allocated with%@AE@% %@AB@%PageUseAlign%@AE@% %@AI@%set cannot be%@AE@% %@AB@%PageReAllocated%@AE@%. %@AI@%nPages%@AE@% is
  5881. a 32 bit unsigned integer which is the new size in 4K pages of the block.  %@NL@%
  5882.  
  5883. Current flags bits:  %@NL@%
  5884.  
  5885. %@AS@%  PageZeroInit  EQU 00000000000000000000000000000001B 
  5886. %@AS@%  PageZeroReInit  EQU 00000000000000000000000000100000B 
  5887. %@AS@%  PageNoCopy  EQU 00000000000000000000000001000000B
  5888. %@AS@%  PageLocked  EQU 00000000000000000000000010000000B
  5889. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B%@AE@%
  5890.  
  5891. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLocked%@AE@% and %@AB@%PageLockedIfDP%@AE@%, if set,
  5892. indicates that if this %@AB@%PageReAllocation%@AE@% is growing the size of the handle,
  5893. the pages added to the handle are to be %@AB@%PageLocked%@AE@% or %@AB@%PageLockedIfDP%@AE@% (see
  5894. %@AB@%PageAllocate%@AE@% for explanation). If the %@AB@%PageReAllocation%@AE@% is not growing the
  5895. handle these bits are ignored. %@AI@%Note that%@AE@% %@AB@%PageFixed%@AE@% %@AI@%is not%@AE@% %@AI@%specified%@AE@%,
  5896. %@AB@%PageReAllocation%@AE@% of a %@AB@%PageFixed%@AE@% handle is implied as %@AB@%PageFixed%@AE@% by the handle
  5897. itself. %@AB@%PageZeroInit%@AE@%, if set, indicates that if the reallocation is
  5898. succesful, and the re-allocation is growing the size of the block, the "grow
  5899. area" of the block is to be initialized with value 0 in all bytes. This bit
  5900. is ignored on a re-allocation which is not growing the size of the block.
  5901. %@AB@%PageZeroReInit%@AE@% , if set, indicates that the entire block is to be
  5902. reinitialized with value zero in all bytes of the block. %@AB@%PageNoCopy%@AE@%, if set,
  5903. indicates that the previous contents of the block are irrelevant, and don't
  5904. need to be copied into the newly sized block. There is no reason that more
  5905. than one of these three bits should be set. If none of the bits are set, the
  5906. previous contents of the block are copied into the new block, up to the
  5907. lesser of the size of the new block, and the size of the old block, and the
  5908. "grow area", if any, is not initialized with anything.  %@NL@%
  5909.  
  5910.  
  5911. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5912.  
  5913. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5914. Low DWORD (%@AB@%EAX%@AE@%) is the memory handle of the new block. The High DWORD (%@AB@%EDX%@AE@%)
  5915. is the 32 bit RING 0 address (offset relative to standard enhanced Windows
  5916. Ring 0 DS) of the block. Value (both DWORDs) is 0 if the reallocation failed
  5917. (insufficient memory, handle wrong type, invalid handle).  %@NL@%
  5918.  
  5919.  
  5920. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5921.  
  5922. Do not make assumptions about the relationship between the passed in %@AI@%hMem%@AE@%
  5923. and the Address returned, if specified. Assume that the returned %@AI@%hMem%@AE@% and
  5924. address are always different than the passed in %@AI@%hMem%@AE@% and previous address.  %@NL@%
  5925.  
  5926. In the case where this call fails, the passed in %@AI@%hMem%@AE@% and previous address
  5927. of the block remain valid. In the case where this call works and returns a
  5928. new %@AI@%hMem%@AE@% and address, the passed in%@AI@% hMem%@AE@% and previous address are no longer
  5929. valid (old block has been PageFreed).  %@NL@%
  5930.  
  5931. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5932. %@AU@%WARNING%@AE@%
  5933.  
  5934. Be very careful about PageReAllocating blocks which are currently
  5935. MapIntoV86ed to some VM context. Doing this can result in a crash.
  5936. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5937.  
  5938. %@AB@%PageLocked%@AE@% and %@AB@%PageLockedIfDP%@AE@% should not both be set. Only one, or the
  5939. other, or neither are valid settings. Note also that %@AB@%PageLockedIfDP%@AE@% cannot
  5940. be set on calls made before the init complete system control call is made.
  5941. This is because it is not possible to ask the %@AB@%PageSwap%@AE@% device what type it
  5942. is before it has been initialized.  %@NL@%
  5943.  
  5944. Note that this call can be used to reset the contents of an existing block
  5945. to 0 by setting %@AI@%nPages%@AE@% to the current size of the block and setting
  5946. PageZeroReInit.  %@NL@%
  5947.  
  5948. You cannot %@AB@%PageReAllocate%@AE@% a block to size 0, use %@AB@%PageFree%@AE@%.  %@NL@%
  5949.  
  5950. The Flag bit equates are defined by including VMM.INC, please use the
  5951. equates.  %@NL@%
  5952.  
  5953. %@CR:C6A00190107 @%%@CR:C6A00190108 @%
  5954. %@2@%%@CR:C6A00190109 @%%@AB@%PageUnLock%@AE@%%@EH@%%@NL@%
  5955. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5956.  
  5957. %@AS@%  unsigned PageUnLock(hMem,nPages,PageOff,flags)
  5958. %@AS@%     unsigned hMem;
  5959. %@AS@%     unsigned nPages;
  5960. %@AS@%     unsigned PageOff;
  5961. %@AS@%     unsigned flags;%@AE@%
  5962.  
  5963. This call is used to unlock all or part of an existing memory handle that
  5964. was previously locked. %@AI@%hMem%@AE@% is the value returned from a previous call to
  5965. %@AB@%PageAllocate%@AE@% or %@AB@%PageReAllocate%@AE@% and indicates the block to be unlocked.
  5966. %@AI@%nPages%@AE@% specifies the count of pages to be unlocked.%@AI@% PageOff%@AE@% specifies the
  5967. page offset from the start of the block of the first page to be unlocked.
  5968. %@AI@%nPages%@AE@% together with %@AI@%PageOff %@AE@%allow all or only part of the %@AI@%hMem%@AE@% block to be
  5969. unlocked. An error will occur if %@AI@%PageOff%@AE@%+%@AI@%nPages %@AE@%is greater than the size of
  5970. %@AI@%hMem%@AE@%.  %@NL@%
  5971.  
  5972. Current flags bits:  %@NL@%
  5973.  
  5974. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B 
  5975. %@AS@%  PageMarkPageOut  EQU 00000000000000000010000000000000B%@AE@%
  5976.  
  5977. All unused bits must be zero. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  5978. unlock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to
  5979. hardware. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to
  5980. hardware), calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively
  5981. NOPs. See the %@AB@%PageAllocat%@AE@%e documentation for a description of the different
  5982. %@AB@%PageSwap%@AE@% device types and their relevance. %@AB@%PageMarkPageOut%@AE@%, if set,
  5983. indicates that if this unlock actually does unlock the pages (lock count
  5984. goes to 0) the pages are to be made prime candidates for page out. This flag
  5985. should only be set if it is unlikely that these pages are going to be
  5986. touched for a while. Effectively what this does is clear the P_ACC bits of
  5987. the pages which causes them to be first level page out candidates.  %@NL@%
  5988.  
  5989.  
  5990. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5991.  
  5992. Returns nonzero value if the block was succesfully unlocked, zero if the
  5993. lock was unsuccesful (invalid %@AI@%hMem,%@AE@% no part of range is locked).  %@NL@%
  5994.  
  5995.  
  5996. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5997.  
  5998. This call %@AI@%may%@AE@% be issued on %@AI@%hMem%@AE@% blocks which are %@AB@%PageFixed%@AE@%, but this is a
  5999. wasted call since %@AB@%PageFixed%@AE@% blocks cannot be unlocked.  %@NL@%
  6000.  
  6001. Note that %@AB@%PageLockedIfDP%@AE@% cannot be set on calls made before the init
  6002. complete system control call is made. This is because it is not possible to
  6003. ask the %@AB@%PageSwap%@AE@% device what type it is before it has been initialized.  %@NL@%
  6004.  
  6005. Each page of a handle has an individual lock count. Each lock increments the
  6006. counter. The counter must go to 0 for the page to be unlocked. This means
  6007. that if the handle is locked 5 times, it has to be unlocked 5 times.  %@NL@%
  6008.  
  6009. The Flag bit equates are defined by including VMM.INC, please use the
  6010. equates.  %@NL@%
  6011.  
  6012. %@CR:C6A00190110 @%%@CR:C6A00190111 @%
  6013. %@2@%%@CR:C6A00190112 @%%@AB@%PhysIntoV86%@AE@%%@EH@%%@NL@%
  6014. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6015.  
  6016. %@AS@%  unsigned PhysIntoV86(PhysPage,VMHandle,VMLinPgNum,nPages,flags)
  6017. %@AS@%     unsigned PhysPage;
  6018. %@AS@%     unsigned VMHandle;
  6019. %@AS@%     unsigned VMLinPgNum;
  6020. %@AS@%     unsigned nPages;
  6021. %@AS@%     unsigned flags;%@AE@%
  6022.  
  6023. This call is very similar to the %@AB@%MapIntoV86%@AE@% call only instead of taking a
  6024. memory handle argument, it takes a Physical address (page number). The
  6025. intent of this call is to "hook up" a particular VM to the actual Physical
  6026. device memory of a device (such as the video memory of a display adaptor).
  6027. %@AI@%PhysPage%@AE@% is the physical page number of the start of the region to be
  6028. mapped, and indicates the block of physical memory to be mapped. For
  6029. instance, to hook up to the 64K of video memory at A000:000, PhysPage would
  6030. be A0h and %@AI@%nPage%@AE@%s would be 10h. The %@AI@%VMHandle%@AE@% parameter must be a valid %@AI@%VM
  6031. %@AI@%handle%@AE@% and indicates the VM into which the map is to occur. %@AI@%VMLinPgNum%@AE@% is
  6032. the address in the 1Meg V86 address space of the VM where the map will start
  6033. (this is a page number, thus linear address A0000h = page A0h). Alignment
  6034. considerations of this address (beyond 4K alignment) are the responsibility
  6035. of the caller. Map addresses below page 10h, or above 10Fh will cause an
  6036. error. %@AI@%nPages%@AE@% is the number of pages to map. The physical region is assumed
  6037. to be contiguous (thus if mapping three pages, they will be PhysPage,
  6038. PhysPage+1 and PhysPage+2 in that order). If the physical region is not
  6039. contiguous, you will have to issue multiple calls in succession. There are
  6040. currently no bits defined in the flags, this parameter must be set to 0.  %@NL@%
  6041.  
  6042.  
  6043. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6044.  
  6045. Returns a nonzero value if the map is succesful, returns 0 value if the map
  6046. was unsuccesful (invalid %@AI@%VMHandle%@AE@%, map range illegal).  %@NL@%
  6047.  
  6048.  
  6049. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6050.  
  6051. You are warned to be careful with this call. Very strange things will happen
  6052. if you specify a physical region which is unoccupied, or belongs to some
  6053. other device.  %@NL@%
  6054.  
  6055. The page attributes for these pages will be P_USER+P_PRES+P_WRITE. P_DIRTY
  6056. and P_ACC will be cleared by the call. PG_TYPE will be set to PG_SYS.  %@NL@%
  6057.  
  6058. The intent of %@AB@%PhysIntoV86%@AE@% support for pages between page 10h and
  6059. FirstV86Page is to support enhanced Windows devices which have
  6060. %@AB@%Allocate_Global_V86_Data_Area%@AE@% a %@AB@%GVDAPageAlign%@AE@% region. Use of mapping in this
  6061. region to other addresses can easily crash the system and should be avoided.
  6062. %@NL@%
  6063.  
  6064. Regions which span across %@AB@%FirstV86Page%@AE@% are not allowed.  %@NL@%
  6065.  
  6066. The reason for the page 10h limitation is that on most versions of the Intel
  6067. 80386 CPU there is an errata which prevents you from setting up a Linear
  6068. Physical address mapping in the first 64k of the address space.  %@NL@%
  6069.  
  6070. %@CR:C6A00190113 @%%@CR:C6A00190114 @%
  6071. %@2@%%@CR:C6A00190115 @%%@AB@%TestGlobalV86Mem%@AE@%%@EH@%%@NL@%
  6072. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6073.  
  6074. %@AS@%  unsigned TestGlobalV86Mem(VMLinAddr,nBytes,flags)
  6075. %@AS@%     unsigned VMLinAddr;
  6076. %@AS@%     unsigned nBytes;
  6077. %@AS@%     unsigned flags;%@AE@%
  6078.  
  6079. Some enhanced Windows devices wish to test whether a given piece of V86
  6080. address space is LOCAL to a particular VM, or GLOBAL. The reason for this
  6081. test is that GLOBAL V86 address ranges are valid and identical in ALL VM
  6082. contexts, while LOCAL V86 address ranges are valid in only one VM context.
  6083. This difference can yield optimizations. For instance, operations involving
  6084. GLOBAL address ranges will typically not need to be "virtualized" in any way
  6085. since the range is valid and addressable in ALL VM contexts. LOCAL address
  6086. range operations may have to be "virtualized" though since it is possible
  6087. for a piece of Virtual Mode code to try and use the address in the "wrong"
  6088. VM context where the address range is invalid, or points to the wrong
  6089. memory. This call can be used to test whether a V86 address range is GLOBAL
  6090. or LOCAL. %@AI@%VMLinAddr%@AE@% is the linear address of the first byte of the V86
  6091. address range. This address is relative to the standard RING 0 DS (ie. the
  6092. linear address of 02C1:0FC5 would be 02C10 + 0FC5 = 3BD5). %@AI@%nBytes%@AE@% is the
  6093. length of the V86 address range in bytes. There are currently no bits
  6094. defined in the flags, this parameter must be set to 0.  %@NL@%
  6095.  
  6096.  
  6097. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6098.  
  6099. Returns 0 if the address is not a valid V86 address range, or the address
  6100. range is LOCAL. Returns 1 if the address range is GLOBAL. Returns 2 if the
  6101. address range is partly LOCAL and partly GLOBAL (range overlaps a
  6102. GLOBAL/LOCAL boundary). Returns 3 if the address range is GLOBAL but
  6103. overlaps with an Instance data region.  %@NL@%
  6104.  
  6105.  
  6106. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6107.  
  6108. The distinction between GLOBAL and INSTANCE is rather subtle because
  6109. INSTANCE pages are "physically global" even though their content is LOCAL.
  6110. The physical address of instance data pages never changes, thus instance
  6111. pages are GLOBAL in the physical address sense. The content of instance data
  6112. regions is per VM though which means they are LOCAL in the sense of "what is
  6113. in them".  %@NL@%
  6114.  
  6115. The MMGR does not know any of the specifics about what is going on in the
  6116. regions above FirstV86Page. This routine will return LOCAL for all regions
  6117. above FirstV86Page, INCLUDING the A0-FF adapter/ROM BIOS area. Some pieces
  6118. of this region may actually be GLOBAL in terms of how they are used, but
  6119. this service doesn't know any of the details so it cannot determine this.  %@NL@%
  6120.  
  6121.  
  6122. %@2@%%@CR:C6A00190116 @%%@AB@%19.6  Looking At Physical Device Memory From a VxD%@AE@%%@EH@%%@NL@%
  6123. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6124.  
  6125. VxDs, such as virtual display drivers, that have a certain region of
  6126. physical address space associated with them, such as Video Memory, need a
  6127. way to look at the device-specific memory when the device is running. The
  6128. method by which this is done is by using a service that returns the correct
  6129. linear address (relative to the standard Ring 0 %@AB@%DS%@AE@%).  %@NL@%
  6130.  
  6131. It may seem to be possible for a VxD together with a Protected Mode
  6132. application to implement its own private "virtual memory" system by hooking
  6133. into the IDT and handling page faults itself. You are strongly warned not to
  6134. try and undertake an implementation of this sort at this time. It is
  6135. realized that support of such an architecture is a desirable feature for
  6136. implementation of such things as "virtual files" and "virtual memory mapped
  6137. devices". This feature will be addressed in a future version of Windows by
  6138. adding new VMM services, and/or modifying existing services to support it.
  6139. Since support for this is planned, any and all work that you might undertake
  6140. on the current version of Windows to implement this will be rendered
  6141. obsolete when support for it is added to the VMM.  %@NL@%
  6142.  
  6143. %@CR:C6A00190117 @%%@CR:C6A00190118 @%
  6144. %@2@%%@CR:C6A00190119 @%%@AB@%MapPhysToLinear%@AE@%%@EH@%%@NL@%
  6145. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6146.  
  6147. %@AS@%  unsigned MapPhysToLinear(PhysAddr,nBytes,flags)
  6148. %@AS@%     unsigned PhysAddr;
  6149. %@AS@%     unsigned nBytes;
  6150. %@AS@%     unsigned flags;%@AE@%
  6151.  
  6152. %@AI@%PhysAddr %@AE@%is the physical address of the start of the region to be looked at.
  6153. This is simply the 32 bit physical address, there are no alignment
  6154. considerations. Physical addresses start at 0, thus the address of physical
  6155. page 0A0h is 0A0000h. %@AI@%nBytes%@AE@% is the length of the physical region in bytes
  6156. starting from %@AI@%PhysAddr.%@AE@% This parameter is used to verify that the entire
  6157. range is addressable. There are currently no bits defined in the %@AI@%flags,%@AE@% this
  6158. parameter must be set to 0.  %@NL@%
  6159.  
  6160.  
  6161. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6162.  
  6163. Returns the RING 0 DS offset of the first byte of the physical region. Will
  6164. return 0FFFFFFFFh if the specified range is not addressable.  %@NL@%
  6165.  
  6166. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6167. %@AU@%WARNING%@AE@%
  6168.  
  6169. You are warned to be careful with this method. Use of this for purposes
  6170. beyond looking at device specific physical memory is extremely dangerous and
  6171. is not approved.
  6172. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6173.  
  6174.  
  6175. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6176.  
  6177. Physical addresses do not move. It is perfectly fine to get the linear
  6178. address of a physical region at Device_Init device call time and then use it
  6179. later. You do not have to keep recalling %@AB@%MapPhysToLinear%@AE@% every time you want
  6180. to look at the region.  %@NL@%
  6181.  
  6182. For instance to look at physical page A0h you would do this:  %@NL@%
  6183.  
  6184. %@AS@%  VMMCall _MapPhysToLinear,<0A0000h,10000h,0>%@AE@%
  6185.  
  6186. %@AB@%DS:[EAX]%@AE@% now addresses this physical page. Physical memory is mapped
  6187. contiguously at this selector so Page 0A1h would be 4096 bytes beyond the
  6188. above address.  %@NL@%
  6189.  
  6190.  
  6191. %@2@%%@CR:C6A00190120 @%%@AB@%19.7  Data Access Services%@AE@%%@EH@%%@NL@%
  6192. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6193.  
  6194. These services are used to get the contents of public memory manager
  6195. variables. All of these services return the value of the associated variable
  6196. in %@AB@%EAX%@AE@%.  %@NL@%
  6197.  
  6198. %@CR:C6A00190121 @%%@CR:C6A00190122 @%
  6199. %@2@%%@CR:C6A00190123 @%%@AB@%GetFirstV86Page%@AE@%%@EH@%%@NL@%
  6200. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6201.  
  6202. %@AS@%  unsigned GetFirstV86Page()%@AE@%
  6203.  
  6204. This call returns the page number of the first page of VM specific V86
  6205. memory.  %@NL@%
  6206.  
  6207.  
  6208. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6209.  
  6210. %@AB@%FirstV86Page%@AE@% MOVES during device initialization. Do not get the value at
  6211. device init time, and then use it later, as the value is invalid.  %@NL@%
  6212.  
  6213. %@CR:C6A00190124 @%%@CR:C6A00190125 @%
  6214. %@2@%%@CR:C6A00190126 @%%@AB@%GetNulPageHandle%@AE@%%@EH@%%@NL@%
  6215. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6216.  
  6217. %@AS@%  unsigned GetNulPageHandle()%@AE@%
  6218.  
  6219. This call returns the memory handle of the system NUL page.  %@NL@%
  6220.  
  6221. %@CR:C6A00190127 @%%@CR:C6A00190128 @%
  6222. %@2@%%@CR:C6A00190129 @%%@AB@%GetAppFlatDSAlias()%@AE@%%@EH@%%@NL@%
  6223. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6224.  
  6225. %@AS@%  unsigned GetAppFlatDSAlias()%@AE@%
  6226.  
  6227. This call returns a selector which can be used by protected mode
  6228. applications to look at the same data that the standard RING 0 DS looks at.
  6229. This is useful when a VxD wishes to provide a protected mode service to
  6230. applications and wants the application to be able to address the same memory
  6231. that the VxD does.  %@NL@%
  6232.  
  6233.  
  6234. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6235.  
  6236. This selector is %@AI@%read only%@AE@%. This is so that the Windows address space is
  6237. protected from a misbehaved application. It is not recommended that you
  6238. build a read/write version of this selector. If the application needs to
  6239. WRITE you should build a descriptor with a much more restricted Base and
  6240. Limit so that the application can only modify those things which it is
  6241. allowed to modify.  %@NL@%
  6242.  
  6243. This selector is RPL = DPL = Protected Mode Application Privilege. Notice
  6244. that a VxD can also use this selector if desired even though the devices run
  6245. at a different privilege level. Its type is "USE 16", this doesn't mean much
  6246. since it is a data selector.  %@NL@%
  6247.  
  6248. This is a GDT selector.  %@NL@%
  6249.  
  6250. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6251. %@AU@%WARNING%@AE@%
  6252.  
  6253. You must not do a Free_GDT_Selector on this selector. It is not protected,
  6254. and so it will get freed. Then anyone using it will fault and crash the
  6255. system. This selector is provided to prevent multiple devices from creating
  6256. multiple versions of the same selector and wasting GDT entries
  6257. unnecessarily. 
  6258. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6259.  
  6260. Notice that enhanced Windows is "USE 32", therefore a protected application,
  6261. which is "USE 16", will have to use the DB 67h addressing mode override on
  6262. its instructions to get 32 bit addressing (MASM will do this for you
  6263. automatically if you set things up correctly).  %@NL@%
  6264.  
  6265. This service can be used to discover what protection ring protectedmode
  6266. applications run at by doing a LAR on the returned selector. Be very careful
  6267. about what you do with this bit of information.  %@NL@%
  6268.  
  6269.  
  6270. %@2@%%@CR:C6A00190130 @%%@AB@%19.8  Special Services For Protected Mode APIs%@AE@%%@EH@%%@NL@%
  6271. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6272.  
  6273. These services are provided to support VxDs that need to manipulate
  6274. protected-mode address space. For example, applications running in protected
  6275. mode need a way to map regions of protected mode, segmented address space
  6276. into the virtual machine's virtual 8086 context. A specific example is the
  6277. MS-DOS INT 21 API. The data pointed to on the INT 21 calls needs to be
  6278. mapped into the VM's V86 address space so that MS-DOS can access it and
  6279. perform the requested operation.  %@NL@%
  6280.  
  6281. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6282. %@AU@%WARNING%@AE@%
  6283.  
  6284. Do not use these services for purposes other than their intended use. These
  6285. calls can be quite dangerous and can result in strange behavior or crashes
  6286. if misused.
  6287. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6288.  
  6289.  
  6290. %@2@%%@CR:C6A00190131 @%%@AB@%GetV86PageableArray%@AE@%%@EH@%%@NL@%
  6291. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6292.  
  6293. %@AS@%  unsigned GetV86PageableArray(VMHandle,ArrayBufPTR,flags)
  6294. %@AS@%  unsigned VMHandle;
  6295. %@AS@%  unsigned ArrayBufPTR;
  6296. %@AS@%  unsigned flags;%@AE@%
  6297.  
  6298. This call is used to obtain a copy of the bit array of pages whose behavior
  6299. has been modified via %@AB@%SetResetV86Pageable%@AE@%. This allows the caller to
  6300. determine which regions of the VM V86 address space have had the normal
  6301. lock/unlock behavior modified. VMHandle specifies the VM to get the bit map
  6302. of. ArrayBufPTR points to a buffer large enough to contain the array. The
  6303. assignment array is an array of 100h bits, one bit for each page in the
  6304. range 0-100h. Thus the size of the array is ((100h/8)+3)/4 = 8 DWORDS. Bits
  6305. in the array which are set (=1) indicate pages whose normal lock/unlock
  6306. behavior is disabled, bits which are clear (=0) indicate pages whose
  6307. behavior is normal. Thus to test the bit for page number N (0 %@NL@%
  6308.  
  6309. %@AS@%  mov ebx, N MOD 32    ; Bit number in DWORD
  6310. %@AS@%  mov eax, N / 32    ; DWORD index into array
  6311. %@AS@%  bt dword ptr ArrayBufPTR[eax*4],ebx  ; Test bit for page N
  6312. %@AS@%  jnc short PageNormal
  6313. %@AS@%      PageModified:%@AE@%
  6314.  
  6315. Note that this code is mearly intended to illustrate how the bit array
  6316. works. This code is not the most efficient, or the only way to implement
  6317. this test. There are currently no bits defined in the flags, this parameter
  6318. must be set to 0.  %@NL@%
  6319.  
  6320.  
  6321. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6322.  
  6323. Returns non-zero if succesfull, returns zero if the bit array could not be
  6324. returned (Invalid VMHandle).  %@NL@%
  6325.  
  6326.  
  6327. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6328.  
  6329. Making this call on a VM whose %@AB@%VMStat_PageableV86%@AE@% bit is clear is not an
  6330. error, it simply returns a bit array whose bits are all 0.  %@NL@%
  6331.  
  6332. %@CR:C6A00190132 @%%@CR:C6A00190133 @%
  6333. %@2@%%@CR:C6A00190134 @%%@AB@%LinMapIntoV86%@AE@%%@EH@%%@NL@%
  6334. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6335.  
  6336. %@AS@%  unsigned long LinMapIntoV86(HLinPgNum,VMHandle,VMLinPgNum,nPages,flags)
  6337. %@AS@%     unsigned HLinPgNum;
  6338. %@AS@%     unsigned VMHandle;
  6339. %@AS@%     unsigned VMLinPgNum;
  6340. %@AS@%     unsigned nPages;
  6341. %@AS@%     unsigned flags;%@AE@%
  6342.  
  6343. This call is provided to assist the interface address mapper functions. Its
  6344. purpose is to provide a way for the address mapper to map regions of
  6345. protected mode address space into a VM V86 address space so that API calls
  6346. can be performed. This calls operation is very similar to %@AB@%MapIntoV86%@AE@%, the
  6347. difference being that instead of taking a memory handle, it takes a linear
  6348. address. The call duplicates the memory map down into the indicated VM's V86
  6349. address range. %@AI@%HLinPgNum%@AE@%, together with %@AI@%nPages%@AE@%, indicates the region of
  6350. protected mode address space, or V86 address space that is to be mapped.
  6351. This is a page number, linear address 60610000h would be passed in as
  6352. 60610h. As with %@AB@%MapIntoV86%@AE@% there are implied %@AB@%PageLock%@AE@% and %@AB@%PageUnlocks%@AE@%. Note
  6353. that the linear address is relative to the standard enhanced Windows Ring 0
  6354. DS selector. The %@AI@%VMHandle%@AE@% parameter must be a valid %@AI@%VM handle%@AE@% and indicates
  6355. the V86 space into which the map is to occur. %@AI@%VMLinPgNum%@AE@% is the address in
  6356. the 1Meg VM V86 address space where the map will start (this is a page
  6357. number, thus linear address 60000h = page 60h). Alignment considerations of
  6358. this address (beyond 4K alignment) are the responsibility of the caller. Map
  6359. addresses below page 10h, or above 10Fh will cause an error. %@AI@%nPages%@AE@% is the
  6360. number of pages to map. Note that if %@AI@%HLinPgNum%@AE@% is a V86 page number (at the
  6361. LOW V86 address (at the LOW V86 address <= page 100h) the call does nothing
  6362. except return the %@AI@%HLinPgNum%@AE@% parameter in %@AB@%EDX%@AE@%. There are currently no bits
  6363. defined in the flags. This parameter must be 0.  %@NL@%
  6364.  
  6365.  
  6366. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6367.  
  6368. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  6369. Low DWORD (%@AB@%EAX%@AE@%) is a nonzero value if the map is succesful, returns 0 in eax
  6370. if the map was unsuccesful (invalid address range, invalid %@AI@%VMHandle%@AE@%, map
  6371. range illegal, size discrepancy, insufficient memory for implied %@AB@%PageLock%@AE@%).
  6372. The High DWORD (%@AB@%EDX%@AE@%) is only valid if %@AB@%EAX%@AE@% is nonzero. It is set to the
  6373. %@AI@%VMLinPgNum%@AE@% parameter if the %@AI@%HLinPgNum%@AE@% parameter was not a LOW V86 space
  6374. address, otherwise it is set to the %@AI@%HLinPgNum%@AE@% parameter. In short, %@AB@%EDX%@AE@% is
  6375. the V86 address where the memory is mapped.  %@NL@%
  6376.  
  6377.  
  6378. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6379.  
  6380. As with %@AB@%MapIntoV86%@AE@% there is an implied %@AB@%PageLock%@AE@% which is performed on all of
  6381. the pages mapped. This is consistent with the fact that V86 memory cannot be
  6382. Demand Paged while the VM is in a runable state. Whenever the V86 memory
  6383. mapping is changed via %@AB@%LinMapIntoV86%@AE@%, the previous memory that was mapped in
  6384. the VM is unlocked. The correct way to think of this is that there is an
  6385. implied %@AB@%PageLock%@AE@% whenever memory is mapped into a V86 context, and an
  6386. implied %@AB@%PageUnlock%@AE@% whenever it is "unmapped" from the V86 context. This
  6387. "unmapping" can occur when: A different handle (including the NulPageHandle)
  6388. is MapIntoV86ed to the region, or a %@AB@%PhysIntoV86%@AE@% is performed to the region.
  6389. %@NL@%
  6390.  
  6391. The V86 region mappped into by this call should be %@AB@%MapIntoV86ed %@AE@%with the
  6392. NulPageHandle when the V86 mapping region is no longer needed. There is
  6393. nothing to prevent you from mapping the same protected mode linear address
  6394. into multiple places in a VM, or into multiple VMs. Such operations are not
  6395. particularly advisable though. For one thing, the reporting of memory owned
  6396. by a VM will be disturbed.  %@NL@%
  6397.  
  6398. The reason this call exists is because a protected mode API mapper does not
  6399. have access to the memory handles associated with the various regions of
  6400. protected mode address space. VxDs which do have access to the memory
  6401. handles of the memory to be mapped should be using %@AB@%MapIntoV86%@AE@% to map the
  6402. memory, not this routine.  %@NL@%
  6403.  
  6404. For regions in the Physical addressing region this call will convert into a
  6405. %@AB@%PhysIntoV86%@AE@% call.  %@NL@%
  6406.  
  6407. For regions in the HIGH VM Linear addressing region this call will perform a
  6408. map of the memory from one VM into another VM (or into a different location
  6409. in the same VM). NOTE CAREFULLY: The intent of this support is to provide a
  6410. way for the V86MMGR device to map a region of V86 address space which is
  6411. currently LOCAL to one VM into a GLOBAL region that is addressable by all
  6412. VMs. This type of API is needed by network API mappers. Do not use this
  6413. capability in your VxD, use the V86MMGR service. The details of this aspect
  6414. of operation will change in a later release and code using the old method
  6415. will not function properly.  %@NL@%
  6416.  
  6417. The page attributes for these pages will be P_USER+P_PRES+P_WRITE. P_DIRTY
  6418. and P_ACC will be cleared by the call. PG_TYPE will be set to whatever the
  6419. type of the pages are at its protected mode linear address.  %@NL@%
  6420.  
  6421. The intent of %@AB@%LinMapIntoV86 %@AE@%support for pages between page 10h and
  6422. %@AB@%FirstV86Page%@AE@% is to support enhanced Windows devices which have
  6423. %@AB@%Allocate_Global_V86_Data_Area%@AE@% a GVDAPageAlign region. Use of mapping in this
  6424. region to other addresses can easily crash the system and should be avoided.
  6425. %@NL@%
  6426.  
  6427. Regions which span across %@AB@%FirstV86Page%@AE@% are not allowed.  %@NL@%
  6428.  
  6429. The reason for the page 10h limitation is that on most versions of the Intel
  6430. 80386 CPU there is an errata which prevents you from setting up a Linear !=
  6431. Physical address mapping in the first 64k of the address space.  %@NL@%
  6432.  
  6433. %@CR:C6A00190135 @%%@CR:C6A00190136 @%
  6434. %@2@%%@CR:C6A00190137 @%%@AB@%LinPageLock%@AE@%%@EH@%%@NL@%
  6435. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6436.  
  6437. %@AS@%  unsigned LinPageLock(HLinPgNum,nPages,flags)
  6438. %@AS@%     unsigned HLinPgNum;
  6439. %@AS@%     unsigned nPages;
  6440. %@AS@%     unsigned flags;%@AE@%
  6441.  
  6442. This call is provided to assist the interface address mapper functions. Its
  6443. purpose is to provide a way for the address mapper to lock regions of
  6444. protected mode address space so that API calls can be performed. This calls
  6445. operation is very similar to %@AB@%PageLock%@AE@%, the difference being that instead of
  6446. taking a memory handle, it takes a linear address. %@AI@%HLinPgNum%@AE@%, together with
  6447. %@AI@%nPages%@AE@%, indicates the region of protected mode address space that is to be
  6448. locked. This is a page number, linear address 60610000h would be passed in
  6449. as 60610h. Note that the linear address is relative to the standard enhanced
  6450. Windows Ring 0 DS selector.  %@NL@%
  6451.  
  6452. Current flags bits:  %@NL@%
  6453.  
  6454. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B%@AE@%
  6455.  
  6456. All unused bits must be zero. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  6457. lock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to hardware.
  6458. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to hardware),
  6459. calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively NOPs. See the
  6460. %@AB@%PageAllocate%@AE@% documentation for a description of the different %@AB@%PageSwap%@AE@%
  6461. device types and their relevance.  %@NL@%
  6462.  
  6463.  
  6464. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6465.  
  6466. Returns a nonzero value if the lock is succesful, returns 0 value if the
  6467. lock was unsuccesful (invalid address range, insufficient memory for lock).
  6468. %@NL@%
  6469.  
  6470.  
  6471. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6472.  
  6473. SEE %@AB@%PageLock%@AE@%.  %@NL@%
  6474.  
  6475. %@CR:C6A00190138 @%%@CR:C6A00190139 @%
  6476. %@2@%%@CR:C6A00190140 @%%@AB@%LinPageUnLock%@AE@%%@EH@%%@NL@%
  6477. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6478.  
  6479. %@AS@%  unsigned LinPageUnLock(HLinPgNum,nPages,flags)
  6480. %@AS@%     unsigned HLinPgNum;
  6481. %@AS@%     unsigned nPages;
  6482. %@AS@%     unsigned flags;%@AE@%
  6483.  
  6484. This call is provided to assist the interface address mapper functions. Its
  6485. purpose is to provide a way for the address mapper to unlock regions of
  6486. protected mode address space after API calls are performed. This calls
  6487. operation is very similar to %@AB@%PageUnLock%@AE@%, the difference being that instead
  6488. of taking a memory handle, it takes a linear address.%@AI@% HLinPgNum%@AE@%, together
  6489. with %@AI@%nPages%@AE@%, indicates the region of protected mode address space that is to
  6490. be unlocked. This is a page number, linear address 60610000h would be passed
  6491. in as 60610h. Note that the linear address is relative to the standard
  6492. enhanced Windows Ring 0 DS selector.  %@NL@%
  6493.  
  6494. Current flags bits:  %@NL@%
  6495.  
  6496. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B
  6497. %@AS@%  PageMarkPageOut  EQU 00000000000000000010000000000000B%@AE@%
  6498.  
  6499. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  6500. unlock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to
  6501. hardware. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to
  6502. hardware), calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively
  6503. NOPs. See the %@AB@%PageAllocate%@AE@% documentation for a description of the different
  6504. %@AB@%PageSwap%@AE@% device types and their relevance. %@AB@%PageMarkPageOut%@AE@%, if set,
  6505. indicates that if this unlock actually does unlock the pages (lock count
  6506. goes to 0) the pages are to be made prime candidates for page out. This flag
  6507. should only be set if it is unlikely that these pages are going to be
  6508. touched for a while. Effectively what this does is clear the P_ACC bits of
  6509. the pages which causes them to be first level page out candidates.  %@NL@%
  6510.  
  6511.  
  6512. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6513.  
  6514. Returns a nonzero value if the unlock is succesful, returns 0 value if the
  6515. unlock was unsuccesful (invalid address range).  %@NL@%
  6516.  
  6517.  
  6518. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6519.  
  6520. SEE %@AB@%PageUnLock%@AE@%.  %@NL@%
  6521.  
  6522. %@CR:C6A00190141 @%%@CR:C6A00190142 @%
  6523. %@2@%%@CR:C6A00190143 @%%@AB@%PageCheckLinRange%@AE@%%@EH@%%@NL@%
  6524. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6525.  
  6526. %@AS@%  unsigned PageCheckLinRange(HLinPgNum,nPages,flags)
  6527. %@AS@%     unsigned HLinPgNum;
  6528. %@AS@%     unsigned nPages;
  6529. %@AS@%     unsigned flags;%@AE@%
  6530.  
  6531. This call is provided to assist the interface address mapper functions. Its
  6532. purpose is to provide a way for the address mapper to validate an intended
  6533. range for %@AB@%LinPageLock%@AE@% or %@AB@%LinMapIntoV86%@AE@%. Sometimes a MAXIMUM length range is
  6534. specified because the true range is unknown. This call will return an
  6535. adjusted %@AI@%nPages%@AE@% argument which will be adjusted down in size if the
  6536. specified range crosses an unreasonable boundary. %@AI@%HLinPgNum%@AE@%, together with
  6537. %@AI@%nPages%@AE@%, indicates the region of protected mode address space that is to be
  6538. checked. This is a page number, linear address 60610000h would be passed in
  6539. as 60610h. Note that the linear address is relative to the standard enhanced
  6540. Windows Ring 0 DS selector. There are currently no bits defined in the
  6541. flags, this parameter must be 0.  %@NL@%
  6542.  
  6543.  
  6544. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6545.  
  6546. Returns an adjusted %@AI@%nPages%@AE@% agrument. This will be %@AI@%zero%@AE@% if the range is
  6547. totally unreasonable, and will return %@AI@%nPages%@AE@% if no adjustment was needed.  %@NL@%
  6548.  
  6549.  
  6550. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6551.  
  6552. The end of a handle is a boundary that will result in an adjustment.  %@NL@%
  6553.  
  6554.  
  6555. %@2@%%@CR:C6A00190144 @%%@AB@%PageDiscardPages%@AE@%%@EH@%%@NL@%
  6556. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6557.  
  6558. %@AS@%  unsigned PageDiscardPages(LinPgNum,VMHandle,nPages,flags)
  6559. %@AS@%  unsigned LinPgNum;
  6560. %@AS@%  unsigned VMHandle;
  6561. %@AS@%  unsigned nPages;
  6562. %@AS@%  unsigned flags;%@AE@%
  6563.  
  6564. This call is provided to assist management of PM applications by providing a
  6565. way to mark pages as "no longer in use". What this does is allow regions
  6566. which were previously "in use" to be "discarded". This means that the page
  6567. does not have to be "paged in" to make it present, thus eliminating the disk
  6568. access required for the page in. LinPgNum and nPages together specify the
  6569. range to be discarded. LinPgNum is a page NUMBER. If LinPgNum is < 110h, or
  6570. at a VM high linear address, then the range lies in a VM and the %@AI@%VMHandle%@AE@%
  6571. parameter specifies the VM. In this case, all pages of the range must be
  6572. marked V86Pageable or the call will fail. Pages in the range which are not
  6573. present or are locked are ignored, this call effects only demand pageable
  6574. pages.  %@NL@%
  6575.  
  6576. Current flags bits:  %@NL@%
  6577.  
  6578. %@AS@%  PageZeroInit  EQU 00000000000000000000000000000001B
  6579. %@AS@%  PageDiscard  EQU 00000000000000010000000000000000B%@AE@%
  6580.  
  6581. Setting PageDiscard indicates that a full discard is to take place, the
  6582. P_ACC and P_DIRTY bits in the page table entrys for the pages are both
  6583. cleared. If PageDiscard is clear, all the call does is clear the P_ACC bit
  6584. in the page table entrys for the pages making them primary page out
  6585. candidates (the DIRTYness and content of the pages is preserved in this
  6586. case). Setting PageZeroInit is relevant only if PageDiscard is also set, and
  6587. it indicates that the pages are to be marked "zero the contents of this page
  6588. the next time it is paged in". In this case this subsequent page in is a NOP
  6589. since the pages have been discarded, this simply causes the pages to come
  6590. back in with a known value (0) in them instead of random garbage.  %@NL@%
  6591.  
  6592.  
  6593. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6594.  
  6595. Returns a non-zero value if successful, otherwise it returns zero (invalid
  6596. range or VM handle).  %@NL@%
  6597.  
  6598.  
  6599. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6600.  
  6601. The Flag bit equates are defined by including VMM.INC, please use the
  6602. equates.  %@NL@%
  6603.  
  6604. %@CR:C6A00190145 @%%@CR:C6A00190146 @%
  6605. %@2@%%@CR:C6A00190147 @%%@AB@%SelectorMapFlat%@AE@%%@EH@%%@NL@%
  6606. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6607.  
  6608. %@AS@%  unsigned SelectorMapFlat(VMHandle,Selector,flags)
  6609. %@AS@%     unsigned VMHandle;
  6610. %@AS@%     unsigned Selector;
  6611. %@AS@%     unsigned flags;%@AE@%
  6612.  
  6613. This call is provided to assist the interface address mapper functions. Its
  6614. purpose is to provide a way for the address mapper to get the RING 0 DS
  6615. offset of the base of a particular GDT or LDT selector. This call assists
  6616. the address mapper in converting a Selector:Offset16 or Selector:Offset32
  6617. pointer into its "flat model" linear address which can then be passed to
  6618. %@AB@%LinMapIntoVM%@AE@%. Selector is a GDT or LDT selector (note that the argument is a
  6619. DWORD not a WORD) value to get the base address of. The %@AI@%VMHandle%@AE@% parameter
  6620. is ignored if Selector is a GDT selector. If Selector is an LDT selector,
  6621. then %@AI@%VMHandle%@AE@% indicates the appropriate VM context for the Selector. There
  6622. are currently no bits defined in the flags, this parameter must be 0.  %@NL@%
  6623.  
  6624.  
  6625. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6626.  
  6627. Returns the linear address of the base of the selector if succesful, returns
  6628. FFFFFFFFh if it is unsuccesful (invalid selector).  %@NL@%
  6629.  
  6630.  
  6631. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6632.  
  6633. You can pass this routine the standard enhanced Windows RING 0 DS selector,
  6634. and it will return 0 as the base. This is a silly thing to do, but it does
  6635. work.  %@NL@%
  6636.  
  6637. The %@AI@%VMHandle%@AE@% parameter must be valid for LDT selectors.  %@NL@%
  6638.  
  6639.  
  6640. %@2@%%@CR:C6A00190148 @%%@AB@%SetResetV86Pageable%@AE@%%@EH@%%@NL@%
  6641. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6642.  
  6643. %@AS@%  unsigned SetResetV86Pageable(VMHandle,VMLinPgNum,nPages,flags)
  6644. %@AS@%  unsigned VMHandle;
  6645. %@AS@%  unsigned VMLinPgNum;
  6646. %@AS@%  unsigned nPages;
  6647. %@AS@%  unsigned flags;%@AE@%
  6648.  
  6649. This call allows the normal locking/unlocking behavior associated with a
  6650. specific range of V86 memory to be modified. %@AI@%VMHandle%@AE@% is the VM in which the
  6651. behavior is being modified. %@AI@%VMLinPgNum%@AE@% is the address in the 1Meg V86
  6652. address space where the behavior modification will start (this is a page
  6653. number, thus linear address 60000h = page 60h). Alignment considerations of
  6654. this address (beyond 4K alignment) are the responsibility of the caller. Map
  6655. addresses below %@AB@%FirstV86Page%@AE@%, or above 100h will cause an error. %@AI@%nPages%@AE@% is
  6656. the number of pages to modify the behavior of. Normally a %@AB@%MapIntoV86%@AE@% causes
  6657. the memory that is mapped to be locked. In the case where this particular VM
  6658. is currently running a Protected Mode application, it is desirable to undo
  6659. the lock, and change this normal lock/unlock behavior. This allows those
  6660. unused pieces of the V86 address space to be paged out and the memory they
  6661. are using to be used by someone else. Note that we can only undo this normal
  6662. behavior because the behavior of the protected mode application is well
  6663. known. In particular, we know that none of the V86 memory that is being
  6664. unlocked contains code that is executed, or data that is touched, at
  6665. interrupt time (including software interrupt time). The typical use of this
  6666. call is by the enhanced Windows device which loads a protected mode
  6667. application. When the PM app is loaded, the device calls %@AB@%SetRestV86Pageable%@AE@%
  6668. with the %@AB@%PageSetV86Pageable%@AE@% bit set on those pieces of the V86 address space
  6669. above %@AB@%FirstV86Page%@AE@% which can be unlocked; this is typically all of the V86
  6670. memory above FirstV86Page which is currently MS-DOS Free. NOTE that MS-DOS
  6671. data areas such as the 100h byte Program Header Prefix %@AI@%must not be included%@AE@%
  6672. in the ranges because they are accessed by MS-DOS. Similarly, when the
  6673. Protected Mode application Exits, the application loader calls
  6674. %@AB@%SetResetV86Pageable%@AE@% with PageClearV86Pageable set, on the V86 memory it had
  6675. initially modified during the load.  %@NL@%
  6676.  
  6677. The other aspect of the behavior that can be modified has to do with the
  6678. "other memory" (the memory that is %@AI@%not%@AE@% V86Pageable) in the VM. Normally this
  6679. memory is locked, except when the pager is type 2 (direct to hardware). Not
  6680. locking the V86 memory allows VM's V86 pages to also be Demand Paged. This
  6681. has the benefit of allowing MS-DOS applications to also run in a Demand
  6682. Paged environment. Sometimes though, this is an undesired behavior because
  6683. of the paging latency which it introduces in the VM. The V86IntsLocked bit
  6684. of a VM allows this aspect to be controled. Setting the V86IntsLocked
  6685. behavior causes the "other memory" to %@AI@%always%@AE@% be locked, even if the pager is
  6686. type 2. Setting this behavior has two important effects:  %@NL@%
  6687.  
  6688.  
  6689.   ■   There is never any "paging latency" while the virtual mode code in
  6690.       this VM is running. This prevents time critical V86 code from having
  6691.       its timing severly disturbed due to the paging overhead.%@NL@%
  6692.  
  6693.   ■   The paging device can enable interrupts in this VM when it is
  6694.       performing paging operations because %@AI@%it knows%@AE@% that a nested page fault
  6695.       will not occur from this VM since all of its interrupt time code is
  6696.       always locked.%@NL@%
  6697.  
  6698.  
  6699. Current flags bits:  %@NL@%
  6700.  
  6701. %@AS@%  PageSetV86Pageable  EQU 00000000000000000000001000000000B
  6702. %@AS@%  PageClearV86Pageable  EQU 00000000000000000000010000000000B
  6703. %@AS@%  PageSetV86IntsLocked  EQU 00000000000000000000100000000000B
  6704. %@AS@%  PageClearV86IntsLocked  EQU 00000000000000000001000000000000B%@AE@%
  6705.  
  6706. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageSetV86Pageable%@AE@%, if set, indicates that the
  6707. normal locking behavior of %@AB@%MapIntoV86%@AE@% is to be disabled (V86 memory can be
  6708. paged) for the indicated region. %@AB@%PageClearV86Pageable%@AE@%, if set, indicates
  6709. that the normal locking behavior is to be enabled on the indicated region.
  6710. %@AB@%PageSetV86IntsLocked%@AE@%, if set, indicates that the "lock all V86 memory that
  6711. is not V86Pageable regardless of pager type" behavior is to be enabled.
  6712. PageClearV86IntsLocked, if set, indicates that the "lock all V86 memory that
  6713. is not V86Pageable regardless of pager type" behavior is to be disabled.
  6714. %@AI@%Note%@AE@% that only %@AI@%one %@AE@%of these bits can be set on a call. Setting more than one
  6715. bit will result in an error. There are two bits in %@AB@%CB_VM_Status%@AE@% that
  6716. indicate the current state of these behaviors:  %@NL@%
  6717.  
  6718. %@AS@%  VMStat_PageableV86  EQU 00000000000000000000100000000000B
  6719. %@AS@%  VMStat_V86IntsLocked  EQU 00000000000000000001000000000000B%@AE@%
  6720.  
  6721. The %@AB@%VMStat_PageableV86%@AE@% bit is set if any regions behavior has been modified
  6722. (there is at least one non zero bit in the array returned by
  6723. %@AB@%GetV86PageableArray%@AE@%). The %@AB@%VMStat_V86IntsLocked%@AE@% bit is set if the "lock
  6724. regardless of pager type" behavior has been enabled in this VM.  %@NL@%
  6725.  
  6726.  
  6727. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6728.  
  6729. Returns non-zero value if the set or clear worked, zero if the current state
  6730. of the VM was not consistent with the call (invalid VMHandle,
  6731. %@AB@%VMStat_PageableV86%@AE@% or %@AB@%VMStat_V86IntsLocked%@AE@% state inconsistent with setting
  6732. of %@AB@%PageSet/ClearV86Pageable%@AE@% or %@AB@%PageSet/ClearV86IntsLocked%@AE@% bit in flags,
  6733. range invalid) or the lock of the memory associated with
  6734. %@AB@%PageClearV86Pageable%@AE@% or %@AB@%PageSetV86IntsLocked%@AE@% failed.  %@NL@%
  6735.  
  6736.  
  6737. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6738.  
  6739. The intent of this call is to better support Protected mode applications
  6740. running in a VM, not to allow you to randomly make v86 parts of VMs
  6741. pageable! Do not issue this call on a VM unless you are loading a Protected
  6742. mode app into it.  %@NL@%
  6743.  
  6744. The V86MMGR device makes a %@AB@%PageSetV86IntsLocked%@AE@% call on VMs which are
  6745. created with their base memory specified as %@AI@%locked%@AE@%.  %@NL@%
  6746.  
  6747. Extreme care must be used when manipulating the PageableV86 behavior of
  6748. regions above A000:0. This should not be done unless the region is GLOBAL or
  6749. LOCAL %@AB@%Assign_Device_V86_Pages%@AE@% owned by the caller.  %@NL@%
  6750.  
  6751. There is no REGION associated with %@AB@%PageSetV86IntsLocked%@AE@% and
  6752. %@AB@%PageClearV86IntsLocked%@AE@% calls. The IMPLIED region is always "everything that
  6753. isn't V86Pageable". For this reason the %@AI@%HLinPgNum%@AE@% and %@AI@%nPages%@AE@% arguments
  6754. should be set to 0 on these calls.  %@NL@%
  6755.  
  6756. VMM.INC contains equates for all of the flag bits described, use the
  6757. equates.  %@NL@%
  6758.  
  6759.  
  6760. %@2@%%@CR:C6A00190149 @%%@AB@%19.9  Instance Data Management%@AE@%%@EH@%%@NL@%
  6761. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6762.  
  6763. The purpose of these services is to provide a means of identifying to the
  6764. system those areas of virtual 8086 mode memory (V86 memory) that contain per
  6765. Virtual Machine or "Instance" data. Each of the VMs in the system has its
  6766. own, private instance of this data and anything the VM does to the values in
  6767. these locations has no effect on other VMs since the values are different in
  6768. each VM.  %@NL@%
  6769.  
  6770. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6771. NOTE
  6772.  
  6773. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  6774. %@AI@%procedure has an underscore in front (i.e., %@AB@%AddInstanceItem%@AE@%%@AI@% is actually%@AE@%%@AI@%%@AB@%
  6775. %@AB@%_AddInstanceItem%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to left (unlike the
  6776. %@AI@%PL/M calling convention used by Windows, which is left to right). The return
  6777. %@AI@%value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the responsibility of the
  6778. %@AI@%caller%@AE@%%@AI@%to clear the arguments off the stack. Registers %@AE@%%@AI@%%@AB@%EAX%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ECX%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EDX%@AE@%%@AE@%%@AI@% are
  6779. %@AI@%changed by calls. Registers %@AE@%%@AI@%%@AB@%DS%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ES%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EBP%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%EDI%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ESI%@AE@%%@AE@%%@AI@%, and
  6780. %@AI@%@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved.%@AE@%%@AE@%
  6781. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6782.  
  6783. %@CR:C6A00190150 @%%@CR:C6A00190151 @%
  6784. %@2@%%@CR:C6A00190152 @%%@AB@%AddInstanceItem%@AE@%%@EH@%%@NL@%
  6785. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6786.  
  6787. %@AS@%  unsigned AddInstanceItem(InstStrucPTR,flags)
  6788. %@AS@%     unsigned InstStrucPTR;
  6789. %@AS@%     unsigned flags;%@AE@%
  6790.  
  6791. This call is used to identify a region of instance data in the V86 address
  6792. space. %@AI@%InstStrucPTR%@AE@% is a pointer to an instance data identification
  6793. structure which has this form:  %@NL@%
  6794.  
  6795. %@AS@%  InstDataStruc struc
  6796. %@AS@%     InstLinkF  dd ? ; RESERVED SET TO 0
  6797. %@AS@%     InstLinkB  dd ? ; RESERVED SET TO 0
  6798. %@AS@%     InstLinAddr  dd ? ; Linear address of start of block
  6799. %@AS@%     InstSize  dd ? ; Size of block in bytes
  6800. %@AS@%     InstType  dd ? ; Type of the block 
  6801. %@AS@%  InstDataStruc ends%@AE@%
  6802.  
  6803. The InstLinkF and InstLinkB fields are filled in by the Instance data
  6804. manager and cannot be used by the caller. InstLinAddr defines the start of
  6805. the block of instance data, NOTE THAT THIS IS NOT IN SEG:OFFSET FORM, it is
  6806. a linear address. Thus the correct value for 40:2F would be 42F. InstSize is
  6807. the size of the instance data block in bytes starting at InstLinAddr.
  6808. InstType defines one of two types of instance data:  %@NL@%
  6809.  
  6810. %@AS@%  INDOS_Field   equ  100h ; Bit indicating INDOS switch requirements 
  6811. %@AS@%  ALWAYS_Field  equ  200h ; Bit indicating ALWAYS switch requirements%@AE@%
  6812.  
  6813. ALWAYS_Field type indicates that the field must always be switched when a VM
  6814. is switched. All instance data sepcified by VxDs should be of this type.
  6815. INDOS_Field type is reserved for special types of MS-DOS internal data which
  6816. only need to be switched with the VM if the VM is currently INDOS.  %@NL@%
  6817.  
  6818. There are currently no bits defined in the flags, this parameter must be set
  6819. to 0.  %@NL@%
  6820.  
  6821.  
  6822. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6823.  
  6824. Returns nonzero value if the instance data block was succesfully added to
  6825. the instance list, zero if the block was unsuccesful added (This is probably
  6826. a FATAL error).  %@NL@%
  6827.  
  6828. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6829. NOTE
  6830.  
  6831. %@AI@%There are two basic ways to allocate the space for the InstDataStrucs
  6832. %@AI@%pointed to with InstStrucPTR. The first is to simply staticly allocate them
  6833. %@AI@%in the INIT data segment. The space they occupy will then be reclaimed when
  6834. %@AI@%the INIT space is reclaimed. The other way is to allocate them on the System
  6835. %@AI@%heap using HeapAllocate. The space can then be freed by HeapFreeing all of
  6836. %@AI@%the heap handles in the device Sys_VM_Init code which is called after all of
  6837. %@AI@%the system initialization (including the instance data initialization) is
  6838. %@AI@%done.%@AE@%
  6839.  
  6840. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6841. %@AU@%WARNING%@AE@%
  6842.  
  6843.  
  6844. If you allocate space for InstDataStrucs on the heap you must be sure NOT to
  6845. HeapReAllocate the heap blocks after passing the address to AddInstanceItem
  6846. because this will invalidate the InstStrucPTR value you previously passed to
  6847. AddInstanceItem.
  6848. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6849.  
  6850.  
  6851. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6852. NOTE 
  6853.  
  6854. %@AI@%This routine is in the init segment of enhanced Windows. It can therefore
  6855. %@AI@%only be called during system initialization. Trying to call it after system
  6856. %@AI@%initialization and the system INIT segment space has been reclaimed will
  6857. %@AI@%result in a fatal page fault.%@AE@%
  6858. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6859.  
  6860. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6861.  
  6862. Once this call is made, the caller %@AB@%must not %@AE@%ever touch the InstDataStruc
  6863. pointed to again. The caller has passed control of this data block to the
  6864. instrance data manager and tampering with it will result in the instance
  6865. data manager failing to identify the instance data correctly.  %@NL@%
  6866.  
  6867. Note that only one, contiguous region of instance data can be identified
  6868. with each structure. It is a good idea for the caller to coalesce adjacent
  6869. blocks of instance data it is identifying in order to cut down the call
  6870. overhead and data space requirements, but this is not required.  %@NL@%
  6871.  
  6872. There is a declaration of the InstDataStruc data structure in VMM.INC.  %@NL@%
  6873.  
  6874. %@CR:C6A00190153 @%%@CR:C6A00190154 @%
  6875. %@2@%%@CR:C6A00190155 @%%@AB@%MMGR_Toggle_HMA%@AE@%%@EH@%%@NL@%
  6876. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6877.  
  6878. %@AS@%  unsigned MMGR_Toggle_HMA(VMHandle,flags)
  6879. %@AS@%   unsigned VMHandle;
  6880. %@AS@%   unsigned flags;%@AE@%
  6881.  
  6882. This call is an interface to the Instance data manager which allows devices
  6883. such as the V86MMGR XMS device to control the behavior of the "highmem"
  6884. memory area, or "HMA", of a VM (V86 linear pages 100h through 10Fh). Any
  6885. device which wishes to modify the "1Meg Address Wrap" behavior of a VM MUST
  6886. use this call to inform the Instance data manager what is going on. This is
  6887. because the Instance manager must know whether 1Meg Address Wrap is on or
  6888. off to manage the instance data correctly for a VM. %@AI@%VMHandle%@AE@% is a valid
  6889. enhanced Windows VM handle which indicates the VM to which the call is to be
  6890. applied. Current flags bits:  %@NL@%
  6891.  
  6892. %@AS@%  MMGRHMAPhysical  EQU 00000000000000000000000000000001B 
  6893. %@AS@%  MMGRHMAEnable  EQU 00000000000000000000000000000010B 
  6894. %@AS@%  MMGRHMADisable  EQU 00000000000000000000000000000100B 
  6895. %@AS@%  MMGRHMAQuerry  EQU 00000000000000000000000000001000B%@AE@%
  6896.  
  6897. All unused bits must be zero. One, and only one of MMGRHMAEnable,
  6898. MMGRHMADisable, MMGRHMAQuerry BITS must be specified, the call will have
  6899. random results if this is not true. MMGRHMAPhysical bit is a modifier which
  6900. modifies the operation of the MMGRHMAEnable bit: See discussion of
  6901. MMGRHMAEnable. MMGRHMADisable, if set, causes the Instance manager to
  6902. restore the normal Wrap mapping for pages 100 through 10F thus Disabling the
  6903. HMA. This is a REMAP of pages 00h through 0Fh of the VM and causes the VMs
  6904. address space to "wrap" back to address zero for addresses >1Meg as it does
  6905. on an 8086 processor. MMGRHMAEnable, if set, disables 1Meg address wrap in
  6906. the VM, thus Enabling the HMA. Exactly what this does is controlled by the
  6907. MMGRHMAPhysical bit. If MMGRHMAPhysical is set, MMGRHMAEnable causes
  6908. PHYSICAL pages 100h through 10Fh to be mapped in Linear pages 100h through
  6909. 10Fh of the VM consistent with the operation of a Global HMA which is shared
  6910. by all VMs. If MMGRHMAPhysical is not set, Linear pages 100h through 10Fh
  6911. will be marked as not present System Pages in the VM. It is then up to the
  6912. CALLER to map some other memory handle into this region of the VM after this
  6913. call. This is consistent with the operation of a per VM HMA. Note that if
  6914. the VM accesses these pages before this mapping is set up, an erroneaous
  6915. page fault will occur which will crash the VM, or the system. MMGRHMAQuerry,
  6916. if set, returns the current state of the HMA in the VM.  %@NL@%
  6917.  
  6918.  
  6919. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6920.  
  6921. This call has no return value unless MMGRHMAQuerry was specified in the
  6922. flags. In this case the call will return value 0 if the HMA is Disabled
  6923. (1Meg address wrap is enabled), and it will return a nonzero value if the
  6924. HMA is Enabled (1Meg address wrap is disabled).  %@NL@%
  6925.  
  6926.  
  6927. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6928.  
  6929. This call is reserved for the V86MMGR XMS device. Other devices should not
  6930. be using this call. Modifying the Wrap state of a VM without the V86MMGR XMS
  6931. device knowing about it will probably result in a state error and a crash.  %@NL@%
  6932.  
  6933. The device issuing this call must be a device which has succesfully Globally
  6934. or Locally %@AB@%Assign_Device_VM_Paged%@AE@% pages 100h through 10Fh in the indicated
  6935. VM. This is not a call which multiple devices should make for a VM as doing
  6936. so will cause confusion between the devices.  %@NL@%
  6937.  
  6938. When VMs are created, they are created with the HMA Disabled (1Meg Address
  6939. Wrap enabled) consistent with normal operation on an 8086 processor. The
  6940. device responsible for the HMA in a VM must adjust this in its %@AB@%Create_VM%@AE@%
  6941. device call if needed.  %@NL@%
  6942.  
  6943. Note that no distinction is drawn on the MMGRHMAQuerry return between
  6944. MMGRHMAPhysical being specified, or not specified on a previous
  6945. MMGRHMADisable call.  %@NL@%
  6946.  
  6947. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6948. NOTE 
  6949.  
  6950. %@AI@%Instance data is not allowed in the hma.%@AE@%
  6951. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6952.  
  6953. The flag bit equates are in VMM.INC, please use the equates.  %@NL@%
  6954.  
  6955.  
  6956. %@2@%%@CR:C6A00190156 @%%@AB@%19.10  Looking At V86 Address Space%@AE@%%@EH@%%@NL@%
  6957. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6958.  
  6959. From time to time, VxDs may wish to look at or modify some piece of the
  6960. virtual 8086 mode address space of a VM that is not the current VM. The
  6961. documented way to do this is as follows.  %@NL@%
  6962.  
  6963. %@CR:C6A00190157 @%%@CR:C6A00190158 @%
  6964. %@2@%%@CR:C6A00190159 @%%@AB@%CB_High_Linear%@AE@%%@EH@%%@NL@%
  6965. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6966.  
  6967. There is a Control Block variable which is a linear address of the start of
  6968. the VM's address space. Thus to look at VM linear adress 40:17 with %@AB@%EBX%@AE@%
  6969. being the VM Handle of the VM you're interested in you would do this:  %@NL@%
  6970.  
  6971. %@AS@%  mov esi,(40h SHL 4) + 17h
  6972. %@AS@%  add esi,[ebx.CB_High_Linear]%@AE@%
  6973.  
  6974. %@AB@%ESI%@AE@% now points to this location in the V86 address space. This can be used
  6975. to look at, modify any V86 address including instance data addresses.  %@NL@%
  6976.  
  6977. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6978. NOTE 
  6979.  
  6980. %@AI@%No code should EVER touch a part of V86 address space at its "low" address
  6981. %@AI@%(>=0,<=400000h) EVEN FOR THE CURRENT VM. There is NO REASON to do this, use
  6982. %@AI@%CB_High_Linear in ALL cases to look at V86 addresses.%@AE@%
  6983. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6984.  
  6985.  
  6986.  
  6987.  
  6988.  
  6989.  
  6990. %@CR:C6A00200001 @%%@1@%%@AB@%Chapter 20  I/O Services and Macros%@AE@%%@EH@%%@NL@%
  6991. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6992.  
  6993. This chapter documents the services available for I/O. Also included are two
  6994. macros and a discussion explaining their usefulness.  %@NL@%
  6995.  
  6996. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  6997. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  6998.  
  6999. When a virtual machine executes an instruction that reads or writes data
  7000. from an I/O port, the 80386 looks up the port number in the I/O Permission
  7001. Map (IOPM). If the corresponding bit in the IOPM is set, then the
  7002. instruction will cause a protection fault.  %@NL@%
  7003.  
  7004. Enhanced Windows provides services that virtual devices use to trap I/O. The
  7005. first thing a virtual device must do is hook the port while the device is
  7006. being initialized. This is done by calling a service called
  7007. %@AB@%Install_IO_Handler%@AE@%. It takes two parameters: the number of the I/O port to
  7008. hook and the address of a callback procedure.  %@NL@%
  7009.  
  7010. The I/O services and macros supported by enhanced Windows are described in
  7011. this chapter in the following order:  %@NL@%
  7012.  
  7013.  
  7014.   ■   %@AB@%Enable_Global_Trapping%@AE@%%@NL@%
  7015.  
  7016.   ■   %@AB@%Disable_Global_Trapping%@AE@%%@NL@%
  7017.  
  7018.   ■   %@AB@%Enable_Local_Trapping%@AE@%%@NL@%
  7019.  
  7020.   ■   %@AB@%Disable_Local_Trapping%@AE@%%@NL@%
  7021.  
  7022.   ■   %@AB@%Install_IO_Handler%@AE@%%@NL@%
  7023.  
  7024.   ■   %@AB@%Install_Mult_IO_Handlers%@AE@%%@NL@%
  7025.  
  7026.   ■   %@AB@%Simulate_IO%@AE@%%@NL@%
  7027.  
  7028.  
  7029.  
  7030. %@2@%%@CR:C6A00200002 @%%@AB@%20.1  Handling Different I/O Types%@AE@%%@EH@%%@NL@%
  7031.  
  7032. The value passed in %@AB@%ECX%@AE@% determines the type of input or output as specified
  7033. by Table 20.1.  %@NL@%
  7034.  
  7035. Table 20.1  I/O Register Values
  7036.  
  7037. %@TH:   9   464 02 22 54 @%
  7038. Value                 Type of input/output
  7039. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7040. 00H                   Byte input
  7041. 04H                   Byte output
  7042. 08H                   WORD input
  7043. 0CH                   WORD output
  7044. 10H                   DWORD input
  7045. 14H                   DWORD output
  7046. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7047. %@TE:   9   464 02 22 54 @%
  7048.  
  7049. Masks that apply only to string I/O are shown in Table 20.2.  %@NL@%
  7050.  
  7051. Table 20.2  String I/O Register Values
  7052.  
  7053. %@TH:   7   417 02 13 63 @%
  7054. Value        Type of input/output
  7055. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7056. 20H          String I/O
  7057. 40H          Repeated string I/O
  7058. 80H          32-bit addressing mode string I/O
  7059. 100H         Reverse string I/O (VM's direction flag is set)
  7060. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7061. %@TE:   7   417 02 13 63 @%
  7062.  
  7063. For all string I/O operations, the high WORD of %@AB@%ECX%@AE@% contains the segment for
  7064. the string I/O. This allows VxDs to ignore the issues of segment overrides
  7065. on these instructions; VMM has already determined the correct segment value.
  7066. Thus, a value of 3247016CH would specify that the VM is doing word reverse
  7067. repeated string output from 3247:SI.  %@NL@%
  7068.  
  7069. For example:  %@NL@%
  7070.  
  7071. High word = segment 3247 0Ch = Word output 20h = String I/O 40h = Repeated
  7072. string I/O 100h = Reverse I/O  %@NL@%
  7073.  
  7074. It would be unreasonable to expect every VxD to support 48 different types
  7075. of I/O. Therefore, the VxD environment only requires VxDs to support byte
  7076. input and output, even though a VxD can directly support any type of I/O
  7077. that is appropriate. For example, there is no reason for the Virtual Printer
  7078. Device (VPD) to support WORD input and output since printer ports are only
  7079. 8-bits wide.  %@NL@%
  7080.  
  7081. However, the VxDs for devices with 16-bit ports can directly support WORD
  7082. I/O as well as byte I/O.  %@NL@%
  7083.  
  7084. Furthermore, devices such as disk drives might need to directly emulate
  7085. string I/O for some ports to achieve acceptable performance. A device can
  7086. emulate some types of I/O and ignore others.  %@NL@%
  7087.  
  7088. But what happens if someone does WORD string output to a printer port? You
  7089. canot just throw the I/O away! For this reason, enhanced Windows has a
  7090. catch-all routine called %@AB@%Simulate_IO%@AE@% that converts I/O into something the
  7091. virtual device can understand. Notice in the port trap code of the VPD
  7092. example that entry points start with the %@AB@%Emulate_Non_Byte_IO%@AE@% macro. This
  7093. macro generates the following code:  %@NL@%
  7094.  
  7095. %@AS@%  cmp ecx, 4 
  7096. %@AS@%   jbe SHORT Foo 
  7097. %@AS@%   VMMjmp Simulate_IO 
  7098. %@AS@%  
  7099. %@AS@%  Foo:%@AE@%
  7100.  
  7101. So, if a VM attempted to do non-repeated forward %@AB@%word%@AE@% string I/O, the
  7102. following sequence of calls to the VPD trap code would be issued:  %@NL@%
  7103.  
  7104. Call VPD trap with:  %@NL@%
  7105.  
  7106. %@AB@%EBX%@AE@% = VM handle %@AB@%EDX%@AE@% = 358h (Port #) %@AB@%ECX%@AE@% = 23A8002Ch (String I/O from segment
  7107. 23A8h) %@AB@%EBP%@AE@% = Client register structure  %@NL@%
  7108.  
  7109. VPD jumps to %@AB@%Simulate_I/O%@AE@% which calls VPD again with:  %@NL@%
  7110.  
  7111. %@AB@%EBX%@AE@% = VM handle %@AB@%EDX%@AE@% = 358h (Port #) %@AB@%ECX%@AE@% = 0Ch (0Ch = Word output) %@AB@%AX %@AE@%= Word
  7112. to output %@AB@%EBP%@AE@% = Client register structure  %@NL@%
  7113.  
  7114. VPD jumps to %@AB@%Simulate_I/O%@AE@% which calls VPD again with:  %@NL@%
  7115.  
  7116. %@AB@%EBX%@AE@% = VM handle %@AB@%EDX%@AE@% = 358h (Port #) %@AB@%ECX%@AE@% = 04h (04h = Byte output) %@AB@%AL%@AE@% = Byte
  7117. to output %@AB@%EBP%@AE@% = Client register structure  %@NL@%
  7118.  
  7119. VPD then simulates the byte output and returns.  %@NL@%
  7120.  
  7121. Notice that the high-order byte of the word output would be sent to the trap
  7122. routine for VPD trap port # +1. So, if VPD is trapping port 358H, then word
  7123. output to this port will be converted into byte output to ports 358H and
  7124. 359H (exactly the way the hardware works).  %@NL@%
  7125.  
  7126.  
  7127. %@2@%%@CR:C6A00200003 @%%@AB@%20.2  I/O Macros%@AE@%%@EH@%%@NL@%
  7128.  
  7129. There are two useful macros for I/O trap routines. The first macro,
  7130. %@AB@%Emulate_Non_Byte_IO%@AE@%, generates the following code:  %@NL@%
  7131.  
  7132. %@AS@%  cmp ecx, Byte_Output
  7133. %@AS@%    jbe SHORT Is_Byte_IO
  7134. %@AS@%    VMMjmp Simulate_IO
  7135. %@AS@%    jnz Is_Byte_Input
  7136. %@AS@%  Is_Byte_IO:%@AE@%
  7137.  
  7138. %@AB@%Dispatch_Byte_IO%@AE@%, the second useful macro, takes two arguments. The first is
  7139. the destination for byte input, and the second is the destination for byte
  7140. output. This macro passes back all non-byte I/O to %@AB@%Simulate_IO%@AE@%. A typical
  7141. I/O trap routine looks like the following:  %@NL@%
  7142.  
  7143. %@AS@%  BeginProc VfooD_Trap_Data
  7144. %@AS@%    Dispatch_Byte_IO Fall_Through, VFood_Out_Data
  7145. %@AS@%     ...
  7146. %@AS@%    (Code for byte input)
  7147. %@AS@%    ...
  7148. %@AS@%    ret 
  7149. %@AS@%  
  7150. %@AS@%  VfooD_Out_Data:
  7151. %@AS@%    ...
  7152. %@AS@%    (Code for byte output)
  7153. %@AS@%    ...
  7154. %@AS@%    ret
  7155. %@AS@%  EndProc VfooD_Trap_Data%@AE@%
  7156.  
  7157. Notice the special value %@AB@%Fall_Through%@AE@% that instructs the %@AB@%Dispatch_Byte_IO%@AE@%
  7158. macro that byte input should fall through to the following code. You can
  7159. substitute %@AB@%Fall_Through%@AE@% for either the input or output parameter (but not
  7160. both) or specify two labels.  %@NL@%
  7161.  
  7162.  
  7163. %@2@%%@CR:C6A00200004 @%%@AB@%20.3  I/O Services%@AE@%%@EH@%%@NL@%
  7164.  
  7165. This section presents detailed information on each of the following I/O
  7166. services:  %@NL@%
  7167.  
  7168.  
  7169.   ■   %@AB@%Enable_Global_Trapping%@AE@%%@NL@%
  7170.  
  7171.   ■   %@AB@%Disable_Global_Trapping%@AE@%%@NL@%
  7172.  
  7173.   ■   %@AB@%Enable_Local_Trapping%@AE@%%@NL@%
  7174.  
  7175.   ■   %@AB@%Disable_Local_Trapping%@AE@%%@NL@%
  7176.  
  7177.   ■   %@AB@%Install_IO_Handler%@AE@%%@NL@%
  7178.  
  7179.   ■   %@AB@%Install_Mult_IO_Handlers%@AE@%%@NL@%
  7180.  
  7181.   ■   %@AB@%Simulate_IO%@AE@%%@NL@%
  7182.  
  7183.  
  7184. %@CR:C6A00200005 @%%@CR:C6A00200006 @%%@CR:C6A00200007 @%%@CR:C6A00200008 @%
  7185. %@2@%%@CR:C6A00200009 @%%@AB@%Enable_Global_Trapping, Disable_Global_Trapping%@AE@%%@EH@%%@NL@%
  7186. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7187.  
  7188.  
  7189. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7190.  
  7191. These services enable and disable I/O port trapping in every VM. A callback
  7192. hook must have been installed during initialization before either of these
  7193. services is used.  %@NL@%
  7194.  
  7195. The global trapping state is by default enabled. When a VM is created, it
  7196. will be created with the current global trapping state.  %@NL@%
  7197.  
  7198.  
  7199. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7200.  
  7201. %@AB@%EDX%@AE@% = I/O port number  %@NL@%
  7202.  
  7203.  
  7204. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7205.  
  7206. None  %@NL@%
  7207.  
  7208.  
  7209. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7210.  
  7211. Flags  %@NL@%
  7212.  
  7213. %@CR:C6A00200010 @%%@CR:C6A00200011 @%%@CR:C6A00200012 @%%@CR:C6A00200013 @%
  7214. %@2@%%@CR:C6A00200014 @%%@AB@%Enable_Local_Trapping, Disable_Local_Trapping%@AE@%%@EH@%%@NL@%
  7215. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7216.  
  7217.  
  7218. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7219.  
  7220. These services enable and disable I/O port trapping in a specific VM. A
  7221. callback hook must have been installed during initialization before either
  7222. of these services is used.  %@NL@%
  7223.  
  7224.  
  7225. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7226.  
  7227. %@AB@%EBX %@AE@%= VM handle %@AB@%EDX%@AE@% = I/O port number  %@NL@%
  7228.  
  7229.  
  7230. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7231.  
  7232. None  %@NL@%
  7233.  
  7234.  
  7235. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7236.  
  7237. Flags  %@NL@%
  7238.  
  7239. %@CR:C6A00200015 @%%@CR:C6A00200016 @%
  7240. %@2@%%@CR:C6A00200017 @%%@AB@%Install_IO_Handler (Initialization only)%@AE@%%@EH@%%@NL@%
  7241. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7242.  
  7243.  
  7244. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7245.  
  7246. This service installs a callback procedure for I/O port trapping and enables
  7247. trapping for the specified port in all VM's. Only one procedure may be
  7248. installed for each port.  %@NL@%
  7249.  
  7250. When an I/O callback is installed, the default global trapping state is
  7251. enabled. You can disable trapping of a port for every or specific VMs using
  7252. the %@AB@%Enable/Disable_Global_Trapping%@AE@% and %@AB@%Enable/Disable_Local_Trapping%@AE@%
  7253. services.  %@NL@%
  7254.  
  7255.  
  7256. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7257.  
  7258. %@AB@%ESI%@AE@% = Address of procedure to call %@AB@%EDX%@AE@% = I/O port  %@NL@%
  7259.  
  7260.  
  7261. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7262.  
  7263. If carry set then  ERROR: Port already hooked by another device or  unable
  7264. to hook any more ports (out of hooks) else  Port hooked successfully  %@NL@%
  7265.  
  7266.  
  7267. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7268.  
  7269. Flags  %@NL@%
  7270.  
  7271.  
  7272. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7273.  
  7274. %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = Type of I/O %@AB@%EDX%@AE@% = Port number %@AB@%EBP%@AE@% -> Client
  7275. register structure  %@NL@%
  7276.  
  7277. If output then  EAX/AX/AL = Data output to port els e (input)  Callback
  7278. procedure must return EAX/AX/AL for data input from  port  %@NL@%
  7279.  
  7280. %@CR:C6A00200018 @%%@CR:C6A00200019 @%
  7281. %@2@%%@CR:C6A00200020 @%%@AB@%Install_Mult_IO_Handlers (Initialization only)%@AE@%%@EH@%%@NL@%
  7282. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7283.  
  7284.  
  7285. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7286.  
  7287. This service makes repeated calls to the %@AB@%Install_IO_Handler%@AE@% service with the
  7288. entries in a table built using macros as follows:  %@NL@%
  7289.  
  7290. Begin_Vxd_IO_Table Table_Name  Vxd_IO <port#>, <procedure name>     ...
  7291. Vxd_IO <port #>, <procedure name>  Vxd_IO <port #>, <procedure name>
  7292. End_Vxd_IO_Table Table_Name  %@NL@%
  7293.  
  7294.  
  7295. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7296.  
  7297. %@AB@%EDI%@AE@% = Address of VxD_IO_Table  %@NL@%
  7298.  
  7299.  
  7300. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7301.  
  7302. If carry set then  ERROR: One or more ports already hooked by another device
  7303. or unable to hook any more ports (out of hooks)  EDX = Number of port that
  7304. could not be hooked  else  Ports hooked successfully  %@NL@%
  7305.  
  7306.  
  7307. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7308.  
  7309. Flags  %@NL@%
  7310.  
  7311.  
  7312. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7313.  
  7314. %@AB@%EAX%@AE@% = Data for output instructions %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = Type of I/O
  7315. %@AB@%EDX%@AE@% = Port number %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  7316.  
  7317. Callback procedure must return EAX/AX/AL for data input from port  %@NL@%
  7318.  
  7319. %@CR:C6A00200021 @%%@CR:C6A00200022 @%
  7320. %@2@%%@CR:C6A00200023 @%%@AB@%Simulate_IO%@AE@%%@EH@%%@NL@%
  7321. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7322.  
  7323.  
  7324. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7325.  
  7326. This service is used to break complex I/O instructions into simpler types of
  7327. I/O. An I/O handler should jump to this service using %@AB@%VMMjmp Simulate_IO%@AE@%
  7328. whenever the handler is called with a type of I/O that it does not directly
  7329. support. A typical I/O trap handler would start with code similar to the
  7330. following:  %@NL@%
  7331.  
  7332. %@AS@%  Sample_IO_Handler:
  7333. %@AS@%    cmp ecx, Byte_Output
  7334. %@AS@%    je SHORT SIH_Simulate_Output
  7335. %@AS@%    jb SHORT SIH_Simulate_Input
  7336. %@AS@%    VMMjmp Simulate_IO %@AE@%
  7337.  
  7338. Since byte input is 0 and byte output is 4, a single compare can be used to
  7339. determine if the I/O is byte input, output, or not supported. When
  7340. %@AB@%Simulate_IO%@AE@% is invoked, it will break the I/O into simpler I/O types and
  7341. recursively call %@AB@%Sample_IO_Handler%@AE@%.  %@NL@%
  7342.  
  7343. For example, assume %@AB@%Sample_IO_Handler%@AE@% is the I/O trap handler for port 534H.
  7344. If it was called with %@AB@%ECX = Word_Output%@AE@%, then it would immediately jump to
  7345. the %@AB@%Simulate_IO%@AE@% service. %@AB@%Simulate_IO%@AE@% would then break the I/O instruction
  7346. into byte output to ports 534H and 535H. When %@AB@%Sample_IO_Handler%@AE@% was called
  7347. again, it would be able to virtualize the byte output to port 534H. The
  7348. output to port 535H would be handled by another port trap routine, or, if
  7349. there was not one installed, the output would be reflected directly to
  7350. hardware port 535H.  %@NL@%
  7351.  
  7352. Two macros, %@AB@%Emulate_Non_Byte_IO%@AE@% and %@AB@%Dispatch_Byte_IO%@AE@%, are provided as
  7353. convenient ways to invoke this service.  %@NL@%
  7354.  
  7355. %@AB@%Emulate_Non_Byte_IO%@AE@% is usually the first line of an I/O trap handler. It
  7356. simply compares %@AB@%ECX%@AE@% to %@AB@%Byte_Output%@AE@% and, if it is greater, it jumps to the
  7357. %@AB@%Simulate_IO%@AE@% service. For example:  %@NL@%
  7358.  
  7359. %@AS@%  Sample_IO_Handler:
  7360. %@AS@%   Emulate_Non_Byte_IO
  7361. %@AS@%   (Here ECX will be 0 for byte input or 4 for byte output) %@AE@%
  7362.  
  7363. %@AB@%Dispatch_Byte_IO%@AE@% is usually more convenient since it will also jump to the
  7364. appropriate code for byte input or output. The macro takes two parameters.
  7365. The first parameter specifies the label to jump to for byte input, and the
  7366. second specifies the label to jump to for byte output. Either parameter (but
  7367. not both) can have the special value %@AB@%Fall_Through%@AE@%, which specifies that the
  7368. code to handle that I/O type immediately follows the macro. For example:  %@NL@%
  7369.  
  7370. %@AS@%  Sample_IO_Handler:
  7371. %@AS@%   Dispatch_Byte_IO Fall_Through, <SHORT  SIH_Output>
  7372. %@AS@%   (...Code here for handling byte input...)
  7373. %@AS@%   ret %@AE@%
  7374.  
  7375. %@AS@%  SIH_Output:
  7376. %@AS@%   (...Code here for handling byte output...)
  7377. %@AS@%   ret %@AE@%
  7378.  
  7379. If, for efficiency reasons, you want to provide code to virtualize I/O other
  7380. than byte input and output, test for the types that you can handle and then
  7381. jump to this service to emulate other types of I/O.  %@NL@%
  7382.  
  7383. Notice that the entry parameters to this service are identical to the
  7384. parameters passed to your I/O trap routine. You should jump to this service
  7385. using the %@AB@%VMMjmp%@AE@% macro with all of the registers in the same state as when
  7386. your I/O trap routine was called (although you may modify %@AB@%ESI%@AE@% and %@AB@%EDI%@AE@% since
  7387. they are not parameters).  %@NL@%
  7388.  
  7389.  
  7390. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7391.  
  7392. %@AB@%EAX%@AE@% = Data for output instructions %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX %@AE@%= Type of I/O
  7393. (same as passed to I/O trap routine) %@AB@%EDX%@AE@% = I/O port %@AB@%EBP%@AE@% -> Client Register
  7394. Structure  %@NL@%
  7395.  
  7396.  
  7397. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7398.  
  7399. All registers modified. If input, then %@AB@%AX%@AE@% or %@AB@%EAX%@AE@% will contain virtualized
  7400. input value.  %@NL@%
  7401.  
  7402.  
  7403. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7404.  
  7405. %@AB@%EAX%@AE@%,%@AB@% EBX%@AE@%, %@AB@%ECX%@AE@%,%@AB@% EDX%@AE@%,%@AB@% ESI, EDI%@AE@%, Flags  %@NL@%
  7406.  
  7407.  
  7408.  
  7409.  
  7410.  
  7411.  
  7412. %@CR:C6A00210001 @%%@1@%%@AB@%Chapter 21  VM Interrupt and Call Services%@AE@%%@EH@%%@NL@%
  7413. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7414.  
  7415. The VM Interrupt and Call Services supported by enhanced Windows are
  7416. described in this chapter in the following order:  %@NL@%
  7417.  
  7418.  
  7419.   ■   %@AB@%Build_Int_Stack_Frame%@AE@%%@NL@%
  7420.  
  7421.   ■   %@AB@%Call_When_Idle%@AE@%%@NL@%
  7422.  
  7423.   ■   %@AB@%Call_When_VM_Ints_Enabled%@AE@%%@NL@%
  7424.  
  7425.   ■   %@AB@%Disable_VM_Ints%@AE@%%@NL@%
  7426.  
  7427.   ■   %@AB@%Enable_VM_Ints%@AE@%%@NL@%
  7428.  
  7429.   ■   %@AB@%Get_PM_Int_Type%@AE@%%@NL@%
  7430.  
  7431.   ■   %@AB@%Get_V86_Int_Vector%@AE@%%@NL@%
  7432.  
  7433.   ■   %@AB@%Get_PM_Int_Vector%@AE@%%@NL@%
  7434.  
  7435.   ■   %@AB@%Hook_V86_Int_Chain%@AE@%%@NL@%
  7436.  
  7437.   ■   %@AB@%Set_PM_Int_Type%@AE@%%@NL@%
  7438.  
  7439.   ■   %@AB@%Set_V86_Int_Vector%@AE@%%@NL@%
  7440.  
  7441.   ■   %@AB@%Set_PM_Int_Vector%@AE@%%@NL@%
  7442.  
  7443.   ■   %@AB@%Simulate_Far_Call%@AE@%%@NL@%
  7444.  
  7445.   ■   %@AB@%Simulate_Far_Jmp%@AE@%%@NL@%
  7446.  
  7447.   ■   %@AB@%Simulate_Far_Ret%@AE@%%@NL@%
  7448.  
  7449.   ■   %@AB@%Simulate_Far_Ret_N%@AE@%%@NL@%
  7450.  
  7451.   ■   %@AB@%Simulate_Int%@AE@%%@NL@%
  7452.  
  7453.   ■   %@AB@%Simulate_Iret%@AE@%%@NL@%
  7454.  
  7455.  
  7456. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  7457. "Virtual Device (VxD) Programming Topics," for general discussions on VM
  7458. Interrupts and Call Services.  %@NL@%
  7459.  
  7460. %@CR:C6A00210002 @%%@CR:C6A00210003 @%
  7461. %@2@%%@CR:C6A00210004 @%%@AB@%Build_Int_Stack_Frame%@AE@%%@EH@%%@NL@%
  7462. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7463.  
  7464.  
  7465. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7466.  
  7467. This service will save the current %@AB@%CS:IP%@AE@% and flags on the VM's stack and,
  7468. then, set the %@AB@%CS:IP%@AE@% to the value passed to the routine. The next time the VM
  7469. is entered, the effect will be that an interrupt occurred, directing control
  7470. to the procedure specified.  %@NL@%
  7471.  
  7472. The procedure that is called must do an IRET to return.  %@NL@%
  7473.  
  7474. Sample code:  %@NL@%
  7475.  
  7476. %@AS@%  VMMcall Begin_Nest_Exec
  7477. %@AS@%        mov      cx, [My_Private_VM_Proc_Segment]
  7478. %@AS@%        mov      edx, [My_Private_VM_Proc_Offset]
  7479. %@AS@%        VMMcall  Build_Int_Stack_Frame
  7480. %@AS@%        VMMcall  Resume_exec
  7481. %@AS@%        VMMcall End_Nest_Exec%@AE@%
  7482.  
  7483.  
  7484. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7485.  
  7486. %@AB@%CX%@AE@% = Code segment of procedure to call %@AB@%EDX%@AE@% = Offset of procedure to call
  7487. (high word must be 0 for 16-bit apps)  %@NL@%
  7488.  
  7489.  
  7490. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7491.  
  7492. None  %@NL@%
  7493.  
  7494.  
  7495. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7496.  
  7497. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  7498.  
  7499. %@CR:C6A00210005 @%%@CR:C6A00210006 @%
  7500. %@2@%%@CR:C6A00210007 @%%@AB@%Call_When_Idle%@AE@%%@EH@%%@NL@%
  7501. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7502.  
  7503.  
  7504. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7505.  
  7506. This service is used by devices that want to perform background operations
  7507. with the system is "idle". For example, this service is used by the pageswap
  7508. device to asynchronously write dirty pages to the swap file. Windows is
  7509. considered idle when all VMs have released their time-slice. When the
  7510. Windows kernel signals that Windows is idle and all other VMs are idle, the
  7511. idle callback procedures will be called. Each callback can either consume
  7512. the idle call or pass it on to the next idle callback in the list. Idle
  7513. calls should be consumed if the device performs an operation that takes a
  7514. significant amount of time. For example, if the pageswap device writes a
  7515. dirty page to the swap file then it will consume the idle call to prevent
  7516. sluggish performance.  %@NL@%
  7517.  
  7518.  
  7519. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7520.  
  7521. %@AB@%ESI%@AE@% -> Procedure to call when all VMs idle  %@NL@%
  7522.  
  7523.  
  7524. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7525.  
  7526. If carry clear then  Callback procedure installed else  Error: Could not
  7527. install call-back procedure  %@NL@%
  7528.  
  7529.  
  7530. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7531.  
  7532. Flags  %@NL@%
  7533.  
  7534.  
  7535. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7536.  
  7537. %@AB@%EBX %@AE@%= System VM Handle (current VM is always the system VM) %@AB@%EBP%@AE@% -> Client
  7538. register structure Return with carry SET to pass the call to next handler
  7539. Return with carry CLEAR to consume the callback and indicate Sys VM is not
  7540. idle. Callback procedure can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags.
  7541. %@NL@%
  7542.  
  7543. %@CR:C6A00210008 @%%@CR:C6A00210009 @%
  7544. %@2@%%@CR:C6A00210010 @%%@AB@%Call_When_VM_Ints_Enabled%@AE@%%@EH@%%@NL@%
  7545. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7546.  
  7547.  
  7548. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7549.  
  7550. If a VxD needs to be called when interrupts are enabled, it can use this
  7551. service to be notified when the VM enables interrupts. If the current VM's
  7552. interrupts are already enabled when this service is called, your callback
  7553. procedure will be called immediately.  %@NL@%
  7554.  
  7555. It is usually more convenient to use the %@AB@%Call_Priority_VM_event%@AE@% service
  7556. instead of calling this service directly. However, this service is faster.  %@NL@%
  7557.  
  7558.  
  7559. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7560.  
  7561. %@AB@%EDX%@AE@% = Reference data %@AB@%ESI%@AE@% = Offset of procedure to call  %@NL@%
  7562.  
  7563.  
  7564. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7565.  
  7566. None  %@NL@%
  7567.  
  7568.  
  7569. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7570.  
  7571. %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  7572.  
  7573.  
  7574. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7575.  
  7576. %@AB@%EBX%@AE@% = Handle of current VM %@AB@%EDX%@AE@% = Reference data passed to this service %@AB@%EBP%@AE@%
  7577. -> Client register structure Called procedure may destroy %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  7578. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  7579.  
  7580. %@CR:C6A00210011 @%%@CR:C6A00210012 @%
  7581. %@2@%%@CR:C6A00210013 @%%@AB@%Disable_VM_Ints%@AE@%%@EH@%%@NL@%
  7582. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7583.  
  7584.  
  7585. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7586.  
  7587. This service will disable interrupts during VM execution for the current
  7588. virtual machine. This has the same effect as the VM executing a CLI
  7589. instruction.  %@NL@%
  7590.  
  7591.  
  7592. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7593.  
  7594. None  %@NL@%
  7595.  
  7596.  
  7597. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7598.  
  7599. None  %@NL@%
  7600.  
  7601.  
  7602. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7603.  
  7604. Flags  %@NL@%
  7605.  
  7606. %@CR:C6A00210014 @%%@CR:C6A00210015 @%
  7607. %@2@%%@CR:C6A00210016 @%%@AB@%Enable_VM_Ints%@AE@%%@EH@%%@NL@%
  7608. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7609.  
  7610.  
  7611. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7612.  
  7613. This service will enable interrupts during VM execution for the current
  7614. virtual machine. This has the same effect as the VM executing an STI
  7615. instruction. This service allows events scheduled using the
  7616. %@AB@%Call_When_Ints_Enabled%@AE@% or %@AB@%Call_Proirity_VM_Event%@AE@% services to be serviced.
  7617. Note, however, that they will not be serviced immediately. They will be
  7618. serviced at event time. This means that VxDs calling this service do not
  7619. need to worry about the VM's state changing during this call.  %@NL@%
  7620.  
  7621.  
  7622. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7623.  
  7624. None  %@NL@%
  7625.  
  7626.  
  7627. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7628.  
  7629. None  %@NL@%
  7630.  
  7631.  
  7632. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7633.  
  7634. Flags  %@NL@%
  7635.  
  7636. %@CR:C6A00210017 @%
  7637. %@2@%%@CR:C6A00210018 @%%@AB@%Get_PM_Int_Type%@CR:C6A00210019 @%%@AE@%%@EH@%%@NL@%
  7638. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7639.  
  7640.  
  7641. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7642.  
  7643. This service is used to determine if a PM interrupt vector is an interrupt
  7644. gate or trap gate type interrupt. Interrupt gate interrupts clear the
  7645. interrupt flag bit to disable interrupts when the interrupt occurs. Trap
  7646. gate interrupts don't modify the interrupt bit. All PM interrupts default to
  7647. the trap gate type, but VxD's such as VPICD need to change some of them to
  7648. interrupt gates so that hardware interrupts disable interrupts. Other
  7649. software interrupts such as INT 21h are left as trap gates, so that their
  7650. handlers don't need to execute an STI and thus avoid the extra overhead of
  7651. an unnecessary ring transition.  %@NL@%
  7652.  
  7653.  
  7654. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7655.  
  7656. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  7657.  
  7658.  
  7659. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7660.  
  7661. %@AB@%EDX%@AE@% = 0 if vector is a trap gate (interrupt flag is not changed)  0 if
  7662. vector is an interupt gate (interrupt flag is cleared)  %@NL@%
  7663.  
  7664.  
  7665. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7666.  
  7667. %@AB@%EDX%@AE@%, Flags  %@NL@%
  7668.  
  7669. %@CR:C6A00210020 @%%@CR:C6A00210021 @%%@CR:C6A00210022 @%%@CR:C6A00210023 @%
  7670. %@2@%%@CR:C6A00210024 @%%@AB@%Get_V86_Int_Vector, Get_PM_Int_Vector%@AE@%%@EH@%%@NL@%
  7671. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7672.  
  7673.  
  7674. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7675.  
  7676. These services return the current VM's interrupt vector for the mode
  7677. specified. For V86 mode, this is the DWORD located in the real mode
  7678. interrupt vector. A PM interrupt vector table is maintained by the VMM for
  7679. every virtual machine.  %@NL@%
  7680.  
  7681. Notice that for PM interrupts, a return with ZF set indicates that the
  7682. interrupt has not been hooked. The %@AB@%CS:EIP%@AE@% returned will point to a PM
  7683. callback break point. The break point will invoke code that reflects the
  7684. interrupt to V86 mode. VxDs can chain to this break point just as they would
  7685. any other protected mode address (using Simulate_Far_Jmp or
  7686. Build_Int_Stack_Frame) although it is also acceptable to reflect the
  7687. interrupt to V86 immediately for optimal performance.  %@NL@%
  7688.  
  7689.  
  7690. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7691.  
  7692. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  7693.  
  7694.  
  7695. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7696.  
  7697. %@AB@%CX%@AE@% = %@AB@%CS%@AE@% in vector (high word zero) %@AB@%EDX%@AE@% = %@AB@%EIP%@AE@% in interrupt vector (for V86
  7698. mode and 16-bit protected mode programs the high word will be zero) For PM
  7699. vectors, if interrupt vector points to reflection code (default) then  Zero
  7700. flag is set  else  Zero flag is clear  %@NL@%
  7701.  
  7702.  
  7703. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7704.  
  7705. %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  7706.  
  7707. %@CR:C6A00210025 @%
  7708. %@2@%%@CR:C6A00210026 @%%@AB@%Hook_V86_Int_Chain (Initialization only)%@AE@%%@EH@%%@NL@%
  7709. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7710.  
  7711. %@CR:C6A00210027 @%Description  %@NL@%
  7712.  
  7713. These services are used to monitor software interrupts and simulated
  7714. hardware interrupts in Virtual-8086 mode. More than one VxD is allowed to
  7715. hook an interrupt. The last interrupt hook will be the first one called.
  7716. Every interrupt hook can either service the interrupt or allow the interrupt
  7717. to be reflected to the next handler in the chain. If no interrupt hook
  7718. procedure consumes the interrupt, then it will be reflected to the virtual
  7719. machine.  %@NL@%
  7720.  
  7721. To consume an interrupt, a hook procedure must return with the Carry flag
  7722. clear. If the Carry flag is set when an interrupt hook returns, then the
  7723. interrupt will be passed on to the next handler in the chain or, if the end
  7724. of the chain is reached, reflected to the current virtual machine.  %@NL@%
  7725.  
  7726. If a VxD calls the %@AB@%Simulate_Int%@AE@% service, then all interrupt chain hooks will
  7727. be called before the interrupt is reflected into the virtual machine.
  7728. Simulated hardware interrupts will also be routed through the interrupt
  7729. hooks. Therefore, your code should not assume that the VM has just executed
  7730. a software interrupt instruction.  %@NL@%
  7731.  
  7732. Notice that there is no corresponding service to hook Protected Mode
  7733. interrupts. PM interrupts must be hooked by hooking the interrupt vector.
  7734. This service is faster than hooking the V86 interrupt vector since the VMM
  7735. must intercept every V86 interrupt. This prevents a switch to V86 mode and
  7736. then back to Ring 0 for every V86 interrupt hook.  %@NL@%
  7737.  
  7738.  
  7739. %@3@%%@AB@%Example%@AE@%%@EH@%%@NL@%
  7740.  
  7741. Windows running in enhanced mode supports an API using software interrupt
  7742. 2FH. The code to handle the Release Time-Slice API looks like this:  %@NL@%
  7743.  
  7744. %@AS@%  Win386_Partial_API_initialization:
  7745. %@AS@%   mov      eax, 2fh
  7746. %@AS@%   mov      esi, OFFSET32 Win386_Partial_API_Hook
  7747. %@AS@%   VMMcall  Hook_V86_Int_Chain
  7748. %@AS@%   clc
  7749. %@AS@%   ret
  7750. %@AS@%  
  7751. %@AS@%  Win386_Partial_API_Hook
  7752. %@AS@%   cmp      [epb.Client_AX], 1680h
  7753. %@AS@%   je       SHORT W386_PA_Our_Call
  7754. %@AS@%   stc
  7755. %@AS@%   ret
  7756. %@AS@%  W386_PA_Our_Call:
  7757. %@AS@%   VMMcall  Release_Time_Slice
  7758. %@AS@%   clc
  7759. %@AS@%   ret%@AE@%
  7760.  
  7761. When %@AB@%Win386_Partial_API_Hook%@AE@% is called, it checks for 1680H in the VM's %@AB@%AX%@AE@%
  7762. register. If %@AB@%Client_AX%@AE@% <> 1680H, then it returns with Carry set, and the
  7763. interrupt will be reflected to the next handler in the interrupt chain.
  7764. However, if %@AB@%Client_AX%@AE@% = 1680H, then it releases the current virtual
  7765. machine's time-slice and consumes the interrupt by returning with Carry
  7766. clear.  %@NL@%
  7767.  
  7768.  
  7769. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7770.  
  7771. %@AB@%EAX%@AE@% = Interrupt # %@AB@%ESI%@AE@% Procedure to call  %@NL@%
  7772.  
  7773.  
  7774. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7775.  
  7776. If carry set then   ERROR: Invalid interrupt number else   Interrupt hook
  7777. installed  %@NL@%
  7778.  
  7779.  
  7780. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7781.  
  7782. Flags  %@NL@%
  7783.  
  7784.  
  7785. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7786.  
  7787. %@AB@%EAX%@AE@% = Interrupt # %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  7788.  
  7789. If the callback procedure returns with carry clear then   The interrupt is
  7790. NOT passed to the next interrupt hook else (if carry set)   The interrupt is
  7791. passed to the next interrupt hook  %@NL@%
  7792.  
  7793. %@CR:C6A00210028 @%%@CR:C6A00210029 @%
  7794. %@2@%%@CR:C6A00210030 @%%@AB@%Set_PM_Int_Type%@AE@%%@EH@%%@NL@%
  7795. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7796.  
  7797.  
  7798. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7799.  
  7800. This service is used to specify if a PM interrupt vector should either be an
  7801. interrupt gate or trap gate type interrupt. Interrupt gate interrupts clear
  7802. the interrupt flag bit to disable interrupts when the interrupt occurs. Trap
  7803. gate interrupts don't modify the interrupt bit.  %@NL@%
  7804.  
  7805. All PM interrupts default to the trap gate type, but VxD's such as VPICD
  7806. need to change some of them to interrupt gates so that hardware interrupts
  7807. disable interrupts.  %@NL@%
  7808.  
  7809. Other software interrupts such as INT 21H are left as trap gates, so that
  7810. their handlers don't need to execute an STI and thus avoid the extra
  7811. overhead of an unnecessary ring transition.  %@NL@%
  7812.  
  7813.  
  7814. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7815.  
  7816. %@AB@%EAX%@AE@% = Interrupt number %@AB@%EDX%@AE@% = 0, if vector is a trap gate (interrupt flag is
  7817. not changed)   0, if vector is an interupt gate (interrupt flag is cleared)
  7818. %@NL@%
  7819.  
  7820.  
  7821. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7822.  
  7823. None  %@NL@%
  7824.  
  7825.  
  7826. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7827.  
  7828. Flags  %@NL@%
  7829.  
  7830. %@CR:C6A00210031 @%%@CR:C6A00210032 @%%@CR:C6A00210033 @%%@CR:C6A00210034 @%
  7831. %@2@%%@CR:C6A00210035 @%%@AB@%Set_V86_Int_Vector, Set_PM_Int_Vector%@AE@%%@EH@%%@NL@%
  7832. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7833.  
  7834.  
  7835. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7836.  
  7837. This service sets the current interrupt vector for the mode specified. If a
  7838. VxD calls %@AB@%Set_%@AE@%xxx%@AB@%_Int_Vector%@AE@% before the %@AB@%Sys_VM_Int%@AE@% control call is made,
  7839. then the installed handler will become part of the default interrupt vector
  7840. table. In other words, every VM will be created with interrupt vectors set
  7841. during enhanced Windows initialization. If this service is called after
  7842. %@AB@%Sys_VM_Init%@AE@%, then the handler will only be installed in the current virtual
  7843. machine.  %@NL@%
  7844.  
  7845.  
  7846. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7847.  
  7848. %@AB@%EAX%@AE@% = Interrupt number %@AB@%CX%@AE@% = CS to set into vector %@AB@%EDX%@AE@% = EIP to set interrupt
  7849. vector (for V86 mode and 16-bit protected mode programs the   `1`high word
  7850. should be zero)  %@NL@%
  7851.  
  7852.  
  7853. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7854.  
  7855. None  %@NL@%
  7856.  
  7857.  
  7858. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7859.  
  7860. Flags  %@NL@%
  7861.  
  7862. %@CR:C6A00210036 @%%@CR:C6A00210037 @%
  7863. %@2@%%@CR:C6A00210038 @%%@AB@%Simulate_Far_Call%@AE@%%@EH@%%@NL@%
  7864. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7865.  
  7866.  
  7867. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7868.  
  7869. This service places the current VM's %@AB@%CS:IP%@AE@% on the VM's stack and puts the
  7870. %@AB@%CS:IP%@AE@% specified in %@AB@%CX:EDX%@AE@% in the client frame. The next time the VM is
  7871. executed, it will be as if a FAR call had been inserted in the VM's
  7872. instruction stream.  %@NL@%
  7873.  
  7874. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  7875.  
  7876.  
  7877. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7878.  
  7879. %@AB@%CX%@AE@% = Segment of procedure to call %@AB@%EDX%@AE@% = Offset of procedure to call (high
  7880. word 0 if 16-bit application)  %@NL@%
  7881.  
  7882.  
  7883. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7884.  
  7885. %@AB@%Old Client_CS%@AE@%:(%@AB@%E%@AE@%)%@AB@%IP%@AE@% on stack. Specified %@AB@%CS%@AE@%:%@AB@%EIP%@AE@% is current %@AB@%CS%@AE@%:%@AB@%EIP%@AE@%.  %@NL@%
  7886.  
  7887.  
  7888. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7889.  
  7890. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_SP%@AE@%, Flags ;  %@NL@%
  7891.  
  7892. %@CR:C6A00210039 @%%@CR:C6A00210040 @%
  7893. %@2@%%@CR:C6A00210041 @%%@AB@%Simulate_Far_Jmp%@AE@%%@EH@%%@NL@%
  7894. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7895.  
  7896.  
  7897. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7898.  
  7899. This service places the specified %@AB@%CS:IP%@AE@% into the VM's %@AB@%CS:IP%@AE@% to simulate a
  7900. FAR jmp instruction.  %@NL@%
  7901.  
  7902.  
  7903. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7904.  
  7905. %@AB@%CX%@AE@% = %@AB@%CS%@AE@% to jump to%@AB@% EDX%@AE@% = %@AB@%EIP%@AE@% to jump to (High word should be zero for 16-bit
  7906. or V86 apps)  %@NL@%
  7907.  
  7908.  
  7909. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7910.  
  7911. None  %@NL@%
  7912.  
  7913.  
  7914. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7915.  
  7916. %@AB@%Client_EIP%@AE@%, %@AB@%Client_CS%@AE@%, Flags  %@NL@%
  7917.  
  7918. %@CR:C6A00210042 @%%@CR:C6A00210043 @%
  7919. %@2@%%@CR:C6A00210044 @%%@AB@%Simulate_Far_Ret%@AE@%%@EH@%%@NL@%
  7920. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7921.  
  7922.  
  7923. %@3@%%@AB@%Decsription%@AE@%%@EH@%%@NL@%
  7924.  
  7925. This procedure pops the top two WORDs orDWORDs on the current VM's stack
  7926. into the client's %@AB@%CS:(E)IP%@AE@%.  %@NL@%
  7927.  
  7928. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  7929.  
  7930.  
  7931. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7932.  
  7933. None  %@NL@%
  7934.  
  7935.  
  7936. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7937.  
  7938. None  %@NL@%
  7939.  
  7940.  
  7941. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7942.  
  7943. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  7944.  
  7945. %@CR:C6A00210045 @%%@CR:C6A00210046 @%
  7946. %@2@%%@CR:C6A00210047 @%%@AB@%Simulate_Far_Ret_N%@AE@%%@EH@%%@NL@%
  7947. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7948.  
  7949.  
  7950. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7951.  
  7952. This procedure pops the top two WORDs or DWORDs on the current VM's stack
  7953. into the client's %@AB@%CS:(E)IP%@AE@%, then subtracts %@AB@%EAX%@AE@% from the VM's stack pointer.
  7954. %@NL@%
  7955.  
  7956. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  7957.  
  7958.  
  7959. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7960.  
  7961. %@AB@%EAX%@AE@% = Number of bytes to pop after far ret  %@NL@%
  7962.  
  7963.  
  7964. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7965.  
  7966. None  %@NL@%
  7967.  
  7968.  
  7969. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7970.  
  7971. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  7972.  
  7973. %@CR:C6A00210048 @%
  7974. %@2@%%@CR:C6A00210049 @%%@AB@%Simulate_Int%@CR:C6A00210050 @%%@AE@%%@EH@%%@NL@%
  7975. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7976.  
  7977.  
  7978. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7979.  
  7980. This service is used mainly by the Virtual Programmable Interrupt Controller
  7981. Device (VPICD) to simulate hardware interrupts. Most VxD writers will want
  7982. to use the %@AB@%Exec_Int%@AE@% service to simulate interrupts.  %@NL@%
  7983.  
  7984. This service has exactly the same effect as a VM executing an %@AB@%Int nn%@AE@%
  7985. instruction. All VxD interrupt chain hooks are called and, if the interrupt
  7986. is not consumed by one of these hooks, an IRET frame is built on the VM's
  7987. stack. Notice, however, that the VM interrupt code will not be executed
  7988. until the enhanced Windows environment returns to the virtual machine. If
  7989. you want to %@AI@%execute%@AE@% an interrupt, then you should use the nested execution
  7990. services (%@AB@%Exec_Int%@AE@%).  %@NL@%
  7991.  
  7992. This service is mode sensitive. Therefore, if the VM is currently in V86
  7993. mode, then a V86 interrupt will be simulated. Otherwise, a PM interrupt will
  7994. be simulated. Since reflecting a PM interrupt may force a mode change to V86
  7995. mode, VxD writers must be very careful when calling this service while
  7996. running a protected-mode application.  %@NL@%
  7997.  
  7998.  
  7999. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8000.  
  8001. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  8002.  
  8003.  
  8004. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8005.  
  8006. If %@AB@%Simulate_Int%@AE@% is called while running a PM application and the PM
  8007. interrupt vector is not hooked, then the mode is changed to V86.  %@NL@%
  8008.  
  8009.  
  8010. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8011.  
  8012. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  8013.  
  8014. %@CR:C6A00210051 @%%@CR:C6A00210052 @%
  8015. %@2@%%@CR:C6A00210053 @%%@AB@%Simulate_Iret%@AE@%%@EH@%%@NL@%
  8016. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8017.  
  8018.  
  8019. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8020.  
  8021. This service pops the values at the top of the current VM's stack into the
  8022. current VM's %@AB@%CS:IP%@AE@% and flags. If the current VM is a 32-bit protected-mode
  8023. application, then this service will pop three DWORDs instead of WORDs
  8024. (simulate an IRETD).  %@NL@%
  8025.  
  8026. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  8027.  
  8028.  
  8029. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8030.  
  8031. None  %@NL@%
  8032.  
  8033.  
  8034. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8035.  
  8036. None  %@NL@%
  8037.  
  8038.  
  8039. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8040.  
  8041. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  8042.  
  8043.  
  8044.  
  8045.  
  8046.  
  8047.  
  8048. %@CR:C6A00220001 @%%@1@%%@AB@%Chapter 22  Nested Execution Services%@AE@%%@EH@%%@NL@%
  8049. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8050.  
  8051. These services provide a way for VxDs to call routines in a VM. Notice that
  8052. the VxD must make sure that the service being called is in a callable state
  8053. (i.e., you must not reenter services that do not expect to be reentered).
  8054. The services are described here in alphabetical order.  %@NL@%
  8055.  
  8056.  
  8057.   ■   %@AB@%Begin_Nest_Exec%@AE@%%@NL@%
  8058.  
  8059.   ■   %@AB@%Begin_Nest_V86_Exec%@AE@%%@NL@%
  8060.  
  8061.   ■   %@AB@%Begin_Use_Locked_PM_Stack%@AE@%%@NL@%
  8062.  
  8063.   ■   %@AB@%End_Nest_Exec%@AE@%%@NL@%
  8064.  
  8065.   ■   %@AB@%End_Use_Locked_PM_Stack%@AE@%%@NL@%
  8066.  
  8067.   ■   %@AB@%Exec_Stack%@AE@%%@NL@%
  8068.  
  8069.   ■   %@AB@%Exec_VxD_Int%@AE@%%@NL@%
  8070.  
  8071.   ■   %@AB@%Restore_Client_State%@AE@%%@NL@%
  8072.  
  8073.   ■   %@AB@%Resume_Exec%@AE@%%@NL@%
  8074.  
  8075.   ■   %@AB@%Save_Client_State%@AE@%%@NL@%
  8076.  
  8077.   ■   %@AB@%Set_PM_Exec_Mode%@AE@%%@NL@%
  8078.  
  8079.   ■   %@AB@%Set_V86_Exec_Mode%@AE@%%@NL@%
  8080.  
  8081.  
  8082. %@CR:C6A00220002 @%%@CR:C6A00220003 @%
  8083. %@2@%%@CR:C6A00220004 @%%@AB@%Begin_Nest_Exec%@AE@%%@EH@%%@NL@%
  8084. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8085.  
  8086.  
  8087. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8088.  
  8089. This service is used by VxDs that need to call software in a VM.  %@NL@%
  8090.  
  8091. For example:  %@NL@%
  8092.  
  8093. %@AS@%  VMMcall Begin_Nest_Exec   ; Start nested execution
  8094. %@AS@%   mov     [ebp.Client_AH], 30h  ; 30h = Get MS-DOS Version #
  8095. %@AS@%   mov     eax, 21h    ; Execute an Int 21h in the
  8096. %@AS@%   VMMcall Exec_Int    ; current VM to call MS-DOS
  8097. %@AS@%   VMMcall End_Nest_Exec   ; End of nested exec calls%@AE@%
  8098.  
  8099. This will make the MS-DOS %@AB@%Get_Version%@AE@% call. The version will be in the
  8100. %@AB@%Client_AH%@AE@% and %@AB@%Client_AL%@AE@% registers.  %@NL@%
  8101.  
  8102. This service only works for the current VM. The VM registers changed by the
  8103. call Will be changes in the VM. If you want to save and restore a VM's
  8104. registers you should use the %@AB@%Save_Client_ State%@AE@% and %@AB@%Restore_Client_State%@AE@%
  8105. services or the %@AB@%Push_Client_State%@AE@% and %@AB@%Pop_Client_State%@AE@% macros documneted
  8106. under %@AB@%Save_Client_State%@AE@% and %@AB@%Restore_Client_State%@AE@%.  %@NL@%
  8107.  
  8108. You may execute any number of interrupts between a %@AB@%Begin/End_Nest_Exec%@AE@% pair.
  8109. For example the following is valid:  %@NL@%
  8110.  
  8111. %@AS@%  Push_Client_State
  8112. %@AS@%      VMMcall Begin_Nest_Exec
  8113. %@AS@%      ...
  8114. %@AS@%      VMMcall Exec_Int
  8115. %@AS@%      ...
  8116. %@AS@%      VMMcall Exec_Int
  8117. %@AS@%      ...
  8118. %@AS@%      VMMcall Simulate_Far_Call
  8119. %@AS@%      VMMcall Resume_Exec
  8120. %@AS@%      ...
  8121. %@AS@%      VMMcall Exec_Int
  8122. %@AS@%      VMMcall End_Nest_Exec
  8123. %@AS@%      Pop_Client_State%@AE@%
  8124.  
  8125. This service will force the VM into protected-mode execution if there is a
  8126. protected-mode application running in the current VM. If there is no
  8127. protected mode application, then the VM will remain in V86 mode. When
  8128. %@AB@%End_Nest_Exec%@AE@% is called, the VM will be returned to whatever mode it was in
  8129. when %@AB@%Begin_Nest_Exec %@AE@%was called. For more information on what is entailed in
  8130. a mode switch refer to the documentation for %@AB@%Set_PM_Exec_Mode%@AE@% and
  8131. %@AB@%Set_V86_Exec_Mode%@AE@% later in this chapter.  %@NL@%
  8132.  
  8133. If there is a protected-mode application in the current VM, then this
  8134. service will automatically switch the VM to the locked PM stack (and
  8135. %@AB@%End_Nest_Exec%@AE@% will switch it back). This allows most devices to change
  8136. execution modes without worrying about demand paging issues.  %@NL@%
  8137.  
  8138.  
  8139. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8140.  
  8141. None  %@NL@%
  8142.  
  8143.  
  8144. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8145.  
  8146. %@AB@%Client_CS:IP%@AE@% contains a break point (used by nested exec services).  %@NL@%
  8147.  
  8148. If a protected mode application is running then  VM execution mode is
  8149. protected mode else  VM execution mode is Virtual-8086 mode %@AB@%Exec_Int%@AE@% and
  8150. %@AB@%Resume_Exec%@AE@% services may be called.  %@NL@%
  8151.  
  8152.  
  8153. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8154.  
  8155. %@AB@%Client_CS%@AE@%, %@AB@%Client_IP%@AE@%, Flags  %@NL@%
  8156.  
  8157. %@CR:C6A00220005 @%%@CR:C6A00220006 @%
  8158. %@2@%%@CR:C6A00220007 @%%@AB@%Begin_Nest_V86_Exec%@AE@%%@EH@%%@NL@%
  8159. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8160.  
  8161.  
  8162. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8163.  
  8164. This service will set the the current VM in Virtual-8086 mode and prepare
  8165. the VM for nested execution. This service is normally used by VxDs that want
  8166. to convert protected mode calls into V86 calls. For example, the DOSMGR
  8167. device uses this call to map INT 21H MS-DOS calls issued from protected mode
  8168. programs into Virtual-8086 mode MS-DOS calls.  %@NL@%
  8169.  
  8170. This call, like %@AB@%Begin_Nest_Exec%@AE@%, saves the current execution mode of the
  8171. virtual machine (either V86 or PM), and %@AB@%End_Nest_Exec%@AE@% will restore the mode.
  8172. %@NL@%
  8173.  
  8174.  
  8175. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8176.  
  8177. None  %@NL@%
  8178.  
  8179.  
  8180. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8181.  
  8182. %@AB@%Client_CS:IP%@AE@% contains a break point (used by nested exec services) VM is in
  8183. Virtual 8086 mode. %@AB@%Exec_Int%@AE@% and %@AB@%Resume_Exec %@AE@%services may be called.  %@NL@%
  8184.  
  8185.  
  8186. %@3@%%@AB@%USES%@AE@%%@EH@%%@NL@%
  8187.  
  8188. %@AB@%Client_CS%@AE@%, %@AB@%Client_IP%@AE@%, Flags  %@NL@%
  8189.  
  8190. %@CR:C6A00220008 @%%@CR:C6A00220009 @%
  8191. %@2@%%@CR:C6A00220010 @%%@AB@%Begin_Use_Locked_PM_Stack%@AE@%%@EH@%%@NL@%
  8192. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8193.  
  8194.  
  8195. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8196.  
  8197. This service is used by VxDs that need to ensure that a protectedmode
  8198. program is running on a stack that will not be demand paged. Most devices
  8199. can rely on %@AB@%Begin_Nest_Exec%@AE@% to switch stacks automatically, and so this
  8200. service is only important for devices, such as the Virtual Programmable
  8201. Interrupt Controller Device (VPICD), which explicitly changes the execution
  8202. mode of a VM.  %@NL@%
  8203.  
  8204. A call to this service must be followed by a call to
  8205. %@AB@%End_Use_Locked_PM_Stack%@AE@%. Note that this service may be called repeatedly,
  8206. but only the first call will switch stacks. Subsequent calls will increment
  8207. a counter but remain on the current locked stack.  %@NL@%
  8208.  
  8209.  
  8210. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8211.  
  8212. Current execution mode of VM must be protected mode (%@AB@%VMStat_PM_Exec%@AE@% status
  8213. bit must be set).  %@NL@%
  8214.  
  8215.  
  8216. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8217.  
  8218. If locked stack not already in use then  Client's SS:SP will be changed to
  8219. locked protected mode stack else  Client's SS:SP will be unchanged  %@NL@%
  8220.  
  8221.  
  8222. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8223.  
  8224. Flags  %@NL@%
  8225.  
  8226. %@CR:C6A00220011 @%
  8227. %@2@%%@CR:C6A00220012 @%%@AB@%End_Nest_Exec%@CR:C6A00220013 @%%@AE@%%@EH@%%@NL@%
  8228. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8229.  
  8230.  
  8231. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8232.  
  8233. This service must be called after a call to %@AB@%Begin_Nest_Exec%@AE@%. A VxD must
  8234. never return to the VMM while still in nested execution. If %@AB@%Begin_Nest_Exec%@AE@%
  8235. changed the execution mode of the VM then this service will restore it to
  8236. the previous mode. Notice that this service %@AI@%will%@AE@% %@AI@%not%@AE@% restore the client's
  8237. registers (except %@AB@%CS:IP%@AE@%) to the values they were when %@AB@%Begin_Nest_Exec %@AE@%was
  8238. called. If you need to preserve the VM's registers, you must use the
  8239. %@AB@%Push_Client_State%@AE@% and %@AB@%Pop_Client_State%@AE@% macros.  %@NL@%
  8240.  
  8241.  
  8242. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8243.  
  8244. None  %@NL@%
  8245.  
  8246.  
  8247. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8248.  
  8249. VM execution mode restored to previous execution mode (before
  8250. %@AB@%Begin_Nest_Exec%@AE@% was called) Client's original %@AB@%CS:IP%@AE@% restored  %@NL@%
  8251.  
  8252.  
  8253. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8254.  
  8255. %@AB@%Client_CS%@AE@%, %@AB@%Client_IP%@AE@%, Flags  %@NL@%
  8256.  
  8257. %@CR:C6A00220014 @%%@CR:C6A00220015 @%
  8258. %@2@%%@CR:C6A00220016 @%%@AB@%End_Use_Locked_PM_Stack%@AE@%%@EH@%%@NL@%
  8259. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8260.  
  8261.  
  8262. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8263.  
  8264. This service must be called once for every call made to
  8265. %@AB@%Begin_Use_Locked_PM_Stack.%@AE@% It will decrement the locked stack use counter
  8266. and, if it is decremented to zero then it will switch the VM back to its
  8267. original %@AB@%SS:SP%@AE@%.  %@NL@%
  8268.  
  8269.  
  8270. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8271.  
  8272. None  %@NL@%
  8273.  
  8274.  
  8275. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8276.  
  8277. If locked stack count decremented to 0 then  Client's SS:SP will be restored
  8278. to original values before  %@AB@%Begin_Use_Locked_PM_Stack%@AE@% was called. else
  8279. Client's SS:SP will be unchanged  %@NL@%
  8280.  
  8281.  
  8282. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8283.  
  8284. Flags  %@NL@%
  8285.  
  8286. %@CR:C6A00220017 @%
  8287. %@2@%%@CR:C6A00220018 @%%@AB@%Exec_Int%@CR:C6A00220019 @%%@AE@%%@EH@%%@NL@%
  8288. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8289.  
  8290.  
  8291. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8292.  
  8293. You must call %@AB@%Begin_Nest_Exec%@AE@% or %@AB@%Begin_Nest_V86_Exec%@AE@% before calling this
  8294. service. It may be called any number of times between a %@AB@%Begin_Nest_Exec%@AE@% and
  8295. %@AB@%End_Nest_Exec%@AE@% pair.  %@NL@%
  8296.  
  8297. This service simulates an interrupt and then resumes VM execution. It has
  8298. exactly the same effect as calling:  %@NL@%
  8299.  
  8300. %@AS@%  mov     eax, (Int #)
  8301. %@AS@%      VMMcall Simulate_Int
  8302. %@AS@%      VMMcall Resume_Exec%@AE@%
  8303.  
  8304. Since most nested execution calls simulate interrupts, this service is
  8305. provided for convenience. See %@AB@%Resume_Exec%@AE@% later in this chapter for more
  8306. details on how this service is used.  %@NL@%
  8307.  
  8308.  
  8309. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8310.  
  8311. %@AB@%EAX%@AE@% = # of interrupt to execute  %@NL@%
  8312.  
  8313.  
  8314. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8315.  
  8316. Interrupt has been executed  %@NL@%
  8317.  
  8318.  
  8319. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8320.  
  8321. Flags  %@NL@%
  8322.  
  8323. %@CR:C6A00220020 @%
  8324. %@2@%%@CR:C6A00220021 @%%@AB@%Exec_VxD_Int%@CR:C6A00220022 @%%@AE@%%@EH@%%@NL@%
  8325. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8326.  
  8327.  
  8328. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8329.  
  8330. This service is used by virtual devices to call MS-DOS or BIOS services as
  8331. though they were an application program. For example, the following code
  8332. gets the current MS-DOS version:  %@NL@%
  8333.  
  8334. %@AS@%  mov     ax, 3000h
  8335. %@AS@%      push    DWORD PTR 21h
  8336. %@AS@%      VMMcall Exec_VxD_Int
  8337. %@AS@%      (AL = Major MS-DOS version, AL = Minor MS-DOS version)%@AE@%
  8338.  
  8339. All MS-DOS and BIOS calls that are supported in protected-mode programs will
  8340. be supported by this service. The VM's registers and flags will not be
  8341. changed by this service so there is no need for the caller to save and
  8342. restore the client register structure. The interrupt number on the stack
  8343. will be removed by this service so the caller should %@AI@%not%@AE@% add four to %@AB@%ESP%@AE@%
  8344. after calling this service.  %@NL@%
  8345.  
  8346. To make calling this service easier, a macro called %@AB@%VxDint%@AE@% is defined in
  8347. VMM.INC as follows:  %@NL@%
  8348.  
  8349. %@AS@%  VxDint  MACRO   Int_Number
  8350. %@AS@%        push    Int_Number
  8351. %@AS@%        VMMcall Exec_VxD_Int
  8352. %@AS@%        ENDM %@AE@%
  8353.  
  8354. This service makes it possible to write code in a VxD that is very similar
  8355. to real mode code. For example, below is the code that opens a file named
  8356. "FOO.TXT" and reads the first 100 bytes:  %@NL@%
  8357.  
  8358. %@AS@%  VxD_DATA_SEG
  8359. %@AS@%   Foo_File_Name   db "FOO.TXT", 0
  8360. %@AS@%   Read_Buffer     db 100 dup (?)
  8361. %@AS@%  VxD_DATA_ENDS%@AE@%
  8362.  
  8363. %@AS@%  VxD_CODE_SEG
  8364. %@AS@%   BeginProc Sample_File_Read
  8365. %@AS@%     mov     ax, 3D00h   ; Open file with handle
  8366. %@AS@%     mov     edx, OFFSET32 Foo_File_Name  ; DS:EDX - File name
  8367. %@AS@%      VxDint  21h     ; Call MS-DOS
  8368. %@AS@%     jc      Error   ; If carry then error
  8369. %@AS@%          ; else AX = File handle
  8370. %@AS@%      mov     bx, ax    ; BX = File handle
  8371. %@AS@%     mov     ecx, 100    ; Read 100 bytes
  8372. %@AS@%     mov     edx, OFFSET32 Read_Buffer ; Into this buffer
  8373. %@AS@%      mov     ah, 3Fh    ; MS-DOS Read
  8374. %@AS@%     VxDint  21h     ; Call MS-DOS
  8375. %@AS@%      jc      Error   ; Error if carry else
  8376. %@AS@%          ; EAX = # bytes read
  8377. %@AS@%     (Do stuff with the data here)%@AE@%
  8378.  
  8379. %@AS@%  EndProc Sample_File_Read
  8380. %@AS@%  VxD_CODE_ENDS%@AE@%
  8381.  
  8382.  
  8383. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  8384.  
  8385. Interrupts will only be routed through VxD interrupt hooks. They will bypass
  8386. any hook the application has installed in protected mode. This may be a
  8387. problem, for example, if an application hooks INT 21h to watch for a file
  8388. open and, then, a VxD uses this service to open a file (the application
  8389. would not see the file open). Do not use this service until the
  8390. %@AB@%Init_Complete%@AE@% control call is made.  %@NL@%
  8391.  
  8392. Do not change %@AB@%DS%@AE@% or %@AB@%ES%@AE@% before calling this service. You should always use
  8393. the ring 0 linear address of the data instead of changing the selector
  8394. value. This may require using the %@AB@%_SelectorMapFlat%@AE@% service to determine the
  8395. base of a selector.  %@NL@%
  8396.  
  8397. Do not call services that will change %@AB@%DS%@AE@% or %@AB@%ES%@AE@%. Mappers should return valid
  8398. pointers without changing the segment register value, but calls that
  8399. explicitly change the %@AB@%DS%@AE@% or %@AB@%ES%@AE@% selectors should never be called. For
  8400. example, if a call returns a pointer in %@AB@%DS:(E)DX%@AE@% then this would be OK to
  8401. call since the mapper would convert the ponter to use the ring 0 linear
  8402. address in %@AB@%EDX%@AE@% without modifying %@AB@%DS%@AE@%. However, if a service returns a
  8403. selector only then you should not use %@AB@%Exec_VxD_Int %@AE@%to call it. This can
  8404. normally be made to work by using code similar to the following:  %@NL@%
  8405.  
  8406. %@AS@%  Push_Client_State
  8407. %@AS@%    VMMcall Begin_Nest_(V86_)Exec
  8408. %@AS@%    . . .
  8409. %@AS@%    (Fiddle with client registers)
  8410. %@AS@%    . . .
  8411. %@AS@%    VMMcall Exec_Int
  8412. %@AS@%    . . .
  8413. %@AS@%    (Get segments/selectors)
  8414. %@AS@%    . . .
  8415. %@AS@%    VMMcall End_Nest_Exec
  8416. %@AS@%    Pop_Client_State%@AE@%
  8417.  
  8418.  
  8419. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8420.  
  8421. DWORD at [ESP+4] is number of interrupt to execute  %@NL@%
  8422.  
  8423.  
  8424. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8425.  
  8426. All registers and flags modified by interrupt will be changed. The interrupt
  8427. number on the stack will have been removed.  %@NL@%
  8428.  
  8429.  
  8430. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8431.  
  8432. All registers and flags modified by interrupt will be changed.  %@NL@%
  8433.  
  8434. %@CR:C6A00220023 @%%@CR:C6A00220024 @%
  8435. %@2@%%@CR:C6A00220025 @%%@AB@%Restore_Client_State%@AE@%%@EH@%%@NL@%
  8436. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8437.  
  8438.  
  8439. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8440.  
  8441. This service restores a VM execution state that was saved using the
  8442. %@AB@%Save_Client_State%@AE@% service. If the client state was saved using the
  8443. %@AB@%Push_Client_State%@AE@% macro then you should use %@AB@%Pop_Client_State%@AE@% to restore the
  8444. VM's execution state. The %@AB@%Pop_Client_State%@AE@% macro looks like:  %@NL@%
  8445.  
  8446. %@AS@%  Pop_Client_State MACRO
  8447. %@AS@%       push    esi
  8448. %@AS@%       lea     esi, [esp+4]
  8449. %@AS@%       VMMcall Restore_Client_State
  8450. %@AS@%       pop     esi
  8451. %@AS@%       add     esp, SIZE Client_Reg_Struc
  8452. %@AS@%      ENDM%@AE@%
  8453.  
  8454. Notice that this service can have side effects if it is not used carefully.
  8455. For instance, it will change modes from V86 to protected mode or from
  8456. protected to V86 mode if the state being restored is in a different
  8457. execution mode from the current one. Also, it may change the state of the
  8458. current virtual machine's interrupt flag and so it may cause callbacks to
  8459. events scheduled through the %@AB@%Call_When_VM_Ints_Enabled%@AE@% or
  8460. %@AB@%Call_Priority_VM_Event%@AE@% services.  %@NL@%
  8461.  
  8462.  
  8463. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8464.  
  8465. %@AB@%ESI %@AE@%-> Buffer  %@NL@%
  8466.  
  8467.  
  8468. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8469.  
  8470. VM execution state is restored  %@NL@%
  8471.  
  8472.  
  8473. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8474.  
  8475. Flags  %@NL@%
  8476.  
  8477. %@CR:C6A00220026 @%
  8478. %@2@%%@CR:C6A00220027 @%%@AB@%Resume_Exec%@CR:C6A00220028 @%%@AE@%%@EH@%%@NL@%
  8479. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8480.  
  8481.  
  8482. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8483.  
  8484. You must call %@AB@%Begin_Nest_Exec%@AE@% or %@AB@%Begin_Nest_V86_Exec%@AE@% before calling this
  8485. service. It may be called any number of times between a %@AB@%Begin_Nest_Exec%@AE@% and
  8486. %@AB@%End_Nest_Exec%@AE@% pair.  %@NL@%
  8487.  
  8488. This service immediately executes the current VM. When the VM returns to the
  8489. same point it was at when %@AB@%Begin_ Nest_Exec%@AE@% was called, this service will
  8490. return. The following example:  %@NL@%
  8491.  
  8492. %@AS@%  Push_Client_State
  8493. %@AS@%   VMMcall  Begin_Nest_Exec
  8494. %@AS@%   mov  cx, [Target_CS]
  8495. %@AS@%   mov  eax, [Target_CS_EIP]
  8496. %@AS@%   VMMcall  Simulate_Far_Call
  8497. %@AS@%   VMMcall Resume_Exec
  8498. %@AS@%    (Examine results returnd in Client registers) 
  8499. %@AS@%   VMMcall End_Nest_Exec
  8500. %@AS@%  Pop_Client_State%@AE@%
  8501.  
  8502. will return when the called procedure returns.The following code will
  8503. process any outstanding events and immediately return:  %@NL@%
  8504.  
  8505. %@AS@%  VMMcall Begin_Nest_Exec
  8506. %@AS@%   VMMcall Resume_Exec
  8507. %@AS@%   VMMcall End_Nest_Exec%@AE@%
  8508.  
  8509. Since the %@AB@%Resume_Exec%@AE@% resumes execution at the same point that
  8510. %@AB@%Begin_Nest_Exec%@AE@% was called it will return immediately.  %@NL@%
  8511.  
  8512. This service is also useful for VxDs that must wait for an external event
  8513. (such as a hardware interrupt) to occur before returning to the VM. Since
  8514. %@AB@%Resume_Exec%@AE@% allows outstanding events to be processed, simulated harware
  8515. interrupts can be sent to the VM while waiting:  %@NL@%
  8516.  
  8517. %@AS@%  (Push_Client_State is not needed)
  8518. %@AS@%   VMMcall Begin_Nest_Exec
  8519. %@AS@%   Wait_Loop:
  8520. %@AS@%   test  [My_Status], Done
  8521. %@AS@%   je  Exit_My_Wait_Loop
  8522. %@AS@%   VMMcall Resume_Exec
  8523. %@AS@%   VMMcall Release_Time_Slice
  8524. %@AS@%   jmp  My_Wait_Loop 
  8525. %@AS@%   Exit_Wait_Loop:
  8526. %@AS@%   VMMcall  End_Nest_Exec
  8527. %@AS@%   (Pop_Client_State is not needed)%@AE@%
  8528.  
  8529. Notice that you do not need to save and restore the client registers in this
  8530. loop since simulated hardware interrupts and events will not modify the
  8531. client registers. You should only use the %@AB@%Push/ Pop_Client_State%@AE@% macros when
  8532. your VxD code explicitly calls code in a VM or directly modifies any client
  8533. register.  %@NL@%
  8534.  
  8535. This service and %@AB@%Exec_Int%@AE@% may be called multiple times in between calls to
  8536. Begin/End nest exec. For example the following code is valid:  %@NL@%
  8537.  
  8538. %@AS@%  Push_Client_State
  8539. %@AS@%    VMMcall Begin_Nest_Exec
  8540. %@AS@%    mov eax, (Int #)
  8541. %@AS@%    VMMcall Exec_Int
  8542. %@AS@%    mov cx, [Target_CS]
  8543. %@AS@%    mov eax, [Target_CS_EIP]
  8544. %@AS@%    VMMcall Simulate_Far_Call
  8545. %@AS@%    VMMcall Resume_Exec
  8546. %@AS@%    VMMcall End_Nest_Exec
  8547. %@AS@%    Pop_Client_State%@AE@%
  8548.  
  8549. Since events are processed when %@AB@%Resume_Exec%@AE@% (or %@AB@%Exec_Int%@AE@%) is called, a task
  8550. switch may occur.  %@NL@%
  8551.  
  8552.  
  8553. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8554.  
  8555. None  %@NL@%
  8556.  
  8557.  
  8558. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8559.  
  8560. None  %@NL@%
  8561.  
  8562.  
  8563. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8564.  
  8565. Flags  %@NL@%
  8566.  
  8567. %@CR:C6A00220029 @%%@CR:C6A00220030 @%
  8568. %@2@%%@CR:C6A00220031 @%%@AB@%Save_Client_State%@AE@%%@EH@%%@NL@%
  8569. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8570.  
  8571.  
  8572. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8573.  
  8574. This service will copy the contents of the current VM's Client Register
  8575. Structure to the specified buffer. The buffer must be the size of the
  8576. structure named %@AB@%Client_Reg_Struc%@AE@% which is defined in VMM.INC. The saved
  8577. state can later be restored by calling %@AB@%Restore_Client_State.%@AE@%  %@NL@%
  8578.  
  8579. Most of the time, it is easier to use the %@AB@%Push_Client_State %@AE@%macro than to
  8580. call this service directly. %@AB@%Push_Client_State%@AE@% copies the client's state onto
  8581. the protected mode stack. The macro code is as follows:  %@NL@%
  8582.  
  8583. %@AS@%  Push_Client_State MACRO
  8584. %@AS@%    sub     esp, SIZE Client_Reg_Struc
  8585. %@AS@%    push    edi
  8586. %@AS@%    lea     edi, [esp+4]
  8587. %@AS@%    VMMcall Save_Client_State
  8588. %@AS@%    pop     edi
  8589. %@AS@%    ENDM%@AE@%
  8590.  
  8591. As you can see, this macro will reserve space on the caller's stack for the
  8592. buffer. You must use the %@AB@%Pop_Client_State%@AE@% macro to get rid of the contents
  8593. saved on your stack. The macro will not change any registers.  %@NL@%
  8594.  
  8595. This service is typically used by VxDs that need to make calls to code in a
  8596. virtual machine that are unrelated to the current VM's thread of execution.
  8597. For example, the demand paging device (PageSwap) does the following:  %@NL@%
  8598.  
  8599. %@AS@%  Push_Client_State
  8600. %@AS@%      VMMcall Begin_Nest_Exec
  8601. %@AS@%      . . .
  8602. %@AS@%      (Perform disk I/O)
  8603. %@AS@%      . . .
  8604. %@AS@%      VMMcall End_Nest_Exec
  8605. %@AS@%      Pop_Client_State%@AE@%
  8606.  
  8607. Notice that the %@AB@%Push_Client_State%@AE@% macro is placed %@AI@%before%@AE@% the call to
  8608. %@AB@%Begin_Nest_Exec%@AE@% and the %@AB@%Pop_Client_State%@AE@% macro is %@AI@%after%@AE@% the call to
  8609. %@AB@%End_Nest_Exec%@AE@%. Any other combination would probably crash enhanced Windows.
  8610. %@NL@%
  8611.  
  8612. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8613. %@AU@%WARNING%@AE@%
  8614.  
  8615. Always use this service to save the client state. Don't just copy the VM's
  8616. client register structure and later copy it back as this will almost
  8617. certianly cause enhanced Windows to hang or crash. 
  8618. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8619.  
  8620.  
  8621. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8622.  
  8623. %@AB@%EDI%@AE@% -> Buffer  %@NL@%
  8624.  
  8625.  
  8626. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8627.  
  8628. Buffer contains a copy of the current VM's client register structure  %@NL@%
  8629.  
  8630.  
  8631. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8632.  
  8633. Flags  %@NL@%
  8634.  
  8635. %@CR:C6A00220032 @%%@CR:C6A00220033 @%
  8636. %@2@%%@CR:C6A00220034 @%%@AB@%Set_PM_Exec_Mode%@AE@%%@EH@%%@NL@%
  8637. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8638.  
  8639.  
  8640. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8641.  
  8642. This service forces the current VM into protected mode. Most devices will
  8643. want to use %@AB@%Begin_Nest_Exec%@AE@% instead of this service.  %@NL@%
  8644.  
  8645. Changing the execution mode of a VM will not change the VM's %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  8646. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and %@AB@%EBP%@AE@% registers or %@AI@%most%@AE@% flags. The VM flag and IOPL flags
  8647. will change. %@AB@%DS%@AE@%, %@AB@%ES%@AE@%, %@AB@%FS%@AE@%, %@AB@%GS%@AE@%, %@AB@%SS%@AE@%, %@AB@%ESP%@AE@%, %@AB@%CS%@AE@%, and %@AB@%EIP%@AE@% will be restored to the
  8648. previous values for protected mode.  %@NL@%
  8649.  
  8650. If the current VM is already in protected mode, then this service has no
  8651. effect.  %@NL@%
  8652.  
  8653.  
  8654. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8655.  
  8656. None  %@NL@%
  8657.  
  8658.  
  8659. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8660.  
  8661. VM is in PM execution mode  %@NL@%
  8662.  
  8663.  
  8664. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8665.  
  8666. Flags  %@NL@%
  8667.  
  8668. %@CR:C6A00220035 @%%@CR:C6A00220036 @%
  8669. %@2@%%@CR:C6A00220037 @%%@AB@%Set_V86_Exec_Mode%@AE@%%@EH@%%@NL@%
  8670. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8671.  
  8672.  
  8673. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8674.  
  8675. This service forces the current VM into V86 mode. Most VxDs will want to use
  8676. %@AB@%Begin_Nest_V86_Exec%@AE@% instead of this service.  %@NL@%
  8677.  
  8678. Changing the execution mode of a VM will not change the VM's %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  8679. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and %@AB@%EBP%@AE@% registers or most flags. The VM flag and IOPL flags
  8680. will change. %@AB@%DS%@AE@%, %@AB@%ES%@AE@%, %@AB@%FS%@AE@%, %@AB@%GS%@AE@%, %@AB@%SS%@AE@%, %@AB@%ESP%@AE@%, %@AB@%CS%@AE@%, and %@AB@%EIP%@AE@% will be restored to the
  8681. previous values for V86 mode.  %@NL@%
  8682.  
  8683. If the current VM is already in V86 mode, then this service has no effect.  %@NL@%
  8684.  
  8685.  
  8686. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8687.  
  8688. None  %@NL@%
  8689.  
  8690.  
  8691. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8692.  
  8693. VM is in V86 execution mode  %@NL@%
  8694.  
  8695.  
  8696. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8697.  
  8698. Flags  %@NL@%
  8699.  
  8700.  
  8701.  
  8702.  
  8703.  
  8704.  
  8705. %@CR:C6A00230001 @%%@1@%%@AB@%Chapter 23  Break Point and Callback Services%@AE@%%@EH@%%@NL@%
  8706. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8707.  
  8708. The services described in this chapter are used to handle breakpoint and
  8709. callback procedures.  %@NL@%
  8710.  
  8711. The discussion of these services is presented in the following order:  %@NL@%
  8712.  
  8713.  
  8714.   ■   %@AB@%Allocate_V86_Call_Back%@AE@%%@NL@%
  8715.  
  8716.   ■   %@AB@%Allocate_PM_Call_Back%@AE@%%@NL@%
  8717.  
  8718.   ■   %@AB@%Call_When_Idle%@AE@%%@NL@%
  8719.  
  8720.   ■   %@AB@%Call_When_VM_Returns%@AE@%%@NL@%
  8721.  
  8722.   ■   %@AB@%Install_V86_Break_Point%@AE@%%@NL@%
  8723.  
  8724.   ■   %@AB@%Remove_V86_Break_Point%@AE@%%@NL@%
  8725.  
  8726.  
  8727. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  8728. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  8729.  
  8730. %@CR:C6A00230002 @%%@CR:C6A00230003 @%%@CR:C6A00230004 @%%@CR:C6A00230005 @%
  8731. %@2@%%@CR:C6A00230006 @%%@AB@%Allocate_V86_Call_Back, Allocate_PM_Call_Back%@AE@%%@EH@%%@NL@%
  8732. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8733.  
  8734.  
  8735. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8736.  
  8737. A %@AI@%V86 callback%@AE@% is used to transition from V86 mode into a protected mode
  8738. VxD. The callback is a SEGMENT:OFFSET that, when executed by a V86 machine,
  8739. will cause a procedure in a virtual device to be called.  %@NL@%
  8740.  
  8741. A %@AI@%PM callback%@AE@% is used to transition from a protected-mode application to a
  8742. VxD. The callback is a SELECTOR:OFFSET that, when executed, will cause a
  8743. procedure in a virtual device to be called.  %@NL@%
  8744.  
  8745. These services are typically used by devices that need to be called by
  8746. software running in a virtual machine. When the VM software calls the
  8747. callback address, the VxD gets control and can service the VM's request.  %@NL@%
  8748.  
  8749. %@AS@%  Initialization:
  8750. %@AS@%    mov edx, My_Ref_Data
  8751. %@AS@%    mov esi, OFFSET33 My_API_Procedure
  8752. %@AS@%    VMMcall Allocate_V86_Call_Back
  8753. %@AS@%    mov [My_V86_Call_Back], eax
  8754. %@AS@%    mov [ebp.Client_DI], ax
  8755. %@AS@%    shr eax, 16
  8756. %@AS@%    mov [ebp.Client_ES], ax 
  8757. %@AS@%   ret%@AE@%
  8758.  
  8759. %@AS@%  My_API_Procedure:
  8760. %@AS@%   . . . (Do something here) . . .
  8761. %@AS@%   VMMcall Simulate_Far_Ret
  8762. %@AS@%   ret%@AE@%
  8763.  
  8764.  
  8765. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8766.  
  8767. %@AB@%EDX%@AE@% = Reference data (any DWORD) %@AB@%ESI%@AE@% = Procedure to call  %@NL@%
  8768.  
  8769.  
  8770. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8771.  
  8772. %@AB@%EAX%@AE@% = CS:IP of V86 callback address  %@NL@%
  8773.  
  8774.  
  8775. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8776.  
  8777. %@AB@%EAX%@AE@%, Flags  %@NL@%
  8778.  
  8779.  
  8780. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8781.  
  8782. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Current VM's client
  8783. register structure  %@NL@%
  8784.  
  8785. %@CR:C6A00230007 @%%@CR:C6A00230008 @%
  8786. %@2@%%@CR:C6A00230009 @%%@AB@%Call_When_Idle%@AE@%%@EH@%%@NL@%
  8787. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8788.  
  8789.  
  8790. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8791.  
  8792. This service is used by devices that want to perform background operations
  8793. with the system is "idle". For example, this service is used by the pageswap
  8794. device to asynchronously write dirty pages to the backing store. Windows is
  8795. considered idle when all VMs have released their time-slice. When the
  8796. Windows kernel signals that Windows is idle and all other VMs are idle, the
  8797. idle callback procedures will be called. Each callback can either consume
  8798. the idle call or pass it on to the next idle callback in the list. Idle
  8799. calls should be consumed if the device performs an operation that takes a
  8800. significant amount of time. For example, if the pageswap device writes a
  8801. dirty page to the backing store then it will consume the idle call to
  8802. prevent slugish performance.  %@NL@%
  8803.  
  8804.  
  8805. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8806.  
  8807. ESI -> Procedure to call when all VMs idle  %@NL@%
  8808.  
  8809.  
  8810. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8811.  
  8812. If carry clear then  Callback procedure installed else  Error: Could not
  8813. install call-back procedure  %@NL@%
  8814.  
  8815.  
  8816. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8817.  
  8818. Flags  %@NL@%
  8819.  
  8820.  
  8821. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8822.  
  8823. EBX = System VM Handle (current VM is always the system VM) EBP -> Client
  8824. register structure Return with carry SET to pass the call to next handler
  8825. Return with carry CLEAR to consume the callback and indicate Sys VM is not
  8826. idle. Callback procedure can modify EAX, EBX, ECX, EDX, ESI, EDI, and Flags.
  8827. %@NL@%
  8828.  
  8829. %@CR:C6A00230010 @%%@CR:C6A00230011 @%
  8830. %@2@%%@CR:C6A00230012 @%%@AB@%Call_When_VM_Returns%@AE@%%@EH@%%@NL@%
  8831. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8832.  
  8833.  
  8834. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8835.  
  8836. This service is normally used to watch the "back end" of a software
  8837. interrupt. For example, assume that the procedure %@AB@%I16_Hook%@AE@% has been placed
  8838. in the V86 interrupt chain (using the %@AB@%Hook_V86_Int_Chain%@AE@% service). If the
  8839. procedure wants to look at the return value from INT 16H, it would use the
  8840. following code:  %@NL@%
  8841.  
  8842. %@AS@%  I16_Hook:
  8843. %@AS@%    xor eax, eax    ; No time-out
  8844. %@AS@%    mov esi, OFFSET32 I16_Return   ; Call this when iret executed
  8845. %@AS@%    VMMcall Call_When_VM_Returns    ; Hook the return
  8846. %@AS@%    stc     ; Reflect to next int handler
  8847. %@AS@%    ret%@AE@%
  8848.  
  8849. %@AS@%  I16_Return:
  8850. %@AS@%    (Examine results of Int 16h)
  8851. %@AS@%    ret%@AE@%
  8852.  
  8853. This service actually replaces the client's %@AB@%CS:IP%@AE@% with a callback. Since at
  8854. the point %@AB@%I16_Hook%@AE@% is executed the interrupt IRET frame has not yet been
  8855. built on the client's stack, the callback will be pushed on the client's
  8856. IRET frame. When the VM executes an IRET to return from the interrupt, the
  8857. callback break point will be executed and control will be transferred to
  8858. %@AB@%I16_Return%@AE@%. This service will take care of restoring the client's %@AB@%CS:IP%@AE@%
  8859. registers to their original value.  %@NL@%
  8860.  
  8861.  
  8862. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8863.  
  8864. %@AB@%EAX%@AE@% = Milliseconds until time-out (0 if no time-out)  If negative value then
  8865. callback will be called for both time out AND return (unless return before
  8866. time-out). %@AB@%EDX%@AE@% = Reference data %@AB@%ESI%@AE@% = Address of procedure to call  %@NL@%
  8867.  
  8868.  
  8869. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8870.  
  8871. %@AB@%Client_CS:EIP%@AE@% replaced with callback address  %@NL@%
  8872.  
  8873.  
  8874. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8875.  
  8876. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, Flags  %@NL@%
  8877.  
  8878.  
  8879. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8880.  
  8881. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  8882. structure  %@NL@%
  8883.  
  8884. If carry set then  Time-out occurred before VM returned else  %@AB@%Client_CS:IP%@AE@%
  8885. restored to original value  VM returned and executed break point  If
  8886. time-out value specified was negative then  If Zero flag set then  Time-out
  8887. DID occur. Second call to this callback  else  Time-out did not and will not
  8888. occur.  %@NL@%
  8889.  
  8890. %@CR:C6A00230013 @%%@CR:C6A00230014 @%
  8891. %@2@%%@CR:C6A00230015 @%%@AB@%Install_V86_Break_Point%@AE@%%@EH@%%@NL@%
  8892. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8893.  
  8894.  
  8895. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8896.  
  8897. This service is used to patch V86 code in a VM. It is primarily used by the
  8898. DOSMGR device to place patches in the MS-DOS BIOS. Most VxD will have no use
  8899. for this service. A good example of a typical use for this service is the
  8900. Windows XMS virtual device. Since there is already a real mode XMS driver
  8901. when the enhanced Windows environment starts, the virtual XMS device must
  8902. place a V86 break point at the real XMS driver entry point so that it can
  8903. intercept all XMS calls.  %@NL@%
  8904.  
  8905. This service places an enhanced Windows V86 break point instruction at the
  8906. specified SEGMENT:OFFSET in the current virtual machine. V86 break points
  8907. will normally be placed in global VM memory during device initialization.
  8908. V86 break points must be placed only in RAM that will have a constant linear
  8909. address (they cannot move or be placed in ROM).  %@NL@%
  8910.  
  8911. When a VM executes the break point, control will be passed to the VxD that
  8912. installed it. The client's (VM's) %@AB@%CS:IP%@AE@% will still point to the break point
  8913. that caused the fault. Therefore, the virtual device must change the %@AB@%CS:IP%@AE@%
  8914. or else the break point will be executed again when the VxD environment
  8915. returns to the VM. In the case of the virtual XMS device, it would call
  8916. %@AB@%Simulate_Far_Ret%@AE@% to return to the code that called the XMS driver. Other
  8917. devices may want to simulate the instruction that was patched out and
  8918. increment the %@AB@%IP%@AE@% past the patch, jump to another %@AB@%CS:IP%@AE@% using
  8919. %@AB@%Simulate_Far_Jmp%@AE@%, or return from an interrupt handler using %@AB@%Simulate_Iret%@AE@%.  %@NL@%
  8920.  
  8921. If a particular V86 break point is no longer needed, then the VxD should
  8922. call %@AB@%Remove_V86_Break_Point%@AE@%. Also, any break points that are placed in
  8923. global V86 code (code loaded before Windows/386 was loaded) %@AI@%must%@AE@% be removed
  8924. at %@AB@%System_Exit%@AE@% time.  %@NL@%
  8925.  
  8926. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8927. NOTE 
  8928.  
  8929. %@AI@%The segment used to install a V86 break point must be the code segment the
  8930. %@AI@%virtual machine will use when it executes the code that is being patched.
  8931. %@AI@%For example, if you place a patch at 0100:0010 and the virtual machine hits
  8932. %@AI@%the break point at 0101:0000h (which is the same linear address as
  8933. %@AI@%0100:0010), then an error will occur even though the VM executed a valid
  8934. %@AI@%break point. %@AE@%
  8935. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8936.  
  8937.  
  8938. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8939.  
  8940. %@AB@%EAX %@AE@% = %@AB@%CS:IP%@AE@% %@AB@%EDX%@AE@% = Reference data (any DWORD) %@AB@%ESI%@AE@% = Offset of procedure to
  8941. call  %@NL@%
  8942.  
  8943.  
  8944. %@3@%%@AB@%Exit:%@AE@%%@EH@%%@NL@%
  8945.  
  8946. %@AS@%  If carry set then
  8947. %@AS@%      Could not install break point
  8948. %@AS@%   else
  8949. %@AS@%      V86 break point successfully installed%@AE@%
  8950.  
  8951.  
  8952. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8953.  
  8954. Flags  %@NL@%
  8955.  
  8956.  
  8957. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8958.  
  8959. %@AB@%EAX%@AE@% = %@AB@%Client CS:IP%@AE@% that faulted %@AB@%EBX %@AE@%= Handle of current VM %@AB@%EDX%@AE@% = Reference
  8960. data %@AB@%ESI%@AE@% = Linear address of break point (CS << 4 + IP)  %@AB@%EBP%@AE@% -> Client
  8961. register structure  %@NL@%
  8962.  
  8963. %@CR:C6A00230016 @%%@CR:C6A00230017 @%
  8964. %@2@%%@CR:C6A00230018 @%%@AB@%Remove_V86_Break_Point%@AE@%%@EH@%%@NL@%
  8965. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8966.  
  8967.  
  8968. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8969.  
  8970. This service is used to remove a V86 break point that was installed using
  8971. the %@AB@%Install_V86_Break_Point%@AE@% service. It will restore the original contents
  8972. of the memory automatically.  %@NL@%
  8973.  
  8974.  
  8975. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8976.  
  8977. %@AB@%EAX%@AE@% = %@AB@%CS:IP%@AE@% of break point to remove  %@NL@%
  8978.  
  8979.  
  8980. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8981.  
  8982. %@AS@%  If carry set then
  8983. %@AS@%      ERROR: Not a valid V86 break point
  8984. %@AS@%   else
  8985. %@AS@%      Previous value restored at break point SEG:OFFSET%@AE@%
  8986.  
  8987.  
  8988. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8989.  
  8990. Flags  %@NL@%
  8991.  
  8992.  
  8993.  
  8994.  
  8995.  
  8996.  
  8997. %@CR:C6A00240001 @%%@1@%%@AB@%Chapter 24  Primary Scheduler Services%@AE@%%@EH@%%@NL@%
  8998. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8999.  
  9000. Each virtual machine is a separate task in the enhanced Windows environment.
  9001. There are several services that are used to control the scheduling of
  9002. virtual machines.  %@NL@%
  9003.  
  9004. Every VM has an execution priority. The VM with the highest execution
  9005. priority is allowed to run unless the VM is suspended or is blocked waiting
  9006. for a critical section to be freed. A VM's execution priority can be raised
  9007. or lowered using the %@AB@%Adjust_Execution_Priority %@AE@%service.  %@NL@%
  9008.  
  9009. A VxD can force a particular virtual machine to run by boosting its
  9010. execution priority. However, VxD authors should take care when changing the
  9011. priority of a VM since doing so can radically effect the behavior of the
  9012. Windows time-slicer.%@CR:C6A00240002 @%%@NL@%
  9013.  
  9014. To allow the mutual exclusion of non-reentrant code, the scheduler supports
  9015. a single critical section. The current VM can claim the critical section at
  9016. any time by calling %@AB@%Begin_Critical_Section%@AE@%. If another VM owns the critical
  9017. section, then the current VM will block until the critical section is
  9018. released. Once the critical section is claimed, the VM's execution priority
  9019. is boosted. However, VMs with higher priorities will still be allowed to
  9020. execute. Normally, VMs are only boosted higher than the critical section
  9021. priority when a hardware interrupt is simulated.  %@NL@%
  9022.  
  9023. A VM may be suspended if it is not in a critical section. However, the
  9024. system VM can never be suspended. A suspended VM will never be scheduled,
  9025. regardless of its execution priority, until it is resumed.  %@NL@%
  9026.  
  9027. An important thing to keep in mind is that since the enhanced Windows
  9028. environment is a single-threaded operating system, you do not have to be
  9029. concerned with a task switch from within a procedure. For example, another
  9030. VM will not be scheduled while in a virtual device I/O trap handler. Task
  9031. switches take place when a VxD makes an explicit call to the scheduler
  9032. (i.e., %@AB@%End_Critical_Section%@AE@%) or at event processing time. Notice that since
  9033. events are processed when %@AB@%Resume_Exec%@AE@% or %@AB@%Exec_Int%@AE@% are called, a task switch
  9034. may occur while performing nested VM execution. Also, touching or locking
  9035. unlocked demand-paged memory may cause a task-switch. In summary, the times
  9036. when a task switch may occur are as follows:%@CR:C6A00240003 @%%@NL@%
  9037.  
  9038.  
  9039.   ■   Explicit calls to the scheduler%@NL@%
  9040.  
  9041.   ■   Performing nested execution (%@AB@%Resume_Exec%@AE@% or %@AB@%Exec_Int)%@AE@% %@NL@%
  9042.  
  9043.   ■   Touching or locking demand-paged memory %@NL@%
  9044.  
  9045.  
  9046. The discussion of services providing support for the Primary Scheduler is
  9047. presented in the following order:  %@NL@%
  9048.  
  9049.  
  9050.   ■   %@AB@%Adjust_Exec_Priority%@AE@%%@NL@%
  9051.  
  9052.   ■   %@AB@%Begin_Critical_Section%@AE@%%@NL@%
  9053.  
  9054.   ■   %@AB@%Call_When_Not_Critical%@AE@%%@NL@%
  9055.  
  9056.   ■   %@AB@%Call_When_Task_Switched%@AE@%%@NL@%
  9057.  
  9058.   ■   %@AB@%Claim_Critical_Section%@AE@%%@NL@%
  9059.  
  9060.   ■   %@AB@%Create_Semaphore%@AE@%%@NL@%
  9061.  
  9062.   ■   %@AB@%Destroy_Semaphore,D%@AE@%%@NL@%
  9063.  
  9064.   ■   %@AB@%End_Crit_And_Suspend%@AE@%%@NL@%
  9065.  
  9066.   ■   %@AB@%End_Critical_Section%@AE@%%@NL@%
  9067.  
  9068.   ■   %@AB@%Get_Crit_Section_Status%@AE@%%@NL@%
  9069.  
  9070.   ■   %@AB@%No_Fail_Resume_VM%@AE@%%@NL@%
  9071.  
  9072.   ■   %@AB@%Nuke_VM%@AE@%%@NL@%
  9073.  
  9074.   ■   %@AB@%Release_Critical_Section%@AE@%%@NL@%
  9075.  
  9076.   ■   %@AB@%Resume_VM%@AE@%%@NL@%
  9077.  
  9078.   ■   %@AB@%Signal_Semaphore%@AE@%%@NL@%
  9079.  
  9080.   ■   %@AB@%Suspend_VM%@AE@%%@NL@%
  9081.  
  9082.   ■   %@AB@%Wait_Semaphore%@AE@% %@NL@%
  9083.  
  9084.  
  9085. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  9086. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  9087.  
  9088. %@CR:C6A00240004 @%%@CR:C6A00240005 @%
  9089. %@2@%%@CR:C6A00240006 @%%@AB@%Adjust_Exec_Priority%@AE@%%@EH@%%@NL@%
  9090. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9091.  
  9092.  
  9093. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9094.  
  9095. This service is used to raise or lower the execution priority of the
  9096. specified VM. Since the non-suspended VM with the highest execution priority
  9097. is always the current VM, this service will cause a task switch under two
  9098. circumstances:  %@NL@%
  9099.  
  9100.  
  9101.   1.  The execution priority of the current VM is lowered (%@AB@%EAX%@AE@% is negative),
  9102.       and there is another VM with a higher priority that is not suspended.%@NL@%
  9103.  
  9104.   2.  The execution priority of a non-suspended VM which is not the current
  9105.       VM is raised (%@AB@%EAX%@AE@% is positive) higher than the current VM's execution
  9106.       priority. %@NL@%
  9107.  
  9108.  
  9109. Note that even if the current VM is in a critical section, a task switch
  9110. will still occur if the priority of another non-suspended VM is raised
  9111. higher than the current VM's priority. However, this will only happen when a
  9112. VM is given a time-critical boost, for example, to simulate a hardware
  9113. interrupt. There are equates defined in VMM.INC that should be used when
  9114. adjusting a VM's priority. They are listed below in order from lowest to
  9115. highest.  %@NL@%
  9116.  
  9117. %@TH:  27  1535 02 34 44 @%
  9118. Equate Name                       Description
  9119. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9120. %@AB@%Reserved_Low_Boost%@AE@%                Reserved for use by system.
  9121.  
  9122. %@AB@%Cur_Run_VM_Boost%@AE@%                  Time-slice scheduler boosts each VM in 
  9123.                                   turn by this value to force them to run 
  9124.                                   for their alloted time-slice.
  9125.  
  9126. %@AB@%Low_Pri_Device_Boost%@AE@%              Used by VxDs that need an event to be 
  9127.                                   processed in a timely fashion but that are
  9128.                                   not extremely time critical.
  9129.  
  9130. %@AB@%High_Pri_Device_Boost%@AE@%             Time critical operations that should not 
  9131.                                   circumvent the critical section boost 
  9132.                                   should use this boost.
  9133.  
  9134. %@AB@%Critical_Section_Boost%@AE@%            VM priority is boosted by this value when %@AB@%%@AE@%
  9135.                                   %@AB@%%@AE@%
  9136.                                   %@AB@%Begin_Critical_Section%@AE@% is called.
  9137.  
  9138. %@AB@%Time_Critical_Boost%@AE@%               Events that must be processed even when 
  9139.                                   another VM is in a critical section should
  9140.                                   use this boost. For example, VPICD uses 
  9141.                                   this when simulating hardware interrupts.
  9142.  
  9143. %@AB@%Reserved_High_Boost%@AE@%               Reserved for use by system.
  9144.  
  9145. %@TE:  27  1535 02 34 44 @%
  9146.  
  9147. It is often more convienient to call %@AB@%Call_Priority_VM_Event%@AE@% than to call
  9148. this service directly.  %@NL@%
  9149.  
  9150.  
  9151. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9152.  
  9153. %@AB@%EAX%@AE@%  = + or - priority boost (signed long integer) %@AB@%EBX%@AE@%  = VM handle  %@NL@%
  9154.  
  9155.  
  9156. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9157.  
  9158. None  %@NL@%
  9159.  
  9160.  
  9161. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9162.  
  9163. Flags  %@NL@%
  9164.  
  9165. %@CR:C6A00240007 @%%@CR:C6A00240008 @%
  9166. %@2@%%@CR:C6A00240009 @%%@AB@%Begin_Critical_Section%@AE@%%@EH@%%@NL@%
  9167. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9168.  
  9169.  
  9170. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9171.  
  9172. Use of this service causes the current VM to enter a global critical
  9173. section. Only one VM can own the critical section at a time. If a VM calls
  9174. this service while another VM owns the critical section, then the current VM
  9175. will block until the critical section is released.  %@NL@%
  9176.  
  9177. The critical section is maintained as a count and so %@AI@%n %@AE@%calls to
  9178. %@AB@%Begin_Critical_Section%@AE@% must be followed by%@AI@% n%@AE@% calls to %@AB@%End_Critical_Section%@AE@%
  9179. before the VM will leave the critical section.  %@NL@%
  9180.  
  9181. When the critical section is first claimed, the execution priority of the
  9182. current VM is boosted by the %@AB@%Critical_Section_Boost%@AE@% value defined in
  9183. VMM.INC. This means that task switches to other VMs will only occur for
  9184. time-critical operations such as simulating hardware interrupts.  %@NL@%
  9185.  
  9186. Critical sections are used for code that must not be entered in more than
  9187. one VM. For example, while in MS-DOS, the DOSMGR VxD places the VM in a
  9188. critical section. If another VM makes a MS-DOS call, then it will block
  9189. until the critical section owner's MS-DOS call completes. However, this
  9190. scenario is unlikely since a VM has an extremely high execution priority
  9191. while it owns the critical section, and, therefore, other VMs will not run
  9192. until the critical section is released. A scenario that%@AI@% would %@AE@%cause a VM to
  9193. block  is as follows:  %@NL@%
  9194.  
  9195. %@AS@%  VM X calls MS-DOS to read a file.
  9196. %@AS@%  The DOSMGR calls Begin_Critical_Section for VM X. This raises
  9197. %@AS@%    VM X's priority by the Critical_Section_Boost.   
  9198. %@AS@%  The Virtual Keyboard Device simulates an interrupt to VM Y.   
  9199. %@AS@%  VM Y is sceduled since it has a higher execution priority 
  9200. %@AS@%   (simulated interrupts use the Time_Critical_Boost).   
  9201. %@AS@%  A T&SR program "wakes up" on the keyboard interrupt and calls DOS.
  9202. %@AS@%  The DOSMGR calls Begin_Critical_Section for VM Y.   
  9203. %@AS@%  VM Y blocks since another VM owns the critical section.   
  9204. %@AS@%  VM X is scheduled since it has the highest exectution priority.
  9205. %@AS@%  The MS-DOS read for VM X completes.   
  9206. %@AS@%  DOSMGR calls End_Critical_Section for VM X. This lowers
  9207. %@AS@%    VM X's priority by the Critical_Section_Boost.   
  9208. %@AS@%  VM Y is un-blocked and scheduled since it has the highest priority.
  9209. %@AS@%  VM Y continues execution at the instruction immediately after the
  9210. %@AS@%    call to Begin_Critical_Section and executes the MS-DOS call.%@AE@%
  9211.  
  9212. Sometimes it is preferable to boost the current VM by the
  9213. %@AB@%Time_Critical_Boost%@AE@% value instead of entering a critical section. This
  9214. prevents the main thread of execution from running in all but the current VM
  9215. but avoids blocking a VM when it is not really necessary.  %@NL@%
  9216.  
  9217.  
  9218. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9219.  
  9220. None  %@NL@%
  9221.  
  9222.  
  9223. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9224.  
  9225. None  %@NL@%
  9226.  
  9227.  
  9228. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9229.  
  9230. Flags  %@NL@%
  9231.  
  9232. %@CR:C6A00240010 @%%@CR:C6A00240011 @%
  9233. %@2@%%@CR:C6A00240012 @%%@AB@%Call_When_Not_Critical%@AE@%%@EH@%%@NL@%
  9234. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9235.  
  9236.  
  9237. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9238.  
  9239. This service will call a VxD when the critical section is released. Notice
  9240. that it will not execute the callback until the current VM's execution
  9241. priority is less than the %@AB@%Critical_Section_Boost%@AE@% even when the current VM is
  9242. %@AI@%not%@AE@% in a critical section. This is done because most VxDs that use this
  9243. service will want to wait until the critical section is free and no hardware
  9244. interrupts are being simulated.  %@NL@%
  9245.  
  9246. Normally it is more convenient to use the %@AB@%Call_Priority_VM_Event %@AE@%service
  9247. than to call this service directly. %@AB@%  %@AE@%%@NL@%
  9248.  
  9249.  
  9250. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9251.  
  9252. %@AB@%ESI%@AE@% = Address of call-back procedure %@AB@%EDX%@AE@% = Reference data to pass to
  9253. callback procedure  %@NL@%
  9254.  
  9255.  
  9256. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9257.  
  9258. None  %@NL@%
  9259.  
  9260.  
  9261. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9262.  
  9263. Flags  %@NL@%
  9264.  
  9265.  
  9266. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  9267.  
  9268. %@AB@%EBX %@AE@%= Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  9269. structure  %@NL@%
  9270.  
  9271. Procedure can corrupt %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@% ECX%@AE@%,%@AB@% EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  9272.  
  9273. %@CR:C6A00240013 @%%@CR:C6A00240014 @%
  9274. %@2@%%@CR:C6A00240015 @%%@AB@%Call_When_Task_Switched%@AE@%%@EH@%%@NL@%
  9275. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9276.  
  9277.  
  9278. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9279.  
  9280. This service provides a way to be informed each time a different VM is to be
  9281. executed. The specified procedure will be called %@AI@%every time%@AE@% a task switch
  9282. occurs. Since this is a frequent operation in most environments, this
  9283. service should be used sparingly, and the callback procedure should be
  9284. optimized for speed.  %@NL@%
  9285.  
  9286. VxDs must sometimes save the state of a hardware device every time a task
  9287. switch occurs and restore the hardware state for the VM that is about to be
  9288. run. However, VM events can often be used in place of using this service.  %@NL@%
  9289.  
  9290.  
  9291. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9292.  
  9293. %@AB@%ESI%@AE@% = Pointer to procedure to call at task switch time  %@NL@%
  9294.  
  9295.  
  9296. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9297.  
  9298. None  %@NL@%
  9299.  
  9300.  
  9301. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9302.  
  9303. Flags  %@NL@%
  9304.  
  9305.  
  9306. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  9307.  
  9308. %@AB@%EAX%@AE@% = Handle of VM switching away from (old %@AB@%Cur_VM_Handle%@AE@%)  %@AB@%EBX%@AE@% = Current VM
  9309. (just switched to)  %@NL@%
  9310.  
  9311. Procedure can destroy %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@% and Flags  %@NL@%
  9312.  
  9313. %@CR:C6A00240016 @%%@CR:C6A00240017 @%
  9314. %@2@%%@CR:C6A00240018 @%%@AB@%Claim_Critical_Section%@AE@%%@EH@%%@NL@%
  9315. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9316.  
  9317.  
  9318. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9319.  
  9320. This service will increment the critical section count by the specified
  9321. value. It has the same effect as calling %@AB@%Begin_Critical_Section%@AE@% repeatedly
  9322. but is faster. Refer to the documentation for %@AB@%Begin_Critical_Section%@AE@% for
  9323. more information on the various side effects of entering a critical section.
  9324. %@NL@%
  9325.  
  9326.  
  9327. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9328.  
  9329. %@AB@%ECX%@AE@% = # of times to claim the critical section (0 is valid & ignored)  %@NL@%
  9330.  
  9331.  
  9332. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9333.  
  9334. None  %@NL@%
  9335.  
  9336.  
  9337. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9338.  
  9339. Flags  %@NL@%
  9340.  
  9341. %@CR:C6A00240019 @%%@CR:C6A00240020 @%
  9342. %@2@%%@CR:C6A00240021 @%%@AB@%Create_Semaphore%@AE@%%@EH@%%@NL@%
  9343. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9344.  
  9345.  
  9346. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9347.  
  9348. Do not use. Reserved for future release.  %@NL@%
  9349.  
  9350. %@CR:C6A00240022 @%%@CR:C6A00240023 @%
  9351. %@2@%%@CR:C6A00240024 @%%@AB@%Destroy_Semaphore%@AE@%%@EH@%%@NL@%
  9352. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9353.  
  9354.  
  9355. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9356.  
  9357. Do not use. Reserved for future release.  %@NL@%
  9358.  
  9359. %@CR:C6A00240025 @%%@CR:C6A00240026 @%
  9360. %@2@%%@CR:C6A00240027 @%%@AB@%End_Crit_And_Suspend%@AE@%%@EH@%%@NL@%
  9361. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9362.  
  9363.  
  9364. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9365.  
  9366. This service will release the critical section and immediately suspend the
  9367. current VM. It is used to block a VM until another event can be processed.
  9368. This service is used by the Shell VxD to display Windows dialog boxes using
  9369. code similar to this:  %@NL@%
  9370.  
  9371. %@AS@%  Show_Dialog_Box:
  9372. %@AS@%    VMMcall  Get_Crit_Section_Status
  9373. %@AS@%   jc  Cant_Do_It!
  9374. %@AS@%    VMMcall  Begin_Critical_Section
  9375. %@AS@%   mov  eax, Low_Pri_Device_Boost
  9376. %@AS@%   VMMcall  Get_Sys_VM_Handle
  9377. %@AS@%    mov  ecx, 11b
  9378. %@AS@%   mov  edx, OFFSET32 (Dialog_Box_Data_Structure)
  9379. %@AS@%    mov  esi, OFFSET32 Show_Dialog_Event
  9380. %@AS@%   VMMcall  Call_Priority_VM_Event
  9381. %@AS@%    VMMcall  End_Crit_And_Suspend
  9382. %@AS@%    jc  Did_Not_Work!
  9383. %@AS@%     ; (When End_Crit_And_Suspend returns the dialog box
  9384. %@AS@%     ; will have been displayed)%@AE@%
  9385.  
  9386. %@AS@%  Show_Dialog_Event:
  9387. %@AS@%    (Call Windows to display the dialog box)
  9388. %@AS@%    mov ebx, [Handle_Of_VM_That_Called_Show_Dialog_Box]
  9389. %@AS@%    VMMcall Resume_VM
  9390. %@AS@%    jc  Error!
  9391. %@AS@%    ret%@AE@%
  9392.  
  9393. The %@AB@%Show_Dialog_Box%@AE@% procedure enters a critical section to prevent the
  9394. %@AB@%Call_Priority_VM_Event %@AE@%service from switching to the system VM immediately.
  9395. It then calls%@AB@% End_Crit_And_Suspend%@AE@%, which blocks the current VM. The
  9396. %@AB@%Show_Dialog_Event%@AE@% procedure runs in the system (Windows) VM and actually
  9397. displays the dialog box. When it is finished, it resumes the VM that called
  9398. %@AB@%Show_Dialog_Box%@AE@%. %@AB@%  %@AE@%%@NL@%
  9399.  
  9400. This service must only be called when the critical section has been claimed
  9401. %@AI@%once%@AE@%. That is the reason for the initial test of the critical section state
  9402. in the %@AB@%Show_Dialog_Box%@AE@% procedure in the sample code.  %@NL@%
  9403.  
  9404.  
  9405. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9406.  
  9407. None  %@NL@%
  9408.  
  9409.  
  9410. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9411.  
  9412. If carry set then  ERROR: Could not suspend VM or could not release critical
  9413. section (crit claim count != 1) else  Call worked. VM execution restarted by
  9414. another VM calling  "Resume_VM".  %@NL@%
  9415.  
  9416.  
  9417. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9418.  
  9419. Flags  %@NL@%
  9420.  
  9421. %@CR:C6A00240028 @%%@CR:C6A00240029 @%
  9422. %@2@%%@CR:C6A00240030 @%%@AB@%End_Critical_Section%@AE@%%@EH@%%@NL@%
  9423. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9424.  
  9425.  
  9426. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9427.  
  9428. This service is used to release the global critical section after a call to
  9429. %@AB@%Begin_Critical_Section%@AE@% has been issued. If the critical section ownership
  9430. count is decremented to 0, then ownership of the critical section is
  9431. released. Since releasing the critical section lowers the execution priority
  9432. of the current VM, this service will cause a task switch if a non-suspended
  9433. VM has a higher priority.  %@NL@%
  9434.  
  9435.  
  9436. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9437.  
  9438. None  %@NL@%
  9439.  
  9440.  
  9441. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9442.  
  9443. None  %@NL@%
  9444.  
  9445.  
  9446. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9447.  
  9448. Flags  %@NL@%
  9449.  
  9450. %@CR:C6A00240031 @%%@CR:C6A00240032 @%
  9451. %@2@%%@CR:C6A00240033 @%%@AB@%Get_Crit_Section_Status%@AE@%%@EH@%%@NL@%
  9452. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9453.  
  9454.  
  9455. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9456.  
  9457. This service returns the critical section claim count in %@AB@%ECX%@AE@% and the owner
  9458. of the critical section in %@AB@%EBX%@AE@%. If %@AB@%ECX%@AE@% is 0, then the current VM handle will
  9459. be returned in %@AB@%EBX%@AE@%.  %@NL@%
  9460.  
  9461. If this service returns with the Carry flag set, then the VM is in a
  9462. time-critical operation such as a hardware interrupt simulation. (It has an
  9463. execution priority = %@AB@%Critical_Section_Boost%@AE@%.)  %@NL@%
  9464.  
  9465.  
  9466. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9467.  
  9468. None  %@NL@%
  9469.  
  9470.  
  9471. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9472.  
  9473. %@AB@%EBX %@AE@%= VM handle of current owner (Current VM if %@AB@%ECX%@AE@% = 0) %@AB@%ECX%@AE@% = # of times
  9474. critical section claimed If carry set then VM is in a time-critical
  9475. operation or critical section.  %@NL@%
  9476.  
  9477.  
  9478. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9479.  
  9480. Flags  %@NL@%
  9481.  
  9482. %@CR:C6A00240034 @%
  9483. %@2@%%@CR:C6A00240035 @%%@AB@%No_Fail_Resume_VM%@CR:C6A00240036 @%%@AE@%%@EH@%%@NL@%
  9484. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9485.  
  9486.  
  9487. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9488.  
  9489. This service is used to resume the execution of a VM that was previously
  9490. suspended by a call to %@AB@%Suspend_VM%@AE@%. It differs from the normal %@AB@%Resume_VM%@AE@%
  9491. service in that it will never return an error. If theVM can not be resumed,
  9492. the scheduler will handle the error condition automatically and the user
  9493. will be notified of the problem. The VM will then be resumed when there is
  9494. sufficient memory available. A task switch will occur to the resumed VM if
  9495. it has a higher priority than the current VM.  %@NL@%
  9496.  
  9497.  
  9498. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9499.  
  9500. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9501.  
  9502.  
  9503. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9504.  
  9505. None  %@NL@%
  9506.  
  9507.  
  9508. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9509.  
  9510. Flags  %@NL@%
  9511.  
  9512. %@CR:C6A00240037 @%
  9513. %@2@%%@CR:C6A00240038 @%%@AB@%Nuke_VM%@CR:C6A00240039 @%%@AE@%%@EH@%%@NL@%
  9514. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9515.  
  9516.  
  9517. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9518.  
  9519. This service is used to close a VM that has not yet terminated normally. It
  9520. is usually called by the Shell VxD to close VMs that the user has selected
  9521. to terminate using the Window Close option on the VM's system menu.  %@NL@%
  9522.  
  9523. Needless to say, this service should be used very cautiously.  %@NL@%
  9524.  
  9525.  
  9526. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9527.  
  9528. %@AB@%EBX%@AE@% = Handle of VM to destroy  %@NL@%
  9529.  
  9530.  
  9531. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9532.  
  9533. If entry EBX = Current VM handle then  This service will never return (same
  9534. as Crash_Cur_VM)  else  If EBX = System VM handle then  This service will
  9535. never return (fatal error─crash to DOS)   else  VM has been nuked  %@NL@%
  9536.  
  9537.  
  9538. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9539.  
  9540. Flags  %@NL@%
  9541.  
  9542. %@CR:C6A00240040 @%%@CR:C6A00240041 @%
  9543. %@2@%%@CR:C6A00240042 @%%@AB@%Release_Critical_Section%@AE@%%@EH@%%@NL@%
  9544. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9545.  
  9546.  
  9547. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9548.  
  9549. This service will decrement the critical section count by the specified
  9550. value. It has the same effect as calling %@AB@%End_Critical_Section%@AE@% repeatedly but
  9551. is faster.  %@NL@%
  9552.  
  9553.  
  9554. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9555.  
  9556. %@AB@%ECX%@AE@% = # of times to release ownership of critical section (0 valid)  %@NL@%
  9557.  
  9558.  
  9559. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9560.  
  9561. None  %@NL@%
  9562.  
  9563.  
  9564. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9565.  
  9566. Flags  %@NL@%
  9567.  
  9568. %@CR:C6A00240043 @%
  9569. %@2@%%@CR:C6A00240044 @%%@AB@%Resume_VM%@CR:C6A00240045 @%%@AE@%%@EH@%%@NL@%
  9570. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9571.  
  9572.  
  9573. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9574.  
  9575. This service is used to resume the execution of a VM that was previously
  9576. suspended by a call to %@AB@%Suspend_VM.%@AE@% If the suspend count is decremented to 0,
  9577. the VM will be placed on the queue of ready processes. A task switch will
  9578. occur to the resumed VM if it has a higher priority than the current VM.  %@NL@%
  9579.  
  9580. It is sometimes not possible to resume a VM. Normally, this is because a VxD
  9581. is unable to lock the VM's memory handles. Every VxD is notified when a VM
  9582. is resumed and can fail the call. In this case, this service will return
  9583. with Carry set, and the VM will remain suspended with a suspend count of 1.
  9584. %@NL@%
  9585.  
  9586.  
  9587. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9588.  
  9589. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9590.  
  9591.  
  9592. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9593.  
  9594. If carry clear then  If suspend count decremented to 0 then VM is runnable
  9595. else  Error could not resume (Suspend count remains 1)  %@NL@%
  9596.  
  9597.  
  9598. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9599.  
  9600. Flags  %@NL@%
  9601.  
  9602. %@CR:C6A00240046 @%%@CR:C6A00240047 @%
  9603. %@2@%%@CR:C6A00240048 @%%@AB@%Signal_Semaphore%@AE@%%@EH@%%@NL@%
  9604. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9605.  
  9606.  
  9607. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9608.  
  9609. Do not use. Reserved for future release.  %@NL@%
  9610.  
  9611. %@CR:C6A00240049 @%
  9612. %@2@%%@CR:C6A00240050 @%%@AB@%Suspend_VM%@CR:C6A00240051 @%%@AE@%%@EH@%%@NL@%
  9613. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9614.  
  9615.  
  9616. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9617.  
  9618. This service will suspend the execution of a specified Virtual Machine. Any
  9619. VM, except the system VM, that is not in a critical section can be
  9620. suspended. This service will fail if the specified VM is the critical
  9621. section owner or the system VM. The system VM can never be suspended.  %@NL@%
  9622.  
  9623. This service maintains a count that is incremented each time a VM is
  9624. suspended. Therefore, if this service is called %@AI@%n%@AE@% times for a given VM,
  9625. %@AB@%Resume_VM%@AE@% must be called %@AI@%n %@AE@%times before the VM will be executed.  %@NL@%
  9626.  
  9627. When a VM is being suspended for the first time (its suspend count is
  9628. incremented from 0 to 1), all devices will receive a control call with %@AB@%EAX%@AE@% =
  9629. %@AB@%VM_Suspend%@AE@%. Devices may %@AI@%not%@AE@% refuse to suspend a VM. However, VxDs are
  9630. allowed to fail the %@AB@%VM_Resume%@AE@% control call. Subsequent calls to %@AB@%Suspend_VM%@AE@%
  9631. will not result in a %@AB@%VM_Suspend%@AE@% control call until the VM has been resumed.
  9632. %@NL@%
  9633.  
  9634. When a VM is suspended, the %@AB@%CB_VM_Status%@AE@% field in the control block will
  9635. have the %@AB@%VMStat_Suspended%@AE@% bit set. When a VM is suspended, VxDs should not
  9636. touch any memory owned by that VM unless the VxD has previously locked the
  9637. memory. You %@AI@%may, %@AE@%however, examine or modify the contents of a suspended VM's
  9638. control block.  %@NL@%
  9639.  
  9640.  
  9641. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9642.  
  9643. %@AB@%EBX %@AE@%= VM handle  %@NL@%
  9644.  
  9645.  
  9646. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9647.  
  9648. If carry flag clear then  VM suspended  else  Error: Could not suspend VM
  9649. (VM is in a critical section or  is the system VM)  %@NL@%
  9650.  
  9651.  
  9652. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9653.  
  9654. Flags  %@NL@%
  9655.  
  9656. %@CR:C6A00240052 @%%@CR:C6A00240053 @%
  9657. %@2@%%@CR:C6A00240054 @%%@AB@%Wait_Semaphore%@AE@%%@EH@%%@NL@%
  9658. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9659.  
  9660.  
  9661. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9662.  
  9663. Do not use. Reserved for future release.  %@NL@%
  9664.  
  9665.  
  9666.  
  9667.  
  9668.  
  9669.  
  9670. %@CR:C6A00250001 @%%@1@%%@AB@%Chapter 25  Time-Slice Scheduler Services%@AE@%%@EH@%%@NL@%
  9671. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9672.  
  9673. The enhanced Windows time-slice scheduler is the preemptive multitasking
  9674. portion of the scheduler. It relies on time-slice priorities and flags to
  9675. determine how much CPU time should be allocated to various virtual machines.
  9676. %@NL@%
  9677.  
  9678. Every VM has a %@AB@%foreground%@AE@% (focus) and a %@AB@%background%@AE@% time-slice priority.
  9679. These should be distinguished from a VM's Execution Priority (described in
  9680. previous chapter). A VM with the largest Execution Priority will run,
  9681. preventing other VMs from executing. The VM with the largest time-slice
  9682. priority will run more often than other VMs but it will not necessarily
  9683. prevent other VMs from executing.  %@NL@%
  9684.  
  9685. There are three flags that affect the way the time-slicer schedules virtual
  9686. machines: %@AB@%VMStat_Exclusive%@AE@%, %@AB@%VMStat_Background%@AE@%, and
  9687. %@AB@%VMStat_High_Pri_Background%@AE@%. These flags are saved in the %@AB@%CB_VM_Status%@AE@% field
  9688. of each VM's control block. You may examine these flags but you must never
  9689. modify them directly. To change any of the flags, you must call the
  9690. %@AB@%Set_Time_Slice_Priority%@AE@% service.  %@NL@%
  9691.  
  9692. If a VM that has the %@AB@%VMStat_Exclusive%@AE@% bit set is assigned the execution
  9693. focus, then it will become the only VM that is allowed to run. In this case,
  9694. foreground and background priorities are meaningless since the VM is using
  9695. 100 percent of the CPU time. The %@AB@%Release_Time_Slice%@AE@% service has no effect on
  9696. an exclusive virtual machine. High-priority background VMs will not run when
  9697. an exclusive VM has the execution focus.  %@NL@%
  9698.  
  9699. The only exception to this is that Windows must be notified of certain
  9700. operations in a VM and will run momentarily in the background when these
  9701. operations occur. For example, if an exclusive VM is running in a window the
  9702. Windows VM will wake up occasionally to update the display.  %@NL@%
  9703.  
  9704. The only exception to this is that Windows must be notified of certain
  9705. operations in a VM and will run momentarily in the background when these
  9706. operations occur. For example, if an exclusive VM is running in a window,
  9707. the Windows VM will wake up occasionally to update the display.  %@NL@%
  9708.  
  9709. If the VM with the focus is %@AI@%not%@AE@% exclusive, then any VM that has the
  9710. %@AB@%VMStat_Background%@AE@% flag set will be allowed to run based on their background
  9711. time-slice priority. The VM with the focus will be scheduled based on its
  9712. foreground time-slice priority.  %@NL@%
  9713.  
  9714. For this scheduler, a higher priority indicates that the VM should get %@AI@%more%@AE@%
  9715. CPU time. The larger the priority, the faster the VM will run.  %@NL@%
  9716.  
  9717. The algorithm used to allocate time determines the percentage of CPU time
  9718. each VM should get based on their percentage of the total of all the
  9719. time-slice priorities. For example, assume the following VMs exist:  %@NL@%
  9720.  
  9721. %@TH:  14   624 02 04 20 20 32 @%
  9722.     Foreground          Background          
  9723. VM  Priority            Priority            Flags
  9724. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9725. 1   100                 50                  Exclusive, Background
  9726.  
  9727. 2   100                 50                  Background
  9728.  
  9729. 3   50                  25                  (None ─ Foreground, 
  9730.                                             non-exclusive)
  9731.  
  9732. 4   250                 75                  Background
  9733.  
  9734. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9735.  
  9736. %@TE:  14   624 02 04 20 20 32 @%
  9737.  
  9738. If the execution focus is set to VM 1, then it will use 100 percent of the
  9739. CPU time since it has the exclusive flag set. If the execution focus is set
  9740. to VM 2, then VMs 1, 2, and 4 will run.VM 3 would not be scheduled since it
  9741. does not have the background flag set.  %@NL@%
  9742.  
  9743. To determine how much time each VM should be allocated, the time-slicer
  9744. first sums all the VM priorities and, then, calculates the percentage of CPU
  9745. time each VM should receive as follows:  %@NL@%
  9746.  
  9747. VM 2 foreground pri = 100 / 225 * 100 = 45% of CPU  %@NL@%
  9748.  
  9749. VM 1 background pri = 50 / 225 * 100 = 22% of CPU  %@NL@%
  9750.  
  9751. VM 4 background pri = 75 / 225 * 100 = 33% of CPU  ───  Total 225  %@NL@%
  9752.  
  9753. Notice that a foreground priority of 10,000 (the maximum allowed) is
  9754. special. When a VM with priority 10,000 is the execution focus VM, only
  9755. high-priority background VMs will run unless the focus VM explicitly
  9756. releases its time slice. This is different from an exclusive VM since other
  9757. VMs %@AI@%can%@AE@% run if the focus gives up its time.  %@NL@%
  9758.  
  9759. When a VM has the %@AB@%VMStat_High_Pri_Back%@AE@% flag set it will execute in the
  9760. background even if the current-focus VM has a priority of 10,000 or is
  9761. exclusive.  %@NL@%
  9762.  
  9763. The discussion of services providing support for the Time-Slice Scheduler is
  9764. presented in the following order:  %@NL@%
  9765.  
  9766.  
  9767.   ■   %@AB@%Adjust_Execution_Time%@AE@%%@NL@%
  9768.  
  9769.   ■   %@AB@%Call_When_Idle%@AE@%%@NL@%
  9770.  
  9771.   ■   %@AB@%Get_Execution_Focus %@AE@%%@NL@%
  9772.  
  9773.   ■   %@AB@%Get_Time_Slice_Granularity%@AE@%%@NL@%
  9774.  
  9775.   ■   %@AB@%Get_Time_Slice_Info%@AE@%%@NL@%
  9776.  
  9777.   ■   %@AB@%Get_Time_Slice_Priority%@AE@%%@NL@%
  9778.  
  9779.   ■   %@AB@%Release_Time_Slice%@AE@%%@NL@%
  9780.  
  9781.   ■   %@AB@%Set_Execution_Focus%@AE@%%@NL@%
  9782.  
  9783.   ■   %@AB@%Set_Time_Slice_Granularity%@AE@%%@NL@%
  9784.  
  9785.   ■   %@AB@%Set_Time_Slice_Priority%@AE@%%@NL@%
  9786.  
  9787.   ■   %@AB@%Wake_Up_VM%@AE@%%@NL@%
  9788.  
  9789.  
  9790. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  9791. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  9792.  
  9793. %@CR:C6A00250002 @%%@CR:C6A00250003 @%
  9794. %@2@%%@CR:C6A00250004 @%%@AB@%Adjust_Execution_Time%@AE@%%@EH@%%@NL@%
  9795. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9796.  
  9797.  
  9798. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9799.  
  9800. This service allows a VxD to change the amount of time a VM will be allowed
  9801. to execute regardless of the VM's time-slice priority. Usually this service
  9802. is used by VxDs such as the Virtual COM Device to boost temporarily the
  9803. priority of a VM that is receiving lots of interrupts. This service can also
  9804. be used to reduce the amount of time a VM will be allowed to run by passing
  9805. a negative value in %@AB@%EAX%@AE@%. However, this is likely to cause execution
  9806. starvation and is discouraged.  %@NL@%
  9807.  
  9808. The value specified in %@AB@%EAX%@AE@% is the number of additional (or fewer)
  9809. milliseconds the VM will be allowed to run. It has the same effect on all
  9810. VMs regardless of their time-slice priority. This means that if a VxD calls
  9811. this service with %@AB@%EAX%@AE@% = 1000, then the specified VM will be allowed to run
  9812. an additional second regardless of its time-slice priority.  %@NL@%
  9813.  
  9814. Notice that if the specified VM is not on the time-slice execution list,
  9815. then this service will do nothing. It will %@AI@%not%@AE@% force a non-runnable VM to
  9816. execute. In other words, a non-background VM cannot be forced to run in the
  9817. background by boosting its execution time.  %@NL@%
  9818.  
  9819. Be careful using this service. It can result in starvation for other
  9820. processes.  %@NL@%
  9821.  
  9822.  
  9823. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9824.  
  9825. %@AB@%EAX%@AE@% = + or - milliseconds to adjust execution time by %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9826.  
  9827.  
  9828. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9829.  
  9830. None  %@NL@%
  9831.  
  9832.  
  9833. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9834.  
  9835. Flags  %@NL@%
  9836.  
  9837. %@CR:C6A00250005 @%%@CR:C6A00250006 @%
  9838. %@2@%%@CR:C6A00250007 @%%@AB@%Call_When_Idle%@AE@%%@EH@%%@NL@%
  9839. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9840.  
  9841.  
  9842. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9843.  
  9844. This service is used by VxDs that want to perform background operations when
  9845. the system is "idle". For example, this service is used by the pageswap
  9846. device to asynchronously write dirty pages to the backing store. Windows is
  9847. considered idle when all VMs have released their time-slice. When the
  9848. Windows kernel signals that Windows is idle and all other VMs are idle, the
  9849. idle call-back procedures will be called. Each call-back can either consume
  9850. the idle call or pass it on to the next idle call-back in the list. Idle
  9851. calls should be consumed if the VxD performs an operation that takes a
  9852. significant amount of time. For example, if the pageswap device writes a
  9853. dirty page to the backing store then it will consume the idle call to
  9854. prevent sluggish performance.  %@NL@%
  9855.  
  9856.  
  9857. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9858.  
  9859. %@AB@%ESI%@AE@% - Procedure to call when all VMs idle  %@NL@%
  9860.  
  9861.  
  9862. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9863.  
  9864. If carry clear then  Call-back procedure installed else  Error: Could not
  9865. install call-back procedure  %@NL@%
  9866.  
  9867.  
  9868. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9869.  
  9870. Flags  %@NL@%
  9871.  
  9872.  
  9873. %@3@%%@AB@%Call-Back%@AE@%%@EH@%%@NL@%
  9874.  
  9875. %@AB@%EBX%@AE@% = System VM Handle (current VM is always the system VM) %@AB@%EBP%@AE@% - Client
  9876. register structure Return with carry SET to pass the call to next handler
  9877. Return with carry CLEAR to "eat" the call-back and indicate Sys VM is not
  9878. idle. Call-back procedure can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and
  9879. Flags.  %@NL@%
  9880.  
  9881. %@CR:C6A00250008 @%%@CR:C6A00250009 @%
  9882. %@2@%%@CR:C6A00250010 @%%@AB@%Get_Execution_Focus%@AE@%%@EH@%%@NL@%
  9883. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9884.  
  9885.  
  9886. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9887.  
  9888. This service returns the handle of the VM that is the focus (foreground) VM.
  9889. This service can be called from an interrupt handler.  %@NL@%
  9890.  
  9891.  
  9892. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9893.  
  9894. None  %@NL@%
  9895.  
  9896.  
  9897. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9898.  
  9899. %@AB@%EBX%@AE@% = Handle of VM with execution focus  %@NL@%
  9900.  
  9901.  
  9902. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9903.  
  9904. %@AB@%EBX%@AE@%, Flags  %@NL@%
  9905.  
  9906. %@CR:C6A00250011 @%%@CR:C6A00250012 @%
  9907. %@2@%%@CR:C6A00250013 @%%@AB@%Get_Time_Slice_Granularity%@AE@%%@EH@%%@NL@%
  9908. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9909.  
  9910.  
  9911. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9912.  
  9913. This service returns the current time-slice granularity in %@AB@%EAX%@AE@%. The value
  9914. returned is the minimum number of milliseconds a VM will be allowed to run
  9915. before being rescheduled.  %@NL@%
  9916.  
  9917.  
  9918. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9919.  
  9920. None  %@NL@%
  9921.  
  9922.  
  9923. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9924.  
  9925. %@AB@%EAX%@AE@% = Minimum time-slice size in milliseconds  %@NL@%
  9926.  
  9927.  
  9928. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9929.  
  9930. %@AB@%EAX%@AE@%, Flags  %@NL@%
  9931.  
  9932. %@CR:C6A00250014 @%%@CR:C6A00250015 @%
  9933. %@2@%%@CR:C6A00250016 @%%@AB@%Get_Time_Slice_Info%@AE@%%@EH@%%@NL@%
  9934. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9935.  
  9936.  
  9937. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9938.  
  9939. This service returns information about the number of virtual machines
  9940. currently scheduled by the time-slicer and the number of VMs that are idle.
  9941. %@NL@%
  9942.  
  9943. This service can be called at interrupt time.  %@NL@%
  9944.  
  9945.  
  9946. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9947.  
  9948. None  %@NL@%
  9949.  
  9950.  
  9951. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9952.  
  9953. %@AB@%EAX%@AE@% = Number of VMs scheduled %@AB@%EBX%@AE@% = Handle of VM currently scheduled %@AB@%ECX%@AE@% =
  9954. Number of scheduled VMs that are currently idle  %@NL@%
  9955.  
  9956.  
  9957. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9958.  
  9959. Nothing  %@NL@%
  9960.  
  9961. %@CR:C6A00250017 @%%@CR:C6A00250018 @%
  9962. %@2@%%@CR:C6A00250019 @%%@AB@%Get_Time_Slice_Priority%@AE@%%@EH@%%@NL@%
  9963. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9964.  
  9965.  
  9966. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9967.  
  9968. This service returns the time-slice execution flags, the foreground and
  9969. background priorities, and the percent of CPU usage for a specified VM.
  9970. Notice that the percent of CPU time returned indicates the amount of time
  9971. the VM is allowed to run, but this number will not reflect the actual amount
  9972. of CPU time if any VM releases its time slice since other VMs will be
  9973. allowed to execute during that VM's time slice.  %@NL@%
  9974.  
  9975.  
  9976. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9977.  
  9978. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9979.  
  9980.  
  9981. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9982.  
  9983. %@AB@%EAX%@AE@% = Flags    (Appropriate flags from CB_VM_Status control block
  9984. field)          %@AB@%VMMStat_Exclusive%@AE@%          %@AB@%VMStat_Background%@AE@%
  9985. %@AB@%VMStat_High_Pri_Back%@AE@% %@AB@%ECX %@AE@%= Foreground time-slice priority (high word 0) %@AB@%EDX%@AE@%
  9986. = Background time-slice priority (high word 0) %@AB@%ESI%@AE@% = % of total CPU time
  9987. used by VM  %@NL@%
  9988.  
  9989.  
  9990. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9991.  
  9992. Flags  %@NL@%
  9993.  
  9994. %@CR:C6A00250020 @%%@CR:C6A00250021 @%
  9995. %@2@%%@CR:C6A00250022 @%%@AB@%Release_Time_Slice%@AE@%%@EH@%%@NL@%
  9996. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9997.  
  9998.  
  9999. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10000.  
  10001. This service causes the current VM to give up any time remaining in its
  10002. current time slice and allows the next VM in the time-slice queue to run.
  10003. This service should be called whenever a VM is idle to allow other VMs to
  10004. execute faster. If there is only one VM in the time-slice queue, this
  10005. service will do nothing.  %@NL@%
  10006.  
  10007. When this service is called for a background VM, it will release the VM's
  10008. time-slice, and adjust the VM's execution time by -500 milliseconds. This
  10009. assures that idle background-VMs will take up very little CPU time.  %@NL@%
  10010.  
  10011. If the focus VM or a high priority background VM calls this service, it will
  10012. only give up it's time slice. It's execution time will not be adjusted.  %@NL@%
  10013.  
  10014.  
  10015. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10016.  
  10017. None  %@NL@%
  10018.  
  10019.  
  10020. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10021.  
  10022. None  %@NL@%
  10023.  
  10024.  
  10025. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10026.  
  10027. Flags  %@NL@%
  10028.  
  10029. %@CR:C6A00250023 @%%@CR:C6A00250024 @%
  10030. %@2@%%@CR:C6A00250025 @%%@AB@%Set_Execution_Focus%@AE@%%@EH@%%@NL@%
  10031. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10032.  
  10033.  
  10034. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10035.  
  10036. This service changes the time-slice exection focus to the specified virtual
  10037. machine. The VM with the focus executes with its foreground priority. If the
  10038. %@AB@%VMStat_Exclusive%@AE@% flag is set, then it will be the only VM scheduled.
  10039. Otherwise, background VMs will be allowed to run. All VMs except the focus
  10040. VM, background VMs, and the system VM will be suspended.  %@NL@%
  10041.  
  10042. This service must only be called in the system VM or when the new focus is
  10043. the same as the current VM (%@AB@%EBX%@AE@% = Cur_VM_Handle).  %@NL@%
  10044.  
  10045.  
  10046. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10047.  
  10048. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  10049.  
  10050.  
  10051. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10052.  
  10053. If carry set then  ERROR: Could not set focus else  Focus set successfully  %@NL@%
  10054.  
  10055.  
  10056. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10057.  
  10058. Flags  %@NL@%
  10059.  
  10060. %@CR:C6A00250026 @%%@CR:C6A00250027 @%
  10061. %@2@%%@CR:C6A00250028 @%%@AB@%Set_Time_Slice_Granularity%@AE@%%@EH@%%@NL@%
  10062. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10063.  
  10064.  
  10065. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10066.  
  10067. This service is used to change the minimum amount of time the time-slice
  10068. scheduler will allocate to a VM. Smaller values will make multitasking
  10069. appear smoother but will increase overhead due to the large number of task
  10070. switches required. Larger values will allow more time for the VMs to execute
  10071. but may make execution appear sporadic to the user.  %@NL@%
  10072.  
  10073.  
  10074. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10075.  
  10076. %@AB@%EAX%@AE@% = Minimum time-slice size in milliseconds  %@NL@%
  10077.  
  10078.  
  10079. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10080.  
  10081. None  %@NL@%
  10082.  
  10083.  
  10084. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10085.  
  10086. Flags  %@NL@%
  10087.  
  10088. %@CR:C6A00250029 @%%@CR:C6A00250030 @%
  10089. %@2@%%@CR:C6A00250031 @%%@AB@%Set_Time_Slice_Priority%@AE@%%@EH@%%@NL@%
  10090. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10091.  
  10092.  
  10093. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10094.  
  10095. This service sets the time-slice execution flags and the foreground and
  10096. background priorities for a specified VM.  %@NL@%
  10097.  
  10098. To change part of a VM's time-slice priority status, first call
  10099. %@AB@%Get_Time_Slice_Priority%@AE@%, then change only the values you are interested in
  10100. and call this service. For example, to set a VM into background mode, you
  10101. would do the following:  %@NL@%
  10102.  
  10103. %@AS@%  mov ebx, [Handle_Of_VM_To_Change] 
  10104. %@AS@%  VMMcall  Get_Time_Slice_Priority 
  10105. %@AS@%  or eax, VMStat_Background 
  10106. %@AS@%  VMMcall  Set_Time_Slice_Priority%@AE@%
  10107.  
  10108.  
  10109. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10110.  
  10111. %@AB@%EAX%@AE@% = Flags  %@AB@%VMStat_Exclusive%@AE@%  %@AB@%VMStat_Background%@AE@%  %@AB@%VMStat_High_Pri_Back%@AE@% %@AB@%EBX%@AE@% =
  10112. VM handle %@AB@%ECX%@AE@% = Foreground priority (high word must be 0) %@AB@%EDX%@AE@% = Background
  10113. priority (high word must be 0)  %@NL@%
  10114.  
  10115.  
  10116. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10117.  
  10118. If carry set then  ERROR: Could not change priority / flags for VM else
  10119. Priority and flags changed  %@NL@%
  10120.  
  10121.  
  10122. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10123.  
  10124. Flags  %@NL@%
  10125.  
  10126. %@CR:C6A00250032 @%%@CR:C6A00250033 @%
  10127. %@2@%%@CR:C6A00250034 @%%@AB@%Wake_Up_VM%@AE@%%@EH@%%@NL@%
  10128. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10129.  
  10130.  
  10131. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10132.  
  10133. This service is used to "wake up" a VM that called the %@AB@%Release_Time_Slice%@AE@%
  10134. service and has the VMStat_Idle flag set. If the specified VM is not idle,
  10135. this service will do nothing.  %@NL@%
  10136.  
  10137.  
  10138. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10139.  
  10140. %@AB@%EBX%@AE@% = Handle of VM begin woken up  %@NL@%
  10141.  
  10142.  
  10143. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10144.  
  10145. None  %@NL@%
  10146.  
  10147.  
  10148. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10149.  
  10150. Flags  %@NL@%
  10151.  
  10152.  
  10153.  
  10154.  
  10155.  
  10156.  
  10157. %@CR:C6A00260001 @%%@1@%%@AB@%Chapter 26  Event Services%@AE@%%@EH@%%@NL@%
  10158. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10159.  
  10160. Enhanced Windows is a single-threaded, non-reentrant operating environment.
  10161. Because it is non-reentrant, VxDs that hook hardware interrupts must have
  10162. some method of synchronizing their calls to VMM. For this reason, enhanced
  10163. Windows has the concept of "event" processing.%@CR:C6A00260002 @%%@NL@%
  10164.  
  10165. When a VxD is entered due to an asynchronous interrupt, such as a hardware
  10166. interrupt, the VxD is limited to a very specific subset of functions. It is
  10167. allowed to do only the following:  %@NL@%
  10168.  
  10169.  
  10170.   ■   Call any Virtual PIC Device (VPICD) service%@NL@%
  10171.  
  10172.   ■   Call any asynchronous VMM service (see individual services for
  10173.       details)%@NL@%
  10174.  
  10175.   ■   Schedule events%@NL@%
  10176.  
  10177.  
  10178. Obviously, VxDs that service hardware interrupts will often need to use
  10179. services other than the ones listed above. When this is the case, the VxD
  10180. will need to schedule an event. When an event is scheduled, the caller
  10181. defines a procedure to call when it is OK to make any VMM call. When VMM
  10182. calls this procedure, the VxD can finish processing the asynchronous event.
  10183. %@NL@%
  10184.  
  10185. VM events are often useful for VxDs that do not service hardware interrupts
  10186. and can be scheduled at any time except during a Non-Maskable Interrupt
  10187. (NMI).  %@NL@%
  10188.  
  10189. When an event service routine is called, it is entered with the following:  %@NL@%
  10190.  
  10191.  
  10192.   ■   %@AB@%EBX%@AE@% = Current VM handle %@NL@%
  10193.  
  10194.   ■   %@AB@%EDX%@AE@% = Reference data passed when the routine was set up%@NL@%
  10195.  
  10196.   ■   %@AB@%EBP%@AE@% -> Client register structure%@NL@%
  10197.  
  10198.  
  10199. The event callback procedure can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, and %@AB@%EDI%@AE@%.  %@NL@%
  10200.  
  10201. The discussion of services providing support for events is presented in the
  10202. following order:  %@NL@%
  10203.  
  10204.  
  10205.   ■   %@AB@%Call_Global_Event%@AE@%%@NL@%
  10206.  
  10207.   ■   %@AB@%Call_Priority_VM_Event%@AE@%%@NL@%
  10208.  
  10209.   ■   %@AB@%Call_VM_Event%@AE@%%@NL@%
  10210.  
  10211.   ■   %@AB@%Cancel_Global_Event%@AE@%%@NL@%
  10212.  
  10213.   ■   %@AB@%Cancel_Priority_VM_Event%@AE@%%@NL@%
  10214.  
  10215.   ■   %@AB@%Cancel_VM_Event%@AE@%%@NL@%
  10216.  
  10217.   ■   %@AB@%Hook_NMI_Event%@AE@%%@NL@%
  10218.  
  10219.   ■   %@AB@%Schedule_Global_Event%@AE@%%@NL@%
  10220.  
  10221.   ■   %@AB@%Schedule_VM_Event%@AE@%%@NL@%
  10222.  
  10223.  
  10224. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  10225. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  10226.  
  10227. %@CR:C6A00260003 @%
  10228. %@2@%%@CR:C6A00260004 @%%@AB@%Call_Global_Event%@CR:C6A00260005 @%%@AE@%%@EH@%%@NL@%
  10229. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10230.  
  10231.  
  10232. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10233.  
  10234. This procedure is a faster method of servicing asynchronous events. If the
  10235. current thread of execution begins in a VM (it was %@AI@%not%@AE@% an interrupt from
  10236. within the VMM), then the event procedure will be called immediately.
  10237. Otherwise, the event will be scheduled.  %@NL@%
  10238.  
  10239.  
  10240. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10241.  
  10242. %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will be passed back
  10243. to procedure)  %@NL@%
  10244.  
  10245.  
  10246. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10247.  
  10248. If %@AB@%ESI %@AE@%= 0 then  Event procedure was called else  %@AB@%ESI%@AE@% = Event handle (can be
  10249. used to cancel events)  %@NL@%
  10250.  
  10251.  
  10252. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10253.  
  10254. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10255.  
  10256.  
  10257. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10258.  
  10259. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client Register
  10260. Structure  %@NL@%
  10261.  
  10262. %@CR:C6A00260006 @%%@CR:C6A00260007 @%
  10263. %@2@%%@CR:C6A00260008 @%%@AB@%Call_Priority_VM_Event%@AE@%%@EH@%%@NL@%
  10264. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10265.  
  10266.  
  10267. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10268.  
  10269. This service combines the functionality of %@AB@%Call_VM_Event,
  10270. %@AB@%Call_When_VM_Ints_Enabled, Call_When_Not_Critical%@AE@%, and %@AB@%Adjust_Exec_Priority%@AE@%
  10271. into one, easy to use service. As with all event services, this service can
  10272. be called from an interrupt handler.  %@NL@%
  10273.  
  10274. %@AB@%Call_Priority_VM_Event%@AE@% is used by VxDs for several purposes. The most common
  10275. uses are as follows:  %@NL@%
  10276.  
  10277.  
  10278.   ■   To wait until a VM enables interrupts and the critical section is free
  10279.       so the VxD can call DOS or some other non-reentrant code. %@NL@%
  10280.  
  10281.   ■   To boost a VM's priority and wait until the VM enables interrupts to
  10282.       simulate an interrupt type event. For example, the VNETBIOS uses this
  10283.       service for asynchronous network request POST callbacks. %@NL@%
  10284.  
  10285.   ■   To force an event to be processed in another VM by boosting the VM's
  10286.       Execution Priority.%@NL@%
  10287.  
  10288.  
  10289.  
  10290. %@3@%%@AB@%Example%@AE@%%@EH@%%@NL@%
  10291.  
  10292. Assume a VxD implements a print spooler that will call a VM back when a
  10293. buffer has been sent to the printer. It could use this service to notify the
  10294. appropriate VM that its buffer has been printed as follows:  %@NL@%
  10295.  
  10296. %@AS@%  VxD_Code_SEG
  10297. %@AS@%   BeginProc Print_Buff_Empty
  10298. %@AS@%   mov  eax, Low_pri_Device_boost
  10299. %@AS@%   mov  ebx, [Call_Back_VM_Handle]
  10300. %@AS@%   mov  ecx, PEF_Wait_ForSTI or PEF_Wait_Not_Crit
  10301. %@AS@%   mov  edx, [Call_back_CS_IP]
  10302. %@AS@%   mov  esi, Buff_Empty_Call_Back_Event
  10303. %@AS@%   VMMcall   Call_Priority_Event
  10304. %@AS@%   ret
  10305. %@AS@%   EndProc  Print_Buff_Empty
  10306. %@AS@%   BeginProc  Buff_Empty_Call_Back_Event
  10307. %@AS@%   VMMcall  Begin_Nest_Exec  ;Get ready to call VM
  10308. %@AS@%   mov   ecx,  edx
  10309. %@AS@%   shr   edx,  16   ;ECX = Segment to call
  10310. %@AS@%   movzx  edx, dx   ;EDX = Offset to call
  10311. %@AS@%   VMMcall    Build_Int_Stack_Frame
  10312. %@AS@%   VMMcall    Resume_Exec  ;call the VMM's callback
  10313. %@AS@%   VMMcall End_Nest_Exec
  10314. %@AS@%   ret
  10315. %@AS@%   EndProc    Buff_Empty_Call_Back_Event%@AE@%
  10316.  
  10317. The %@AB@%Print_Buff_Empty%@AE@% procedure could be called from a hardware interrupt
  10318. handler in any VM. It uses %@AB@%Call_Priority_VM_Event%@AE@% to force the correct VM to
  10319. be scheduled. The priority boost specified in %@AB@%EAX %@AE@%will force the event to be
  10320. processed quickly although not as fast as a hardware interrupt. The options
  10321. specified in the %@AB@%ECX%@AE@% register will force the event to be delayed until the
  10322. critical section is free and the VM's interrupts are enabled. The reference
  10323. data in %@AB@%EDX%@AE@% contains the %@AB@%CS:IP %@AE@%of the procedure to call in the VM.  %@NL@%
  10324.  
  10325. When %@AB@%Buff_Empty_Call_Back_Event%@AE@% is called it can make several assumptions:
  10326. it is running in the desired VM, the critical section is not owned, and the
  10327. VM has enabled interrupts. It uses the %@AB@%CS:IP%@AE@% value passed in %@AB@%EDX%@AE@% to simulate
  10328. a pseudo-interrupt in the VM. The procedure called in the VM would have to
  10329. execute an IRET to return from the callback. When %@AB@%Buff_Empty_Call_Back_Event%@AE@%
  10330. returns, the execution priority boost is automatically deducted.  %@NL@%
  10331.  
  10332. Notice this example is incomplete ─ An actual VxD handler would need to do
  10333. more work. It does not address several problems. For example
  10334. %@AB@%Buff_Empty_Call_Back_Event%@AE@% does not take into account whether the call
  10335. should be made to a V86 CS:IP or protected mode CS:IP. It also would not
  10336. work for 32-bit protected mode programs since it would need to pass a 32-bit
  10337. offset (EIP) to Simulate_Far_Call.  %@NL@%
  10338.  
  10339.  
  10340. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10341.  
  10342. %@AB@%EAX%@AE@% = Priority boost (can be 0) %@AB@%EBX%@AE@% = VM handle %@AB@%ECX%@AE@% = Option flags (defined
  10343. in VMM.INC)  PEF_Wait_For_STI - Event will not be called until  VM enables
  10344. interrupts  PEF_Wait_Not_Crit - Event will not be called until  VM is not in
  10345. a critical section  or time-critical operation.  PEF_Dont_Unboost - Priority
  10346. of VM will not be reduced  after return from event procedure.
  10347. PEF_Always_Sched - Always schedule the event. This means  the event
  10348. procedure will never be called immediately.  All other bits are reserved and
  10349. must be 0. %@AB@%EDX%@AE@% = Reference data (will be passed back to procedure) %@AB@%ESI%@AE@% =
  10350. Offset of procedure to call  %@NL@%
  10351.  
  10352.  
  10353. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10354.  
  10355. If ESI = 0 then  Event procedure already called  else  Event procedure will
  10356. be called later ESI = Event handle (can cancel using
  10357. Cancel_Priority_VM_Event)  %@NL@%
  10358.  
  10359.  
  10360. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10361.  
  10362. Flags  %@NL@%
  10363.  
  10364.  
  10365. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10366.  
  10367. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  10368. structure  %@NL@%
  10369.  
  10370. Procedure can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,%@AB@% EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  10371.  
  10372. %@CR:C6A00260009 @%
  10373. %@2@%%@CR:C6A00260010 @%%@AB@%Call_VM_Event%@CR:C6A00260011 @%%@AE@%%@EH@%%@NL@%
  10374. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10375.  
  10376.  
  10377. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10378.  
  10379. This procedure is a faster method of servicing asynchronous events. If the
  10380. current thread of execution begins in a virtual machine (it was %@AI@%not %@AE@%an
  10381. interrupt from within the VMM) %@AI@%and%@AE@% the event is for the current VM, then the
  10382. event procedure will be called immediately. Otherwise, the event will be
  10383. scheduled.  %@NL@%
  10384.  
  10385.  
  10386. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10387.  
  10388. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will
  10389. be passed back to procedure)  %@NL@%
  10390.  
  10391.  
  10392. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10393.  
  10394. If ESI = 0 then  Event procedure was called else  ESI = Event handle (can be
  10395. used to cancel events)  %@NL@%
  10396.  
  10397.  
  10398. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10399.  
  10400. Flags  %@NL@%
  10401.  
  10402.  
  10403. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10404.  
  10405. %@AB@%EBX %@AE@%= Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  10406. structure  %@NL@%
  10407.  
  10408. %@CR:C6A00260012 @%%@CR:C6A00260013 @%
  10409. %@2@%%@CR:C6A00260014 @%%@AB@%Cancel_Global_Event%@AE@%%@EH@%%@NL@%
  10410. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10411.  
  10412.  
  10413. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10414.  
  10415. This service is used to cancel an event that was previously scheduled by
  10416. %@AB@%Schedule_Global_Event%@AE@% or %@AB@%Call_Global_Event%@AE@%. Notice that, once a scheduled
  10417. event is serviced, you must not attempt to cancel that event.  %@NL@%
  10418.  
  10419. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10420. NOTE 
  10421.  
  10422. %@AI@%It is valid to pass %@AB@%ESI%@AE@%%@AI@% = 0 to this service (it will do nothing). This is
  10423. %@AI@%provided so that code that uses this service can use 0 to indicate no event
  10424. %@AI@%scheduled and not have to perform a test every time it wants to cancel an
  10425. %@AI@%event. For example: %@AE@%%@AE@%
  10426. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10427.  
  10428. %@AS@%  xor     esi, esi
  10429. %@AS@%      xchg    esi, [My_Event_Handle]
  10430. %@AS@%      VMMcall Cancel_Global_Event%@AE@%
  10431.  
  10432. %@AI@%will always work even if no event was scheduled. You will also need to set
  10433. [%@AB@%My_Event_Handle%@AE@%] to 0 in your event procedure. %@AE@%
  10434.  
  10435. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10436.  
  10437. %@AB@%ESI%@AE@% = Event handle (0 is acceptable)  %@NL@%
  10438.  
  10439.  
  10440. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10441.  
  10442. Global event has been canceled  %@NL@%
  10443.  
  10444.  
  10445. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10446.  
  10447. Flags  %@NL@%
  10448.  
  10449. %@CR:C6A00260015 @%%@CR:C6A00260016 @%
  10450. %@2@%%@CR:C6A00260017 @%%@AB@%Cancel_Priority_VM_Event%@AE@%%@EH@%%@NL@%
  10451. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10452.  
  10453.  
  10454. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10455.  
  10456. This service is used to cancel an event that was previously scheduled by
  10457. %@AB@%Call_Priority_VM_Event.%@AE@% Notice that once a scheduled event is serviced, you
  10458. must not attempt to cancel that event.  %@NL@%
  10459.  
  10460. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10461. NOTE 
  10462.  
  10463. %@AI@%It is valid to pass %@AB@%ESI%@AE@%%@AI@% = 0 to this service (it will do nothing). This is
  10464. %@AI@%provided so that code that uses this service can use 0 to indicate no event
  10465. %@AI@%scheduled and not have to perform a test every time it wants to cancel an
  10466. %@AI@%event. For example: %@AE@%%@AE@%
  10467. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10468.  
  10469. %@AS@%  xor     esi, esi
  10470. %@AS@%      xchg    esi, [My_Event_Handle]
  10471. %@AS@%      VMMcall Cancel_VM_Event%@AE@%
  10472.  
  10473. %@AI@%will always work even if no event was scheduled. You will also need to set
  10474. [%@AB@%My_Event_Handle%@AE@%] to 0 in your event procedure. %@AE@%
  10475. Any priority boost associated with this event will be canceled even if the
  10476. %@AB@%PEF_DONT_UNBOOST%@AE@% flag was set when the event was scheduled.  %@NL@%
  10477.  
  10478. Do not use this service to cancel events scheduled using the %@AB@%Call_VM_Event
  10479. %@AB@%%@AE@%or %@AB@%Schedule_VM_Event%@AE@% services. You must cancel normal VM events using the
  10480. %@AB@%Cancel_VM_Event%@AE@% service.  %@NL@%
  10481.  
  10482.  
  10483. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10484.  
  10485. %@AB@%ESI%@AE@% = Priority event handle (0 is valid)  %@NL@%
  10486.  
  10487.  
  10488. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10489.  
  10490. Event canceled, %@AB@%ESI%@AE@% contains garbage  %@NL@%
  10491.  
  10492.  
  10493. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10494.  
  10495. Flags, %@AB@%ESI%@AE@%  %@NL@%
  10496.  
  10497. %@CR:C6A00260018 @%
  10498. %@2@%%@CR:C6A00260019 @%%@AB@%Cancel_VM_Event%@CR:C6A00260020 @%%@AE@%%@EH@%%@NL@%
  10499. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10500.  
  10501.  
  10502. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10503.  
  10504. This service is used to cancel an event that was previously scheduled by
  10505. %@AB@%Schedule_VM_Event%@AE@% or %@AB@%Call_VM_Event%@AE@%. Notice that, once a scheduled event is
  10506. serviced, you must not attempt to cancel that event.  %@NL@%
  10507.  
  10508. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10509. NOTE 
  10510.  
  10511. %@AI@%It is valid to pass %@AB@%ESI%@AE@%%@AI@% = 0 to this service (it will do nothing). This is
  10512. %@AI@%provided so that code that uses this service can use 0 to indicate no event
  10513. %@AI@%scheduled and not have to perform a test every time it wants  to cancel an
  10514. %@AI@%event. For example:%@AE@%%@AE@%
  10515. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10516.  
  10517. %@AS@%  xor     esi, esi
  10518. %@AS@%      xchg    esi, [My_Event_Handle]
  10519. %@AS@%      VMMcall Cancel_VM_Event%@AE@%
  10520.  
  10521. %@AI@%will always work even if no event was scheduled. You will also need to set
  10522. [%@AB@%My_Event_Handle%@AE@%] to 0 in your event procedure. %@AE@%
  10523. Do not use this service to cancel events scheduled using the
  10524. %@AB@%Call_Priority_VM_Event%@AE@% service. You must cancel priority events using the
  10525. %@AB@%Cancel_Priority_VM_Event%@AE@% service.  %@NL@%
  10526.  
  10527.  
  10528. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10529.  
  10530. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Event handle (0 is acceptable)  %@NL@%
  10531.  
  10532.  
  10533. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10534.  
  10535. None  %@NL@%
  10536.  
  10537.  
  10538. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10539.  
  10540. Flags  %@NL@%
  10541.  
  10542. %@CR:C6A00260021 @%
  10543. %@2@%%@CR:C6A00260022 @%%@AB@%Hook_NMI_Event%@CR:C6A00260023 @%%@AE@%%@EH@%%@NL@%
  10544. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10545.  
  10546.  
  10547. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10548.  
  10549. See documentation for Get_NMI_Handler_Addr for information on this service.
  10550. This service must only be called during initialization.  %@NL@%
  10551.  
  10552.  
  10553. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10554.  
  10555. %@AB@%ESI%@AE@% = Address of NMI event procedure  %@NL@%
  10556.  
  10557.  
  10558. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10559.  
  10560. None  %@NL@%
  10561.  
  10562.  
  10563. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10564.  
  10565. Flags  %@NL@%
  10566.  
  10567.  
  10568. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10569.  
  10570. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client Register Structure  %@NL@%
  10571.  
  10572. %@CR:C6A00260024 @%%@CR:C6A00260025 @%
  10573. %@2@%%@CR:C6A00260026 @%%@AB@%Schedule_Global_Event%@AE@%%@EH@%%@NL@%
  10574. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10575.  
  10576.  
  10577. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10578.  
  10579. This procedure is used to schedule asynchronous events that are not VM
  10580. specific. The events will be processed immediately before the VMM IRETs to
  10581. any VM.  %@NL@%
  10582.  
  10583.  
  10584. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10585.  
  10586. %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will be passed back
  10587. to procedure)  %@NL@%
  10588.  
  10589.  
  10590. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10591.  
  10592. %@AB@%ESI %@AE@%= Event handle (can be used to cancel event)  %@NL@%
  10593.  
  10594.  
  10595. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10596.  
  10597. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10598.  
  10599.  
  10600. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10601.  
  10602. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  10603. structure  %@NL@%
  10604.  
  10605. %@CR:C6A00260027 @%
  10606. %@2@%%@CR:C6A00260028 @%%@AB@%Schedule_VM_Event%@CR:C6A00260029 @%%@AE@%%@EH@%%@NL@%
  10607. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10608.  
  10609.  
  10610. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10611.  
  10612. This procedure is used to schedule asynchronous events that are VM specific.
  10613. The events will be processed immediately before the VMM IRETs to the
  10614. specified VM.  %@NL@%
  10615.  
  10616. VM events will only be executed in the VM for which they were scheduled for.
  10617. Therefore, if a VM event is scheduled for a VM other than the current
  10618. virtual machine, it will not be processed until a task switch occurs to that
  10619. VM.  %@NL@%
  10620.  
  10621.  
  10622. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10623.  
  10624. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will
  10625. be passed back to procedure)  %@NL@%
  10626.  
  10627.  
  10628. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10629.  
  10630. %@AB@%ESI%@AE@% = Event handle (can be used to cancel event)  %@NL@%
  10631.  
  10632.  
  10633. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10634.  
  10635. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10636.  
  10637.  
  10638. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10639.  
  10640. %@AB@%EBX%@AE@% = Current VM handle (VM event was scheduled for) %@AB@%EDX%@AE@% = Reference data
  10641. %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  10642.  
  10643.  
  10644.  
  10645.  
  10646.  
  10647.  
  10648. %@CR:C6A00270001 @%%@1@%%@AB@%Chapter 27  Timing Services%@AE@%%@EH@%%@NL@%
  10649. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10650.  
  10651. Timing services are provided for use by VxDs that need to perform periodic
  10652. operations or need to establish the amount of time elapsed since a
  10653. particular event. They are described here in the following order:  %@NL@%
  10654.  
  10655.  
  10656.   ■   %@AB@%Cancel_Time_Out%@AE@%%@NL@%
  10657.  
  10658.   ■   %@AB@%Get_Last_Updated_System_Time%@AE@%%@NL@%
  10659.  
  10660.   ■   %@AB@%Get_Last_Updated_VM_Exec_Time%@AE@%%@NL@%
  10661.  
  10662.   ■   %@AB@%Get_System_Time%@AE@%%@NL@%
  10663.  
  10664.   ■   %@AB@%Get_VM_Exec_Time%@AE@%%@NL@%
  10665.  
  10666.   ■   %@AB@%Set_Global_Time_Out%@AE@%%@NL@%
  10667.  
  10668.   ■   %@AB@%Set_VM_Time_Out%@AE@%%@NL@%
  10669.  
  10670.   ■   %@AB@%Update_System_Clock%@AE@%%@NL@%
  10671.  
  10672.  
  10673. See Chapter 16, "Overview of Windows in Enhanced Mode," and Chapter 17,
  10674. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  10675.  
  10676. %@CR:C6A00270002 @%
  10677. %@2@%%@CR:C6A00270003 @%%@AB@%Cancel_Time_Out%@CR:C6A00270004 @%%@AE@%%@EH@%%@NL@%
  10678. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10679.  
  10680.  
  10681. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10682.  
  10683. This service is used to cancel a time-out that was scheduled through either
  10684. %@AB@%Set_VM_Time_Out%@AE@% or %@AB@%Set_Global_Time_Out%@AE@%.  %@NL@%
  10685.  
  10686. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10687. NOTE
  10688.  
  10689. %@AI@%It is valid to pass ESI = 0 to this service (it will do nothing). This is
  10690. %@AI@%provided so that code that uses this service can use 0 to indicate no
  10691. %@AI@%time-out scheduled and not have to perform a test every time it wants  to
  10692. %@AI@%cancel a time-out. For example:%@AE@%
  10693. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10694.  
  10695. %@AS@%  xor      esi, esi
  10696. %@AS@%    xchg     esi, [Local_Time_Out_Handle]
  10697. %@AS@%    call      Cancel_Time_Out %@AE@%
  10698.  
  10699. %@AI@%will always work even if no time-out was scheduled. %@AE@%
  10700.  
  10701. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10702.  
  10703. %@AB@%ESI%@AE@% = Time-out handle to cancel OR 0 if no time-out to be canceled  %@NL@%
  10704.  
  10705.  
  10706. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10707.  
  10708. Time-out is canceled, old time-out handle now invalid  %@NL@%
  10709.  
  10710.  
  10711. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10712.  
  10713. Flags  %@NL@%
  10714.  
  10715. %@CR:C6A00270005 @%%@CR:C6A00270006 @%
  10716. %@2@%%@CR:C6A00270007 @%%@AB@%Get_Last_Updated_System_Time%@AE@%%@EH@%%@NL@%
  10717. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10718.  
  10719. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10720. NOTE
  10721.  
  10722. %@AI@%The description for this service has been identified as out of date and the
  10723. %@AI@%updated information was unavailable for this release.%@AE@%
  10724. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10725.  
  10726. %@CR:C6A00270008 @%%@CR:C6A00270009 @%
  10727. %@2@%%@CR:C6A00270010 @%%@AB@%Get_Last_Updated_VM_Exec_Time%@AE@%%@EH@%%@NL@%
  10728. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10729.  
  10730. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10731. NOTE
  10732.  
  10733. %@AI@%The description for this service has been identified as out of date and the
  10734. %@AI@%updated information was unavailable for this release.%@AE@%
  10735. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10736.  
  10737. %@CR:C6A00270011 @%
  10738. %@2@%%@CR:C6A00270012 @%%@AB@%Get_System_Time%@CR:C6A00270013 @%%@AE@%%@EH@%%@NL@%
  10739. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10740.  
  10741.  
  10742. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10743.  
  10744. This service will return the time in milliseconds since the enhanced Windows
  10745. environment was started. There is no way to detect rollover of the clock
  10746. through this function but the clock will take 49.5 days to roll over.  %@NL@%
  10747.  
  10748. If you are concerned about rollover, you should schedule a time-out every 30
  10749. days.  %@NL@%
  10750.  
  10751.  
  10752. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10753.  
  10754. None  %@NL@%
  10755.  
  10756.  
  10757. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10758.  
  10759. %@AB@%EAX%@AE@% = Elapsed time in milliseconds since enhanced Windows was started  %@NL@%
  10760.  
  10761.  
  10762. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10763.  
  10764. %@AB@%EAX%@AE@%, Flags  %@NL@%
  10765.  
  10766. %@CR:C6A00270014 @%
  10767. %@2@%%@CR:C6A00270015 @%%@AB@%Get_VM_Exec_Time%@CR:C6A00270016 @%%@AE@%%@EH@%%@NL@%
  10768. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10769.  
  10770.  
  10771. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10772.  
  10773. This service returns the amount of time that a particular VM has executed.
  10774. Every VM starts with an %@AB@%Exec_Time%@AE@% of 0 when it is created, and the %@AB@%Exec_Time%@AE@%
  10775. is only increased when the VM is actually executed. Therefore, the value
  10776. returned does %@AI@%not%@AE@% reflect the length of time the VM has existed. Instead, it
  10777. indicates the amount of time that task has actually been the currently
  10778. running VM.  %@NL@%
  10779.  
  10780.  
  10781. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10782.  
  10783. None  %@NL@%
  10784.  
  10785.  
  10786. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10787.  
  10788. %@AB@%EAX %@AE@%= Amount of time in milliseconds that VM has executed  %@NL@%
  10789.  
  10790.  
  10791. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10792.  
  10793. %@AB@%EAX,%@AE@% Flags  %@NL@%
  10794.  
  10795. %@CR:C6A00270017 @%%@CR:C6A00270018 @%
  10796. %@2@%%@CR:C6A00270019 @%%@AB@%Set_Global_Time_Out%@AE@%%@EH@%%@NL@%
  10797. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10798.  
  10799.  
  10800. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10801.  
  10802. Schedules a time-out that will occur after %@AB@%EAX%@AE@% milliseconds have elapsed.  %@NL@%
  10803.  
  10804. The callback procedure will be called with %@AB@%ECX%@AE@% equal to the number of
  10805. milliseconds that have elapsed since the actual time-out occurred. Time-outs
  10806. are often delayed by 10 milliseconds or more since the normal system timer
  10807. runs at 20 milliseconds or slower. If you need more accurate time-outs, then
  10808. you must increase the timer interrupt frequency. See the VTD documentation
  10809. for more details on setting the timer interrupt period.  %@NL@%
  10810.  
  10811.  
  10812. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10813.  
  10814. %@AB@%EAX%@AE@% = Number of milliseconds to wait until time-out %@AB@%EDX%@AE@% = Reference data to
  10815. return to procedure %@AB@%ESI%@AE@% = Address of procedure to call when time-out occurs
  10816. %@NL@%
  10817.  
  10818.  
  10819. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10820.  
  10821. If time-out was NOT scheduled then  ESI = 0 (This is useful since 0 = NO
  10822. TIME-OUT SCHEDULED)  else  ESI = Time-out handle (used to cancel time-out)  %@NL@%
  10823.  
  10824.  
  10825. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10826.  
  10827. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10828.  
  10829.  
  10830. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10831.  
  10832. %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = Number of EXTRA milliseconds that have elapsed
  10833. %@AB@%EDX %@AE@%= Reference data %@AB@%EBP%@AE@% -> Client register structure Procedure may corrupt
  10834. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  10835.  
  10836. %@CR:C6A00270020 @%
  10837. %@2@%%@CR:C6A00270021 @%%@AB@%Set_VM_Time_Out%@CR:C6A00270022 @%%@AE@%%@EH@%%@NL@%
  10838. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10839.  
  10840.  
  10841. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10842.  
  10843. Schedules a time-out that will occur after a VM has executed for the
  10844. specified length of time. Notice that the time-out will occur after the VM
  10845. has run for %@AB@%EAX%@AE@% milliseconds. Therefore, if there is more that one VM
  10846. executing, it may take more than%@AB@% EAX%@AE@% milliseconds to occur.  %@NL@%
  10847.  
  10848. The callback procedure will be called with %@AB@%ECX%@AE@% equal to the number of
  10849. milliseconds that have elapsed since the actual time-out occurred. Time-outs
  10850. are often delayed by 10 milliseconds or more since the normal system timer
  10851. runs at 20 milliseconds or slower. If you need more accurate time-outs, then
  10852. you must increase the timer interrupt frequency. See the VTD documentation
  10853. for more details on setting the timer interrupt period.  %@NL@%
  10854.  
  10855.  
  10856. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10857.  
  10858. %@AB@%EAX%@AE@% = Number of milliseconds to wait until time-out %@AB@%EBX %@AE@%= VM handle %@AB@%EDX%@AE@% =
  10859. Reference data to return to procedure %@AB@%ESI%@AE@% = Address of procedure to call
  10860. when time-out occurs  %@NL@%
  10861.  
  10862.  
  10863. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10864.  
  10865. %@AS@%  If time-out was NOT scheduled then
  10866. %@AS@%      ESI = 0 (This is useful since 0 = NO TIME-OUT SCHEDULED) 
  10867. %@AS@%  else
  10868. %@AS@%      ESI = Time-out handle (used to cancel time-out)%@AE@%
  10869.  
  10870.  
  10871. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10872.  
  10873. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10874.  
  10875.  
  10876. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10877.  
  10878. %@AB@%EBX%@AE@% = Current VM handle (VM time-out was scheduled for) %@AB@%ECX%@AE@% = Number of
  10879. EXTRA milliseconds that have elapsed %@AB@%EDX %@AE@%= Reference data %@AB@%EBP%@AE@% -> Client
  10880. register structure Procedure may corrupt %@AB@%EAX%@AE@%, E%@AB@%BX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and
  10881. Flags.  %@NL@%
  10882.  
  10883. %@CR:C6A00270023 @%%@CR:C6A00270024 @%
  10884. %@2@%%@CR:C6A00270025 @%%@AB@%Update_System_Clock%@AE@%%@EH@%%@NL@%
  10885. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10886.  
  10887.  
  10888. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10889.  
  10890. This service must be called only by the Virtual Timer Device. If more than
  10891. one device calls this service, then the VMM timing services will not behave
  10892. correctly. The timer calls this procedure to update the current system time
  10893. and the current VM's execution time. The value passed in %@AB@%ECX%@AE@% is the number
  10894. of milliseconds that have elapsed since the last call to this service. In
  10895. other words, if the current system time is%@AI@% n%@AE@%, then, after a call to
  10896. %@AB@%Update_System_Clock,%@AE@% the current system time would be %@AI@%n%@AE@%+%@AB@%ECX%@AE@%.  %@NL@%
  10897.  
  10898. This service assumes interrupts are disabled!  %@NL@%
  10899.  
  10900.  
  10901. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10902.  
  10903. %@AB@%ECX%@AE@% = Elapsed time in milliseconds  %@NL@%
  10904.  
  10905.  
  10906. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10907.  
  10908. Flags  %@NL@%
  10909.  
  10910.  
  10911.  
  10912.  
  10913.  
  10914.  
  10915. %@CR:C6A00280001 @%%@1@%%@AB@%Chapter 28  Processor Fault and Interrupt Services%@AE@%%@EH@%%@NL@%
  10916. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10917.  
  10918. The discussion of services providing general support for processor faults
  10919. and interrupts are presented in the following order:  %@NL@%
  10920.  
  10921.  
  10922.   ■   %@AB@%Get_Fault_Hook_Addrs%@AE@%%@NL@%
  10923.  
  10924.   ■   %@AB@%Get_NMI_Handler_Addr%@AE@%%@NL@%
  10925.  
  10926.  
  10927. @lb1 = %@AB@%Hook_PM_Fault%@AE@%  %@NL@%
  10928.  
  10929.  
  10930.   ■   %@AB@%Hook_NMI_Event%@AE@%%@NL@%
  10931.  
  10932.  
  10933. @lb1 = %@AB@%Hook_V86_Fault  %@AE@%%@NL@%
  10934.  
  10935.  
  10936.   ■   %@AB@%Hook_V86_Page%@AE@%%@NL@%
  10937.  
  10938.  
  10939. @lb1 = %@AB@%Hook_VMM_Fault  %@AE@%%@NL@%
  10940.  
  10941.  
  10942.   ■   %@AB@%Set_NMI_Handler_Addr%@AE@%%@NL@%
  10943.  
  10944.  
  10945. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  10946. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  10947.  
  10948. %@CR:C6A00280002 @%
  10949. %@2@%%@CR:C6A00280003 @%%@AB@%Get_Fault_Hook_Addrs%@AE@%%@EH@%%@NL@%
  10950. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10951.  
  10952.  
  10953. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10954.  
  10955. Returns the address of the V86 mode, PM application, and VMM reenter fault
  10956. handlers for a specified fault. If the fault does not have a handler, then
  10957. this procedure will return 0. You cannot get the hook address for interrupt
  10958. 2 (NMI). You must use the %@AB@%Get/Set_NMI_Handler_Addr%@AE@% services to hook
  10959. interrupt 2.  %@NL@%
  10960.  
  10961.  
  10962. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10963.  
  10964. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  10965.  
  10966.  
  10967. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10968.  
  10969. If carry clear then  EDX = Address of V86 Mode App fault handler (0 if none
  10970. installed)  ESI = Address of Prot Mode App fault handler (0 if none
  10971. installed)  EDI = Address of VMM Re-enter fault handler (0 if none
  10972. installed)  else  ERROR: Invalid fault number  %@NL@%
  10973.  
  10974.  
  10975. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10976.  
  10977. Flags  %@NL@%
  10978.  
  10979. %@CR:C6A00280004 @%
  10980. %@2@%%@CR:C6A00280005 @%%@AB@%Get_NMI_Handler_Addr%@AE@%%@EH@%%@NL@%
  10981. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10982.  
  10983.  
  10984. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10985.  
  10986. If a VxD needs to hook the Non-Maskable Interrupt (NMI), it must first call
  10987. this service to get the current NMI handler address, save the address so the
  10988. current handler can be chained to it, and then set the new address.  %@NL@%
  10989.  
  10990. Notice that your NMI interrupt handler can only touch local data in the
  10991. device's VxD_LOCKED_DATA_SEG. It cannot touch memory in a VM handle, V86
  10992. memory, or any other memory. It also cannot call %@AI@%any%@AE@% services, %@AI@%including%@AE@%
  10993. services that can be called during normal hardware interrupts. Because an
  10994. NMI can occur at any time, it is difficult to do much of anything during
  10995. interrupt time that is guaranteed not to reenter a non-reentrant procedure
  10996. or affect a data structure.  %@NL@%
  10997.  
  10998. Most NMI handlers will want to have an NMI event handler. This handler is
  10999. similar to a normal event handler except that you only need to hook the NMI
  11000. event chain once instead of scheduling an event every time. Every NMI event
  11001. handler will be called every time an NMI occurs. Thus, most NMI interrupt
  11002. routines simply detect that the NMI is for them and set a variable that
  11003. their NMI event handler uses to perform some function. For example:  %@NL@%
  11004.  
  11005. %@AS@%  Initialization:
  11006. %@AS@%      VMMcall Get_NMI_Handler_Addr
  11007. %@AS@%      mov     [NMI_Chain_Addr], esi
  11008. %@AS@%      mov     esi, OFFSET32 My_NMI_Handler
  11009. %@AS@%      VMMcall Set_NMI_Handler_Addr
  11010. %@AS@%      mov     esi, OFFSET32 My_NMI_Event
  11011. %@AS@%      VMMcall Hook_NMI_Event
  11012. %@AS@%      clc
  11013. %@AS@%      ret%@AE@%
  11014.  
  11015. %@AS@%  My_NMI_Handler:
  11016. %@AS@%      in    al, My_Stat_Port
  11017. %@AS@%      test  al, My_Int_Mask
  11018. %@AS@%      jz    SHORT MNH_Exit
  11019. %@AS@%      inc   [NMI_From_Me]
  11020. %@AS@%  MNH_Chain:
  11021. %@AS@%      jmp   [NMI_Chain_Addr]%@AE@%
  11022.  
  11023. %@AS@%  My_NMI_Event:
  11024. %@AS@%      xor   al, al
  11025. %@AS@%      xchg  al, [NMI_From_Me]
  11026. %@AS@%      test  al, al
  11027. %@AS@%      jz    SHORT NME_Exit
  11028. %@AS@%   (Do something here ─ NMI from my device) 
  11029. %@AS@%  MNE_Exit:
  11030. %@AS@%      ret%@AE@%
  11031.  
  11032.  
  11033. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11034.  
  11035. None  %@NL@%
  11036.  
  11037.  
  11038. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11039.  
  11040. %@AB@%ESI%@AE@% = Offset of current NMI handler  %@NL@%
  11041.  
  11042.  
  11043. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11044.  
  11045. %@AB@%ESI%@AE@%, Flags  %@NL@%
  11046.  
  11047. %@CR:C6A00280006 @%
  11048. %@2@%%@CR:C6A00280007 @%%@AB@%Hook_NMI_Event%@AE@%%@EH@%%@NL@%
  11049. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11050.  
  11051.  
  11052. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11053.  
  11054. See the documentation mentioned earlier in this chapter on
  11055. %@AB@%Get_NMI_Handler_Addr%@AE@% for information on this service.  %@NL@%
  11056.  
  11057.  
  11058. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11059.  
  11060. %@AB@%ESI %@AE@%= Address of NMI event procedure  %@NL@%
  11061.  
  11062.  
  11063. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11064.  
  11065. None  %@NL@%
  11066.  
  11067.  
  11068. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11069.  
  11070. Flags  %@NL@%
  11071.  
  11072.  
  11073. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  11074.  
  11075. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  11076.  
  11077. Procedure may corrupt %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%  %@NL@%
  11078.  
  11079. %@CR:C6A00280008 @%%@CR:C6A00280009 @%%@CR:C6A00280010 @%
  11080. %@2@%%@CR:C6A00280011 @%%@AB@%Hook_V86_Fault, Hook_PM_Fault, Hook_VMM_Fault%@AE@%%@EH@%%@NL@%
  11081. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11082.  
  11083.  
  11084. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11085.  
  11086. These services replace the fault handler procedure address with the
  11087. procedure supplied. They will return the old fault handler's address or 0 to
  11088. indicate that there was no previous fault handler. If the value returned in
  11089. ESI is non-zero, then you may chain to the next handler with ALL REGISTERS
  11090. PRESERVED. Your handler can "eat" a fault without chaining by executing a
  11091. near return (not an IRET) and can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, and %@AB@%EDI%@AE@%.  %@NL@%
  11092.  
  11093. If you hook a fault during the %@AB@%Sys_Critical_Init%@AE@% phase of device
  11094. initialization, your fault handler will be "behind" any VMM fault handler.
  11095. If the VMM cannot properly handle a fault (for example, a General Protection
  11096. fault), then it will chain to the next handler. By hooking GP faults during
  11097. %@AB@%Sys_Critical_Init%@AE@% your VxD can intercept any GP fault that would otherwise
  11098. crash the current VM. Any hooks installed after %@AB@%Sys_Critical_Init%@AE@% will be
  11099. placed "in front of" the default VMM fault handlers. This allows devices to
  11100. examine faults before they are processed by the VMM.  %@NL@%
  11101.  
  11102. Note that the processor Non-Maskable Interrupt (NMI) must be hooked using
  11103. the %@AB@%Get/Set_NMI_Addr%@AE@% services (do not call Hook_xxx_Fault with %@AB@%EAX%@AE@% = 2).
  11104. Also, hardware interrupts should be hooked using the Virtual Programmable
  11105. Interrupt Controller Device (VPICD). A VxD should NOT attempt to circumvent
  11106. the VPICD using these services.  %@NL@%
  11107.  
  11108. For version 3.0 of enhanced Windows, the largest interrupt number available
  11109. is 4FH. Interrupts 00H-1FH are reserved by Intel for processor faults.
  11110. Interrupts 20H-2FH are reserved by enhanced Windows. Interrupts 50H-5FH are
  11111. used by the VPICD. Interrupts 40H and 41H are used by the debugger.
  11112. Interrupts 42H-4FH are free for use by VxDs.  %@NL@%
  11113.  
  11114.  
  11115. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11116.  
  11117. %@AB@%EAX%@AE@% = Interrupt number %@AB@%ESI%@AE@% = Procedure offset  %@NL@%
  11118.  
  11119.  
  11120. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11121.  
  11122. If carry clear then  %@AB@%ESI%@AE@% = Old procedure offset (0 if none) else  ERROR:
  11123. Invalid fault number in EAX  %@NL@%
  11124.  
  11125.  
  11126. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11127.  
  11128. %@AB@%ESI%@AE@%, Flags  %@NL@%
  11129.  
  11130.  
  11131. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  11132.  
  11133. Interrupts disabled %@AB@%EBX%@AE@% = Current VM handle If fault from V86 or PM app then
  11134. %@AB@%EBP%@AE@% -> Client_Register_Strucuture else  VMM reentered ─ Only asynchronous
  11135. services may be called.  %@AB@%EBP%@AE@% -> VMM re-entrant fault stack frame  %@NL@%
  11136.  
  11137. If your handler chains, then it must preserve %@AI@%all%@AE@% registers (even registers
  11138. %@AI@%not%@AE@% documented as entry conditions to this callback).  %@NL@%
  11139.  
  11140. %@CR:C6A00280012 @%
  11141. %@2@%%@CR:C6A00280013 @%%@AB@%Hook_V86_Page%@AE@%%@EH@%%@NL@%
  11142. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11143.  
  11144.  
  11145. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11146.  
  11147. This service allows VxDs to intercept page faults in portions of the V86
  11148. address space of every virtual machine. It is used by devices such as the
  11149. Virtual Display Device to detect when particular address ranges are
  11150. accessed.  %@NL@%
  11151.  
  11152. You must specify a page number and address of a callback routine to this
  11153. service. If it is installed successfully, your hook will be called every
  11154. time a page fault occurs in %@AI@%any%@AE@% VM on that page. See the memory manager
  11155. %@AB@%_Modify_Pages%@AE@% documentation in Chapter 19, "Memory Management Services," for
  11156. making hooked pages not present and for registering the ownership of pages.
  11157. %@NL@%
  11158.  
  11159. The callback routine is responsible for mapping memory at the location of
  11160. the page fault or crashing the VM. In unusual circumstances, it may be
  11161. appropriate to map a NULL page at the faulting address page. See the memory
  11162. manager documentation for details on mapping memory and mapping NULL pages.
  11163. %@NL@%
  11164.  
  11165. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11166. NOTE 
  11167.  
  11168. %@AI@%Do not rely on the contents of the %@AB@%CR2%@AE@%%@AI@% (page fault) register. Use the value
  11169. %@AI@%passed to your callback in %@AE@%%@AI@%%@AB@%EAX%@AE@%%@AE@%%@AI@%. %@AE@%%@AE@%
  11170. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11171.  
  11172.  
  11173. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11174.  
  11175. %@AB@%EAX%@AE@% = Page number (A0h - FFh) %@AB@%ESI = Address of trap routine  %@AE@%%@NL@%
  11176.  
  11177.  
  11178. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11179.  
  11180. If carry flag set then  ERROR: Invalid page number or page already hooked
  11181. else  Page hooked  %@NL@%
  11182.  
  11183.  
  11184. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11185.  
  11186. Procedure may corrupt %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  11187.  
  11188.  
  11189. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  11190.  
  11191. %@AB@%EAX%@AE@% = Faulting page number %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% does NOT point to the
  11192. client register structure.  %@NL@%
  11193.  
  11194. %@CR:C6A00280014 @%
  11195. %@2@%%@CR:C6A00280015 @%%@AB@%Set_NMI_Handler_Addr%@AE@%%@EH@%%@NL@%
  11196. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11197.  
  11198.  
  11199. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11200.  
  11201. See the documentation mentioned earlier in this chapter on
  11202. %@AB@%Get_NMI_Handler_Addr%@AE@% for information on this service.  %@NL@%
  11203.  
  11204.  
  11205. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11206.  
  11207. %@AB@%ESI%@AE@% = Offset of new NMI handler  %@NL@%
  11208.  
  11209.  
  11210. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11211.  
  11212. None  %@NL@%
  11213.  
  11214.  
  11215. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11216.  
  11217. Flags  %@NL@%
  11218.  
  11219.  
  11220.  
  11221.  
  11222.  
  11223.  
  11224. %@CR:C6A00290001 @%%@1@%%@AB@%Chapter 29  Information Services%@AE@%%@EH@%%@NL@%
  11225. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11226.  
  11227. These services return the requested information without instigating any
  11228. other action.  %@NL@%
  11229.  
  11230. They provide information on the following:  %@NL@%
  11231.  
  11232.  
  11233.   ■   VM handles%@NL@%
  11234.  
  11235.   ■   The VMM reenter count%@NL@%
  11236.  
  11237.   ■   HMA XMS%@NL@%
  11238.  
  11239.   ■   Installation status of the debugger%@NL@%
  11240.  
  11241.  
  11242. They are described here in the following order:  %@NL@%
  11243.  
  11244.  
  11245.   ■   %@AB@%Get_Cur_VM_Handle%@AE@%%@NL@%
  11246.  
  11247.   ■   %@AB@%Get_Next_VM_Handle%@AE@%%@NL@%
  11248.  
  11249.   ■   %@AB@%Get_Sys_VM_Handle%@AE@%%@NL@%
  11250.  
  11251.   ■   %@AB@%Get_VMM_Reenter_Count%@AE@%%@NL@%
  11252.  
  11253.   ■   %@AB@%Get_VMM_Version%@AE@%%@NL@%
  11254.  
  11255.   ■   %@AB@%GetSet_HMA_Info%@AE@%%@NL@%
  11256.  
  11257.   ■   %@AB@%Test_Cur_VM_Handle%@AE@%%@NL@%
  11258.  
  11259.   ■   %@AB@%Test_Debug_Installed%@AE@%%@NL@%
  11260.  
  11261.   ■   %@AB@%Test_Sys_VM_Handle%@AE@%%@NL@%
  11262.  
  11263.   ■   %@AB@%Validate_VM_Handle%@AE@%%@NL@%
  11264.  
  11265.  
  11266. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  11267. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  11268.  
  11269. %@CR:C6A00290002 @%%@CR:C6A00290003 @%
  11270. %@2@%%@CR:C6A00290004 @%%@AB@%Get_Cur_VM_Handle%@AE@%%@EH@%%@NL@%
  11271. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11272.  
  11273.  
  11274. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11275.  
  11276. This service returns the handle to the currently running VM. It is valid to
  11277. call this service at interrupt time.  %@NL@%
  11278.  
  11279.  
  11280. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11281.  
  11282. None  %@NL@%
  11283.  
  11284.  
  11285. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11286.  
  11287. %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  11288.  
  11289.  
  11290. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11291.  
  11292. %@AB@%EBX%@AE@%, Flags  %@NL@%
  11293.  
  11294. %@CR:C6A00290005 @%%@CR:C6A00290006 @%
  11295. %@2@%%@CR:C6A00290007 @%%@AB@%Get_Next_VM_Handle%@AE@%%@EH@%%@NL@%
  11296. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11297.  
  11298.  
  11299. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11300.  
  11301. VMM maintains a list of all valid VM handles. This service provides a means
  11302. of scanning the list easily. Normally, code that uses this service looks
  11303. something like this:  %@NL@%
  11304.  
  11305. %@AS@%  VMMcall Get_Cur_VM_Handle
  11306. %@AS@%   Scan_Loop:
  11307. %@AS@%   ...
  11308. %@AS@%   (Do something to VM state)
  11309. %@AS@%   ...
  11310. %@AS@%   VMMcall Get_Next_VM_Handle
  11311. %@AS@%   VMMcall  Test_Cur_VM_Handle
  11312. %@AS@%   jne Scan_Loop%@AE@%
  11313.  
  11314. This allows the state of every VM to be modified. However, there are also
  11315. other uses for this service. There is no guaranteed ordering of the list
  11316. other than the fact that each VM will appear in the list only once. Notice
  11317. also that the list is circular so you will need to test for the end case
  11318. (Next VM = First VM). It is valid to call this service at interrupt time.  %@NL@%
  11319.  
  11320.  
  11321. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11322.  
  11323. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  11324.  
  11325.  
  11326. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11327.  
  11328. %@AB@%EBX%@AE@% = Next VM handle in VM list  %@NL@%
  11329.  
  11330.  
  11331. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11332.  
  11333. %@AB@%EBX%@AE@%, Flags  %@NL@%
  11334.  
  11335. %@CR:C6A00290008 @%%@CR:C6A00290009 @%
  11336. %@2@%%@CR:C6A00290010 @%%@AB@%Get_Sys_VM_Handle%@AE@%%@EH@%%@NL@%
  11337. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11338.  
  11339.  
  11340. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11341.  
  11342. This service returns the System VM handle. It is valid to call this service
  11343. at interrupt time.  %@NL@%
  11344.  
  11345.  
  11346. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11347.  
  11348. None  %@NL@%
  11349.  
  11350.  
  11351. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11352.  
  11353. %@AB@%EBX%@AE@% = System VM handle  %@NL@%
  11354.  
  11355.  
  11356. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11357.  
  11358. %@AB@%EBX%@AE@%, Flags  %@NL@%
  11359.  
  11360. %@CR:C6A00290011 @%%@CR:C6A00290012 @%
  11361. %@2@%%@CR:C6A00290013 @%%@AB@%Get_VMM_Reenter_Count%@AE@%%@EH@%%@NL@%
  11362. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11363.  
  11364.  
  11365. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11366.  
  11367. This service is used to determine if the VMM has been reentered from an
  11368. interrupt. The normal situation for reentering VMM is from a hardware
  11369. interrupt, page fault, or other processor exception. Since most VMM services
  11370. are non-reentrant, this test should be used to determine if other VMM
  11371. services can be called or if a global event should be scheduled. Notice that
  11372. the %@AB@%Call_Global_Event%@AE@% service tests this condition automatically and will
  11373. schedule an event if VMM has been reentered.  %@NL@%
  11374.  
  11375.  
  11376. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11377.  
  11378. None  %@NL@%
  11379.  
  11380.  
  11381. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11382.  
  11383. %@AB@%ECX%@AE@% = 0 indicates VMM has NOT been re-entered. If  0 then %@AB@%ECX%@AE@% = # of times
  11384. re-entered  %@NL@%
  11385.  
  11386.  
  11387. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11388.  
  11389. Flags  %@NL@%
  11390.  
  11391. %@CR:C6A00290014 @%
  11392. %@2@%%@CR:C6A00290015 @%%@AB@%Get_VMM_Version%@CR:C6A00290016 @%%@AE@%%@EH@%%@NL@%
  11393. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11394.  
  11395.  
  11396. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11397.  
  11398. This service returns the Windows VMM version.  %@NL@%
  11399.  
  11400.  
  11401. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11402.  
  11403. None  %@NL@%
  11404.  
  11405.  
  11406. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11407.  
  11408. %@AB@%AH%@AE@% = Major version number (3) %@AB@%AL%@AE@% = Minor version number (0) Carry flag clear
  11409. %@NL@%
  11410.  
  11411.  
  11412. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11413.  
  11414. %@AB@%EAX%@AE@% , Flags  %@NL@%
  11415.  
  11416. %@CR:C6A00290017 @%
  11417. %@2@%%@CR:C6A00290018 @%%@AB@%GetSet_HMA_Info%@CR:C6A00290019 @%%@AE@%%@EH@%%@NL@%
  11418. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11419.  
  11420.  
  11421. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11422.  
  11423. This service returns and sets information related to the HMA XMS region.  %@NL@%
  11424.  
  11425. This service is intended to assist the XMS driver that is part of the
  11426. V86MMGR device. It allows the protected-mode XMS code to find out if there
  11427. was a global HMA user in before enhanced Windows was started and allows
  11428. access to the Enable count variable (Get and Set). This service is always
  11429. valid (i.e., not restricted to initialization).  %@NL@%
  11430.  
  11431.  
  11432. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11433.  
  11434. %@AB@%ECX%@AE@% == 0 Get %@AB@%ECX%@AE@%  0 Set  %@AB@%DX%@AE@% = A20 enable count to set for enhanced Windows
  11435. loader  NOTE THAT THE GLOBAL HMA FLAG CANNOT BE SET. It is not  appropriate
  11436. or valid to set this.  %@NL@%
  11437.  
  11438.  
  11439. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11440.  
  11441. If Get  %@AB@% EAX%@AE@% == 0 if enhanced Windows DID NOT allocate the HMA (GLOBAL HMA
  11442. User)  %@AB@% EAX%@AE@%  0 if enhanced Windows allocated the HMA (NO GLOBAL HMA User)
  11443. %@AB@%EDX%@AE@% = A20 enable count before enhanced Windows came in If Set  %@NL@%
  11444.  
  11445.  
  11446. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11447.  
  11448. %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11449.  
  11450. %@CR:C6A00290020 @%%@CR:C6A00290021 @%
  11451. %@2@%%@CR:C6A00290022 @%%@AB@%Test_Cur_VM_Handle%@AE@%%@EH@%%@NL@%
  11452. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11453.  
  11454.  
  11455. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11456.  
  11457. This routine tests to see if the given VM handle is the handle of the
  11458. currently running VM. It is valid to call this service at interrupt time.  %@NL@%
  11459.  
  11460.  
  11461. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11462.  
  11463. %@AB@%EBX%@AE@% = VM handle to test  %@NL@%
  11464.  
  11465.  
  11466. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11467.  
  11468. Zero flag is set if VM handle passed in is currently running VM's handle.  %@NL@%
  11469.  
  11470.  
  11471. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11472.  
  11473. Flags  %@NL@%
  11474.  
  11475. %@CR:C6A00290023 @%%@CR:C6A00290024 @%
  11476. %@2@%%@CR:C6A00290025 @%%@AB@%Test_Debug_Installed%@AE@%%@EH@%%@NL@%
  11477. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11478.  
  11479.  
  11480. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11481.  
  11482. Tests internal flag that indicates whether a debugger exists or not. It is
  11483. valid to call this service at interrupt time.  %@NL@%
  11484.  
  11485.  
  11486. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11487.  
  11488. None  %@NL@%
  11489.  
  11490.  
  11491. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11492.  
  11493. Zero flag = Debugger NOT installed (i.e., jz No_Debug_Installed)  %@NL@%
  11494.  
  11495.  
  11496. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11497.  
  11498. Flags  %@NL@%
  11499.  
  11500. %@CR:C6A00290026 @%%@CR:C6A00290027 @%
  11501. %@2@%%@CR:C6A00290028 @%%@AB@%Test_Sys_VM_Handle%@AE@%%@EH@%%@NL@%
  11502. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11503.  
  11504.  
  11505. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11506.  
  11507. This routine tests to see if the given VM handle is the handle of the system
  11508. VM. It is valid to call this service at interrupt time.  %@NL@%
  11509.  
  11510.  
  11511. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11512.  
  11513. %@AB@%EBX%@AE@% = VM handle to test  %@NL@%
  11514.  
  11515.  
  11516. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11517.  
  11518. Zero flag is set if VM handle passed in is system VM's handle. (je
  11519. %@AB@%Is_Sys_VM%@AE@%)  %@NL@%
  11520.  
  11521.  
  11522. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11523.  
  11524. Flags  %@NL@%
  11525.  
  11526. %@CR:C6A00290029 @%%@CR:C6A00290030 @%
  11527. %@2@%%@CR:C6A00290031 @%%@AB@%Validate_VM_Handle%@AE@%%@EH@%%@NL@%
  11528. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11529.  
  11530.  
  11531. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11532.  
  11533. This service is used to test the validity of a VM handle. This service can
  11534. be called at interrupt time.  %@NL@%
  11535.  
  11536.  
  11537. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11538.  
  11539. %@AB@%EBX%@AE@% = VM handle to test  %@NL@%
  11540.  
  11541.  
  11542. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11543.  
  11544. If carry flag set then    ERROR:VM handle is invalid else    Value in %@AB@%EBX%@AE@% is
  11545. a valid VM handle  %@NL@%
  11546.  
  11547.  
  11548. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11549.  
  11550. Flags  %@NL@%
  11551.  
  11552.  
  11553.  
  11554.  
  11555.  
  11556.  
  11557. %@CR:C6A00300001 @%%@1@%%@AB@%Chapter 30  Initialization Information Services%@AE@%%@EH@%%@NL@%
  11558. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11559.  
  11560. These services provide access to the SYSTEM.INI file and the environment
  11561. variables. Configurable VxDs will use these services to get their
  11562. configuration parameters. They are described here in the following order:  %@NL@%
  11563.  
  11564.  
  11565.   ■   %@AB@%Convert_Boolean_String%@AE@%%@NL@%
  11566.  
  11567.   ■   %@AB@%Convert_Decimal_String%@AE@%%@NL@%
  11568.  
  11569.   ■   %@AB@%Convert_Fixed_Point_String%@AE@%%@NL@%
  11570.  
  11571.   ■   %@AB@%Convert_Hex_String%@AE@%%@NL@%
  11572.  
  11573.   ■   %@AB@%Get_Config_Directory%@AE@%%@NL@%
  11574.  
  11575.   ■   %@AB@%GetDOSVectors%@AE@%%@NL@%
  11576.  
  11577.   ■   %@AB@%Get_Environment_String%@AE@%%@NL@%
  11578.  
  11579.   ■   %@AB@%Get_Exec_Path%@AE@%%@NL@%
  11580.  
  11581.   ■   %@AB@%Get_Machine_Info%@AE@%%@NL@%
  11582.  
  11583.   ■   %@AB@%Get_Next_Profile_String%@AE@%%@NL@%
  11584.  
  11585.   ■   %@AB@%Get_Profile_Boolean%@AE@%%@NL@%
  11586.  
  11587.   ■   %@AB@%Get_Profile_Decimal_Int%@AE@%%@NL@%
  11588.  
  11589.   ■   %@AB@%Get_Profile_Fixed_Point%@AE@%%@NL@%
  11590.  
  11591.   ■   %@AB@%Get_Profile_Hex_Int%@AE@%%@NL@%
  11592.  
  11593.   ■   %@AB@%Get_Profile_String%@AE@%%@NL@%
  11594.  
  11595.   ■   %@AB@%Get_PSP_Segment%@AE@%%@NL@%
  11596.  
  11597.   ■   %@AB@%OpenFile%@AE@%%@NL@%
  11598.  
  11599.  
  11600. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  11601. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  11602.  
  11603. %@CR:C6A00300002 @%%@CR:C6A00300003 @%
  11604. %@2@%%@CR:C6A00300004 @%%@AB@%Convert_Boolean_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11605. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11606.  
  11607.  
  11608. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11609.  
  11610. This service attempts to determine if the string pointed to by%@AB@% EDX%@AE@% is TRUE
  11611. or FALSE. There are many valid values for TRUE and FALSE. A short list of
  11612. valid values for TRUE are:  %@NL@%
  11613.  
  11614.  True, Yes, On, 1  %@NL@%
  11615.  
  11616. For false they include:  %@NL@%
  11617.  
  11618.  False, No, Off, 0  %@NL@%
  11619.  
  11620. This list may grow to include other words such as "oui" and "ja." This
  11621. service is only valid during initialization.  %@NL@%
  11622.  
  11623.  
  11624. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11625.  
  11626. %@AB@%EDX%@AE@% = Pointer to ASCIIZ string to convert to boolean  %@NL@%
  11627.  
  11628.  
  11629. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11630.  
  11631. If carry clear then  EAX = 0 if FALSE, -1 if TRUE, zero flag NOT set else
  11632. String was not a valid boolean (EAX not changed)  %@NL@%
  11633.  
  11634.  
  11635. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11636.  
  11637. Flags, %@AB@%EAX%@AE@%  %@NL@%
  11638.  
  11639. %@CR:C6A00300005 @%%@CR:C6A00300006 @%
  11640. %@2@%%@CR:C6A00300007 @%%@AB@%Convert_Decimal_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11641. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11642.  
  11643.  
  11644. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11645.  
  11646. This service converts a string that contains a decimal value and returns the
  11647. value in %@AB@%EAX%@AE@%. It also returns a pointer to the character that terminated the
  11648. decimal integer value. This is useful for parsing entries such as:  %@NL@%
  11649.  
  11650.  FOO=100,300  %@NL@%
  11651.  
  11652. since the 100 would be returned with %@AB@%EDX %@AE@%pointing to the ",". The pointer
  11653. could be incremented one byte and, then, this service called again to
  11654. evaluate the second number.  %@NL@%
  11655.  
  11656. Notice that a NULL string or a string that does not contain a valid decimal
  11657. integer will return 0 and %@AB@%EDX%@AE@% will not be advanced since the first character
  11658. of the string terminated the analysis. This service is only valid during
  11659. initialization.  %@NL@%
  11660.  
  11661.  
  11662. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11663.  
  11664. %@AB@%EDX %@AE@%= Pointer to ASCIIZ string to convert to integer  %@NL@%
  11665.  
  11666.  
  11667. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11668.  
  11669. %@AB@%EAX%@AE@% = Value of decimal string %@AB@%EDX%@AE@% = Pointer to terminating character
  11670. (non-valid decimal char)  %@NL@%
  11671.  
  11672.  
  11673. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11674.  
  11675. %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11676.  
  11677. %@CR:C6A00300008 @%%@CR:C6A00300009 @%
  11678. %@2@%%@CR:C6A00300010 @%%@AB@%Convert_Fixed_Point_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11679. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11680.  
  11681.  
  11682. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11683.  
  11684. This service returns the value of a fixed point decimal number string
  11685. pointed to by %@AB@%EDX.%@AE@% Use %@AB@%Get_Profile_String%@AE@% to initialize %@AB@%EDX%@AE@% to point to the
  11686. string to be parsed. Fixed Point is zero or more decimal digits followed by
  11687. a terminator or a decimal point followed by zero or more decimal digits. The
  11688. value returned is %@AB@%ECX%@AE@%*10*>. Note that decimal digits beyond the accuracy
  11689. specified by %@AB@%ECX%@AE@% are ignored in the value returned in %@AB@%EAX,%@AE@% but %@AB@%EDX%@AE@% points to
  11690. the byte following the last valid ASCII decimal digit. Values that begin
  11691. with a minus will evaluate to negative numbers. Positive values may
  11692. optionally begin with a plus sign.  %@NL@%
  11693.  
  11694. This service is only valid during initialization.  %@NL@%
  11695.  
  11696.  
  11697. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11698.  
  11699. %@AB@%ECX%@AE@% = Number of decimal places %@AB@%EDX%@AE@% = Pointer to ASCIIZ string to convert to
  11700. integer  %@NL@%
  11701.  
  11702.  
  11703. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11704.  
  11705. %@AB@%EAX%@AE@% = Value of fixed point string %@AB@%EDX%@AE@% = Pointer to terminating character
  11706. (non-valid character)  %@NL@%
  11707.  
  11708.  
  11709. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11710.  
  11711. %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11712.  
  11713. %@CR:C6A00300011 @%%@CR:C6A00300012 @%
  11714. %@2@%%@CR:C6A00300013 @%%@AB@%Convert_Hex_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11715. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11716.  
  11717.  
  11718. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11719.  
  11720. This service converts the string pointed to by %@AB@%EDX%@AE@% to Hexadecimal.
  11721. Hexadecimal is zero or more hexadecimal digits (0-9, A-F) followed by a
  11722. terminating character or a small or capital letter "h". The "h" has no
  11723. effect on the value. %@AB@%EDX%@AE@% is left pointing to the next byte after the "h" or,
  11724. if the "h" is not present, after the last valid hexadecimal digit. Use
  11725. %@AB@%Get_Profile_String%@AE@% to set up %@AB@%EDX%@AE@% to point to the string to be parsed. This
  11726. service is only valid during initialization.  %@NL@%
  11727.  
  11728.  
  11729. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11730.  
  11731. %@AB@%EDX%@AE@% -> ASCIIZ string to convert to integer  %@NL@%
  11732.  
  11733.  
  11734. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11735.  
  11736. %@AB@%EAX%@AE@% = Value of hexadecimal string %@AB@%EDX%@AE@% advanced to terminating character
  11737. (non-valid hex char)  %@NL@%
  11738.  
  11739.  
  11740. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11741.  
  11742. Flags  %@NL@%
  11743.  
  11744. %@CR:C6A00300014 @%%@CR:C6A00300015 @%
  11745. %@2@%%@CR:C6A00300016 @%%@AB@%Get_Config_Directory (Initialization only)%@AE@%%@EH@%%@NL@%
  11746. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11747.  
  11748.  
  11749. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11750.  
  11751. This service returns a pointer to the directory that contains the
  11752. configuration files for the enhanced Windows environment (such as
  11753. SYSTEM.INI). The string returned is guaranteed to be a valid, fully
  11754. qualified pathname that ends with a terminating "\" followed by a NULL (0)
  11755. byte.  %@NL@%
  11756.  
  11757.  
  11758. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11759.  
  11760. None  %@NL@%
  11761.  
  11762.  
  11763. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11764.  
  11765. %@AB@%EDX%@AE@% = Pointer to ASCIIZ directory name  %@NL@%
  11766.  
  11767.  
  11768. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11769.  
  11770. %@AB@%EDX%@AE@%, Flags  %@NL@%
  11771.  
  11772. %@CR:C6A00300017 @%%@CR:C6A00300018 @%
  11773. %@2@%%@CR:C6A00300019 @%%@AB@%Get_Environment_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11774. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11775.  
  11776.  
  11777. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11778.  
  11779. This service takes a pointer to an ASCIIZ string that is the name of an
  11780. environment variable and returns a pointer to an ASCIIZ string that is the
  11781. value of that environment variable. Environment variables are set using the
  11782. MS-DOS %@AB@%SET%@AE@% command and should be of the format "%@AB@%SET%@AE@% <%@AI@%variable
  11783. %@AS@%name%@AE@%>=<%@AI@%variable value%@AE@%>" with no intervening spaces between the variable
  11784. name, the equal sign, and the variable value. Environment strings are an
  11785. alternative way of setting parameters for virtual device drivers. In
  11786. general, these should be used sparingly, as the environment is of limited
  11787. size. Use environment strings only when the value is a global entity, used
  11788. by more than one program or device driver. This service is only valid during
  11789. initialization.  %@NL@%
  11790.  
  11791.  
  11792. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11793.  
  11794. %@AB@%ESI%@AE@% = pointer to ASCIIZ string environment variable name  %@NL@%
  11795.  
  11796.  
  11797. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11798.  
  11799. If carry is set then  Environment string was not found else  EDX = pointer
  11800. to ASCIIZ string value of environment variable  %@NL@%
  11801.  
  11802.  
  11803. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11804.  
  11805. %@AB@%EDX%@AE@%, Flags  %@NL@%
  11806.  
  11807. %@CR:C6A00300020 @%%@CR:C6A00300021 @%
  11808. %@2@%%@CR:C6A00300022 @%%@AB@%Get_Exec_Path (Initialization only)%@AE@%%@EH@%%@NL@%
  11809. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11810.  
  11811.  
  11812. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11813.  
  11814. This service returns a pointer to an ASCIIZ string that gives the full path
  11815. by which WIN386.EXE was executed. It is used to locate files associated with
  11816. the enhanced Windows environment or the virtual device drivers that are not
  11817. in subdirectories indicated by the PATH environment variable. This service
  11818. is only valid during initialization.  %@NL@%
  11819.  
  11820.  
  11821. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11822.  
  11823. None  %@NL@%
  11824.  
  11825.  
  11826. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11827.  
  11828. %@AB@%EDX%@AE@% = Pointer to ASCIIZ string of full path name + program name (program
  11829. name is  "WIN386.EXE") %@AB@%ECX%@AE@% = Number of characters in string up to and
  11830. including the last "\"  %@NL@%
  11831.  
  11832. %@CR:C6A00300023 @%
  11833. %@2@%%@CR:C6A00300024 @%%@AB@%GetDOSVectors (Initialization only)%@CR:C6A00300025 @%%@AE@%%@EH@%%@NL@%
  11834. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11835.  
  11836.  
  11837. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11838.  
  11839. This service returns the "true" INT 23 and INT 24 MS-DOS vectors. The
  11840. enhanced Windows loader points these vectors at its own handlers which have
  11841. the correct behavior for the enhanced Windows LOAD. When a VM is started up
  11842. we wish to reset these vectors to the handlers that were in place before the
  11843. loader changed them.  %@NL@%
  11844.  
  11845. THIS SERVICE SHOULD ONLY BE USED BY THE DOSMGR DEVICE.  %@NL@%
  11846.  
  11847.  
  11848. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11849.  
  11850.  
  11851. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11852.  
  11853. EAX = Segment:Offset (V86 address) that INT 23 pointed to before loader EDX
  11854. = Segment:Offset (V86 address) that INT 24 pointed to before loader  %@NL@%
  11855.  
  11856.  
  11857. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11858.  
  11859. %@CR:C6A00300026 @%%@CR:C6A00300027 @%
  11860. %@2@%%@CR:C6A00300028 @%%@AB@%Get_Machine_Info (Initialization only)%@AE@%%@EH@%%@NL@%
  11861. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11862.  
  11863.  
  11864. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11865.  
  11866. This service returns information about the computer system running enhanced
  11867. Windows.  %@NL@%
  11868.  
  11869.  
  11870. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11871.  
  11872. None  %@NL@%
  11873.  
  11874.  
  11875. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11876.  
  11877. %@AB@%AH%@AE@% = MS-DOS Major Version %@AB@%AL%@AE@%   = MS-DOS Minor Version %@AB@%BH%@AE@%   = MS-DOS OEM
  11878. serial number %@AB@%BL%@AE@%   = Machine Model Byte (at F000:FFFE in system ROM) HIGH 16
  11879. bits of %@AB@%EBX%@AE@% are other flags  GMIF_80486 EQU 10000h 80486 processor
  11880. GMIF_PCXT EQU 20000h PC/XT(tm) accelerator  GMIF_MCA EQU 40000h Micro
  11881. Channel(tm)  GMIF_EISA EQU 80000h EISA %@AB@%EDX%@AE@% = Equipment flags (as returned
  11882. from Int 11h) %@AB@%ECX%@AE@% = 0 if not PS/2 or extended BIOS, else %@AB@%ECX%@AE@% contains a
  11883. ring 0 linear address to System Configuration Parameters  returned from BIOS
  11884. service Int 15h, AH=C0h. See the PS/2  BIOS documentation for details on
  11885. this structure.  %@NL@%
  11886.  
  11887.  
  11888. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11889.  
  11890. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11891.  
  11892. %@CR:C6A00300029 @%%@CR:C6A00300030 @%
  11893. %@2@%%@CR:C6A00300031 @%%@AB@%Get_Next_Profile_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11894. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11895.  
  11896.  
  11897. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11898.  
  11899. This service, given a pointer to a profile string, will return a pointer to
  11900. the next profile string with the key name provided. It is used by devices
  11901. that have multiple entries with the same key name. First, use
  11902. %@AB@%Get_Profile_String%@AE@% to get the first entry with a given key name and, then,
  11903. use this service to get subsequent entries. Do not modify the string
  11904. returned. This service is only valid during initialization.  %@NL@%
  11905.  
  11906.  
  11907. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11908.  
  11909. %@AB@%EDX%@AE@% = Pointer returned from previous %@AB@%Get_(Next)_Profile_String %@AE@% %@AB@%EDI %@AE@%  =
  11910. Pointer to key name string  %@NL@%
  11911.  
  11912.  
  11913. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11914.  
  11915. If carry clear then  EDX = NEXT string from SYSTEM.INI else  No more
  11916. matching entries found  %@NL@%
  11917.  
  11918.  
  11919. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11920.  
  11921. %@AB@%EDX%@AE@%, Flags  %@NL@%
  11922.  
  11923. %@CR:C6A00300032 @%%@CR:C6A00300033 @%
  11924. %@2@%%@CR:C6A00300034 @%%@AB@%Get_Profile_Boolean (Initialization only)%@AE@%%@EH@%%@NL@%
  11925. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11926.  
  11927.  
  11928. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11929.  
  11930. This service returns the value of a Boolean profile entry from the
  11931. SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then %@AB@%EAX%@AE@% will
  11932. not be modified. Profile entries are of the form:  %@NL@%
  11933.  
  11934.  [SectionName]   KeyName=>  %@NL@%
  11935.  
  11936. That is, Section Name is delineated by square brackets and KeyName is
  11937. followed by an equal sign. Neither name should have any spaces or
  11938. nonprintable characters. The value following the equal sign can be in a
  11939. number of formats. Boolean is "Yes," "No," "Y," "N," "True," "False," "On,"
  11940. "Off," "1," or "0"(foreign versions of Windows may add other language
  11941. equivalents to the above). Logical TRUE returns -1 and logical FALSE returns
  11942. 0.  %@NL@%
  11943.  
  11944. This service is only valid during initialization.  %@NL@%
  11945.  
  11946.  
  11947. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11948.  
  11949. %@AB@%EAX %@AE@%= Default value %@AB@%ESI%@AE@% = Pointer to section name string or 0 for [386enh]
  11950. %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  11951.  
  11952.  
  11953. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11954.  
  11955. If carry set  Entry not found or invalid boolean value  EAX = Default value
  11956. else  If value string was null,  zero flag is set and  EAX = Default value
  11957. else  EAX = 0 if FALSE, -1 if TRUE SYSTEM.INI entry value  %@NL@%
  11958.  
  11959.  
  11960. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11961.  
  11962. Flags  %@NL@%
  11963.  
  11964. %@CR:C6A00300035 @%%@CR:C6A00300036 @%
  11965. %@2@%%@CR:C6A00300037 @%%@AB@%Get_Profile_Decimal_Int (Initialization only)%@AE@%%@EH@%%@NL@%
  11966. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11967.  
  11968.  
  11969. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11970.  
  11971. This service returns the value of a decimal profile entry from the
  11972. SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then %@AB@%EAX%@AE@% will
  11973. not be modified. Profile entries are of the form:  %@NL@%
  11974.  
  11975.  [SectionName]  KeyName=>  %@NL@%
  11976.  
  11977. That is, SectionName is delineated by square brackets and KeyName is
  11978. followed by an equal sign. Neither name should have any spaces or
  11979. non-printable characters. The value following the equal sign must be a
  11980. decimal value. It can begin optionally with a plus (+) or minus (-) and must
  11981. contain all decimal digits with no embedded spaces or decimal points.  %@NL@%
  11982.  
  11983. This service is only valid during initialization.  %@NL@%
  11984.  
  11985.  
  11986. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11987.  
  11988. %@AB@%EAX %@AE@%= Default value (optional) %@AB@%ESI %@AE@%= Pointer to section name string or 0 for
  11989. [386enh] %@AB@%EDI %@AE@%= Pointer to key name string  %@NL@%
  11990.  
  11991.  
  11992. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11993.  
  11994. If carry is set  Entry was NOT found  EAX = Default value (value passed to
  11995. this procedure) else  If value string was null, zero flag is set and  EAX =
  11996. Default value  else  EAX = Value of SYSTEM.INI entry  %@NL@%
  11997.  
  11998.  
  11999. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12000.  
  12001. Flags  %@NL@%
  12002.  
  12003. %@CR:C6A00300038 @%%@CR:C6A00300039 @%
  12004. %@2@%%@CR:C6A00300040 @%%@AB@%Get_Profile_Fixed_Point (Initialization only)%@AE@%%@EH@%%@NL@%
  12005. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12006.  
  12007.  
  12008. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12009.  
  12010. This service returns the value of a fixed point decimal number profile entry
  12011. from the SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then
  12012. %@AB@%EAX%@AE@% will not be modified. Profile entries are of the form:  %@NL@%
  12013.  
  12014.  [SectionName]  KeyName=>  %@NL@%
  12015.  
  12016. That is, SectionName is delineated by square brackets and KeyName is
  12017. followed by an equal sign. Neither name should have any spaces or
  12018. nonprintable characters. The value following the equal sign can be in a
  12019. number of formats. Fixed Point values may begin with an optional plus (+) or
  12020. minus (-) followed by zero or more decimal digits followed by a terminating
  12021. character or by a decimal point followed by zero or more decimal digits. The
  12022. value returned is 10^%@AB@%ECX%@AE@%*>.  %@NL@%
  12023.  
  12024. This service is only valid during initialization.  %@NL@%
  12025.  
  12026.  
  12027. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12028.  
  12029. %@AB@%EAX%@AE@% = Default value %@AB@%ECX%@AE@% = Number of decimal places %@AB@%ESI%@AE@% = Pointer to section
  12030. name string or 0 for [386enh] %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  12031.  
  12032.  
  12033. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12034.  
  12035. If carry is set  Entry was NOT found  EAX = Default value (value passed to
  12036. this procedure) else  If value string was null, zero flag is set and  EAX =
  12037. Default value else  EAX = Value of SYSTEM.INI entry  %@NL@%
  12038.  
  12039. %@CR:C6A00300041 @%%@CR:C6A00300042 @%
  12040. %@2@%%@CR:C6A00300043 @%%@AB@%Get_Profile_Hex_Int (Initialization only)%@AE@%%@EH@%%@NL@%
  12041. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12042.  
  12043.  
  12044. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12045.  
  12046. This service returns the value of a hexadecimal number profile entry from
  12047. the SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then %@AB@%EAX%@AE@%
  12048. will not be modified. Profile entries are of the form:  %@NL@%
  12049.  
  12050.  [SectionName]  KeyName=>  %@NL@%
  12051.  
  12052. That is, SectionName is delineated by square brackets and KeyName is
  12053. followed by an equal sign. Neither name should have any spaces or
  12054. nonprintable characters. The value following the equal sign can be in a
  12055. number of formats. Hexadecimal is zero or more hexadecimal digits (0-9, A-F)
  12056. followed by a terminating character or a small or capital letter "h." The
  12057. "h" has no effect on the value. If the value following the equal sign is not
  12058. a valid hexadecimal number, %@AB@%EAX%@AE@% is unchanged.  %@NL@%
  12059.  
  12060. This service is only valid during initialization.  %@NL@%
  12061.  
  12062.  
  12063. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12064.  
  12065. %@AB@%EAX%@AE@% = Default value (optional) %@AB@%ESI%@AE@% = Pointer to section name string or 0 for
  12066. [386enh] %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  12067.  
  12068.  
  12069. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12070.  
  12071. If carry is set  Entry was NOT found  EAX = Default value (value passed to
  12072. this procedure) else  If value string was null  zero flag is set  EAX =
  12073. Default value  else  EAX = Value of SYSTEM.INI entry  %@NL@%
  12074.  
  12075.  
  12076. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12077.  
  12078. Flags  %@NL@%
  12079.  
  12080. %@CR:C6A00300044 @%%@CR:C6A00300045 @%
  12081. %@2@%%@CR:C6A00300046 @%%@AB@%Get_Profile_String (Initialization only)%@AE@%%@EH@%%@NL@%
  12082. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12083.  
  12084.  
  12085. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12086.  
  12087. This service searches the initialization file for a specified entry and
  12088. returns a pointer to a string. Do %@AI@%not%@AE@% modify the string in place. The
  12089. pointer returned points into the initialization file data area. If you need
  12090. to modify the string, you must first copy it and, then, modify it. This
  12091. service is only valid during initialization.  %@NL@%
  12092.  
  12093.  
  12094. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12095.  
  12096. %@AB@%EDX%@AE@% = Pointer to default string (optional) %@AB@%ESI%@AE@% = Pointer to program name
  12097. string or 0 for [386enh] %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  12098.  
  12099.  
  12100. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12101.  
  12102. If carry clear  EDX = Pointer to ASCIIZ string from SYSTEM.INI else  EDX is
  12103. unchanged  %@NL@%
  12104.  
  12105.  
  12106. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12107.  
  12108. Flags, may change %@AB@%EDX%@AE@%  %@NL@%
  12109.  
  12110. %@CR:C6A00300047 @%%@CR:C6A00300048 @%
  12111. %@2@%%@CR:C6A00300049 @%%@AB@%Get_PSP_Segment (Initialization only)%@AE@%%@EH@%%@NL@%
  12112. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12113.  
  12114.  
  12115. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12116.  
  12117. This service returns the segment of the WIN386.EXE PSP. Use it to locate PSP
  12118. values other than the EXEC path and environment variables since separate
  12119. services are available for retrieving those ASCIIZ strings. Notice that a
  12120. segment value is returned. To convert the segment to an address, shift the
  12121. value left by 4 bits. This service is only valid during initialization.  %@NL@%
  12122.  
  12123.  
  12124. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12125.  
  12126. None  %@NL@%
  12127.  
  12128.  
  12129. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12130.  
  12131. %@AB@%EAX %@AE@%= Segment of WIN386.EXE PSP (high word always = 0)  %@NL@%
  12132.  
  12133.  
  12134. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12135.  
  12136. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12137.  
  12138. %@CR:C6A00300050 @%
  12139. %@2@%%@CR:C6A00300051 @%%@AB@%OpenFile (Initialization only)%@CR:C6A00300052 @%%@AE@%%@EH@%%@NL@%
  12140. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12141.  
  12142.  
  12143. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12144.  
  12145. Open a file via searching in the standard Windows Places:  %@NL@%
  12146.  
  12147. WINDIR= ARGV[0] Current Working Directory Path  %@NL@%
  12148.  
  12149.  
  12150. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12151.  
  12152. EDX -> Name to open. If this string contains a drive letter or  path seps
  12153. this routine does not search. Else the above search  strategy is employed.
  12154. EDI -> Buffer to hold name of file opened (at least 128 bytes)  Notice that
  12155. this buffer should contain a correctly formed path  for the file but this is
  12156. not guarenteed. This aspect of the behavior is dependent on the WINDIR and
  12157. PATH environment  variables being well formed.  %@NL@%
  12158.  
  12159. Must be able to do Exec_Int activity in the current VM. Temp_V86_Data_Area
  12160. must not be allocated.  %@NL@%
  12161.  
  12162.  
  12163. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12164.  
  12165. Carry Set  File could not be opened (file not found) Carry Clear  EAX = DOS
  12166. File handle (low 16 bits) OPEN IN MODE 0 (for read only)  %@NL@%
  12167.  
  12168.  
  12169. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12170.  
  12171. EAX, FLAGS  %@NL@%
  12172.  
  12173.  
  12174.  
  12175.  
  12176.  
  12177.  
  12178. %@CR:C6A00310001 @%%@1@%%@AB@%Chapter 31  Linked List Services%@AE@%%@EH@%%@NL@%
  12179. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12180.  
  12181. These services provide a convenient set of routines for managing a
  12182. linked-list data structure. They are described here in the following order:
  12183. %@NL@%
  12184.  
  12185.  
  12186.   ■   %@AB@%List_Allocate%@AE@%%@NL@%
  12187.  
  12188.   ■   %@AB@%List_Attach%@AE@%%@NL@%
  12189.  
  12190.   ■   %@AB@%List_Attach_Tail%@AE@%%@NL@%
  12191.  
  12192.   ■   %@AB@%List_Create%@AE@%%@NL@%
  12193.  
  12194.   ■   %@AB@%List_Deallocate%@AE@%%@NL@%
  12195.  
  12196.   ■   %@AB@%List_Destroy%@AE@%%@NL@%
  12197.  
  12198.   ■   %@AB@%List_Get_First%@AE@%%@NL@%
  12199.  
  12200.   ■   %@AB@%List_Get_Next%@AE@%%@NL@%
  12201.  
  12202.   ■   %@AB@%List_Insert%@AE@%%@NL@%
  12203.  
  12204.   ■   %@AB@%List_Remove%@AE@%%@NL@%
  12205.  
  12206.   ■   %@AB@%List_Remove_First%@AE@%%@NL@%
  12207.  
  12208.  
  12209. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  12210. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  12211.  
  12212. %@CR:C6A00310002 @%
  12213. %@2@%%@CR:C6A00310003 @%%@AB@%List_Allocate%@CR:C6A00310004 @%%@AE@%%@EH@%%@NL@%
  12214. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12215.  
  12216.  
  12217. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12218.  
  12219. This service allocates a new node for the list specified by %@AB@%ESI%@AE@%. The
  12220. contents of the node are undefined (probably nonzero). Normally, a node is
  12221. immediately attached to the list through the %@AB@%List_Attach%@AE@% or %@AB@%List_Insert%@AE@%
  12222. services after it has been allocated.  %@NL@%
  12223.  
  12224.  
  12225. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12226.  
  12227. %@AB@%ESI%@AE@% = List handle  %@NL@%
  12228.  
  12229.  
  12230. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12231.  
  12232. If list was created with LF_Alloc_Error flag then  If carry clear then  EAX
  12233. -> New node  else  Error:Could not allocate node else  EAX -> New node
  12234. (Current VM crashed if node can not be allocated ─ Service  never returns to
  12235. caller)  %@NL@%
  12236.  
  12237.  
  12238. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12239.  
  12240. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12241.  
  12242. %@CR:C6A00310005 @%
  12243. %@2@%%@CR:C6A00310006 @%%@AB@%List_Attach%@CR:C6A00310007 @%%@AE@%%@EH@%%@NL@%
  12244. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12245.  
  12246.  
  12247. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12248.  
  12249. This service attaches a list node to the head (i.e., front) of a list.
  12250. Notice that %@AB@%EAX%@AE@% must point to a node that was allocated using %@AB@%List_Allocate%@AE@%.
  12251. %@NL@%
  12252.  
  12253. Nodes can be attached to any list that has the same size node. This can be
  12254. used, for example, to move a node from one list to another.  %@NL@%
  12255.  
  12256. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12257.  
  12258.  
  12259. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12260.  
  12261. %@AB@%ESI%@AE@% = List handle %@AB@%EAX %@AE@%-> Node  %@NL@%
  12262.  
  12263.  
  12264. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12265.  
  12266. Node attached to list  %@NL@%
  12267.  
  12268.  
  12269. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12270.  
  12271. Flags  %@NL@%
  12272.  
  12273. %@CR:C6A00310008 @%%@CR:C6A00310009 @%
  12274. %@2@%%@CR:C6A00310010 @%%@AB@%List_Attach_Tail%@AE@%%@EH@%%@NL@%
  12275. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12276.  
  12277.  
  12278. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12279.  
  12280. This service attaches a list node to the tail (i.e., end) of a list. %@AB@%EAX%@AE@%
  12281. must point to a node that was allocated using %@AB@%List_Allocate%@AE@%.  %@NL@%
  12282.  
  12283. Nodes can be attached to any list that has the same size node. This can be
  12284. used, for example, to move a node from one list to another.  %@NL@%
  12285.  
  12286. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12287.  
  12288.  
  12289. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12290.  
  12291. %@AB@%ESI%@AE@% = List handle %@AB@%EAX %@AE@%-> Node to insert  %@NL@%
  12292.  
  12293.  
  12294. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12295.  
  12296. Node inserted at tail (end) of list  %@NL@%
  12297.  
  12298.  
  12299. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12300.  
  12301. Flags  %@NL@%
  12302.  
  12303. %@CR:C6A00310011 @%
  12304. %@2@%%@CR:C6A00310012 @%%@AB@%List_Create%@CR:C6A00310013 @%%@AE@%%@EH@%%@NL@%
  12305. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12306.  
  12307.  
  12308. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12309.  
  12310. This service is used to create a new list structure. This service returns a
  12311. list handle that is used when calling all subsequent list services.  %@NL@%
  12312.  
  12313. Lists normally allocate nodes from a "pool" of free nodes. This prevents the
  12314. overhead that would be incurred by calling %@AB@%_HeapAlloc%@AE@% and%@AB@% _HeapFree%@AE@% for
  12315. every list allocation and deallocation. Once a node is created, it is never
  12316. destroyed. Instead, %@AB@%List_Deallocate%@AE@% places the node back in the free pool.
  12317. The node can then be reclaimed quickly when %@AB@%List_Allocate%@AE@% is called.  %@NL@%
  12318.  
  12319. If the size of the list nodes are large, you should force them to be
  12320. allocated from the system heap by setting the %@AB@%LF_Use_Heap%@AE@% flag. All
  12321. allocate/deallocate calls for lists created in this way will use %@AB@%_HeapAlloc%@AE@%
  12322. and %@AB@%_HeapFree%@AE@% to create and destroy nodes.  %@NL@%
  12323.  
  12324. If you want to be able to access a list during hardware interrupts, you
  12325. should set the %@AB@%LF_Async%@AE@% flag. This forces list operations to be atomic
  12326. operations (they cannot be re-entered). If you select this option, you must
  12327. call list services with %@AI@%INTERRUPTS DISABLED%@AE@% or an error will occur. You must
  12328. disable interrupts even if you are not calling the list service from an
  12329. interrupt. Remember, always use %@AB@%pushf/CLI/popf%@AE@% to disable interrupts. Never
  12330. explicitly use STI unless other documentation states that this is
  12331. permissable. Notice that since %@AB@%_HeapAllocate%@AE@% and %@AB@%_HeapFree%@AE@% cannot be called
  12332. from a hardware interrupt, you cannot select this option and %@AB@%LF_Use_Heap%@AE@%.  %@NL@%
  12333.  
  12334. The%@AB@% LF_Alloc_Error%@AE@% flag should be used if you would like to recover from an
  12335. allocation error (i.e., out of memory). The default behavior for a failed
  12336. allocation is to crash the current VM. However, if your VxD would like to
  12337. have the allocation return an error, set this flag. If this option is
  12338. selected, then %@AB@%List_Allocate%@AE@% will return with the Carry flag set when an
  12339. allocation fails. Otherwise, it will crash the current virtual machine
  12340. whenever it cannot allocate a new node.  %@NL@%
  12341.  
  12342.  
  12343. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12344.  
  12345. %@AB@%EAX%@AE@% = Flags  LF_Use_Heap - All data on system heap (Can't use with LF_Async)
  12346. LF_Async - List services can be called at interrupt time  LF_Alloc_Error -
  12347. Return from alloc with carry set if can't allocate  %@AB@%ECX%@AE@% = Node size  %@NL@%
  12348.  
  12349.  
  12350. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12351.  
  12352. If Carry Flag is clear then  ESI = List handle else  Error: Unable to create
  12353. list  %@NL@%
  12354.  
  12355.  
  12356. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12357.  
  12358. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12359.  
  12360. %@CR:C6A00310014 @%
  12361. %@2@%%@CR:C6A00310015 @%%@AB@%List_Deallocate%@CR:C6A00310016 @%%@AE@%%@EH@%%@NL@%
  12362. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12363.  
  12364.  
  12365. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12366.  
  12367. This service places a list node in the free memory pool. Once a node has
  12368. been deallocated, it should not be referenced again. You must remove the
  12369. node from any list to which it is attached before deallocating it.  %@NL@%
  12370.  
  12371.  
  12372. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12373.  
  12374. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> List node  %@NL@%
  12375.  
  12376.  
  12377. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12378.  
  12379. %@AB@%EAX%@AE@% is undefined  %@NL@%
  12380.  
  12381.  
  12382. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12383.  
  12384. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12385.  
  12386. %@CR:C6A00310017 @%
  12387. %@2@%%@CR:C6A00310018 @%%@AB@%List_Destroy%@CR:C6A00310019 @%%@AE@%%@EH@%%@NL@%
  12388. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12389.  
  12390.  
  12391. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12392.  
  12393. This service deallocates all nodes on a list and destroys the list handle.
  12394. Once a list has been destroyed, its handle is no longer valid.  %@NL@%
  12395.  
  12396.  
  12397. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12398.  
  12399. %@AB@%ESI%@AE@% = List handle  %@NL@%
  12400.  
  12401.  
  12402. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12403.  
  12404. %@AB@%ESI %@AE@%is undefined List is destroyed, all nodes deallocated.  %@NL@%
  12405.  
  12406.  
  12407. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12408.  
  12409. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12410.  
  12411. %@CR:C6A00310020 @%
  12412. %@2@%%@CR:C6A00310021 @%%@AB@%List_Get_First%@CR:C6A00310022 @%%@AE@%%@EH@%%@NL@%
  12413. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12414.  
  12415.  
  12416. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12417.  
  12418. This service returns a pointer to the first node in a list. If the list is
  12419. empty, it will return 0 and the Zero Flag will be set.  %@NL@%
  12420.  
  12421.  
  12422. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12423.  
  12424. %@AB@%ESI%@AE@% = List handle  %@NL@%
  12425.  
  12426.  
  12427. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12428.  
  12429. %@AS@%  If ZF is clear then
  12430. %@AS@%      EAX -> First node in list 
  12431. %@AS@%  else
  12432. %@AS@%      List is empty. EAX = 0.%@AE@%
  12433.  
  12434.  
  12435. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12436.  
  12437. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12438.  
  12439. %@CR:C6A00310023 @%
  12440. %@2@%%@CR:C6A00310024 @%%@AB@%List_Get_Next%@CR:C6A00310025 @%%@AE@%%@EH@%%@NL@%
  12441. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12442.  
  12443.  
  12444. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12445.  
  12446. This service returns the next node in a list. It is used to traverse the
  12447. list when searching for a specific element. If the end of the list is
  12448. reached, it will return 0 and the Zero Flag will be set.  %@NL@%
  12449.  
  12450. Typically, this service is used in conjunction with %@AB@%List_Get_First%@AE@% to scan
  12451. an entire list.  %@NL@%
  12452.  
  12453. %@AS@%  EXAMPLE:
  12454. %@AS@%    BeginProc Scan_My_List
  12455. %@AS@%    mov  esi, [My_List_Handle]
  12456. %@AS@%    VMMcall List_Get_First
  12457. %@AS@%    jz  SHORT Scan_Done 
  12458. %@AS@%    Scan_Loop:
  12459. %@AS@%    (Do something with EAX here)
  12460. %@AS@%    VMMcall List_Get_Next
  12461. %@AS@%    jnz  Scan_Loop 
  12462. %@AS@%    Scan_Done:
  12463. %@AS@%    ret 
  12464. %@AS@%    EndProc Scan_My_List%@AE@%
  12465.  
  12466.  
  12467. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12468.  
  12469. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> Node  %@NL@%
  12470.  
  12471.  
  12472. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12473.  
  12474. If ZF is clear then  %@AB@%EAX%@AE@% -> Next node in list else  End of list reached. %@AB@%EAX%@AE@%
  12475. = 0.  %@NL@%
  12476.  
  12477.  
  12478. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12479.  
  12480. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12481.  
  12482. %@CR:C6A00310026 @%
  12483. %@2@%%@CR:C6A00310027 @%%@AB@%List_Insert%@CR:C6A00310028 @%%@AE@%%@EH@%%@NL@%
  12484. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12485.  
  12486.  
  12487. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12488.  
  12489. This service inserts a node at a specified point in a list. The caller must
  12490. specify two nodes: the node to be inserted in %@AB@%EAX%@AE@%, and a position to insert
  12491. the node %@AI@%after%@AE@% in %@AB@%ECX%@AE@%. This means that node %@AB@%EAX%@AE@% will occupy the position in
  12492. the list immediately after node %@AB@%ECX%@AE@%. If %@AB@%ECX%@AE@% is zero, then node %@AB@%EAX%@AE@% will be
  12493. inserted at the head of the list.  %@NL@%
  12494.  
  12495. Nodes can be inserted in any list that has the same size node. This can be
  12496. used, for example, to move a node from one list to another.  %@NL@%
  12497.  
  12498. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12499.  
  12500.  
  12501. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12502.  
  12503. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> Node to insert %@AB@%ECX%@AE@% -> Node to insert after (0 to
  12504. attach to head)  %@NL@%
  12505.  
  12506.  
  12507. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12508.  
  12509. Node inserted in list  %@NL@%
  12510.  
  12511.  
  12512. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12513.  
  12514. Flags  %@NL@%
  12515.  
  12516. %@CR:C6A00310029 @%
  12517. %@2@%%@CR:C6A00310030 @%%@AB@%List_Remove%@CR:C6A00310031 @%%@AE@%%@EH@%%@NL@%
  12518. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12519.  
  12520.  
  12521. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12522.  
  12523. This service removes a specified node from a list.The node will %@AI@%not%@AE@% be
  12524. deallocated by this service. It is up to the caller to deallocate the node
  12525. or attach it to another list (it can only be attached to a list with node
  12526. size equal to the original list).  %@NL@%
  12527.  
  12528. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12529.  
  12530.  
  12531. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12532.  
  12533. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> Node to remove from list  %@NL@%
  12534.  
  12535.  
  12536. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12537.  
  12538. Node removed from list  %@NL@%
  12539.  
  12540.  
  12541. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12542.  
  12543. Flags  %@NL@%
  12544.  
  12545. %@CR:C6A00310032 @%%@CR:C6A00310033 @%
  12546. %@2@%%@CR:C6A00310034 @%%@AB@%List_Remove_First%@AE@%%@EH@%%@NL@%
  12547. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12548.  
  12549.  
  12550. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12551.  
  12552. This service removes the first node from a list. Notice that the node is %@AI@%not%@AE@%
  12553. deallocated by this service. It is up to the caller to deallocate the node
  12554. or attach it to another list (it can only be attached to a list with node
  12555. size equal to the original list).  %@NL@%
  12556.  
  12557. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12558.  
  12559.  
  12560. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12561.  
  12562. %@AB@%ESI %@AE@%= List handle  %@NL@%
  12563.  
  12564.  
  12565. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12566.  
  12567. If Zero Flag is clear then  EAX -> Node that has been removed from list else
  12568. List is empty and EAX = 0  %@NL@%
  12569.  
  12570.  
  12571. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12572.  
  12573. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12574.  
  12575.  
  12576.  
  12577.  
  12578.  
  12579.  
  12580. %@CR:C6A00320001 @%%@1@%%@AB@%Chapter 32  Error Condition Services%@AE@%%@EH@%%@NL@%
  12581. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12582.  
  12583. These error services are used by VxDs when they have detected the VM to be
  12584. in an unrecoverable state. Examples of situations that might lead to such a
  12585. state include an attempted VM execution of a protected instruction or an
  12586. operation which might fail due to lack of memory. The services are described
  12587. here in the following order:  %@NL@%
  12588.  
  12589.  
  12590.   ■   %@AB@%Crash_Cur_VM%@AE@%%@NL@%
  12591.  
  12592.   ■   %@AB@%Fatal_Error_Handler%@AE@%%@NL@%
  12593.  
  12594.   ■   %@AB@%Fatal_Memory_Error%@AE@%%@NL@%
  12595.  
  12596.  
  12597. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  12598. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  12599.  
  12600. %@CR:C6A00320002 @%
  12601. %@2@%%@CR:C6A00320003 @%%@AB@%Crash_Cur_VM%@CR:C6A00320004 @%%@AE@%%@EH@%%@NL@%
  12602. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12603.  
  12604.  
  12605. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12606.  
  12607. This service will crash the current VM. It is to be called when a
  12608. catastrophic error has occured in the VM, such as executing an illegal
  12609. instruction or attempting to program a piece of hardware in a way
  12610. incompatible with the device virtualization.  %@NL@%
  12611.  
  12612. If the system VM is the current VM, enhanced Windows will exit with a fatal
  12613. error without explicitly crashing the other VMs.  %@NL@%
  12614.  
  12615.  
  12616. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12617.  
  12618. None  %@NL@%
  12619.  
  12620.  
  12621. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12622.  
  12623. None  %@NL@%
  12624.  
  12625. %@CR:C6A00320005 @%%@CR:C6A00320006 @%
  12626. %@2@%%@CR:C6A00320007 @%%@AB@%Fatal_Error_Handler%@AE@%%@EH@%%@NL@%
  12627. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12628.  
  12629.  
  12630. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12631.  
  12632. This service is called (or jumped to) when a fatal error is detected. It
  12633. returns to real mode and, optionally, prints out an error message. You can
  12634. hang the computer by selecting the "EF_Hang_On_Exit" flag (defined in
  12635. VMM.INC). All of the devices that have been initialized are informed about
  12636. the exit before returning to real mode.  %@NL@%
  12637.  
  12638. The "Fatal_Error" macro supplied in VMM.INC is a convienient way of calling
  12639. this service. Examples:  %@NL@%
  12640.  
  12641. %@AS@%  Fatal_Error                     ; 
  12642. %@AS@%  This exits with no error message
  12643. %@AS@%  Fatal_Error OFFSET32 My_Err_Msg ; 
  12644. %@AS@%  Exits and prints error message%@AE@%
  12645.  
  12646. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12647. NOTE
  12648.  
  12649. %@AI@%Since this routine can be called by _InitializeMemoryManager, no assumptions
  12650. %@AI@%about the contents of any registers or data structures should be made.%@AE@%
  12651. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12652.  
  12653.  
  12654. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12655.  
  12656. ESI = Ptr ASCIIZ string to display (0 if none) EAX = Exit flags to send to
  12657. the loader (real mode exit code)  Bit 0 = 1 - Hang system on exit to real
  12658. mode  Others undefined and must be 0  %@NL@%
  12659.  
  12660.  
  12661. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12662.  
  12663. Does not return  %@NL@%
  12664.  
  12665.  
  12666. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12667.  
  12668. All registers  %@NL@%
  12669.  
  12670. %@CR:C6A00320008 @%%@CR:C6A00320009 @%
  12671. %@2@%%@CR:C6A00320010 @%%@AB@%Fatal_Memory_Error%@AE@%%@EH@%%@NL@%
  12672. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12673.  
  12674.  
  12675. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12676.  
  12677. This routine calls the Fatal_Error_Handler with exit flags equal to zero and
  12678. the message "Insufficient Memory to Initialize Windows in 386 enhanced
  12679. mode." It should be called during intialization if there is not enough
  12680. memory to initialize.  %@NL@%
  12681.  
  12682. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12683. NOTE
  12684.  
  12685. %@AI@%Since this routine can be called by _InitializeMemoryManager, no assumptions
  12686. %@AI@%about the contents of any registers or data structures should be made.%@AE@%
  12687. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12688.  
  12689.  
  12690. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12691.  
  12692. None  %@NL@%
  12693.  
  12694.  
  12695. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12696.  
  12697. None  %@NL@%
  12698.  
  12699.  
  12700. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12701.  
  12702. All registers  %@NL@%
  12703.  
  12704.  
  12705.  
  12706.  
  12707.  
  12708.  
  12709. %@CR:C6A00330001 @%%@1@%%@AB@%Chapter 33  Miscellaneous Services%@AE@%%@EH@%%@NL@%
  12710. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12711.  
  12712. The services discussed in this chapter provide functions not easily
  12713. categorized such as hooking another VxDs API and sending system control
  12714. messages. They are provided here in the following order:  %@NL@%
  12715.  
  12716.  
  12717.   ■   %@AB@%Begin_Reentrant_Execution%@AE@%%@NL@%
  12718.  
  12719.   ■   %@AB@%End_Reentrant_Execution%@AE@%%@NL@%
  12720.  
  12721.   ■   %@AB@%Hook_Device_Service%@AE@%%@NL@%
  12722.  
  12723.   ■   %@AB@%Hook_Device_V86_API%@AE@%%@NL@%
  12724.  
  12725.   ■   %@AB@%Hook_PM_Device_API%@AE@%%@NL@%
  12726.  
  12727.   ■   %@AB@%Map_Flat%@AE@%%@NL@%
  12728.  
  12729.   ■   %@AB@%Map_Lin_To_VM_Addr%@AE@%%@NL@%
  12730.  
  12731.   ■   %@AB@%MMGR_SetNULPageAddr%@AE@%%@NL@%
  12732.  
  12733.   ■   %@AB@%Set_System_Exit_Code%@AE@%%@NL@%
  12734.  
  12735.   ■   %@AB@%Simulate_Pop%@AE@%%@NL@%
  12736.  
  12737.   ■   %@AB@%Simulate_Push%@AE@%%@NL@%
  12738.  
  12739.   ■   %@AB@%System_Control%@AE@%%@NL@%
  12740.  
  12741.  
  12742. See Chapter 16. "Overview of Windows in 386 Enhanced Mode" and Chapter 17,
  12743. "Virtual Device Programming Topics" for general environment discussions.  %@NL@%
  12744.  
  12745. %@CR:C6A00330002 @%%@CR:C6A00330003 @%
  12746. %@2@%%@CR:C6A00330004 @%%@AB@%Begin_Reentrant_Execution%@AE@%%@EH@%%@NL@%
  12747. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12748.  
  12749.  
  12750. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12751.  
  12752. THIS IS A VERY DANGEROUS SERVICE. BE VERY CAREFUL WHEN CALLING IT. Most
  12753. virtual devices have no reason to use this service. Do NOT use this service
  12754. to avoid scheduling events on hardware interrupts.  %@NL@%
  12755.  
  12756. It is intended to be used by devices that hook VMM Faults (re-entrant
  12757. processor exeptions) that must call non-asynchronous VMM or VxD services or
  12758. execute a VM. This would be valid to use, for example, if a VxD provided a
  12759. ring 0 software interrupt interface (although this is not recommended ─ You
  12760. should provide device services through the enhanced Windows dynamic-linking
  12761. mechanism). It would be INVALID to use this service during a hardware
  12762. interrupt (such as a timer or disk interrupt).  %@NL@%
  12763.  
  12764.  
  12765. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12766.  
  12767. None  %@NL@%
  12768.  
  12769.  
  12770. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12771.  
  12772. %@AB@%ECX%@AE@% = Old reentrancy count (must be passed to %@AB@%End_Reentrant_Execution%@AE@%)  %@NL@%
  12773.  
  12774.  
  12775. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12776.  
  12777. %@AB@%ECX%@AE@%, Flags  %@NL@%
  12778.  
  12779. %@CR:C6A00330005 @%%@CR:C6A00330006 @%
  12780. %@2@%%@CR:C6A00330007 @%%@AB@%End_Reentrant_Execution%@AE@%%@EH@%%@NL@%
  12781. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12782.  
  12783.  
  12784. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12785.  
  12786. A VxD that calls %@AB@%Begin_Reentrant_Execution%@AE@% must call this service before
  12787. returning.  %@NL@%
  12788.  
  12789.  
  12790. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12791.  
  12792. %@AB@%ECX%@AE@% = Reentrancy count returned from %@AB@%Begin_Reentrant_Execution%@AE@%  %@NL@%
  12793.  
  12794.  
  12795. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12796.  
  12797. None  %@NL@%
  12798.  
  12799.  
  12800. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12801.  
  12802. Flags  %@NL@%
  12803.  
  12804. %@CR:C6A00330008 @%%@CR:C6A00330009 @%
  12805. %@2@%%@CR:C6A00330010 @%%@AB@%Hook_Device_Service%@AE@%%@EH@%%@NL@%
  12806. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12807.  
  12808.  
  12809. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12810.  
  12811. This service allows one device to monitor or replace a device service.
  12812. %@AI@%extreme care%@AE@% must be taken here not to destroy the functionality of the
  12813. device whose routine is being monitored or replaced. This service also
  12814. allows VMM services to be hooked (the VMM is device 1).  %@NL@%
  12815.  
  12816. Hooking a service is often useful for monitoring the activities of other
  12817. devices. For example, if a device needed to know whenever a VM was set into
  12818. background mode, it could use the following code:  %@NL@%
  12819.  
  12820. %@AS@%  (Initialization code)
  12821. %@AS@%        mov    eax, Set_Time_Slice_Priority
  12822. %@AS@%        mov    esi, OFFSET32 My_Hook_Proc
  12823. %@AS@%        VMMcall Hook_Device_Service
  12824. %@AS@%        jc    Error!
  12825. %@AS@%        mov    [Real_Proc], esi%@AE@%
  12826.  
  12827. %@AS@%  BeginProc My_Hook_Proc
  12828. %@AS@%        test    eax, VMStat_Background
  12829. %@AS@%        jz    SHORT MHP_Chain
  12830. %@AS@%        pushad
  12831. %@AS@%        (Do something here)
  12832. %@AS@%        popad
  12833. %@AS@%  MHP_Chain:
  12834. %@AS@%        jmp     [Real_Proc]
  12835. %@AS@%  EndProc My_Hook_Proc%@AE@%
  12836.  
  12837. Every time a VxD calls %@AB@%Set_Time_Slice_Priority%@AE@%, the %@AB@%My_Hook_Proc%@AE@% procedure
  12838. will be called. The hook procedure should normally chain to the actual
  12839. device or VMM service although this is not required. Also, be sure to save
  12840. and restore any registers in your hook procedure.  %@NL@%
  12841.  
  12842. You will notice that the sample initialization code moves
  12843. %@AB@%Set_Time_Slice_Priority%@AE@% into %@AB@%EAX%@AE@%. Remember, services are defined as EQUATES,
  12844. not external procedure references. Thus, %@AB@%Set_Time_Slice_Priority%@AE@% is just a
  12845. number. (VMM device ID%@NL@%
  12846.  
  12847. Your hook must preserve all registers that are not modified by the service
  12848. you have hooked. Also, if flags are passed as an entry or exit parameter,
  12849. your hook procedure must also preserve the flags.  %@NL@%
  12850.  
  12851. Be careful about hooking C calling convention (stack-based) services. If you
  12852. want to examine the "back end" of a C calling convention service, you will
  12853. need to copy the entire parameter stack frame before calling the actual
  12854. service.  %@NL@%
  12855.  
  12856. More than one VxD can hook a device service. The last hook installed will be
  12857. the first one called.  %@NL@%
  12858.  
  12859.  
  12860. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12861.  
  12862. %@AB@%EAX%@AE@% = Device ID  %@AB@%ESI%@AE@% = New procedure  %@NL@%
  12863.  
  12864.  
  12865. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12866.  
  12867. If carry clear then  ESI = Old dynalink procedure else  ERROR. Invalid
  12868. Device or Service number  %@NL@%
  12869.  
  12870.  
  12871. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12872.  
  12873. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12874.  
  12875. %@CR:C6A00330011 @%%@CR:C6A00330012 @%%@CR:C6A00330013 @%%@CR:C6A00330014 @%
  12876. %@2@%%@CR:C6A00330015 @%%@AB@%Hook_Device_V86_API, Hook_PM_Device_API%@AE@%%@EH@%%@NL@%
  12877. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12878.  
  12879.  
  12880. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12881.  
  12882. These services allow a VxD to hook another virtual device's V86 or protected
  12883. mode API interface.You are responsible for chaining to the real API handler.
  12884. Be careful to preserve the %@AB@%EBX%@AE@% and %@AB@%EBP%@AE@% registers when calling the next
  12885. handler in the chain.  %@NL@%
  12886.  
  12887. Most VxDs will never need to hook another virtual device's API procedure.
  12888. These services are provided mainly as a mechanism for devices that may be
  12889. developed in the future to intercept API calls to other virtual devices. For
  12890. example, a new version of the Virtual Mouse Device may need to intercept
  12891. calls to the Virtual Display Device so that it can save and restore the
  12892. mouse cursor. In such a case, these services could be used.  %@NL@%
  12893.  
  12894.  
  12895. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12896.  
  12897. %@AB@%EAX%@AE@% = Device ID %@AB@%ESI %@AE@%= Offset of new API handler  %@NL@%
  12898.  
  12899.  
  12900. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12901.  
  12902. If carry clear then  ESI = Offset of previous API handler (used to chain to
  12903. next  handler) else  ERROR: Device does not support API interface  %@NL@%
  12904.  
  12905.  
  12906. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12907.  
  12908. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12909.  
  12910.  
  12911. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  12912.  
  12913. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure (Same parameters as
  12914. standard API entry point)  %@NL@%
  12915.  
  12916. %@CR:C6A00330016 @%
  12917. %@2@%%@CR:C6A00330017 @%%@AB@%Map_Flat%@CR:C6A00330018 @%%@AE@%%@EH@%%@NL@%
  12918. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12919.  
  12920.  
  12921. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12922.  
  12923. This service provides a convenient way of converting a SEGMENT:OFFSET or
  12924. SELECTOR:OFFSET pair into a linear address. %@AB@%Map_Flat%@AE@% works only for the
  12925. current VM. It determines whether the value passed to it is a V86 segment or
  12926. a PM selector by the execution mode of the current VM. This allows VxDs to
  12927. use identical code for PM and V86 handlers. For example, assume a VxD wanted
  12928. to simulate MS-DOS reads in both V86 and protected mode. It would hook both
  12929. the V86 and PM %@AB@%int%@AE@% chains with the same procedure:  %@NL@%
  12930.  
  12931. %@AS@%  VxD_DOS_Read_Hook:
  12932. %@AS@%    cmp [ebp.Client_AH], 3Fh ; Q: Is it a read
  12933. %@AS@%    jne SHORT VxD_DRH_Reflect ;    N: Reflect it
  12934. %@AS@%        ;    Y: DS:DX -> Read buffer
  12935. %@AS@%    mov ax, (Client_DS SHL 8) + Client_DX
  12936. %@AS@%    VMMcall Map_Flat  ; EAX = Lin addr of DS:DX
  12937. %@AS@%    . . .
  12938. %@AS@%    (Do something useful here)
  12939. %@AS@%    . . .
  12940. %@AS@%    clc    ; Eat this int 21h
  12941. %@AS@%    ret 
  12942. %@AS@%  VxD_DRH_Reflect:
  12943. %@AS@%    stc
  12944. %@AS@%    ret%@AE@%
  12945.  
  12946. Notice that the above procedure does not need to examine the VM's execution
  12947. state. By calling %@AB@%Map_Flat%@AE@% it converts the DS:DX pointer into a valid linear
  12948. address regardless of the VM's execution mode. If the VM was running a
  12949. 32-bit protected mode application, it would convert the client's DS:EDX into
  12950. a linear address. For V86 and 16-bit protected-mode applications, it would
  12951. ignore the high word of the Client_EDX.  %@NL@%
  12952.  
  12953. There is a macro called %@AB@%Client_Ptr_Flat%@AE@% that will generate this code
  12954. automatically. For the example above you would use:  %@NL@%
  12955.  
  12956. %@AS@%  Client_Ptr_Flat eax, DS, DX%@AE@%
  12957.  
  12958. The first parameter specifies the 32-bit register to contain the linear
  12959. address. The second parameter specifies the client's segment. The third
  12960. parameter is optional and specifies the offset register (if blank then an
  12961. offset of 0 is assumed).  %@NL@%
  12962.  
  12963. You must set %@AB@%AH%@AE@% to the equate for the client segment register you want to
  12964. map flat and AL to the offset register to add to the pointer base.
  12965. Alternately, if you do not want an offset added to the segment base you
  12966. should set AL to -1 (0FFh). This will just convert the segment to a linear
  12967. address.  %@NL@%
  12968.  
  12969. Notice that during the running of 32-bit protected mode applications, or
  12970. while in "VxD_Exec" mode, pointers will use the 32-bit offset register.
  12971. Therefore, the above example would use %@AB@%DS:EDX%@AE@% when the %@AB@%CB_VM_Status%@AE@% field of
  12972. a VM's control block has either bit set in %@AB@%VMStat_Use32_Mask%@AE@%. This makes
  12973. %@AB@%Map_Flat%@AE@% work for V86, 16-bit protected mode, and 32-bit protected mode
  12974. programs.  %@NL@%
  12975.  
  12976.  
  12977. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12978.  
  12979. AH = Offset in client structure of segment register to use. AL = Offset in
  12980. client structure of offset register to use  OR -1 if no offset to be added
  12981. to segment base  %@NL@%
  12982.  
  12983.  
  12984. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12985.  
  12986. %@AB@%EAX%@AE@% = Ring 0 linear address  %@NL@%
  12987.  
  12988.  
  12989. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12990.  
  12991. Flags, %@AB@%EAX%@AE@%  %@NL@%
  12992.  
  12993. %@CR:C6A00330019 @%%@CR:C6A00330020 @%
  12994. %@2@%%@CR:C6A00330021 @%%@AB@%MMGR_SetNULPageAddr%@AE@%%@EH@%%@NL@%
  12995. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12996.  
  12997.  
  12998. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12999.  
  13000. This call is used to set the physical address of the system nul page.  %@NL@%
  13001.  
  13002. It can be called at device INIT time to set the address of a KNOWN
  13003. non-existant page in the system. This is usually called by the V86MMGR
  13004. device because he does memory scans and therefore has a good idea about what
  13005. a good page will be.  %@NL@%
  13006.  
  13007.  
  13008. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13009.  
  13010. %@AB@%EAX%@AE@% is PHYSICAL address for NUL Page (Page number %@NL@%
  13011.  
  13012.  
  13013. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13014.  
  13015. None  %@NL@%
  13016.  
  13017.  
  13018. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13019.  
  13020. Flags  %@NL@%
  13021.  
  13022. %@CR:C6A00330022 @%%@CR:C6A00330023 @%
  13023. %@2@%%@CR:C6A00330024 @%%@AB@%Set_System_Exit_Code%@AE@%%@EH@%%@NL@%
  13024. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13025.  
  13026.  
  13027. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13028.  
  13029. This service sets the DOS system call 4Ch return code value passed in AL on
  13030. the EXIT call made by the loader. Thus this sets the MS-DOS exit code that
  13031. Windows Enhanced Mode exits with. This service is intended for use by the
  13032. SHELL device.  %@NL@%
  13033.  
  13034. Notice that this exit code is associated only with the EXIT of the the
  13035. system (i.e. the SYS VM).  %@NL@%
  13036.  
  13037. Nice that in the case of an abnormal termination the LOADER may set its own
  13038. exit code, which will cause the one set with this service to be ignored.  %@NL@%
  13039.  
  13040.  
  13041. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13042.  
  13043. AL == Exit Code to set  %@NL@%
  13044.  
  13045.  
  13046. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13047.  
  13048. None  %@NL@%
  13049.  
  13050.  
  13051. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13052.  
  13053. EDX,FLAGS  %@NL@%
  13054.  
  13055. %@CR:C6A00330025 @%
  13056. %@2@%%@CR:C6A00330026 @%%@AB@%Simulate_Pop%@CR:C6A00330027 @%%@AE@%%@EH@%%@NL@%
  13057. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13058.  
  13059.  
  13060. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13061.  
  13062. Returns the WORD or DWORD at the top of the current VM's client stack and
  13063. adds 2 or 4 to the client's %@AB@%SP%@AE@%.  %@NL@%
  13064.  
  13065.  
  13066. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13067.  
  13068. None  %@NL@%
  13069.  
  13070.  
  13071. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13072.  
  13073. %@AB@%EAX%@AE@% = Word popped from application's stack (high word 0 if use 16 app)  %@NL@%
  13074.  
  13075.  
  13076. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13077.  
  13078. %@AB@%EAX%@AE@%, %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  13079.  
  13080. %@CR:C6A00330028 @%
  13081. %@2@%%@CR:C6A00330029 @%%@AB@%Simulate_Push%@CR:C6A00330030 @%%@AE@%%@EH@%%@NL@%
  13082. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13083.  
  13084.  
  13085. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13086.  
  13087. Pushes a WORD or DWORD onto the current VM's client stack and decrements the
  13088. VM's %@AB@%SP%@AE@% by 2 or 4.  %@NL@%
  13089.  
  13090.  
  13091. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13092.  
  13093. If in V86 mode or 16 bit PM application then  AX = WORD to push else  EAX =
  13094. DWORD to push  %@NL@%
  13095.  
  13096.  
  13097. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13098.  
  13099. (D)WORD pushed on application program's stack  %@NL@%
  13100.  
  13101.  
  13102. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13103.  
  13104. %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  13105.  
  13106. %@CR:C6A00330031 @%
  13107. %@2@%%@CR:C6A00330032 @%%@AB@%System_Control%@CR:C6A00330033 @%%@AE@%%@EH@%%@NL@%
  13108. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13109.  
  13110.  
  13111. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13112.  
  13113. This service sends system control messages to all the VxD's and for some
  13114. messages, to parts of VMM as well. Notice that incorrect usage of the system
  13115. control messages can cause erratic behavior by the system. For example, only
  13116. the Shell device should initiate %@AB@%Create_VM%@AE@% and %@AB@%Destroy_VM%@AE@% messages. Also
  13117. notice that when a %@AB@%Set_Device_Focus%@AE@% message is done with a device ID of
  13118. zero, all devices with a settable focus must set their focus to the VM
  13119. indicated.  %@NL@%
  13120.  
  13121. The valid %@AB@%System_Control %@AE@%messages are as follows:  %@NL@%
  13122.  
  13123. %@TH:  26  1162 02 23 53 @%
  13124. Initialization         %@AB@%Sys_Critical_Init%@AE@%%@AB@%%@AE@%
  13125.                        %@AB@%Device_Init%@AE@%%@AB@%%@AE@%
  13126.                        %@AB@%Init_Complete%@AE@%
  13127. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13128. System VM creation     %@AB@%Sys_VM_Init%@AE@%%@AB@%%@AE@%
  13129.                        %@AB@%Sys_VM_Terminate%@AE@%
  13130.  
  13131. System VM destruction  %@AB@%System_Exit%@AE@%%@AB@%%@AE@%
  13132. (enhanced Windows      %@AB@%Sys_Critical_Exit%@AE@%
  13133. exit)                  
  13134.  
  13135. Other VM creation      %@AB@%Create_VM%@AE@%%@AB@%%@AE@%
  13136.                        %@AB@%VM_Critical_Init%@AE@%%@AB@%%@AE@%
  13137.                        %@AB@%VM_Init%@AE@%
  13138.  
  13139. Other VM destruction   %@AB@%VM_Terminate%@AE@%%@AB@%%@AE@%
  13140.                        %@AB@%VM_Not_Executable%@AE@%%@AB@%%@AE@%
  13141.                        %@AB@%Destroy_VM%@AE@%
  13142.  
  13143. VM state changes       %@AB@%VM_Suspend%@AE@%%@AB@%%@AE@%
  13144.                        %@AB@%VM_Resume%@AE@%%@AB@%%@AE@%
  13145.                        %@AB@%Set_Device_Focus%@AE@%
  13146.  
  13147. Special messages       %@AB@%Reboot_Processor%@AE@%%@AB@%%@AE@%
  13148.                        %@AB@%Debug_Query%@AE@%
  13149.  
  13150. %@TE:  26  1162 02 23 53 @%
  13151.  
  13152. The control calls that are valid for devices to issue are as follows:  %@NL@%
  13153.  
  13154. %@AB@%Create_VM %@AE@%  (used by SHELL) %@AB@%Destroy_VM%@AE@% (used by SHELL) %@AB@%Set_Device_Focus%@AE@%  %@NL@%
  13155.  
  13156.  
  13157. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13158.  
  13159. %@AB@%EAX%@AE@% = System control message %@AB@%EBX%@AE@% = VM handle (if needed by message)
  13160. %@AB@%ESI%@AE@%,%@AB@%EDI%@AE@%,%@AB@%EDX%@AE@% = message specific parameter, such as Device ID (for
  13161. Set_Device_Focus message) %@AB@%ECX%@AE@% register is used by this service and cannot
  13162. contain any parameter that  will be passed through to the devices.  %@NL@%
  13163.  
  13164.  
  13165. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13166.  
  13167. Carry Set  Call failed Carry Clear  Call Succeeded  If Entry EAX = %@AB@%Create_VM%@AE@%
  13168. EBX = New VM handle created  %@NL@%
  13169.  
  13170.  
  13171. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13172.  
  13173. Flags, %@AB@%EBX%@AE@% if %@AB@%Create_VM%@AE@%  %@NL@%
  13174.  
  13175.  
  13176.  
  13177.  
  13178.  
  13179.  
  13180. %@CR:C6A00340001 @%%@1@%%@AB@%Chapter 34  Shell Services%@AE@%%@EH@%%@NL@%
  13181. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13182.  
  13183. The Shell services provide a way for VxDs to communicate with the user. This
  13184. chapter presents descriptions of the Shell services in the following order:
  13185. %@NL@%
  13186.  
  13187.  
  13188.   ■   %@AB@%SHELL_Event%@AE@%%@NL@%
  13189.  
  13190.   ■   %@AB@%SHELL_Get_Version%@AE@%%@NL@%
  13191.  
  13192.   ■   %@AB@%SHELL_Message%@AE@%%@NL@%
  13193.  
  13194.   ■   %@AB@%SHELL_Resolve_Contention%@AE@%%@NL@%
  13195.  
  13196.   ■   %@AB@%SHELL_SYSMODAL_Message%@AE@%%@NL@%
  13197.  
  13198.  
  13199. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  13200. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  13201.  
  13202.  
  13203. %@2@%%@CR:C6A00340002 @%%@AB@%SHELL_Event%@CR:C6A00340003 @%%@AE@%%@EH@%%@NL@%
  13204. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13205.  
  13206.  
  13207. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13208.  
  13209. This procedure posts an event occuring in the windows shell to VMDOSAPP.
  13210. This service is primarily for SHELL to WINOLDAPP communication. The VDD also
  13211. sends a couple messages to WINOLDAPP, other VxDs should have no use for this
  13212. service.  %@NL@%
  13213.  
  13214.  
  13215. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13216.  
  13217. %@AB@%EBX%@AE@% is VM Handle for Event %@AB@%ECX%@AE@% is event # %@AB@%AX%@AE@% = wParam for event High 16 bits
  13218. %@AB@%EAX%@AE@% special boost flags %@AB@%ESI%@AE@% is callback procedure for event (==0 if none)
  13219. %@AB@%EDX%@AE@% is reference data for event callback  %@NL@%
  13220.  
  13221.  
  13222. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13223.  
  13224. Carry Clear  Event placed in queue  %@AB@%EAX%@AE@% is "Event Handle" of event (only if
  13225. valid entry %@AB@%ESI %@AE@%  0) Carry Set  Event not placed  VMDOSAPP not present
  13226. Insufficient memory for placement  %@NL@%
  13227.  
  13228.  
  13229. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  13230.  
  13231. Carry Set  Event could not be placed in VMDOSAPP queue  %@AB@%EDX%@AE@% = reference data
  13232. NOTE THAT %@AB@%EBX%@AE@% != VM Handle of event! Carry Clear  Called when VMDOSAPP
  13233. signals event processing complete  %@AB@%EBP%@AE@% -> VMDOSAPP Client frame so registers
  13234. can be accessed  %@AB@%EDX%@AE@% = reference data  NOTE THAT %@AB@%EBX%@AE@% != VM Handle of event!
  13235. %@NL@%
  13236.  
  13237.  
  13238. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13239.  
  13240. Flags, %@AB@%EAX%@AE@%  %@NL@%
  13241.  
  13242.  
  13243. %@2@%%@CR:C6A00340004 @%%@AB@%SHELL_Get_Version%@CR:C6A00340005 @%%@AE@%%@EH@%%@NL@%
  13244. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13245.  
  13246.  
  13247. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13248.  
  13249. This procedure returns the version of the Shell VxD.  %@NL@%
  13250.  
  13251.  
  13252. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13253.  
  13254. None  %@NL@%
  13255.  
  13256.  
  13257. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13258.  
  13259. %@AB@%AH%@AE@% = Major version %@AB@%AL%@AE@% = Minor version Carry Flag clear  %@NL@%
  13260.  
  13261.  
  13262. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13263.  
  13264. %@AB@%EAX%@AE@%, Flags  %@NL@%
  13265.  
  13266.  
  13267. %@2@%%@CR:C6A00340006 @%%@AB@%SHELL_Message%@CR:C6A00340007 @%%@AE@%%@EH@%%@NL@%
  13268. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13269.  
  13270.  
  13271. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13272.  
  13273. This procedure is called to put up messages. Refer to SHELL.INC and the
  13274. %@AI@%Microsoft Windows Software Development Kit%@AE@% for information on message box
  13275. parameters.  %@NL@%
  13276.  
  13277.  
  13278. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13279.  
  13280. %@AB@%EBX%@AE@% = VM Handle of VM responsible for message %@AB@%EAX%@AE@% = Message box flags (SEE
  13281. MB_xxxx in SHELL.INC) %@AB@%ECX%@AE@% -> NUL terminated Message Text %@AB@%EDI%@AE@% -> NUL
  13282. terminated caption Text == 0 for standard caption  -> NUL for No caption %@AB@%ESI%@AE@%
  13283. -> Callback procedure to call with response when dialog is finished == 0 if
  13284. no call back desired %@AB@%EDX%@AE@% = Reference data for callback  %@NL@%
  13285.  
  13286.  
  13287. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13288.  
  13289. Carry Clear  %@AB@%EAX%@AE@% is "Event Handle" of message Carry Set  Message cannot be
  13290. displayed (insufficient memory)  Caller may wish to call
  13291. %@AB@%SHELL_SYSMODAL_MESSAGE%@AE@% in this csae.  %@AB@%SHELL_Sysmodal_Message%@AE@% will not fail.
  13292. %@NL@%
  13293.  
  13294.  
  13295. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  13296.  
  13297. Called when message box is complete %@AB@%EAX%@AE@% = Response code from dialog box (SEE
  13298. IDxx in SHELL.INC)  %@AB@%EDX%@AE@% = reference data %@AB@%EBX%@AE@%  VM Handle of message VM  %@NL@%
  13299.  
  13300.  
  13301. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13302.  
  13303. Flags,%@AB@% EAX%@AE@%  %@NL@%
  13304.  
  13305. %@CR:C6A00340008 @%
  13306. %@2@%%@CR:C6A00340009 @%%@AB@%SHELL_Resolve_Contention%@AE@%%@EH@%%@NL@%
  13307. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13308.  
  13309.  
  13310. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13311.  
  13312. This procedure is called to resolve contention. It displays a dialog box in
  13313. which the user chooses which VM should get ownership of the device.  %@NL@%
  13314.  
  13315.  
  13316. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13317.  
  13318. %@AB@%EAX%@AE@% = VM handle of current device owner %@AB@%EBX%@AE@% = VM handle of contending VM
  13319. (Must be %@AB@%Cur_VM_Handle%@AE@%) %@AB@%ESI%@AE@% -> 8 byte device name SPACE PADDED!!!  %@NL@%
  13320.  
  13321.  
  13322. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13323.  
  13324. %@AB@%EBX%@AE@% = VM handle of contention winner If carry is set then contention could
  13325. not be resolved  %@NL@%
  13326.  
  13327.  
  13328. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13329.  
  13330. %@AB@%EBX%@AE@%, Flags  %@NL@%
  13331.  
  13332.  
  13333. %@2@%%@CR:C6A00340010 @%%@AB@%SHELL_SYSMODAL_Message%@AE@%%@EH@%%@NL@%
  13334. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13335.  
  13336.  
  13337. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13338.  
  13339. This procedure is called to put up SYSMODAL messages. Refer to SHELL.INC and
  13340. the %@AI@%Windows SDK%@AE@% for information on message box parameters.  %@NL@%
  13341.  
  13342.  
  13343. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13344.  
  13345. %@AB@%EBX%@AE@% = VM Handle of VM responsible for message %@AB@%EAX%@AE@% = Message box flags (SEE
  13346. MB_xxxx in SHELL.INC)  NOTE THAT MB_SYSTEMMODAL MUST BE SET. %@AB@%ECX%@AE@% -> NUL
  13347. terminated Message Text %@AB@%EDI%@AE@% -> NUL terminated Caption Text == 0 for standard
  13348. caption  -> NUL for No caption  %@NL@%
  13349.  
  13350.  
  13351. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13352.  
  13353. %@AB@%EAX%@AE@% = Response code from dialog box (SEE IDxx in SHELL.INC)  %@NL@%
  13354.  
  13355.  
  13356. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13357.  
  13358. Flags, %@AB@%EAX%@AE@%  %@NL@%
  13359.  
  13360.  
  13361.  
  13362.  
  13363.  
  13364.  
  13365. %@CR:C6A00350001 @%%@1@%%@AB@%Chapter 35  Virtual Display Device (VDD) Services%@AE@%%@EH@%%@NL@%
  13366. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13367.  
  13368. These are the Virtual Display Device (VDD) services. See Chapter 18, "The
  13369. VDD and Grabber DLL," for a more detailed explanation.%@CR:C6A00350002 @%%@NL@%
  13370.  
  13371. The services are described in the following order:  %@NL@%
  13372.  
  13373.  
  13374.   ■   %@AB@%VDD_Msg_BakColor%@AE@%%@NL@%
  13375.  
  13376.   ■   %@AB@%VDD_Msg_ClrScrn%@AE@%%@NL@%
  13377.  
  13378.   ■   %@AB@%VDD_Msg_ForColor%@AE@%%@NL@%
  13379.  
  13380.   ■   %@AB@%VDD_Msg_SetCursorPos%@AE@%%@NL@%
  13381.  
  13382.   ■   %@AB@%VDD_Msg_TextOut%@AE@%%@NL@%
  13383.  
  13384.   ■   %@AB@%VDD_Get_GrabRtn%@AE@%%@NL@%
  13385.  
  13386.   ■   %@AB@%VDD_Get_ModTime%@AE@%%@NL@%
  13387.  
  13388.   ■   %@AB@%VDD_Get_Version%@AE@%%@NL@%
  13389.  
  13390.   ■   %@AB@%VDD_Hide_Cursor%@AE@%%@NL@%
  13391.  
  13392.   ■   %@AB@%VDD_PIF_State%@AE@%%@NL@%
  13393.  
  13394.   ■   %@AB@%VDD_Query_Access%@AE@%%@NL@%
  13395.  
  13396.   ■   %@AB@%VDD_Set_HCurTrk%@AE@%%@NL@%
  13397.  
  13398.   ■   %@AB@%VDD_Set_VMType%@AE@%%@NL@%
  13399.  
  13400.   ■   %@AB@%VDD_Query_Access%@AE@%%@NL@%
  13401.  
  13402.  
  13403.  
  13404. %@2@%%@CR:C6A00350003 @%%@AB@%35.1  Displaying a VM's Video Memory in a Window%@AE@%%@EH@%%@NL@%
  13405.  
  13406. There are several API services supplied to render efficiently a VM's video
  13407. memory into a window. These routines are called by the Grabber. Since the
  13408. Grabber runs in the Windows virtual machine, parameters are passed in the
  13409. Client Registers and in VM memory pointed to by the Client Registers.  %@NL@%
  13410.  
  13411. The first step in updating windowed VMs is for the Shell to call %@AB@%Set_VMState%@AE@%
  13412. with a parameter indicating that the VM is to be windowed. This will enable
  13413. the VDD controller and memory state tracking and reporting of changes. When
  13414. the VM is no longer windowed, %@AB@%Set_VMState%@AE@% is called again. When the VMState
  13415. is not windowed, the %@AB@%Get_Mod%@AE@% call will always return no changes, and the
  13416. video update message will never be generated.  %@NL@%
  13417.  
  13418. The Grabber has to be assured that the call to get the video memory is
  13419. consistent with the call to get the video state; for example, displaying a
  13420. mode 3 VM in mode 10 is inconsistent. To support this, the VM will not run
  13421. after a %@AB@%Get_Mod%@AE@% or %@AB@%Get_Mem%@AE@% call (an exception is hardware interrupts). The
  13422. VM resumes only after a %@AB@%Free_Mem%@AE@% or %@AB@%UnLock_App%@AE@% call. This way the VM's state
  13423. will not change during the process of window updating.  %@NL@%
  13424.  
  13425. An exception is a VM that may update it's video memory during a timer
  13426. interrupt.  %@NL@%
  13427.  
  13428. Notice that when a VM's video state changes, including controller state
  13429. changes such as cursor movement and memory modification, the VDD will send
  13430. WINOLDAPP a display update message. All the changes made to the video state
  13431. will accumulate and be reported by %@AB@%Get_Mod%@AE@% until a %@AB@%Clear_Mod%@AE@% call is made.
  13432. There will only be one display update message per %@AB@%Clear_Mod%@AE@% call.  %@NL@%
  13433.  
  13434.  
  13435. %@2@%%@CR:C6A00350004 @%%@AB@%35.2  Message Mode Services%@AE@%%@EH@%%@NL@%
  13436.  
  13437. When a %@AB@%Begin_Message_Mode%@AE@% control call is made, the VDD goes into a special
  13438. mode that allows the Shell device to use the VDD message services to output
  13439. text to the screen without changing the VM's video state. When the message
  13440. is complete, an %@AB@%End_Message_Mode%@AE@% control call is made that restores the
  13441. focus VM to the hardware.  %@NL@%
  13442.  
  13443. %@CR:C6A00350005 @%
  13444. %@2@%%@CR:C6A00350006 @%%@AB@%VDD_Msg_BakColor%@AE@%%@EH@%%@NL@%
  13445. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13446.  
  13447.  
  13448. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13449.  
  13450. After calling %@AB@%Begin_Message_Mode%@AE@%, this service sets up the background
  13451. attribute.  %@NL@%
  13452.  
  13453.  
  13454. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13455.  
  13456. %@AB@%EAX%@AE@% = Color (for EGA/VGA driver, a text mode attribute) %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13457.  
  13458.  
  13459. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13460.  
  13461. None  %@NL@%
  13462.  
  13463.  
  13464. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13465.  
  13466. Flags  %@NL@%
  13467.  
  13468. %@CR:C6A00350007 @%
  13469. %@2@%%@CR:C6A00350008 @%%@AB@%VDD_Msg_ClrScrn%@AE@%%@EH@%%@NL@%
  13470. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13471.  
  13472.  
  13473. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13474.  
  13475. This routine is called by the Shell to initialize the screen for putting up
  13476. messages. If the focus VM is the current VM, it will clear the screen
  13477. immediately. Otherwise, the screen will be initialized when the focus
  13478. changes. A %@AB@%Begin_Message_Mode%@AE@% device control must be issued before this
  13479. service is used.  %@NL@%
  13480.  
  13481.  
  13482. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13483.  
  13484. %@AB@%EBX%@AE@% = VM handle %@AB@%EAX%@AE@% = background attribute  %@NL@%
  13485.  
  13486.  
  13487. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13488.  
  13489. %@AB@%EAX%@AE@% = width in columns %@AB@%EDX%@AE@% = height in rows  %@NL@%
  13490.  
  13491.  
  13492. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13493.  
  13494. Flags, %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%  %@NL@%
  13495.  
  13496. %@CR:C6A00350009 @%
  13497. %@2@%%@CR:C6A00350010 @%%@AB@%VDD_Msg_ForColor%@AE@%%@EH@%%@NL@%
  13498. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13499.  
  13500.  
  13501. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13502.  
  13503. After calling %@AB@%Begin_Message_Mode%@AE@%, this service sets up the foreground
  13504. attribute.  %@NL@%
  13505.  
  13506.  
  13507. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13508.  
  13509. %@AB@%EAX%@AE@% = Color (for EGA/VGA driver, a text mode attribute) %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13510.  
  13511.  
  13512. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13513.  
  13514. None  %@NL@%
  13515.  
  13516.  
  13517. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13518.  
  13519. Flags  %@NL@%
  13520.  
  13521. %@CR:C6A00350011 @%
  13522. %@2@%%@CR:C6A00350012 @%%@AB@%VDD_Msg_SetCursPos%@AE@%%@EH@%%@NL@%
  13523. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13524.  
  13525.  
  13526. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13527.  
  13528. After calling %@AB@%Begin_Message_Mode%@AE@%, this routine sets the cursor position.  %@NL@%
  13529.  
  13530.  
  13531. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13532.  
  13533. %@AB@%EAX%@AE@% = row %@AB@%EDX%@AE@% = column %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13534.  
  13535.  
  13536. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13537.  
  13538. None  %@NL@%
  13539.  
  13540.  
  13541. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13542.  
  13543. Flags  %@NL@%
  13544.  
  13545. %@CR:C6A00350013 @%
  13546. %@2@%%@CR:C6A00350014 @%%@AB@%VDD_Msg_TextOut%@AE@%%@EH@%%@NL@%
  13547. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13548.  
  13549.  
  13550. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13551.  
  13552. After calling %@AB@%Begin_Message_Mode%@AE@% and setting up the foreground and
  13553. background colors, this service puts characters on the screen.  %@NL@%
  13554.  
  13555.  
  13556. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13557.  
  13558. %@AB@%ESI%@AE@% = address of string %@AB@%ECX%@AE@% = length of string %@AB@%EAX%@AE@% = row start %@AB@%EDX%@AE@% = column
  13559. start %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13560.  
  13561.  
  13562. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13563.  
  13564. None  %@NL@%
  13565.  
  13566.  
  13567. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13568.  
  13569. Flags  %@NL@%
  13570.  
  13571.  
  13572. %@2@%%@CR:C6A00350015 @%%@AB@%35.3  Miscellaneous VDD Services%@AE@%%@EH@%%@NL@%
  13573. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13574.  
  13575. The services discussed in this section provide other VDD functions not
  13576. easily catagorized, such as hiding the cursor. They are provided here in
  13577. alphabetical order.  %@NL@%
  13578.  
  13579. %@CR:C6A00350016 @%
  13580. %@2@%%@CR:C6A00350017 @%%@AB@%VDD_Get_GrabRtn%@AE@%%@EH@%%@NL@%
  13581. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13582.  
  13583.  
  13584. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13585.  
  13586. This service returns the address of video grab routine. The grab routine is
  13587. called by the Shell device when the appropriate hot key is pressed by the
  13588. user. It makes a copy of the visible screen and controller state of the
  13589. current VM. That copy is then accessible via the %@AB@%GRB_Get_GrbState%@AE@% and
  13590. %@AB@%GRB_Get_GrbMem%@AE@% services.  %@NL@%
  13591.  
  13592.  
  13593. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13594.  
  13595. None  %@NL@%
  13596.  
  13597.  
  13598. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13599.  
  13600. %@AB@%ESI%@AE@% = address of grab routine  %@NL@%
  13601.  
  13602.  
  13603. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13604.  
  13605. Flags, %@AB@%ESI%@AE@%  %@NL@%
  13606.  
  13607. %@CR:C6A00350018 @%
  13608. %@2@%%@CR:C6A00350019 @%%@AB@%VDD_Get_ModTime%@AE@%%@EH@%%@NL@%
  13609. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13610.  
  13611.  
  13612. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13613.  
  13614. This routine is used to determine if any video activity has occurred. The
  13615. poll device uses it to determine if the VM is idle.  %@NL@%
  13616.  
  13617.  
  13618. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13619.  
  13620. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13621.  
  13622.  
  13623. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13624.  
  13625. %@AB@%EAX%@AE@% = System Timer at last video modification  %@NL@%
  13626.  
  13627.  
  13628. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13629.  
  13630. Flags, %@AB@%EAX%@AE@%  %@NL@%
  13631.  
  13632. %@CR:C6A00350020 @%
  13633. %@2@%%@CR:C6A00350021 @%%@AB@%VDD_Get_Version%@AE@%%@EH@%%@NL@%
  13634. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13635.  
  13636.  
  13637. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13638.  
  13639. This service returns the version number and device ID.  %@NL@%
  13640.  
  13641.  
  13642. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13643.  
  13644. None  %@NL@%
  13645.  
  13646.  
  13647. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13648.  
  13649. %@AB@%ESI %@AE@%= ptr to 8 byte ID string %@AB@%AH%@AE@% = major version %@AB@%AL%@AE@% = minor version Carry
  13650. Flag clear  %@NL@%
  13651.  
  13652.  
  13653. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13654.  
  13655. Flags, %@AB@%AX%@AE@%, %@AB@%ESI%@AE@%  %@NL@%
  13656.  
  13657. %@CR:C6A00350022 @%
  13658. %@2@%%@CR:C6A00350023 @%%@AB@%VDD_Hide_Cursor%@AE@%%@EH@%%@NL@%
  13659. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13660.  
  13661.  
  13662. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13663.  
  13664. This service hides/shows the cursor in a window. If %@AB@%EAX%@AE@% is nonzero, then
  13665. this service sets a hide cursor flag or else clears the flag. This is so
  13666. that, if the mouse is using a hardware cursor, it can turn off that cursor
  13667. while the VM is windowed (since the VM will no longer own the mouse).  %@NL@%
  13668.  
  13669.  
  13670. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13671.  
  13672. %@AB@%EAX%@AE@% = 0 if cursor SHOULD be displayed in a window   0 if cursor SHOULD NOT
  13673. be displayed in a window  %@AB@%EBX%@AE@% = control block pointer  %@NL@%
  13674.  
  13675.  
  13676. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13677.  
  13678. None  %@NL@%
  13679.  
  13680.  
  13681. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13682.  
  13683. Flags  %@NL@%
  13684.  
  13685. %@CR:C6A00350024 @%
  13686. %@2@%%@CR:C6A00350025 @%%@AB@%VDD_PIF_State%@AE@%%@EH@%%@NL@%
  13687. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13688.  
  13689.  
  13690. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13691.  
  13692. This service informs the VDD about PIF bits for the VM just created.  %@NL@%
  13693.  
  13694.  
  13695. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13696.  
  13697. %@AB@%EBX%@AE@% = VM handle %@AB@%AX%@AE@% = PIF bits  %@NL@%
  13698.  
  13699.  
  13700. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13701.  
  13702. None  %@NL@%
  13703.  
  13704.  
  13705. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13706.  
  13707. Flags  %@NL@%
  13708.  
  13709. %@CR:C6A00350026 @%
  13710. %@2@%%@CR:C6A00350027 @%%@AB@%VDD_Query_Access%@AE@%%@EH@%%@NL@%
  13711. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13712.  
  13713.  
  13714. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13715.  
  13716. Returns error if there is an attempt by the specified VM by the specified VM
  13717. to access the video memory. This is used by the Virtual Mouse Device to
  13718. decide whether or not to turn off the mouse cursor when a VM no longer has
  13719. the mouse focus. This service should only be called in a VM Event just
  13720. before returning to the VM, e.g. %@AB@%Exec_Int%@AE@% to the mouse driver.  %@NL@%
  13721.  
  13722.  
  13723. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13724.  
  13725. %@AB@%EBX%@AE@% = VM Handle  %@NL@%
  13726.  
  13727.  
  13728. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13729.  
  13730. If video access OK  Carry Flag Clear else  Carry Flag Set  %@NL@%
  13731.  
  13732.  
  13733. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13734.  
  13735. Flags Returns error if an attempt  %@NL@%
  13736.  
  13737. %@CR:C6A00350028 @%
  13738. %@2@%%@CR:C6A00350029 @%%@AB@%VDD_Set_HCurTrk%@AE@%%@EH@%%@NL@%
  13739. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13740.  
  13741.  
  13742. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13743.  
  13744. This service sets flag passed to VMDOSAPP indicating that VMDOSAPP should
  13745. maintain the cursor position within the display window for this application.
  13746. This is called by the Keyboard driver when a keyboard interrupt is simulated
  13747. into a VM.  %@NL@%
  13748.  
  13749.  
  13750. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13751.  
  13752. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13753.  
  13754.  
  13755. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13756.  
  13757. None  %@NL@%
  13758.  
  13759.  
  13760. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13761.  
  13762. Flags  %@NL@%
  13763.  
  13764. %@CR:C6A00350030 @%
  13765. %@2@%%@CR:C6A00350031 @%%@AB@%VDD_Set_VMType%@AE@%%@EH@%%@NL@%
  13766. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13767.  
  13768.  
  13769. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13770.  
  13771. This service is used to inform the VDD of a VM's type. The parameter
  13772. explicitly passed is the windowed flag. The VM status flags, Exclusive and
  13773. Background, are implicity passed. This should be called prior to running the
  13774. VM and each time thereafter that any of the VM parameters are modified.
  13775. Notice that, for a system critical %@AB@%Set_Focus%@AE@%, this routine may not be called
  13776. before the %@AB@%Set_Focus%@AE@%. In that case, the VDD is responsible for doing an
  13777. implied %@AB@%Set_VMType%@AE@% (not windowed).  %@NL@%
  13778.  
  13779.  
  13780. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13781.  
  13782. %@AB@%EAX%@AE@% = state flag (= nonzero if changing to windowed VM) %@AB@%EBX%@AE@% = VM handle
  13783. whose state is to change  %@NL@%
  13784.  
  13785.  
  13786. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13787.  
  13788. None  %@NL@%
  13789.  
  13790.  
  13791. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13792.  
  13793. Flags  %@NL@%
  13794.  
  13795. %@CR:C6A00350032 @%
  13796. %@2@%%@CR:C6A00350033 @%%@AB@%VDD_Query_Access%@AE@%%@EH@%%@NL@%
  13797. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13798.  
  13799.  
  13800. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13801.  
  13802. This service is used by the other VxDs when they want to access video
  13803. memory. The VxD should not access video memory unless this routine says it
  13804. is OK.  %@NL@%
  13805.  
  13806.  
  13807. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13808.  
  13809. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13810.  
  13811.  
  13812. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13813.  
  13814. if access is OK, carry flag = 0  else carry flag = 1  %@NL@%
  13815.  
  13816.  
  13817. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13818.  
  13819. Flags  %@NL@%
  13820.  
  13821.  
  13822.  
  13823.  
  13824.  
  13825.  
  13826. %@CR:C6A00360001 @%%@1@%%@AB@%Chapter 36  Virtual Keyboard Device (VKD) Services%@AE@%%@EH@%%@NL@%
  13827. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13828.  
  13829. The Virtual Keyboard Device (VKD) provides services that support hot keys,
  13830. Message Mode key handling, and keyed input to VMs. The services are
  13831. presented in the following order:%@CR:C6A00360002 @%%@NL@%
  13832.  
  13833.  
  13834.   ■   %@AB@%VKD_Cancel_Hot_Key_State%@AE@%%@NL@%
  13835.  
  13836.   ■   %@AB@%VKD_Cancel_Paste%@AE@%%@NL@%
  13837.  
  13838.   ■   %@AB@%VKD_Define_Hot_Key%@AE@%%@NL@%
  13839.  
  13840.   ■   %@AB@%VKD_Define_Paste_Mode%@AE@%%@NL@%
  13841.  
  13842.   ■   %@AB@%VKD_Flush_Msg_Key_Queue%@AE@%%@NL@%
  13843.  
  13844.   ■   %@AB@%VKD_Force_Keys%@AE@%%@NL@%
  13845.  
  13846.   ■   %@AB@%VKD_Get_Kbd_Owner%@AE@%%@NL@%
  13847.  
  13848.   ■   %@AB@%VKD_Get_Msg_Key%@AE@%%@NL@%
  13849.  
  13850.   ■   %@AB@%VKD_Get_Version%@AE@%%@NL@%
  13851.  
  13852.   ■   %@AB@%VKD_Local_Disable_Hot_Key%@AE@%%@NL@%
  13853.  
  13854.   ■   %@AB@%VKD_Local_Enable_Hot_Key%@AE@%%@NL@%
  13855.  
  13856.   ■   %@AB@%VKD_Peek_Msg_Key%@AE@%%@NL@%
  13857.  
  13858.   ■   %@AB@%VKD_Reflect_Hot_Key%@AE@%%@NL@%
  13859.  
  13860.   ■   %@AB@%VKD_Remove_Hot_Key%@AE@%%@NL@%
  13861.  
  13862.   ■   %@AB@%VKD_Start_Paste%@AE@%%@NL@%
  13863.  
  13864.  
  13865. These are protected-mode API services used by WINOLDAP to send keys to a
  13866. windowed VM.  %@NL@%
  13867.  
  13868. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  13869. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  13870.  
  13871. %@CR:C6A00360003 @%
  13872. %@2@%%@CR:C6A00360004 @%%@AB@%VKD_Cancel_Hot_Key_State%@AE@%%@EH@%%@NL@%
  13873. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13874.  
  13875.  
  13876. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13877.  
  13878. This service causes the VKD to exit the hot key state.  %@NL@%
  13879.  
  13880.  
  13881. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13882.  
  13883. None  %@NL@%
  13884.  
  13885.  
  13886. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13887.  
  13888. Keys will start being passed into the focus VM again  %@NL@%
  13889.  
  13890.  
  13891. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13892.  
  13893. None  %@NL@%
  13894.  
  13895. %@CR:C6A00360005 @%
  13896. %@2@%%@CR:C6A00360006 @%%@AB@%VKD_Cancel_Paste%@AE@%%@EH@%%@NL@%
  13897. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13898.  
  13899.  
  13900. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13901.  
  13902. This service cancels the paste that was started in the VM with
  13903. %@AB@%VKD_Start_Paste%@AE@%.  %@NL@%
  13904.  
  13905.  
  13906. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13907.  
  13908. %@AB@%EBX%@AE@% is VM handle  %@NL@%
  13909.  
  13910.  
  13911. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13912.  
  13913. None  %@NL@%
  13914.  
  13915.  
  13916. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13917.  
  13918. Flags  %@NL@%
  13919.  
  13920. %@CR:C6A00360007 @%
  13921. %@2@%%@CR:C6A00360008 @%%@AB@%VKD_Define_Hot_Key%@AE@%%@EH@%%@NL@%
  13922. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13923.  
  13924.  
  13925. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13926.  
  13927. This service defines a hot key notification routine. Hot keys are detected
  13928. by ANDing the shift state mask with the global shift state, then comparing
  13929. the resulting state with the shift state compare value. If this matches, and
  13930. the key code matches, then the callback routine is called with the specified
  13931. reference data in %@AB@%EDX%@AE@%.  %@NL@%
  13932.  
  13933.  
  13934. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13935.  
  13936. %@AB@%AL%@AE@% = scan code of the main key %@AB@%AH%@AE@% = 0, if normal code %@AB@%AH%@AE@% = 1, if extended
  13937. code (ExtendedKey_B) %@AB@%AH%@AE@% = 0FFh, if either (AllowExtended_B) %@AB@%EBX%@AE@% = shift
  13938. state  high word is mask that is ANDed with the global shift state  when
  13939. checking for this hot key; low word is masked shift state  compare value.
  13940. Equates for common shift mask and compare values are    defined in VKD.INC:
  13941. HKSS_Shift for either shift key      HKSS_Ctrl for either control key
  13942. HKSS_Alt for either ALT key    The macro ShiftState is also defined to load
  13943. %@AB@%EBX%@AE@% with the mask    and compare value. e.g.,      ShiftState <SS_ALT +
  13944. SS_Toggle_mask>, SS_RAlt    loads %@AB@%EBX%@AE@% so that the hot key will only be
  13945. recognized when the    Right ALT key is held down.    VKD>INC also defines
  13946. "SS_" equates for the different shift state    bits and common combinations
  13947. of bits. %@AB@%CL%@AE@% = flags  CallOnPress - Call callback when key press is detected
  13948. CallOnRelease - Call callback when key release is  detected  (keyboard may
  13949. still be in hot-key hold  state)  CallOnRepeat - Call callback when repeated
  13950. press is  detected  CallOnComplete - Call callback when the hot key state is
  13951. ended(all shift modifier keys are  released) or when a different hot key is
  13952. entered (i.e. pressing ALT 1 2, if both  ALT+1 and ALT+2 are defined hot
  13953. keys,  then ALT+1's callback will be called  before ALT+2's to indicate that
  13954. the ALT+1  is complete even though the ALT key is  still down)  CallOnUpDwn
  13955. - Call on both press and release  CallOnAll  - Call on press, release and
  13956. repeats  PriorityNotify - Used with one of the call options to  specify that
  13957. the callback can only be  called when interrupts are enabled and the
  13958. critical section is un-owned  Local_Key - Key can be locally
  13959. enabled/disabled  %@NL@%
  13960.  
  13961. %@AB@%ESI%@AE@% = offset of callback routine %@AB@%EDX%@AE@% = reference data %@AB@%EDI%@AE@% = maximum
  13962. notification delay if PriorityNotify is set,  0, means always notify
  13963. (milliseconds)  %@NL@%
  13964.  
  13965.  
  13966. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13967.  
  13968. If Carry clear then  EAX = definition handle else the definition failed (no
  13969. more room)  %@NL@%
  13970.  
  13971.  
  13972. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13973.  
  13974. Flags  %@NL@%
  13975.  
  13976.  
  13977. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  13978.  
  13979. Called when hot key is detected, and detection meets mask requirements.
  13980. (CallOnPress, CallOnRelease, CallOnRepeat, CallOnUpDwn, or CallOnAll)  %@AB@%AL%@AE@% =
  13981. scan code of key  %@AB@%AH%@AE@% = 0, if key just pressed (Hot_Key_Pressed)  = 1, if key
  13982. just released (Hot_Key_Released)  = 2, if key is an auto-repeat press
  13983. (Hot_Key_Repeated)  = 3, hot key state ended (Hot_Key_Completed)  %@AB@%EBX%@AE@% is hot
  13984. key handle  %@AB@%ECX%@AE@% = global shift state  %@AB@%EDX%@AE@% is reference data  %@AB@%EDI%@AE@% = elapsed
  13985. time for delayed notification (milliseconds) (normally 0, but if
  13986. PriorityNotify is specified then this value could be larger) This procedure
  13987. can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI, %@AE@%and Flags%@AB@%  %@AE@%%@NL@%
  13988.  
  13989. %@CR:C6A00360009 @%
  13990. %@2@%%@CR:C6A00360010 @%%@AB@%VKD_Define_Paste_Mode%@AE@%%@EH@%%@NL@%
  13991. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13992.  
  13993.  
  13994. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13995.  
  13996. This service selects the VM's paste mode, whether INT 16 pasting can be
  13997. attempted or not. Some applications hook INT 9 and do things that will not
  13998. allow pasting to be done through INT 16H. Normally, VKD can detect this by
  13999. setting a timeout to see if any INT 16s are being done by the application,
  14000. and if not, then switching to INT 9 paste. But, some applications may do
  14001. some INT 16s, in which case the paste would be broken. Therefore, this
  14002. service is provided to allow the Shell device to force a VM into INT 9
  14003. paste, based only on a PIF bit.  %@NL@%
  14004.  
  14005.  
  14006. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14007.  
  14008. %@AB@%AL%@AE@% = 0 allow INT 16 paste attempts %@AB@%AL%@AE@% = 1 force INT 9 pasting %@AB@%EBX%@AE@% = VM
  14009. handle  %@NL@%
  14010.  
  14011.  
  14012. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14013.  
  14014. None  %@NL@%
  14015.  
  14016.  
  14017. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14018.  
  14019. Flags  %@NL@%
  14020.  
  14021. %@CR:C6A00360011 @%
  14022. %@2@%%@CR:C6A00360012 @%%@AB@%VKD_Flush_Msg_Key_Queue%@AE@%%@EH@%%@NL@%
  14023. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14024.  
  14025.  
  14026. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14027.  
  14028. This service flushes any available keys from the special message mode input
  14029. buffer.  %@NL@%
  14030.  
  14031.  
  14032. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14033.  
  14034. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14035.  
  14036.  
  14037. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14038.  
  14039. Input buffer has been cleared  %@NL@%
  14040.  
  14041.  
  14042. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14043.  
  14044. Flags  %@NL@%
  14045.  
  14046. %@CR:C6A00360013 @%
  14047. %@2@%%@CR:C6A00360014 @%%@AB@%VKD_Force_Keys%@AE@%%@EH@%%@NL@%
  14048. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14049.  
  14050.  
  14051. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14052.  
  14053. This service forces scan codes into the keyboard buffer that look exactly
  14054. like they had been typed on the physical keyboard. These keys will be
  14055. processed in the context of the focus VM.  %@NL@%
  14056.  
  14057.  
  14058. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14059.  
  14060. %@AB@%ESI%@AE@% points to a buffer of scan codes %@AB@%ECX%@AE@% is # of scan codes in the buffer  %@NL@%
  14061.  
  14062.  
  14063. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14064.  
  14065. If the keyboard buffer was overflowed, then  Carry set  ECX is # of
  14066. remaining scan codes that did not fit  %@NL@%
  14067.  
  14068.  
  14069. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14070.  
  14071. %@AB@%ECX%@AE@%,Flags  %@NL@%
  14072.  
  14073. %@CR:C6A00360015 @%
  14074. %@2@%%@CR:C6A00360016 @%%@AB@%VKD_Get_Kbd_Owner%@AE@%%@EH@%%@NL@%
  14075. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14076.  
  14077.  
  14078. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14079.  
  14080. This service gets the VM Handle of the keyboard focus VM.  %@NL@%
  14081.  
  14082.  
  14083. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14084.  
  14085. None  %@NL@%
  14086.  
  14087.  
  14088. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14089.  
  14090. %@AB@%EBX%@AE@% = VM Handle of keyboard owner  %@NL@%
  14091.  
  14092.  
  14093. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14094.  
  14095. Flags, %@AB@%EBX%@AE@%  %@NL@%
  14096.  
  14097. %@CR:C6A00360017 @%
  14098. %@2@%%@CR:C6A00360018 @%%@AB@%VKD_Get_Msg_Key%@AE@%%@EH@%%@NL@%
  14099. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14100.  
  14101.  
  14102. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14103.  
  14104. This service returns the next available key from the special message mode
  14105. input buffer and removes it from the buffer. If no key is available, then it
  14106. returns with the Z flag set. (This is not a blocking read!)  %@NL@%
  14107.  
  14108.  
  14109. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14110.  
  14111. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14112.  
  14113.  
  14114. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14115.  
  14116. Z flag clear, if key was read  AL = scan code  AH = modifier flags  MK_Shift
  14117. - a SHIFT key is down  MK_Ctrl - a CTRL key is down  MK_Alt - an ALT key is
  14118. down  MK_Extended - the key is an extended key  Z flag set, if no key
  14119. available  %@NL@%
  14120.  
  14121.  
  14122. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14123.  
  14124. %@AB@%EAX%@AE@%, Flags  %@NL@%
  14125.  
  14126. %@CR:C6A00360019 @%
  14127. %@2@%%@CR:C6A00360020 @%%@AB@%VKD_Get_Version%@AE@%%@EH@%%@NL@%
  14128. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14129.  
  14130.  
  14131. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14132.  
  14133. This service gets the VKD version number.  %@NL@%
  14134.  
  14135.  
  14136. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14137.  
  14138. None  %@NL@%
  14139.  
  14140.  
  14141. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14142.  
  14143. %@AB@%AH%@AE@% = major, %@AB@%AL%@AE@% = minor Carry Flag clear  %@NL@%
  14144.  
  14145.  
  14146. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14147.  
  14148. %@AB@%EAX%@AE@%, Flags  %@NL@%
  14149.  
  14150. %@CR:C6A00360021 @%
  14151. %@2@%%@CR:C6A00360022 @%%@AB@%VKD_Local_Disable_Hot_Key%@AE@%%@EH@%%@NL@%
  14152. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14153.  
  14154.  
  14155. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14156.  
  14157. This service disables a hot key in the specified VM. It is only allowed on
  14158. hot keys which were declared with the Local_Key bit set in CL.  %@NL@%
  14159.  
  14160.  
  14161. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14162.  
  14163. %@AB@%EAX%@AE@% is hot key handle %@AB@%EBX%@AE@% is VM handle  %@NL@%
  14164.  
  14165.  
  14166. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14167.  
  14168. None  %@NL@%
  14169.  
  14170.  
  14171. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14172.  
  14173. Flags  %@NL@%
  14174.  
  14175. %@CR:C6A00360023 @%
  14176. %@2@%%@CR:C6A00360024 @%%@AB@%VKD_Local_Enable_Hot_Key%@AE@%%@EH@%%@NL@%
  14177. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14178.  
  14179.  
  14180. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14181.  
  14182. This service enables a hot key in the specified VM. It is only allowed on
  14183. hot keys which were declared with the local key bit set in CL.  %@NL@%
  14184.  
  14185.  
  14186. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14187.  
  14188. %@AB@%EAX%@AE@% is hot key handle %@AB@%EBX%@AE@% is VM handle  %@NL@%
  14189.  
  14190.  
  14191. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14192.  
  14193. None  %@NL@%
  14194.  
  14195.  
  14196. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14197.  
  14198. Flags  %@NL@%
  14199.  
  14200. %@CR:C6A00360025 @%
  14201. %@2@%%@CR:C6A00360026 @%%@AB@%VKD_Peek_Msg_Key%@AE@%%@EH@%%@NL@%
  14202. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14203.  
  14204.  
  14205. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14206.  
  14207. This service returns the next available key from the special message mode
  14208. input buffer without removing it from the buffer. If no key is available,
  14209. then it returns with the Z flag set.  %@NL@%
  14210.  
  14211.  
  14212. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14213.  
  14214. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14215.  
  14216.  
  14217. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14218.  
  14219. Z flag clear, if key available  AL = scan code  AH = modifier flags
  14220. MK_Shift - a shift key is down  MK_Ctrl - a control key is down  MK_Alt - an
  14221. alt key is down  MK_Extended - the key is an extended key Z flag set, if no
  14222. key available  %@NL@%
  14223.  
  14224.  
  14225. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14226.  
  14227. %@AB@%EAX%@AE@%, Flags  %@NL@%
  14228.  
  14229. %@CR:C6A00360027 @%
  14230. %@2@%%@CR:C6A00360028 @%%@AB@%VKD_Reflect_Hot_Key%@AE@%%@EH@%%@NL@%
  14231. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14232.  
  14233.  
  14234. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14235.  
  14236. This service reflects a hot key into a specified VM and exits the hot key
  14237. state. This service is normally called by a hot key notification callback
  14238. routine. It enables the callback to send the hot key into a VM and pretend
  14239. that it wasn't really recognized as a hot key. VKD will simulate the
  14240. required key strokes to get the VM into the state of this specified shift
  14241. state, then it will simulate the key strokes for the hot key itself, and
  14242. finally simulate key strokes to get the VM to match the current global shift
  14243. state.  %@NL@%
  14244.  
  14245.  
  14246. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14247.  
  14248. %@AB@%EAX%@AE@% is hot key handle %@AB@%EBX%@AE@% is VM handle %@AB@%CX%@AE@% is required shift state  %@NL@%
  14249.  
  14250.  
  14251. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14252.  
  14253. Hot key has been reflected, and VKD is no longer in hot key state  %@NL@%
  14254.  
  14255.  
  14256. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14257.  
  14258. Flags  %@NL@%
  14259.  
  14260. %@CR:C6A00360029 @%
  14261. %@2@%%@CR:C6A00360030 @%%@AB@%VKD_Remove_Hot_Key%@AE@%%@EH@%%@NL@%
  14262. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14263.  
  14264.  
  14265. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14266.  
  14267. This service removes a defined hot key.  %@NL@%
  14268.  
  14269.  
  14270. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14271.  
  14272. %@AB@%EAX%@AE@% is hot key definition handle to be removed  %@NL@%
  14273.  
  14274.  
  14275. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14276.  
  14277. None  %@NL@%
  14278.  
  14279.  
  14280. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14281.  
  14282. Flags  %@NL@%
  14283.  
  14284. %@CR:C6A00360031 @%
  14285. %@2@%%@CR:C6A00360032 @%%@AB@%VKD_Start_Paste%@AE@%%@EH@%%@NL@%
  14286. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14287.  
  14288.  
  14289. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14290.  
  14291. This service puts a VM into paste mode by simulating keyboard activity with
  14292. keystrokes taken from the specified paste buffer. Depending on the mode set
  14293. with the service %@AB@%VKD_Define_Paste_Mode%@AE@% (default is to try INT 16 pasting),
  14294. VKD waits for the VM to poll the keyboard BIOS through its INT 16 interface.
  14295. If the VM does keyboard input through the BIOS, then VKD will simulate the
  14296. keyboard input at this high level (plugging in ASCII codes.) If the VM fails
  14297. to perform any INT 16s within in a timeout period, or the mode has been set
  14298. to avoid INT 16 pasting, then VKD will simulate the necessary hardware
  14299. interrupts to perform the pasting. Physically typed hot keys are still
  14300. processed while pasting is in progress.  %@NL@%
  14301.  
  14302.  
  14303. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14304.  
  14305. %@AB@%EAX%@AE@% is linear address of paste buffer  the paste buffer contains an array of
  14306. key structures:  OEM_ASCII_value db ?  scan_code db ?  shift_state dw ?
  14307. shift state bits are:  0000000000000010b shift key depressed
  14308. 0000000000000100b ctrl key depressed The scan code should be FFh and the
  14309. shift state FFFFh, if VKD should convert the key to a ALT+numpad sequence.
  14310. (this information is identical to what is given by the Window's keyboard
  14311. routine %@AB@%OEMKeyScan%@AE@%)   %@AB@%EBX%@AE@% is VM handle  %@AB@%ECX%@AE@% is number of paste entries in
  14312. the paste buffer  %@AB@%ESI%@AE@% is call back address (can be 0)  %@AB@%EDX%@AE@% is reference data
  14313. %@NL@%
  14314.  
  14315.  
  14316. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14317.  
  14318. Carry clear paste is started  Carry set paste failed, unable to allocate
  14319. memory for buffer copy  %@NL@%
  14320.  
  14321.  
  14322. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14323.  
  14324. Flags  %@NL@%
  14325.  
  14326.  
  14327. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  14328.  
  14329. Called when paste is completed or cancelled   %@AB@%EAX%@AE@% is completion flags
  14330. %@AB@%Paste_Complete%@AE@% - paste completed successfully   %@AB@%Paste_Aborted%@AE@% - paste
  14331. cancelled by user   %@AB@%Paste_VM_Term%@AE@% - paste aborted because VM terminated
  14332. %@AB@%EBX%@AE@% is VM handle of VM that was receiving the paste   %@AB@%EDX%@AE@% is reference data
  14333. Procedure can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  14334.  
  14335.  
  14336.  
  14337.  
  14338.  
  14339.  
  14340. %@CR:C6A00370001 @%%@1@%%@AB@%Chapter 37  Virtual PIC Device (VPICD) Services%@AE@%%@EH@%%@NL@%
  14341. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14342.  
  14343. The Virtual Programmable Interrupt Controller Device (VPICD) routes hardware
  14344. interrupts to other virtual devices, provides services that allow virtual
  14345. devices to request interrupts, and simulates hardware interrupts into
  14346. virtual machines. See Chapter 16, "Overview of Windows in 386 Enhanced
  14347. Mode," and Chapter 17, "Virtual Device Programming Topics," for general
  14348. discussions of the VPICD.%@CR:C6A00370002 @%%@NL@%
  14349.  
  14350. Peripherals, such as disk drives and COM ports, use hardware (physical)
  14351. interrupts to notify software of changes in their status.  %@NL@%
  14352.  
  14353. The topics in this chapter are presented in the following order:  %@NL@%
  14354.  
  14355.  
  14356.   ■   Default Interrupt Handling%@NL@%
  14357.  
  14358.   ■   Virtualizing an IRQ%@NL@%
  14359.  
  14360.   ■   Virtualized IRQ Callback Procedures%@NL@%
  14361.  
  14362.   ■   VPICD Services%@NL@%
  14363.  
  14364.   ■   Grabber
  14365. %@NL@%
  14366.  
  14367.  
  14368.  
  14369. %@2@%%@CR:C6A00370003 @%%@AB@%37.1  Default Interrupt Handling%@AE@%%@EH@%%@NL@%
  14370.  
  14371. The most basic function of VPICD is to emulate the functions of the physical
  14372. interrupt controller (PIC). This entails reflecting interrupts into virtual
  14373. machines and simulating I/O such as recognizing when a VM issues an EOI (End
  14374. Of Interrupt), reading the mask register, etc. When VPICD is initialized, it
  14375. sets up a default interrupt handler for every Interrupt ReQuest (IRQ). These
  14376. handlers determine which VM an interrupt should be reflected into, and they
  14377. arbitrate conflicts between virtual machines that attempt to unmask the same
  14378. interrupt.  %@NL@%
  14379.  
  14380. An interrupt that is unmasked when enhanced Windows is initialized is
  14381. considered a global interrupt. A global interrupt will always be reflected
  14382. into the currently executing virtual machine, and any VM can mask or unmask
  14383. the IRQ. If a virtual machine unmasks an IRQ that was masked when the
  14384. enhanced Windows environment was initialized, it will own that IRQ. All
  14385. interrupts for an owned IRQ will be reflected only to the IRQ's owner. If
  14386. another virtual machine attempts to unmask the interrupt, the second VM will
  14387. be terminated and the user will see a dialog box that tells him to reboot
  14388. his computer.  %@NL@%
  14389.  
  14390. It is important to remember that this is only the default behavior of VPICD.
  14391. If another virtual device virtualizes an IRQ it is up to the device that
  14392. virtualized the interrupt to determine which VMs receive interrupts and
  14393. arbitrate conflicts. Once an IRQ is virtualized, VPICD's default handling
  14394. for that IRQ stops.  %@NL@%
  14395.  
  14396.  
  14397. %@2@%%@CR:C6A00370004 @%%@AB@%37.2  Virtualizing an IRQ%@AE@%%@EH@%%@NL@%
  14398.  
  14399. When a virtual device needs to hook a specific IRQ (Interrupt ReQuest), it
  14400. must ask VPICD for permission. If another device has already virtualized the
  14401. IRQ, then the call will fail if either of the VxDs is unable to share the
  14402. IRQ (both must have the %@AB@%Can_Share%@AE@% option set for two VxDs to use the same
  14403. IRQ).  %@NL@%
  14404.  
  14405. When a VxD calls%@AB@% VPICD_Virtualize_IRQ%@AE@%, it passes a pointer to a structure
  14406. called an IRQ Descriptor that contains the number of the IRQ and the address
  14407. of several callback procedures. This structure is included in the file
  14408. VPICD.INC:  %@NL@%
  14409.  
  14410. %@AS@%  VPICD_IRQ_Descriptor  STRUC     
  14411. %@AS@%   VID_IRQ_Number       dw   ?     
  14412. %@AS@%   VID_Options          dw   0     
  14413. %@AS@%   VID_Hw_Int_Proc      dd   ?     
  14414. %@AS@%   VID_Virt_Int_Proc    dd   0     
  14415. %@AS@%   VID_EOI_Proc         dd   0     
  14416. %@AS@%   VID_Mask_Change_Proc dd   0     
  14417. %@AS@%   VID_IRET_Proc        dd   0     
  14418. %@AS@%   VID_IRET_Time_Out    dd   500     
  14419. %@AS@%  VPICD_IRQ_Descriptor  ENDS%@AE@%
  14420.  
  14421. The %@AB@%VID_IRQ_Number%@AE@% contains the number of the IRQ the VxD wishes to
  14422. virtualize. %@AB@%VID_Options%@AE@% is a bit field that is used to specify special
  14423. options. The next five fields specify the address of various callback
  14424. procedures. The final field determines the maximum amount of time in
  14425. milliseconds that VPICD will allow before the interrupt is timed-out.
  14426. Time-outs are very important to prevent the enhanced Windows environment
  14427. from hanging while simulating a hardware interrupt.  %@NL@%
  14428.  
  14429.  
  14430. %@2@%%@CR:C6A00370005 @%%@AB@%37.3  Virtualized IRQ Callback Procedures%@AE@%%@EH@%%@NL@%
  14431.  
  14432. A virtual device may specify up to five callback procedures in its
  14433. %@AB@%IRQ_Descriptor%@AE@% structure. One of these, %@AB@%Hw_Int_Proc%@AE@%, is required. The other
  14434. callback procedures are optional and are simply used to inform a virtual
  14435. device whenever the state of the virtualized IRQ changes. For example, the
  14436. %@AB@%Virt_Int_Proc%@AE@% procedure will be called whenever an interrupt is simulated
  14437. into a VM; the %@AB@%Mask_Change_Proc%@AE@% is called whenever a virtual machine masks
  14438. or unmasks the interrupt, etc. Each of the callback procedures is described
  14439. in this section in detail and in alphabetical order. Callback procedures may
  14440. modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, and Flags. Although they will be called with
  14441. interrupts disabled, they are allowed to enable them. If the procedures
  14442. perform a lot of processing, interrupts should be executed.  %@NL@%
  14443.  
  14444. %@CR:C6A00370006 @%
  14445. %@2@%%@CR:C6A00370007 @%%@AB@%VID_Hw_Int_Proc%@AE@%%@EH@%%@NL@%
  14446. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14447.  
  14448.  
  14449. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14450.  
  14451. The %@AB@%VID_Hw_Int_Proc%@AE@% procedure is called whenever a hardware interrupt
  14452. occurs. Notice that the procedure is just that, a procedure that returns
  14453. using a near return ─ not an IRET. Since the the VxD environment kernel is
  14454. single-threaded, the services that this procedure is allowed to call are
  14455. limited because it is possible for an interrupt to occur while executing in
  14456. the VMM. Therefore, many interrupt procedures will need to use the
  14457. %@AB@%Schedule_Call_Global_Event%@AE@% services to perform additional processing of an
  14458. interrupt. A typical %@AB@%VID_Hw_Int_Proc%@AE@% will service the physical device, call
  14459. %@AB@%VPICD_Phys_EOI%@AE@% to end the physical interrupt, and set the virtual IRQ
  14460. request for a specific virtual machine. Some VxDs may never request an
  14461. interrupt for a virtual machine and others may request more than one
  14462. interrupt per physical interrupt. In any case, every physical interrupt does
  14463. not need to be reflected 1-1 into a virtual machine.  %@NL@%
  14464.  
  14465.  
  14466. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14467.  
  14468. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  14469.  
  14470.  
  14471. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14472.  
  14473. If the IRQ is shareable then Carry Set indicates that the interrupt was not
  14474. handled by VxD Carry Clear indicates that the interrupt was handled by VxD  %@NL@%
  14475.  
  14476.  
  14477. %@2@%%@CR:C6A00370008 @%%@AB@%VID_EOI_Proc%@CR:C6A00370009 @%%@AE@%%@EH@%%@NL@%
  14478. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14479.  
  14480.  
  14481. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14482.  
  14483. The %@AB@%VID_EOI_Proc%@AE@% callback is normally used for devices that are partially
  14484. virtualized. For example, the Virtual Mouse Device (VMD) lets the MS-DOS
  14485. mouse driver handle all I/O with the mouse hardware. The VMD just reflects
  14486. the interrupt to the VM that owns the mouse. Since it doesn't service the
  14487. device during the %@AB@%VMD_Hw_Int%@AE@% procedure, it can't call %@AB@%VPICD_Phys_EOI%@AE@% at this
  14488. point (since it's not the end of the interrupt). Once a virtual machine has
  14489. serviced the interrupt, it will issue an EOI and, at this point, the VMD
  14490. calls %@AB@%VPICD_Clear_Int_Request%@AE@% followed by %@AB@%VPICD_Phys_EOI%@AE@%. The default
  14491. interrupt routines need the %@AB@%VID_EOI_Proc%@AE@% callback for the same reason ─ they
  14492. have to wait for the VM to service the interrupting device before they
  14493. physically signal an EOI to the IRQ.  %@NL@%
  14494.  
  14495.  
  14496. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14497.  
  14498. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  14499.  
  14500.  
  14501. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14502.  
  14503. None  %@NL@%
  14504.  
  14505. %@CR:C6A00370010 @%
  14506. %@2@%%@CR:C6A00370011 @%%@AB@%VID_Virt_Int_Proc%@AE@%%@EH@%%@NL@%
  14507. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14508.  
  14509.  
  14510. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14511.  
  14512. The %@AB@%VID_Virt_Int_Proc%@AE@% callback can be useful for implementing critical
  14513. sections around a simulated hardware interrupt. A VxD will request an
  14514. interrupt, and that interrupt may be simulated at a later point in time.
  14515. This callback is issued at the point when the interrupt is actually being
  14516. simulated into the virtual machine. This call is made after the "point of no
  14517. return" has been passed. Therefore, it is impossible for a virtual device to
  14518. stop the interrupt once this call has been issued. A VxD that uses this
  14519. callback will usually also use the %@AB@%VID_Virt_IRET_Proc%@AE@% callback to detect the
  14520. end of the simulated interrupt.  %@NL@%
  14521.  
  14522.  
  14523. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14524.  
  14525. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  14526.  
  14527.  
  14528. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14529.  
  14530. None  %@NL@%
  14531.  
  14532.  
  14533. %@2@%%@CR:C6A00370012 @%%@AB@%VID_IRET_Proc%@CR:C6A00370013 @%%@AE@%%@EH@%%@NL@%
  14534. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14535.  
  14536.  
  14537. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14538.  
  14539. This callback is useful for devices that must simulate large numbers of
  14540. interrupts in a short period of time. For example, the Virtual COM Device
  14541. will simulate an interrupt, allow one character to be read from the COM
  14542. port, and wait for the virtual machine to IRET before putting more data into
  14543. the virtual COM receive buffer. This is because many programs would crash if
  14544. too many bytes of data were queued and shovelled into the virtual machine
  14545. too quickly. The crash would occur because the program's stack would
  14546. overflow. For example, assume that a terminal program has an interrupt
  14547. routine that looks like this:  %@NL@%
  14548.  
  14549. %@AS@%  push      ax               ; (Push AX, DX is the
  14550. %@AS@%       push      dx               ; minimum possible)
  14551. %@AS@%       (Read a byte from the COM port)
  14552. %@AS@%       mov       al, 20h          ; Non-Specific EOI
  14553. %@AS@%       out       20h, al          ; EOI the PIC
  14554. %@AS@%       sti                        ; Enable interrupts
  14555. %@AS@%       (Do other stuff)
  14556. %@AS@%       pop       dx
  14557. %@AS@%       pop       ax
  14558. %@AS@%       iret%@AE@%
  14559.  
  14560. This is a perfectly valid interrupt procedure and, in fact, it is very
  14561. common in actual terminal programs. Now consider what would happen if the
  14562. Virtual COM Device (VCD) had 500 bytes of data queued, and it did not use
  14563. the %@AB@%VID_IRET_Proc%@AE@% callback. When the VM reads a byte of data, VCD puts the
  14564. next byte of data into the receive buffer and request another interrupt.
  14565. When the terminal program executes the STI instruction, VPICD immediately
  14566. simulates another COM interrupt. This sequence of events is repeated 499
  14567. times, each time nesting an interrupt while in the terminal program's
  14568. interrupt routine. The problem is that the IRET frame on the stack requires
  14569. 6 bytes per interrupt, and the 2 pushed registers take up 4 more bytes for a
  14570. total of 10 bytes per interrupt. Since we would nest 500 interrupts, 5K
  14571. bytes of stack space would be required.  %@NL@%
  14572.  
  14573. Since this is obviously unacceptable, VCD waits for the terminal program to
  14574. IRET before simulating another interrupt. The Virtual Timer uses similar
  14575. logic to prevent shoving too many timer interrupts into a virtual machine.  %@NL@%
  14576.  
  14577.  
  14578. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14579.  
  14580. Interrupts Disabled %@AB@%EAX %@AE@%= IRQ handle %@AB@%EBX%@AE@% = Current VM handle If carry is set
  14581. then interrupt timed-out  %@NL@%
  14582.  
  14583.  
  14584. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14585.  
  14586. None  %@NL@%
  14587.  
  14588. %@CR:C6A00370014 @%
  14589. %@2@%%@CR:C6A00370015 @%%@AB@%VID_Mask_Change_Proc%@AE@%%@EH@%%@NL@%
  14590. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14591.  
  14592.  
  14593. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14594.  
  14595. The %@AB@%VID_Mask_Change_Proc%@AE@% is often used to detect contention for a device.
  14596. The default interrupt routines use this callback to detect conflicts with
  14597. nonglobal interrupts.  %@NL@%
  14598.  
  14599.  
  14600. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14601.  
  14602. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = 0 if VM
  14603. is unmasking IRQ,   0 if masking IRQ  %@NL@%
  14604.  
  14605.  
  14606. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14607.  
  14608. None  %@NL@%
  14609.  
  14610.  
  14611. %@2@%%@CR:C6A00370016 @%%@AB@%37.4  VPICD Services%@AE@%%@EH@%%@NL@%
  14612. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14613.  
  14614. This section presents descriptions of the VPICD services in alphabetical
  14615. order.  %@NL@%
  14616.  
  14617. %@CR:C6A00370017 @%
  14618. %@2@%%@CR:C6A00370018 @%%@AB@%VPICD_Call_When_Hw_Int%@AE@%%@EH@%%@NL@%
  14619. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14620.  
  14621.  
  14622. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14623.  
  14624. You must call this procedure with interrupts %@AI@%disabled%@AE@%. This service enables
  14625. other VxDs to be notified when every hardware interrupt occurs. It is
  14626. intended to be used by the Virtual DMA Device (VDMAD) to detect when a DMA
  14627. transfer is complete. However, any VxD can use this service. It should be
  14628. noted though, that since your callback will be called for every hardware
  14629. interrupt, it could have a major performance impact on systems with devices
  14630. that interrupt frequently. Therefore, you should avoid using this service.  %@NL@%
  14631.  
  14632. A callback installed by this service is responsible for chaining to the next
  14633. handler in the interrupt filter chain, and it must preserve the %@AB@%EBX%@AE@% register
  14634. for the next handler.  %@NL@%
  14635.  
  14636. %@AS@%  Sample_Hook_Init:
  14637. %@AS@%        pushfd
  14638. %@AS@%        cli
  14639. %@AS@%        mov     esi, OFFSET32 My_Int_Hook
  14640. %@AS@%        VxDcall VPICD_Call_When_Hw_Int
  14641. %@AS@%        popfd
  14642. %@AS@%        mov     [Next_Int_Hook_Addr], esi
  14643. %@AS@%        clc
  14644. %@AS@%        ret
  14645. %@AS@%  
  14646. %@AS@%      My_Int_Hook:
  14647. %@AS@%        push    ebx
  14648. %@AS@%        (Do something useful here)
  14649. %@AS@%        pop     ebx
  14650. %@AS@%        jmp     [Next_Int_Hook_Addr]%@AE@%
  14651.  
  14652.  
  14653. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14654.  
  14655. %@AB@%ESI%@AE@% -> Procedure to call  %@NL@%
  14656.  
  14657.  
  14658. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14659.  
  14660. %@AB@%ESI%@AE@% -> Procedure to chain to  %@NL@%
  14661.  
  14662.  
  14663. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14664.  
  14665. %@AB@%ESI%@AE@%, Flags  %@NL@%
  14666.  
  14667.  
  14668. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  14669.  
  14670. %@AB@%EBX%@AE@% = %@AB@%Cur_VM_Handle%@AE@%  %@NL@%
  14671.  
  14672. %@CR:C6A00370019 @%
  14673. %@2@%%@CR:C6A00370020 @%%@AB@%VPICD_Clear_Int_Request%@AE@%%@EH@%%@NL@%
  14674. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14675.  
  14676.  
  14677. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14678.  
  14679. This service resets an IRQ request that was previously set by a call to
  14680. %@AB@%VPICD_Set_Int_Request%@AE@%. If the IRQ is being shared with another device, then
  14681. this service may not reset the virtual request if another device has also
  14682. set the virtual IRQ. However, the request will be cleared when all devices
  14683. that have called %@AB@%Set_Int_Request%@AE@% call this service.  %@NL@%
  14684.  
  14685.  
  14686. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14687.  
  14688. %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14689.  
  14690.  
  14691. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14692.  
  14693. Virtual IRQ request is cleared  %@NL@%
  14694.  
  14695.  
  14696. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14697.  
  14698. Flags  %@NL@%
  14699.  
  14700. %@CR:C6A00370021 @%
  14701. %@2@%%@CR:C6A00370022 @%%@AB@%VPICD_Convert_Handle_To_IRQ%@AE@%%@EH@%%@NL@%
  14702. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14703.  
  14704.  
  14705. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14706.  
  14707. This service returns the number of the IRQ for the IRQ handle in %@AB@%EAX%@AE@%.  %@NL@%
  14708.  
  14709.  
  14710. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14711.  
  14712. %@AB@%EAX%@AE@% = IRQ Handle  %@NL@%
  14713.  
  14714.  
  14715. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14716.  
  14717. %@AB@%ESI%@AE@% = IRQ Number  %@NL@%
  14718.  
  14719.  
  14720. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14721.  
  14722. %@AB@%ESI%@AE@%, Flags  %@NL@%
  14723.  
  14724. %@CR:C6A00370023 @%
  14725. %@2@%%@CR:C6A00370024 @%%@AB@%VPICD_Convert_Int_To_IRQ%@AE@%%@EH@%%@NL@%
  14726. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14727.  
  14728.  
  14729. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14730.  
  14731. This service takes an interrupt vector number and returns the number of the
  14732. IRQ that is mapped to that interrupt. For example, INT 8 will typically be
  14733. converted to IRQ 0. However, VMs are allowed to remap the virtual PIC to any
  14734. interrupt vector they wish. Therefore, devices should never make assumptions
  14735. about to which interrupt vector a particular IRQ is mapped.  %@NL@%
  14736.  
  14737.  
  14738. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14739.  
  14740. %@AB@%EAX%@AE@% = Interrupt vector number  %@NL@%
  14741.  
  14742.  
  14743. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14744.  
  14745. If carry is clear then  EAX = IRQ number else  Interrupt vector not mapped
  14746. to any IRQ  %@NL@%
  14747.  
  14748.  
  14749. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14750.  
  14751. None  %@NL@%
  14752.  
  14753. %@CR:C6A00370025 @%
  14754. %@2@%%@CR:C6A00370026 @%%@AB@%VPICD_Convert_IRQ_To_Int%@AE@%%@EH@%%@NL@%
  14755. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14756.  
  14757.  
  14758. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14759.  
  14760. This service accepts an IRQ number and returns an interrupt vector number
  14761. for a specified VM. For example, typically IRQ 0 will be converted to INT 8
  14762. on an IBM PC. However, VMs are allowed to remap the virtual PIC to any
  14763. interrupt vector they wish. Therefore, devices should never make assumptions
  14764. about to which interrupt vector a particular IRQ is mapped.  %@NL@%
  14765.  
  14766.  
  14767. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14768.  
  14769. %@AB@%EAX%@AE@% = IRQ number ─ NOT HANDLE! %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14770.  
  14771.  
  14772. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14773.  
  14774. %@AB@%EAX%@AE@% = Interrupt vector  %@NL@%
  14775.  
  14776.  
  14777. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14778.  
  14779. %@AB@%EAX%@AE@%, Flags  %@NL@%
  14780.  
  14781. %@CR:C6A00370027 @%
  14782. %@2@%%@CR:C6A00370028 @%%@AB@%VPICD_Get_Complete_Status%@AE@%%@EH@%%@NL@%
  14783. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14784.  
  14785. Refer to %@AB@%VPICD_Get_Status%@AE@% for description.  %@NL@%
  14786.  
  14787. %@CR:C6A00370029 @%
  14788. %@2@%%@CR:C6A00370030 @%%@AB@%VPICD_Get_IRQ_Complete_Status%@AE@%%@EH@%%@NL@%
  14789. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14790.  
  14791.  
  14792. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14793.  
  14794. This service is similar to %@AB@%VPICD_Get_Complete_Status%@AE@% except that it takes an
  14795. IRQ number as a parameter instead of an IRQ handle. This is useful for
  14796. devices to inspect an IRQ before attempting to virtualize it or for
  14797. inspecting the state of another device's interrupt. Also, since it indicates
  14798. whether or not an IRQ has been virtualized already, it can be used by
  14799. devices to prevent conflicts when more than one device may want to use an
  14800. IRQ.  %@NL@%
  14801.  
  14802.  
  14803. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14804.  
  14805. %@AB@%EAX%@AE@% = IRQ number  %@NL@%
  14806.  
  14807.  
  14808. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14809.  
  14810. %@AB@%ECX%@AE@% = Status as described for %@AB@%VPICD_Get_Complete_Status%@AE@%  %@NL@%
  14811.  
  14812. %@AS@%  If the carry flag is set then
  14813. %@AS@%      The IRQ has been virtualized 
  14814. %@AS@%  else
  14815. %@AS@%      The IRQ has not been virtualized%@AE@%
  14816.  
  14817.  
  14818. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14819.  
  14820. %@AB@%ECX%@AE@%, Flags  %@NL@%
  14821.  
  14822. %@CR:C6A00370031 @%
  14823. %@2@%%@CR:C6A00370032 @%%@AB@%VPICD_Get_Status%@AE@%%@EH@%%@NL@%
  14824. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14825.  
  14826.  
  14827. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14828.  
  14829. These services return the status of a virtual IRQ for a specified VM. The
  14830. status returned in %@AB@%ECX%@AE@% is defined by equates in the VPICD.INC file.
  14831. %@AB@%VPICD_Get_Status%@AE@% will only return the Virtual %@AB@%In_Service%@AE@% and %@AB@%IRET_Pending%@AE@%
  14832. status bits. %@AB@%VPICD_Get_Complete_Status%@AE@% will return with all status bits
  14833. defined. The shorter version is supplied because it is much faster, and the
  14834. status returned contains the most commonly used information.  %@NL@%
  14835.  
  14836.  
  14837. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14838.  
  14839. %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14840.  
  14841.  
  14842. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14843.  
  14844. %@AB@%ECX%@AE@% = Status flags (see equates VPICD.INI)  %@NL@%
  14845.  
  14846. %@TH:  10   518 02 16 60 @%
  14847. Bit             Description
  14848. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14849. 0 = 1           A Virtual IRET is pending
  14850. 1 = 1           The IRQ is virtually in service
  14851. 2 = 1           The IRQ is physically masked
  14852. 3 = 1           The IRQ is physically in service
  14853. 4 = 1           VM has masked the IRQ
  14854. 5 = 1           The Virtual IRQ is set (by any VxD)
  14855. 6 = 1           The physical IRQ is set
  14856. 7 = 1           Tha calling VxD's Virtual IRQ is set
  14857. %@TE:  10   518 02 16 60 @%
  14858.  
  14859.  
  14860. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14861.  
  14862. %@AB@%ECX%@AE@%, Flags  %@NL@%
  14863.  
  14864. %@CR:C6A00370033 @%
  14865. %@2@%%@CR:C6A00370034 @%%@AB@%VPICD_Get_Version%@AE@%%@EH@%%@NL@%
  14866. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14867.  
  14868.  
  14869. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14870.  
  14871. This service returns the VPICD major and minor version numbers.  %@NL@%
  14872.  
  14873.  
  14874. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14875.  
  14876. None  %@NL@%
  14877.  
  14878.  
  14879. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14880.  
  14881. %@AB@%AH%@AE@% = Major version %@AB@%AL%@AE@% = Minor version %@AB@%EBX%@AE@% = Flags  Bit 0 = 1 - Master/Slave
  14882. PC/AT type configuration  0 - PC/XT type single PIC configuration  Other
  14883. bits reserved for future versions. %@AB@%ECX%@AE@% = Maximum IRQ supported (07H or 0FH)
  14884. Carry flag clear  %@NL@%
  14885.  
  14886.  
  14887. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14888.  
  14889. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, Flags  %@NL@%
  14890.  
  14891. %@CR:C6A00370035 @%
  14892. %@2@%%@CR:C6A00370036 @%%@AB@%VPICD_Phys_EOI%@AE@%%@EH@%%@NL@%
  14893. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14894.  
  14895.  
  14896. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14897.  
  14898. Calling this procedure will end a physical interrupt and will allow further
  14899. hardware interrupts from the specified IRQ. Notice that an interrupt that is
  14900. physically in service will %@AI@%not%@AE@% suppress interrupts to "lower priority" IRQs,
  14901. since VPICD does not prioritize hardware interrupts. Therefore, it is
  14902. acceptable for an interrupt to be physically in service for an arbitrary
  14903. length of time.  %@NL@%
  14904.  
  14905.  
  14906. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14907.  
  14908. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14909.  
  14910.  
  14911. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14912.  
  14913. None  %@NL@%
  14914.  
  14915.  
  14916. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14917.  
  14918. Flags  %@NL@%
  14919.  
  14920. %@CR:C6A00370037 @%
  14921. %@2@%%@CR:C6A00370038 @%%@AB@%VPICD_Physically_Mask%@AE@%%@EH@%%@NL@%
  14922. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14923.  
  14924.  
  14925. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14926.  
  14927. This service will mask the specified IRQ on the hardware PIC. This will
  14928. suppress all hardware interrupts on the IRQ until %@AB@%VPICD_Physically_Unmask%@AE@% or
  14929. %@AB@%VPICD_Set_Auto_Masking%@AE@% is called.  %@NL@%
  14930.  
  14931.  
  14932. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14933.  
  14934. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14935.  
  14936.  
  14937. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14938.  
  14939. IRQ is masked  %@NL@%
  14940.  
  14941.  
  14942. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14943.  
  14944. Flags  %@NL@%
  14945.  
  14946. %@CR:C6A00370039 @%
  14947. %@2@%%@CR:C6A00370040 @%%@AB@%VPICD_Physically_Unmask%@AE@%%@EH@%%@NL@%
  14948. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14949.  
  14950.  
  14951. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14952.  
  14953. This service will unmask the specified IRQ on the hardware PIC regardless of
  14954. the mask state of virtual machines. This means that even if every VM has
  14955. masked the virtual IRQ, the physical IRQ will remain unmasked.  %@NL@%
  14956.  
  14957.  
  14958. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14959.  
  14960. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14961.  
  14962.  
  14963. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14964.  
  14965. IRQ is masked  %@NL@%
  14966.  
  14967.  
  14968. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14969.  
  14970. Flags  %@NL@%
  14971.  
  14972. %@CR:C6A00370041 @%
  14973. %@2@%%@CR:C6A00370042 @%%@AB@%VPICD_Set_Auto_Masking%@AE@%%@EH@%%@NL@%
  14974. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14975.  
  14976.  
  14977. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14978.  
  14979. Automatic masking is the default state for every IRQ. It can be overridden
  14980. by %@AB@%VPICD_Physically_Mask/Unmask%@AE@%. When automatic masking is used, the state
  14981. of the physical mask is determined by the state of every virtual machine's
  14982. virtual mask. If at least one VM has the IRQ unmasked, then the physical IRQ
  14983. will remain unmasked. Otherwise, the IRQ will be masked on the hardware PIC.
  14984. %@NL@%
  14985.  
  14986.  
  14987. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14988.  
  14989. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14990.  
  14991.  
  14992. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14993.  
  14994. IRQ will be physically unmasked if at least one VM has unmasked the IRQ.  %@NL@%
  14995.  
  14996.  
  14997. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14998.  
  14999. Flags  %@NL@%
  15000.  
  15001. %@CR:C6A00370043 @%
  15002. %@2@%%@CR:C6A00370044 @%%@AB@%VPICD_Set_Int_Request%@AE@%%@EH@%%@NL@%
  15003. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15004.  
  15005.  
  15006. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15007.  
  15008. This service sets the virtual interrupt request for the specified IRQ and
  15009. VM. It may cause an interrupt to be simulated immediately. However, in many
  15010. cases, the interrupt will %@AI@%not%@AE@% be simulated until a later point in time. The
  15011. interrupt will not be simulated immediately if:  %@NL@%
  15012.  
  15013.  
  15014.   ■   The virtual machine has interrupts disabled. %@NL@%
  15015.  
  15016.   ■   The virtual machine has masked the IRQ. %@NL@%
  15017.  
  15018.   ■   A higher priority virtual IRQ is in service. %@NL@%
  15019.  
  15020.   ■   It is not possible to run the specified VM (it is suspended, etc). %@NL@%
  15021.  
  15022.   ■   There are other reasons the interrupt may be postponed.%@NL@%
  15023.  
  15024.  
  15025. However, since the interrupt may be simulated immediately, virtual devices
  15026. that have a virtual interrupt handler must be able to handle the case when
  15027. their virtual interrupt procedure is called before this service returns.  %@NL@%
  15028.  
  15029. Setting an interrupt request is not a guarantee that the interrupt will ever
  15030. be simulated. For example, if the VM has masked the interrupt and never
  15031. unmasks it, the interrupt will never be simulated. Also, a call to
  15032. %@AB@%VPICD_Clear_Int_Request%@AE@% that is made before the virtual interrupt is
  15033. simulated will prevent the interrupt simulation.  %@NL@%
  15034.  
  15035. It is important to keep in mind that VPICD simulates a level triggered PIC.
  15036. This means that once a virtual EOI occurs, another interrupt will be
  15037. simulated immediately unless the virtual interrupt request is cleared.  %@NL@%
  15038.  
  15039.  
  15040. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15041.  
  15042. %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  15043.  
  15044.  
  15045. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15046.  
  15047. Virtual IRQ request is set  %@NL@%
  15048.  
  15049.  
  15050. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15051.  
  15052. Flags  %@NL@%
  15053.  
  15054. %@CR:C6A00370045 @%
  15055. %@2@%%@CR:C6A00370046 @%%@AB@%VPICD_Test_Phys_Request%@AE@%%@EH@%%@NL@%
  15056. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15057.  
  15058.  
  15059. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15060.  
  15061. This service will return with Carry set if the physical (hardware PIC)
  15062. interrupt request is set for the specified IRQ.  %@NL@%
  15063.  
  15064.  
  15065. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15066.  
  15067. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  15068.  
  15069.  
  15070. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15071.  
  15072. Carry flag = Physical Interrupt Request state  %@NL@%
  15073.  
  15074.  
  15075. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15076.  
  15077. Flags  %@NL@%
  15078.  
  15079. %@CR:C6A00370047 @%
  15080. %@2@%%@CR:C6A00370048 @%%@AB@%VPICD_Virtualize_IRQ%@AE@%%@EH@%%@NL@%
  15081. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15082.  
  15083.  
  15084. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15085.  
  15086. This is not an async service; it cannot be called during an interrupt. This
  15087. service is used to gain access to a specified virtual interrupt request. The
  15088. caller passes this procedure a pointer to the IRQ descriptor (the structure
  15089. declared in VPICD.INC) which specifies:  %@NL@%
  15090.  
  15091.  
  15092.   ■   IRQ number (required)%@NL@%
  15093.  
  15094.   ■   Options%@NL@%
  15095.  
  15096.   ■   Hardware interrupt handler (required)%@NL@%
  15097.  
  15098.   ■   Virtual interrupt handler%@NL@%
  15099.  
  15100.   ■   Virtual EOI handler%@NL@%
  15101.  
  15102.   ■   Virtual mask change handler%@NL@%
  15103.  
  15104.   ■   Virtual IRET handler%@NL@%
  15105.  
  15106.   ■   Virtual IRET time-out (0 for no time-out)%@NL@%
  15107.  
  15108.  
  15109. For more information on the various options and parameters to this service
  15110. see Section 37.3 "Virtualizing an IRQ," earlier in this chapter. When this
  15111. service returns, if Carry is set, then the IRQ cannot be virtualized.
  15112. Otherwise, %@AB@%EAX%@AE@% contains an IRQ handle. This handle is used for all
  15113. subsequent communication with VPICD.  %@NL@%
  15114.  
  15115. If every device that virtualizes the IRQ has the %@AB@%Can_Share%@AE@% option set then
  15116. the IRQ can be shared by up to 32 devices.  %@NL@%
  15117.  
  15118.  
  15119. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15120.  
  15121. %@AB@%EDI%@AE@% -> %@AB@%VPICD_IRQ_Descriptor%@AE@%  %@NL@%
  15122.  
  15123.  
  15124. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15125.  
  15126. If carry clear then  EAX = IRQ Handle else  Error ─ Handle already allocated
  15127. or invalid IRQ #  %@NL@%
  15128.  
  15129.  
  15130. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15131.  
  15132. %@AB@%EAX%@AE@% , Flags  %@NL@%
  15133.  
  15134.  
  15135.  
  15136.  
  15137.  
  15138.  
  15139. %@CR:C6A00380001 @%%@1@%%@AB@%Chapter 38  Virtual Sound Device (VSD) Services%@AE@%%@EH@%%@NL@%
  15140. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15141.  
  15142. These two services enable VxDs to generate a warning beep or return the VSD
  15143. version number:%@CR:C6A00380002 @%%@NL@%
  15144.  
  15145.  
  15146.   ■   %@AB@%VSD_Bell%@AE@%%@NL@%
  15147.  
  15148.   ■   %@AB@%VSD_Get_Version%@AE@%%@NL@%
  15149.  
  15150.  
  15151. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  15152. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  15153.  
  15154.  
  15155. %@2@%%@CR:C6A00380003 @%%@AB@%VSD_Bell%@CR:C6A00380004 @%%@AE@%%@EH@%%@NL@%
  15156. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15157.  
  15158.  
  15159. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15160.  
  15161. This service is provided so that devices can generate a warning beep. This
  15162. is normally used when the user presses an invalid key or when an error
  15163. occurs. Notice that this service will produce a 1/2-second tone, but it will
  15164. then return immediately (it does not busy wait).  %@NL@%
  15165.  
  15166.  
  15167. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15168.  
  15169. None  %@NL@%
  15170.  
  15171.  
  15172. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15173.  
  15174. None  %@NL@%
  15175.  
  15176.  
  15177. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15178.  
  15179. Flags  %@NL@%
  15180.  
  15181. %@CR:C6A00380005 @%
  15182. %@2@%%@CR:C6A00380006 @%%@AB@%VSD_Get_Version%@AE@%%@EH@%%@NL@%
  15183. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15184.  
  15185.  
  15186. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15187.  
  15188. This service returns the version number of the Virtual Sound Device.  %@NL@%
  15189.  
  15190.  
  15191. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15192.  
  15193. None  %@NL@%
  15194.  
  15195.  
  15196. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15197.  
  15198. AH = Major version number AL = Minor version number Carry flag clear  %@NL@%
  15199.  
  15200.  
  15201. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15202.  
  15203. %@AB@%EAX%@AE@%, Flags  %@NL@%
  15204.  
  15205.  
  15206.  
  15207.  
  15208.  
  15209.  
  15210. %@CR:C6A00390001 @%%@1@%%@AB@%Chapter 39  Virtual Timer Device (VTD) Services%@AE@%%@EH@%%@NL@%
  15211. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15212.  
  15213. This chapter presents descriptions of the following VTD services:%@CR:C6A00390002 @%%@NL@%
  15214.  
  15215.  
  15216.   ■   %@AB@%VTD_Begin_Min_Int_Period%@AE@%%@NL@%
  15217.  
  15218.   ■   %@AB@%VTD_Disable_Trapping%@AE@%%@NL@%
  15219.  
  15220.   ■   %@AB@%VTD_Enable_Trapping%@AE@%%@NL@%
  15221.  
  15222.   ■   %@AB@%VTD_End_Min_Int_Period%@AE@%%@NL@%
  15223.  
  15224.   ■   %@AB@%VTD_Get_Interrupt_Rate%@AE@%%@NL@%
  15225.  
  15226.   ■   %@AB@%VTD_Get_Version%@AE@%%@NL@%
  15227.  
  15228.   ■   %@AB@%VTD_Update_System_Clock%@AE@%%@NL@%
  15229.  
  15230.  
  15231. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  15232. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  15233.  
  15234. %@CR:C6A00390003 @%
  15235. %@2@%%@CR:C6A00390004 @%%@AB@%VTD_Begin_Min_Int_Period%@AE@%%@EH@%%@NL@%
  15236. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15237.  
  15238.  
  15239. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15240.  
  15241. This service is used by VxDs to ensure a minimum accuracy for system timing.
  15242. When this service is called, if the interrupt period specified is lower than
  15243. the current timer interrupt period, the interrupt period will be set to the
  15244. new frequency.  %@NL@%
  15245.  
  15246. Until a matching %@AB@%VTD_End_Min_Int_Period%@AE@% call is made, the timer interrupt
  15247. period is guaranteed never to be slower than the value specified.  %@NL@%
  15248.  
  15249. A VxD should call this service only once before calling
  15250. %@AB@%VTD_End_Min_Int_Period%@AE@%.  %@NL@%
  15251.  
  15252. Typically the %@AB@%Begin/End_Min_Int_Period%@AE@% services are used by devices such as
  15253. execution profilers that need extremely accurate timing. VMM system time-out
  15254. services rely on the VTD to keep time. Therefore, more frequent timer
  15255. interrupts will allow the time out services to be more accurate.  %@NL@%
  15256.  
  15257. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15258. %@AU@%WARNING%@AE@%
  15259.  
  15260. Fast timer interrupt periods can be very, very expensive in terms of total
  15261. system performance. For example, on some machines a timer interrupt of 1
  15262. millisecond will degrade total machine throughput by 10 percent and disk I/O
  15263. by up to 50 percent.
  15264. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15265.  
  15266.  
  15267. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15268.  
  15269. %@AB@%EAX %@AE@%= Desired interrupt period  %@NL@%
  15270.  
  15271.  
  15272. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15273.  
  15274. If carry clear then  Interrupt period set else  Specified interrupt period
  15275. is not valid  %@NL@%
  15276.  
  15277.  
  15278. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15279.  
  15280. Flags  %@NL@%
  15281.  
  15282. %@CR:C6A00390005 @%
  15283. %@2@%%@CR:C6A00390006 @%%@AB@%VTD_Disable_Trapping%@AE@%%@EH@%%@NL@%
  15284. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15285.  
  15286.  
  15287. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15288.  
  15289. This service will force VTD to stop I/O trapping on the timer ports for a
  15290. specified virtual machine. %@AB@%VTD_Enable_Trapping%@AE@% must be called once for every
  15291. call made to this service. By default, timer port trapping is enabled when a
  15292. VM is created.  %@NL@%
  15293.  
  15294. It is sometimes necessary to disable temporarily I/O trapping for virtual
  15295. machine code that reads the timer in extremely tight timing loops. A good
  15296. example is the hard disk BIOS code that reads the ports hundreds of times
  15297. per disk transfer. The overhead for servicing the I/O traps would cause disk
  15298. performance to slow to a crawl.  %@NL@%
  15299.  
  15300. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15301. %@AU@%WARNING%@AE@%
  15302.  
  15303. This service must be used very carefully. If a VM reprograms the timer while
  15304. port trapping is disabled, system timing will behave randomly. Only
  15305. "trusted" code should be executed when timer port trapping is disabled.
  15306. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15307.  
  15308. If this service is called N times, then %@AB@%VTD_Enable_Trapping%@AE@% must also be
  15309. called N times before trapping is reenabled. This allows nested calls to
  15310. this service by more than one VxD.  %@NL@%
  15311.  
  15312.  
  15313. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15314.  
  15315. %@AB@%EBX %@AE@%= VM handle  %@NL@%
  15316.  
  15317.  
  15318. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15319.  
  15320. None  %@NL@%
  15321.  
  15322.  
  15323. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15324.  
  15325. Flags  %@NL@%
  15326.  
  15327. %@CR:C6A00390007 @%
  15328. %@2@%%@CR:C6A00390008 @%%@AB@%VTD_Enable_Trapping%@AE@%%@EH@%%@NL@%
  15329. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15330.  
  15331.  
  15332. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15333.  
  15334. This service must be called to re-enable timer I/O port trapping after
  15335. calling %@AB@%VTD_Disable_Trapping%@AE@%. Notice that this call must be made once for
  15336. every call to %@AB@%VTD_Disable_Trapping%@AE@%. Only when every disable call has been
  15337. matched by a call to this service will port trapping be reenabled.  %@NL@%
  15338.  
  15339.  
  15340. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15341.  
  15342. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  15343.  
  15344.  
  15345. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15346.  
  15347. None  %@NL@%
  15348.  
  15349.  
  15350. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15351.  
  15352. Flags  %@NL@%
  15353.  
  15354. %@CR:C6A00390009 @%
  15355. %@2@%%@CR:C6A00390010 @%%@AB@%VTD_End_Min_Int_Period%@AE@%%@EH@%%@NL@%
  15356. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15357.  
  15358.  
  15359. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15360.  
  15361. This service allows a device to "unrequest" a timer interrupt period that it
  15362. set earlier through the %@AB@%VTD_Begin_Min_Int_Period%@AE@% service. See the
  15363. documentation for %@AB@%VTD_Begin_Min_Int_Period%@AE@% earlier in this chapter for more
  15364. information on the proper use of this service.  %@NL@%
  15365.  
  15366.  
  15367. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15368.  
  15369. %@AB@%EAX%@AE@% = Value passed earlier to %@AB@%Begin_Begin_Min_Int_Period%@AE@%  %@NL@%
  15370.  
  15371.  
  15372. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15373.  
  15374. %@AS@%  If carry clear then
  15375. %@AS@%      Interrupt period request removed successfully
  15376. %@AS@%  else 
  15377. %@AS@%      Specified interrupt period is not valid%@AE@%
  15378.  
  15379.  
  15380. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15381.  
  15382. Flags  %@NL@%
  15383.  
  15384. %@CR:C6A00390011 @%
  15385. %@2@%%@CR:C6A00390012 @%%@AB@%VTD_Get_Interrupt_Period%@AE@%%@EH@%%@NL@%
  15386. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15387.  
  15388.  
  15389. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15390.  
  15391. This service returns the current timer interrupt period.  %@NL@%
  15392.  
  15393.  
  15394. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15395.  
  15396. None  %@NL@%
  15397.  
  15398.  
  15399. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15400.  
  15401. %@AB@%EAX %@AE@%= Length of time between ticks in milliseconds  %@NL@%
  15402.  
  15403.  
  15404. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15405.  
  15406. Flags  %@NL@%
  15407.  
  15408. %@CR:C6A00390013 @%
  15409. %@2@%%@CR:C6A00390014 @%%@AB@%VTD_Get_Version%@AE@%%@EH@%%@NL@%
  15410. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15411.  
  15412.  
  15413. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15414.  
  15415. This service returns the version number and the range of interrupt periods
  15416. allowable by this device.  %@NL@%
  15417.  
  15418.  
  15419. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15420.  
  15421. None  %@NL@%
  15422.  
  15423.  
  15424. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15425.  
  15426. %@AB@%EAX%@AE@% = Version number (AH = Major, AL = Minor) %@AB@%EBX%@AE@% = Fastest possible
  15427. interrupt period in milliseconds %@AB@%ECX%@AE@% = Slowest possible interrupt period in
  15428. milliseconds Carry flag clear  %@NL@%
  15429.  
  15430.  
  15431. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15432.  
  15433. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, Flags  %@NL@%
  15434.  
  15435. %@CR:C6A00390015 @%
  15436. %@2@%%@CR:C6A00390016 @%%@AB@%VTD_Update_System_Clock%@AE@%%@EH@%%@NL@%
  15437. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15438.  
  15439.  
  15440. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15441.  
  15442. This service should %@AI@%only%@AE@% be called by the VMM. Devices should call the
  15443. %@AB@%Get_System_Time%@AE@% VMM service. The VMM will then call this service to update
  15444. the system clock.  %@NL@%
  15445.  
  15446.  
  15447. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15448.  
  15449. None  %@NL@%
  15450.  
  15451.  
  15452. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15453.  
  15454. None  %@NL@%
  15455.  
  15456.  
  15457. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15458.  
  15459. Flags  %@NL@%
  15460.  
  15461.  
  15462.  
  15463.  
  15464.  
  15465.  
  15466. %@CR:C6A00400001 @%%@1@%%@AB@%Chapter 40  V86 Mode Memory Manager Device Services%@AE@%%@EH@%%@NL@%
  15467. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15468.  
  15469. The V86MMGR is responsible for managing memory in the Virtual 8086 portion
  15470. of each VM. It supports EMS and XMS, is responsible for allocating the base
  15471. memory for VMs when they are created, and translates APIs from
  15472. protected-mode applications into V86 calls for other VxDs.%@CR:C6A00400002 @%%@NL@%
  15473.  
  15474. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  15475. "Virtual Device Programming Topics," for general environment discussions.
  15476. Other chapters that discuss memory management are Chapter 19, "Memory
  15477. Management Services," and Chapter 6, "Network Support," in the %@AI@%Microsoft
  15478. %@AI@%Windows Device Driver Adaptation Guide%@AE@%. Memory management is also discussed
  15479. in the %@AI@%Microsoft Windows Software Development Kit, Programming Tools%@AE@%.  %@NL@%
  15480.  
  15481. The V86MMGR services are presented as follows:  %@NL@%
  15482.  
  15483.  
  15484.   ■   Initialization Services%@NL@%
  15485.  
  15486. %@STUB@%      %@AB@%V886MMGR_Get_Version%@AE@%%@NL@%
  15487.  
  15488. %@STUB@%      %@AB@%V86MMGR_Allocate_V86_Pages%@AE@%%@NL@%
  15489.  
  15490. %@STUB@%      %@AB@%V86MMGR_Set_EMS_XMS_Limits%@AE@%%@NL@%
  15491.  
  15492. %@STUB@%      %@AB@%V86MMGR_Get_EMS_XMS_Limits%@AE@%%@NL@%
  15493.  
  15494.   ■   API Translation and Mapping Services%@NL@%
  15495.  
  15496. %@STUB@%      %@AB@%V886MMGR_Set_Mapping_Info%@AE@%%@NL@%
  15497.  
  15498. %@STUB@%      %@AB@%V86MMGR_Xlat_API%@AE@%%@NL@%
  15499.  
  15500. %@STUB@%      %@AB@%V86MMGR_Load_Client_Ptr%@AE@%%@NL@%
  15501.  
  15502. %@STUB@%      %@AB@%V86MMGR_Allocate_Buffer%@AE@%%@NL@%
  15503.  
  15504. %@STUB@%      %@AB@%V886MMGR_Free_Buffer%@AE@%%@NL@%
  15505.  
  15506. %@STUB@%      %@AB@%V86MMGR_Get_Xlat_Buff_State%@AE@%%@NL@%
  15507.  
  15508. %@STUB@%      %@AB@%V86MMGR_Set_Xlat_Buff_State%@AE@%%@NL@%
  15509.  
  15510. %@STUB@%      %@AB@%V86MMGR_Get_VM_Flat_Sel%@AE@%%@NL@%
  15511.  
  15512. %@STUB@%      %@AB@%V86MMGR_Get_Mapping_Info%@AE@%%@NL@%
  15513.  
  15514. %@STUB@%      %@AB@%V86MMGR_Map_Pages%@AE@%%@NL@%
  15515.  
  15516. %@STUB@%      %@AB@%V86MMGR_Free_Page_Map_Region%@AE@%%@NL@%
  15517.  
  15518.  
  15519.  
  15520. %@2@%%@CR:C6A00400003 @%%@AB@%40.1  Initialization Services%@AE@%%@EH@%%@NL@%
  15521.  
  15522. These services are used when a VM is created except for the
  15523. %@AB@%V86MMGR_Get_Version%@AE@%, which may be used anytime.%@CR:C6A00400004 @%%@NL@%
  15524.  
  15525. %@CR:C6A00400005 @%
  15526. %@2@%%@CR:C6A00400006 @%%@AB@%V86MMGR_Get_Version%@AE@%%@EH@%%@NL@%
  15527. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15528.  
  15529.  
  15530. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15531.  
  15532. Returns the version of the V86MMGR VxD.  %@NL@%
  15533.  
  15534.  
  15535. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15536.  
  15537. None  %@NL@%
  15538.  
  15539.  
  15540. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15541.  
  15542. %@AB@%AH %@AE@%= Major version number %@AB@%AL%@AE@% = Minor version number Carry flag clear  %@NL@%
  15543.  
  15544.  
  15545. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15546.  
  15547. %@AB@%EAX%@AE@%, Flags  %@NL@%
  15548.  
  15549. %@CR:C6A00400007 @%
  15550. %@2@%%@CR:C6A00400008 @%%@AB@%V86MMGR_Allocate_V86_Pages%@AE@%%@EH@%%@NL@%
  15551. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15552.  
  15553.  
  15554. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15555.  
  15556. This service is used by the SHELL VxD to set up the initial base memory of a
  15557. VM when it is created. It allocates the memory, maps it into the virtual
  15558. machine, and does a local %@AB@%Assign_Device_V86_Pages%@AE@% for the region allocated.
  15559. %@NL@%
  15560.  
  15561.  
  15562. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15563.  
  15564. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Desired size of VM address space in K bytes %@AB@%EDI %@AE@% =
  15565. Minimum size of VM address space in K bytes %@AB@%ECX%@AE@% = Flags, see bit definitions
  15566. in V86MMGR.INC  %@NL@%
  15567.  
  15568. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15569. NOTE
  15570.  
  15571. %@AI@%The %@AB@%ESI%@AE@%%@AI@% and %@AE@%%@AI@%%@AB@%EDI%@AE@%%@AE@%%@AI@% sizes include the %@AE@%%@AI@%%@AB@%0-First_VM_Page%@AE@%%@AE@%%@AI@% region of V86 address
  15572. %@AI@%space.%@AE@%%@AE@%
  15573. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15574.  
  15575.  
  15576. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15577.  
  15578. If carry set then    ERROR: Could not allocate memory else    Memory
  15579. allocated and mapped into VM %@AB@%EAX%@AE@% = ACTUAL number of pages allocated and
  15580. mapped (size of VM). Notice that this size %@AI@%does not%@AE@% include the space from
  15581. 0-%@AB@%First_VM_Page%@AE@%  %@NL@%
  15582.  
  15583.  
  15584. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15585.  
  15586. %@AB@%EAX%@AE@%,Flags  %@NL@%
  15587.  
  15588. %@CR:C6A00400009 @%
  15589. %@2@%%@CR:C6A00400010 @%%@AB@%V86MMGR_Set_EMS_XMS_Limits%@AE@%%@EH@%%@NL@%
  15590. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15591.  
  15592.  
  15593. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15594.  
  15595. This service is used by the SHELL VxD to set the EMS and XMS limit
  15596. parameters for a VM.  %@NL@%
  15597.  
  15598.  
  15599. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15600.  
  15601. %@AB@%EBX%@AE@% = VM handle to set limits of %@AB@% EAX%@AE@% = Min EMS kilobytes %@AB@% EDX%@AE@% = Max EMS
  15602. kilobytes %@AB@% ESI%@AE@% = Min XMS kilobytes %@AB@% EDI %@AE@% = Max XMS kilobytes %@AB@% ECX%@AE@% = Flag
  15603. bits, see V86MMGR.INC  %@NL@%
  15604.  
  15605.  
  15606. %@3@%%@AB@%Notes%@AE@%%@EH@%%@NL@%
  15607.  
  15608. To disable access to XMS or EMS memory, set Max = Min = 0 To set only %@AI@%one%@AE@% of
  15609. the two limits, set the OTHER Max = Min = -1 The XMS Limit %@AI@%does not%@AE@% include
  15610. the HMA.  %@NL@%
  15611.  
  15612.  
  15613. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15614.  
  15615. If carry set then could not set limits    Insufficient memory for Min
  15616. allocation request    note that some of the limits may have been set. To
  15617. Find    out what happened, use %@AB@%V86MMGR_Get_EMS_XMS_Limits%@AE@% else limits set  %@NL@%
  15618.  
  15619.  
  15620. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15621.  
  15622. Flags  %@NL@%
  15623.  
  15624. %@CR:C6A00400011 @%
  15625. %@2@%%@CR:C6A00400012 @%%@AB@%V86MMGR_Get_EMS_XMS_Limits%@AE@%%@EH@%%@NL@%
  15626. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15627.  
  15628.  
  15629. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15630.  
  15631. This service is used by the SHELL VxD to get the EMS and XMS limit
  15632. parameters for a VM.  %@NL@%
  15633.  
  15634.  
  15635. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15636.  
  15637. %@AB@%EBX%@AE@% = VM handle to get limits of  %@NL@%
  15638.  
  15639.  
  15640. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15641.  
  15642. %@AB@%EAX%@AE@% = Min EMS kilobytes (always a multiple of 4) %@AB@%EDX%@AE@% = Max EMS kilobytes
  15643. (always a multiple of 4) %@AB@%ESI%@AE@% = Min XMS kilobytes (always a multiple of 4)
  15644. %@AB@%EDI%@AE@% = Max XMS kilobytes (always a multiple of 4) %@AB@%ECX%@AE@% = 0 if access to the
  15645. HMA is disabled %@AB@%ECX%@AE@% = 1 if access to the HMA is enabled  %@NL@%
  15646.  
  15647.  
  15648. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15649.  
  15650. %@AB@%EAX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, Flags  %@NL@%
  15651.  
  15652.  
  15653. %@2@%%@CR:C6A00400013 @%%@AB@%40.2  API Translation and Mapping%@AE@%%@EH@%%@NL@%
  15654. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15655.  
  15656. One of the major roles of the V86MMGR is to provide a mechanism for other
  15657. VxDs to translate API calls made from application software running in
  15658. protected mode into the V86 portion of the virtual machine. The term "API
  15659. translation" is used in this document to describe the conversion of an API
  15660. call in protected mode into a corresponding V86 mode call. Because enhanced
  15661. Windows runs under a standard MS-DOS, MS-DOS and BIOS calls must be
  15662. reflected to V86 mode code to handle the call. There is a layer of code in
  15663. the DOSMGR device that converts protected mode MS-DOS calls into V86 calls.%@CR:C6A00400014 @%%@CR:C6A00400015 @%%@NL@%
  15664.  
  15665. The main translation service, %@AB@%V86MMGR_Xlat_API%@AE@%, is a simple interpreter that
  15666. copies data into a buffer in the V86 address space and converts pointers to
  15667. point to the copied data. Note that the data is %@AI@%copied%@AE@%. The memory is not
  15668. mapped into V86 memory by changing page tables.  %@NL@%
  15669.  
  15670. Other services are provided to allocate buffer space, map memory into global
  15671. V86 address space, and perform other functions necessary for API
  15672. translation.  %@NL@%
  15673.  
  15674. Translations services work only for the current VM, and most are only
  15675. available from the protected-mode portion of a VM.  %@NL@%
  15676.  
  15677. Only one VxD should translate a given API call.  %@NL@%
  15678.  
  15679. DPMI provides a way for an application to do translation without installing
  15680. a VxD to do the transition.  %@NL@%
  15681.  
  15682.  
  15683. %@3@%%@AB@%40.2.1  Basic API Translation%@AE@%%@EH@%%@NL@%
  15684.  
  15685. Many APIs require little or no translation. Others are extremely complex and
  15686. require a great deal of coding. The simplest API is one that has no
  15687. pointers. A software interrupt based API, in which all parameters are passed
  15688. in the %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and %@AB@%EBP %@AE@%registers and flags, requires
  15689. no special translation software. By default, enhanced Windows will reflect
  15690. an interrupt that is executed in protected mode into V86 mode. For example,
  15691. the BIOS printer interface (Int 17h) requires no translation code since all
  15692. APIs are register-based with no pointers.  %@NL@%
  15693.  
  15694. However, most APIs have at least some calls that take pointers as
  15695. parameters. For example, to open a file through MS-DOS, you must point at
  15696. the name of the file to open with the %@AB@%DS:DX%@AE@% registers. Since the address
  15697. that a protected mode program will pass in %@AB@%DS:DX%@AE@% is not usually addressable
  15698. in the V86 portion of the VM, there must be code that copies the filename
  15699. into a buffer that is addressable in V86 mode so that MS-DOS can access the
  15700. filename.  %@NL@%
  15701.  
  15702.  
  15703. %@3@%%@AB@%40.2.2  Complex API Translation%@AE@%%@EH@%%@NL@%
  15704.  
  15705. Some APIs are too complex or their buffers are too large to be handled by
  15706. the %@AB@%V86MMGR_Xlat_API%@AE@% service. The MS-DOS Exec function takes a pointer to a
  15707. data structure that contains more pointers. This API requires special code
  15708. to translate the pointers in the data structure and to copy the data that
  15709. those pointers point to into V86 mode memory.  %@NL@%
  15710.  
  15711. The MS-DOS read and write file functions can have buffers as large as 64K.
  15712. The typical V86MMGR translation copy buffer is 4K. Therefore, these calls
  15713. require code to divide the call into several smaller reads or writes in V86
  15714. mode.  %@NL@%
  15715.  
  15716.  
  15717. %@3@%%@AB@%40.2.3  Hooking the Interrupt%@AE@%%@EH@%%@NL@%
  15718.  
  15719. Since the translation code should be the last protected mode handler you
  15720. will need to hook the PM interrupt vector (using the %@AB@%Hook_PM_Int_Vector%@AE@%
  15721. service) during the %@AB@%Sys_Critical_Init%@AE@% or %@AB@%Device_Init%@AE@% phases of
  15722. initialization. All translation code should be initialized before the
  15723. Init_Complete phase of initialization so that the %@AB@%Exec_VxD_Int%@AE@% service
  15724. (provided by the VMM) can be used during this phase. Note that the V86MMGR
  15725. translation services (except for %@AB@%Set_Mapping_Info%@AE@%) should not be called
  15726. during %@AB@%Sys_Critical_Init%@AE@% or %@AB@%Device_Init%@AE@%.  %@NL@%
  15727.  
  15728. By hooking the interrupt vector instead of using the %@AB@%Hook_PM_Int_Chain%@AE@%
  15729. service you will allow protected mode applications to hook software
  15730. interrupts "in front" of your translation code. This is very important for
  15731. the Windows kernel since it needs to monitor the activity of Windows
  15732. applications' API calls.  %@NL@%
  15733.  
  15734.  
  15735. %@4@%%@AB@%Sample Code%@AE@%%@EH@%%@NL@%
  15736.  
  15737. The code for a typical translation VxD looks like this:  %@NL@%
  15738.  
  15739. %@AS@%  VxD_ICODE_SEG
  15740. %@AS@%  BeginProc My_Xlat_Init
  15741. %@AS@%   mov eax, My_Translation_Int_Number
  15742. %@AS@%   VMMcall Get_PM_Int_Vector
  15743. %@AS@%   mov [Chain_Segment], cx
  15744. %@AS@%   mov [Chain_Offset], edx
  15745. %@AS@%   mov esi, OFFSET32 My_Xlat_Procedure
  15746. %@AS@%   VMMcall Allocate_PM_Call_Back
  15747. %@AS@%   mov ecx, eax
  15748. %@AS@%   movzx edx, cx
  15749. %@AS@%   shr ecx, 16
  15750. %@AS@%   mov eax, My_Translation_Int_Number
  15751. %@AS@%   VMMcall Set_PM_Int_Vector
  15752. %@AS@%   clc
  15753. %@AS@%   ret
  15754. %@AS@%  EndProc My_Xlat_Init
  15755. %@AS@%  VxD_ICODE_ENDS
  15756. %@AS@%  
  15757. %@AS@%  VxD_CODE_SEG
  15758. %@AS@%  BeginProc My_Xlat_Procedure
  15759. %@AS@%   movzx eax, [ebp.Client_AH]
  15760. %@AS@%   cmp eax, My_Max_API_Number
  15761. %@AS@%   ja Chain_To_Next_Handler
  15762. %@AS@%   VMMcall Simulate_Iret
  15763. %@AS@%   mov edx, My_Trans_Script_Table[eax*4]
  15764. %@AS@%   VxDcall V86MMGR_Xlat_API
  15765. %@AS@%   ret
  15766. %@AS@%  Chain_To_Next_Handler:
  15767. %@AS@%   movzx ecx, [Chain_Segment]
  15768. %@AS@%   jecxz Reflect_To_V86_Now
  15769. %@AS@%   mov edx, [Chain_Offset]
  15770. %@AS@%   VMMcall Simulate_Far_Jmp
  15771. %@AS@%   ret
  15772. %@AS@%  Reflect_To_V86_Now:
  15773. %@AS@%   VMMcall Begin_Nest_V86_Exec
  15774. %@AS@%   mov eax, My_Translation_Int_Number
  15775. %@AS@%   VMMcall Exec_Int
  15776. %@AS@%   VMMcall End_Nest_Exec
  15777. %@AS@%   ret
  15778. %@AS@%  EndProc My_Xlat_Procedure
  15779. %@AS@%  VxD_CODE_ENDS%@AE@%
  15780.  
  15781. If the value in AH is not translated by this handler then it will be
  15782. reflected to the next protected mode interrupt handler. If there is not
  15783. another PM interrupt handler (code segment is zero) then the interrupt is
  15784. immediately reflected to V86 mode.  %@NL@%
  15785.  
  15786. You will note that My_Xlat_Procedure calls the %@AB@%Simulate_Iret%@AE@% service before
  15787. it calls %@AB@%V86MMGR_Xlat_API%@AE@%. If you plan to "eat" an interrupt it is usually
  15788. best to call this service first. If the iret was simulated after the call to
  15789. %@AB@%V86MMGR_Xlat_API%@AE@% then any flags returned by the V86 interrupt handler would
  15790. be destroyed (an iret pops flags from the interrupt stack frame).  %@NL@%
  15791.  
  15792.  
  15793. %@3@%%@AB@%40.2.4  Mapping vs. Copying%@AE@%%@EH@%%@NL@%
  15794.  
  15795. Some VxDs need to use the paging mechanism of the 386 to map pages from
  15796. extended address space into the 1MB V86 address space of every virtual
  15797. machine. The Virtual NetBIOS Device uses the mapping services when an
  15798. asynchronous receive is issued so that the proper physical memory will be
  15799. updated regardless of which VM is currently running. When memory is mapped
  15800. using %@AB@%V86MMGR_Map_Pages%@AE@% it will be mapped to the same linear address in
  15801. every virtual machine. Thus it is best to avoid using these services.  %@NL@%
  15802.  
  15803. Do not use mapping as an alternative to copying just because you think
  15804. mapping seems easier. It is faster to copy memory than to map it since the
  15805. memory manager does not need to perform any page table mapping and locking.
  15806. Mapping also uses a lot of address space (although it requires no memory).
  15807. The mapping services should only be used for APIs that require memory mapped
  15808. to the same address in every VM.  %@NL@%
  15809.  
  15810. Note that the mapping services allow memory from one VM's V86 address space
  15811. to be mapped into all VMs at a common address. %@AI@%Don't use this for
  15812. %@AI@%interprocess communication.%@AE@% It will eat mapping space that may be required
  15813. by other devices. If you want to design an IPC interface, either make it
  15814. work for PM applications (which can share memory) or copy the data.  %@NL@%
  15815.  
  15816.  
  15817. %@3@%%@AB@%40.2.5  Writing Your Own Translation Procedures%@AE@%%@EH@%%@NL@%
  15818.  
  15819. Often, it is impossible to translate part or all of an API using the
  15820. supplied macro interpreter. Therefore you may need to write procedures that
  15821. do all or part of the translation. Examples of calls that require extra code
  15822. are the MS-DOS read and write commands and the get and set interrupt vector
  15823. commands. The MS-DOS commands to get and set interrupt vectors behave
  15824. differently in protected mode since they must hook the protected mode
  15825. interrupt vectors. These calls are never reflected to the "real" MS-DOS
  15826. running in V86 mode.  %@NL@%
  15827.  
  15828. The MS-DOS read and write file commands can use a buffer as large as 64K.
  15829. Since the translation buffers can be as small as 4K, reads and writes must
  15830. be divided before being reflected to MS-DOS.  %@NL@%
  15831.  
  15832. Since most APIs have some interfaces that can be handled by the
  15833. %@AB@%V86MMGR_Xlat_API%@AE@% script language and others that must be translated by
  15834. custom procedures you will probably want to dispatch to the custom
  15835. procedures using the %@AB@%Xlat_API_Jmp_To_Proc%@AE@% macro.  %@NL@%
  15836.  
  15837. To adjust V86 segment registers you should leave the VM in %@AB@%PM_Exec_Mode%@AE@% and
  15838. change the %@AB@%Alt_Client%@AE@% registers. When in %@AB@%PM_Exec_Mode%@AE@% these registers
  15839. contain the V86 segment registers and stack pointer. They will contain the
  15840. PM segment registers and stack pointer when the VM is in %@AB@%V86_Exec_Mode%@AE@%.  %@NL@%
  15841.  
  15842.  
  15843. %@3@%%@AB@%40.2.6  Sample API Translation%@AE@%%@EH@%%@NL@%
  15844.  
  15845. This sample API is for an imaginary, incredibly simple network. The
  15846. functions allow you to connect to a server and send or receive data. Assume
  15847. that the network supports the following API from software interrupt 92h:  %@NL@%
  15848.  
  15849.  
  15850. %@4@%%@AB@%%@AB@%Function 0: Get version%@AE@%%@AE@%%@EH@%%@NL@%
  15851.  
  15852.  
  15853. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15854.  
  15855. %@AB@%AH%@AE@% = 0  %@NL@%
  15856.  
  15857.  
  15858. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15859.  
  15860. %@AB@%AH%@AE@% = Major version %@AB@%AL%@AE@% = Minor version  %@NL@%
  15861.  
  15862.  
  15863. %@4@%%@AB@%%@AB@%Function 1: Get Server Name%@AE@%%@AE@%%@EH@%%@NL@%
  15864.  
  15865.  
  15866. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15867.  
  15868. %@AB@%AH %@AE@%= 1 %@AB@%DS:DX%@AE@% = Pointer to a 16 byte buffer to hold name  %@NL@%
  15869.  
  15870.  
  15871. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15872.  
  15873.  None  %@NL@%
  15874.  
  15875.  
  15876. %@4@%%@AB@%%@AB@%Function 2: Connect To New Server%@AE@%%@AE@%%@EH@%%@NL@%
  15877.  
  15878.  
  15879. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15880.  
  15881.  %@AB@%AH%@AE@% = 2  %@AB@%DS:DX%@AE@% = Pointer to null terminated string that is name of server  %@NL@%
  15882.  
  15883.  
  15884. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15885.  
  15886.  None  %@NL@%
  15887.  
  15888.  
  15889. %@4@%%@AB@%%@AB@%Function 3: Read/Write Data%@AE@%%@AE@%%@EH@%%@NL@%
  15890.  
  15891.  
  15892. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15893.  
  15894.  %@AB@%AH %@AE@%= 3  %@AB@%ES:BX%@AE@% = Pointer to command block with following structure:  %@NL@%
  15895.  
  15896. %@TH:   5   229 02 08 06 62 @%
  15897. Offset  Size  Description
  15898. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15899. 0       1     Command
  15900. 1       2     Buffer size
  15901. 3       4     Buffer pointer
  15902. %@TE:   5   229 02 08 06 62 @%
  15903.  
  15904. Command field values:  0 = Read data from server  1 = Write data to server  %@NL@%
  15905.  
  15906.  
  15907. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15908.  
  15909. None  %@NL@%
  15910.  
  15911. Since function 0 is register based it requires no translation other than
  15912. reflecting the interrupt to V86 mode. Functions 1 and 2 both can be
  15913. translated by scripts using the %@AB@%V86MMGR_Xlat_API%@AE@% service. Function 3
  15914. requires a custom translation procedure.  %@NL@%
  15915.  
  15916. %@AS@%  VxD_DATA_SEG 
  15917. %@AS@%  Fctn_0_Script:
  15918. %@AS@%    Xlat_API_Exec_Int  92h 
  15919. %@AS@%  Fctn_1_Script:  Xlat_API_Fixed_Len ds, dx, 16
  15920. %@AS@%   Xlat_API_Exec_Int  92h 
  15921. %@AS@%  Fctn_2_Script:  Xlat_API_ASCIIZ   ds, dx 
  15922. %@AS@%   Xlat_API_Exec_Int 92h 
  15923. %@AS@%  Fctn_3_Script: 
  15924. %@AS@%   Xlat_API_Jmp_To_Proc Trans_Fctn_3
  15925. %@AS@%  Copy_Command_Block_Script: 
  15926. %@AS@%   Xlat_API_Fixed_Len es, bx, 7
  15927. %@AS@%   Xlat_API_Exec_Int  92h%@AE@%
  15928.  
  15929. %@AS@%  Xlat_Ptr_Table: 
  15930. %@AS@%   dd OFFSET32 Fctn_0_Script 
  15931. %@AS@%   dd OFFSET32 Fctn_1_Script  dd OFFSET32 Fctn_2_Script 
  15932. %@AS@%   dd OFFSET32 Fctn_3_Script 
  15933. %@AS@%  VxD_DATA_ENDS%@AE@%
  15934.  
  15935. %@AS@%  VxD_CODE_SEG 
  15936. %@AS@%  BeginProc Translate_Sample_API 
  15937. %@AS@%   movzx edx, [ebp.Client_AH]
  15938. %@AS@%   cmp edx, 3 
  15939. %@AS@%   ja Chain_To_Next_Handler 
  15940. %@AS@%   VMMcall Simulate_Iret 
  15941. %@AS@%   mov edx, Xlat_Ptr_Table[edx*4] 
  15942. %@AS@%   VxDcall V86MMGR_Xlat_API 
  15943. %@AS@%   jc Translation_Error  ret 
  15944. %@AS@%  Chain_To_Next_Handler: 
  15945. %@AS@%   movzx ecx, [Chain_Segment] 
  15946. %@AS@%   jecxz Reflect_To_V86_Now
  15947. %@AS@%   mov edx, [Chain_Offset] 
  15948. %@AS@%   VMMcall Simulate_Far_Jmp 
  15949. %@AS@%   ret 
  15950. %@AS@%  Reflect_To_V86_Now:
  15951. %@AS@%   VMMcall Begin_Nest_V86_Exec 
  15952. %@AS@%   mov eax, 92h 
  15953. %@AS@%   VMMcall Exec_Int VMMcall
  15954. %@AS@%   End_Nest_Exec
  15955. %@AS@%   ret 
  15956. %@AS@%  Translation_Error: 
  15957. %@AS@%   Debug_Out "Unable to translate sample API"
  15958. %@AS@%   VMMjmp Crash_Cur_VM 
  15959. %@AS@%  EndProc Translate_Sample_API%@AE@%
  15960.  
  15961. %@AS@%  BeginProc Trans_Fctn_3 
  15962. %@AS@%   push fs 
  15963. %@AS@%   push gs 
  15964. %@AS@%   pushad 
  15965. %@AS@%  ; Get pointer to command block 
  15966. %@AS@%   mov ax, (Client_ES*100h)+Client_BX 
  15967. %@AS@%   VxDcall V86MMGR_Load_Client_Ptr 
  15968. %@AS@%  ; If command is invalid then fail the call 
  15969. %@AS@%   mov al, BYTE PTR fs:[esi] 
  15970. %@AS@%   cmp al, 1 
  15971. %@AS@%   ja Can_Not_Translate 
  15972. %@AS@%  ; Get buffer size and pointer from command block 
  15973. %@AS@%   mov dx, fs 
  15974. %@AS@%   mov gs, dx 
  15975. %@AS@%   mov edx, esi movzx ecx, WORD PTR gs:[edx+1] 
  15976. %@AS@%   mov fs, WORD PTR gs:[edx+5] 
  15977. %@AS@%   movzx   esi, WORD PTR gs:[edx+3] 
  15978. %@AS@%  ; Allocate a buffer, copying data if command is a write
  15979. %@AS@%   bt eax, 0 
  15980. %@AS@%   VxDcall V86MMGR_Allocate_Buffer 
  15981. %@AS@%   jc Can_Not_Translate
  15982. %@AS@%   mov DWORD PTR gs:[edx+3], edi 
  15983. %@AS@%  ; Copy the command block and execute the interrupt 
  15984. %@AS@%   push edx 
  15985. %@AS@%   mov edx, OFFSET32 Copy_Command_Block_Script
  15986. %@AS@%   VxDcall V86MMGR_Xlat_API 
  15987. %@AS@%   pop edx 
  15988. %@AS@%   jc Can_Not_Translate 
  15989. %@AS@%  ; Free the buffer, copying data if command is a read 
  15990. %@AS@%   mov al, BYTE PTR gs:[edx]
  15991. %@AS@%   bt eax, 0 
  15992. %@AS@%   cmc 
  15993. %@AS@%   VxDcall V86MMGR_Free_Buffer 
  15994. %@AS@%  ; Restore original pointer in command block 
  15995. %@AS@%   mov WORD PTR gs:[edx+5], fs 
  15996. %@AS@%   mov WORD PTR gs:[edx+3], si 
  15997. %@AS@%   clc 
  15998. %@AS@%  Trans_F3_Exit: 
  15999. %@AS@%   popad 
  16000. %@AS@%   pop gs 
  16001. %@AS@%   pop fs 
  16002. %@AS@%   ret 
  16003. %@AS@%  Can_Not_Translate:  stc 
  16004. %@AS@%   jmp Trans_F3_Exit 
  16005. %@AS@%  EndProc Trans_Fctn_3
  16006. %@AS@%  
  16007. %@AS@%  VxD_CODE_ENDS%@AE@%
  16008.  
  16009. %@CR:C6A00400016 @%
  16010. %@2@%%@CR:C6A00400017 @%%@AB@%V86MMGR_Set_Mapping_Info%@AE@%%@EH@%%@NL@%
  16011. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16012.  
  16013.  
  16014. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16015.  
  16016. This service must be called during the %@AB@%Sys_Critical_Init %@AE@%or %@AB@%Device_Init
  16017. %@AB@%%@AE@%phase of device initialization. It is used to define the minimum amount of
  16018. translation buffer and global V86 map address space that will be required.
  16019. VxDs such as the VNETBIOS use this service to ensure that there will be
  16020. adequate global page mapping space to map network buffers. By default the
  16021. translation copy buffer size is 4K and there are no global mapping pages.  %@NL@%
  16022.  
  16023. Multiple VxDs may call this service. The V86MMGR will use the largest value
  16024. for each of the parameters when allocating buffer space. In other words, if
  16025. 10 VxDs request a two-page copy buffer then the copy buffer will be two
  16026. pages (not 20).  %@NL@%
  16027.  
  16028. Note that while a large copy buffer can speed up operations such as MS-DOS
  16029. reads, it requires extra memory to be allocated for every VM. Therefore, you
  16030. should try to get by with a copy buffer size of one page if possible.  %@NL@%
  16031.  
  16032.  
  16033. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16034.  
  16035. %@AB@%AL%@AE@% = Minimum number of pages required for default copy buffer %@AB@%AH%@AE@% = Maximum
  16036. number of pages desired for default copy buffer %@AB@%BL%@AE@% = Minimum number of pages
  16037. required for global page mapping region %@AB@%BH%@AE@% = Maximum number of pages desired
  16038. for global page mapping region  %@NL@%
  16039.  
  16040.  
  16041. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16042.  
  16043. None  %@NL@%
  16044.  
  16045.  
  16046. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16047.  
  16048. Flags  %@NL@%
  16049.  
  16050. %@CR:C6A00400018 @%
  16051. %@2@%%@CR:C6A00400019 @%%@AB@%V86MMGR_Xlat_API%@AE@%%@EH@%%@NL@%
  16052. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16053.  
  16054.  
  16055. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16056.  
  16057. This service is actually a simple interpreter that executes scripts that are
  16058. created using macros defined in V86MMGR.INC. The macros are described in
  16059. detail below.  %@NL@%
  16060.  
  16061. You can combine any of the macros, although you should keep in mind that
  16062. %@AB@%Xlat_API_Exec_Int%@AE@% and %@AB@%Xlat_API_Jmp_To_Proc%@AE@% both terminate interpretation of
  16063. the current script.  %@NL@%
  16064.  
  16065. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16066. %@AU@%WARNING%@AE@%
  16067.  
  16068. You should always specify the exact length of a buffer or else strange
  16069. things may occur. For example, it is incorrect to translate an API that has
  16070. a maximum buffer size of 128 bytes by using the Xlat_API_Fixed_Len macro if
  16071. the buffer can be smaller than 128 bytes. This can cause bugs if the program
  16072. has data that is updated at interrupt time that is located past the end of
  16073. the buffer.
  16074. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16075.  
  16076. For example, assume a program has the following data:  %@NL@%
  16077.  
  16078. %@AS@%  Buffer_Length db 64
  16079. %@AS@%  Buffer_Data db 64 dup (?)
  16080. %@AS@%  Time_Of_Day dd 0
  16081. %@AS@%  Other_Stuff db 500 dup (?)%@AE@%
  16082.  
  16083.  
  16084. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16085.  
  16086. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure %@AB@%EDX%@AE@% -> Script to
  16087. translate  %@NL@%
  16088.  
  16089.  
  16090. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16091.  
  16092. %@AB@%EDX%@AE@% is destroyed If carry set then  Error while executing script else
  16093. Script has been executed successfully  %@NL@%
  16094.  
  16095.  
  16096. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16097.  
  16098. %@AB@%EDX%@AE@%, Flags  %@NL@%
  16099.  
  16100.  
  16101. %@3@%%@AB@%Macro5%@AE@%%@EH@%%@NL@%
  16102.  
  16103. The following define the translation scripts.  %@NL@%
  16104.  
  16105.  
  16106. %@4@%%@AB@%Xlat_API_Exec_Int [Int Number]%@AE@%%@EH@%%@NL@%
  16107.  
  16108. Terminates the interpretation of the translation script and reflects the
  16109. specified interrupt into Virtual 8086 mode. When the interrupt returns then
  16110. it will return to the caller.  %@NL@%
  16111.  
  16112. %@AS@%  DOS_No_Xlat_API:
  16113. %@AS@%   Xlat_API_Exec_Int 21h%@AE@%
  16114.  
  16115.  
  16116. %@4@%%@AB@%Xlat_API_Fixed_Len [Segment], [Offset], [Length Constant]%@AE@%%@EH@%%@NL@%
  16117.  
  16118. Copies a fixed length buffer from extended memory into the translation
  16119. buffer and fixes up the V86 Seg:Offset.  %@NL@%
  16120.  
  16121. This service will fail if there is not enough room in the translation buffer
  16122. to copy the data.  %@NL@%
  16123.  
  16124. For example, the MS-DOS Get Current Directory function (%@AB@%AH%@AE@%=47h), must be
  16125. called with %@AB@%DS:SI%@AE@% pointing to a 64-byte buffer. The following script would
  16126. perform the appropriate translation:  %@NL@%
  16127.  
  16128. %@AS@%  DOS_Get_Current_Directory_API:
  16129. %@AS@%   Xlat_API_Fixed_Len ds, si, 64
  16130. %@AS@%   Xlat_API_Exec_Int  21h%@AE@%
  16131.  
  16132.  
  16133. %@4@%%@AB@%Xlat_API_Var_Len [Segment], [Offset], [Length Register]%@AE@%%@EH@%%@NL@%
  16134.  
  16135. Copies a variable number of bytes from extended memory into the translation
  16136. buffer. This is used for APIs where the caller places the buffer size in a
  16137. register.  %@NL@%
  16138.  
  16139. This service will fail if there is not enough room in the translation buffer
  16140. to copy the data.  %@NL@%
  16141.  
  16142. For example, the Int 10h write string function (AH=0Eh), must be called with
  16143. %@AB@%ES:BP%@AE@% pointing to the string to print and %@AB@%CX%@AE@% equal to the number of bytes to
  16144. display. The following script would translate this call:  %@NL@%
  16145.  
  16146. %@AS@%  Int_10h_Write_String:
  16147. %@AS@%   Xlat_API_Var_Len  es, bp, cx
  16148. %@AS@%   Xlat_API_Exec_Int 10h%@AE@%
  16149.  
  16150.  
  16151. %@4@%%@AB@%Xlat_API_Calc_Len [Segment], [Ptr_Off], [Calc_Proc_Addr]%@AE@%%@EH@%%@NL@%
  16152.  
  16153. Used to copy buffers that change in size. You must specify the
  16154. selector:offset register pair that points to the buffer and the name of a
  16155. procedure that will calculate the actual buffer size. The procedure will be
  16156. called with %@AB@%FS:ESI%@AE@% pointing to the buffer and must return with %@AB@%ECX%@AE@% equal to
  16157. the number of bytes to copy. The procedure must preserve all registers
  16158. except %@AB@%ECX%@AE@%.  %@NL@%
  16159.  
  16160. This service will fail if there is not enough room in the translation buffer
  16161. to copy the data.  %@NL@%
  16162.  
  16163. For example, the MS-DOS buffered keyboard input command (AH=0Ah) can have a
  16164. buffer size from 3 to 257 bytes long. The first byte of the buffer specifies
  16165. the length of the input buffer as follows:  %@NL@%
  16166.  
  16167. %@TH:  12   643 02 34 44 @%
  16168. Byte                              Contents
  16169. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16170. 0                                 Maximum number of characters to read 
  16171.                                   (1-255); this value must be set by the 
  16172.                                   process before Function 0Ah is called.
  16173.  
  16174. 1                                 Count of characters read.
  16175.  
  16176. 2-(n+2)                           Actual string of characters read, 
  16177.                                   including the carriage return; 
  16178.                                   n = number of bytes read.
  16179.  
  16180. %@TE:  12   643 02 34 44 @%
  16181.  
  16182. The translation code for this API would look something like this:  %@NL@%
  16183.  
  16184. %@AS@%  VxD_DATA_SEG
  16185. %@AS@%  Buff_Keyboard_Input_API:
  16186. %@AS@%   Xlat_API_Calc_Len ds, dx, Calc_Input_Buff_Size
  16187. %@AS@%   Xlat_API_Exec_Int 21h
  16188. %@AS@%  VxD_DATA_ENDS
  16189. %@AS@%  
  16190. %@AS@%  VxD_CODE_SEG
  16191. %@AS@%  BeginProc Int_21_PM_To_V86_Translator
  16192. %@AS@%  
  16193. %@AS@%   cmp [ebp.Client_AH], 0Ah
  16194. %@AS@%   jne Not_Buffered_Keyboard_Input
  16195. %@AS@%   VMMcall Simulate_Iret
  16196. %@AS@%   mov edx, OFFSET32 Buff_Keyboard_Input_API
  16197. %@AS@%   VxDcall V86MMGR_Xlat_API
  16198. %@AS@%   ret
  16199. %@AS@%  
  16200. %@AS@%  EndProc Int_21_PM_To_V86_Translator
  16201. %@AS@%  
  16202. %@AS@%  BeginProc Calc_Input_Buff_Size
  16203. %@AS@%  
  16204. %@AS@%   movzx ecx, BYTE PTR fs:[esi]
  16205. %@AS@%   add ecx, 2
  16206. %@AS@%   ret
  16207. %@AS@%  
  16208. %@AS@%  EndProc Calc_Input_Buff_Size
  16209. %@AS@%  VxD_CODE_ENDS%@AE@%
  16210.  
  16211.  
  16212. %@4@%%@AB@%Xlat_API_ASCIIZ [Ptr_Seg], [Ptr_Off]%@AE@%%@EH@%%@NL@%
  16213.  
  16214. Copies a null-terminated string into V86 memory and adjusts the V86 pointer
  16215. appropriately. Note that the string will not be copied back after the call
  16216. is complete.  %@NL@%
  16217.  
  16218. This service will fail if there is not enough room in the translation buffer
  16219. to copy the string.  %@NL@%
  16220.  
  16221. For example, the MS-DOS Open File With Handle function (AH=3Dh), must be
  16222. called with %@AB@%DS:DX%@AE@% pointing to the name of the file to open. The following
  16223. script could be used translate the API:  %@NL@%
  16224.  
  16225. %@AS@%  DOS_Open_File_With_Handle:
  16226. %@AS@%   Xlat_API_ASCIIZ   ds, dx
  16227. %@AS@%   Xlat_API_Exec_Int 21h%@AE@%
  16228.  
  16229. The interpreter can copy multiple buffers. For example, the following
  16230. translation table translates the MS-DOS rename file call (AH = 56h):  %@NL@%
  16231.  
  16232. %@AS@%  Rename_API:
  16233. %@AS@%   Xlat_API_ASCIIZ   ds, dx
  16234. %@AS@%   Xlat_API_ASCIIZ   es, di
  16235. %@AS@%   Xlat_API_Exec_Int 21h%@AE@%
  16236.  
  16237. The first instruction copies the null-terminated string (ASCIIZ string) that
  16238. %@AB@%DS:DX%@AE@% points to into the translation buffer in V86 memory, sets the V86 DS
  16239. to the translation buffer segment, and changes %@AB@%DX%@AE@% to the offset in the
  16240. buffer.  %@NL@%
  16241.  
  16242. The second macro copies the ASCIIZ string that is pointed to by %@AB@%ES:(E)DI%@AE@%
  16243. into V86 memory and adjusts the pointer accordingly.  %@NL@%
  16244.  
  16245. The final macro terminates the interpretation of the script and reflects an
  16246. Int 21h into the V86 portion of the VM. When the Int 21h returns, both
  16247. buffers will be freed.  %@NL@%
  16248.  
  16249.  
  16250. %@4@%%@AB@%Xlat_API_Jmp_To_Proc [Proc_Name]%@AE@%%@EH@%%@NL@%
  16251.  
  16252. Terminates the interpretation of the translation script and transfers
  16253. control to a user defined procedure. The procedure can completely handle the
  16254. API translation or can call %@AB@%V86MMGR_Xlat_API%@AE@% again. This can be useful for
  16255. APIs that have several sub-APIs such as the DOS IOCTL calls.  %@NL@%
  16256.  
  16257. The procedure will be called with %@AB@%EBX%@AE@% equal to Current VM Handle, %@AB@%EBP%@AE@%
  16258. pointing to Client register structure, and %@AB@%EDX%@AE@% points to the next entry in
  16259. the translation script (if there is one). It must preserve every register
  16260. except for %@AB@%EDX%@AE@%. Therefore the procedure must preserve %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%ESI%@AE@%,
  16261. %@AB@%EDI%@AE@%, %@AB@%EBP%@AE@%, %@AB@%DS%@AE@%, %@AB@%ES%@AE@%, %@AB@%FS%@AE@%, and %@AB@%GS%@AE@%.  %@NL@%
  16262.  
  16263. Your procedure should return with the carry flag clear if the translation
  16264. was successful. Otherwise, it should return with carry set to indicate an
  16265. error.  %@NL@%
  16266.  
  16267.  
  16268. %@4@%%@AB@%Xlat_API_Return_Ptr [Ptr_Seg], [Ptr_Off]%@AE@%%@EH@%%@NL@%
  16269.  
  16270. Used for calls that return a pointer to a structure. For 16-bit protected
  16271. mode programs, if an appropriate selector does not exist to map the call,
  16272. then this service automatically creates one. For 32-bit protected mode
  16273. programs the selector returned will always be the %@AB@%V86MMGR_VM_Flat_Selector%@AE@%
  16274. and the offset will be adjusted. Note that although this macro is placed
  16275. before the %@AB@%Exec_Int%@AE@% macro in a translation script, the pointer is created
  16276. after the interrupt has been executed.  %@NL@%
  16277.  
  16278. This service will fail if it can not create an appropriate LDT selector.  %@NL@%
  16279.  
  16280. For example, this service is used to translate Int 15h with AH=C0h, which
  16281. returns a pointer in %@AB@%ES:BX%@AE@% that points to a hardware information structure
  16282. on PS/2 machines. The following script would return the appropriate pointer:
  16283. %@NL@%
  16284.  
  16285. %@AS@%  Get_Machine_Info:
  16286. %@AS@%   Xlat_API_Return_Ptr es, bx
  16287. %@AS@%   Xlat_API_Exec_Int   15h%@AE@%
  16288.  
  16289.  
  16290. %@4@%%@AB@%Xlat_API_Return_Seg [Ptr_Seg]%@AE@%%@EH@%%@NL@%
  16291.  
  16292. Used for calls that return a segment. If an appropriate selector does not
  16293. exist to map the call then this service automatically creates one. Note that
  16294. although this macro is placed before the %@AB@%Exec_Int%@AE@% macro in a translation
  16295. script, the selector is created after the interrupt has been executed.  %@NL@%
  16296.  
  16297. This service will fail if it can not create an appropriate LDT selector.  %@NL@%
  16298.  
  16299. For example, this service is used to translate Int 15h with %@AB@%AH%@AE@%=C1h, which
  16300. returns the segment of the EBIOS data area in %@AB@%ES%@AE@%. The following script would
  16301. return a selector that points to the EBIOS data area:  %@NL@%
  16302.  
  16303. %@AS@%  Get_EBIOS_Selector:
  16304. %@AS@%   Xlat_API_Return_Seg es
  16305. %@AS@%   Xlat_API_Exec_Int   15h%@AE@%
  16306.  
  16307. Assume the program updates the Time_Of_Day field from the timer interrupt.
  16308. If the translation code copies 128 bytes of data starting with Buffer_Length
  16309. into V86 mode memory and while processing the call a timer interrupt
  16310. executes then the Time_Of_Day field will be incremented. However, when the
  16311. buffer is copied back the old time will be copied on top of the current
  16312. (correct) Time_Of_Day field.  %@NL@%
  16313.  
  16314. %@CR:C6A00400020 @%
  16315. %@2@%%@CR:C6A00400021 @%%@AB@%V86MMGR_Load_Client_Ptr%@AE@%%@EH@%%@NL@%
  16316. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16317.  
  16318.  
  16319. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16320.  
  16321. This service will load %@AB@%FS:ESI%@AE@% with the specified Client_Seg:Offset. If the
  16322. VM is running a 16-bit protected mode then the high word of the offset in
  16323. %@AB@%ESI%@AE@% will be zeroed. Otherwise, if the VM is running a 32-bit program or is
  16324. in %@AB@%VxD_Exec_Mode%@AE@% then the high word of %@AB@%ESI%@AE@% will not be zeroed. This allows
  16325. most translation procedures to operate correctly without the need to test
  16326. the execution mode of the current VM.  %@NL@%
  16327.  
  16328. The value passed in %@AB@%AX%@AE@% should be formed from the Client Register Structure
  16329. equates. For example, to load the VM's %@AB@%DS:(E)DX%@AE@% you would use the following
  16330. code:  %@NL@%
  16331.  
  16332. %@AS@%  mov ax, (Client_DS * 100h) + Client_DX
  16333. %@AS@%  VxDcall V86MMGR_Load_Client_Ptr
  16334. %@AS@%  (FS:ESI -> Same address as Client_DS:(E)DX).%@AE@%
  16335.  
  16336.  
  16337. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16338.  
  16339. VM must be in protected mode %@AB@%AH%@AE@% = Client segment register equate %@AB@%AL%@AE@% = Client
  16340. offset register equate %@AB@%EBX%@AE@% = Current VM Handle %@AB@%EBP%@AE@% -> Client register
  16341. structure  %@NL@%
  16342.  
  16343.  
  16344. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16345.  
  16346. %@AB@%FS:ESI%@AE@% -> Client's buffer  %@NL@%
  16347.  
  16348.  
  16349. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16350.  
  16351. %@AB@%FS%@AE@%, %@AB@%ESI%@AE@%, Flags  %@NL@%
  16352.  
  16353. %@CR:C6A00400022 @%
  16354. %@2@%%@CR:C6A00400023 @%%@AB@%V86MMGR_Allocate_Buffer%@AE@%%@EH@%%@NL@%
  16355. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16356.  
  16357.  
  16358. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16359.  
  16360. Allocates a portion of the current VM's translation buffer and optionally
  16361. copies data from the PM pointer in %@AB@%FS:ESI%@AE@% into the allocated buffer.  %@NL@%
  16362.  
  16363. Note that this service will map fewer bytes than the value specified in the
  16364. %@AB@%ECX%@AE@% parameter if the length of the buffer extends past the FS segment limit.
  16365. Therefore, you need to preserve the value returned in ECX from this service
  16366. to use when deallocating the buffer using %@AB@%V86MMGR_Free_Buffer%@AE@%.  %@NL@%
  16367.  
  16368. The buffers are maintained as a stack. Therefore, the last buffer allocated
  16369. must be the first buffer freed.  %@NL@%
  16370.  
  16371.  
  16372. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16373.  
  16374. Current VM must be in protected mode %@AB@%EBX%@AE@% = Current VM Handle %@AB@%EBP%@AE@% -> Client
  16375. register structure %@AB@%ECX%@AE@% = Number of bytes to allocate %@AB@%FS:ESI %@AE@%= Pointer to
  16376. extended memory to copy If carry flag is set then  Source buffer will be
  16377. copied into V86 buffer else  Source buffer will not be copied into V86
  16378. memory  %@NL@%
  16379.  
  16380.  
  16381. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16382.  
  16383. If carry set then  ERROR: Could not allocate buffer (out of space) else  ECX
  16384. = Actual number of bytes allocated (<= original %@AB@%ECX%@AE@%)  High WORD of %@AB@%EDI%@AE@% = V86
  16385. segment of translation buffer  Low WORD of %@AB@%EDI%@AE@% = Offset of allocated buffer
  16386. %@NL@%
  16387.  
  16388.  
  16389. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16390.  
  16391. %@AB@%ECX%@AE@%, %@AB@%EDI%@AE@%, Flags  %@NL@%
  16392.  
  16393. %@CR:C6A00400024 @%
  16394. %@2@%%@CR:C6A00400025 @%%@AB@%V86MMGR_Free_Buffer%@AE@%%@EH@%%@NL@%
  16395. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16396.  
  16397.  
  16398. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16399.  
  16400. Deallocates a buffer that was allocated by the %@AB@%V86MMGR_Allocate_Buffer%@AE@%
  16401. service. It will optionally copy data from the translation buffer to the
  16402. buffer pointed to by %@AB@%FS:ESI%@AE@%.  %@NL@%
  16403.  
  16404. The buffers are maintained as a stack. Therefore, the last buffer allocated
  16405. must be the first buffer freed.  %@NL@%
  16406.  
  16407.  
  16408. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16409.  
  16410. Current VM must be in protected mode %@AB@%EBX%@AE@% = Current VM Handle %@AB@%EBP%@AE@% -> Client
  16411. register structure %@AB@%ECX%@AE@% = Number of bytes to free (returned from
  16412. Allocate_Buffer) %@AB@%FS:ESI%@AE@% = Pointer to extended memory buffer If carry flag is
  16413. set then  Buffer will be copied from V86 memory before buffer freed else
  16414. Buffer will not be copied  %@NL@%
  16415.  
  16416.  
  16417. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16418.  
  16419. None  %@NL@%
  16420.  
  16421.  
  16422. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16423.  
  16424. Flags  %@NL@%
  16425.  
  16426. %@CR:C6A00400026 @%
  16427. %@2@%%@CR:C6A00400027 @%%@AB@%V86MMGR_Get_Xlat_Buff_State%@AE@%%@EH@%%@NL@%
  16428. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16429.  
  16430.  
  16431. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16432.  
  16433. This service returns information about the current mapping buffer status.  %@NL@%
  16434.  
  16435. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16436. %@AU@%WARNING%@AE@%
  16437.  
  16438. Always call this service to find the segment of the translation buffer.
  16439. Since the buffer can move at any time you should never make any assumptions
  16440. about the size or location of the buffer.
  16441. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16442.  
  16443.  
  16444. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16445.  
  16446. %@AB@%EBX %@AE@%= VM handle (any VM handle valid)  %@NL@%
  16447.  
  16448.  
  16449. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16450.  
  16451. %@AB@%EAX%@AE@% = V86 segment of translation buffer (high word 0) %@AB@%ECX%@AE@% = Number of bytes
  16452. of buffer not in use %@AB@%EDX%@AE@% = Total size of buffer in bytes (max size 10000h)  %@NL@%
  16453.  
  16454.  
  16455. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16456.  
  16457. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, Flags  %@NL@%
  16458.  
  16459. %@CR:C6A00400028 @%
  16460. %@2@%%@CR:C6A00400029 @%%@AB@%V86MMGR_Set_Xlat_Buff_State%@AE@%%@EH@%%@NL@%
  16461. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16462.  
  16463.  
  16464. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16465.  
  16466. This service is used to switch to an alternate mapping buffer. This feature
  16467. is provided for protected mode terminated-and-stay resident programs which
  16468. may need to switch to a private translation buffer before executing
  16469. protected mode MS-DOS calls since the default buffer may be full.  %@NL@%
  16470.  
  16471. You should get the current translation buffer state, set the new state,
  16472. perform any MS-DOS call, and then set the state back to the original values.
  16473. %@NL@%
  16474.  
  16475.  
  16476. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16477.  
  16478. %@AB@%EBX%@AE@% = VM handle (any VM handle valid) %@AB@%EAX %@AE@%= V86 segment of translation
  16479. buffer (high word 0) %@AB@%ECX%@AE@% = Number of bytes of buffer not in use %@AB@%EDX%@AE@% = Total
  16480. size of buffer in bytes (max size 10000h)  %@NL@%
  16481.  
  16482.  
  16483. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16484.  
  16485. None  %@NL@%
  16486.  
  16487.  
  16488. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16489.  
  16490. Flags  %@NL@%
  16491.  
  16492. %@CR:C6A00400030 @%
  16493. %@2@%%@CR:C6A00400031 @%%@AB@%V86MMGR_Get_VM_Flat_Sel%@AE@%%@EH@%%@NL@%
  16494. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16495.  
  16496.  
  16497. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16498.  
  16499. This service returns a selector that points to the base of the specified
  16500. VM's V86 address space. This is useful for 32-bit applications since this
  16501. selector can be used to point to any address in the VM's V86 address space.
  16502. The selector is writeable and has a limit of 11,000h bytes so that the high
  16503. memory area is also addressable.  %@NL@%
  16504.  
  16505. The selector returned is in the specified VM's LDT. Therefore, the selector
  16506. is only valid to use when the VM is running (is the current VM).  %@NL@%
  16507.  
  16508.  
  16509. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16510.  
  16511. %@AB@%EBX %@AE@%= VM handle (any VM handle is valid)  %@NL@%
  16512.  
  16513.  
  16514. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16515.  
  16516. %@AB@%EAX %@AE@%= Selector with base at high linear addr of V86 memory (high word 0)  %@NL@%
  16517.  
  16518.  
  16519. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16520.  
  16521. %@AB@%EAX%@AE@%, Flags  %@NL@%
  16522.  
  16523. %@CR:C6A00400032 @%
  16524. %@2@%%@CR:C6A00400033 @%%@AB@%V86MMGR_Get_Mapping_Info%@AE@%%@EH@%%@NL@%
  16525. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16526.  
  16527.  
  16528. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16529.  
  16530. This service will return information about the current page mapping areas.  %@NL@%
  16531.  
  16532.  
  16533. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16534.  
  16535. None  %@NL@%
  16536.  
  16537.  
  16538. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16539.  
  16540. %@AB@%CH%@AE@% = Number of pages reserved for global mapping (total) %@AB@%CL%@AE@% = Number of
  16541. pages available (not in use) for global mapping  %@NL@%
  16542.  
  16543. %@CR:C6A00400034 @%
  16544. %@2@%%@CR:C6A00400035 @%%@AB@%V86MMGR_Map_Pages%@AE@%%@EH@%%@NL@%
  16545. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16546.  
  16547.  
  16548. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16549.  
  16550. This service maps the specified buffer into every VM at the same address
  16551. using page mapping. If the contents of memory are changed in one VM, the
  16552. change will be reflected in the original buffer as well in all other VMs.  %@NL@%
  16553.  
  16554.  
  16555. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16556.  
  16557. %@AB@%ESI %@AE@%-> Linear address to map %@AB@%ECX%@AE@% = Number of bytes to map  %@NL@%
  16558.  
  16559.  
  16560. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16561.  
  16562. If carry flag is set then  ERROR: Could not map memory else  Memory is
  16563. mapped  %@AB@%ESI%@AE@% = Map handle (used to free the map region)  %@AB@%EDI %@AE@%= Linear address
  16564. of map buffer (%@NL@%
  16565.  
  16566.  
  16567. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16568.  
  16569. %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, Flags  %@NL@%
  16570.  
  16571. %@CR:C6A00400036 @%
  16572. %@2@%%@CR:C6A00400037 @%%@AB@%V86MMGR_Free_Page_Map_Region%@AE@%%@EH@%%@NL@%
  16573. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16574.  
  16575.  
  16576. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16577.  
  16578. This service will "unmap" pages that were mapped by the %@AB@%V86MMGR_Map_Pages%@AE@%
  16579. service.  %@NL@%
  16580.  
  16581.  
  16582. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16583.  
  16584. %@AB@%ESI%@AE@% = Map handle to free  %@NL@%
  16585.  
  16586.  
  16587. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16588.  
  16589. Old map buffer address contains null memory %@AB@%ESI%@AE@% is undefined  %@NL@%
  16590.  
  16591.  
  16592. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16593.  
  16594. %@AB@%ESI%@AE@%, Flags  %@NL@%
  16595.  
  16596.  
  16597.  
  16598.  
  16599.  
  16600.  
  16601. %@CR:C6A00410001 @%%@1@%%@AB@%Chapter 41  Virtual DMA Device (VDMAD) Services%@AE@%%@EH@%%@NL@%
  16602. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16603.  
  16604. The VDMAD is the Microsoft Windows virtual device providing DMA services
  16605. according to the VDS specifications. This VxD should be used in the enhanced
  16606. Windows environment rather than using the VDS services directely. By
  16607. default, it handles all programmed I/O for the DMA controllers and
  16608. arbitrates I/O to the physical DMA ports so that more than one VM can be
  16609. using the same DMA channels at the same time. In some cases, the default
  16610. handling of DMA channels is not desirable. To handle these cases, VDMAD
  16611. provides a number of services to enable another VxD to take control of the
  16612. virtualization of specific DMA channels.%@CR:C6A00410002 @%%@NL@%
  16613.  
  16614. VDMAD also provides some services that can be used by Bus Master devices
  16615. that have their own DMA controllers. These devices still need to be able to
  16616. lock and unlock DMA regions in memory and determine the physical addresses
  16617. of these regions. Bus Master devices can also make use of the buffer
  16618. services, if they cannot otherwise scatter/gather a linear region that is
  16619. not physically contiguous.  %@NL@%
  16620.  
  16621. The VDMAD services available for Bus Master use are as follows:  %@NL@%
  16622.  
  16623.  
  16624.   ■   %@AB@%VDMAD_Copy_From_Buffer%@AE@%%@NL@%
  16625.  
  16626.   ■   %@AB@%VDMAD_Copy_To_Buffer%@AE@%%@NL@%
  16627.  
  16628.   ■   %@AB@%VDMAD_Default_Handler%@AE@%%@NL@%
  16629.  
  16630.   ■   %@AB@%VDMAD_Disable_Translation%@AE@%%@NL@%
  16631.  
  16632.   ■   %@AB@%VDMAD_Enable_Translation%@AE@%%@NL@%
  16633.  
  16634.   ■   %@AB@%VDMAD_Get_EISA_Adr_Mode%@AE@%%@NL@%
  16635.  
  16636.   ■   %@AB@%VDMAD_Get_Region_Info%@AE@%%@NL@%
  16637.  
  16638.   ■   %@AB@%VDMAD_Get_Version%@AE@%%@NL@%
  16639.  
  16640.   ■   %@AB@%VDMAD_Get_Virt_State%@AE@%%@NL@%
  16641.  
  16642.   ■   %@AB@%VDMAD_Lock_DMA_Region%@AE@%%@NL@%
  16643.  
  16644.   ■   %@AB@%VDMAD_Mask_Channel%@AE@%%@NL@%
  16645.  
  16646.   ■   %@AB@%VDMAD_Release_Buffer%@AE@%%@NL@%
  16647.  
  16648.   ■   %@AB@%VDMAD_Request_Buffer%@AE@%%@NL@%
  16649.  
  16650.   ■   %@AB@%VDMAD_Reserve_Buffer_Space%@AE@%%@NL@%
  16651.  
  16652.   ■   %@AB@%VDMAD_Scatter_Lock%@AE@%%@NL@%
  16653.  
  16654.   ■   %@AB@%VDMAD_Scatter_Unlock%@AE@%%@NL@%
  16655.  
  16656.   ■   %@AB@%VDMAD_Set_EISA_Adr_Mode%@AE@%%@NL@%
  16657.  
  16658.   ■   %@AB@%VDMAD_Set_Phys_State%@AE@%%@NL@%
  16659.  
  16660.   ■   %@AB@%VDMAD_Set_Region_Info%@AE@%%@NL@%
  16661.  
  16662.   ■   %@AB@%VDMAD_Set_Virt_State%@AE@%%@NL@%
  16663.  
  16664.   ■   %@AB@%VDMAD_Unlock_DMA_Region%@AE@%%@NL@%
  16665.  
  16666.   ■   %@AB@%VDMAD_UnMask_Channel%@AE@%%@NL@%
  16667.  
  16668.   ■   %@AB@%VDMAD_Virtualize_Channel%@AE@%%@NL@%
  16669.  
  16670.  
  16671. %@CR:C6A00410003 @%
  16672. %@2@%%@CR:C6A00410004 @%%@AB@%VDMAD_Copy_From_Buffer%@AE@%%@EH@%%@NL@%
  16673. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16674.  
  16675.  
  16676. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16677.  
  16678. This service allows another device to copy data from the VDMAD buffer to the
  16679. actual DMA region associated with the buffer. This service is called after
  16680. %@AB@%VDMAD_Request_Buffer%@AE@%, after a memory write transfer and before
  16681. %@AB@%VDMAD_Release_Buffer%@AE@%.  %@NL@%
  16682.  
  16683.  
  16684. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16685.  
  16686. %@AB@%EBX%@AE@% = buffer ID %@AB@%ESI%@AE@% = region linear %@AB@%EDI %@AE@%= offset within buffer for start of
  16687. copy %@AB@%ECX%@AE@% = size  %@NL@%
  16688.  
  16689.  
  16690. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16691.  
  16692. Carry clear  data copied from buffer into DMA region Carry set  %@AB@%AL%@AE@% = 0Ah
  16693. (DMA_Invalid_Buffer) - invalid buffer  id supplied  = 0Bh
  16694. (DMA_Copy_Out_Range) - (%@AB@%ESI %@AE@%+ %@AB@%ECX%@AE@%) is  greater than buffer size  %@NL@%
  16695.  
  16696.  
  16697. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16698.  
  16699. Flags  %@NL@%
  16700.  
  16701. %@CR:C6A00410005 @%
  16702. %@2@%%@CR:C6A00410006 @%%@AB@%VDMAD_Copy_To_Buffer%@AE@%%@EH@%%@NL@%
  16703. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16704.  
  16705.  
  16706. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16707.  
  16708. This service allows another device to copy data into the VDMAD buffer from
  16709. the actual DMA region associated with the buffer.This service is called
  16710. after %@AB@%VDMAD_Request_Buffer%@AE@% and before starting a memory read transfer.  %@NL@%
  16711.  
  16712.  
  16713. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16714.  
  16715. %@AB@%EBX%@AE@% = buffer id %@AB@%ESI %@AE@% = region linear %@AB@%EDI %@AE@%= offset within buffer for start of
  16716. copy %@AB@%ECX%@AE@% = size  %@NL@%
  16717.  
  16718.  
  16719. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16720.  
  16721. Carry clear  data copied from DMA region into buffer Carry set  %@AB@%AL%@AE@% = 0Ah
  16722. (DMA_Invalid_Buffer) - invalid buffer  id supplied  = 0Bh
  16723. (DMA_Copy_Out_Range) - (%@AB@%ESI%@AE@% + %@AB@%ECX%@AE@%) is  greater than buffer size  %@NL@%
  16724.  
  16725.  
  16726. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16727.  
  16728. Flags  %@NL@%
  16729.  
  16730. %@CR:C6A00410007 @%
  16731. %@2@%%@CR:C6A00410008 @%%@AB@%VDMAD_Default_Handler%@AE@%%@EH@%%@NL@%
  16732. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16733.  
  16734.  
  16735. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16736.  
  16737. Default DMA channel I/O callback routine. This routine receives
  16738. notifications of virtual state changes and handles setting up the physical
  16739. state to start DMA transfers.  %@NL@%
  16740.  
  16741. %@AS@%  get virtual state
  16742. %@AS@%  If channel virtually unmasked then
  16743. %@AS@%      lock region
  16744. %@AS@%      If lock fails then
  16745. %@AS@%         request buffer
  16746. %@AS@%         If memory read operation then
  16747. %@AS@%             copy data to buffer
  16748. %@AS@%      set phyical state
  16749. %@AS@%      physically unmask channel%@AE@%
  16750.  
  16751.  
  16752. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16753.  
  16754. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  16755.  
  16756.  
  16757. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16758.  
  16759. None  %@NL@%
  16760.  
  16761.  
  16762. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16763.  
  16764. Anything  %@NL@%
  16765.  
  16766. %@CR:C6A00410009 @%
  16767. %@2@%%@CR:C6A00410010 @%%@AB@%VDMAD_Disable_Translation%@AE@%%@EH@%%@NL@%
  16768. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16769.  
  16770.  
  16771. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16772.  
  16773. This service disables the automatic translation done for the standard DMA
  16774. channels.It is necessary, if a V86 app or driver, or a PM app uses the DMA
  16775. services thru INT 4BH to determine actual physical addresses for DMA
  16776. transfers. A disable count is maintained, so a matching call to
  16777. %@AB@%VDMAD_Enable_Translation%@AE@% is required for each call to this service to
  16778. re-enable translation.  %@NL@%
  16779.  
  16780.  
  16781. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16782.  
  16783. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM Handle  %@NL@%
  16784.  
  16785.  
  16786. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16787.  
  16788. Carry clear   automatic translation is disable for the channel Carry set
  16789. the disable count overflowed  %@NL@%
  16790.  
  16791.  
  16792. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16793.  
  16794. Flags  %@NL@%
  16795.  
  16796. %@CR:C6A00410011 @%
  16797. %@2@%%@CR:C6A00410012 @%%@AB@%VDMAD_Enable_Translation%@AE@%%@EH@%%@NL@%
  16798. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16799.  
  16800.  
  16801. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16802.  
  16803. This decrements the disable count associated with a standard DMA channel. If
  16804. the disable count goes to 0, then automatic translation is re-enabled. See
  16805. %@AB@%VDMAD_Disable_Translation%@AE@% for further information.  %@NL@%
  16806.  
  16807.  
  16808. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16809.  
  16810. %@AB@%EAX %@AE@%= DMA handle %@AB@%EBX%@AE@% = VM Handle  %@NL@%
  16811.  
  16812.  
  16813. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16814.  
  16815. Carry clear   service completed successfully   Z-flag clear, if automatic
  16816. translation is re-enabled Carry set   attempt to enable when translation
  16817. already enabled  %@NL@%
  16818.  
  16819.  
  16820. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16821.  
  16822. Flags  %@NL@%
  16823.  
  16824. %@CR:C6A00410013 @%
  16825. %@2@%%@CR:C6A00410014 @%%@AB@%VDMAD_Get_EISA_Adr_Mode%@AE@%%@EH@%%@NL@%
  16826. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16827.  
  16828.  
  16829. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16830.  
  16831. Get EISA extended mode - the hardware doesn't allow for reading the extended
  16832. mode for a channel, so VDMAD defaults to the ISA defaults (channels 0-3 are
  16833. byte channels and 5-7 are word channels with word addresses and counts) An
  16834. INI switch can specify an alternate setting.  %@NL@%
  16835.  
  16836.  
  16837. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16838.  
  16839. %@AB@%EAX%@AE@% = Channel # (0..7) or  DMA Handle  %@NL@%
  16840.  
  16841.  
  16842. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16843.  
  16844. %@AB@%CL%@AE@% = 0 - 8-bit I/O, with count in bytes %@AB@%CL%@AE@% = 1 - 16-bit I/O, with count in
  16845. words and adr shifted %@AB@%CL%@AE@% = 2 - 32-bit I/O, with count in bytes %@AB@%CL%@AE@% = 3 -
  16846. 16-bit I/O, with count in bytes  %@NL@%
  16847.  
  16848.  
  16849. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16850.  
  16851. %@AB@%ECX%@AE@%, Flags  %@NL@%
  16852.  
  16853. %@CR:C6A00410015 @%
  16854. %@2@%%@CR:C6A00410016 @%%@AB@%VDMAD_Get_Region_Info%@AE@%%@EH@%%@NL@%
  16855. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16856.  
  16857.  
  16858. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16859.  
  16860. Get information about the current region assigned to a DMA handle. This
  16861. information can be used by a handler to call the following services:  %@NL@%
  16862.  
  16863.  
  16864.   ■   %@AB@%VDMAD_Unlock_DMA_Region%@AE@%%@NL@%
  16865.  
  16866.   ■   %@AB@%VDMAD_Release_Buffer%@AE@%%@NL@%
  16867.  
  16868.   ■   %@AB@%VDMAD_Copy_To_Buffer%@AE@%%@NL@%
  16869.  
  16870.   ■   %@AB@%VDMAD_Copy_From_Buffer%@AE@%%@NL@%
  16871.  
  16872.  
  16873.  
  16874. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16875.  
  16876. %@AB@%EAX%@AE@% = DMA handle  %@NL@%
  16877.  
  16878.  
  16879. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16880.  
  16881. %@AB@%BL %@AE@%= buffer id %@AB@%BH%@AE@% = pages locked (0 = FALSE, else TRUE) %@AB@%ESI %@AE@% = region linear
  16882. %@AB@%ECX%@AE@% = size in bytes  %@NL@%
  16883.  
  16884.  
  16885. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16886.  
  16887. %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%ESI%@AE@%  %@NL@%
  16888.  
  16889. %@CR:C6A00410017 @%
  16890. %@2@%%@CR:C6A00410018 @%%@AB@%VDMAD_Get_Version%@AE@%%@EH@%%@NL@%
  16891. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16892.  
  16893.  
  16894. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16895.  
  16896. Returns the version of the Virtual DMA Device  %@NL@%
  16897.  
  16898.  
  16899. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16900.  
  16901. None  %@NL@%
  16902.  
  16903.  
  16904. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16905.  
  16906. %@AB@%AH%@AE@% = Major version number %@AB@%AL%@AE@% = Minor version number %@AB@%ECX%@AE@% = Buffer size in
  16907. bytes (0, if not allocated; a buffer will always  be allocated, but it
  16908. doesn't happen until %@AB@%Device_Init%@AE@%) Carry flag clear  %@NL@%
  16909.  
  16910.  
  16911. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16912.  
  16913. %@AB@%EAX%@AE@%, Flags  %@NL@%
  16914.  
  16915. %@CR:C6A00410019 @%
  16916. %@2@%%@CR:C6A00410020 @%%@AB@%VDMAD_Get_Virt_State%@AE@%%@EH@%%@NL@%
  16917. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16918.  
  16919.  
  16920. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16921.  
  16922. This service allows a channel owner to determine the current virtual state
  16923. of the channel. The virtual state consists of all the information necessary
  16924. to physically program the DMA channel for a DMA transfer (linear address of
  16925. target region, byte length of region, mode of transfer, and state of mask
  16926. bit and software request bit) This state information reflects how the VM
  16927. thinks the hardware is currently programmed.  %@NL@%
  16928.  
  16929.  
  16930. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16931.  
  16932. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  16933.  
  16934.  
  16935. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16936.  
  16937. If translation is enabled  %@AB@%ESI%@AE@% = high linear address of the user's DMA
  16938. region    (high linear is used so that the DMA can proceed    even if a
  16939. different VM is actually running at the    time of the transfer) Else  %@AB@%ESI%@AE@% =
  16940. physical byte address programmed (shifted left 1,    for word ports) %@AB@%ECX%@AE@% =
  16941. count in bytes %@AB@%DL%@AE@%= mode (same as 8042 mode byte with channel # removed
  16942. and DMA_masked & DMA_requested set as    appropriate:      DMA_masked
  16943. channel masked and not ready            for a transfer      DMA_requested
  16944. software request flag set) %@AB@%DH%@AE@%= extended mode (ignored on non-PS2 machines
  16945. that don't       have extended DMA capabilities)  %@NL@%
  16946.  
  16947.  
  16948. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16949.  
  16950. %@AB@%ESI%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, flags  %@NL@%
  16951.  
  16952. %@CR:C6A00410021 @%
  16953. %@2@%%@CR:C6A00410022 @%%@AB@%VDMAD_Lock_DMA_Region%@AE@%%@EH@%%@NL@%
  16954. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16955.  
  16956.  
  16957. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16958.  
  16959. This service attempts to lock a region of memory for a DMA transfer. It is
  16960. called before a DMA transfer is started (before the physical state is set
  16961. for a channel and before it is unmasked.)  %@NL@%
  16962.  
  16963. It first verifies that the region is mapped to contiguous pages of physical
  16964. memory.  %@NL@%
  16965.  
  16966. Then it determines whether the region will result in a DMA bank (page)  %@NL@%
  16967.  
  16968. wrap  %@NL@%
  16969.  
  16970. %@STUB@%    On AT(R) class machines each channel has a base address register and a
  16971.     page address register. The base address register is incremented after
  16972.     each byte or word transfered. If the increment of this 16 bit register
  16973.     results in the roll over from FFFFh to 0, then the transfer wraps to the
  16974.     start of the DMA bank because the page register is not updated. Normally
  16975.     MS-DOS watches for this condition and adjusts INT 13h parameters to
  16976.     split transfers to avoid this wrap, but MS-DOS doesn't know anything
  16977.     about the difference between linear and physical addresses under
  16978.     enhanced Windows, so VDMAD checks again to prevent wrap from occurring
  16979.     undesirably.%@NL@%
  16980.  
  16981. If all of these checks are okay, then the service calls the memory manager
  16982. to lock the physical pages.  %@NL@%
  16983.  
  16984. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16985. NOTE
  16986.  
  16987. %@AI@%This routine does not check to see if the region is within some physical
  16988. %@AI@%maximum constraint. If the region is lockable, then it locks the memory, and
  16989. %@AI@%it is up to the caller to check to see if the physical region is acceptable.
  16990. %@AI@%If the region is not acceptable, then the caller should unlock the region
  16991. %@AI@%and perform a buffered DMA transfer.%@AE@%
  16992. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16993.  
  16994.  
  16995. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16996.  
  16997. %@AB@%ESI %@AE@% = linear address of actual DMA region %@AB@%ECX%@AE@% = # of bytes in DMA region %@AB@%DL
  16998. %@AB@%%@AE@%  = 1b, if region must be aligned on 64K page boundary  = 10b, if region
  16999. must be aligned on 128K page boundary  %@NL@%
  17000.  
  17001.  
  17002. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17003.  
  17004. Carry set, if lock failed   %@AB@%ECX%@AE@% = # of bytes that are lockable in the region
  17005. (starting from ESI)   %@AB@%AL%@AE@% = 1 (DMA_Not_Contiguous), region not contiguous  =
  17006. 2 (DMA_Not_Aligned), region crossed physical  alignment boundary  = 3
  17007. (DMA_Lock_Failed), unable to lock pages ELSE  %@AB@%EDX%@AE@% = physical address of the
  17008. DMA region  the region has been locked  %@NL@%
  17009.  
  17010.  
  17011. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17012.  
  17013. %@AB@%EAX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  17014.  
  17015. %@CR:C6A00410023 @%
  17016. %@2@%%@CR:C6A00410024 @%%@AB@%VDMAD_Mask_Channel%@AE@%%@EH@%%@NL@%
  17017. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17018.  
  17019.  
  17020. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17021.  
  17022. This service physically masks a channel so that it will not attempt any
  17023. further DMA transfers.  %@NL@%
  17024.  
  17025.  
  17026. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17027.  
  17028. %@AB@%EAX%@AE@% = DMA handle  %@NL@%
  17029.  
  17030.  
  17031. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17032.  
  17033. None  %@NL@%
  17034.  
  17035.  
  17036. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17037.  
  17038. Flags  %@NL@%
  17039.  
  17040. %@CR:C6A00410025 @%%@CR:C6A00410026 @%
  17041. %@2@%%@CR:C6A00410027 @%%@AB@%VDMAD_Release_Buffer%@AE@%%@EH@%%@NL@%
  17042. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17043.  
  17044.  
  17045. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17046.  
  17047. Release the VDMAD buffer assigned to a DMA channel from a previous
  17048. %@AB@%VDMAD_Request_Buffer%@AE@% call. This routine exits from a critical section and
  17049. the DMA buffer will now be available for other users. Any data in the buffer
  17050. is not automatically copied, so %@AB@%VDMAD_Copy_From_Buffer%@AE@% must be called if the
  17051. data is important.  %@NL@%
  17052.  
  17053.  
  17054. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17055.  
  17056. %@AB@%EBX%@AE@% = Buffer ID  %@NL@%
  17057.  
  17058.  
  17059. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17060.  
  17061. Carry clear  buffer released Carry set  bad ID  %@NL@%
  17062.  
  17063.  
  17064. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17065.  
  17066. Flags  %@NL@%
  17067.  
  17068. %@CR:C6A00410028 @%%@CR:C6A00410029 @%
  17069. %@2@%%@CR:C6A00410030 @%%@AB@%VDMAD_Request_Buffer%@AE@%%@EH@%%@NL@%
  17070. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17071.  
  17072.  
  17073. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17074.  
  17075. This service reserves the DMA buffer for a DMA transfer.  %@NL@%
  17076.  
  17077.  
  17078. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17079.  
  17080. %@AB@%ESI%@AE@% = linear address of actual DMA region %@AB@%ECX%@AE@% = # of bytes in DMA region  %@NL@%
  17081.  
  17082.  
  17083. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17084.  
  17085. Carry clear  %@AB@%EBX%@AE@% = buffer ID  %@AB@%EDX%@AE@% = the physical address of the buffer Carry
  17086. set  AL = 5 (DMA_Buffer_Too_Small), region request is  too large for buffer
  17087. = 6 (DMA_Buffer_In_Use), buffer already in use  %@NL@%
  17088.  
  17089.  
  17090. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17091.  
  17092. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ESI%@AE@%, Flags  %@NL@%
  17093.  
  17094. %@CR:C6A00410031 @%
  17095. %@2@%%@CR:C6A00410032 @%%@AB@%VDMAD_Reserve_Buffer_Space%@AE@%%@EH@%%@NL@%
  17096. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17097.  
  17098.  
  17099. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17100.  
  17101. This service allows other devices that are going to handle DMA to make sure
  17102. that VDMAD allocates a buffer large enough for any transfers that they might
  17103. require. It also allows a device to specify a maximum physical address that
  17104. would be valid for the device's DMA requests (such as 1Mb for an XT.) During
  17105. the %@AB@%Device_Init%@AE@% phase of initialization, VDMAD will allocate the DMA buffer
  17106. using all of the contraints specified by other devices.i.e. the buffer will
  17107. be at least as big as the largest size specified by the calls to this
  17108. service, and it will be allocate below the lowest maximum physical addresses
  17109. specified.  %@NL@%
  17110.  
  17111. This service is only available during %@AB@%Sys_Critical_Init%@AE@%.  %@NL@%
  17112.  
  17113.  
  17114. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17115.  
  17116. %@AB@%EAX%@AE@% = # of pages requested %@AB@%ECX%@AE@% = maximum physical address that can be
  17117. included in a  DMA transfer; 0, if no limit.  %@NL@%
  17118.  
  17119.  
  17120. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17121.  
  17122. None  %@NL@%
  17123.  
  17124.  
  17125. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17126.  
  17127. Flags  %@NL@%
  17128.  
  17129. %@CR:C6A00410033 @%
  17130. %@2@%%@CR:C6A00410034 @%%@AB@%VDMAD_Scatter_Lock%@AE@%%@EH@%%@NL@%
  17131. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17132.  
  17133.  
  17134. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17135.  
  17136. This service attempts to lock all pages mapped to a DMA region and return
  17137. the actual physical addresses of the pages.  %@NL@%
  17138.  
  17139.  
  17140. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17141.  
  17142. %@AB@%EBX%@AE@% = VM Handle %@AB@%AL%@AE@% = 0, if the DDS table should be filled with physical
  17143. addresses and sizes of the physical regions that  make up the DMA region %@AB@%AL%@AE@%
  17144. = 1, if the DDS table should be filled with the actual  page table entries
  17145. %@AB@%AL%@AE@% = 3, if the DDS table should be filled with the actual  page table
  17146. entries and not present pages should not  be locked %@AB@%EDI%@AE@% -> extended DDS (DMA
  17147. Descriptor Structure)  %@NL@%
  17148.  
  17149.  
  17150. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17151.  
  17152. Carry clear  Z-flag set  whole region was locked successfully  Z-flag clear
  17153. partial region locked Carry set  nothing locked  %@AB@%EDX %@AE@%= # of table entries
  17154. needed to describe whole region DDS_size = # of bytes locked DDS table has
  17155. been updated if request was for page table copy (AL=1 OR 3), then  %@AB@%ESI%@AE@% =
  17156. offset into first page for start of the region  %@NL@%
  17157.  
  17158.  
  17159. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17160.  
  17161. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, Flags  %@NL@%
  17162.  
  17163. %@CR:C6A00410035 @%
  17164. %@2@%%@CR:C6A00410036 @%%@AB@%VDMAD_Scatter_Unlock%@AE@%%@EH@%%@NL@%
  17165. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17166.  
  17167.  
  17168. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17169.  
  17170. This service attempts to unlock all pages locked by a previous call to
  17171. %@AB@%VDMAD_Scatter_Lock%@AE@%  %@NL@%
  17172.  
  17173.  
  17174. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17175.  
  17176. %@AB@%EBX%@AE@% = VM Handle %@AB@%AL%@AE@% = 0, if the DDS table should be filled with physical
  17177. addresses and sizes of the physical regions that  make up the DMA region %@AB@%AL
  17178. %@AB@%%@AE@%= 1, if the DDS table should be filled with the actual  page table entries
  17179. %@AB@%AL %@AE@%= 3, if the DDS table should be filled with the actual  page table
  17180. entries and not present pages should not  be locked %@AB@%EDI%@AE@% -> extended DDS (DMA
  17181. Descriptor Structure)  (The table at the end of the DDS is not required, so
  17182. it is not necessary to maintain the table for this  unlock call.)  %@NL@%
  17183.  
  17184.  
  17185. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17186.  
  17187. Carry clear  Lock counts have been decremented. If no other VxD's  had pages
  17188. locked, then the pages have been unlocked. Carry set  The memory was not
  17189. locked.  %@NL@%
  17190.  
  17191.  
  17192. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17193.  
  17194. Flags  %@NL@%
  17195.  
  17196. %@CR:C6A00410037 @%
  17197. %@2@%%@CR:C6A00410038 @%%@AB@%VDMAD_Set_EISA_Adr_Mode%@AE@%%@EH@%%@NL@%
  17198. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17199.  
  17200.  
  17201. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17202.  
  17203. Set EISA extended mode  %@NL@%
  17204.  
  17205.  
  17206. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17207.  
  17208. %@AB@%EAX%@AE@% = Channel # (0..7) or  DMA Handle %@AB@%CL%@AE@% = 0 - 8-bit I/O, with count in
  17209. bytes %@AB@%CL%@AE@% = 1 - 16-bit I/O, with count in words and adr shifted %@AB@%CL%@AE@% = 2 -
  17210. 32-bit I/O, with count in bytes %@AB@%CL %@AE@%= 3 - 16-bit I/O, with count in bytes  %@NL@%
  17211.  
  17212.  
  17213. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17214.  
  17215. None  %@NL@%
  17216.  
  17217.  
  17218. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17219.  
  17220. Flags  %@NL@%
  17221.  
  17222. %@CR:C6A00410039 @%
  17223. %@2@%%@CR:C6A00410040 @%%@AB@%VDMAD_Set_Phys_State%@AE@%%@EH@%%@NL@%
  17224. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17225.  
  17226.  
  17227. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17228.  
  17229. This service programs the DMA controller state for a channel. All that it
  17230. needs to know is the desired mode. The location and size of the buffer is
  17231. taken from the information passed to the service %@AB@%VDMAD_Set_Region_Info%@AE@% which
  17232. must be called previously.  %@NL@%
  17233.  
  17234.  
  17235. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17236.  
  17237. %@AB@%EAX %@AE@%= DMA handle %@AB@%EBX %@AE@%= VM handle %@AB@%DL%@AE@% = mode %@AB@%DH %@AE@%= extended mode  %@NL@%
  17238.  
  17239.  
  17240. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17241.  
  17242. None  %@NL@%
  17243.  
  17244.  
  17245. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17246.  
  17247. Flags  %@NL@%
  17248.  
  17249. %@CR:C6A00410041 @%
  17250. %@2@%%@CR:C6A00410042 @%%@AB@%VDMAD_Set_Region_Info%@AE@%%@EH@%%@NL@%
  17251. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17252.  
  17253.  
  17254. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17255.  
  17256. Set information about the current region assigned to a DMA handle. This
  17257. service must be called before calling %@AB@%VDMAD_Set_Phys_State%@AE@%.  %@NL@%
  17258.  
  17259.  
  17260. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17261.  
  17262. %@AB@%EAX %@AE@%= DMA handle %@AB@%BL %@AE@%= buffer id %@AB@%BH %@AE@%= pages locked (0 = FALSE, else TRUE) %@AB@%ESI%@AE@%
  17263. = region linear %@AB@%ECX %@AE@%= size in bytes %@AB@%EDX%@AE@% = physical address for transfer  %@NL@%
  17264.  
  17265.  
  17266. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17267.  
  17268. None  %@NL@%
  17269.  
  17270.  
  17271. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17272.  
  17273. Flags  %@NL@%
  17274.  
  17275. %@CR:C6A00410043 @%
  17276. %@2@%%@CR:C6A00410044 @%%@AB@%VDMAD_Set_Virt_State%@AE@%%@EH@%%@NL@%
  17277. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17278.  
  17279.  
  17280. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17281.  
  17282. Modify the virtual state of a DMA channel. This is service is used when a
  17283. channel owner wants to change the virtual state of a channel from how the VM
  17284. programmed it.This might be used to split a DMA request into smaller pieces,
  17285. etc.  %@NL@%
  17286.  
  17287.  
  17288. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17289.  
  17290. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM handle If translation is enabled  %@AB@%ESI%@AE@% = high
  17291. linear address of the user's DMA region  (high linear is used so that the
  17292. DMA can proceed  even if a different VM is actually running at the  time of
  17293. the transfer) Else  %@AB@%ESI%@AE@% = physical byte address programmed (shifted left 1,
  17294. for word ports) %@AB@%ECX%@AE@% = count in bytes %@AB@%DL%@AE@%= mode (same as 8042 mode byte with
  17295. channel # removed  and DMA_masked & DMA_requested set as  appropriate:
  17296. DMA_masked channel masked and not ready  for a transfer  DMA_requested
  17297. software request flag set) %@AB@%DH%@AE@%= extended mode (ignored on non-PS2 machines
  17298. that don't  have extended DMA capabilities)  %@NL@%
  17299.  
  17300.  
  17301. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17302.  
  17303. None  %@NL@%
  17304.  
  17305.  
  17306. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17307.  
  17308. Flags  %@NL@%
  17309.  
  17310. %@CR:C6A00410045 @%
  17311. %@2@%%@CR:C6A00410046 @%%@AB@%VDMAD_Unlock_DMA_Region%@AE@%%@EH@%%@NL@%
  17312. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17313.  
  17314.  
  17315. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17316.  
  17317. This service unlocks the DMA region previously locked to a channel. It is
  17318. called after a DMA transfer is complete and the channel has been masked. So
  17319. that the controller will not attempt any further transfers to the programmed
  17320. address.  %@NL@%
  17321.  
  17322.  
  17323. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17324.  
  17325. %@AB@%ESI%@AE@% = linear address of actual DMA region %@AB@%ECX%@AE@% = # of bytes in DMA region  %@NL@%
  17326.  
  17327.  
  17328. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17329.  
  17330. Carry clear    memory unlocked Carry set    error  %@NL@%
  17331.  
  17332.  
  17333. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17334.  
  17335. Flags  %@NL@%
  17336.  
  17337. %@CR:C6A00410047 @%
  17338. %@2@%%@CR:C6A00410048 @%%@AB@%VDMAD_UnMask_Channel%@AE@%%@EH@%%@NL@%
  17339. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17340.  
  17341.  
  17342. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17343.  
  17344. This service physically unmasks a channel so that DMA transfers can proceed.
  17345. %@NL@%
  17346.  
  17347.  
  17348. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17349.  
  17350. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX %@AE@%= VM Handle  %@NL@%
  17351.  
  17352.  
  17353. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17354.  
  17355. None  %@NL@%
  17356.  
  17357.  
  17358. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17359.  
  17360. Flags  %@NL@%
  17361.  
  17362. %@CR:C6A00410049 @%
  17363. %@2@%%@CR:C6A00410050 @%%@AB@%VDMAD_Virtualize_Channel%@AE@%%@EH@%%@NL@%
  17364. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17365.  
  17366.  
  17367. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17368.  
  17369. This service allows another VxD to claim ownership of a standard DMA
  17370. channel. The new owner registers a callback routine that will be called
  17371. whenever the virtual state of the channel is changed as a result of I/O done
  17372. in a VM. In some cases a device doesn't want to allow a VM to perform DMA to
  17373. a channel at all (they will handle programming based on a private API, etc.
  17374. instead of virtualized hardware I/O), so it is possible to pass a 0 to
  17375. specify a null callback routine. VDMAD will continue to trap the I/O for the
  17376. channel, but won't ever change the physical state of the channel as a result
  17377. of any VM I/O.  %@NL@%
  17378.  
  17379.  
  17380. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17381.  
  17382. %@AB@%EAX%@AE@% is Channel # %@AB@%ESI%@AE@% is I/O Callback procedure (0 = none)  %@NL@%
  17383.  
  17384.  
  17385. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17386.  
  17387. Carry set if channel is already owned ELSE  %@AB@%EAX%@AE@% is DMA handle  %@NL@%
  17388.  
  17389.  
  17390. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17391.  
  17392. Flags  %@NL@%
  17393.  
  17394.  
  17395. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  17396.  
  17397. ENTRY   %@AB@%EAX%@AE@% = DMA handle   %@AB@%EBX%@AE@% = VM handle   Proc can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  17398. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and flags  EXIT   None  %@NL@%
  17399.  
  17400.  
  17401.  
  17402.  
  17403.  
  17404.  
  17405. %@CR:C6A00420001 @%%@1@%%@AB@%Chapter 42  Virtual DOSNET Device Services%@AE@%%@EH@%%@NL@%
  17406. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17407.  
  17408. The DOSNET device manages the network drives. To do so, it has a service
  17409. (%@AB@%DOSNET_Do_PSP_Adjust%@AE@%) that enables it to indicate that the network server
  17410. uses PSP addresses to identify tasks uniquely. Therefore, each VM's address
  17411. space should start at a unique address. It has another service
  17412. (%@AB@%DOSNET_Send_FILESYSCHANGE%@AE@%) that enables the Shell to determine whether or
  17413. not a particular drive is redirected in the System VM. These services are
  17414. required when network software is loaded with Windows in 386 enhanced mode.
  17415. %@NL@%
  17416.  
  17417.  
  17418. %@2@%%@CR:C6A00420002 @%%@AB@%DOSNET_Get_Version%@CR:C6A00420003 @%%@AE@%%@EH@%%@NL@%
  17419. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17420.  
  17421.  
  17422. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17423.  
  17424. This service returns the DOSNET device version.  %@NL@%
  17425.  
  17426.  
  17427. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17428.  
  17429. None  %@NL@%
  17430.  
  17431.  
  17432. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17433.  
  17434. %@AB@%EAX%@AE@% = Version, Major in %@AB@%AH%@AE@%, Minor in %@AB@%AL%@AE@% Carry clear  %@NL@%
  17435.  
  17436.  
  17437. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17438.  
  17439. Flags, %@AB@%EAX%@AE@%  %@NL@%
  17440.  
  17441. %@CR:C6A00420004 @%
  17442. %@2@%%@CR:C6A00420005 @%%@AB@%DOSNET_Do_PSP_Adjust%@AE@%%@EH@%%@NL@%
  17443. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17444.  
  17445.  
  17446. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17447.  
  17448. This service enables the DOSMGR device to ask whether or not it should
  17449. perform adjustments to try to give each VM in the system a different
  17450. starting MS-DOS PSP address. This needs to be done on networks (such as
  17451. MSNET) that use the PSP address as part of an ID to identify uniquely
  17452. different processes talking to the server (this effects the behavior of DOS
  17453. SHARE on the server end). On a network that uses MS-DOS PSP addresses as
  17454. part of an ID, enhanced Windows can cause the ID to be non-unique since
  17455. there are now multiple VMs that can all have an application in them that has
  17456. the same PSP address. If the PSP adjust is enabled by this service, the
  17457. DOSMGR device causes each VM to start at a different paragraph address (VMID
  17458. is the basis of the adjustment value) and thus have a different PSP address.
  17459. This has the cost of wasting some memory and the benefit of making the PSP
  17460. addresses different in all the VMs.  %@NL@%
  17461.  
  17462. For a network that does not use MS-DOS PSP addresses for anything, or for
  17463. one that is enhanced-Windows aware and uses the %@AB@%Get_VMID%@AE@% INT 2F service of
  17464. enhanced Windows to deal with this problem, a return of Carry SET, %@AB@%EAX%@AE@%  0 is
  17465. appropriate.  %@NL@%
  17466.  
  17467. Notice that the uniqueness of PSPs is not guaranteed by this. It will deal
  17468. with the case on most configurations, but on some it will not. The only
  17469. absolutely correct solution is to make the network software enhanced-Windows
  17470. aware and work the VMID into the network ID, in addition to the PSP address,
  17471. by using the %@AB@%Get_VMID%@AE@% INT 2F service of enhanced Windows.  %@NL@%
  17472.  
  17473.  
  17474. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17475.  
  17476. None  %@NL@%
  17477.  
  17478.  
  17479. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17480.  
  17481. Carry Set  Do %@AI@%not%@AE@% do PSP adjustment  %@AB@% EAX%@AE@% == 0 if SYSTEM.INI override of
  17482. this is allowed  %@AB@%EAX%@AE@%  0 if SYSTEM.INI override of this is %@AI@%not%@AE@% allowed Carry
  17483. Clear  DO PSP adjustment  %@AB@%EAX%@AE@% == 0 if SYSTEM.INI override of this is allowed
  17484. %@AB@%EAX %@AE@%0 if SYSTEM.INI override of this is %@AI@%not%@AE@% allowed  %@NL@%
  17485.  
  17486. Notice that the behavior of DOSMGR, if the DOSNET device is not loaded, is a
  17487. return of carry Set, %@AB@%EAX %@AE@%= 0.  %@NL@%
  17488.  
  17489.  
  17490. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17491.  
  17492. Flags, %@AB@%EAX%@AE@%  %@NL@%
  17493.  
  17494. %@CR:C6A00420006 @%
  17495. %@2@%%@CR:C6A00420007 @%%@AB@%DOSNET_Send_FILESYSCHANGE%@AE@%%@EH@%%@NL@%
  17496. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17497.  
  17498.  
  17499. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17500.  
  17501. It is incorrect to send the WM_FILESYSCHANGE message to the Windows Shell on
  17502. drives about which Windows knows nothing. This routine tells the caller
  17503. whether this is a "local to this VM" drive or not. The message enables
  17504. Windows applications to be told when a change is made to the file volume
  17505. name space so that they can update portions of their display that may be
  17506. showing that part of the file volume.  %@NL@%
  17507.  
  17508. Sending a WM_FILESYSCHANGE message on a drive incorrectly can result in all
  17509. sorts of misbehavior. If the indicated drive letter is invalid in the System
  17510. VM, the Windows application may get an error that it is not expecting. If
  17511. the indicated drive letter actually maps a different file system volume in
  17512. the System VM, all sorts of other unexpected errors may occur.  %@NL@%
  17513.  
  17514. Notice that this is a DOSNET device service and cannot be implemented
  17515. directly in another VxD. Another VxD that also wishes to effect the
  17516. WM_FILESYSCHANGE behavior must hook this service. Notice also that the
  17517. DOSNET device does not install if there is no REDIR, so a VxD that wants to
  17518. hook this service must ship with a modified DOSNET device that always loads
  17519. (i.e., with the real-mode init code removed).  %@NL@%
  17520.  
  17521.  
  17522. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17523.  
  17524. %@AB@%EAX%@AE@% (AL) = Drive number (0 = A) %@AB@%EBX%@AE@% is VM Handle of VM involved  %@NL@%
  17525.  
  17526.  
  17527. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17528.  
  17529. Carry Set  WM_FILESYSCHANGE should %@AI@%not%@AE@% be sent on this drive Carry Clear
  17530. WM_FILESYSCHANGE %@AI@%should%@AE@% be sent on this drive  %@NL@%
  17531.  
  17532.  
  17533. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17534.  
  17535. Flags  %@NL@%
  17536.  
  17537.  
  17538.  
  17539.  
  17540.  
  17541.  
  17542. %@CR:C6A-A0001   @%%@1@%%@AB@%Appendix A  Appendix A Terms and Acronyms%@AE@%%@EH@%%@NL@%
  17543. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17544.  
  17545. The following list explains the terms and acronyms that are found in the
  17546. %@AI@%Microsoft Windows Device Development Kit%@AE@% for Windows 3.0.  %@NL@%
  17547.  
  17548. %@2@%%@AB@%Banding%@AE@%%@EH@%%@NL@%
  17549. %@3@%The process of dividing a display surface such as a page into smaller%@EH@%
  17550. horizontal rectangles, composing those individual bands within memory, and
  17551. then sending the output to the printer one band at a time.%@NL@%
  17552.  
  17553. %@2@%%@AB@%Clipping%@AE@%%@EH@%%@NL@%
  17554. %@3@%The process of removing any portion of a graphic image that extends beyond a%@EH@%
  17555. specified boundary.%@NL@%
  17556.  
  17557. %@2@%%@AB@%Control Block%@AE@%%@EH@%%@NL@%
  17558. %@3@%A per Virtual Machine data structure in which Virtual Devices and the%@EH@%
  17559. Virtual Machine Manager can maintain the VM's state information. The control
  17560. block shares the flat segment with the VMM and VxDs. It is pointed to by the
  17561. VM Handle.%@NL@%
  17562.  
  17563. %@2@%%@AB@%Control Panel%@AE@%%@EH@%%@NL@%
  17564. %@3@%A Windows application that lets you change system settings, including%@EH@%
  17565. printer assignments and system characteristics.%@NL@%
  17566.  
  17567. %@2@%%@AB@%Descriptor Table%@AE@%%@EH@%%@NL@%
  17568. %@3@%An array of segment descriptors. There are two kinds of descriptor tables:%@EH@%
  17569. the unique Global Descriptor Table, and the per-VM Local Descriptor Table.%@NL@%
  17570.  
  17571. %@2@%%@AB@%Device Driver%@AE@%%@EH@%%@NL@%
  17572. %@3@%The dynamic-link library that provides the hardware-dependent, low-level%@EH@%
  17573. interface between Windows GDI functions and the graphics output device.%@NL@%
  17574.  
  17575. %@2@%%@AB@%Device Independent Bitmap (DIB)%@AE@%%@EH@%%@NL@%
  17576. %@3@%A bitmap format that can be interpreted and converted by a device driver%@EH@%
  17577. into its own specific format. It is called "device independent" because any
  17578. driver capable of using DIBs can display (or otherwise use) the DIB to the
  17579. best of its ability.%@NL@%
  17580.  
  17581. %@2@%%@AB@%Direct Memory Access (DMA) %@AE@%%@EH@%%@NL@%
  17582. %@3@%An accelerated memory access technique that enables peripheral devices to%@EH@%
  17583. take control of the bus. See also Virtual DMA Services (VDS).%@NL@%
  17584.  
  17585. %@2@%%@AB@%DOS Protected Mode Interface (DPMI) %@AE@%%@EH@%%@NL@%
  17586. %@3@%The industry standard for non-Windows applications using protected mode. It%@EH@%
  17587. is available from Intel at 1-800-548-4725.%@NL@%
  17588.  
  17589. %@2@%%@AB@%Dynamic Data Exchange (DDE)%@AE@%%@EH@%%@NL@%
  17590. %@3@%A protocol that cooperating programs can use to exchange data without user%@EH@%
  17591. intervention.%@NL@%
  17592.  
  17593. %@2@%%@AB@%Dynamic-Link Library (DLL) %@AE@%%@EH@%%@NL@%
  17594. %@3@%An executable module that contains functions available to applications and%@EH@%
  17595. that is linked at run time, rather than at link time.%@NL@%
  17596.  
  17597. %@2@%%@AB@%Enhanced Windows%@AE@%%@EH@%%@NL@%
  17598. %@3@%Windows 3.0 when running in 386 enhanced mode.%@NL@%%@EH@%
  17599.  
  17600. %@2@%%@AB@%Escape%@AE@%%@EH@%%@NL@%
  17601. %@3@%A device-dependent operation that is not supported by the device-independent%@EH@%
  17602. GDI module. The entry point in the device driver is called %@AB@%Control()%@AE@%; in GDI
  17603. (i.e., to the application), it is called %@AB@%Escape()%@AE@%.%@NL@%
  17604.  
  17605. %@2@%%@AB@%Extended Memory Specification (XMS)%@AE@%%@EH@%%@NL@%
  17606. %@3@%The XMS driver provides an API for managing extended memory. Windows uses%@EH@%
  17607. XMS to load its code and data into extended memory.%@NL@%
  17608.  
  17609. %@2@%%@AB@%Flat Model%@AE@%%@EH@%%@NL@%
  17610. %@3@%A memory organization in which there is only one segment.%@NL@%%@EH@%
  17611.  
  17612. %@2@%%@AB@%Font Resource%@AE@%%@EH@%%@NL@%
  17613. %@3@%A group of individual fonts that have various combinations of heights,%@EH@%
  17614. widths, and pitches.%@NL@%
  17615.  
  17616. %@2@%%@AB@%GDI Library%@AE@%%@EH@%%@NL@%
  17617. %@3@%A set of supporting functions for device drivers. These utilities include%@EH@%
  17618. versions of output functions such as %@AB@%BitBlt%@AE@% and %@AB@%StrBlt%@AE@%, a Transpose function
  17619. for banding devices, and priority queue functions for daisywheel printers.%@NL@%
  17620.  
  17621. %@2@%%@AB@%Global Descriptor Table (GDT)%@AE@%%@EH@%%@NL@%
  17622. %@3@%See Descriptor Table.%@NL@%%@EH@%
  17623.  
  17624. %@2@%%@AB@%Graphics Device Interface (GDI)%@AE@%%@EH@%%@NL@%
  17625. %@3@%A device-independent, high-level graphics manager. GDI provides the%@EH@%
  17626. interface that feeds graphics commands from Windows application programs to
  17627. the device driver.%@NL@%
  17628.  
  17629. %@2@%%@AB@%IOPM%@AE@%%@EH@%%@NL@%
  17630. %@3@%I/O Permission Map%@NL@%%@EH@%
  17631.  
  17632. %@2@%%@AB@%Local Descriptor Table (LDT)%@AE@%%@EH@%%@NL@%
  17633. %@3@%See Descriptor Table.%@NL@%%@EH@%
  17634.  
  17635. %@2@%%@AB@%Metafile%@AE@%%@EH@%%@NL@%
  17636. %@3@%A collection of GDI function calls stored in a binary coded form and used to%@EH@%
  17637. transfer device-independent pictures between programs.%@NL@%
  17638.  
  17639. %@2@%%@AB@%Microsoft Macro Assembler (MASM)%@AE@%%@EH@%%@NL@%
  17640. %@3@%An assembly language compiler.%@NL@%%@EH@%
  17641.  
  17642. %@2@%%@AB@%Non-Windows Application%@AE@%%@EH@%%@NL@%
  17643. %@3@%A program that does not make use of the Windows environment. Instead, it%@EH@%
  17644. calls MS-DOS and the BIOS, and accesses the hardware directly.%@NL@%
  17645.  
  17646. %@2@%%@AB@%Page%@AE@%%@EH@%%@NL@%
  17647. %@3@%A 4K block of contiguous memory locations.%@NL@%%@EH@%
  17648.  
  17649. %@2@%%@AB@%Paging%@AE@%%@EH@%%@NL@%
  17650. %@3@%A memory-management technique used by enhanced Windows to support virtual%@EH@%
  17651. memory. It simulates a large, unsegmented address space by using a small,
  17652. fragmented address space and some disk storage. Paging accomplishes this by
  17653. keeping the available memory space partly in memory and partly on disk.%@NL@%
  17654.  
  17655. %@2@%%@AB@%Palette%@AE@%%@EH@%%@NL@%
  17656. %@3@%The range of colors that the video adapter can display and manage.%@NL@%%@EH@%
  17657.  
  17658. %@2@%%@AB@%Pixel%@AE@%%@EH@%%@NL@%
  17659. %@3@%The smallest element of a physical display surface that can be independently%@EH@%
  17660. assigned color or intensity.%@NL@%
  17661.  
  17662. %@2@%%@AB@%Pixel Array%@AE@%%@EH@%%@NL@%
  17663. %@3@%A matrix of pixels that defines the color for a region on an actual display.%@EH@%
  17664. There is exactly one pixel definition for each addressable picture element
  17665. of a raster display covered by the pixel array.%@NL@%
  17666.  
  17667. %@2@%%@AB@%Primitive%@AE@%%@EH@%%@NL@%
  17668. %@3@%A basic graphic function to be performed.%@NL@%%@EH@%
  17669.  
  17670. %@2@%%@AB@%Print Manager%@AE@%%@EH@%%@NL@%
  17671. %@3@%The Windows utility that prints files without suspending the operation of%@EH@%
  17672. other programs. It also enables you to change the priority of print jobs or
  17673. to cancel them.%@NL@%
  17674.  
  17675. %@2@%%@AB@%Printer Command Language (PCL)%@AE@%%@EH@%%@NL@%
  17676. %@3@%The language used by Hewlett-Packard (R) Laserjet (R) and compatible%@EH@%
  17677. printers.%@NL@%
  17678.  
  17679. %@2@%%@AB@%Privilege Rings%@AE@%%@EH@%%@NL@%
  17680. %@3@%The protection value applied to segments and segment selectors. Enhanced%@EH@%
  17681. Windows uses the most privileged level (ring 0) for the VMM and VxDs. Code
  17682. and data for applications running in virtual-86 mode use the least
  17683. privileged level (ring 3). Protected-mode applications run in rings 1, 2, or
  17684. 3.%@NL@%
  17685.  
  17686. %@2@%%@AB@%Protected Mode (PM)%@AE@%%@EH@%%@NL@%
  17687. %@3@%A mode of the 80386 and 80486 processors that provides, among other%@EH@%
  17688. capabilities, arbitrary mapping of segment register values to physical
  17689. memory. See Appendix B, "Understanding Modes," for a detailed description.
  17690. Applications that want to use protected mode must conform to the DPMI
  17691. specification.%@NL@%
  17692.  
  17693. %@2@%%@AB@%Raster Device%@AE@%%@EH@%%@NL@%
  17694. %@3@%A device that uses a matrix of pixels covering the entire screen or page%@EH@%
  17695. area (display or printed surface) to draw graphics. Pixels (points) are
  17696. turned on and off, bit-by-bit.%@NL@%
  17697.  
  17698. %@2@%%@AB@%Real Mode%@AE@%%@EH@%%@NL@%
  17699. %@3@%An execution mode of an Intel processor that functions as an 8086; also%@EH@%
  17700. called "real-address mode." The 80286, 80386, and 80486 processors run in
  17701. this mode when started up. See also Appendix B, "Understanding Modes."%@NL@%
  17702.  
  17703. %@2@%%@AB@%Red, Green, Blue (RGB)%@AE@%%@EH@%%@NL@%
  17704. %@3@%Values from a color table. This color table is used in mapping from a color%@EH@%
  17705. index to corresponding color values.%@NL@%
  17706.  
  17707. %@2@%%@AB@%Resolution%@AE@%%@EH@%%@NL@%
  17708. %@3@%The number of visibly distinct dots that can be displayed in a given area of%@EH@%
  17709. the screen. Typical resolution is 100 dots per inch.%@NL@%
  17710.  
  17711. %@2@%%@AB@%Scaling%@AE@%%@EH@%%@NL@%
  17712. %@3@%Coordinate scaling transforms points from one level to another. GDI scales%@EH@%
  17713. coordinates from NDC space to values appropriate for your graphics device.%@NL@%
  17714.  
  17715. %@2@%%@AB@%%@AB@%SETUP.INF%@AE@%%@AE@%%@EH@%%@NL@%
  17716. %@3@%A file containing all the information needed to set up a device driver for%@EH@%
  17717. Windows. See also Appendix C, "Creating Distribution Disks for Drivers."%@NL@%
  17718.  
  17719. %@2@%%@AB@%%@AB@%SYSTEM.INI%@AE@%%@AE@%%@EH@%%@NL@%
  17720. %@3@%A file in the Windows directory that holds the Windows configuration%@EH@%
  17721. information that is used when starting up Windows. It differs from WIN.INI,
  17722. which is mainly for storing user preferences, by containing hardware and
  17723. software descriptions.%@NL@%
  17724.  
  17725. %@2@%%@AB@%System VM%@AE@%%@EH@%%@NL@%
  17726. %@3@%The first Virtual Machine (VM) under enhanced Windows. The VM in which%@EH@%
  17727. Windows runs.%@NL@%
  17728.  
  17729. %@2@%%@AB@%Task%@AE@%%@EH@%%@NL@%
  17730. %@3@%A program that is running or waiting to run.%@NL@%%@EH@%
  17731.  
  17732. %@2@%%@AB@%Task Switch%@AE@%%@EH@%%@NL@%
  17733. %@3@%A transfer of execution between tasks (i.e., a context switch). Unlike%@EH@%
  17734. procedure calls, which saves only the contents of the general registers, a
  17735. task switch saves most of the processor state. For example, the registers
  17736. used for address translation are reloaded, so that each task can have a
  17737. different logical-to-physical address mapping.%@NL@%
  17738.  
  17739. %@2@%%@AB@%TSRs%@AE@%%@EH@%%@NL@%
  17740. %@3@%Terminate-and-Stay Resident applications.%@NL@%%@EH@%
  17741.  
  17742. %@2@%%@AB@%VCD%@AE@%%@EH@%%@NL@%
  17743. %@3@%Virtual Comm Device%@NL@%%@EH@%
  17744.  
  17745. %@2@%%@AB@%VDD%@AE@%%@EH@%%@NL@%
  17746. %@3@%Virtual Display Device%@NL@%%@EH@%
  17747.  
  17748. %@2@%%@AB@%VDMAD%@AE@%%@EH@%%@NL@%
  17749. %@3@%Virtual DMA Device%@NL@%%@EH@%
  17750.  
  17751. %@2@%%@AB@%VFD%@AE@%%@EH@%%@NL@%
  17752. %@3@%Virtual Floppy Drive Device%@NL@%%@EH@%
  17753.  
  17754. %@2@%%@AB@%VHD%@AE@%%@EH@%%@NL@%
  17755. %@3@%Virtual Hard Disk Device%@NL@%%@EH@%
  17756.  
  17757. %@2@%%@AB@%VKD%@AE@%%@EH@%%@NL@%
  17758. %@3@%Virtual Keyboard Device%@NL@%%@EH@%
  17759.  
  17760. %@2@%%@AB@%VMD%@AE@%%@EH@%%@NL@%
  17761. %@3@%Virtual Mouse Device%@NL@%%@EH@%
  17762.  
  17763. %@2@%%@AB@%VPD%@AE@%%@EH@%%@NL@%
  17764. %@3@%Virtual Printer Device%@NL@%%@EH@%
  17765.  
  17766. %@2@%%@AB@%VPICD%@AE@%%@EH@%%@NL@%
  17767. %@3@%Virtual Programmable Interrupt Controller Device%@NL@%%@EH@%
  17768.  
  17769. %@2@%%@AB@%Vector Device%@AE@%%@EH@%%@NL@%
  17770. %@3@%A device that draws graphics with lines. Beginning and ending points are set%@EH@%
  17771. and a line is drawn between them.%@NL@%
  17772.  
  17773. %@2@%%@AB@%Virtual 8086 mode (V86)%@AE@%%@EH@%%@NL@%
  17774. %@3@%A mode of the 80386 processor by which the 80386 emulates the function of%@EH@%
  17775. the 8086 processor. In this mode, each segment has a linear address limit of
  17776. 64K, and the applications can address a total of 1M + 64K - 16 bytes.
  17777. Software running in V86 mode, however, can use the 80386's 32-bit registers.%@NL@%
  17778.  
  17779. %@2@%%@AB@%Virtual DMA Device (VDMAD) %@AE@%%@EH@%%@NL@%
  17780. %@3@%The VDMAD is the Windows virtual device that supports standard DMA devices%@EH@%
  17781. on ISA machines as well as the VDS API for non-ISA devices.%@NL@%
  17782.  
  17783. %@2@%%@AB@%Virtual DMA Services (VDS) %@AE@%%@EH@%%@NL@%
  17784. %@3@%The VDS specification describes how an MS-DOS DMA device driver can perform%@EH@%
  17785. DMA. VxD authors should use the services of the VDMAD rather than work
  17786. directly from this specification.%@NL@%
  17787.  
  17788. %@2@%%@AB@%Virtual "x" Device (VxD)%@AE@%%@EH@%%@NL@%
  17789. %@3@%The name of the device virtualized replaces the "x" in this name. There must%@EH@%
  17790. be a VxD for each piece of hardware that can have a different state in each
  17791. of the VMs. Any piece of hardware that does not have an associated VxD is
  17792. global. It must handle interleaved access from multiple VMs or have a global
  17793. piece of software (such as a DOS device driver or TSR) that serializes
  17794. access to the hardware. All the VxDs run in the same, flat-model, 32-bit
  17795. segment as the rest of the VMM. A VxD can also provide services that are not
  17796. directly associated with a piece of hardware (e.g., a piece of code that
  17797. replaces an MS-DOS or BIOS service).%@NL@%
  17798.  
  17799. %@2@%%@AB@%Virtual Machine (VM)%@AE@%%@EH@%%@NL@%
  17800. %@3@%The part of the enhanced Windows environment in which Windows and%@EH@%
  17801. non-Windows applications execute. A VM consists of all the resources
  17802. (physical and/or virtualized) available to the application, plus the state
  17803. of the application. The state of the application includes the memory, the
  17804. processor state, and the state of the VMM and VxDs as maintained in the VM
  17805. control block.%@NL@%
  17806.  
  17807. %@2@%%@AB@%Virtual Machine Manager (VMM)%@AE@%%@EH@%%@NL@%
  17808. %@3@%The core of enhanced Windows. It runs, along with all the VxDs, in one,%@EH@%
  17809. flat-model, 32-bit segment.%@NL@%
  17810.  
  17811. %@2@%%@AB@%Virtual Memory%@AE@%%@EH@%%@NL@%
  17812. %@3@%Memory that an application can access that is greater than the actual%@EH@%
  17813. physical memory present. To support this, enhanced Windows transparently
  17814. pages 4K memory blocks to and from physical memory on behalf of the
  17815. applications. %@NL@%
  17816.  
  17817. %@2@%%@AB@%WDEB386%@AE@%%@EH@%%@NL@%
  17818. %@3@%A Windows 3.0 debugger program that can be used in protected mode with%@EH@%
  17819. either an 80286, 80386, or 80486 processor.%@NL@%
  17820.  
  17821. %@2@%%@AB@%Window%@AE@%%@EH@%%@NL@%
  17822. %@3@%A rectangular region on a display screen in which the system displays the%@EH@%
  17823. contents of an application.%@NL@%
  17824.  
  17825. %@2@%%@AB@%Windows Application%@AE@%%@EH@%%@NL@%
  17826. %@3@%Any program that has been specifically designed to run under Microsoft%@EH@%
  17827. Windows.%@NL@%
  17828.  
  17829. %@2@%%@AB@%WIN.INI%@AE@%%@EH@%%@NL@%
  17830. %@3@%The Windows initialization file in which you maintain the system-wide%@EH@%
  17831. settings for user preferences. The SYSTEM.INI file contains the hardware and
  17832. software descriptions. WIN.INI is a text-based file that resides in the
  17833. Windows software directory.%@NL@%
  17834.  
  17835. %@2@%%@AB@%XMS%@AE@%%@EH@%%@NL@%
  17836. %@3@%See Extended Memory Specification. %@NL@%%@EH@%
  17837.  
  17838.  
  17839.  
  17840.  
  17841.  
  17842.  
  17843. %@CR:C6A-B0001   @%%@1@%%@AB@%Appendix B  Understanding Modes%@AE@%%@EH@%%@NL@%
  17844. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17845.  
  17846. Microsoft Windows 3.0 documentation uses the term "mode" in overlapping
  17847. ways. This appendix is provided to clarify the different uses.  %@NL@%
  17848.  
  17849.  
  17850. %@2@%%@CR:C6A-B0002   @%%@AB@%B.1  Windows Modes%@AE@%%@EH@%%@NL@%
  17851.  
  17852. To provide the greatest features for the available hardware, Windows 3.0 can
  17853. run in three software modes: real, standard, or 386 enhanced. The following
  17854. table compares the memory models and required microprocessor for each of
  17855. these Windows modes.%@CR:C6A-B0003   @%%@NL@%
  17856.  
  17857. %@TH:  15   715 02 13 11 15 37 @%
  17858. Windows 3.0  Real Mode  Standard Mode  386 Enhanced Mode
  17859. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17860. Supported    Real Mode  Real Mode      Real Mode 
  17861.  Memory                  Protected      Protected Mode (32-bit)
  17862.  Model                  Mode (16-bit)   V86 Mode
  17863.  
  17864. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17865.  
  17866. Required     8086                      
  17867. Hardware      80286      80286          80386
  17868.               80386      80386          80486
  17869.               80486      80486         
  17870.  
  17871. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17872.  
  17873. %@TE:  15   715 02 13 11 15 37 @%
  17874.  
  17875.  
  17876. %@2@%%@CR:C6A-B0004   @%%@AB@%B.2  Microprocessor Modes%@AE@%%@EH@%%@NL@%
  17877.  
  17878. As the Intel microprocessors evolved greater capabilities, they continued to
  17879. support the programs and operating systems of the earlier architectures. As
  17880. a result, the 80386 has no fewer than four modes. Each is compared below to
  17881. the earlier architectures.  %@NL@%
  17882.  
  17883. The first is the familiar %@AI@%real mode%@AE@%, wherein the 80386 functions as a fast
  17884. 8086/88-compatible processor with some bonus opcodes. Like the 80286, the
  17885. 80386 always powers up in real mode and can, therefore, run any existing
  17886. 8086 operating systems and software.%@CR:C6A-B0005   @%%@NL@%
  17887.  
  17888. In %@AI@%protected mode%@AE@%, the 80386 can take on two different personalities. It can
  17889. execute a logical superset of the 80286 protected-mode instructions and run
  17890. 16-bit programs. Or, while in its native protected mode, it can use 32-bit
  17891. instructions, registers, and stacks and can allow individual memory segments
  17892. as large as 4GB. The native protected mode also has an additional level of
  17893. address translation─supported in hardware by page tables─that allows much
  17894. greater flexibility in mapping the linear address onto physical memory. In
  17895. either protected mode, the 80386 translates selectors and offsets to linear
  17896. addresses using descriptor tables in much the same manner as the 80286.%@CR:C6A-B0006   @%%@NL@%
  17897.  
  17898. The forth operating mode, %@AI@%virtual 86 mode%@AE@% (V86), provides another form of
  17899. 8086 emulation. But now, instead of a single program running in a single
  17900. memory partition, the 80386 can create multiple partitions, each capable of
  17901. running a real-mode program. Each partition has its own address space, I/O
  17902. port space, and interrupt vector table. Enhanced Windows uses the V86-mode
  17903. partitions to create virtual machines, the fundamental components in its
  17904. virtual machine architecture. The architecture is described in Chapter 16,
  17905. "Overview of Windows in 386 Enhanced Mode."%@CR:C6A-B0007   @%%@NL@%
  17906.  
  17907. The following table summarizes the four modes of the 80386 microprocessor:  %@NL@%
  17908.  
  17909. %@TH:  18   963 02 40 40 @%
  17910. Mode                                    Description
  17911. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17912. Real Mode                               Functions as a very fast 
  17913.                                         8086/88-compatible processor.
  17914.  
  17915. Protected Mode (16-bit)                 Functions in protected mode as an 
  17916.                                         enhanced 286 processor.
  17917.  
  17918. Protected Mode (32-bit, native mode)    Functions in protected mode using full
  17919.                                         32-bit instructions, registers, and 
  17920.                                         stacks.
  17921.  
  17922. Virtual 86 Mode                         Runs multiple, protected, virtual 8086
  17923.                                         machines, each with its own 1MB of 
  17924.                                         memory space.
  17925.  
  17926. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17927.  
  17928. %@TE:  18   963 02 40 40 @%
  17929.  
  17930.  
  17931.  
  17932.  
  17933.  
  17934.  
  17935. %@CR:C6A-C0001   @%%@1@%%@AB@%Appendix C  Creating Distribution Disks for Drivers%@AE@%%@EH@%%@NL@%
  17936. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17937.  
  17938. Once you have developed your device driver and/or virtual device, you must
  17939. create a distribution disk for installing it into the user's Windows
  17940. environment.  %@NL@%
  17941.  
  17942. In Windows 3.0, we have included two Windows utilities (i.e., Setup and
  17943. Control Panel) that make installing device drivers and virtual devices that
  17944. are not available in the retail product much easier for the user. These
  17945. utilities do this by using the data stored in the Information (.INF) file
  17946. that is provided in the Windows retail product.  %@NL@%
  17947.  
  17948. This appendix provides information on the following topics:  %@NL@%
  17949.  
  17950.  
  17951.   ■   How Setup and Control Panel use Information files%@NL@%
  17952.  
  17953.   ■   The various components of the Information file %@NL@%
  17954.  
  17955.   ■   How to create an Information file for installing your device driver
  17956.       and/or virtual device%@NL@%
  17957.  
  17958.   ■   Syntax and examples of the data in an Information file, given by
  17959.       device type%@NL@%
  17960.  
  17961.   ■   How to use Setup and Control Panel to test the installation of your
  17962.       device driver and/or virtual device%@NL@%
  17963.  
  17964.   ■   How to inform Microsoft about the availability of your device driver
  17965.       and/or virtual device
  17966. %@NL@%
  17967.  
  17968.  
  17969.  
  17970. %@2@%%@CR:C6A-C0002   @%%@AB@%C.1  What is an Information File?%@AE@%%@EH@%%@NL@%
  17971.  
  17972. An Information (.INF) file provides the data required for Windows to install
  17973. drivers and virtual devices that are provided on a set of disks.  %@NL@%
  17974.  
  17975. It contains the following type of information:  %@NL@%
  17976.  
  17977.  
  17978.   ■   The location of the driver and virtual device files (e.g., disk)%@NL@%
  17979.  
  17980.   ■   The device description string to be presented to the end user%@NL@%
  17981.  
  17982.   ■   Which driver and/or virtual device or other dependent files to
  17983.       install, depending on the device. For example, which screen fonts to
  17984.       install for a particular display and the associated virtual device
  17985.       (when setting up on an 80386 machine)%@NL@%
  17986.  
  17987.   ■   System configuration data for various machine types%@NL@%
  17988.  
  17989.  
  17990. The Setup utility uses the data in the Information (.INF) file to install
  17991. the following types of configuration information, device drivers, and
  17992. virtual devices:  %@NL@%
  17993.  
  17994.  
  17995.   ■   Displays and associated font files%@NL@%
  17996.  
  17997.   ■   Mice or other pointing devices%@NL@%
  17998.  
  17999.   ■   Networks%@NL@%
  18000.  
  18001.   ■   Keyboard types, subtypes, and layouts%@NL@%
  18002.  
  18003.   ■   386 enhanced mode virtual devices%@NL@%
  18004.  
  18005.   ■   Machine dependent configurations:%@NL@%
  18006.  
  18007. %@STUB@%      Display%@NL@%
  18008.  
  18009. %@STUB@%      Mouse or other pointing device%@NL@%
  18010.  
  18011. %@STUB@%      Keyboard%@NL@%
  18012.  
  18013. %@STUB@%      Comm%@NL@%
  18014.  
  18015. %@STUB@%      Sound%@NL@%
  18016.  
  18017. %@STUB@%      System%@NL@%
  18018.  
  18019. %@STUB@%      Any required 386 enhanced mode virtual devices and switches %@NL@%
  18020.  
  18021.  
  18022. Control Panel uses the data in the Information (.INF) file to install
  18023. printer drivers and Windows raster (or screen) fonts.  %@NL@%
  18024.  
  18025.  
  18026. %@2@%%@CR:C6A-C0003   @%%@AB@%C.2  Different Types of Information Files%@AE@%%@EH@%%@NL@%
  18027.  
  18028. The .INF file provided with Windows is named SETUP.INF and is stored in the
  18029. Windows ..\SYSTEM subdirectory. The SETUP.INF filename is unique and used by
  18030. Setup and Control Panel for standard Windows operations. This name is
  18031. reserved for Windows and should not be used on your distribution disk.  %@NL@%
  18032.  
  18033. A second type of .INF file that is used by Setup and Control Panel is called
  18034. OEMSETUP.INF. This name is to be used specifically for installing additional
  18035. drivers on a distribution disk.  %@NL@%
  18036.  
  18037. Setup and Control Panel look for this filename, OEMSETUP.INF, when
  18038. installing drivers and virtual devices that are not part of the retail
  18039. package. In general, the OEMSETUP.INF file you create will contain a subset
  18040. of the information provided in the SETUP.INF file.  %@NL@%
  18041.  
  18042. You may want to print a copy of the SETUP.INF file to use as a reference for
  18043. the following sections. The file is in ASCII text format and can be printed
  18044. on most printers.  %@NL@%
  18045.  
  18046. The steps for installing additional drivers are described in more detail
  18047. later in Section C.7, "Testing the Installation of Your Information File."  %@NL@%
  18048.  
  18049.  
  18050. %@2@%%@CR:C6A-C0004   @%%@AB@%C.3  General Format and Syntax for Information Files%@AE@%%@EH@%%@NL@%
  18051.  
  18052. .INF files are broken up into %@AI@%sections%@AE@%, with each section generally
  18053. containing information pertaining to a specific set of Windows driver or
  18054. system files. Section names are always enclosed in square brackets ([]).  %@NL@%
  18055.  
  18056. Sections are further broken up into %@AI@%lines%@AE@%, with each line generally
  18057. containing information about a single Windows system or driver file.  %@NL@%
  18058.  
  18059. Finally, the lines within sections are further broken up into %@AI@%fields%@AE@%, with
  18060. each field within a line generally containing information specific to the
  18061. system or driver file listed on that line. Fields are always separated by
  18062. commas (,).  %@NL@%
  18063.  
  18064. The following is a generalized syntax line and, then, a sample section from
  18065. the SETUP.INF file:  %@NL@%
  18066.  
  18067. Profile_string = Disk:Filename,"Text_Description",Disk:Virtual_Device  %@NL@%
  18068.  
  18069. %@AS@%  [pointing.device]
  18070. %@AS@%  nomouse   = 2:nomouse.drv,   "No mouse or pointing device",     3:*vmd
  18071. %@AS@%  ps2mouse  = 1:mouse.drv,     "Microsoft, or IBM PS/2",          3:*vmd
  18072. %@AS@%  msmouse1  = 2:msmouse1.drv,  "Mouse Systems (or VisiOn) COM1:", 3:*vmd
  18073. %@AS@%  msmouse2  = 2:msmouse2.drv,  "Mouse Systems (or VisiOn) COM2:", 3:*vmd
  18074. %@AS@%  lmouse    = 2:lmouse.drv,    "Logitech",                        3:*vmd
  18075. %@AS@%  kbdmouse  = 2:kbdmouse.drv,  "AT&T/Olivetti Keyboard Mouse",    3:*vmd
  18076. %@AS@%  hpmouse   = 2:hpmouse.drv,   "HP Mouse (HP-HIL)",               3:*vmd%@AE@%
  18077.  
  18078. In the above example, the section name is [pointing.device]. Each line in
  18079. the section contains information pertaining to the mouse driver listed in
  18080. the first field of the line.  %@NL@%
  18081.  
  18082. The string on the lefthand side of the equal sign (=) in the first field is
  18083. a %@AI@%profile%@AE@% string. The profile string is the unique "handle" that Setup uses
  18084. to parse a line from the .INF file that matches the hardware for which Setup
  18085. is configuring Windows. For example, if Setup detects that a Logitech mouse
  18086. is connected to the computer for which it is configuring Windows, it will
  18087. look for the string "lmouse" in the [pointing.device] section of the .INF
  18088. file. Once found, Setup uses the information on that line to determine how
  18089. to configure Windows for the Logitech mouse. The profile string portion of
  18090. the first field is considered to be field zero or may be referred to as the
  18091. profile field. Profile strings are limited to 15 characters.  %@NL@%
  18092.  
  18093. The second field of each line is a %@AI@%Text_Description%@AE@% string for the mouse
  18094. driver on that line. Description strings are limited to 48 characters.  %@NL@%
  18095.  
  18096. The third field is the name of the %@AI@%Virtual_Device%@AE@% file required for that
  18097. mouse to operate correctly under the 386 enhanced mode of Windows. If the
  18098. first character of any virtual device name is an asterisk (*), then that
  18099. driver is part of the WIN386.EXE file. If the virtual device name does not
  18100. contain an asterisk, then that file is separate from WIN386.EXE. 386
  18101. enhanced mode VxD files generally have the file extension .386 to identify
  18102. then as 386 enhanced mode VxDs.  %@NL@%
  18103.  
  18104.  
  18105. %@2@%%@CR:C6A-C0005   @%%@AB@%C.4  File Location Information%@AE@%%@EH@%%@NL@%
  18106.  
  18107. All the files that are listed in the .INF file have associated with them a
  18108. logical disk ID. The logical disk ID is a single character (1-9 A-Z).
  18109. Therefore, there are 1-9 + A-Z = 35 possible logical disk IDs. The logical
  18110. disk ID is added to the beginning of every filename listed in the .INF file
  18111. and separated from the filename by a colon (:) in the form %@AI@%x:filename%@AE@% where
  18112. %@AI@%x%@AE@% is the logical disk ID. The logical disk ID zero (0) is reserved for use
  18113. by Setup.  %@NL@%
  18114.  
  18115. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18116. NOTE
  18117.  
  18118. %@AI@%You must use a unique filename. We also suggest that this name be different
  18119. %@AI@%from the names of files defined in SETUP.INF.%@AE@%
  18120. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18121.  
  18122. The logical disk ID is mapped to a physical disk in the [disks] section of
  18123. the .INF file. The following is a generalized syntax line and, then, a
  18124. sample of a .INF file's [disks] section that maps the logical to physical
  18125. disk location of the mouse drivers listed in the [pointing.device] section.
  18126. %@NL@%
  18127.  
  18128. Disk_ID = Drive,"Text_Description"  %@NL@%
  18129.  
  18130. %@AS@%  [disks]
  18131. %@AS@%  1 =.\,       "Microsoft Windows 3.0 Disk #1"
  18132. %@AS@%  2 =.\disk2,  "Microsoft Windows 3.0 Disk #2"%@AE@%
  18133.  
  18134. In the preceding [disks] section example, the profile string corresponds to
  18135. a logical disk ID. For every logical disk ID used in the .INF file, there
  18136. must be a line in the [disks] section that maps that logical disk ID to a
  18137. physical disk location.  %@NL@%
  18138.  
  18139. The first field in the [disks] section is the physical location that
  18140. corresponds to the logical disk ID in the profile string. In the preceding
  18141. example, all the filenames that start with logical disk ID 1 will exist in
  18142. the physical root of the current drive (.\). All the filenames that start
  18143. with logical disk ID 2 will exist in the physical subdirectory \disk2 of the
  18144. current drive.  %@NL@%
  18145.  
  18146. The second field is a %@AI@%Text_Description%@AE@% string used to identify the physical
  18147. disk location. This is used by Setup and Control Panel for disk prompting if
  18148. the physical disk locations for different logical disk IDs are on different
  18149. floppy disks, which is normal.  %@NL@%
  18150.  
  18151.  
  18152. %@2@%%@CR:C6A-C0006   @%%@AB@%C.5  Creating .INF File Entries%@AE@%%@EH@%%@NL@%
  18153.  
  18154. The following .INF file entries are examples to follow when creating an
  18155. OEMSETUP.INF file for displays, mice or other pointing devices, networks,
  18156. keyboards, and machine-dependent configurations.  %@NL@%
  18157.  
  18158. See Section C.6, "Creating .INF File Entries for Printer Drivers," for
  18159. information on how to create an OEMSETUP.INF file for printer devices.  %@NL@%
  18160.  
  18161. See Section C.3, "General Format and Syntax for Information Files," and
  18162. Section C.4, "File Location Information," for more information about profile
  18163. strings, text descriptions, driver filenames, and disk location
  18164. descriptions. These fields are referenced throughout the following examples.
  18165. %@NL@%
  18166.  
  18167. The colons, commas, and quotes shown in the following examples are required
  18168. as part of the format.  %@NL@%
  18169.  
  18170.  
  18171. %@3@%%@CR:C6A-C0007   @%%@AB@%C.5.1  Display Device%@AE@%%@EH@%%@NL@%
  18172.  
  18173. The following is a generalized example of the syntax used for display
  18174. devices along with definitions of each of the terms presented.  %@NL@%
  18175.  
  18176. [display] Profile_string = Disk:Filename,"Text_Description","Aspect_Ratio",
  18177. Disk:Grabber,Disk:Logo_Code,Disk:Virtual_Display_Device,
  18178. Disk:386_Grabber,[Disk:EGA_DOS_Driver],Disk:Logo_Data  %@NL@%
  18179.  
  18180. Where:  %@NL@%
  18181.  
  18182. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  18183.  
  18184. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  18185.  
  18186. %@AI@%Aspect_Ratio%@AE@% is information that is used to determine which raster (or
  18187. screen) fonts to install for use by the device. Any fonts found with
  18188. matching aspect values in the [sysfonts], [fixedfonts], [oemfonts], or
  18189. [fonts] sections of the .INF file will be installed in the [fonts] section
  18190. of the WIN.INI file.  %@NL@%
  18191.  
  18192. Aspect_Ratio includes the following three values:  %@NL@%
  18193.  
  18194.  
  18195.   ■   X and Y aspect ratio%@NL@%
  18196.  
  18197.   ■   X pixels-per-inch%@NL@%
  18198.  
  18199.   ■   Y pixels-per-inch%@NL@%
  18200.  
  18201.  
  18202. The three values are separated by commas and enclosed within quotation
  18203. marks. For example, for a VGA display, the values would be as follows:  %@NL@%
  18204.  
  18205. "100,96,96"  %@NL@%
  18206.  
  18207. Where:  %@NL@%
  18208.  
  18209. %@AI@%100%@AE@% is the X and Y aspect ratio (1-to-1).  %@NL@%
  18210.  
  18211. %@AI@%96%@AE@% is the X (horizontal) pixels-per-inch.  %@NL@%
  18212.  
  18213. %@AI@%96%@AE@% is the Y (vertical) pixels-per-inch.  %@NL@%
  18214.  
  18215. See the description of the GDIINFO data structure in Chapter 2, "Display
  18216. Drivers," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% for more
  18217. information on calculating these values.  %@NL@%
  18218.  
  18219. %@AI@%Grabber%@AE@% is the MS-DOS filename of the grabber used when Windows is running
  18220. in real and standard mode.  %@NL@%
  18221.  
  18222. %@AI@%Logo_Code%@AE@% is the MS-DOS filename of the logo display code that is used by
  18223. Setup to build the WIN.COM file.  %@NL@%
  18224.  
  18225. %@AI@%Virtual_Display_Device%@AE@% is the MS-DOS filename of the VDD that Windows will
  18226. use in 386 enhanced mode.  %@NL@%
  18227.  
  18228. %@AI@%386_Grabber%@AE@% is the MS-DOS filename of the grabber used when Windows is
  18229. running in 386 enhanced mode.  %@NL@%
  18230.  
  18231. %@AI@%EGA_DOS_Driver%@AE@% is an optional field. It is the MS-DOS filename of an MS-DOS
  18232. installable device driver used to virtualize the write-only registers on EGA
  18233. display cards so that they can be read.  %@NL@%
  18234.  
  18235. %@AI@%Logo_Data%@AE@% is the MS-DOS filename of the logo data that is used by Setup to
  18236. build the WIN.COM file.  %@NL@%
  18237.  
  18238. The following is an example of what a .INF file for a specific EGA display
  18239. driver would look like.  %@NL@%
  18240.  
  18241. %@AS@%  [data]
  18242. %@AS@%  defxlat = 437%@AE@%
  18243.  
  18244. %@AS@%  [disks]
  18245. %@AS@%  1 =. ,"OEM Display Driver Disk #1"%@AE@%
  18246.  
  18247. %@AS@%  [display]
  18248. %@AS@%  oemega = 1:ega.drv,"OEM EGA Color","133,96,72", 
  18249. %@AS@%  1:egacolor.gr2,1:egalogo.lgo,1:vddega.386, 
  18250. %@AS@%  1:ega.gr3,1:ega.sys,1:egalogo.rle%@AE@%
  18251.  
  18252. %@AS@%  [EGA.GR3]
  18253. %@AS@%  1:CGA40WOA.FON,1:CGA40850.FON
  18254. %@AS@%  1:CGA80WOA.FON,1:CGA80850.FON
  18255. %@AS@%  1:EGA40WOA.FON,1:EGA40850.FON
  18256. %@AS@%  1:EGA80WOA.FON,1:EGA80850.FON%@AE@%
  18257.  
  18258. %@AS@%  [codepages]
  18259. %@AS@%  ;       Xlat Table    OEM Font      description.
  18260. %@AS@%  863 = 2:xlat863.bin, 2:vga863.fon, "French Canadian (863)"
  18261. %@AS@%  861 = 2:xlat861.bin, 2:vga861.fon, "Icelandic (861)"
  18262. %@AS@%  865 = 2:xlat865.bin, 2:vga865.fon, "Norway & Denmark (865)"
  18263. %@AS@%  850 = 2:xlat850.bin, 2:vga850.fon, "International (850)"
  18264. %@AS@%  860 = 2:xlat860.bin, 2:vga860.fon, "Portuguese (860)"
  18265. %@AS@%  437 =              ,             , "Standard (437)"%@AE@%
  18266.  
  18267. %@AS@%  [sysfonts]
  18268. %@AS@%  1:egasys.fon,"EGA (640x350) resolution System Font","133,96,72"%@AE@%
  18269.  
  18270. %@AS@%  [fixedfonts]
  18271. %@AS@%  1:egafix.fon,"EGA (640x350) resolution Fixed System Font","133,96,72"%@AE@%
  18272.  
  18273. %@AS@%  [oemfonts]
  18274. %@AS@%  1:egaoem.fon,"EGA (640x350) resolution Terminal Font
  18275. %@AS@%(USA/Europe)","133,96,72",1%@AE@%
  18276.  
  18277. %@AS@%  [fonts]
  18278. %@AS@%  1:HELVB.FON,   "Helv 8,10,12,14,18,24 (EGA res)",    "133,96,72"
  18279. %@AS@%  1:COURB.FON,   "Courier 10,12,15 (EGA res)",         "133,96,72"
  18280. %@AS@%  1:TMSRB.FON,   "Tms Rmn 8,10,12,14,18,24 (EGA res)", "133,96,72"
  18281. %@AS@%  1:SYMBOLB.FON, "Symbol 8,10,12,14,18,24 (EGA res)",  "133,96,72"
  18282. %@AS@%  1:ROMAN.FON,   "Roman (All res)",  "CONTINUOUSSCALING"
  18283. %@AS@%  1:SCRIPT.FON,  "Script (All res)", "CONTINUOUSSCALING"
  18284. %@AS@%  1:MODERN.FON,  "Modern (All res)", "CONTINUOUSSCALING"%@AE@%
  18285.  
  18286. Because there are many display-dependent files, the .INF file for installing
  18287. display drivers is more complicated. For any given Windows display driver,
  18288. the following related files are also required by Windows 3.0.  %@NL@%
  18289.  
  18290. %@TH:  12   619 02 32 44 @%
  18291. File                            Needed by
  18292. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18293. Display driver                  All modes
  18294. Standard-mode grabber           Standard and real mode
  18295. Enhanced-mode grabber           Enhanced mode
  18296. Logo display code               All modes
  18297. Logo display data               All modes
  18298. System font                     All modes
  18299. Fixed font                      All modes
  18300. OEM/Terminal font               Standard and real mode
  18301. 386 OEM/Terminal font           Enhanced mode
  18302. User fonts                      All modes
  18303. %@TE:  12   619 02 32 44 @%
  18304.  
  18305. The profile string for the display driver must be unique from all the other
  18306. display profile strings, including those listed in the Microsoft Windows 3.0
  18307. SETUP.INF file.  %@NL@%
  18308.  
  18309. Setup selects fonts by matching the aspect ratio of the display to that of
  18310. the font. Setup will, however, ignore aspect ratio information for
  18311. configurations using a code page other than 437. For these configurations,
  18312. Setup asks MS-DOS for code page information and selects an OEM/Terminal font
  18313. from the [codepages] section based on that information. Since only MS-DOS
  18314. version 3.30 and higher supports the call for code page information, Setup
  18315. may (depending on the MS-DOS version) rely on the %@AI@%defxlat%@AE@% profile string
  18316. (under the [data] section) to get code page information.  %@NL@%
  18317.  
  18318. When preparing your distribution disks, you may choose one of the following
  18319. three methods for providing .FON font files:  %@NL@%
  18320.  
  18321.  
  18322.   ■   Include the appropriate Windows .FON font files from the Windows 3.0
  18323.       retail product.%@NL@%
  18324.  
  18325.   ■   Refer in the [disks] section of your OEMSETUP.INF file to the Windows
  18326.       3.0 retail disk(s) containing these files.%@NL@%
  18327.  
  18328.   ■   Distribute your own .FON font files if your display requires fonts
  18329.       that are tuned for a particular aspect ratio and not supported by the
  18330.       Windows .FON font files.%@NL@%
  18331.  
  18332.  
  18333. See the "Grant of License to Use" section, in the Microsoft License
  18334. Agreement that is printed on the DDK disk envelope, for information on your
  18335. rights to distribute these font files should you choose to include them on
  18336. your distribution disk.  %@NL@%
  18337.  
  18338.  
  18339. %@3@%%@CR:C6A-C0008   @%%@AB@%C.5.2  Mouse or Other Pointing Device%@AE@%%@EH@%%@NL@%
  18340.  
  18341. The following is a generalized example of the syntax used for mice or other
  18342. pointing devices along with definitions of each of the terms presented.  %@NL@%
  18343.  
  18344. [pointing.device] Profile_string =
  18345. Disk:Filename,"Text_Description",Disk:Virtual_Mouse_Driver  %@NL@%
  18346.  
  18347. Where:  %@NL@%
  18348.  
  18349. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  18350.  
  18351. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  18352.  
  18353. %@AI@%Virtual_Mouse_Driver%@AE@% is the MS-DOS filename of the associated virtual device
  18354. to be installed for running Windows in 386 enhanced mode.  %@NL@%
  18355.  
  18356. The following is an example of what a .INF file for a specific OEM mouse
  18357. driver would look like.  %@NL@%
  18358.  
  18359. %@AS@%  [disks]
  18360. %@AS@%  1 =. ,"OEM Mouse driver disk #1"%@AE@%
  18361.  
  18362. %@AS@%  [pointing.device]
  18363. %@AS@%  oemmouse = 1:oemmouse.drv,"OEM Mouse driver",1:oemvmd.386%@AE@%
  18364.  
  18365.  
  18366. %@3@%%@CR:C6A-C0009   @%%@AB@%C.5.3  Network Device%@AE@%%@EH@%%@NL@%
  18367.  
  18368. The following is a generalized example of the syntax used for network
  18369. devices along with definitions of each of the terms presented.  %@NL@%
  18370.  
  18371. Notice that all the fields in brackets ([ ]) are optional. All other fields
  18372. are required. The quotes, commas, and colons are required as well.  %@NL@%
  18373.  
  18374. Profile_string = Disk:Filename,"Text_Description", [Disk:Help_File],
  18375. [Disk:Optional_File],[WIN.INI_ Mods], [SYSTEM.INI_
  18376. Mods],[Disk:Virtual_Net_Device ...]  %@NL@%
  18377.  
  18378. Where:  %@NL@%
  18379.  
  18380. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  18381.  
  18382. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  18383.  
  18384. %@AI@%Help_File%@AE@% is the MS-DOS filename of an associated Help file. Setup copies
  18385. this file to the Windows installation directory. This file is optional.  %@NL@%
  18386.  
  18387. %@AI@%Optional_File%@AE@% is the MS-DOS filename of an optional file, which may be
  18388. necessary for your network. Setup copies this file to the Windows
  18389. installation directory. This file is optional.  %@NL@%
  18390.  
  18391. %@AI@%WIN.INI_Mods%@AE@% is the name of a section within the OEMSETUP.INF file that
  18392. describes modifications to be made to the user's WIN.INI file.  %@NL@%
  18393.  
  18394. %@AI@%SYSTEM.INI_Mods%@AE@% is the name of a section within the OEMSETUP.INF file that
  18395. describes modifications to be made to the user's SYSTEM.INI file.  %@NL@%
  18396.  
  18397. %@AI@%Virtual_Net_Device%@AE@% is the MS-DOS filename of an associated virtual device to
  18398. be installed for running Windows in 386 enhanced mode.  %@NL@%
  18399.  
  18400. The following is an example of what a .INF file for a specific network
  18401. driver would look like.  %@NL@%
  18402.  
  18403. %@AS@%  [disks]
  18404. %@AS@%  1 = . ,"Oem Network driver disk #1"%@AE@%
  18405.  
  18406. %@AS@%  [network]
  18407. %@AS@%  oem_net = 1:oem.drv,"OEM Network Driver",
  18408. %@AS@%1:oemnet.hlp,1:oem_app.exe,oem_winini,oem_sysini,
  18409. %@AS@%  1:oem1.386,1:oem2.386%@AE@%
  18410.  
  18411. %@AS@%  [oem_winini]
  18412. %@AS@%  Windows,load,oem_app.exe%@AE@%
  18413.  
  18414. %@AS@%  [oem_sysini]
  18415. %@AS@%  386enh,TimerCriticalSection,500%@AE@%
  18416.  
  18417. The %@AI@%oem_sysini%@AE@% and %@AI@%oem_winini%@AE@% sections describe modifications to be made in
  18418. the WIN.INI and SYSTEM.INI files. A .INI modification description section is
  18419. comprised of lines that contain three fields describing a new entry to be
  18420. made to the .INI file. The fields in each line are as follows:  %@NL@%
  18421.  
  18422.  
  18423.   ■   Field 1 = .INI file section name%@NL@%
  18424.  
  18425.   ■   Field 2 = Profile string or descriptor to the lefthand side of the
  18426.       equal sign%@NL@%
  18427.  
  18428.   ■   Field 3 = Descriptor to the righthand side of the equal sign%@NL@%
  18429.  
  18430.  
  18431. In the preceding example, Setup would add the string "load=oem_app.exe" to
  18432. the [windows] section of WIN.INI. If a "load=" line already existed in
  18433. WIN.INI, then Setup would add "oem_app.exe" to the righthand side of the
  18434. "load=" line.  %@NL@%
  18435.  
  18436. Setup would also add the string "TimerCriticalSection=500" to the [386enh]
  18437. section of SYSTEM.INI.  %@NL@%
  18438.  
  18439.  
  18440. %@3@%%@CR:C6A-C0010   @%%@AB@%C.5.4  Keyboard Device%@AE@%%@EH@%%@NL@%
  18441.  
  18442. The following are generalized examples of the layout, type, and subtype
  18443. syntax used for keyboard devices along with definitions of each of the terms
  18444. presented.  %@NL@%
  18445.  
  18446. The layout syntax is as follows:  %@NL@%
  18447.  
  18448. Profile_string = Disk:Filename,"Text_Description"  %@NL@%
  18449.  
  18450. The type and subtype syntax is as follows :  %@NL@%
  18451.  
  18452. Type_Subtype_Profile_string = "Text_Description"  %@NL@%
  18453.  
  18454. Where:  %@NL@%
  18455.  
  18456. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  18457.  
  18458. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  18459.  
  18460. %@AI@%Type_Subtype_Profile_string%@AE@% is a combination of type/subtype and profile
  18461. string information. The type/subtype information is represented in the form
  18462. of "t##s##." The remaining characters represent the profile string
  18463. information.  %@NL@%
  18464.  
  18465. The following is an example of what a .INF file for a specific keyboard
  18466. driver would look like.  %@NL@%
  18467.  
  18468. %@AS@%  [data]
  18469. %@AS@%  defkeydll = ussrdll%@AE@%
  18470.  
  18471. %@AS@%  [disks]
  18472. %@AS@%  1 = . ,"Oem Keyboard disk #1"%@AE@%
  18473.  
  18474. %@AS@%  [keyboard.types]
  18475. %@AS@%  t3s9oem  = "Russian OEM Keyboard"%@AE@%
  18476.  
  18477. %@AS@%  [keyboard.tables]
  18478. %@AS@%  ussrdll = 1:kbdussr.dll,"Russian"%@AE@%
  18479.  
  18480. The keyboard type entry is unique because it involves only SYSTEM.INI
  18481. settings. No driver files are copied. The keyboard type and subtype entries
  18482. in SYSTEM.INI are used by the Windows 3.0 keyboard driver during boot time
  18483. to determine the keyboard type.  %@NL@%
  18484.  
  18485. If the keyboard type is selected during a first time installation, Setup
  18486. will also select a keyboard layout (DLL or dynamic-link library). Setup
  18487. selects a keyboard DLL by looking at the data on the righthand side of the
  18488. equal sign of %@AI@%defkeydll%@AE@% in the [data] section of the .INF file. Using the
  18489. profile string obtained from this data, Setup selects a keyboard DLL from
  18490. the [keyboard.tables] section of the .INF file.  %@NL@%
  18491.  
  18492.  
  18493. %@3@%%@CR:C6A-C0011   @%%@AB@%C.5.5  Machine-Dependent Configuration%@AE@%%@EH@%%@NL@%
  18494.  
  18495. Setup installs machine-dependent configuration information for the display,
  18496. keyboard, mouse, sound, comm, system, and 386 enhanced-mode BIOS devices,
  18497. and their related files, other virtual devices, and special SYSTEM.INI
  18498. switches.  %@NL@%
  18499.  
  18500. The following is an example of how to define a machine-dependent
  18501. configuration in a .INF file by combining the information discussed in the
  18502. previous sections.  %@NL@%
  18503.  
  18504. %@AS@%  [data]
  18505. %@AS@%  defxlat = 437
  18506. %@AS@%  deflang = rus%@AE@%
  18507.  
  18508. %@AS@%  [disks]
  18509. %@AS@%  1 =. ,"OEM Display Driver Disk #1"%@AE@%
  18510.  
  18511. %@AS@%  [display]
  18512. %@AS@%  oemega = 1:ega.drv,"OEM EGA Color","133,96,72", 
  18513. %@AS@%  1:egacolor.gr2,1:egalogo.lgo,1:vddega.386, 
  18514. %@AS@%  1:ega.gr3,1:ega.sys,1:egalogo.rle%@AE@%
  18515.  
  18516. %@AS@%  [EGA.GR3]
  18517. %@AS@%  1:CGA40WOA.FON,1:CGA40850.FON
  18518. %@AS@%  1:CGA80WOA.FON,1:CGA80850.FON
  18519. %@AS@%  1:EGA40WOA.FON,1:EGA40850.FON
  18520. %@AS@%  1:EGA80WOA.FON,1:EGA80850.FON%@AE@%
  18521.  
  18522. %@AS@%  [sysfonts]
  18523. %@AS@%  1:egasys.fon,"EGA (640x350) resolution System Font","133,96,72"%@AE@%
  18524.  
  18525. %@AS@%  [fixedfonts]
  18526. %@AS@%  1:egafix.fon,"EGA (640x350) resolution Fixed System Font","133,96,72"%@AE@%
  18527.  
  18528. %@AS@%  [oemfonts]
  18529. %@AS@%  1:egaoem.fon,"EGA (640x350) resolution Terminal Font
  18530. %@AS@%(USA/Europe)","133,96,72",1%@AE@%
  18531.  
  18532. %@AS@%  [codepages]
  18533. %@AS@%  ;       Xlat Table    OEM Font      description.
  18534. %@AS@%  863 = 2:xlat863.bin, 2:vga863.fon, "French Canadian (863)"
  18535. %@AS@%  861 = 2:xlat861.bin, 2:vga861.fon, "Icelandic (861)"
  18536. %@AS@%  865 = 2:xlat865.bin, 2:vga865.fon, "Norway & Denmark (865)"
  18537. %@AS@%  850 = 2:xlat850.bin, 2:vga850.fon, "International (850)"
  18538. %@AS@%  860 = 2:xlat860.bin, 2:vga860.fon, "Portuguese (860)"
  18539. %@AS@%  437 =              ,             , "Standard (437)"%@AE@%
  18540.  
  18541. %@AS@%  [fonts]
  18542. %@AS@%  1:HELVB.FON,   "Helv 8,10,12,14,18,24 (EGA res)",    "133,96,72"
  18543. %@AS@%  1:COURB.FON,   "Courier 10,12,15 (EGA res)",         "133,96,72"
  18544. %@AS@%  1:TMSRB.FON,   "Tms Rmn 8,10,12,14,18,24 (EGA res)", "133,96,72"
  18545. %@AS@%  1:SYMBOLB.FON, "Symbol 8,10,12,14,18,24 (EGA res)",  "133,96,72"
  18546. %@AS@%  1:ROMAN.FON,   "Roman (All res)",  "CONTINUOUSSCALING"
  18547. %@AS@%  1:SCRIPT.FON,  "Script (All res)", "CONTINUOUSSCALING"
  18548. %@AS@%  1:MODERN.FON,  "Modern (All res)", "CONTINUOUSSCALING"%@AE@%
  18549.  
  18550. %@AS@%  [pointing.device]
  18551. %@AS@%  oemmouse = 1:oemmouse.drv, "Mouse driver for OEM machine", 1:oemvmd.386%@AE@%
  18552.  
  18553. %@AS@%  [language]
  18554. %@AS@%  rus = 1:langussr.dll, "Russian"%@AE@%
  18555.  
  18556. %@AS@%  [keyboard.types]
  18557. %@AS@%  t4s8enha = "Super OEM 200 key Keyboard"%@AE@%
  18558.  
  18559. %@AS@%  [keyboard.drivers]
  18560. %@AS@%  oemkbd = 1:oemkbd.drv%@AE@%
  18561.  
  18562. %@AS@%  [system]
  18563. %@AS@%  oemsys  = 1:oemsys.drv
  18564. %@AS@%  oemsnd  = 1:oemsnd.drv
  18565. %@AS@%  oemcomm = 1:oemcom.drv%@AE@%
  18566.  
  18567. %@AS@%  [ebios]
  18568. %@AS@%  oemebios = 1:oemebios.386,x:*ebios%@AE@%
  18569.  
  18570. %@AS@%  [machine]%@AE@%
  18571.  
  18572. %@AS@%  "386 OEM Machine","78"
  18573. %@AS@%    oemsys    ;1
  18574. %@AS@%    oemkbd    ;2
  18575. %@AS@%    t4s8enha    ;3
  18576. %@AS@%    oemmouse    ;4
  18577. %@AS@%    oemega    ;5
  18578. %@AS@%    oemsnd    ;6
  18579. %@AS@%    oemcomm    ;7
  18580. %@AS@%    nohimemswitch   ;8
  18581. %@AS@%    oemebios    ;9
  18582. %@AS@%    "emmexclude=c700-c800"  ;10
  18583. %@AS@%    "device=",1:oemvxd.386"  ;11
  18584. %@AS@%        ;n%@AE@%
  18585.  
  18586. Setup may or may not use all the configuration information given in the
  18587. [machine] section. It does use the information provided to install the
  18588. system, keyboard layout, sound, comm, and BIOS drivers. However, only if
  18589. Setup is unable to detect the hardware in question, is the information for
  18590. the mouse, display, and keyboard type/subtype used.  %@NL@%
  18591.  
  18592. In the preceding example, lines 10 and 11 under the [machine] section are
  18593. optional. These lines are provided for the installation of special virtual
  18594. devices or SYSTEM.INI [386enh] section switches. Up to six of these lines
  18595. may be added as needed.  %@NL@%
  18596.  
  18597. Setup also uses code page information (obtained either by means of an MS-DOS
  18598. call, on MS-DOS versions 3.30 or later, or from the %@AI@%defxlat%@AE@% profile string
  18599. in the [data] section) to install a keyboard translation table. This
  18600. information is obtained from the .INF file in the [codepages] section.  %@NL@%
  18601.  
  18602. Finally, Setup also selects a language driver based on the profile string
  18603. given on the righthand side of the equal sign of the %@AI@%deflang%@AE@% entry in the
  18604. [data] section of the .INF file.  %@NL@%
  18605.  
  18606.  
  18607. %@2@%%@CR:C6A-C0012   @%%@AB@%C.6  Creating .INF File Entries for Printer Drivers%@AE@%%@EH@%%@NL@%
  18608.  
  18609. Control Panel does not require an OEMSETUP.INF file for installing a printer
  18610. driver. In Windows 3.0, Control Panel only uses the OEMSETUP.INF file to
  18611. install more than one set of raster (or screen) fonts and to install
  18612. dependent files (e.g., Help files or a font installer). Otherwise, it is not
  18613. required.  %@NL@%
  18614.  
  18615. Control Panel scans the driver files for the driver description regardless
  18616. of whether an OEMSETUP.INF file is present or not. Therefore, it is
  18617. important for you to properly define your driver description in the
  18618. definition (.DEF) file.  %@NL@%
  18619.  
  18620. The following subsections contain information on creating .INF entries for
  18621. OEMSETUP.INF and on the format of the driver's description string in the
  18622. .DEF file.  %@NL@%
  18623.  
  18624.  
  18625. %@3@%%@CR:C6A-C0013   @%%@AB@%C.6.1  .INF File Entries%@AE@%%@EH@%%@NL@%
  18626.  
  18627. The following are generalized examples of the syntax used for printer
  18628. devices along with definitions of each of the terms presented. The colons,
  18629. commas, and quotes shown in the examples are required as part of the format.
  18630. The brackets ([ ]) represent optional fields, except in the case of section
  18631. names.  %@NL@%
  18632.  
  18633. [io.device] Disk:Filename,"Text_Description",
  18634. "Aspect_Ratio"[,"Aspect_Ratio"...]  %@NL@%
  18635.  
  18636. [io.dependent] Filename=Disk:File1[,Disk:File2...]  %@NL@%
  18637.  
  18638. Where:  %@NL@%
  18639.  
  18640. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file. It is used by Control
  18641. Panel to check on whether or not the driver has been installed previously
  18642. and to copy the driver from the distribution disk to the Windows ..\SYSTEM
  18643. directory. This driver name is also the first element on the righthand side
  18644. of the equal sign (=) in the entries under the [devices] and [PrinterPorts]
  18645. sections of the WIN.INI file. %@AI@%Filename%@AE@% in the [io.dependent] section must
  18646. match (case insensitive) the %@AI@%Filename%@AE@% element of the [io.device] section.  %@NL@%
  18647.  
  18648. %@AI@%Text_Description%@AE@% is displayed in the printers listbox (without the quotation
  18649. marks) once the driver is installed. It is placed on the lefthand side of
  18650. the equal sign-in the entries under the [devices] and [PrinterPorts]
  18651. sections of the WIN.INI file. It should also match the %@AI@%Text_Description%@AE@%
  18652. string in the .DEF file of the driver (see the following section for more
  18653. information on the .DEF file). If there is a portion within the text
  18654. description that is enclosed in square brackets, it will be used as the
  18655. lefthand side of the equal sign (=) in the WIN.INI entries. The text in the
  18656. brackets would normally be used to provide a "generic" name for a driver
  18657. that may support many printer models (see the following example for the XYZ
  18658. Ink Jet printer).  %@NL@%
  18659.  
  18660. %@AI@%Aspect_Ratio%@AE@% is information used to determine which raster (or screen) fonts
  18661. to install for use by the device. Any fonts found with matching aspect
  18662. values are installed in the [fonts] section of the WIN.INI file. Up to 5
  18663. different aspect ratio values may be listed. At least one must be listed. If
  18664. no raster font installation is desired, use "DEVICESPECIFIC" as the only
  18665. value.  %@NL@%
  18666.  
  18667. Aspect_Ratio includes the following three values:  %@NL@%
  18668.  
  18669.  
  18670.   ■   X and Y aspect ratio%@NL@%
  18671.  
  18672.   ■   X pixels-per-inch%@NL@%
  18673.  
  18674.   ■   Y pixels-per-inch%@NL@%
  18675.  
  18676.  
  18677. The three values are separated by commas and enclosed within quotation
  18678. marks. For example, for a VGA display, the values would be as follows:  %@NL@%
  18679.  
  18680. "100,96,96"  %@NL@%
  18681.  
  18682. Where:  %@NL@%
  18683.  
  18684. %@AI@%100%@AE@% is the X and Y aspect ratio (1-to-1).  %@NL@%
  18685.  
  18686. %@AI@%96%@AE@% is the X (horizontal) pixels-per-inch.  %@NL@%
  18687.  
  18688. %@AI@%96%@AE@% is the Y (vertical) pixels-per-inch.  %@NL@%
  18689.  
  18690. See the description of the GDIINFO data structure in Chapter 2, "Display
  18691. Drivers," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% for more
  18692. information on calculating these values.  %@NL@%
  18693.  
  18694. %@AI@%File1 %@AE@%is the MS-DOS filename of the dependent file. This might include a
  18695. help (.HLP) file or a font installer that is associated with File1. You can
  18696. have more than one dependent file listed, but each must have a unique name.
  18697. %@NL@%
  18698.  
  18699. See Section C.6.3, "Special Considerations," for information on how Control
  18700. Panel installs font files.  %@NL@%
  18701.  
  18702. The following is an example of what a .INF file for a specific printer
  18703. driver would look like.  %@NL@%
  18704.  
  18705. %@AS@%  [disk]
  18706. %@AS@%  1 = . ,"XYZ Printers Disk"%@AE@%
  18707.  
  18708. %@AS@%  [io.device]
  18709. %@AS@%  1:XYZLASER.DRV,"XYZ Laser Printer","DEVICESPECIFIC"
  18710. %@AS@%  1:XYZINK.DRV,"XYZ Ink Jet Printer [XYZ Series]", 
  18711. %@AS@%  "100,120,120","100,96,96"%@AE@%
  18712.  
  18713. %@AS@%  [io.dependent]
  18714. %@AS@%  XYZLASER.DRV= 1:XYZLASER.HLP,1:SFXYZ.DLL%@AE@%
  18715.  
  18716. If the driver is not found in the current drive, Control Panel will prompt
  18717. the user for that disk.  %@NL@%
  18718.  
  18719. The following is an example of a WIN.INI file after installation.  %@NL@%
  18720.  
  18721. %@AS@%  [windows]
  18722. %@AS@%   |
  18723. %@AS@%  device=XYZ Series,XYZINK,LPT1:  ; Default printer, only one allowed at 
  18724. %@AS@%  a time
  18725. %@AS@%   |%@AE@%
  18726.  
  18727. %@AS@%  [printerports]
  18728. %@AS@%  XYZ Series=XYZINK,LPT1:,15,45
  18729. %@AS@%  XYZ Laser Printer=XYZLASER,LPT2:,15,45%@AE@%
  18730.  
  18731. %@AS@%  [devices]
  18732. %@AS@%  XYZ Series=XYZINK,LPT1:
  18733. %@AS@%  XYZ Laser Printer=XYZLASER,LPT2:%@AE@%
  18734.  
  18735.  
  18736. %@3@%%@CR:C6A-C0014   @%%@AB@%C.6.2  Driver Description (.DEF) File%@AE@%%@EH@%%@NL@%
  18737.  
  18738. All drivers must provide a description string in the printer driver's .DEF
  18739. file. The following are a generalized example of the syntax used for printer
  18740. devices and a specific example along with definitions of each of the terms
  18741. presented.  %@NL@%
  18742.  
  18743. DESCRIPTION 'DDRV Text_Description:Aspect_Ratio  %@NL@%
  18744.  
  18745. DESCRIPTION 'DDRV PCL / HP LaserJet:100,300,300'  %@NL@%
  18746.  
  18747. Where:  %@NL@%
  18748.  
  18749. The character immediately following DDRV can be anything and is always
  18750. ignored.  %@NL@%
  18751.  
  18752. %@AI@%DDRV%@AE@% must be capitalized.  %@NL@%
  18753.  
  18754. %@AI@%Text_Description%@AE@%, up to but not including the colon, is placed on the
  18755. lefthand side of the equal sign for the entries in the [devices] and
  18756. [PrinterPorts] sections of the WIN.INI file. It is also the first element on
  18757. the righthand side of the "device=" line in the [windows] section. Because
  18758. the righthand side of the "device=" line is parsed using commas, if
  18759. %@AI@%Text_Description%@AE@% includes a comma, it will be terminated there. For example:
  18760. %@NL@%
  18761.  
  18762. DESCRIPTION 'Printer 1, Printer2:100,300,300'  %@NL@%
  18763.  
  18764. %@AI@%Printer 1%@AE@% will be used as the lefthand and righthand sides in the above
  18765. mentioned sections. This will cause problems when installing with the
  18766. Control Panel. If you need to list more than one printer, we suggest you use
  18767. a delimiter other than a comma. For example:  %@NL@%
  18768.  
  18769. DESCRIPTION 'Printer 1/Printer2:100,300,300'  %@NL@%
  18770.  
  18771. Aspect_Ratio includes the following three values:  %@NL@%
  18772.  
  18773.  
  18774.   ■   X and Y aspect ratio%@NL@%
  18775.  
  18776.   ■   X pixels-per-inch%@NL@%
  18777.  
  18778.   ■   Y pixels-per-inch%@NL@%
  18779.  
  18780.  
  18781. The three values are separated by commas and enclosed within quotation
  18782. marks. For example, for a VGA display, the values would be as follows:  %@NL@%
  18783.  
  18784. "100,96,96"  %@NL@%
  18785.  
  18786. Where:  %@NL@%
  18787.  
  18788. %@AI@%100%@AE@% is the X and Y aspect ratio (1-to-1).  %@NL@%
  18789.  
  18790. %@AI@%96%@AE@% is the X (horizontal) pixels-per-inch.  %@NL@%
  18791.  
  18792. %@AI@%96%@AE@% is the Y (vertical) pixels-per-inch.  %@NL@%
  18793.  
  18794. See the description of the GDIINFO data structure in Chapter 2, "Display
  18795. Drivers," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% for more
  18796. information on calculating these values.  %@NL@%
  18797.  
  18798.  
  18799. %@3@%%@CR:C6A-C0015   @%%@AB@%C.6.3  Special Considerations%@AE@%%@EH@%%@NL@%
  18800.  
  18801. Control Panel references the SETUP.INF file in the Windows ..\SYSTEM
  18802. subdirectory for the raster font files. Control Panel will prompt the user
  18803. as necessary for the Microsoft Windows disk defined in the SETUP.INF file if
  18804. a font matching the %@AI@%Aspect_Ratio%@AE@% is available.  %@NL@%
  18805.  
  18806. If dependent files exist, the OEMSETUP.INF file needs to exist in the same
  18807. directory as the driver file.  %@NL@%
  18808.  
  18809.  
  18810. %@2@%%@CR:C6A-C0016   @%%@AB@%C.7  Testing the Installation of Your .INF File%@AE@%%@EH@%%@NL@%
  18811.  
  18812. Before testing, you need to create a .INF file according to the instructions
  18813. given in Section C.5, "Creating .INF File Entries," and Section C.6,
  18814. "Creating .INF File Entries for Printer Drivers." The .INF file and other
  18815. associated driver and virtual device files should then be copied to a disk
  18816. (or any other form on which you plan to distribute them).  %@NL@%
  18817.  
  18818. Depending on the type of device you support, you will need to run either
  18819. Setup or Control Panel to test your .INF file.  %@NL@%
  18820.  
  18821. Setup installs display, mouse or other pointing device, network, keyboard,
  18822. or machine-dependent drivers and virtual devices.  %@NL@%
  18823.  
  18824. Printer drivers are installed by Control Panel.  %@NL@%
  18825.  
  18826.  
  18827. %@3@%%@CR:C6A-C0017   @%%@AB@%C.7.1  Testing with Setup%@AE@%%@EH@%%@NL@%
  18828.  
  18829. You must run the Setup utility from MS-DOS when installing additional device
  18830. support (via an OEMSETUP.INF file). If you run Setup directly from Windows,
  18831. you can install only device drivers and virtual devices that are supplied
  18832. with Windows (i.e., defined in the SETUP.INF file).  %@NL@%
  18833.  
  18834. During debugging, we suggest you use the debugging version of the Setup
  18835. utility, which is provided on the DDK disks. For more information on the
  18836. error messages that might appear, see Section C.9, "Error Messages When
  18837. Running Debug Setup."  %@NL@%
  18838.  
  18839. Follow these steps to install additional drivers and virtual devices with
  18840. Setup:  %@NL@%
  18841.  
  18842.  
  18843.   1.  Exit Windows.%@NL@%
  18844.  
  18845. %@STUB@%      Do not use the DOS Prompt icon in the Main Group window. Using this
  18846.       icon will result in an incorrect setup.%@NL@%
  18847.  
  18848.   2.  Type %@AI@%setup%@AE@% and press ENTER.%@NL@%
  18849.  
  18850. %@STUB@%      Setup lists your current Windows configuration.%@NL@%
  18851.  
  18852.   3.  Press the UP or DOWN ARROW key to select the setting you want to
  18853.       change and press ENTER.%@NL@%
  18854.  
  18855. %@STUB@%      A list of choices is displayed.%@NL@%
  18856.  
  18857.   4.  Scroll to the bottom of the list using the DOWN ARROW key.%@NL@%
  18858.  
  18859.   5.  Select Other and press ENTER.%@NL@%
  18860.  
  18861. %@STUB@%      Setup prompts you for the disk containing the device driver or virtual
  18862.       device.%@NL@%
  18863.  
  18864.   6.  Insert your distribution disk into drive A. Setup displays a list of
  18865.       the device drivers or virtual devices defined in the OEMSETUP.INF file
  18866.       on that disk. Then select the appropriate driver or virtual device and
  18867.       press ENTER.%@NL@%
  18868.  
  18869. %@STUB@%      Or type the pathname of the device driver or virtual device and press
  18870.       ENTER.%@NL@%
  18871.  
  18872.   7.  Press ENTER to complete the process.%@NL@%
  18873.  
  18874.  
  18875. Be sure to install and test all the files described in your OEMSETUP.INF
  18876. file.  %@NL@%
  18877.  
  18878. Setup automatically expands your files if you choose to use the COMPRESS.EXE
  18879. utility supplied in the SDK to compress your files. Notice, however, that
  18880. OEMSETUP.INF should %@AI@%not%@AE@% be compressed.  %@NL@%
  18881.  
  18882.  
  18883. %@3@%%@CR:C6A-C0018   @%%@AB@%C.7.2  Testing with Control Panel%@AE@%%@EH@%%@NL@%
  18884.  
  18885. To test your OEMSETUP.INF file and the DESCRIPTION in your printer driver's
  18886. .DEF file, you need to run Control Panel.  %@NL@%
  18887.  
  18888. Additional printer drivers are installed the same way you would install a
  18889. driver supplied by Windows. Instead of selecting a printer from the list (of
  18890. those defined in the SETUP.INF file) to install, you would select Unlisted
  18891. Printer from the bottom of the list.  %@NL@%
  18892.  
  18893. Follow these steps to install an additional printer driver:  %@NL@%
  18894.  
  18895.  
  18896.   1.  Run Control Panel and select the Printers Icon.%@NL@%
  18897.  
  18898.   2.  Choose the Add Printer button.%@NL@%
  18899.  
  18900.   3.  Select Unlisted Printer from the bottom of the printers list.%@NL@%
  18901.  
  18902.   4.  Choose the Install button.%@NL@%
  18903.  
  18904.   5.  Insert your distribution disk, if necessary.%@NL@%
  18905.  
  18906.   6.  Select the appropriate drive and directory path.%@NL@%
  18907.  
  18908.   7.  Select OK.%@NL@%
  18909.  
  18910.   8.  Select the appropriate driver filename from the Driver Files list.%@NL@%
  18911.  
  18912.   9.  Select OK.%@NL@%
  18913.  
  18914.  
  18915. At this point, Control Panel looks for OEMSETUP.INF. If found, Control Panel
  18916. will install all the raster font and associated files defined in the
  18917. [io.dependent] section (if applicable to the driver file that you selected).
  18918. %@NL@%
  18919.  
  18920. If OEMSETUP.INF does not exist on this disk or in the specified directory,
  18921. Control Panel inspects the DESCRIPTION line within the driver and copies the
  18922. raster fonts that match exactly the values defined there.  %@NL@%
  18923.  
  18924. Control Panel expands your files automatically if you choose to use the
  18925. COMPRESS.EXE utility supplied in the SDK to compress your files. Notice,
  18926. however, that the OEMSETUP.INF file should %@AI@%not%@AE@% be compressed.  %@NL@%
  18927.  
  18928.  
  18929. %@2@%%@CR:C6A-C0019   @%%@AB@%C.8  Informing Microsoft About the Availability of Your Driver and/or%@EH@%
  18930. %@AB@%Virtual Device%@AE@%%@NL@%
  18931.  
  18932. Microsoft publishes the %@AI@%Microsoft Windows Software and Hardware Directory%@AE@%.
  18933. This publication is available to both developers and Windows users. The
  18934. directory contains information on the following:  %@NL@%
  18935.  
  18936.  
  18937.   ■   Windows-compatible applications%@NL@%
  18938.  
  18939.   ■   Windows device drivers%@NL@%
  18940.  
  18941.   ■   Windows virtual devices%@NL@%
  18942.  
  18943.   ■   Windows-based consultants%@NL@%
  18944.  
  18945.  
  18946. Included in this package is a %@AI@%Microsoft Windows Directory Survey%@AE@%. If you
  18947. want to publish information in the directory about your device drivers
  18948. and/or virtual devices, please complete this survey and return it to the
  18949. address listed on the survey form. There is no fee for taking advantage of
  18950. this opportunity to tell Microsoft Windows 3.0 users all about the support
  18951. for your product.  %@NL@%
  18952.  
  18953.  
  18954. %@2@%%@CR:C6A-C0020   @%%@AB@%C.9  Error Messages When Running Debug Setup%@AE@%%@EH@%%@NL@%
  18955.  
  18956. When using the debug version of Setup that is provided on the DDK disks, you
  18957. may see several error messages regarding possible Setup assertion failures.
  18958. The following list provides the error message numbers and a brief
  18959. description of each along with possible solutions:  %@NL@%
  18960.  
  18961. %@TH:  37  2307 02 34 44 @%
  18962. Message                           Description
  18963. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18964. SUINF.C:68:                       Setup could not find a suitable (correct 
  18965.                                   aspect ratio) system font for the display 
  18966.                                   driver selected. Ensure that a matching 
  18967.                                   aspect ratio font is available in the 
  18968.                                   [sysfonts] section of the .INF file.
  18969.  
  18970. SUINF.C:77:                       Setup could not find a suitable (correct 
  18971.                                   aspect ratio) OEM font for the display 
  18972.                                   driver selected. Ensure that a matching 
  18973.                                   aspect ratio font is available in the 
  18974.                                   [oemfonts] section of the .INF file.
  18975.  
  18976. SUINF.C:80:                       Setup could not find a suitable (correct 
  18977.                                   aspect ratio) OEM font for the display 
  18978.                                   driver selected. Ensure that a matching 
  18979.                                   aspect ratio font is available in the 
  18980.                                   [oemfonts] section of the .INF file.
  18981.  
  18982. SUINF.C:84:                       Setup could not find a suitable (correct 
  18983.                                   aspect ratio) fixed font for the display 
  18984.                                   driver selected. Ensure that a matching 
  18985.                                   aspect ratio font is available in the 
  18986.                                   [fixedfonts] section of the .INF file.
  18987.  
  18988. SUINF.C:165:                      Setup detected a machine for which it 
  18989.                                   could not find a machine entry in the 
  18990.                                   [machine] section of the .INF file. 
  18991.  
  18992. SUUTIL.C:451:                     Setup cannot find a disk entry in the 
  18993.                                   [disks] section of SETUP.INF for a logical
  18994.                                   disk ID given in the .INF file. Check to 
  18995.                                   see that all logical disk ID values have a
  18996.                                   corresponding entry in the [disks] section
  18997.                                   of the .INF file.
  18998.  
  18999. %@TE:  37  2307 02 34 44 @%
  19000.  
  19001.  
  19002.  
  19003.  
  19004.  
  19005.  
  19006. %@CR:C6A-D0001   @%%@1@%%@AB@%Appendix D  Windows INT 2FH API%@AE@%%@EH@%%@NL@%
  19007. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19008.  
  19009. Enhanced Windows 3.0 supports an application program interface (API)
  19010. designed to enable MS-DOS device drivers, TSR programs, and application
  19011. programs to take full advantage of the multitasking abilities of the
  19012. enhanced Windows environment.  %@NL@%
  19013.  
  19014. Most application program writers will use the interface that releases the
  19015. current virtual machine's time-slice. This API allows enhanced Windows and
  19016. OS/2 to multitask non-Windows specific MS-DOS applications more efficiently.
  19017. The Release Time Slice API should be used by applications even if they are
  19018. not running under enhanced Windows. This allows OS/2 to detect idleness in
  19019. MS-DOS applications. OS/2 will recognize the enhanced Windows release
  19020. time-slice call but it does not support other enhanced Windows APIs.  %@NL@%
  19021.  
  19022. The Microsoft 80286 DOS extender will issue the initialization and exit INT
  19023. 2FH API calls so that real mode software can free extended memory through
  19024. XMS. The 286 DOS extender also supports the Int 31h service detection Int
  19025. 2FH API call.  %@NL@%
  19026.  
  19027. Other APIs are used by MS-DOS device drivers and TSRs that have enhanced
  19028. Windows specific requirements.  %@NL@%
  19029.  
  19030.  
  19031. %@2@%%@CR:C6A-D0002   @%%@AB@%D.1  Call-In Interfaces%@AE@%%@EH@%%@NL@%
  19032.  
  19033. Call-in interfaces are APIs that real mode MS-DOS device drivers, TSRs, and
  19034. applications use to communicate with enhanced Windows. These include:  %@NL@%
  19035.  
  19036.  
  19037.   ■   Get Windows version%@NL@%
  19038.  
  19039.   ■   Get virtual machine ID%@NL@%
  19040.  
  19041.   ■   Begin critical section%@NL@%
  19042.  
  19043.   ■   End critical section%@NL@%
  19044.  
  19045.   ■   Release time slice%@NL@%
  19046.  
  19047.   ■   Get device API entry point%@NL@%
  19048.  
  19049.   ■   Switch VMs and callback
  19050. %@NL@%
  19051.  
  19052.  
  19053.  
  19054. %@3@%%@CR:C6A-D0003   @%%@AB@%D.1.1  Enhanced Windows Installation Check (AX=1600H)%@AE@%%@EH@%%@NL@%
  19055.  
  19056. This API call is valid under all versions of enhanced Windows. If a program
  19057. intends to use a enhanced Windows API, it must first make sure that the
  19058. enhanced Windows environment is running. To do this, issue:  %@NL@%
  19059.  
  19060. %@AS@%  mov ax, 1600h
  19061. %@AS@%  int 2Fh
  19062. %@AS@%  test al, 7Fh
  19063. %@AS@%  jz Not_Running_Win386
  19064. %@AS@%  (Otherwise enhanced Windows is running)
  19065. %@AS@%  cmp al, 1
  19066. %@AS@%  je Running_Ver_2xx
  19067. %@AS@%  cmp al, -1
  19068. %@AS@%  je Running_Ver_2xx
  19069. %@AS@%  (Else al contains major version, AH contains minor)%@AE@%
  19070.  
  19071. If 0 or 80H is returned in AL, enhanced Windows is not running. Any other
  19072. value means that enhanced Windows is running. A value of 1 or -1 (0FFH)
  19073. indicates that the application is running under enhanced Windows version 2.0
  19074. or 3.0. Otherwise, %@AB@%AL%@AE@% will contain the major version number (3 or higher)
  19075. and %@AB@%AH%@AE@% will contain the minor version number. The table below summarizes the
  19076. possible return values:  %@NL@%
  19077.  
  19078. %@TH:  14   517 02 15 51 12 @%
  19079. Value in AL    Meaning
  19080. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19081. 00H            Enhanced Windows 3.x or Windows/386 version 2.xx 
  19082.                is not running
  19083.  
  19084. 80H            Enhanced Windows 3.x or Windows/386 version 2.xx 
  19085.                is not running
  19086.  
  19087. 01H            Windows/386 version 2.xx running
  19088.  
  19089. FFH            Windows/386 version 2.xx running
  19090.  
  19091. Anything else  AL = Major version number                          AH = Minor
  19092.  
  19093. %@TE:  14   517 02 15 51 12 @%
  19094.  
  19095.  
  19096. %@3@%%@CR:C6A-D0004   @%%@AB@%D.1.2  Releasing Current Virtual Machine's Time-Slice (AX=1680h)%@AE@%%@EH@%%@NL@%
  19097.  
  19098. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19099. %@AB@%NOTE %@AE@%%@AI@%
  19100. %@AI@%%@AI@%This API should be used only by non-Windows specific applications. Windows
  19101. %@AI@%programs should yield their time by calling the WaitMessage%@AI@% function.%@AE@%%@AE@%
  19102. %@AE@%────────────────────────────────────────────────────────────────────────────%@NL@%
  19103.  
  19104. This API is used by programs to indicate that the program is idle (usually
  19105. waiting for the user to type something). By issuing this interrupt,
  19106. applications prevent enhanced Windows from wasting time running a program
  19107. that is essentially doing nothing. This allows other programs to use the
  19108. time.  %@NL@%
  19109.  
  19110. Programs should always use this API even if they are not Windows-specific
  19111. applications and even if they are not currently running under Windows in 386
  19112. enhanced mode. This allows OS/2 to detect idleness even though it does not
  19113. support the complete enhanced Windows API. The only check you should make
  19114. before issuing the API call is to make sure that the INT 2FH interrupt
  19115. vector is not zero.  %@NL@%
  19116.  
  19117. Sample code:  %@NL@%
  19118.  
  19119. %@AS@%  mov ax, 352Fh
  19120. %@AS@%   int 21h  ; DOS get vector 2Fh
  19121. %@AS@%   mov ax, es  ; ES:BX = Vector
  19122. %@AS@%   or ax, bx  ; Q: Is it zero?
  19123. %@AS@%   jz Skip_Idle_Call ;    Y: Skip this
  19124. %@AS@%   mov ax, 1680h ;    N: Tell Win
  19125. %@AS@%   int 2Fh  ;       we're idle.
  19126. %@AS@%  Skip_Idle_Call:%@AE@%
  19127.  
  19128. If the API is supported, the INT 2FH will return with %@AB@%AL%@AE@%=0, otherwise it
  19129. will return with AL unchanged (80h). Usually application programs will not
  19130. be interested in the return value.  %@NL@%
  19131.  
  19132. Note that when an application uses this API it will continue to run
  19133. occasionally so your program should re-issue the interrupt in the program's
  19134. idle loop. In other words, this API does NOT block your application until a
  19135. key is pressed.  %@NL@%
  19136.  
  19137.  
  19138. %@3@%%@CR:C6A-D0005   @%%@AB@%D.1.3  Begin Critical Section (AX=1681h)%@AE@%%@EH@%%@NL@%
  19139.  
  19140. If an MS-DOS device driver or TSR needs to prevent a task-switch from
  19141. occurring, it should call this interface. When a virtual machine is in a
  19142. critical section, no other task will be allowed to run except to service
  19143. hardware interrupts. For this reason, the critical section should be freed
  19144. (using the end critical section API) as soon as possible.  %@NL@%
  19145.  
  19146.  
  19147. %@3@%%@CR:C6A-D0006   @%%@AB@%D.1.4  End Critical Section (AX=1682h)%@AE@%%@EH@%%@NL@%
  19148.  
  19149. This API must be called to release ownership of the critical section that
  19150. was claimed using the Begin Critical Section API. Every call to Begin
  19151. Critical Section must be followed by a matching call to End Critical
  19152. Section.  %@NL@%
  19153.  
  19154.  
  19155. %@3@%%@CR:C6A-D0007   @%%@AB@%D.1.5  Get Current Virtual Machine ID (AX=1683h)%@AE@%%@EH@%%@NL@%
  19156.  
  19157. This API returns with %@AB@%BX%@AE@% = Current virtual machine ID. The ID is unique for
  19158. each virtual machine. Although Windows currently runs in VM 1, your software
  19159. should not rely on this. Also, if a VM is destroyed, its ID may be reused by
  19160. another new virtual machine. Be sure to treat VM IDs as a word (not a byte).
  19161. An ID of 0 will %@AI@%never%@AE@% be returned.  %@NL@%
  19162.  
  19163.  
  19164. %@3@%%@CR:C6A-D0008   @%%@AB@%D.1.6  Get Device API Entry Point (AX=1684h)%@AE@%%@EH@%%@NL@%
  19165.  
  19166. Some VxDs (enhanced Windows device drivers) provide a set of services that
  19167. application programs can access. For example, the Virtual Display Device
  19168. provides services that the Windows old application program uses to display
  19169. MS-DOS programs in a window. Any VxD can support an API for MS-DOS
  19170. applications. Your program must issue an INT 2FH with %@AB@%AX%@AE@%=1684h and %@AB@%BX%@AE@% =
  19171. Virtual device ID. The entry point address will be returned in %@AB@%ES:DI%@AE@%. Your
  19172. application must execute a FAR CALL to this address to call the virtual
  19173. device. If the value returned is 0:0 then the device does not support an
  19174. API, otherwise %@AB@%ES:DI%@AE@% is the address of the procedure to call. You should
  19175. either make sure your application is running on version 3.0 or zero %@AB@%ES%@AE@% and
  19176. %@AB@%DI%@AE@% before using this API.  %@NL@%
  19177.  
  19178. %@AS@%  xor di, di ; * Only necessary if you have  *
  19179. %@AS@%  mov es, di ; * not checked for Win ver 3.0 *
  19180. %@AS@%  mov ax, 1684h
  19181. %@AS@%  mov bx, My_Device_ID
  19182. %@AS@%  int 2Fh
  19183. %@AS@%  mov ax, es
  19184. %@AS@%  or ax, di
  19185. %@AS@%  jz API_Is_Not_Supported
  19186. %@AS@%  (else API address in ES:DI)%@AE@%
  19187.  
  19188. The definition of a device API is specified by the virtual device driver.
  19189. Refer to individual virtual device documentation for details.  %@NL@%
  19190.  
  19191.  
  19192. %@3@%%@CR:C6A-D0009   @%%@AB@%D.1.7  Switch VMs and CallBack (AX=1685h)%@AE@%%@EH@%%@NL@%
  19193.  
  19194. Some MS-DOS devices, such as networks, need to perform functions in a
  19195. specific virtual machine. These devices can use this interface to force the
  19196. appropriate virtual machine to be installed so that they can modify the VM's
  19197. data. Refer to Chapter 24, "Primary Scheduler Services," for information on
  19198. appropriate priority boosts.  %@NL@%
  19199.  
  19200. Entry: %@AB@%AX%@AE@% = 1685h %@AB@% BX %@AE@%= VM ID of virtual machine to switch to %@AB@% CX%@AE@% = Flags
  19201. Bit 0 = 1 if wait until interrupts enabled  Bit 1 = 1 if wait until critical
  19202. section unowned  All other bits must be 0 %@AB@% DX:SI%@AE@% = Priority boost (%@AB@%DX%@AE@%=High
  19203. word, %@AB@%SI%@AE@%=Low word) %@AB@% ES:DI%@AE@% = %@AB@%CS:IP%@AE@% of procedure to call  %@NL@%
  19204.  
  19205. Exit:  %@NL@%
  19206.  
  19207. %@AS@%  If carry set then
  19208. %@AS@%     AX = Error code
  19209. %@AS@%  else
  19210. %@AS@%     Event will be called or has been called already.%@AE@%
  19211.  
  19212. Error codes: 1 = Invalid VM ID  2 = Invalid priority boost  3 = Invalid
  19213. flags  %@NL@%
  19214.  
  19215. Callback procedure: Must save all registers modified  Must IRET to caller
  19216. Priority will remain boosted until procedure irets  %@NL@%
  19217.  
  19218.  
  19219. %@3@%%@CR:C6A-D0010   @%%@AB@%D.1.8  Detect Presence of INT 31H Services (AX=1686h)%@AE@%%@EH@%%@NL@%
  19220.  
  19221. If a program needs to detect the presence of the INT 31H protected mode API,
  19222. it can use this INT 2FH. Note that this particular API is also supported by
  19223. the Microsoft 80286 DOS extender for protected mode Windows. INT 31H
  19224. services are only supported for protected mode programs.  %@NL@%
  19225.  
  19226.  
  19227. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  19228.  
  19229.  %@AB@%AX%@AE@% = 1686h  %@NL@%
  19230.  
  19231.  
  19232. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  19233.  
  19234. If AX = 0 then    INT 31H services are available and can be called else (AX
  19235. 0)    zINT 31H services are not available  %@NL@%
  19236.  
  19237.  
  19238. %@2@%%@CR:C6A-D0011   @%%@AB@%D.2  Call Out Interfaces%@AE@%%@EH@%%@NL@%
  19239. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19240.  
  19241. Enhanced Windows will broadcast INT 2FH to real mode device drivers and TSRs
  19242. to inform them of various activities. These can be used to load enhanced
  19243. Windows installable devices, free extended memory, instance per-VM data
  19244. structures, and turn on or off various device services or features. For
  19245. example, SmartDrv can free extended memory for enhanced Windows to use when
  19246. the initialization call is made and then reclaim it when it receives the
  19247. termination call. MS-DOS devices such as networks can inform the enhanced
  19248. Windows loader to load a special protected mode installable device that
  19249. cooperates with the real mode network device driver.  %@NL@%
  19250.  
  19251.  
  19252. %@3@%%@AB@%D.2.1  Enhanced Windows and 286 DOS Extender Initialization (AX=1605h)%@AE@%%@EH@%%@NL@%
  19253.  
  19254. The enhanced Windows loader and the Microsoft 286 DOS extender will
  19255. broadcast an INT 2FH with the following parameters:  %@NL@%
  19256.  
  19257. %@AB@%AX%@AE@% = 1605h %@AB@%ES:BX%@AE@% = 0:0 %@AB@%DS:SI%@AE@% = 0:0 %@AB@%CX%@AE@% = 0 %@AB@%DX%@AE@% = Flags    Bit 0 = 0 if
  19258. enhanced Windows initialization    1 if Microsoft 286 DOS extender
  19259. initialization    All other bits reserved and undefined. %@AB@%DI%@AE@% = Version #:
  19260. major version in upper byte, minor version in lower byte  %@NL@%
  19261.  
  19262. Any MS-DOS device driver or TSR can hook Int 2FH and watch for this
  19263. particular broadcast. When this broadcast is received, the real mode
  19264. software can inform enhanced Windows or the 286 DOS extender that it should
  19265. not load by returning with %@AB@%CX%@AE@%  0. The TSR or device that fails the
  19266. initialization should print an error message so the user can take
  19267. appropriate steps to reconfigure the machine. Enhanced Windows and the
  19268. Microsoft DOS extender will not print an error message─they will only issue
  19269. the termination API call and return to MS-DOS.  %@NL@%
  19270.  
  19271. If it is OK for enhanced Windows or the DOS extender to load, the real mode
  19272. software should not modify CX and may want to do one or more of the
  19273. following:  %@NL@%
  19274.  
  19275.  
  19276.   ■   Release extended memory through the XMS interface.%@NL@%
  19277.  
  19278.   ■   Switch back to real mode (if currently in virtual 8086 mode) or set
  19279.       %@AB@%DS:SI%@AE@% to the Virtual 8086 mode enable/disable routine address.%@NL@%
  19280.  
  19281.   ■   Load an installable device (enhanced Windows only).%@NL@%
  19282.  
  19283.   ■   Instance private data structures (enhanced Windows only).%@NL@%
  19284.  
  19285.  
  19286. The DOS extender only pays attention to the value returned in %@AB@%CX%@AE@%. It will
  19287. not instance any data or load enhanced Windows installable device drivers.
  19288. The DOS extender only issues this call so that extended memory can be
  19289. released and the machine can be placed in real mode if it is currently in
  19290. virtual 8086 mode.  %@NL@%
  19291.  
  19292. Instance data refers to data in a TSR or MS-DOS device driver that must have
  19293. a private copy in each VM. Normally, all TSRs and devices loaded before
  19294. enhanced Windows is run are considered global memory. That means that all of
  19295. the data is shared between virtual machines. However, there are some pieces
  19296. of data that actually should be maintained on a per-VM basis. For example,
  19297. the MS-DOS command line buffer needs to be instanced (this is done
  19298. automatically by enhanced Windows). However, TSRs such as the MS-DOS command
  19299. line editors will not function properly unless they identify the data that
  19300. needs to be instanced.  %@NL@%
  19301.  
  19302. The first two options (release extended memory, or switch from V86 to real
  19303. mode) are up to the device to handle on its own. The last options require
  19304. returning a pointer to a list of structures to load. Your INT 2FH hook must
  19305. first chain to the next INT 2FH handler with all registers unmodified. When
  19306. the handler returns you must take the %@AB@%ES:BX %@AE@%value returned and place it in
  19307. the following data structure in the %@AI@%Next_Dev_Ptr%@AE@% field:  %@NL@%
  19308.  
  19309. %@AS@%  Win386_Startup_Info_Struc STRUC
  19310. %@AS@%  SIS_Version   db 3, 0
  19311. %@AS@%  SIS_Next_Dev_Ptr   dd ?
  19312. %@AS@%  SIS_Virt_Dev_File_Ptr  dd 0
  19313. %@AS@%  SIS_Reference_Data  dd ?
  19314. %@AS@%  SIS_Instance_Data_Ptr  dd 0
  19315. %@AS@%  Win386_Startup_Info_Struc ENDS%@AE@%
  19316.  
  19317. Your software must point %@AB@%ES:BX%@AE@% at this structure and return. This allows
  19318. multiple enhanced Windows installable devices to be loaded through a single
  19319. INT 2FH call.  %@NL@%
  19320.  
  19321. The %@AB@%SIS_Version%@AE@% field is used by enhanced Windows to determine the size of
  19322. the structure. This field should always contain 3, 0 to indicate that it is
  19323. version 3.0.  %@NL@%
  19324.  
  19325. The %@AB@%SIS_Next_Dev_Ptr%@AE@% points to the next structure in the list. This field
  19326. must be filled in with the returned %@AB@%ES:BX%@AE@% after your software chains to the
  19327. next INT 2FH handler.  %@NL@%
  19328.  
  19329. %@AB@%SIS_Virt_Dev_File_Ptr%@AE@% is a pointer to an ASCIIZ string that contains the
  19330. name of a enhanced Windows virtual device file. MS-DOS devices such as
  19331. networks use this to force a special enhanced Windows protected mode virtual
  19332. device to be loaded. If this field is zero, then no device will be loaded.  %@NL@%
  19333.  
  19334. The %@AB@%SIS_Reference_Data%@AE@% is only used when the %@AB@%SIS_Virt_Dev_File_Ptr%@AE@% is
  19335. non-zero. This DWORD will be passed to the virtual device when it is
  19336. initialized. The DWORD can contain any value. Often it contains a pointer to
  19337. some device specific data structure.  %@NL@%
  19338.  
  19339. The %@AB@%SIS_Instance_Data_Ptr%@AE@% field points to a list of data to be instanced. If
  19340. the field is zero, then no data will be instanced. Each entry in the list
  19341. has the following structure:  %@NL@%
  19342.  
  19343. %@AS@%  Instance_Item_Struc STRUC
  19344. %@AS@%   IIS_Ptr   dd ?
  19345. %@AS@%   IIS_Size  dw ?
  19346. %@AS@%  Instance_Item_Struc ENDS%@AE@%
  19347.  
  19348. The list is terminated with a zero DWORD.  %@NL@%
  19349.  
  19350. Your handler must preserve all registers except the values returned in %@AB@%ES,
  19351. %@AB@%BX,%@AE@% and %@AB@%CX%@AE@%. It must also preserve %@AB@%DS%@AE@% and %@AB@%SI%@AE@% unless it explicitly changes
  19352. them to return the address of the virtual 8086 mode enable/disable routine.
  19353. Remember, any device that returns with %@AB@%CX%@AE@%  0 will force enhanced Windows or
  19354. the 286 DOS extender to abort. If the load is aborted, the termination INT
  19355. 2FH will be issued immediately.  %@NL@%
  19356.  
  19357. Enhanced Windows supports loading with a virtual mode program such as an EMM
  19358. "LIMulator" running provided that the program supports a virtual 8086 mode
  19359. enable/disable callback routine. The address of the routine must be returned
  19360. in %@AB@%DS:SI%@AE@%. If your TSR or device driver sets this return parameter, it should
  19361. first check to make sure that %@AB@%DS%@AE@% and%@AB@% SI%@AE@% are both zero. If they are non-zero,
  19362. then fail the initialization by setting CX=non-zero. Notice that the
  19363. Microsoft 286 DOS extender will not call this routine. Therefore, you must
  19364. either set the processor into real mode during the initialization INT 2FH or
  19365. set CX=non-zero to abort the load.  %@NL@%
  19366.  
  19367. The virtual mode enable/disable callback will be called with %@AB@%AX%@AE@%=0 to disable
  19368. V86 mode (return to real mode) and %@AB@%AX%@AE@%=1 to re-enable V86 mode. Just before
  19369. attempting to enter protected mode enhanced Windows will disable V86 mode
  19370. after every VxD has been loaded. It will call the enable/disable routine
  19371. with %@AB@%AX%@AE@%=0 and with interrupts disabled. Do not enable interrupts in your
  19372. routine unless the routine will return with Carry set to indicate failure.
  19373. After enhanced Windows exits, it will call the enable/disable routine in
  19374. real mode with %@AB@%AX%@AE@%=1 and with interrupts disabled to set the machine back
  19375. into V86 mode.  %@NL@%
  19376.  
  19377. The enable/disable routine will be called with a FAR return frame. It must
  19378. return with the carry flag clear to indicate success or Carry set to
  19379. indicate an error. If an error is returned from the disable call, then
  19380. enhanced Windows will abort. The error return from the enable V86 call will
  19381. be ignored and the machine will be left in real mode. It is the
  19382. responsibility of the enable/disable routine to print an error message.  %@NL@%
  19383.  
  19384.  
  19385. %@3@%%@AB@%D.2.2  Enhanced Windows and 286 DOS Extender Exit (AX=1606h)%@AE@%%@EH@%%@NL@%
  19386.  
  19387. When enhanced Windows or the 286 DOS extender terminates, it will broadcast
  19388. an INT 2FH with the following parameters:  %@NL@%
  19389.  
  19390. %@AB@%AX%@AE@% = 1606H. %@AB@%DX%@AE@% = Flags Bit 0 = 0 if enhanced Windows exit 1 if Microsoft 286
  19391. DOS extender exit All other bits reserved and undefined.  %@NL@%
  19392.  
  19393. This call will be issued in real mode. It allows devices and TSRs to undo
  19394. anything they did when enhanced Windows or the DOS extender initialized. For
  19395. example, a device like SmartDrv may re-allocate extended memory that it
  19396. released during initialization.  %@NL@%
  19397.  
  19398. If the initialization broadcast fails (returns with %@AB@%CX%@AE@%  0) then this
  19399. broadcast will be issued immediately.  %@NL@%
  19400.  
  19401.  
  19402. %@3@%%@AB@%D.2.3  Device Call Out API (AX=1607h)%@AE@%%@EH@%%@NL@%
  19403.  
  19404. This API is, in reality, more of a convention than an API. It specifies a
  19405. standard mechanism for enhanced Windows virtual devices to talk to MS-DOS
  19406. device drivers and TSRs.  %@NL@%
  19407.  
  19408. Some devices need to ask real-mode MS-DOS software for information. For
  19409. example, the Virtual NetBIOS mapper VxD will issue an INT 2FH to determine
  19410. if a network supports an extended NetBIOS API. The standard device call out
  19411. will have %@AB@%AX%@AE@%=1607H and %@AB@%BX%@AE@%=Device ID. As with the device API entry point
  19412. call-in interface, the details of the interface are specified by the device
  19413. that issues the interrupt.  %@NL@%
  19414.  
  19415. This interrupt may be issued at any time, either in real mode or after
  19416. enhanced Windows has begun execution.  %@NL@%
  19417.  
  19418.  
  19419. %@3@%%@AB@%D.2.4  Enhanced Windows Initialization Complete (AX=1608h)%@AE@%%@EH@%%@NL@%
  19420.  
  19421. This API call is made by enhanced Windows after all the installable devices
  19422. have initialized. At this point, it is still possible to identify instance
  19423. data and perform other functions that are restricted to enhanced Windows
  19424. initialization time. The enhanced Windows device initialization phase is
  19425. complete, so it is possible to call enhanced Windows device API entry
  19426. points.  %@NL@%
  19427.  
  19428. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19429. %@AU@%WARNING%@AE@%
  19430.  
  19431. Real mode software such as a TSR or DOS device driver may be called after
  19432. the enhanced Windows initialization call and before this API call is made.
  19433. It is the responsibility of the real mode software to detect and properly
  19434. handle this situation.
  19435. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19436.  
  19437.  
  19438. %@3@%%@AB@%D.2.5  Enhanced Windows Begin Exit (AX=1609H)%@AE@%%@EH@%%@NL@%
  19439.  
  19440. This API call is issued at the beginning of a normal Enhanced Windows exit
  19441. sequence. It is sent at the start of the %@AB@%Sys_VM_Terminate%@AE@% device control
  19442. call phase. All VxDs still exist so calls to device API entry points are
  19443. still valid.  %@NL@%
  19444.  
  19445. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19446. %@AU@%WARNING%@AE@%
  19447.  
  19448. This call will not be made in the event of a fatal system crash. Also, real
  19449. mode code may be executed after this API call has been made and before
  19450. enhanced Windows has returned to real mode. It is the responsibility of the
  19451. real mode software to detect and properly handle these situations.
  19452. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19453.  
  19454.  
  19455. %@2@%%@CR:C6A-D0012   @%%@AB@%D.3  Windows/386 Version 2.xx API Compatibility%@AE@%%@EH@%%@NL@%
  19456. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19457.  
  19458. The release of Windows/386 (version 2.xx) had a limited Application Program
  19459. Interface that was defined to help support real mode MS-DOS device drivers
  19460. such as networks. The 2.xx API allows MS-DOS programs to:  %@NL@%
  19461.  
  19462.  
  19463.   ■   Determine if Windows/386 or enhanced Windows (version 3.0) is running%@NL@%
  19464.  
  19465.   ■   Get the ID of the current Virtual Machine%@NL@%
  19466.  
  19467.   ■   Enter and leave a global critical section%@NL@%
  19468.  
  19469.  
  19470. The APIs used under version 2.xx are fairly complex and inflexible. We
  19471. suggest that, unless your application or device driver absolutely needs to
  19472. run under version 2.xx, you ignore all version 2.xx APIs and use the 3.0
  19473. APIs instead.  %@NL@%
  19474.  
  19475.  
  19476. %@3@%%@AB@%D.3.1  Installation Check%@AE@%%@EH@%%@NL@%
  19477.  
  19478. To test for Windows/386 version 2.xx, you should issue an Int 2fh with
  19479. %@AB@%AX%@AE@%=1600h. Refer to Windows Installation Check for complete documentation for
  19480. this API call.  %@NL@%
  19481.  
  19482.  
  19483. %@3@%%@AB@%D.3.2  Determining the Current Virtual Machine (Get VM ID)%@AE@%%@EH@%%@NL@%
  19484.  
  19485. Once the software has determined that it is running under Windows/386
  19486. version 2.xx, it must make another call to get the API procedure address. To
  19487. do this, issue:  %@NL@%
  19488.  
  19489. %@AS@%  mov ax, 1602h
  19490. %@AS@%   int 2fh
  19491. %@AS@%   (ES:DI -> Windows/386 API procedure)%@AE@%
  19492.  
  19493. The API procedure is the same address for every virtual machine, so you will
  19494. need to issue this call only once (although you can issue it as often as you
  19495. want).  %@NL@%
  19496.  
  19497. To get the ID of the current virtual machine %@AI@%jump%@AE@% to the Windows/386 API
  19498. procedure with %@AB@%AX%@AE@% = 0 and %@AB@%ES:DI%@AE@% - the address to return to.  %@NL@%
  19499.  
  19500. Sample code:  %@NL@%
  19501.  
  19502. %@AS@%  mov di, cs
  19503. %@AS@%   mov es, di
  19504. %@AS@%   mov di, OFFSET Win386_AIP_Return
  19505. %@AS@%   xor ax, ax   ; AX = 0
  19506. %@AS@%   jmp [Win386_API_Proc]
  19507. %@AS@%  Win386_API_Return:
  19508. %@AS@%   (Now BX contains the current VM ID)%@AE@%
  19509.  
  19510. Note that you must place the return address in %@AB@%ES:DI%@AE@% and JUMP to the API
  19511. procedure. When enhanced Windows returns control to your program it will
  19512. return to %@AB@%ES:DI%@AE@%.  %@NL@%
  19513.  
  19514. This interface is supported under version 3.0 only for compatibility
  19515. reasons. New MS-DOS devices or applications should use the version 3.0
  19516. interface.  %@NL@%
  19517.  
  19518.  
  19519. %@3@%%@AB@%D.3.3  Critical Section Handling%@AE@%%@EH@%%@NL@%
  19520.  
  19521. Windows/386 version 2.xx does not support API calls to enter and leave a
  19522. critical section. However, by incrementing and decrementing a special DOS
  19523. critical section counter called the InDOS flag, you can force the current
  19524. virtual machine into a critical section. Incrementing InDOS is not
  19525. sufficient to enter a critical section in version 3.0. You will need to make
  19526. an API call first and then, if it fails, increment the InDOS flag.  %@NL@%
  19527.  
  19528. To get the address of the InDOS flag, issue the following MS-DOS call
  19529. (documented in %@AI@%The MS-DOS Encyclopedia%@AE@% ):  %@NL@%
  19530.  
  19531. %@AS@%  mov ah, 34h
  19532. %@AS@%   int 21h
  19533. %@AS@%   (ES:BX -> InDOS flag)%@AE@%
  19534.  
  19535. The InDOS flag is a byte within the MS-DOS kernel. The value in InDOS is
  19536. incremented when MS-DOS begins execution of an Interrupt 21H and decremented
  19537. when MS-DOS's processing of that function has completed. When you increment
  19538. the byte, current versions of enhanced Windows will not switch to another
  19539. virtual machine. Therefore, to enter a critical section, you need to
  19540. increment the byte and to leave a critical section you should decrement the
  19541. InDOS flag.  %@NL@%
  19542.  
  19543. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19544. %@AU@%WARNING%@AE@%
  19545.  
  19546. You must make sure your code never decrements the InDOS flag through zero.
  19547. MS-DOS will set the InDOS flag to zero under some error conditions (for
  19548. example, the user types CTRL+C). Also, even if the InDOS flag is non-zero,
  19549. an Int 28H may cause the VM to be rescheduled.
  19550. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19551.  
  19552. For versions 3.xx and greater of Windows you will need to issue an INT 2FH
  19553. %@AB@%AX%@AE@% = 1681H to begin a critical section and %@AB@%AX%@AE@% = 1682H to end a critical
  19554. section. Note that if a program enters the critical section N times, it must
  19555. also issue the end critical section interrupt N times before the critical
  19556. section is actually released. Thus, nested begin/end critical section calls
  19557. are valid. Both of these APIs will zero the %@AB@%AL%@AE@% register to indicate that the
  19558. critical section API is supported. You should %@AI@%not%@AE@% increment and decrement
  19559. InDOS under versions of Windows that support these API calls.  %@NL@%
  19560.  
  19561. Unlike the InDOS critical section method, an INT 28H will%@AI@% not %@AE@%reschedule the
  19562. current virtual machine. The only way a task switch will occur is by
  19563. completely releasing the critical section.  %@NL@%
  19564.  
  19565. Since you need to call the Windows API or increment the InDOS flag you will
  19566. probably want to write two procedures similar to the following:  %@NL@%
  19567.  
  19568. %@AS@%  Begin_Win_Critical_Section:
  19569. %@AS@%   push ax
  19570. %@AS@%   mov ax, 1681h
  19571. %@AS@%   int 2Fh
  19572. %@AS@%   test al, al
  19573. %@AS@%   jz BCS_Quick_Exit
  19574. %@AS@%   push es
  19575. %@AS@%   les ax, [InDOS_Address]
  19576. %@AS@%   inc BYTE PTR es:[ax]
  19577. %@AS@%   pop es
  19578. %@AS@%  BCS_Quick_Exit:
  19579. %@AS@%   pop ax
  19580. %@AS@%   ret
  19581. %@AS@%  
  19582. %@AS@%  End_Win_Critical_Section:
  19583. %@AS@%   push ax
  19584. %@AS@%   mov ax, 1682h
  19585. %@AS@%   int 2Fh
  19586. %@AS@%   test al, al
  19587. %@AS@%   jz ECS_Quick_Exit
  19588. %@AS@%   push es
  19589. %@AS@%   les ax, [InDOS_Address]
  19590. %@AS@%   cmp BYTE PTR es:[ax], 0
  19591. %@AS@%   je (Error handler routine)
  19592. %@AS@%   dec BYTE PTR es:[ax]
  19593. %@AS@%   pop es
  19594. %@AS@%  ECS_Quick_Exit:
  19595. %@AS@%   pop ax
  19596. %@AS@%   ret %@AE@%
  19597.  
  19598. %@AS@%  %@AE@%
  19599.  
  19600.  
  19601.  
  19602. %@CR:GeneralIndex@%
  19603. %@1@%%@AB@%INDEX%@AE@%%@EH@%%@NL@%
  19604. %@AB@%──────────────────────────────────────────────────────────────────────────
  19605.  
  19606. %@2@%%@AB@%    A%@AE@%%@EH@%%@NL@%
  19607. ADDHDR, defined%@BO:       17bcf@%
  19608. AddInstanceItem service%@BO:       4bee4@%
  19609. AdjustInitEndPt function%@BO:       23530@%
  19610. Adjust_Execution_Time service%@BO:       6734f@%
  19611. Adjust_Exec_Priority service%@BO:       60bf8@%
  19612. Allocate_Device_CB_Area service%@BO:       28edf@%
  19613. Allocate_GDT_Selector service%@BO:       2fdf7@%
  19614. Allocate_Global_V86_Data_Area service%@BO:       29cc5@%
  19615. Allocate_LDT_Selector service%@BO:       30824@%
  19616. Allocate_PM_Call_Back service%@BO:       5d5cf@%
  19617. Allocate_Temp_V86_Data_Area service%@BO:       2bcb5@%
  19618. Allocate_V86_Call_Back service%@BO:       5d5cf@%
  19619. API translation%@BO:       964ee@%
  19620.  
  19621. %@2@%%@AB@%    B%@AE@%%@EH@%%@NL@%
  19622. BeginSelection function%@BO:       23919@%
  19623. Begin_Critical_Section service%@BO:       61895@%
  19624. Begin_Nest_Exec service%@BO:       57b24@%
  19625. Begin_Nest_V86_Exec service%@BO:       586ec@%
  19626. Begin_Reentrant_Execution service%@BO:       7f1a0@%
  19627. Begin_Use_Locked_PM_Stack service%@BO:       58b70@%
  19628. Break Point and Callback services
  19629.   Allocate_PM_Call_Back%@BO:       5d5cf@%
  19630.   Allocate_V86_Call_Back%@BO:       5d5cf@%
  19631.   Call_When_Idle%@BO:       5dd07@%
  19632.   Call_When_VM_Returns%@BO:       5e379@%
  19633.   Install_V86_Break_Point%@BO:       5ed0b@%
  19634.   Remove_V86_Break_Point%@BO:       5fa54@%
  19635. BuildDescDWORDs service%@BO:       319f1@%
  19636. Build_Int_Stack_Frame service%@BO:       528fa@%
  19637.  
  19638. %@2@%%@AB@%    C%@AE@%%@EH@%%@NL@%
  19639. Callback procedures%@BO:        fac1@%
  19640. Calling conventions, defined%@BO:       14100@%
  19641. Call_Global_Event service%@BO:       6aa5d@%
  19642. Call_Priority_VM_Event service%@BO:       6ae98@%
  19643. Call_VM_Event service%@BO:       6c204@%
  19644. Call_When_Idle service%@BO:       52df0@%%@BO:       5dd07@%%@BO:       67a21@%
  19645. Call_When_Not_Critical service%@BO:       624c1@%
  19646. Call_When_Task_Switched service%@BO:       62a34@%
  19647. Call_When_VM_Ints_Enabled service%@BO:       534c7@%
  19648. Call_When_VM_Returns service%@BO:       5e379@%
  19649. Cancel_Global_Event service%@BO:       6c66b@%
  19650. Cancel_Priority_VM_Event service%@BO:       6cc11@%
  19651. Cancel_Time_Out service%@BO:       6e834@%
  19652. Cancel_VM_Event service%@BO:       6d33b@%
  19653. CB_High_Linear service%@BO:       4e22c@%
  19654. CheckGRBVersion function%@BO:       255fd@%
  19655. Claim_Critical_Section service%@BO:       62f7e@%
  19656. ConsSelecRec function%@BO:       23b5c@%
  19657. Convert_Boolean_String service%@BO:       75bdc@%
  19658. Convert_Decimal_String service%@BO:       75fe0@%
  19659. Convert_Fixed_Point_String service%@BO:       76526@%
  19660. Convert_Hex_String service%@BO:       76ad5@%
  19661. CopyPageTable service%@BO:       363e2@%
  19662. Crash_Cur_VM service%@BO:       7e09d@%
  19663. Create_Semaphore service%@BO:       632a5@%
  19664. CursorOff function%@BO:       25824@%
  19665. CursorOn function%@BO:       259d5@%
  19666. CursorPosit function%@BO:       25b90@%
  19667.  
  19668. %@2@%%@AB@%    D%@AE@%%@EH@%%@NL@%
  19669. DCP. See Device control procedure%@BO:        bfc4@%
  19670. DDB. See Device descriptor block%@BO:        c377@%
  19671. DeAssign_Device_V86_Pages service%@BO:       2e286@%
  19672. Destroy_Semaphore service%@BO:       633ca@%
  19673. Device control procedure, defined%@BO:        bfc4@%
  19674. Device descriptor block, defined%@BO:        c377@%
  19675. Disable_Global_Trapping service%@BO:       503d0@%
  19676. Disable_Local_Trapping service%@BO:       506fa@%
  19677. Disable_VM_Ints service%@BO:       539be@%
  19678. DPMI. See DOS protected mode interface%@BO:        f1f1@%
  19679.  
  19680. %@2@%%@AB@%    E%@AE@%%@EH@%%@NL@%
  19681. Enable_Global_Trapping service%@BO:       503d0@%
  19682. Enable_Local_Trapping service%@BO:       506fa@%
  19683. Enable_VM_Ints service%@BO:       53beb@%
  19684. EndSelection function%@BO:       23d73@%
  19685. End_Critical_Section service%@BO:       63df2@%
  19686. End_Crit_And_Suspend service%@BO:       634f0@%
  19687. End_Nest_Exec service%@BO:       59092@%
  19688. End_Reentrant_Execution service%@BO:       7f662@%
  19689. End_Use_Locked_PM_Stack service%@BO:       59525@%
  19690. Error Condition services
  19691.   Crash_Cur_VM%@BO:       7e0b1@%
  19692.   Fatal_Error_Handler%@BO:       7e378@%
  19693.   Fatal_Memory_Error%@BO:       7e991@%
  19694. Event services
  19695.   Call_Global_Event%@BO:       6aa71@%
  19696.   Call_Priority_VM_Event%@BO:       6ae98@%
  19697.   Call_VM_Events%@BO:       6c218@%
  19698.   Cancel_Global_Event%@BO:       6c66b@%
  19699.   Cancel_Priority_VM_Event%@BO:       6cc11@%
  19700.   Cancel_VM_Event%@BO:       6d34f@%
  19701.   Hook_NMI_Event%@BO:       6d9b1@%
  19702.   Schedule_Global_Event%@BO:       6dc61@%
  19703.   Schedule_VM_Event%@BO:       6e001@%
  19704. Event
  19705.   defined%@BO:        ce2a@%%@BO:       6a244@%
  19706. Exec_Int service%@BO:       5986e@%
  19707. Exec_VxD_Int service%@BO:       59cb7@%
  19708.  
  19709. %@2@%%@AB@%    F%@AE@%%@EH@%%@NL@%
  19710. Fatal_Error_Handler service%@BO:       7e378@%
  19711. Fatal_Memory_Error service%@BO:       7e991@%
  19712. Free_GDT_Selector service%@BO:       32374@%
  19713. Free_LDT_Selector service%@BO:       32709@%
  19714. Free_Temp_V86_Data_Area service%@BO:       2c73b@%
  19715.  
  19716. %@2@%%@AB@%    G%@AE@%%@EH@%%@NL@%
  19717. GetAppFlatDSAlias service%@BO:       44bb2@%
  19718. GetDemandPageInfo service%@BO:       36fd0@%
  19719. GetDisplayUpd function%@BO:       25015@%
  19720. GetDOSVectors service%@BO:       77b5e@%
  19721. GetFirstV86Page service%@BO:       44869@%
  19722. GetFontList function%@BO:       25daa@%
  19723. GetFreePageCount service%@BO:       37896@%
  19724. GetNulPageHandle service%@BO:       44a7a@%
  19725. GetSetPageOutCount service%@BO:       38022@%
  19726. GetSet_HMA_Info service%@BO:       7479d@%
  19727. GetSysPageCount service%@BO:       3868b@%
  19728. GetVMPageCount service%@BO:       38983@%
  19729. Get_Config_Directory service%@BO:       76f31@%
  19730. Get_Crit_Section_Status service%@BO:       64124@%
  19731. Get_Cur_VM_Handle service%@BO:       7383b@%
  19732. Get_Device_V86_Pages_Array service%@BO:       2e960@%
  19733. Get_Environment_String service%@BO:       77237@%
  19734. Get_Execution_Focus service%@BO:       680fe@%
  19735. Get_Exec_Path service%@BO:       777c8@%
  19736. Get_Last_Updated_System_Time service%@BO:       6ed4a@%
  19737. Get_Last_Updated_VM_Exec_Time service%@BO:       6ef5f@%
  19738. Get_Machine_Info service%@BO:       77edf@%
  19739. Get_Next_Profile_String service%@BO:       783d3@%
  19740. Get_Next_VM_Handle service%@BO:       73a71@%
  19741. Get_PM_Int_Type service%@BO:       53f77@%
  19742. Get_PM_Int_Vector service%@BO:       5442b@%
  19743. Get_Profile_Boolean service%@BO:       7881a@%
  19744. Get_Profile_Decimal_Int service%@BO:       78e0f@%
  19745. Get_Profile_Fixed_Point service%@BO:       793bc@%
  19746. Get_Profile_Hex_Int service%@BO:       799e4@%
  19747. Get_Profile_String service%@BO:       7a020@%
  19748. Get_PSP_Segment service%@BO:       7a436@%
  19749. Get_System_Time service%@BO:       6f175@%
  19750. Get_Sys_VM_Handle service%@BO:       73f55@%
  19751. Get_Time_Slice_Granularity service%@BO:       68358@%
  19752. Get_Time_Slice_Info service%@BO:       685f7@%
  19753. Get_Time_Slice_Priority service%@BO:       688f2@%
  19754. Get_V86_Int_Vector service%@BO:       5442b@%
  19755. Get_VMM_Reenter_Count service%@BO:       74178@%
  19756. Get_VMM_Version service%@BO:       7456b@%
  19757. Get_VM_Exec_Time service%@BO:       6f49e@%
  19758. Global descriptor table, defined%@BO:       2fd83@%
  19759. Grabber DLL functions
  19760.   AdjustInitEndPt%@BO:       23544@%
  19761.   BeginSelection%@BO:       2392d@%
  19762.   CheckGRBVersion%@BO:       25611@%
  19763.   ConsSelecRec%@BO:       23b70@%
  19764.   CursorOff%@BO:       25824@%
  19765.   CursorOn%@BO:       259d5@%
  19766.   CursorPosit%@BO:       25b90@%
  19767.   EndSelection%@BO:       23d87@%
  19768.   GetDisplayUpd%@BO:       25029@%
  19769.   GetFontList%@BO:       25daa@%
  19770.   GrabComplete%@BO:       25f92@%
  19771.   GrabEvent%@BO:       262aa@%
  19772.   GrbUnLockApp%@BO:       265c0@%
  19773.   InitGrabber%@BO:       2676f@%
  19774.   InvertSelection%@BO:       23f1d@%
  19775.   KeySelection%@BO:       24105@%
  19776.   MakeSelctRect%@BO:       24740@%
  19777.   PaintScreen%@BO:       269be@%
  19778.   RenderSelection%@BO:       24c1f@%
  19779.   ScreenFree%@BO:       26d11@%
  19780.   SetPaintFnt%@BO:       26efa@%
  19781.   UpdateScreen%@BO:       2750d@%
  19782. Grabber%@BO:       227fa@%
  19783. GrabComplete function%@BO:       25f7e@%
  19784. GrabEvent function%@BO:       262aa@%
  19785. GrbUnLockApp function%@BO:       265ac@%
  19786.  
  19787. %@2@%%@AB@%    H%@AE@%%@EH@%%@NL@%
  19788. Hardware interrupt hooks%@BO:       10129@%
  19789. HeapAllocate service%@BO:       342b0@%
  19790. HeapFree service%@BO:       34995@%
  19791. HeapGetSize service%@BO:       34cac@%
  19792. HeapReAllocate service%@BO:       34fcc@%
  19793. Hook_Device_Service service%@BO:       7f8af@%
  19794. Hook_Device_V86_API service%@BO:       8034c@%
  19795. Hook_NMI_Event service%@BO:       6d99d@%
  19796. Hook_PM_Device_API service%@BO:       8034c@%
  19797. Hook_V86_Int_Chain service%@BO:       54b13@%
  19798. Hook_V86_Page service%@BO:       2f294@%
  19799.  
  19800. %@2@%%@AB@%    I%@AE@%%@EH@%%@NL@%
  19801. I/O port traps%@BO:        fdf0@%
  19802. I/O services and macros
  19803.   Disable_Global_Trapping%@BO:       503d0@%
  19804.   Disable_Local_Trapping%@BO:       506fa@%
  19805.   Enable_Global_Trapping%@BO:       503d0@%
  19806.   Enable_Local_Trapping%@BO:       506fa@%
  19807.   Install_IO_Handler%@BO:       509b8@%
  19808.   Install_Mult_IO_Handlers%@BO:       50f2e@%
  19809.   Simulate_IO%@BO:       51442@%
  19810. IDT. See Interrupt descriptor table%@BO:        de08@%
  19811. Information services
  19812.   GetSet_HMA_Info%@BO:       747b1@%
  19813.   Get_Cur_VM_Handle%@BO:       7383b@%
  19814.   Get_Next_VM_Handle%@BO:       73a71@%
  19815.   Get_Sys_VM_Handle%@BO:       73f55@%
  19816.   Get_VMM_Reenter_Count%@BO:       74178@%
  19817.   Get_VMM_Version%@BO:       7457f@%
  19818.   Test_Cur_VM_Handle%@BO:       74cb5@%
  19819.   Test_Debug_Installed%@BO:       74f3f@%
  19820.   Test_Sys_VM_Handle%@BO:       7518c@%
  19821.   Validate_VM_Handle%@BO:       7541b@%
  19822. InitGrabber function%@BO:       2676f@%
  19823. Initialization Information services
  19824.   Convert_Boolean_String%@BO:       75bdc@%
  19825.   Convert_Decimal_String%@BO:       75fe0@%
  19826.   Convert_Fixed_Point_String%@BO:       76526@%
  19827.   Convert_Hex_String%@BO:       76ad5@%
  19828.   GetDOSVectors%@BO:       77b4a@%
  19829.   Get_Config_Directory%@BO:       76f31@%
  19830.   Get_Environment_String%@BO:       77237@%
  19831.   Get_Exec_Path%@BO:       777c8@%
  19832.   Get_Machine_Info%@BO:       77edf@%
  19833.   Get_Next_Profile_String%@BO:       783d3@%
  19834.   Get_Profile_Boolean%@BO:       7881a@%
  19835.   Get_Profile_Decimal_Int%@BO:       78e0f@%
  19836.   Get_Profile_Fixed_Point%@BO:       793bc@%
  19837.   Get_Profile_Hex_Int%@BO:       799e4@%
  19838.   Get_Profile_String%@BO:       7a020@%
  19839.   Get_PSP_Segment%@BO:       7a436@%
  19840.   OpenFile%@BO:       7a7a1@%
  19841. Install_IO_Handler service%@BO:       509b8@%
  19842. Install_Mult_IO_Handlers service%@BO:       50f2e@%
  19843. Install_V86_Break_Point service%@BO:       5ed0b@%
  19844. INT 2FH%@BO:        cc14@%%@BO:       15c12@%
  19845. Interrupt descriptor table
  19846.   In protected mode%@BO:        de08@%
  19847. Interrupt request%@BO:       1029e@%
  19848. InvertSelection function%@BO:       23f09@%
  19849. IRQ. See Interrupt Request%@BO:       1029e@%
  19850.  
  19851. %@2@%%@AB@%    K%@AE@%%@EH@%%@NL@%
  19852. KeySelection function%@BO:       240f1@%
  19853.  
  19854. %@2@%%@AB@%    L%@AE@%%@EH@%%@NL@%
  19855. LDT. See Local descriptor table%@BO:       2fd83@%
  19856. Link386, defined%@BO:       16f12@%
  19857. Linked List services
  19858.   List_Allocate%@BO:       7aff8@%
  19859.   List_Attach%@BO:       7b3b8@%
  19860.   List_Attach_Tail%@BO:       7b6f3@%
  19861.   List_Create%@BO:       7ba66@%
  19862.   List_Deallocate%@BO:       7c58d@%
  19863.   List_Destroy%@BO:       7c854@%
  19864.   List_Get_First%@BO:       7cada@%
  19865.   List_Get_Next%@BO:       7cd85@%
  19866.   List_Insert%@BO:       7d24c@%
  19867.   List_Remove%@BO:       7d6dd@%
  19868.   List_Remove_First%@BO:       7d9fc@%
  19869. LinMapIntoV86 service%@BO:       45ff4@%
  19870. LinPageLock service%@BO:       4776c@%
  19871. LinPageUnLock service%@BO:       47ec0@%
  19872. List_Allocate service%@BO:       7afe4@%
  19873. List_Attach service%@BO:       7b3a4@%
  19874. List_Attach_Tail service%@BO:       7b6f3@%
  19875. List_Create service%@BO:       7ba52@%
  19876. List_Deallocate service%@BO:       7c579@%
  19877. List_Destroy service%@BO:       7c840@%
  19878. List_Get_First service%@BO:       7cac6@%
  19879. List_Get_Next service%@BO:       7cd71@%
  19880. List_Insert service%@BO:       7d238@%
  19881. List_Remove service%@BO:       7d6c9@%
  19882. List_Remove_First service%@BO:       7d9fc@%
  19883. Local descriptor table, defined%@BO:       2fd83@%
  19884.  
  19885. %@2@%%@AB@%    M%@AE@%%@EH@%%@NL@%
  19886. MakeSelctRect function%@BO:       2472c@%
  19887. MapIntoV86 service%@BO:       38e97@%
  19888. MapPhysToLinear service%@BO:       43f18@%
  19889. MAPSYM32, defined%@BO:       17d77@%
  19890. Map_Flat service%@BO:       80970@%
  19891. MASM5, defined%@BO:       16ba4@%
  19892. Memory Management services
  19893.   Data Access services
  19894.     GetAppFlatDSAlias%@BO:       44bb2@%
  19895.     GetFirstV86Page%@BO:       44869@%
  19896. Memory management services
  19897.   Data Access services
  19898.     GetNulPageHandle%@BO:       44a7a@%
  19899. Memory Management services
  19900.   Device V86 Page Management services
  19901.     Assign_Device_V86_Pages%@BO:       2dac4@%
  19902.     DeAssign_Device_V86_Pages%@BO:       2e286@%
  19903.     Get_Device_V86_Pages_Array%@BO:       2e960@%
  19904.     Hook_V86_Page%@BO:       2f294@%
  19905.   GDT/LDT Management services
  19906.     Allocate_GDT_Selector%@BO:       2fdf7@%
  19907.     Allocate_LDT_Selector%@BO:       30824@%
  19908.     BuildDescDWORDs%@BO:       319f1@%
  19909.     Free_GDT_Selector%@BO:       32374@%
  19910.     Free_LDT_Selector%@BO:       32709@%
  19911.   Instance Data Management services
  19912.     AddInstanceItem%@BO:       4bee4@%
  19913.     MMGR_Toggle_HMA%@BO:       4cff1@%
  19914.   Physical Device Memory in PM services
  19915.     MapPhysToLinear%@BO:       43f18@%
  19916.   Special services for PM APIs
  19917.     LinMapIntoV86%@BO:       45ff4@%
  19918.     LinPageLock%@BO:       4776c@%
  19919.     LinPageUnLock%@BO:       47ec0@%
  19920.     PageCheckLinRange%@BO:       487de@%
  19921.     SelectorMapFlat%@BO:       496d4@%
  19922.   System Data Object Management services
  19923.     Allocate_Device_CB_Area%@BO:       28edf@%
  19924.     Allocate_Global_V86_Data_Area%@BO:       29cc5@%
  19925.     Allocate_Temp_V86_Data_Area%@BO:       2bcb5@%
  19926.     Free_Temp_V86_Data_Area%@BO:       2c73b@%
  19927.   System Heap Allocator services
  19928.     HeapAllocate%@BO:       342b0@%
  19929.     HeapFree%@BO:       34995@%
  19930.     HeapGetSize%@BO:       34cac@%
  19931.     HeapReAllocate%@BO:       34fcc@%
  19932.   System Page Allocator services
  19933.     CopyPageTable%@BO:       363e2@%
  19934.     GetDemandPageInfo%@BO:       36fd0@%
  19935.     GetFreePageCount%@BO:       37896@%
  19936.     GetSetPageOutCount%@BO:       38022@%
  19937.     GetSysPageCount%@BO:       3868b@%
  19938.     GetVMPageCount%@BO:       38983@%
  19939.     MapIntoV86%@BO:       38e97@%
  19940.     ModifyPageBits%@BO:       3a7a5@%
  19941.     PageAllocate%@BO:       3b570@%
  19942.     PageFree%@BO:       3d91f@%
  19943.     PageGetAllocInfo%@BO:       3df18@%
  19944.     PageGetSizeAddr%@BO:       3e79e@%
  19945.     PageLock%@BO:       3ec7f@%
  19946.     PageOutDirtyPages%@BO:       3f883@%
  19947.     PageReAllocate%@BO:       4047b@%
  19948.     PageUnLock%@BO:       41741@%
  19949.     PhysIntoV86%@BO:       42347@%
  19950.     TestGlobalV86Mem%@BO:       42f20@%
  19951.   V86 Address Space services
  19952.     CB_High_Linear%@BO:       4e22c@%
  19953. Memory management, V86 mode
  19954.   API translation%@BO:       964ee@%
  19955. Memory management
  19956.    defined%@BO:       951b5@%
  19957. Message mode, defined%@BO:       1e6f8@%
  19958. Miscellaneous services
  19959.   Begin_Reentrant_Execution%@BO:       7f1a0@%
  19960.   End_Reentrant_Execution%@BO:       7f662@%
  19961.   Hook_Device_Service%@BO:       7f8af@%
  19962.   Hook_Device_V86_API%@BO:       8034c@%
  19963.   Hook_PM_Device_API%@BO:       8034c@%
  19964.   Map_Flat%@BO:       80984@%
  19965.   MMGR_SetNULPageAddr%@BO:       81604@%
  19966.   Set_System_Exit_code%@BO:       8190e@%
  19967.   Simulate_Pop%@BO:       81cc7@%
  19968.   Simulate_Push%@BO:       81f44@%
  19969.   System_Control%@BO:       821d7@%
  19970. MMGR_SetNULPageAddr service%@BO:       81604@%
  19971. MMGR_Toggle_HMA service%@BO:       4cff1@%
  19972. Mode
  19973.   Protected%@BO:        ade5@%%@BO:        f1f1@%
  19974.   Real%@BO:       18309@%%@BO:       aa1e3@%
  19975.   Virtual-86%@BO:        acd8@%%@BO:        f1f1@%
  19976. ModifyPageBits service%@BO:       3a7a5@%
  19977.  
  19978. %@2@%%@AB@%    N%@AE@%%@EH@%%@NL@%
  19979. Nested Execution services
  19980.   Begin_Nest_Exec%@BO:       57b24@%
  19981.   Begin_Nest_V86_Exec%@BO:       586ec@%
  19982.   Begin_Use_Locked_PM_Stack%@BO:       58b70@%
  19983.   End_Nest_Exec%@BO:       590a6@%
  19984.   End_Use_Locked_PM_Stack%@BO:       59525@%
  19985.   Exec_Int%@BO:       59882@%
  19986.   Exec_VxD_Int%@BO:       59ccb@%
  19987.   Restore_Client_State%@BO:       5ae0a@%
  19988.   Resume_Exec%@BO:       5b3f0@%
  19989.   Save_Client_State%@BO:       5bfed@%
  19990.   Set_PM_Exec_Mode%@BO:       5ca00@%
  19991.   Set_V86_Exec_Mode%@BO:       5ce5d@%
  19992. No_Fail_Resume_VM service%@BO:       6453b@%
  19993. Nuke_VM service%@BO:       648e9@%
  19994.  
  19995. %@2@%%@AB@%    O%@AE@%%@EH@%%@NL@%
  19996. OpenFile service%@BO:       7a7b5@%
  19997.  
  19998. %@2@%%@AB@%    P%@AE@%%@EH@%%@NL@%
  19999. PageAllocate service%@BO:       3b570@%
  20000. PageCheckLinRange service%@BO:       487de@%
  20001. PageFree service%@BO:       3d91f@%
  20002. PageGetAllocInfo service%@BO:       3df18@%
  20003. PageGetSizeAddr service%@BO:       3e79e@%
  20004. PageLock service%@BO:       3ec7f@%
  20005. PageOutDirtyPages service%@BO:       3f883@%
  20006. PageReAllocate service%@BO:       4047b@%
  20007. PageUnLock service%@BO:       41741@%
  20008. PaintScreen function%@BO:       269be@%
  20009. PhysIntoV86 service%@BO:       42347@%
  20010. PM. See Protected mode%@BO:        9ea7@%
  20011. Primary Scheduler services
  20012.   Adjust_Exec_Priority%@BO:       60bf8@%
  20013.   Begin_Critical_Section%@BO:       61895@%
  20014.   Call_When_Not_Critical%@BO:       624c1@%
  20015.   Call_When_Task_Switched%@BO:       62a34@%
  20016.   Claim_Critical_Section%@BO:       62f7e@%
  20017.   Create_Semaphore%@BO:       632a5@%
  20018.   Destroy_Semaphore%@BO:       633ca@%
  20019.   End_Critical_Section%@BO:       63df2@%
  20020.   End_Crit_And_Suspend%@BO:       634f0@%
  20021.   Get_Crit_Section_Status%@BO:       64124@%
  20022.   No_Fail_Resume_VM%@BO:       6454f@%
  20023.   Nuke_VM%@BO:       648fd@%
  20024.   Release_Critical_Section%@BO:       64c8e@%
  20025.   Resume_VM%@BO:       64f35@%
  20026.   Signal_Semaphore%@BO:       653ac@%
  20027.   Suspend_VM%@BO:       654e5@%
  20028.   Wait_Semaphore%@BO:       65c2c@%
  20029. Privilege rings%@BO:        f011@%
  20030. Processor Fault and Interrupt services
  20031.   Get_Fault_Hook_Addrs%@BO:       70d86@%
  20032.   Get_NMI_Handler_Addr%@BO:       71164@%
  20033.   Hook_NMI_Event%@BO:       71aba@%
  20034.   Hook_PM_Fault%@BO:       71dc6@%
  20035.   Hook_V86_Fault%@BO:       71dc6@%
  20036.   Hook_V86_Page%@BO:       72948@%
  20037.   Hook_VMM_Fault%@BO:       71dc6@%
  20038.   Set_NMI_Handler_Addr%@BO:       731b7@%
  20039. Protected mode
  20040.   defined%@BO:        e9d5@%%@BO:       aa9e7@%
  20041.   Initialization%@BO:       19c75@%
  20042.   Interrupt descriptor table%@BO:        de08@%
  20043.  
  20044. %@2@%%@AB@%    R%@AE@%%@EH@%%@NL@%
  20045. Real mode
  20046.   defined%@BO:       aa73f@%
  20047.   initialization%@BO:       18309@%
  20048. Release_Critical_Section service%@BO:       64c8e@%
  20049. Release_Time_Slice service%@BO:       68daf@%
  20050. Remove_V86_Break_Point service%@BO:       5fa54@%
  20051. RenderSelection function%@BO:       24c0b@%
  20052. Restore_Client_State service%@BO:       5ae0a@%
  20053. Resume_Exec service%@BO:       5b3dc@%
  20054. Resume_VM service%@BO:       64f21@%
  20055.  
  20056. %@2@%%@AB@%    S%@AE@%%@EH@%%@NL@%
  20057. Save_Client_State service%@BO:       5bfed@%
  20058. Schedule_Global_Event service%@BO:       6dc61@%
  20059. Schedule_VM_Event service%@BO:       6dfed@%
  20060. Scheduling
  20061.   defined%@BO:       600e0@%%@BO:       606ef@%
  20062.   Enhanced Windows execution%@BO:        cd21@%
  20063.   Primary scheduler%@BO:        d51a@%%@BO:        d708@%
  20064.   Time-slice scheduler%@BO:        d51a@%
  20065. ScreenFree function%@BO:       26d11@%
  20066. SelectorMapFlat service%@BO:       496d4@%
  20067. Services, defined%@BO:        f34f@%
  20068. SetPaintFnt function%@BO:       26efa@%
  20069. Set_Execution_Focus service%@BO:       691ff@%
  20070. Set_Global_Time_Out service%@BO:       6f829@%
  20071. Set_PM_Exec_Mode service%@BO:       5ca00@%
  20072. Set_PM_Int_Type service%@BO:       5578a@%
  20073. Set_PM_Int_Vector service%@BO:       55c52@%
  20074. Set_System_Exit_code service%@BO:       8190e@%
  20075. Set_Time_Slice_Granularity service%@BO:       695f3@%
  20076. Set_Time_Slice_Priority service%@BO:       69922@%
  20077. Set_V86_Exec_Mode service%@BO:       5ce5d@%
  20078. Set_V86_Int_Vector service%@BO:       55c52@%
  20079. Set_VM_Time_Out service%@BO:       6fe99@%
  20080. Shell services
  20081.   SHELL_Event%@BO:       82fac@%
  20082.   SHELL_Get_Version%@BO:       83589@%
  20083.   SHELL_Message%@BO:       8379b@%
  20084.   SHELL_Resolve_Contention%@BO:       83d4b@%
  20085. Shell, defined%@BO:        b971@%
  20086. Signal_Semaphore service%@BO:       653ac@%
  20087. Simulate_Far_Call service%@BO:       560e1@%
  20088. Simulate_Far_Jmp service%@BO:       5651a@%
  20089. Simulate_Far_Ret service%@BO:       567d9@%
  20090. Simulate_Far_Ret_N service%@BO:       56a68@%
  20091. Simulate_Int service%@BO:       56d67@%
  20092. Simulate_IO service%@BO:       51442@%
  20093. Simulate_Iret service%@BO:       57415@%
  20094. Simulate_Pop service%@BO:       81cb3@%
  20095. Simulate_Push service%@BO:       81f30@%
  20096. Software interrupt hooks%@BO:       1029e@%
  20097. Suspend_VM service%@BO:       654d1@%
  20098. System_Controls service%@BO:       821c3@%
  20099.  
  20100. %@2@%%@AB@%    T%@AE@%%@EH@%%@NL@%
  20101. TestGlobalV86Mem service%@BO:       42f20@%
  20102. Test_Cur_VM_Handle service%@BO:       74cb5@%
  20103. Test_Debug_Installed service%@BO:       74f3f@%
  20104. Test_Sys_VM_Handle service%@BO:       7518c@%
  20105. Time-Slice Scheduler services
  20106.   Adjust_Execution_Time%@BO:       6734f@%
  20107.   Call_When_Idle%@BO:       67a21@%
  20108.   Get_Execution_Focus%@BO:       680fe@%
  20109.   Get_Time_Slice_Granularity%@BO:       68358@%
  20110.   Get_Time_Slice_Info%@BO:       685f7@%
  20111.   Get_Time_Slice_Priority%@BO:       688f2@%
  20112.   Release_Time_Slice%@BO:       68daf@%
  20113.   Set_Execution_Focus%@BO:       691ff@%
  20114.   Set_Time_Slice_Granularity%@BO:       695f3@%
  20115.   Set_Time_Slice_Priority%@BO:       69922@%
  20116.   Wake_Up_VM%@BO:       69e3d@%
  20117. Timing services
  20118.   Cancel_Time_Out%@BO:       6e848@%
  20119.   Get_Last_Updated_System_Time%@BO:       6ed4a@%
  20120.   Get_Last_Updated_VM_Exec_Time%@BO:       6ef5f@%
  20121.   Get_System_Time%@BO:       6f189@%
  20122.   Get_VM_Exec_Time%@BO:       6f4b2@%
  20123.   Set_Global_Time_Out%@BO:       6f829@%
  20124.   Set_VM_Time_Out%@BO:       6fead@%
  20125.   Update_System_Clock%@BO:       7063b@%
  20126.  
  20127. %@2@%%@AB@%    U%@AE@%%@EH@%%@NL@%
  20128. UpdateScreen function%@BO:       274f9@%
  20129. Update_System_Clock service%@BO:       7063b@%
  20130.  
  20131. %@2@%%@AB@%    V%@AE@%%@EH@%%@NL@%
  20132. V86 Mode Memory Manager Device services
  20133.   V86MMGR_Allocate_Buffer%@BO:       9cf13@%
  20134.   V86MMGR_Allocate_V86_Pages%@BO:       95420@%
  20135.   V86MMGR_Free_Buffer%@BO:       9d56c@%
  20136.   V86MMGR_Free_Page_Map_Region%@BO:       9ebcd@%
  20137.   V86MMGR_Get_EMS_XMS_Limits%@BO:       95e83@%
  20138.   V86MMGR_Get_Mapping_Info%@BO:       9e61f@%
  20139.   V86MMGR_Get_Version%@BO:       9520b@%
  20140.   V86MMGR_Get_VM_Flat_Sel%@BO:       9e224@%
  20141.   V86MMGR_Get_Xlat_Buff_State%@BO:       9d990@%
  20142.   V86MMGR_Load_Client_Ptr%@BO:       9c965@%
  20143.   V86MMGR_Map_Pages%@BO:       9e84b@%
  20144.   V86MMGR_Set_EMS_XMS_Limits%@BO:       959ed@%
  20145.   V86MMGR_Set_Mapping_Info%@BO:       999a6@%
  20146.   V86MMGR_Set_Xlat_Buff_State%@BO:       9ddf6@%
  20147.   V86MMGR_Xlat_API%@BO:       9a016@%
  20148. V86. See Virtual-86 mode%@BO:        9ea7@%
  20149. V86MMGR services. See V86 Mode Memory Manager Device services%@BO:       94b08@%
  20150. Validate_VM_Handle service%@BO:       7541b@%
  20151. VDD services. See Virtual Display Device services%@BO:       84524@%
  20152. VDMAD services. See Virtual DMA Device services%@BO:       9f136@%
  20153. VDMAD_Request_Buffer service%@BO:       a26e3@%%@BO:       a2a0e@%
  20154. Virtual device
  20155.   API procedure%@BO:        c377@%%@BO:       1350f@%
  20156.   API%@BO:       15a2e@%
  20157.   Building%@BO:       163c5@%
  20158.   Declaration%@BO:       12781@%
  20159.   defined%@BO:        a188@%%@BO:        b971@%
  20160.   Device control procedure name%@BO:       1350f@%
  20161.   Device control procedure%@BO:        bfc4@%
  20162.   Device descriptor block%@BO:        c377@%
  20163.   ID%@BO:       1350f@%
  20164.   IDS%@BO:        c95b@%
  20165.   Initialization order%@BO:        c95b@%
  20166.   Initialization%@BO:       1350f@%%@BO:       18166@%
  20167.   Installing%@BO:       17fd6@%
  20168.   Memory model%@BO:       11b28@%
  20169.   Segmentation%@BO:       12054@%
  20170.   Service table%@BO:       1350f@%
  20171.   Services%@BO:       13fb4@%
  20172.   Version%@BO:       1350f@%
  20173.   Writing strategy%@BO:       1150e@%
  20174. Virtual Display Device services
  20175.   VDD_Get_GrabRtn%@BO:       85edb@%
  20176.   VDD_Get_ModTime%@BO:       861e6@%
  20177.   VDD_Get_Version%@BO:       86441@%
  20178.   VDD_Hide_Cursor%@BO:       8668d@%
  20179.   VDD_Msg_BakColor%@BO:       850e9@%
  20180.   VDD_Msg_ClrScrn%@BO:       85322@%
  20181.   VDD_Msg_ForColor%@BO:       8567e@%
  20182.   VDD_Msg_SetCursPos%@BO:       858b7@%
  20183.   VDD_Msg_TextOut%@BO:       85ad5@%
  20184.   VDD_PIF_State%@BO:       869d0@%
  20185.   VDD_Query_Access%@BO:       86bc4@%
  20186.   VDD_Set_HCurTrk%@BO:       86f1f@%
  20187.   VDD_Set_VMType%@BO:       871a5@%%@BO:       87599@%
  20188. Virtual DMA Device services
  20189.   VDMAD_Copy_From_Buffer%@BO:       9f794@%
  20190.   VDMAD_Copy_To_Buffer%@BO:       9fb89@%
  20191.   VDMAD_Default_Handler%@BO:       9ff5e@%
  20192.   VDMAD_Disable_Translation%@BO:       a02fd@%
  20193.   VDMAD_Enable_Translation%@BO:       a069f@%
  20194.   VDMAD_Get_EISA_Adr_Mode%@BO:       a09d1@%
  20195.   VDMAD_Get_Region_Info%@BO:       a0d86@%
  20196.   VDMAD_Get_Version%@BO:       a1128@%
  20197.   VDMAD_Get_Virt_State%@BO:       a13d7@%
  20198.   VDMAD_Lock_DMA_Region%@BO:       a1a16@%
  20199.   VDMAD_Mask_Channel%@BO:       a24e9@%
  20200.   VDMAD_Release_Buffer%@BO:       a26e3@%
  20201.   VDMAD_Request_Buffer%@BO:       a2a0e@%
  20202.   VDMAD_Reserve_Buffer_Space%@BO:       a2d49@%
  20203.   VDMAD_Scatter_Lock%@BO:       a321c@%
  20204.   VDMAD_Scatter_Unlock%@BO:       a3762@%
  20205.   VDMAD_Set_EISA_Adr_Mode%@BO:       a3c23@%
  20206.   VDMAD_Set_Phys_State%@BO:       a3ed2@%
  20207.   VDMAD_Set_Region_Info%@BO:       a41c8@%
  20208.   VDMAD_Set_Virt_State%@BO:       a44b6@%
  20209.   VDMAD_Unlock_DMA_Region%@BO:       a49eb@%
  20210.   VDMAD_UnMask_Channel%@BO:       a4ce8@%
  20211.   VDMAD_Virtualize_Channel%@BO:       a4eed@%
  20212. Virtual DOSNET device services
  20213.   DOSNET_Do_PSP_Adjust%@BO:       a5965@%
  20214.   DOSNET_Get_Version%@BO:       a574f@%
  20215.   DOSNET_Send_FILESYSCHANGE%@BO:       a6301@%
  20216. Virtual Keyboard Device services
  20217.   VKD_Cancel_Hot_Key_State%@BO:       87d2a@%
  20218.   VKD_Cancel_Paste%@BO:       87f19@%
  20219.   VKD_Define_Hot_Key%@BO:       8810e@%
  20220.   VKD_Define_Paste_Mode%@BO:       88f54@%
  20221.   VKD_Flush_Msg_Key_Queue%@BO:       89367@%
  20222.   VKD_Force_Keys%@BO:       89573@%
  20223.   VKD_Get_Kbd_Owner%@BO:       8987e@%
  20224.   VKD_Get_Msg_Key%@BO:       89a74@%
  20225.   VKD_Get_Version%@BO:       89dd3@%
  20226.   VKD_Local_Disable_Hot_Key%@BO:       89fc9@%
  20227.   VKD_Local_Enable_Hot_Key%@BO:       8a217@%
  20228.   VKD_Peek_Msg_Key%@BO:       8a463@%
  20229.   VKD_Reflect_Hot_Key%@BO:       8a7ab@%
  20230.   VKD_Remove_Hot_Key%@BO:       8abd8@%
  20231.   VKD_Start_Paste%@BO:       8adb9@%
  20232. Virtual machine manager, defined%@BO:        a009@%%@BO:        b408@%
  20233. Virtual machine
  20234.   Client Register structure%@BO:        a9b5@%%@BO:        b24c@%
  20235.   defined%@BO:        9ea7@%%@BO:        a7a9@%
  20236.   Events%@BO:        cf3b@%
  20237.   Initialization%@BO:       1a4b0@%
  20238.   Loading sequence%@BO:       103cb@%
  20239.   Privilege rings%@BO:        abfc@%
  20240.   Scheduling%@BO:        d319@%
  20241.   States%@BO:       1a3d8@%
  20242.   Termination%@BO:       1b691@%
  20243.   VM handle%@BO:        b0f0@%
  20244. Virtual PIC Device services
  20245.   VID_EOI_Proc%@BO:       8d140@%
  20246.   VID_Hw_Int_Proc%@BO:       8cb43@%
  20247.   VID_IRET_Proc%@BO:       8da51@%
  20248.   VID_Mask_Change_Proc%@BO:       8e485@%
  20249.   VID_Virt_Int_Proc%@BO:       8d62a@%
  20250.   VPICD_Call_When_Hw_Int%@BO:       8e81b@%
  20251.   VPICD_Clear_Int_Request%@BO:       8eee3@%
  20252.   VPICD_Convert_Handle_To_IRQ%@BO:       8f22e@%
  20253.   VPICD_Convert_Int_To_IRQ%@BO:       8f44d@%
  20254.   VPICD_Convert_IRQ_To_Int%@BO:       8f7b8@%
  20255.   VPICD_Get_Complete_Status%@BO:       8fb18@%
  20256.   VPICD_Get_IRQ_Complete_Status%@BO:       8fc16@%
  20257.   VPICD_Get_Status%@BO:       9006f@%
  20258.   VPICD_Get_Version%@BO:       9066f@%
  20259.   VPICD_Physically_Mask%@BO:       90ca9@%
  20260.   VPICD_Physically_Unmask%@BO:       90f1f@%
  20261.   VPICD_Phys_EOI%@BO:       90981@%
  20262.   VPICD_Set_Auto_Masking%@BO:       9119d@%
  20263.   VPICD_Set_Int_Request%@BO:       91506@%
  20264.   VPICD_Test_Phys_Request%@BO:       91c64@%
  20265.   VPICD_Virtualize_IRQ%@BO:       91ea4@%
  20266. Virtual PIC Device
  20267.   defined%@BO:       1029e@%
  20268. Virtual Sound Device services
  20269.   VSD_Bell%@BO:       92713@%
  20270.   VSD_Get_Version%@BO:       9299b@%
  20271. Virtual Timer Device services
  20272.   VTD_Begin_Min_Int_Period%@BO:       92eba@%
  20273.   VTD_Disable_Trapping%@BO:       9359e@%
  20274.   VTD_Enable_Trapping%@BO:       93bec@%
  20275.   VTD_End_Min_Int_Period%@BO:       93ebd@%
  20276.   VTD_Get_Interupt_Period%@BO:       94243@%
  20277.   VTD_Get_Version%@BO:       9443f@%
  20278.   VTD_Update_System_Clock%@BO:       94725@%
  20279. Virtual-86 mode, defined%@BO:        e9d5@%%@BO:       aac5e@%
  20280. VKD services. See Virtual Keyboard Device services%@BO:       87950@%
  20281. VM Interrupt and Call services
  20282.   Build_Int_Stack_Frame%@BO:       528fa@%
  20283.   Call_When_Idle%@BO:       52df0@%
  20284.   Call_When_VM_Ints_Enabled%@BO:       534c7@%
  20285.   Disable_VM_Ints%@BO:       539be@%
  20286.   Enable_VM_Ints%@BO:       53beb@%
  20287.   Get_PM_Int_Type%@BO:       53f8b@%
  20288.   Get_PM_Int_Vector%@BO:       5442b@%
  20289.   Get_V86_Int_Vector%@BO:       5442b@%
  20290.   Hook_V86_Int_Chain%@BO:       54a46@%
  20291.   Set_PM_Int_Type%@BO:       5578a@%
  20292.   Set_PM_Int_Vector%@BO:       55c52@%
  20293.   Set_V86_Int_Vector%@BO:       55c52@%
  20294.   Simulate_Far_Call%@BO:       560e1@%
  20295.   Simulate_Far_Jmp%@BO:       5651a@%
  20296.   Simulate_Far_Ret%@BO:       567d9@%
  20297.   Simulate_Far_Ret_N%@BO:       56a68@%
  20298.   Simulate_Int%@BO:       56d7b@%
  20299.   Simulate_Iret%@BO:       57415@%
  20300. VM. See Virtual machine%@BO:        9ea7@%
  20301. VMM. See Virtual machine manager%@BO:        a009@%
  20302. VPICD services. See Virtual PIC Device services%@BO:       8b941@%
  20303. VSD services. See Virtual Sound Device services%@BO:       925fc@%
  20304. VTD services. See Virtual Timer Device services%@BO:       92c76@%
  20305. VxD. See Virtual device%@BO:        a188@%
  20306.  
  20307. %@2@%%@AB@%    W%@AE@%%@EH@%%@NL@%
  20308. Wait_Semaphore service%@BO:       65c2c@%
  20309. Wake_Up_VM service%@BO:       69e3d@%
  20310. WINOLDAP%@BO:       15a2e@%%@BO:       227fa@%
  20311.  
  20312.