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 @%Topic                                   Reference%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%Intel(R) 80386 and 80486 architecture   Introduction to the 80386, Intel                                         Literature Sales P.O. Box 58130 Santa                                         Clara, CA 95052-8130 Order Number:                                         231252-001 ISBN 0-917017-38-2                                        i486(tm) Microprocessor Programmer's                                         Reference Manual, Intel Literature                                         Sales P.O. Box 58130 Santa Clara, CA                                         95052-8130 Order Number: 240486-001                                         ISBN 1-5512-101-2MS-DOS(R)                               Duncan, Ray. %@AI@%Advanced MS-DOS%@AE@%.                                         Microsoft Press, P.O. Box 97017,                                         Redmond WA. 98073-9717. ISBN Number:                                         0-914845-77-2                                        %@AI@%MS-DOS Encyclopedia%@AE@%. Microsoft Press,                                         P.O. Box 97017, Redmond WA. 98073-9717.                                        ISBN Number: 1-5565-174-8Microsoft Windows 3.0 (especially the   %@AI@%Microsoft Windows Software Development%@AE@%Memory Management topics)               %@AI@%Kit%@AE@%, %@AI@%Programming Topics%@AE@%%@TE:  25  1549 02 40 40 @%
  653.  
  654. To obtain the DOS Protected Mode Interface (DPMI) specification, contact
  655. Intel at 1-800-548-4725. For the Virtual DMA Services (VDS) specification,
  656. submit a service request via Microsoft OnLine.  %@NL@%
  657.  
  658.  
  659. %@2@%%@CR:C6A00000002 @%%@AB@%Organization of This Document%@AE@%%@EH@%%@NL@%
  660.  
  661. This document is divided into the following parts and chapters:  %@NL@%
  662.  
  663. Part 3, "Writing Virtual Devices," describes the requirements of a virtual
  664. device and the environment of Windows when running in 386 enhanced mode. It
  665. contains the following chapters:  %@NL@%
  666.  
  667.  
  668.   ■   Chapter 16, "Overview of Windows in 386 Enhanced Mode," which provides
  669.       the conceptual foundation of the Windows virtual machine environment.%@NL@%
  670.  
  671.   ■   Chapter 17, "Virtual Device Programming Topics," which provides a more
  672.       in-depth look at various programming topics.%@NL@%
  673.  
  674.   ■   Chapter 18, "The VDD and Grabber DLL," which describes the development
  675.       of a Virtual Display Driver (VDD) and the dynamic-link library (DLL)
  676.       needed to support a video adapter.%@NL@%
  677.  
  678.  
  679. Part 4, "Virtual Device Services," provides detailed descriptions of all the
  680. available services. It consists of the following 24 chapters:  %@NL@%
  681.  
  682.  
  683.   ■   Chapter 19, "Memory Management Services"%@NL@%
  684.  
  685.   ■   Chapter 20, "I/O Services and Macros"%@NL@%
  686.  
  687.   ■   Chapter 21, "VM Interrupt and Call Services"%@NL@%
  688.  
  689.   ■   Chapter 22, "Nested Execution Services"%@NL@%
  690.  
  691.   ■   Chapter 23, "Break Point and Callback Services"%@NL@%
  692.  
  693.   ■   Chapter 24, "Primary Scheduler Services"%@NL@%
  694.  
  695.   ■   Chapter 25, "Time-Slice Scheduler Services"%@NL@%
  696.  
  697.   ■   Chapter 26, "Event Services"%@NL@%
  698.  
  699.   ■   Chapter 27, "Timing Services"%@NL@%
  700.  
  701.   ■   Chapter 28, "Processor Fault and Interrupt Services"%@NL@%
  702.  
  703.   ■   Chapter 29, "Information Services"%@NL@%
  704.  
  705.   ■   Chapter 30, "Initialization Information Services"%@NL@%
  706.  
  707.   ■   Chapter 31, "Linked List Services"%@NL@%
  708.  
  709.   ■   Chapter 32, "Error Condition Services"%@NL@%
  710.  
  711.   ■   Chapter 33, "Miscellaneous Services"%@NL@%
  712.  
  713.   ■   Chapter 34, "Shell Services"%@NL@%
  714.  
  715.   ■   Chapter 35, "Virtual Display Device (VDD) Services"%@NL@%
  716.  
  717.   ■   Chapter 36, "Virtual Keyboard Device (VKD) Services"%@NL@%
  718.  
  719.   ■   Chapter 37, "Virtual PIC Device (VPICD) Services"%@NL@%
  720.  
  721.   ■   Chapter 38, "Virtual Sound Device (VSD) Services"%@NL@%
  722.  
  723.   ■   Chapter 39, "Virtual Timer Device (VTD) Services"%@NL@%
  724.  
  725.   ■   Chapter 40, "V86 Mode Memory Manager Device Services"%@NL@%
  726.  
  727.   ■   Chapter 41, "Virtual DMA Device (VDMAD) Services"%@NL@%
  728.  
  729.   ■   Chapter 42, "Virtual DOSNET Device Services"%@NL@%
  730.  
  731.  
  732. Part 5, "Appendixes," provides the following supplemental reference
  733. material:  %@NL@%
  734.  
  735.  
  736.   ■   Appendix A, "Terms and Acronyms"%@NL@%
  737.  
  738.   ■   Appendix B, "Understanding Modes"%@NL@%
  739.  
  740.   ■   Appendix C, "Creating Distribution Disks for Drivers"%@NL@%
  741.  
  742.   ■   Appendix D, "Windows INT 2FH API"%@NL@%
  743.  
  744.  
  745.  
  746. %@2@%%@CR:C6A00000003 @%%@AB@%Notational Conventions%@AE@%%@EH@%%@NL@%
  747.  
  748. The following notational conventions are used throughout the DDK
  749. documentation set.  %@NL@%
  750.  
  751. %@TH:  29  1747 02 34 44 @%Convention                        Meaning%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@AB@%bold%@AE@%                              Bold is used for keywords, such as                                   function, register, macro, and data                                   structure field names. These names are                                   spelled exactly as they should appear in                                   source programs. Notice the bold in the                                   following example:                                  %@AB@%Disable%@AE@% (%@AI@%lpDestDev%@AE@%)                                  Here, %@AB@%Disable%@AE@% is bold to indicate that it                                   is the name of a function.%@AI@%italics%@AE@%                           Italics are used to indicate a placeholder                                  that should be replaced by an actual                                   argument. In the preceding example, %@AI@%%@AE@%                                  %@AI@%lpDestDev%@AE@% is italic to indicate that it                                   should be replaced by an argument.(parentheses)                     Parentheses enclose the parameter or                                   parameters that are to be passed to a                                   function. In the preceding example, %@AI@%%@AE@%                                  %@AI@%lpDestDev%@AE@% is the parameter.%@AS@%Monospace%@AE@%                         Monospace type is used for program code                                   fragments and to illustrate the syntax of                                   data structures.%@TE:  29  1747 02 34 44 @%
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758. %@CR:C6A-Part 03 @%%@1@%%@AB@%PART III  Writing Virtual Devices%@AE@%%@EH@%%@NL@%
  759. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  760.  
  761. Microsoft Windows 3.0, while running in 386 enhanced mode, is a
  762. single-threaded multitasking environment. It can run unmodified,
  763. singletasking non-Windows applications by virtualizing system resources. A
  764. resource should be virtualized when multiple applications might use the
  765. resource. The software that does this, the %@AI@%virtual device%@AE@%, can also be used
  766. to provide other services, both to applications and other virtual devices.  %@NL@%
  767.  
  768. This part describes the enhanced Windows environment and details the writing
  769. of virtual devices. Part 4, "Virtual Device Services," describes the
  770. services provided by virtual devices. Chapter 1, "Overview of Windows," in
  771. the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% also contains material
  772. of general interest to the virtual device author.  %@NL@%
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779. %@CR:C6A00160001 @%%@1@%%@AB@%Chapter 16  Overview of Windows in 386 Enhanced Mode%@AE@%%@EH@%%@NL@%
  780. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  781.  
  782. When Microsoft Windows 3.0 is loaded and invoked on an appropriately
  783. configured system, it runs in an "enhanced" mode designed to capitalize on
  784. the power of the Intel 80386/80486 microprocessors. The 80386 and 80486
  785. chips, support multiple, independent memory regions. Enhanced Windows uses
  786. this to build multiple, independent virtual machines, each capable of
  787. running an application program.  %@NL@%
  788.  
  789. Enhanced Windows supports this multitasking virtual machine environment with
  790. a sophisticated set of services that are provided by the virtual devices
  791. (VxDs). Virtual devices provide access to all the system resources,
  792. including memory management, scheduling, and all the hardware devices.  %@NL@%
  793.  
  794. By writing a VxD for a particular hardware device, the author integrates
  795. that device into the powerful, enhanced Windows environment. For instance, a
  796. properly implemented virtual printer device will, by serializing access to
  797. the hardware port, enable multiple applications to share a single printer.  %@NL@%
  798.  
  799. This chapter provides a general description of the virtual machine
  800. environment and introduces the components of a virtual device. However,
  801. detailed programming instructions for the 80386 and 80486 are not provided.
  802. Therefore, a VxD programmer should already be familiar with the topics
  803. described in the preceding "Introduction to Virtual Devices."  %@NL@%
  804.  
  805. In the September, 1987, issue of the %@AI@%Microsoft Systems Journal%@AE@%, the article
  806. entitled "Microsoft Windows/386: Creating a Virtual Machine Environment,"
  807. discusses the structure of Windows/386(tm) version 2.x. It also contains an
  808. excellent description of the four modes of the Intel 80386 microprocessor. A
  809. portion of that discussion is included in Appendix B, "Understanding Modes,"
  810. to help you understand the current version of Windows when running in 386
  811. enhanced mode.  %@NL@%
  812.  
  813.  
  814. %@2@%%@CR:C6A00160002 @%%@AB@%16.1  The Operating Environment%@AE@%%@EH@%%@NL@%
  815.  
  816. Windows in 386 enhanced mode has a virtual machine (VM) architecture that
  817. provides preemptive multitasking for DOS applications on the 80386 and 80486
  818. processor.  %@NL@%
  819.  
  820. The following three major components are also shown graphically in Figure
  821. 16.1:  %@NL@%
  822.  
  823.  
  824.   ■   Virtual machines%@NL@%
  825.  
  826.   ■   Virtual Machine Manager%@NL@%
  827.  
  828.   ■   Virtual devices%@NL@%
  829.  
  830.  
  831. Windows 3.0 virtual machines (VMs) consist of a virtual 8086 (V86) mode
  832. portion and, a optional protected-mode (PM) portion and a control block used
  833. by the environment. The first VM created is called the System VM. This is
  834. the virtual machine in which the Windows graphical user interface runs.
  835. Non-Windows applications run in VMs of their own.%@CR:C6A00160003 @%%@CR:C6A00160004 @%%@CR:C6A00160005 @%%@CR:C6A00160006 @%%@NL@%
  836.  
  837. The Virtual Machine Manager (VMM) functions as a multitasking operating
  838. environment. The VMM provides services that control the main memory, the CPU
  839. execution time, and the peripheral devices. It runs, along with all the
  840. VxDs, in one, flat-model, 32-bit memory segment.%@CR:C6A00160007 @%%@CR:C6A00160008 @%%@NL@%
  841.  
  842. The virtual devices (VxDs) either virtualize a peripheral device, provide
  843. services for the VMM and VxDs, or both. The "x" in VxD stands for an
  844. arbitrary device. In an actual device name, the "x" is replaced with the
  845. name of the virtualized device, e.g., VDD for Virtual Display Device and
  846. VDMAD for Virtual DMA Device.%@CR:C6A00160009 @%%@CR:C6A00160010 @%%@NL@%
  847.  
  848. Internal hardware devices (e.g., the Programmable Interrupt Controller) and
  849. peripheral devices (e.g., a printer) are shown outside of the enhanced
  850. Windows environment in Figure 16.1. However, this is a simplified drawing
  851. since software routines such as BIOS may also be considered part of the
  852. peripheral device.  %@NL@%
  853.  
  854. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  855.  
  856.  
  857. %@2@%%@CR:C6A00160011 @%%@AB@%16.2  Virtual Machines%@AE@%%@EH@%%@NL@%
  858.  
  859. When Windows is running in 386 enhanced mode, it creates memory partitions
  860. that have a remarkable characteristic: programs that run within these
  861. partitions execute as though they were running on an 80386 in real mode.
  862. Each partition, called a %@AI@%virtual machine%@AE@%, comes complete with its own
  863. address space, I/0 port space, and interrupt vector table. Multiple virtual
  864. machines can be running simultaneously, with each under the illusion that it
  865. is in complete control of the computer.  %@NL@%
  866.  
  867. A VM initially runs in the %@AI@%Virtual-86 (V86) mode%@AE@% of the processor. In this
  868. mode, the application running in the VM can make use of all the functions
  869. associated with 8086 emulation and additional privileged instructions
  870. provided by the 80386. The application can also use the %@AI@%protected mode%@AE@%
  871. features of the 80386, but should do so via the DPMI (DOS Protected Mode
  872. Interface) specification (available from Intel at 1-800-548-4725).  %@NL@%
  873.  
  874. A virtual machine (VM) is a complete description of the state of an
  875. application. Each VM includes the following:%@CR:C6A00160012 @%%@NL@%
  876.  
  877.  
  878.   ■   The memory associated with the application%@NL@%
  879.  
  880.   ■   The processor registers%@NL@%
  881.  
  882.   ■   The data structures associated with virtualization%@NL@%
  883.  
  884.  
  885. The data is used by the VMM and VxDs to virtualize the hardware and to
  886. provide services. It is maintained in a data structure called the Control
  887. Block. The processor registers are maintained on the VMM stack and can be
  888. accessed via the Client Register Structure. The memory can be accessed and
  889. manipulated by means of a number of VMM memory manager services.%@CR:C6A00160013 @%%@NL@%
  890.  
  891. The code for MS-DOS and the Windows portion common to the three product
  892. modes (real, standard, and 386 enhanced) runs in the System VM. Most of
  893. MS-DOS, including all the MS-DOS device drivers and TSRs, is usually shared
  894. globally among the VMs.  %@NL@%
  895.  
  896.  
  897. %@3@%%@CR:C6A00160014 @%%@AB@%16.2.1  The Privilege Rings of a VM%@AE@%%@EH@%%@NL@%
  898.  
  899. A VM can have more than one privilege ring. Code executing in one privilege
  900. ring can only have access to memory in the same privilege ring or one with a
  901. higher number (i.e., lower privilege level).%@CR:C6A00160015 @%%@NL@%
  902.  
  903. The virtual-8086 (V86) mode portion, shown in Figure 16.2, runs in privilege
  904. ring 3. This is the code and data most typically associated with MS-DOS
  905. applications.%@CR:C6A00160016 @%%@NL@%
  906.  
  907. The second part is a protected-mode (PM) portion that runs at privilege ring
  908. 1, 2, or 3. This portion can be used by applications running under enhanced
  909. Windows. In the System VM (SYS VM), this portion is used to run the Windows
  910. graphical interface.%@CR:C6A00160017 @%%@NL@%
  911.  
  912. The third part is code and data utilized by the VMM and the VxDs running at
  913. privilege ring 0.  %@NL@%
  914.  
  915. The ring 0 data has three subparts, each associated with a particular VM
  916. (per VM):  %@NL@%
  917.  
  918.  
  919.   1.  The stack, which contains the Client Register Structure (CRS). The
  920.       ring 0 stack is used by the VMM and VxDs when a VM is running.%@NL@%
  921.  
  922.   2.  The control block, which contains other data (i.e., values associated
  923.       with the virtualization of hardware for a VM) local to a VM. %@NL@%
  924.  
  925.   3.  Data owned by a VxD, which contains information that maintains the
  926.       state, such as the state of the physical hardware, across all VMs.%@NL@%
  927.  
  928. %@STUB@%      %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  929.  
  930.  
  931.  
  932. %@3@%%@CR:C6A00160018 @%%@AB@%16.2.2  VM Handles%@CR:C6A00160019 @%%@AE@%%@EH@%%@NL@%
  933.  
  934. Enhanced Windows virtual devices refer to specific VMs by VM handles. By
  935. convention, VM handles are usually stored in the %@AB@%EBX%@AE@% register. A VM handle
  936. is actually a 32-bit linear address of the virtual machine's control block
  937. data structure.  %@NL@%
  938.  
  939.  
  940. %@3@%%@CR:C6A00160020 @%%@AB@%16.2.3  The Client Register Structure %@CR:C6A00160021 @%%@AE@%%@EH@%%@NL@%
  941.  
  942. The Client Register Structure (CRS), as shown in Figure 16.3, contains the
  943. virtual machine processor state including all the virtual machine's
  944. registers and flags. When a device wants to look at or modify a virtual
  945. machine's registers, it must modify the CRS.  %@NL@%
  946.  
  947. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  948.  
  949.  
  950. %@2@%%@CR:C6A00160022 @%%@AB@%16.3  The Virtual Machine Manager%@CR:C6A00160023 @%%@AE@%%@EH@%%@NL@%
  951.  
  952. The Virtual Machine Manager (VMM) is a device-independent layer of code that
  953. provides a framework upon which the virtual devices build virtualizations of
  954. physical devices or provide services for each of the VMs. In this sense, the
  955. VMM lies between the VMs and the VxDs. All interaction between the software
  956. running in the VMs and the VxDs occurs via the interface provided by the
  957. VMM.  %@NL@%
  958.  
  959. The VMM also provides a set of services that allows for creating,
  960. destroying, running, synchronizing, and altering the state of the VMs. The
  961. VMM, as shown in Figure 16.4, handles all the privilege ring transitions of
  962. VMs to privilege ring 0, provides scheduling services, manages memory, and
  963. provides services for such activities as trapping I/O and hooking software
  964. interrupts.  %@NL@%
  965.  
  966. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  967.  
  968.  
  969. %@2@%%@CR:C6A00160024 @%%@AB@%16.4  Virtual Devices%@AE@%%@EH@%%@NL@%
  970.  
  971. Enhanced Windows virtual devices (VxDs) are the interfaces between
  972. application software and the hardware. Most VxDs correspond to a hardware
  973. device, though not all do. For example, the VxDs for printers and displays
  974. simulate actual hardware interfaces, but the VxD called Shell provides
  975. access to the Windows graphical user interface. VxDs use services provided
  976. by the VMM and other VxDs.%@CR:C6A00160025 @%%@CR:C6A00160026 @%%@NL@%
  977.  
  978. VxDs can provide control functions, service functions, API functions, and
  979. callback procedures that are used to virtualize, synchronize, and maintain
  980. the state of the hardware for the VMs. A callback procedure is a request for
  981. notification when a specified event occurs in the normal execution of the
  982. application code.  %@NL@%
  983.  
  984. There must be a VxD for each piece of hardware that can have a different
  985. state in each of the VMs.  %@NL@%
  986.  
  987.  
  988. %@3@%%@CR:C6A00160027 @%%@AB@%16.4.1  VxD Components%@AE@%%@EH@%%@NL@%
  989.  
  990. Installable virtual devices have the following five, distinct parts, which
  991. are shown graphically in Figure 16.5:  %@NL@%
  992.  
  993.  
  994.   1.  Real-mode initialization code and data, which is discarded after
  995.       loading parts 2 - 5 %@NL@%
  996.  
  997.   2.  Protected-mode (PM) initialization code, which is discarded after
  998.       initialization %@NL@%
  999.  
  1000.   3.  Protected-mode (PM) initialization data, which is discarded after
  1001.       initialization %@NL@%
  1002.  
  1003.   4.  PM code, which contains the Device Control Procedure, API and callback
  1004.       procedures, and services%@NL@%
  1005.  
  1006.   5.  PM data, which contains the Device Descriptor Block, Service Table,
  1007.       and Global Data%@NL@%
  1008.  
  1009.  
  1010.  
  1011. %@3@%%@CR:C6A00160028 @%%@AB@%16.4.2  The Device Control Procedure%@AE@%%@EH@%%@NL@%
  1012.  
  1013. The Device Control Procedure (DCP) is the dispatch point for most of the VMM
  1014. interaction with the VxD. Besides the initialization of the system, there
  1015. are device control calls for creating, initializing, and destroying VMs; for
  1016. setting the device focus to a VM; and for indicating a change in the state
  1017. of the VM.%@CR:C6A00160029 @%%@CR:C6A00160030 @%%@CR:C6A00160031 @%%@NL@%
  1018.  
  1019. The VMM broadcasts messages to all VxD DCPs indicating changes in the state
  1020. of the system or of a VM. The DCP can then modify the device's data
  1021. structure or the VM's state. The address of the DCP is specified in a
  1022. special data structure called a Device Descriptor Block that all virtual
  1023. devices must have. See Chapter 17, "Virtual Device Programming Topics," for
  1024. details on messages passed to the DCP.  %@NL@%
  1025.  
  1026.  
  1027. %@3@%%@CR:C6A00160032 @%%@AB@%16.4.3  The Device Descriptor Block%@AE@%%@EH@%%@NL@%
  1028.  
  1029. The Device Descriptor Block (DDB) is a VxD-unique data structure containing
  1030. the VxD's name, version IDs, and entry points for the three code areas: the
  1031. Device Control Procedure, V86-mode API procedure, and the PM API procedure.
  1032. In addition, the DDB can contain a pointer to a table of services provided
  1033. by the VxD. See Chapter 17, "Virtual Device Programming Topics, " for a
  1034. detailed description of a DDB.%@CR:C6A00160033 @%%@CR:C6A00160034 @%%@CR:C6A00160035 @%%@CR:C6A00160036 @%%@NL@%
  1035.  
  1036. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1037.  
  1038.  
  1039. %@3@%%@CR:C6A00160037 @%%@AB@%16.4.4  VxD IDs%@AE@%%@EH@%%@NL@%
  1040.  
  1041. VxD IDs uniquely identify a VxD. They are a 16-bit combination of the OEM
  1042. number and the device number in the form:  %@NL@%
  1043.  
  1044. %@AS@%  xOOOOOOOOOODDDDD%@AE@%
  1045.  
  1046. The high bit of the VxD ID is reserved for future use. The next 10 bits are
  1047. the OEM number, which should be requested from Microsoft. The last 5 bits
  1048. are the VxD number. This enables each OEM to create 32 unique VxDs. If an
  1049. OEM is creating a replacement for a standard VxD, then it should re-use the
  1050. standard ID. VxDs that do not provide services or APIs or that do INT 2FH
  1051. callouts should use the equate Undefined_Device_ID. See VMM.INC for other
  1052. examples of device IDs. Microsoft has reserved the first 16 OEM numbers (0
  1053. through 0FH).  %@NL@%
  1054.  
  1055.  
  1056. %@3@%%@CR:C6A00160038 @%%@AB@%16.4.5  VxD Initialization Order%@AE@%%@EH@%%@NL@%
  1057.  
  1058. VxDs are initialized in order from the %@AI@%lowest%@AE@% to the %@AI@%highest%@AE@% initialization
  1059. order value. If two or more VxDs have the same initialization order value,
  1060. then they are initialized in their order of occurence. Therefore, a specific
  1061. order is not guaranteed. You should use the initialization order equates in
  1062. VMM.INC to specify the initialization order for your VxD. If you want your
  1063. VxD to be initialized slightly before or after a defined initialization
  1064. order, use the equate plus an increment or minus a decrement.%@CR:C6A00160039 @%%@CR:C6A00160040 @%%@NL@%
  1065.  
  1066. Most likely your VxD will not have any initialization ordering dependencies.
  1067. In this case use the Undefined_Init_Order equate.  %@NL@%
  1068.  
  1069.  
  1070. %@2@%%@CR:C6A00160041 @%%@AB@%16.5  How VxDs Work%@AE@%%@EH@%%@NL@%
  1071.  
  1072. The following sections contain general explanations of how VxDs work and
  1073. provide information on the following topics:  %@NL@%
  1074.  
  1075.  
  1076.   ■   Scheduling%@NL@%
  1077.  
  1078.   ■   Memory use%@NL@%
  1079.  
  1080.   ■   Services%@NL@%
  1081.  
  1082.   ■   Callback procedures%@NL@%
  1083.  
  1084.   ■   I/O port hooks%@NL@%
  1085.  
  1086.   ■   Interrupt hooks%@NL@%
  1087.  
  1088.   ■   Loading %@NL@%
  1089.  
  1090.  
  1091. The following related topics are covered in Appendix D, "Windows INT 2FH
  1092. API:"%@CR:C6A00160042 @%%@NL@%
  1093.  
  1094.  
  1095.   ■   Getting the address of a VxD API procedure%@NL@%
  1096.  
  1097.   ■   How a VxD calls out to a TSR or an MS-DOS device driver%@NL@%
  1098.  
  1099.   ■   How a TSR or MS-DOS device driver specifies a VxD to load when
  1100.       starting enhanced Windows
  1101. %@NL@%
  1102.  
  1103.  
  1104.  
  1105. %@3@%%@CR:C6A00160043 @%%@AB@%16.5.1  Enhanced Windows Execution Scheduling %@CR:C6A00160044 @%%@AE@%%@EH@%%@NL@%
  1106.  
  1107. The following is a brief description of how events are scheduled and
  1108. processed. The concepts are also described graphically in Figure 16.6.  %@NL@%
  1109.  
  1110.  
  1111. %@4@%%@AB@%Events%@CR:C6A00160045 @%%@AE@%%@EH@%%@NL@%
  1112.  
  1113. The enhanced Windows VMM is a single-threaded, non-reentrant operating
  1114. system. Because it is non-reentrant, virtual devices that hook interrupts
  1115. must have some method of synchronizing their calls to the VMM. For this
  1116. reason, enhanced Windows uses the concept of event processing.%@CR:C6A00160046 @%%@NL@%
  1117.  
  1118. Event procedures are registered asynchronously and, then, called back just
  1119. before the VMM returns to the application. At this point, the event
  1120. procedure can use all the VMM services.  %@NL@%
  1121.  
  1122. VxDs can also use event procedures to perform some action on a VM that is
  1123. not the current VM. Examples of this include restoring the display to a VM
  1124. when the display focus changes or simulating an interrupt into a VM the next
  1125. time the VM is scheduled.  %@NL@%
  1126.  
  1127. There are two types of events: global and VM specific. Global events are
  1128. processed before returning to a virtual machine regardless of which VM is
  1129. about to run. VM-specific events are only processed when the specified
  1130. virtual machine is about to run.  %@NL@%
  1131.  
  1132.  
  1133. %@4@%%@AB@%Scheduler%@AE@%%@EH@%%@NL@%
  1134.  
  1135. When Windows is running in 386 enhanced mode, each application runs in it
  1136. own VM. Each VM can be given a share of the CPU time. To assign priority
  1137. among the VMs, the VMM has a Scheduler.%@CR:C6A00160047 @%%@NL@%
  1138.  
  1139. The Scheduler is the part of the VMM that determines which VM gets CPU time.
  1140. It is divided into two parts. At the lowest level, the Primary Scheduler
  1141. maintains execution priorities, and the VM with the highest priority is
  1142. allowed to run. VxDs will raise and lower the execution priorities to affect
  1143. task switching among the VMs. The second level of scheduling is handled by
  1144. the Time Slicer, which boosts a VM's execution priority for a given time
  1145. slice.%@CR:C6A00160048 @%%@CR:C6A00160049 @%%@NL@%
  1146.  
  1147. With the Primary Scheduler, there are specific values assigned to execution
  1148. priorities to accomplish task switching, without violating the need for some
  1149. sections of code to execute exclusively until completion. Additionally,
  1150. high-priority device events, such as interrupts that must be serviced in a
  1151. timely manner, will boost execution priorities of VMs that need to be
  1152. serviced. The VMM provides services and defines execution priorities to
  1153. handle these cases.%@CR:C6A00160050 @%%@NL@%
  1154.  
  1155. The enhanced Windows Time Slicer is the preemptive multitasking portion of
  1156. the Scheduler. It relies on time-slice priorities and flags to determine how
  1157. much CPU time should be allocated to various virtual machines.  %@NL@%
  1158.  
  1159. Every VM has a foreground and a background time-slice priority. These should
  1160. be distinguished from a VM's %@AI@%execution%@AE@% priority. The VM with the largest
  1161. execution priority will run, preventing other VMs from executing. The VM
  1162. with the largest time-slice priority will run more often than other VMs but
  1163. it will not necessarily prevent other VMs from executing.  %@NL@%
  1164.  
  1165.  
  1166. %@4@%%@AB@%Transitions Into and Out of the VMM and VxDs%@AE@%%@EH@%%@NL@%
  1167.  
  1168. The enhanced Windows VMM uses the protection mechanism of the 80386 to force
  1169. privilege ring transitions, as shown in Figure 16.6, whenever an application
  1170. program issues a software interrupt or causes a protection fault. One
  1171. example is when a VM performs I/O to a hooked port. The exact mechanisms
  1172. used to make the transition into the VMM are not important to a virtual
  1173. device developer. It is almost never necessary to directly intercept a
  1174. processor fault or hardware interrupt. The only device that handles hardware
  1175. interrupts directly is the Virtual PIC (Programmable Interrupt Controller)
  1176. Device. Callback procedures have been provided to signal a calling routine
  1177. when a specific event occurs. (See Section 16.5.4, "Callback Procedures,"
  1178. for more information.)  %@NL@%
  1179.  
  1180. Programmers familiar with the 80386 architecture may assume that, to hook an
  1181. interrupt, a virtual device will hook the protected-mode Interrupt
  1182. Descriptor Table (IDT) directly. However, this is not true for Windows in
  1183. 386 enhanced mode. Services to hook interrupts at this level are provided by
  1184. the VMM.%@CR:C6A00160051 @%%@CR:C6A00160052 @%%@CR:C6A00160053 @%%@NL@%
  1185.  
  1186. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1187. %@AU@%WARNING%@AE@%
  1188.  
  1189. VxDs must never modify the actual IDT. To do so will cause enhanced Windows
  1190. to crash.
  1191. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1192.  
  1193. The sequence of events for entering the VMM from a virtual machine because
  1194. of an interrupt is as follows:  %@NL@%
  1195.  
  1196.  
  1197.   1.  The VM performs an operation that generates a fault.%@NL@%
  1198.  
  1199.   2.  A ring transition occurs, and the appropriate IDT interrupt handler is
  1200.       called. %@NL@%
  1201.  
  1202.   3.  The VMM dispatches the interrupt to the appropriate handler by a CALL.
  1203.       %@NL@%
  1204.  
  1205.   4.  The protected-mode handler processes the fault and executes a near
  1206.       RET. %@NL@%
  1207.  
  1208.   5.  The VMM processes any outstanding events. %@NL@%
  1209.  
  1210.   6.  An IRET is executed that causes a ring transition back to the VM.%@NL@%
  1211.  
  1212.  
  1213. Notice that the VMM looks at the interrupt before any virtual devices and
  1214. immediately before returning to the virtual machine.  %@NL@%
  1215.  
  1216. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1217.  
  1218.  
  1219. %@3@%%@CR:C6A00160054 @%%@AB@%16.5.2  Memory Models%@AE@%%@EH@%%@NL@%
  1220.  
  1221. Windows in 386 enhanced mode makes use of the 80386's ability to run within
  1222. different memory models. Some devices may have initialization code that is
  1223. run in real mode. See Section 16.5.7, "Loading Sequence," for the loading
  1224. sequence description. After that code is run successfully, a transition is
  1225. made to protected mode (using selector:offset addressing) in which the VMM
  1226. is installed and begins executing. The VMM creates a separate VM that
  1227. consists of a V86-mode portion and an optional, protected-mode (PM) portion
  1228. for each application.  %@NL@%
  1229.  
  1230. The VMM and all the enhanced Windows VxDs run in a 32-bit, flat-model
  1231. protected mode segment. This means that every VxD has complete access to 4
  1232. gigabytes of linear address space. A VxD can access any VM's memory at any
  1233. time.  %@NL@%
  1234.  
  1235. Because enhanced Windows is flat model, virtual devices cannot change the
  1236. %@AB@%CS%@AE@%, %@AB@%DS%@AE@%, %@AB@%ES%@AE@%, or %@AB@%SS%@AE@% segment registers. These segment registers always contain
  1237. a selector that has a base of 0 and a limit of 4 gigabytes. Devices can use
  1238. the %@AB@%FS%@AE@% and %@AB@%GS%@AE@% segment registers, but there usually is no reason to do so.
  1239. VMM services will not modify the %@AB@%FS%@AE@% or %@AB@%GS%@AE@% segment registers. Pointers are
  1240. always 32-bit linear addresses unless otherwise specified.  %@NL@%
  1241.  
  1242. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1243. NOTE
  1244.  
  1245. %@AI@%Since the VMM (privilege ring 0 code) resides in a single, flat memory
  1246. %@AI@%segment, the selector of the selector:offset PM addressing for the VMM and
  1247. %@AI@%VxDs never changes.%@AE@%
  1248.  
  1249. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1250.  
  1251.  
  1252. %@4@%%@AB@%Modes%@AE@%%@EH@%%@NL@%
  1253.  
  1254. Application programs typically run in a V86-mode portion of the enhanced
  1255. Windows operating environment.%@CR:C6A00160055 @%%@CR:C6A00160056 @%%@NL@%
  1256.  
  1257. As described in Appendix B, "Understanding Modes," V86 mode is similar to
  1258. real mode. The crucial difference between the two is that memory protection,
  1259. virtual memory, and privilege-checking mechanisms are in effect when code
  1260. runs in V86 mode. Therefore, a program executing in V86 mode cannot
  1261. interfere with the operating environment or damage other processes. If the
  1262. program reads or writes memory addresses that have not been mapped into its
  1263. VM or manipulates I/O ports to which it has not been allowed access, an
  1264. exception (fault) is generated, and the operating environment regains
  1265. control.  %@NL@%
  1266.  
  1267. An application may also run in protected mode (also described in Appendix
  1268. B). An example of this is the the Windows graphical interface.  %@NL@%
  1269.  
  1270. However, non-Windows applications %@AI@%must use%@AE@% DPMI when using protected-mode
  1271. features. The DPMI (DOS Protected Mode Interface) specification is available
  1272. from Intel at 1-800-548-4725. By using DPMI, applications gain access to
  1273. extended memory, the ability to run in a 16-bit or a 32-bit memory model,
  1274. and other features of the 80386 protected mode.  %@NL@%
  1275.  
  1276.  
  1277. %@4@%%@AB@%Privilege Rings%@AE@%%@EH@%%@NL@%
  1278.  
  1279. By running in ring 0, the VMM and all the VxDs have the most privileges.
  1280. Protected-mode applications, such as Windows itself, run in rings 1, 2, or 3
  1281. and have lower privileges. Least privileged are MS-DOS and the applications
  1282. running in V86 mode, which run only in ring 3.  %@NL@%
  1283.  
  1284. Figure 16.7 shows each of these components within there respective rings.
  1285. Also shown are the Control Block and the Client Register Structure.%@CR:C6A00160057 @%%@NL@%
  1286.  
  1287. Since all virtual devices run at ring 0, they have the ability to execute
  1288. any 80386 instruction without producing a protection violation. However,
  1289. devices should not execute protected instructions as they will usually cause
  1290. Windows to crash immediately. The only exception to this is the Virtual Math
  1291. Coprocessor Device, which is allowed to change the 80387 bits in the %@AB@%CR0%@AE@%
  1292. register.%@CR:C6A00160058 @%%@CR:C6A00160059 @%%@CR:C6A00160060 @%%@NL@%
  1293.  
  1294. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1295.  
  1296.  
  1297. %@3@%%@CR:C6A00160061 @%%@AB@%16.5.3  Services%@AE@%%@EH@%%@NL@%
  1298.  
  1299. Services are the shared routines of the VMM and VxDs. VxDs use services to
  1300. handle interrupts, to initiate callback procedures, and to process
  1301. exceptions/faults.%@CR:C6A00160062 @%%@NL@%
  1302.  
  1303. Notice that there are some VxD services that the VMM requires. Most notable
  1304. of these are the services provided by the Virtual Programmable Interrupt
  1305. Controller Device (VPICD), which virtualizes the PIC for the VxDs (for
  1306. requesting interrupts) and the VMs.  %@NL@%
  1307.  
  1308. Detailed descriptions of each service are provided in Part 4, "Virtual
  1309. Device Services." The services are also categorized there as follows:  %@NL@%
  1310.  
  1311.  
  1312.   ■   Memory Management services%@NL@%
  1313.  
  1314.   ■   I/O services and macros%@NL@%
  1315.  
  1316.   ■   VM Interrupt and Call services%@NL@%
  1317.  
  1318.   ■   Nested Execution services%@NL@%
  1319.  
  1320.   ■   Break Point and Callback services%@NL@%
  1321.  
  1322.   ■   Primary Scheduler services%@NL@%
  1323.  
  1324.   ■   Time-Slice Scheduler services%@NL@%
  1325.  
  1326.   ■   Event services%@NL@%
  1327.  
  1328.   ■   Timing services%@NL@%
  1329.  
  1330.   ■   Processor Fault and Interrupt services%@NL@%
  1331.  
  1332.   ■   Information services%@NL@%
  1333.  
  1334.   ■   Initialization Information services%@NL@%
  1335.  
  1336.   ■   Linked List services%@NL@%
  1337.  
  1338.   ■   Error Condition services%@NL@%
  1339.  
  1340.   ■   Miscellaneous services%@NL@%
  1341.  
  1342.   ■   Shell services%@NL@%
  1343.  
  1344.   ■   Virtual Display Device (VDD) services%@NL@%
  1345.  
  1346.   ■   Virtual Keyboard Device (VKD) services%@NL@%
  1347.  
  1348.   ■   Virtual PIC Device (VPICD) services%@NL@%
  1349.  
  1350.   ■   Virtual Sound Device (VSD) services%@NL@%
  1351.  
  1352.   ■   Virtual Timer Device (VTD) services%@NL@%
  1353.  
  1354.   ■   V86 Mode Memory Manager Device services%@NL@%
  1355.  
  1356.   ■   Virtual DMA Device (VDMAD) services%@NL@%
  1357.  
  1358.   ■   Virtual DOSNET Device services%@NL@%
  1359.  
  1360.  
  1361.  
  1362. %@3@%%@CR:C6A00160063 @%%@AB@%16.5.4  Callback Procedures%@AE@%%@EH@%%@NL@%
  1363.  
  1364. Some services enable a calling routine to register a procedure that will be
  1365. called back when a particular event occurs. Callback procedures are used for
  1366. maintaining the VM state via I/O and interrupt trapping, and for
  1367. synchronizing with the VMM via the event services.  %@NL@%
  1368.  
  1369. The VMM includes services that enable virtual devices to install callback
  1370. procedures to do the following:%@CR:C6A00160064 @%%@NL@%
  1371.  
  1372.  
  1373.   ■   Trap interrupts from virtual machines %@NL@%
  1374.  
  1375.   ■   Trap I/O to specific ports %@NL@%
  1376.  
  1377.   ■   Trap access to memory %@NL@%
  1378.  
  1379.   ■   Schedule per-VM or global time-outs %@NL@%
  1380.  
  1381.   ■   Schedule per-VM or global events %@NL@%
  1382.  
  1383.   ■   Detect when a VM returns from an interrupt or FAR call %@NL@%
  1384.  
  1385.   ■   Detect when a VM executes a particular piece of V86 code %@NL@%
  1386.  
  1387.   ■   Detect the release of the critical section %@NL@%
  1388.  
  1389.   ■   Detect changes to the VM's interrupt enable flag %@NL@%
  1390.  
  1391.   ■   Detect task switches%@NL@%
  1392.  
  1393.  
  1394.  
  1395. %@3@%%@CR:C6A00160065 @%%@AB@%16.5.5  I/O Port Hooks%@AE@%%@EH@%%@NL@%
  1396.  
  1397. The VMM provides a service called %@AB@%Install_IO_Handler%@AE@%. The service takes two
  1398. parameters: the port to be hooked, and the address of the procedure to be
  1399. called whenever the port is accessed.%@CR:C6A00160066 @%%@NL@%
  1400.  
  1401. When a VxD calls %@AB@%Install_IO_Handler%@AE@%, the VMM sets the appropriate bit in the
  1402. I/O permission map (IOPM) and registers the procedure. When a virtual
  1403. machine executes an instruction that reads or writes data from an I/O port,
  1404. the 80386 looks up the port number in the I/O permission map. If the
  1405. corresponding bit in the IOPM is set, then the instruction will cause a
  1406. protection fault that results in calling the registered procedure. %@AB@%  %@AE@%%@NL@%
  1407.  
  1408.  
  1409. %@3@%%@CR:C6A00160067 @%%@AB@%16.5.6  Interrupt Hooks%@AE@%%@EH@%%@NL@%
  1410.  
  1411. The Virtual Programmable Interrupt Controller Device (VPICD) routes hardware
  1412. interrupts to other virtual devices, provides services that enable virtual
  1413. devices to request interrupts, and simulates hardware interrupts into
  1414. virtual machines.%@CR:C6A00160068 @%%@NL@%
  1415.  
  1416. When a virtual device needs to hook a specific IRQ, it must ask VPICD for
  1417. permission. If another device has already virtualized the IRQ, then VPICD
  1418. will refuse. Chapter 37, "Virtual PIC Device (VPICD) Services," details the
  1419. workings of the VPICD.  %@NL@%
  1420.  
  1421. For services used in hooking software interrupts and supporting software
  1422. interrupt hooks, see Chapter 21, "VM Interrupt and Call Services."%@CR:C6A00160069 @%%@CR:C6A00160070 @%%@CR:C6A00160071 @%%@CR:C6A00160072 @%%@NL@%
  1423.  
  1424.  
  1425. %@3@%%@CR:C6A00160073 @%%@AB@%16.5.7  Loading Sequence%@AE@%%@EH@%%@NL@%
  1426.  
  1427. The following is a generalized description of the loading sequence. Figures
  1428. 16.8 and 16.9 are an example of a specific loading sequence.%@CR:C6A00160074 @%%@NL@%
  1429.  
  1430. When Windows in 386 enhanced mode is first started, the following happens:  %@NL@%
  1431.  
  1432.  
  1433.   1.  The loader allocates extended memory via the XMS driver, loads the VMM
  1434.       and all the specified virtual devices into extended memory.%@NL@%
  1435.  
  1436.   2.  The system switches to protected mode.%@NL@%
  1437.  
  1438.   3.  The loader passes control to the VMM initialization routine.%@NL@%
  1439.  
  1440.   4.  The initialization routine completes the initialization of the VMM and
  1441.       calls all the VxD initialization routines.%@NL@%
  1442.  
  1443.   5.  The System VM is created and initialized.%@NL@%
  1444.  
  1445.   6.  The Shell VxD executes WINSTART.BAT and, then, Windows.%@NL@%
  1446.  
  1447.  
  1448. Each VxD can have different sections of code that are executed during
  1449. various phases of initialization and normal program execution, as shown in
  1450. Figure 16.8.  %@NL@%
  1451.  
  1452. The first phase of initialization is load time. During load time, the
  1453. virtual device can abort the loading of the device, abort the loading of
  1454. enhanced Windows, specify instance data, and exclude pages of memory from
  1455. utilization by enhanced Windows. This load time code is in its own segment
  1456. and is run in real mode and, then, discarded. See Chapter 17, "Virtual
  1457. Device Programming Topics," for details on real-mode initialization.  %@NL@%
  1458.  
  1459. The rest of the virtual device is run in 32-bit, flat-model protected mode
  1460. and is divided into the following four parts:  %@NL@%
  1461.  
  1462.  
  1463.   ■   Initialization code%@NL@%
  1464.  
  1465.   ■   Initialization data%@NL@%
  1466.  
  1467.   ■   Code%@NL@%
  1468.  
  1469.   ■   Data%@NL@%
  1470.  
  1471.  
  1472. The initialization code and data are purged from memory after
  1473. initialization, as shown in Figure 16.9. These segments contain services and
  1474. data that are accessed only during the three phases of enhanced Windows
  1475. system initialization: %@AB@%Sys_Critical_Init%@AE@%, %@AB@%Device_Init%@AE@%, and %@AB@%Init_Complete%@AE@%.
  1476. Some of the enhanced Windows VMM services are available only during
  1477. initialization.  %@NL@%
  1478.  
  1479. The sections of code and data that are not specifically for initialization
  1480. perform the device virtualization and can provide services for other
  1481. devices.  %@NL@%
  1482.  
  1483. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1484.  
  1485. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1486.  
  1487.  
  1488. %@2@%%@CR:C6A00160075 @%%@AB@%16.6  VxD Examples%@AE@%%@EH@%%@NL@%
  1489.  
  1490. Often, new VxDs are actually modifications of existing ones. To help with
  1491. your VxD development, Microsoft includes with the DDK the source code for
  1492. fully operational VxDs. We encourage you to use them as examples whenever
  1493. convenient. See the DDK %@AI@% Installation and Update Guide%@AE@% for more detailed
  1494. descriptions and a complete list of the source samples provided for this
  1495. version of Windows.  %@NL@%
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502. %@CR:C6A00170001 @%%@1@%%@AB@%Chapter 17  Virtual Device Programming Topics%@AE@%%@EH@%%@NL@%
  1503. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1504.  
  1505. This chapter presents details on writing and installing VxDs. You should be
  1506. familiar with Chapter 16, "Overview of Windows in 386 Enhanced Mode," before
  1507. proceeding with this material. For explanations on specific types of
  1508. services provided by the Virtual Machine Manager (VMM), see the appropriate
  1509. chapters in Part 4, "Virtual Device Services." This chapter is divided into
  1510. the following general topics:  %@NL@%
  1511.  
  1512.  
  1513.   ■   Writing VxDs%@NL@%
  1514.  
  1515.   ■   Building a VxD%@NL@%
  1516.  
  1517.   ■   Initializing a VxD%@NL@%
  1518.  
  1519.   ■   Tracking the VM states%@NL@%
  1520.  
  1521.   ■   Exiting Windows%@NL@%
  1522.  
  1523.  
  1524. We recommend that you scan all the topics before beginning a VxD project.
  1525. You should also review the sample VxDs supplied on the %@AI@%Microsoft Windows
  1526. %@AI@%Device Development Kit%@AE@% (DDK) disks for examples of how to accomplish
  1527. specific tasks. The following table suggests some VxDs to study when
  1528. investigating specific service topics.  %@NL@%
  1529.  
  1530. %@TH:   8   396 02 34 42 @%Service topic                     Sample VxD%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%Memory management                 VDDHardware interrupts               VKDI/O                               VPDScheduler                         VKDEvents                            VKDTimeouts                          VKD%@TE:   8   396 02 34 42 @%
  1531.  
  1532.  
  1533. %@2@%%@CR:C6A00170002 @%%@AB@%17.1  Writing VxDs%@AE@%%@EH@%%@NL@%
  1534.  
  1535. Enhanced Windows virtual devices are not "Windows" programs. You do not need
  1536. to know anything about Windows programming to write a VxD.%@CR:C6A00170003 @%%@NL@%
  1537.  
  1538. Often, new VxDs are simply modifications of existing ones. To help with your
  1539. VxD development, Microsoft includes the code for many, fully operational
  1540. VxDs in the %@AI@%Microsoft Windows Device Development Kit%@AE@%. We encourage you to
  1541. use them as examples whenever convenient.  %@NL@%
  1542.  
  1543. However, some VxDs will require a significant effort to develop. The
  1544. following can be used as a guideline when writing a complex VxD.  %@NL@%
  1545.  
  1546.  
  1547.   1.  Build a skeleton. Using the supplied sources as a guide, build a
  1548.       skeleton of the VxD with the device control procedure, the services,
  1549.       and the API procedures defined but not functional. %@NL@%
  1550.  
  1551.   2.  Add the initialization functionality, including the control block and
  1552.       global memory allocation, physical page hooking, I/O hooking, and
  1553.       interrupt hooking.%@NL@%
  1554.  
  1555.   3.  Fill out the procedures that handle the various hooks.%@NL@%
  1556.  
  1557.   4.  Test the procedures.%@NL@%
  1558.  
  1559.   5.  Implement the APIs and services, if there are any.%@NL@%
  1560.  
  1561.   6.  Test the APIs and services.
  1562. %@NL@%
  1563.  
  1564.  
  1565.  
  1566. %@3@%%@CR:C6A00170004 @%%@AB@%17.1.1  VxD Memory Model%@AE@%%@EH@%%@NL@%
  1567.  
  1568. The part of the enhanced Windows environment containing the VMM and all the
  1569. VxDs (ring 0), is one, flat-model, 32-bit segment. This means that all the
  1570. code and data belong to the same group. Two selectors are created: one for
  1571. code and one for data. Both have a base of zero and a limit of four
  1572. gigabytes, so all the segment registers point to the same address space (the
  1573. entire virtual address space provided by the 80386 processor).%@CR:C6A00170005 @%%@NL@%
  1574.  
  1575. When a VxD is loaded, all the offsets are fixed according to the the VxD's
  1576. actual position. This is different from MS-DOS's loading of .EXE files, in
  1577. which segments are fixed up and offsets are left untouched.  %@NL@%
  1578.  
  1579. All procedures are NEAR, and data pointers are 32-bit offsets.  %@NL@%
  1580.  
  1581. VxDs do not export routines or data. To access VMM or VxD services, a
  1582. dynamic-link mechanism is employed using macros contained in VMM.INC. The
  1583. VMM services are available with the %@AB@%VMMcall%@AE@% macro, and the VxD services with
  1584. the %@AB@%VxDcall%@AE@% macro. Data is shared via declared services only.  %@NL@%
  1585.  
  1586. You must use the %@AB@%OFFSET32%@AE@% macro in your flat-model, 32-bit segments anywhere
  1587. you would normally use the %@AB@%OFFSET%@AE@% assembler directive. That is, in all
  1588. segments except for the real-mode initialization segment. This macro
  1589. correctly defines all the offsets so that LINK386 will produce the correct
  1590. offset fixup information. For example:  %@NL@%
  1591.  
  1592. %@AS@%  mov   esi, OFFSET32 My_Data%@AE@%
  1593.  
  1594.  
  1595. %@3@%%@CR:C6A00170006 @%%@AB@%17.1.2  VxD Segmentation%@AE@%%@EH@%%@NL@%
  1596.  
  1597. As discussed in Chapter 16, "Overview of Windows in 386 Enhanced Mode," VxDs
  1598. have five functional parts. Each of these parts exists as a separate
  1599. segment. Macros have been created to define segments for each of the parts.%@CR:C6A00170007 @%%@NL@%
  1600.  
  1601. Each macro name consists of a segment name followed by "_SEG," which means
  1602. that this macro begins the segment. A segment descriptor terminated by
  1603. "_ENDS" is used for macros that end the segment. For example, macros used
  1604. for defining a segment for real-mode load-time initialization would appear
  1605. as %@AB@%VxD_REAL_INIT_SEG%@AE@% and %@AB@%VxD_REAL_INIT_ENDS%@AE@%.  %@NL@%
  1606.  
  1607. In some enhanced Windows installations, it is possible to demand page
  1608. portions of VxDs. These installations require a dedicated swap device or a
  1609. fully virtualized hard disk with a dedicated swap partition. This way,
  1610. paging can be done without concern for reentering portions of MS-DOS, device
  1611. drivers, or BIOS. To support paging, a VxD must place the following in
  1612. locked memory:  %@NL@%
  1613.  
  1614.  
  1615.   ■   Device Control Procedure (DCP)%@NL@%
  1616.  
  1617.   ■   Device Descriptor Block (DDB)%@NL@%
  1618.  
  1619.   ■   Hardware interrupt procedures (and the data accessed by them)%@NL@%
  1620.  
  1621.   ■   Asynchronous (Async) services that can be called from hardware
  1622.       interrupt procedures%@NL@%
  1623.  
  1624.  
  1625. Some of the macros supplied in VMM.INC (e.g., %@AB@%Declare_Virtual_Device%@AE@%)
  1626. correctly place code and data objects in locked segments. The following are
  1627. the different segment descriptor types:  %@NL@%
  1628.  
  1629. %@AS@%  VxD_REAL_INIT  - Real-mode load-time initialization
  1630. %@AS@%  VxD_ICODE  - Protected mode initialization code
  1631. %@AS@%  VxD_IDATA  - Protected mode initialization data
  1632. %@AS@%  VxD_LOCKED_CODE  - Code that cannot be paged
  1633. %@AS@%  VxD_LOCKED_DATA  - Data that cannot be paged
  1634. %@AS@%  VxD_CODE   - Pageable code
  1635. %@AS@%  VxD_DATA   - Pageable data%@AE@%
  1636.  
  1637.  
  1638. %@3@%%@CR:C6A00170008 @%%@AB@%17.1.3  VxD Declaration%@AE@%%@EH@%%@NL@%
  1639.  
  1640. A VxD's first few lines of code must always be the assembler directive
  1641. (".386p"), the INCLUDE files, and the Device Descriptor Block declaration.%@CR:C6A00170009 @%%@NL@%
  1642.  
  1643.  
  1644. %@4@%%@AB@%Assembler Directive%@AE@%%@EH@%%@NL@%
  1645.  
  1646. Every VxD must inform the assembler that the code is 80386 protected-mode
  1647. code. This is done by including the following directive:  %@NL@%
  1648.  
  1649. %@AS@%  .386p%@AE@%
  1650.  
  1651.  
  1652. %@4@%%@AB@%INCLUDE Files%@AE@%%@EH@%%@NL@%
  1653.  
  1654. INCLUDE files enable VxDs to use code located in other parts of enhanced
  1655. Windows. The following INCLUDE files may be included:  %@NL@%
  1656.  
  1657. %@TH:  38  2531 02 34 44 @%Filename                          Description%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%VMM.INC                           (Required) Contains definitions of all the                                  enhanced Window services, as well as                                   required macros and equates. DEBUG.INC                         (Optional) Contains useful macros for                                   dumping messages to a                                   debugging terminal and performing checks                                   on various data. The macros provided by                                   this file produce code only when the VxD                                   is assembled with the DEBUG switch. See                                   the %@AI@%Microsoft Windows Software Development%@AE@%                                  %@AI@%Kit%@AE@% (SDK) for information on the Windows                                   debugging services.VPICD.INC                         (Optional) Contains equates and service                                   declarations for the                                   Virtual Programmable Interrupt Controller                                   Device (VPICD). All enhanced Windows                                   interrupts are handled by the VPICD. Most                                   VxDs will require VPICD services. For                                   example, the VPD uses the services to hook                                  all the printer port's hardware interrupts.SHELL.INC                         (Optional) Contains definitions of the                                   public services provided by the Shell VxD.                                  The Shell device provides the VxDs with                                   access to the Windows graphical user                                   interface, thus giving the VxDs the                                   ability to display dialog boxes to the                                   user. For example, if two VMs attempted                                   simultaneously to use the same peripheral                                   device, the VxD could call %@AB@%%@AE@%                                  %@AB@%Resolve_Contention%@AE@%, which would display a                                   dialog box asking the user to choose                                   between the two VM applications.%@TE:  38  2531 02 34 44 @%
  1658.  
  1659.  
  1660. %@4@%%@AB@%Device Descriptor Block%@AE@%%@EH@%%@NL@%
  1661.  
  1662. The declaration of the VxD is accomplished by its Device Descriptor Block
  1663. (DDB). The DDB is generated automatically by the %@AB@%Declare_Virtual_Device%@AE@%
  1664. macro. The following example is from the VPD sample provided with the DDK.  %@NL@%
  1665.  
  1666. %@AS@%  DECLARE_VIRTUAL_DEVICE VPD,3,0,VPD_Control, VPD_Device_ID,
  1667. %@AS@%VPD_Init_Order,, VPD_PM_API_Handler,, %@AE@%
  1668.  
  1669. The table in Figure 17.1 describes each of the parameters:%@CR:C6A00170010 @%%@CR:C6A00170011 @%%@CR:C6A00170012 @%%@CR:C6A00170013 @%%@CR:C6A00170014 @%%@CR:C6A00170015 @%%@NL@%
  1670.  
  1671. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  1672.  
  1673.  
  1674. %@4@%%@AB@%VxD IDs%@AE@%%@EH@%%@NL@%
  1675.  
  1676. To ensure cooperation with current and future versions of enhanced Windows
  1677. environment components, VxDs need to have unique ID numbers assigned. If you
  1678. are directly replacing an existing VxD, use the previous ID. Otherwise, if
  1679. you are creating a new VxD that provides any of the following:  %@NL@%
  1680.  
  1681.  
  1682.   ■   Service(s)%@NL@%
  1683.  
  1684.   ■   V86 mode API (see Appendix D, Section D.1.6, "Get Device API Entry
  1685.       Point")%@NL@%
  1686.  
  1687.   ■   Protected Mode API (see Appendix D, Section D.2.3, "Device Call Out
  1688.       API")%@NL@%
  1689.  
  1690.  
  1691. or if the VxD needs to call an MS-DOS device (listed in .SYS) or TSR, the
  1692. VxD will need a new ID. Device IDs are a 16-bit combination of the OEM
  1693. number and the device number in the form:  %@NL@%
  1694.  
  1695. %@AS@%  xOOOOOOOOOODDDDD%@AE@%
  1696.  
  1697. The high bit of the VxD ID is reserved for future use. The next ten bits are
  1698. the OEM number that is assigned by Microsoft. The last five bits are the
  1699. device number. This enables each OEM to create 32 unique VxDs. VxDs that do
  1700. not provide services or APIs or that do INT 2FH call-outs should use the
  1701. equate Undefined_Device_ID.  %@NL@%
  1702.  
  1703. See VMM.INC for other examples of device IDs. Microsoft reserves the first
  1704. 16 OEM numbers (0 through 0FH).  %@NL@%
  1705.  
  1706.  
  1707. %@4@%%@AB@%Initialization Order%@AE@%%@EH@%%@NL@%
  1708.  
  1709. VxDs are initialized in order from the %@AI@%lowest%@AE@% to the %@AI@%highest%@AE@% initialization
  1710. order value. If two or more devices have the same initialization order
  1711. value, then they are initialized in their order of occurence. Therefore, a
  1712. specific order is not guaranteed. You should use the initialization order
  1713. equates in VMM.INC to specify the initialization order for your VxD. If you
  1714. want your VxD to be initialized slightly before or after a defined
  1715. initialization order, use the equate plus an increment or minus a decrement.
  1716. Most likely, your VxD will not have any initialization ordering
  1717. dependencies. In this case, use the Undefined_Init_Order equate.  %@NL@%
  1718.  
  1719.  
  1720. %@3@%%@CR:C6A00170016 @%%@AB@%17.1.4  VxD Services%@AE@%%@EH@%%@NL@%
  1721.  
  1722. The functionality a VxD provides, if either directly to the VMM or other
  1723. VxDs, or through them to applications, is always via services. The services
  1724. use a dynamic-linking mechanism using INT 20H. (This mechanism is not the
  1725. same as the DLL protocol.) An example of a service call is shown below.  %@NL@%
  1726.  
  1727. This section contains descriptions on how to declare and call services, how
  1728. to verify the presence of a VxD, and a comparison of standard vs.
  1729. asynchronous services.%@CR:C6A00170017 @%%@NL@%
  1730.  
  1731.  
  1732. %@4@%%@AB@%Service Calling Conventions%@AE@%%@EH@%%@NL@%
  1733.  
  1734. All the enhanced Windows services use either a register-based calling
  1735. convention or a 32-bit C-type calling convention. In general, all the memory
  1736. manager calls use C calling conventions, and all other services are register
  1737. based.%@CR:C6A00170018 @%%@NL@%
  1738.  
  1739. The C convention services all begin with an underscore (_) in front of the
  1740. service name. They are similar to the standard C conventions: all parameters
  1741. are passed on the stack, and results are returned in the %@AB@%EAX%@AE@% and %@AB@%EDX%@AE@%
  1742. registers.  %@NL@%
  1743.  
  1744. Unlike the standard C conventions, the %@AB@%EBX%@AE@%, %@AB@%ES%@AE@%, %@AB@%FS%@AE@%, and %@AB@%GS%@AE@% registers are
  1745. preserved as well as the %@AB@%ESI%@AE@% and %@AB@%EDI%@AE@% registers. Only the flags and the %@AB@%EAX%@AE@%,
  1746. %@AB@%ECX%@AE@%, and %@AB@%EDX%@AE@% registers are modified.  %@NL@%
  1747.  
  1748. The %@AB@%VMMcall%@AE@% and %@AB@%VxDcall%@AE@% macros support stack parameter passing like the
  1749. standard C macro package. For example:  %@NL@%
  1750.  
  1751. %@AS@%  VMMcall _HeapAllocate, <<SIZE Data_Node>, 0>>%@AE@%
  1752.  
  1753. will generate the following code:  %@NL@%
  1754.  
  1755. %@AS@%  push 0
  1756. %@AS@%  push SIZE Data_Node
  1757. %@AS@%  int 20h
  1758. %@AS@%  dd _HeapAllocate
  1759. %@AS@%  add esp, 2*4%@AE@%
  1760.  
  1761. Notice that the parameters are pushed on the stack from right to left as in
  1762. the standard convention.  %@NL@%
  1763.  
  1764. All the Windows services for running in 386 enhanced mode that do not begin
  1765. with an underscore (_) are register-based services. All the parameters to
  1766. the services are passed in registers and all the results are returned in
  1767. registers. If a service does not explicitly return a result in a register,
  1768. than that register will be preserved.  %@NL@%
  1769.  
  1770.  
  1771. %@4@%%@AB@%Declaring Services%@AE@%%@EH@%%@NL@%
  1772.  
  1773. Virtual devices use two macros, %@AB@%Begin_Service_Table%@AE@% and %@AB@%End_Service_Table%@AE@%,
  1774. that are declared in VMM.INC to export services. The service table is
  1775. normally declared in an INCLUDE file that other VxDs can include to import
  1776. the services. For example, a typical service table declaration would look
  1777. something like this for the Virtual "FOO" Device:  %@NL@%
  1778.  
  1779. %@AS@%  Begin_Service_Table VFooD%@AE@%
  1780.  
  1781. %@AS@%  VFooD_Service vFooD_Get_Version, LOCAL
  1782. %@AS@%   VFooD_Service vFooD_Do_Something
  1783. %@AS@%   VFooD_Service vFooD_Do_Somthing_Else
  1784. %@AS@%   VFooD_Service vFooD_Do_Yet_Another_Thing, VxD_ICODE%@AE@%
  1785.  
  1786. %@AS@%  End_Service_Table VFooD%@AE@%
  1787.  
  1788. The %@AB@%Begin_Service_Table%@AE@% macro uses a single argument to generate the macro
  1789. used to declare individual services. %@AB@%Begin_Service_Table%@AE@% names the macro by
  1790. taking the name of the device and appending "_Service" to it. In the
  1791. preceding example, %@AB@%VFooD_Service%@AE@% is the name of the macro.  %@NL@%
  1792.  
  1793. The %@AB@%Device_Service%@AE@% macro can take one or two parameters. The first parameter
  1794. is the name of the service (e.g., %@AB@%Get_Version%@AE@%). This must match the name of
  1795. a procedure that was declared with the %@AB@%BeginProc%@AE@% macro using the "%@AB@%Service%@AE@%"
  1796. or "%@AB@%Async_Service%@AE@%" options. The second parameter is optional. If it is
  1797. omitted, then the service procedure is declared as an external reference in
  1798. the VxD_CODE segment.  %@NL@%
  1799.  
  1800. If the special value "LOCAL" is used as the second parameter (as in the
  1801. VFooD_Get_Version declaration), then the procedure is not declared as
  1802. external. This option is used when the service is declared in the same file
  1803. in which the service table will be created. If, in this case, it were to be
  1804. declared external, then MASM would generate an error.  %@NL@%
  1805.  
  1806. If the service procedure is not in the same file as the one used to create
  1807. the service table, and not in the VxD_CODE segment, then you must supply the
  1808. name of the segment it resides in so that the proper external declaration
  1809. can be made. In the above example, the %@AB@%VFooD_Do_Yet_Another_Thing%@AE@% service is
  1810. declared to be in the VxD_INIT code segment. All others are left in the
  1811. default VxD_CODE segment.  %@NL@%
  1812.  
  1813. The first service for every device %@AI@%must%@AE@% be a %@AB@%Get_Version%@AE@% service. This
  1814. service must return with %@AB@%AX%@AE@%  0 and the Carry flag clear. See the following
  1815. section, "%@AB@%VxD Presence Verification%@AE@%," for more details.  %@NL@%
  1816.  
  1817. Once the table of services has been created, you must force the table to be
  1818. generated in one of the VxD source files by defining a special equate (EQU)
  1819. called "%@AB@%Create_xxx_Service_Table%@AE@%," where %@AI@%xxx%@AE@% is the name of the device
  1820. before including the service declaration INCLUDE file. For example, the main
  1821. source file of the VFooD service table would contain the following INCLUDE
  1822. statements:%@AB@%  %@AE@%%@NL@%
  1823.  
  1824. %@AS@%  INCLUDE VMM.INC
  1825. %@AS@%  INCLUDE Debug.INC
  1826. %@AS@%  Create_VFooD_Service_Table EQU true
  1827. %@AS@%  INCLUDE VFooD.INC%@AE@%
  1828.  
  1829. This must be done in the same source file that contains the device
  1830. declaration. This table is automatically generated and the pointer to the
  1831. table is stored in the device's DDB.  %@NL@%
  1832.  
  1833. Notice that, since the macros generate equates, you will now want to add
  1834. service declarations to the end of the INCLUDE file. That is, never change
  1835. the order of the declarations. Adding, removing, or changing the order of
  1836. services changes the service numbering and all the VxDs that call these
  1837. services will need to be rebuilt.  %@NL@%
  1838.  
  1839.  
  1840. %@4@%%@AB@%VxD Presence Verification%@AE@%%@EH@%%@NL@%
  1841.  
  1842. Many VxDs will not load under certain circumstances. For example the EBIOS
  1843. device will not load when the machine does not have an extended BIOS data
  1844. area. Before calling VxD services, you should make sure that the VxD is
  1845. loaded by calling the VxD %@AB@%Get_Version%@AE@% service. %@AB@%Get_Version%@AE@% for a VxD will
  1846. return with %@AB@%AX%@AE@% = 0 and the Carry flag set if the VxD is not installed.  %@NL@%
  1847.  
  1848.  
  1849. %@4@%%@AB@%Standard Vs. Asynchronous Services%@AE@%%@EH@%%@NL@%
  1850.  
  1851. Most services are not reentrant. This means they cannot be called from
  1852. hardware interrupt procedures. However, a select group of services is
  1853. declared as "Async" services and can be called from hardware interrupt
  1854. procedures. You may declare services that can be called from interrupt
  1855. handlers by using the "%@AB@%Async_Service%@AE@%" option for the %@AB@%BeginProc%@AE@% macro.  %@NL@%
  1856.  
  1857. When writing async services, do not call non-async services, and be sure the
  1858. routine can handle reentrancy.  %@NL@%
  1859.  
  1860.  
  1861. %@3@%%@CR:C6A00170019 @%%@AB@%17.1.5  VxD APIs (Call-Ins)%@AE@%%@EH@%%@NL@%
  1862.  
  1863. While VxD services are used to communicate with other enhanced Windows
  1864. virtual devices, APIs are used to communicate with software running in a
  1865. virtual machine. For example, the Shell device supports an API that is used
  1866. to communicate with WinOldAp (the Windows support program for non-Windows
  1867. applications) that runs in the System VM.%@CR:C6A00170020 @%%@CR:C6A00170021 @%%@NL@%
  1868.  
  1869. A VxD can support API for V86-mode code, protected-mode code, or both. The
  1870. procedure entry point(s) for the API is specified in the device declaration
  1871. macro (see Section 17.1.3, "VxD Declaration," for more details on
  1872. %@AB@%Declare_Virtual_Device%@AE@%). The VM software issues an INT 2FH with %@AB@%AX%@AE@% = 1684H
  1873. and %@AB@%BX%@AE@% = Device_ID to get the address to call to access the API. See
  1874. Appendix D, "Windows INT 2FH API," for more information.%@CR:C6A00170022 @%%@NL@%
  1875.  
  1876. The application can then call this address, passing appropriate information
  1877. in registers. The same address is used to call all API functions provided by
  1878. a single VxD.  %@NL@%
  1879.  
  1880. When such a call is made, the VMM will in turn call the VxD's API procedure
  1881. with the following parameters:  %@NL@%
  1882.  
  1883. %@AS@%  EBX = Current VM handle
  1884. %@AS@%  EBP = Client register structure
  1885. %@AS@%  Client_CS:IP = Instruction following API call%@AE@%
  1886.  
  1887. API procedures must examine the client registers (through the client
  1888. register structure) to determine which API call was made. The normal calling
  1889. convention uses %@AB@%AH%@AE@% = Major function number and %@AB@%AL%@AE@% = Minor function number.
  1890. Other registers are used for parameters to the functions. However, a device
  1891. can use any calling convention that is appropriate. If you want to return a
  1892. value to the caller, then the API procedure should modify the client
  1893. registers.  %@NL@%
  1894.  
  1895. 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@%
  1896.  
  1897.  
  1898. %@3@%%@CR:C6A00170023 @%%@AB@%17.1.6  VxD INT 2F Usage%@AE@%%@EH@%%@NL@%
  1899.  
  1900. Appendix E, "The Windows INT 2F API," includes several INT 2F functions that
  1901. are of interest to VxD writers. Specifically, there is an INT 2F to get the
  1902. address for calling the VxD API procedure, an INT 2F for a VxD to call out
  1903. to a T&SR or a DOS device driver, and an INT 2F by which a T&SR or DOS
  1904. device driver can specify a VxD to load when starting enhanced mode Windows.
  1905. If your VxD interacts with global software, be sure to study this appendix.
  1906. %@NL@%
  1907.  
  1908.  
  1909. %@2@%%@CR:C6A00170024 @%%@AB@%17.2  Building a VxD%@AE@%%@EH@%%@NL@%
  1910.  
  1911. This section describes in general the steps necessary to build and install a
  1912. VxD into the enhanced Windows environment. These steps are typically
  1913. specified and executed from the MAKE file. Detailed examples are also
  1914. included in a MAKE files located on the supplied DDK disks.%@CR:C6A00170025 @%%@NL@%
  1915.  
  1916. There are three required steps for building a VxD, with each requiring a
  1917. specific software tool:  %@NL@%
  1918.  
  1919.  
  1920.   1.  Assemble the VxD code with MASM5.10B, which is the special version of
  1921.       the assembler used to handle a new pseudo group, FLAT. (%@AB@%.ASM  %@AE@%.OBJ)%@NL@%
  1922.  
  1923.   2.  Link the .OBJ files utilizing a .DEF file, with LINK386. LINK386 is
  1924.       the linker used to create the special 32-bit .EXEs.(%@AB@%.OBJ %@AE@% %@AB@%.386%@AE@%, %@AB@%.MAP%@AE@%)%@NL@%
  1925.  
  1926.   3.  Declare the code to be a VxD with ADDHDR, which adds special VxD
  1927.       information into the .EXE produced with LINK386.(%@AB@%.386 %@AE@% %@AB@%.386%@AE@%)%@NL@%
  1928.  
  1929. %@STUB@%      An optional fourth step, is available for debugging:%@NL@%
  1930.  
  1931.   4.  Generate symbol files with MAPSYM32, which generates 32-bit symbol
  1932.       (.SYM) files for debugging.(%@AB@%.MAP  .%@AE@%SYM)%@NL@%
  1933.  
  1934.  
  1935. These four tools are included in this version of the DDK. See the following
  1936. sections for detailed invocation instructions.  %@NL@%
  1937.  
  1938. The following MAKE file sample is from the Virtual Printer Device (VPD). The
  1939. complete source for building the VPD is included on the DDK disks.  %@NL@%
  1940.  
  1941. %@AS@%  vpd.obj: vpd.asm
  1942. %@AS@%           masm5 -p -w2 vpd;
  1943. %@AS@%  
  1944. %@AS@%  vpd.386: vpd.obj vpd.def
  1945. %@AS@%           link386 vpd, vpd.386/NOI /NOD /NOP,/MAP,,vpd.def
  1946. %@AS@%           addhdr vpd.386
  1947. %@AS@%           mapsym32 vpd%@AE@%
  1948.  
  1949. The MAKE file assumes that the four tools are included in the MS-DOS %@AB@%PATH%@AE@%
  1950. command. If they are not, then you must modify the MAKE file to specify
  1951. their exact locations.  %@NL@%
  1952.  
  1953.  
  1954. %@3@%%@CR:C6A00170026 @%%@AB@%17.2.1  MASM5.10B%@AE@%%@EH@%%@NL@%
  1955.  
  1956. This is a special version of MASM that supports 32-bit, flat-model code. It
  1957. has been named MASM5 to differentiate it from other versions of MASM you may
  1958. already have. It has the same command-line options and format as MASM 5.1,
  1959. so you can refer to version 5.1 documentation for information on this
  1960. program.%@CR:C6A00170027 @%%@NL@%
  1961.  
  1962. It is recommended that the %@AB@%-p%@AE@% and %@AB@%-w2%@AE@% options be used when assembling
  1963. virtual devices. The %@AB@%-p%@AE@% option specifies that impure code segment references
  1964. should generate warning messages. This is desirable, because it is illegal
  1965. to write data with a %@AB@%CS%@AE@% override. The %@AB@%-w2%@AE@% option sets the warning level to
  1966. 2, so that warning messages are generated for such things as jumps that are
  1967. within SHORT range and for data size mismatches.  %@NL@%
  1968.  
  1969. MASM5 will look for INCLUDE files in the current directory and the INCLUDE
  1970. path specified by the environment variable INCLUDE. Therefore, the DDK
  1971. INCLUDE files (e.g., VMM.INC, VPICD.INC, and VDD.INC) should be either in
  1972. the current directory or located along the INCLUDE path.  %@NL@%
  1973.  
  1974.  
  1975. %@3@%%@CR:C6A00170028 @%%@AB@%17.2.2  LINK386%@AE@%%@EH@%%@NL@%
  1976.  
  1977. The LINK386 command line is as follows:%@CR:C6A00170029 @%%@NL@%
  1978.  
  1979. %@AS@%  LINK386 <object file>, <output file> {<options>}, <map file>, <def file>%@AE@%
  1980.  
  1981. For example:  %@NL@%
  1982.  
  1983. %@AS@%  link386 vpd, vpd.386/NOI /NOD /NOP, /MAP,,vpd.def%@AE@%
  1984.  
  1985. LINK386 links into one device file the individual object (OBJ) files that
  1986. make up a virtual device. By convention, Windows devices have the extension
  1987. .386. The command line specifies the object files(s), the desired output
  1988. file, option switches, and definition file. The following list describes the
  1989. option switches used to link a VxD.  %@NL@%
  1990.  
  1991. %@TH:  17   929 02 12 24 40 @%Option      Full Name               Description%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@AB@%/NOI%@AE@%        NOIGNORECASE            Specifies that case should not be                                     ignored.%@AB@%/NOD%@AE@%        NODEFAULTLIBRARYSEARCH  Specifies that LINK386 should not                                     search for default libraries.%@AB@%/NOP%@AE@%        NOPACKEDCODE            Specifies that code segments should %@AB@%%@AE@%                                    not be packed into one code segment in                                    the .EXE file.%@AB@%/MAP%@AE@%                                Specifies that all public symbols                                     should be included in the MAP file.%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@TE:  17   929 02 12 24 40 @%
  1992.  
  1993. Definition (DEF) files are used by LINK386 to identify the device descriptor
  1994. block within the device and the types of segments. DEF files for virtual
  1995. devices all look similar to the following example:  %@NL@%
  1996.  
  1997. %@AS@%  LIBRARY VPD%@AE@%
  1998.  
  1999. %@AS@%  DESCRIPTION 'Win386 VPD Device (Version 2.0)'%@AE@%
  2000.  
  2001. %@AS@%  EXETYPE DEV386%@AE@%
  2002.  
  2003. %@AS@%  SEGMENTS
  2004. %@AS@%   _LTEXT PRELOAD NONDISCARDABLE
  2005. %@AS@%   _LDATA PRELOAD NONDISCARDABLE
  2006. %@AS@%   _ITEXT CLASS 'ICODE' DISCARDABLE
  2007. %@AS@%   _IDATA CLASS 'ICODE' DISCARDABLE
  2008. %@AS@%   _TEXT CLASS 'PCODE'   NONDISCARDABLE
  2009. %@AS@%   _DATA CLASS 'PCODE'   NONDISCARDABLE%@AE@%
  2010.  
  2011. %@AS@%  EXPORTS
  2012. %@AS@%   VPD_DDB @1%@AE@%
  2013.  
  2014. The LIBRARY line is required to identify the device as a module that is part
  2015. of a system rather than an executable application. The DESCRIPTION line is
  2016. optional and simply records the text string into the .386 file. The EXETYPE
  2017. line is required to identify the .386 file as an enhanced Windows device
  2018. file.  %@NL@%
  2019.  
  2020. The SEGMENTS section is identical for all devices, because it identifies the
  2021. six possible types of protected-mode segments that can be part of a device.
  2022. (If a device has a real-mode initialization section, then it can have seven
  2023. types of segments. However, the real-mode section does not need any special
  2024. identification in the DEF file.)  %@NL@%
  2025.  
  2026. The EXPORTS section is also required; it identifies the name and location of
  2027. the device descriptor block for the virtual device. It must match the name
  2028. used in the %@AB@%Declare_Virtual_Device%@AE@% statement in the device source, with _DDB
  2029. appended to the end. It must also be identified as ordinal number 1 with the
  2030. @ symbol.  %@NL@%
  2031.  
  2032.  
  2033. %@3@%%@CR:C6A00170030 @%%@AB@%17.2.3  ADDHDR%@AE@%%@EH@%%@NL@%
  2034.  
  2035. The ADDHDR command line is as follows:%@CR:C6A00170031 @%%@NL@%
  2036.  
  2037. %@AS@%  addhdr <filename>%@AE@%
  2038.  
  2039. For example:  %@NL@%
  2040.  
  2041. %@AS@%  addhdr vpd.386%@AE@%
  2042.  
  2043. ADDHDR simply reads the specified 32-bit .EXE file, performs some validation
  2044. checks, and writes some additional header information needed by the enhanced
  2045. Windows loader into the file's .EXE header.  %@NL@%
  2046.  
  2047.  
  2048. %@3@%%@CR:C6A00170032 @%%@AB@%17.2.4  MAPSYM32%@AE@%%@EH@%%@NL@%
  2049.  
  2050. The MAPSYM32 command line is as follows:%@CR:C6A00170033 @%%@NL@%
  2051.  
  2052. %@AS@%  mapsym32 <device name>%@AE@%
  2053.  
  2054. For example:  %@NL@%
  2055.  
  2056. %@AS@%  mapsym32 vpd%@AE@%
  2057.  
  2058. MAPSYM32 reads a MAP file and creates a 32-bit .SYM file for use with the
  2059. Windows debugger, WDEB386. The %@AB@%/MAP%@AE@% option must be specified for LINK386 to
  2060. generate the necessary MAP file.  %@NL@%
  2061.  
  2062.  
  2063. %@3@%%@CR:C6A00170034 @%%@AB@%17.2.5  Installing a VxD%@AE@%%@EH@%%@NL@%
  2064.  
  2065. In order to install the newly created VxD with the rest of enhanced Windows,
  2066. edit the SYSTEM.INI file. in the %@AB@%[386ENH]%@AE@% section by inserting %@AB@%DEVICE%@AE@% =
  2067. <your VxD file name> and put your file in the Windows SYSTEM subdirectory.%@CR:C6A00170035 @%%@NL@%
  2068.  
  2069.  
  2070. %@2@%%@CR:C6A00170036 @%%@AB@%17.3  Initializing a VxD%@AE@%%@EH@%%@NL@%
  2071.  
  2072. As described in Chapter 16, "Overview of Windows in 386 Enhanced Mode," VxDs
  2073. are initialized along with the enhanced Windows environment. Both real-mode
  2074. and protected-mode code may be used and are described in the following
  2075. subsections.%@CR:C6A00170037 @%%@NL@%
  2076.  
  2077.  
  2078. %@3@%%@CR:C6A00170038 @%%@AB@%17.3.1  Real-Mode Initialization%@AE@%%@EH@%%@NL@%
  2079.  
  2080. Each VxD can have a portion that is run in real mode at load time. This
  2081. capability is provided to enable a VxD to determine whether or not it can
  2082. operate in the current environment and to provide information to the loader
  2083. about how it should vary the environment. This portion is only executed at
  2084. load time and, then is discarded.%@CR:C6A00170039 @%%@CR:C6A00170040 @%%@NL@%
  2085.  
  2086. A real-mode portion is included in the same binary file as the rest of the
  2087. VxD code and data, but is located in a special 16-bit sement. It has a
  2088. single entry point, declared as a NEAR procedure. At load time, if the
  2089. loader determines that a real-mode portion is present, it loads it and calls
  2090. its entry point as specified by the END statement at the end of the file
  2091. (%@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
  2092. must be mixed in the same segment. The code can then perform the checks that
  2093. are necessary and return an exit code back to the loader.  %@NL@%
  2094.  
  2095. Valid exit codes are as follows (see VMM.INC for equates):  %@NL@%
  2096.  
  2097.  
  2098.   ■   0 - Everything is fine, and the loader should continue loading the
  2099.       protected-mode portion and the rest of the VxDs.%@NL@%
  2100.  
  2101.   ■   1 - This device is not compatible with the current environment and
  2102.       will not be loaded, but the loader can continue to load other VxDs.%@NL@%
  2103.  
  2104.   ■   2 - Something is wrong and the loader should abort the Windows load
  2105.       completely.%@NL@%
  2106.  
  2107.  
  2108. If 1 or 2 is returned, then the loader will normally print an appropriate
  2109. error message naming the VxD that failed. If the real-mode portion has
  2110. already handled the message reporting or does not want any default error
  2111. message, then it should set the high bit of the return code in %@AB@%AX%@AE@% (i.e.,
  2112. 8001H or 8002H.)  %@NL@%
  2113.  
  2114. The real-mode portion can also inform the loader to do the following:  %@NL@%
  2115.  
  2116.  
  2117.   ■   Pass a DWORD of reference data to the protected-mode portion of the
  2118.       device.%@NL@%
  2119.  
  2120.   ■   Pass a table of pages in low memory (0-1Mb) that should be excluded
  2121.       from general use by the enhanced Windows memory manager.%@NL@%
  2122.  
  2123.   ■   Pass a table of pointers to data that should be instanced for each
  2124.       virtual machine. %@NL@%
  2125.  
  2126.  
  2127. It is possible for a VxD to exclude pages and/or declare instance data
  2128. without actually having a protected-mode portion; it should return 8001H as
  2129. the return code, so that the loader will attempt no further loading of the
  2130. device and will not display the default error message.  %@NL@%
  2131.  
  2132. The real-mode portion can perform most BIOS or MS-DOS interrupts and examine
  2133. memory to check the environment of the machine. It cannot attempt to perform
  2134. any type of MS-DOS exit calls because these will halt the loader in an
  2135. unclean state, and it will be necessary to reboot the machine. Also, any
  2136. open files should be closed before returning since they will not be closed
  2137. by the loader.  %@NL@%
  2138.  
  2139. The following is a summary of entry assumption:  %@NL@%
  2140.  
  2141. CS = DS = ES = segment of loaded code and data IP = specified entry point or
  2142. 0. SI = environment segment, passed to the loader from MS-DOS AX = VMM
  2143. version number BX = flags    bit 0: duplicate device ID already loaded
  2144. bit 1: duplicate ID was from the INT 2F device list    bit 2: this device is
  2145. from the INT 2F device list %@AB@%EDX%@AE@% = reference data from INT 2F response, or 0
  2146. %@NL@%
  2147.  
  2148. %@AB@%SS:SP%@AE@% point to loader's stack.  %@NL@%
  2149.  
  2150. The following is a summary of exit assumptions:  %@NL@%
  2151.  
  2152. Must return with a NEAR return %@AB@%AX%@AE@% = return code (see above) %@AB@%BX%@AE@% = ptr to list
  2153. of pages to exclude (0, if none), where:    list is = one or more words in
  2154. the range 1 to 9FH (terminated) by a word of zero %@AB@%SI%@AE@% = ptr to list of
  2155. Instance data items (0, if none), where:     list is = one or more instance
  2156. data items followed by three words   of zero (note that 0-3FF, the interrupt
  2157. vectors are   always instanced). instance data item = pointer to   data
  2158. (word segment, word offset),word length of data  %@NL@%
  2159.  
  2160. %@AB@%EDX%@AE@% = DWORD of reference data to be passed to the protected-mode portion.
  2161. (This can be a linear pointer to ROM data, a constant, etc. that will affect
  2162. the way the protected portion might operate. For example, an EBIOS device
  2163. can pass the EBIOS page number, so that the protected-mode portion does not
  2164. have to look for the page again.)  %@NL@%
  2165.  
  2166. All the other registers except SS:SP can be modified.  %@NL@%
  2167.  
  2168. The macros %@AB@%VxD_REAL_INIT_SEG%@AE@% and %@AB@%VxD_REAL_INIT_ENDS%@AE@% are defined in VMM.INC
  2169. to facilitate creating a real-mode portion of a device driver. The real-mode
  2170. portion cannot access code or data outside of its segment. If this is
  2171. attempted, the linker will generate warnings and a corrupt .386 file. Fixed
  2172. segments such as the BIOS (40H) segments are an exception to this. It is
  2173. possible to have declared in multiple source files real-mode portions that
  2174. will all be linked together (e.g., separating message text from the code).  %@NL@%
  2175.  
  2176. The following is an example of real-mode initialization code:  %@NL@%
  2177.  
  2178. %@AS@%  VxD_REAL_INIT_SEG
  2179. %@AS@%  BeginProc ebios_init
  2180. %@AS@%   mov ah, 0C0h
  2181. %@AS@%   int 15h
  2182. %@AS@%   test es:[bx.SD_feature1], EBIOS_allocated
  2183. %@AS@%   jz short no_ebios_fnd
  2184. %@AS@%   mov ah, 0C1h      ; get segment adr of EBIOS
  2185. %@AS@%   int 15h
  2186. %@AS@%  
  2187. %@AS@%   jc short no_ebios_fnd
  2188. %@AS@%   mov ax, es    ; get EBIOS segment address
  2189. %@AS@%   shr ax, 8    ; convert to a page #
  2190. %@AS@%   movzx edx, ax     ; return EBIOS pg as ref 
  2191. %@AS@%        ; data
  2192. %@AS@%   mov bx, OFFSET exc_ebios_page  ; ptr to exclusion table
  2193. %@AS@%   mov [bx], ax    ; exclude EBIOS page
  2194. %@AS@%        ; from memory manager use
  2195. %@AS@%   xor si, si    ; no instance data to 
  2196. %@AS@%        ; declare
  2197. %@AS@%   mov ax, Device_Load_Ok  ; go ahead and load the 
  2198. %@AS@%        ; device
  2199. %@AS@%   jmp short init_exit   ; return to loader
  2200. %@AS@%  
  2201. %@AS@%  no_ebios_fnd:
  2202. %@AS@%   mov ah, 9
  2203. %@AS@%   mov dx, OFFSET no_ebios_msg    ; print message thru DOS
  2204. %@AS@%   int 21h
  2205. %@AS@%   xor bx, bx    ; no exclusion table
  2206. %@AS@%   xor si, si    ; no instance data table
  2207. %@AS@%   xor edx, edx    ; no reference data
  2208. %@AS@%   mov ax, Abort_Device_Load + No_Fail_Message
  2209. %@AS@%        ; don't load pmode portion 
  2210. %@AS@%        ; and don't display an 
  2211. %@AS@%        ; error msg
  2212. %@AS@%  
  2213. %@AS@%  init_exit:
  2214. %@AS@%   ret
  2215. %@AS@%  exc_ebios_page dw 0, 0
  2216. %@AS@%  no_ebios_msg db 'PS/2 type EBIOS not detected', 13, 10, '$'
  2217. %@AS@%  EndProc ebios_init
  2218. %@AS@%  VxD_REAL_INIT_ENDS
  2219. %@AS@%  END ebios_init     ; specify real mode 
  2220. %@AS@%        ; initialization entry point%@AE@%
  2221.  
  2222.  
  2223. %@3@%%@CR:C6A00170041 @%%@AB@%17.3.2  Protected-Mode Initialization%@AE@%%@EH@%%@NL@%
  2224.  
  2225. The enhanced Windows environment has a three-phase, protected-mode
  2226. initialization. Returning a carry during any of the phases will abort the
  2227. VxD load.%@CR:C6A00170042 @%%@NL@%
  2228.  
  2229.  
  2230. %@4@%%@AB@%Phase 1. Sys_Critical_Init%@AE@%%@EH@%%@NL@%
  2231.  
  2232. During the first phase of initialization, interrupts are not yet enabled.
  2233. Therefore, this phase should accomplish the following tasks as quickly as
  2234. possible.  %@NL@%
  2235.  
  2236.  
  2237.   ■   Initialization of critical functions necessary when interrupts are
  2238.       enabled. %@NL@%
  2239.  
  2240.   ■   Claiming a particular range of V86 pages if necessary (such as the
  2241.       video memory for the VDD).%@NL@%
  2242.  
  2243.   ■   Initialization of data needed by the services provided by the VxD.%@NL@%
  2244.  
  2245.   ■   During this phase, the System VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% commands
  2246.       must not be used.%@NL@%
  2247.  
  2248.  
  2249.  
  2250. %@4@%%@AB@%Phase 2. Device_Init%@AE@%%@EH@%%@NL@%
  2251.  
  2252. During this phase most VxDs do the bulk of their initialization. They will:
  2253. %@NL@%
  2254.  
  2255.  
  2256.   ■   Allocate their Control Block area%@NL@%
  2257.  
  2258.   ■   Allocate other required memory areas%@NL@%
  2259.  
  2260.   ■   Hook interrupts%@NL@%
  2261.  
  2262.   ■   Hook I/O ports%@NL@%
  2263.  
  2264.   ■   Specify instance data%@NL@%
  2265.  
  2266.   ■   Initialize themselves%@NL@%
  2267.  
  2268.  
  2269. The System VM's Control Block should be set up with the inital state of the
  2270. VxD. Since the System VM has already been created, calls such as
  2271. Simulate_Int or Exec_Int is allowed.  %@NL@%
  2272.  
  2273.  
  2274. %@4@%%@AB@%Phase 3. Init_Complete%@AE@%%@EH@%%@NL@%
  2275.  
  2276. This is the final phase of %@AB@%Device_Init%@AE@% that is called just before the WIN386
  2277. INIT pages are released and the instance snapshot is taken. VxDs that want
  2278. to search for a region of V86 memory to use should do so during this phase.
  2279. Most devices, though, will not need to do anything here.  %@NL@%
  2280.  
  2281.  
  2282. %@2@%%@CR:C6A00170043 @%%@AB@%17.4  Tracking the VM States%@AE@%%@EH@%%@NL@%
  2283.  
  2284. Most likely, the VxD that you are writing needs to keep track of the status
  2285. of the different VMs that may need your VxD. This includes VM creation,
  2286. initialization, and termination. The following subsections describe these
  2287. and other possible VM states.%@CR:C6A00170044 @%%@NL@%
  2288.  
  2289.  
  2290. %@3@%%@CR:C6A00170045 @%%@AB@%17.4.1  VM Creation and Initialization%@AE@%%@EH@%%@NL@%
  2291.  
  2292. Like the initialization of the enhanced Windows environment, a VM's go
  2293. through a multi-phase initialization process.%@CR:C6A00170046 @%%@NL@%
  2294.  
  2295.  
  2296. %@4@%%@AB@%Phase 1. Create_VM%@AE@%%@EH@%%@NL@%
  2297.  
  2298. This call creates a new VM. %@AB@%EBX%@AE@% = VM handle of the new VM. Returning Carry
  2299. will fail the %@AB@%Create_VM%@AE@%. VxDs should initialize data associated with the VM,
  2300. especially the control block.  %@NL@%
  2301.  
  2302.  
  2303. %@4@%%@AB@%Phase 2. VM_Critical_Init%@AE@%%@EH@%%@NL@%
  2304.  
  2305. %@AB@%EBX%@AE@% = VM handle of the new VM. Returning Carry will cause the VM to
  2306. %@AB@%VM_Not_Executeable%@AE@%, then be destroyed (see Section 17.4.3). VM %@AB@%Simulate_Int%@AE@%
  2307. or %@AB@%Exec_Int%@AE@% activity is not allowed.  %@NL@%
  2308.  
  2309.  
  2310. %@4@%%@AB@%Phase 3. VM_Init and Sys_VM_Init%@AE@%%@EH@%%@NL@%
  2311.  
  2312. The VxD interacts with the VM in order to initialize the state of the
  2313. software in the VM (e.g., the VDD does an INT 10H to set the initial display
  2314. mode.  %@NL@%
  2315.  
  2316. System VM initialization is the same as other VM initializations except its
  2317. Phase 1 and 2 are done at Device_Init and if Carry is returned, all of
  2318. enhanced Windows will exit.  %@NL@%
  2319.  
  2320.  
  2321. %@3@%%@CR:C6A00170047 @%%@AB@%17.4.2  VM State Changes%@AE@%%@EH@%%@NL@%
  2322.  
  2323. During the normal execution of enhanced Windows, VMs will go through state
  2324. changes. Most state changes may be ignored by VxDs. However, depending on
  2325. the purpose of the VxD, some may require VxD response. The following calls
  2326. describe the possible VM state changes.  %@NL@%
  2327.  
  2328.  
  2329. %@4@%%@AB@%VM_Suspend%@AE@%%@EH@%%@NL@%
  2330.  
  2331. The VM is not runnable until a resume. %@AB@%EBX%@AE@% = VM handle. The call cannot be
  2332. failed. The VxD should unlock any resources associated with the VM.  %@NL@%
  2333.  
  2334. The VM_Suspend message is sent only once each time the VM is suspended. Note
  2335. that there is a bit the the control block CB_VM_Status flags indicating the
  2336. current state. See VMM.INC for details.  %@NL@%
  2337.  
  2338.  
  2339. %@4@%%@AB@%VM_Resume%@AE@%%@EH@%%@NL@%
  2340.  
  2341. The VM is leaving a suspended state. %@AB@%EBX%@AE@% = VM handle. Returning a carry
  2342. fails and backs out of the resume. Lock any resources and otherwise prepare
  2343. internal data structures for the VM to start running again.  %@NL@%
  2344.  
  2345. The VM_Resume message is sent only once after a VM_Suspend message has been
  2346. sent.  %@NL@%
  2347.  
  2348.  
  2349. %@4@%%@AB@%Set_Device_Focus%@AE@%%@EH@%%@NL@%
  2350.  
  2351. This sets the focus of the specified VxD to the specified VM. %@AB@%EBX%@AE@% = VM
  2352. handle of desired VM. %@AB@%EDX%@AE@% = VxD ID. For VxD specific set focus, %@AB@%EDX%@AE@% = 0 for
  2353. device critical set focus (all devices).  %@NL@%
  2354.  
  2355. This call cannot be failed. Restore the hardware associated with the device
  2356. to the state of the specified VM. As much as possible, remove VxD
  2357. interaction with VM (such as disabling I/O trapping) so that VM can run as
  2358. fast as possible.  %@NL@%
  2359.  
  2360.  
  2361. %@4@%%@AB@%Begin_Message_Mode%@AE@%%@EH@%%@NL@%
  2362.  
  2363. This call prepares the device for message processing. This is only of
  2364. interest to the keyboard, mouse, and display. When in message mode, special
  2365. services provided by the display and keyboard are used to interact with the
  2366. user. Message mode is used for the ALT+TAB screen and for message boxes when
  2367. Windows is not available to process a message box. EBX = VM handle going
  2368. into message mode. This call cannot be failed.  %@NL@%
  2369.  
  2370.  
  2371. %@4@%%@AB@%End_Message_Mode%@AE@%%@EH@%%@NL@%
  2372.  
  2373. %@AB@%EBX%@AE@% = VM handle leaving message mode. This call cannot be failed.  %@NL@%
  2374.  
  2375.  
  2376. %@4@%%@AB@%Reboot_Processor%@AE@%%@EH@%%@NL@%
  2377.  
  2378. This call requests a machine reboot. The device (usually the keyboard
  2379. device) that knows how to reboot the machine does the necessary operations.
  2380. %@NL@%
  2381.  
  2382.  
  2383. %@4@%%@AB@%Query_Destroy%@AE@%%@EH@%%@NL@%
  2384.  
  2385. This call asks if it can destroy the running VM. %@AB@%Query_Destroy%@AE@% is an
  2386. information call made by the Shell device before an attempt is made to
  2387. initiate a destroy VM sequence on a running VM that has not exited normally.
  2388. %@AB@%EBX%@AE@% = VM handle. Returning Carry indicates that a VxD has a problem with
  2389. allowing this. It is recommended that the VxD returning the Carry indicating
  2390. a problem call %@AB@%SHELL_Message%@AE@% to post an informational dialog about the
  2391. reason for the problem.  %@NL@%
  2392.  
  2393.  
  2394. %@4@%%@AB@%Debug_Query%@AE@%%@EH@%%@NL@%
  2395.  
  2396. %@AB@%Debug_Query%@AE@% is a special call for device-specific DEBUG information display
  2397. and activity. This call is made in response to the user typing a period
  2398. followed by the VxD name in response to the WDEB386 prompt. The VxD name is
  2399. declared with the %@AB@%Declare_Virtual_Device%@AE@% macro (see Section 17.1.3, "VxD
  2400. Declaration"). Use conditional assembly to remove this call from the final
  2401. VxD.  %@NL@%
  2402.  
  2403.  
  2404. %@3@%%@CR:C6A00170048 @%%@AB@%17.4.3  VM Termination%@AE@%%@EH@%%@NL@%
  2405.  
  2406. Graceful termination of a VM occurs in the following three steps:%@CR:C6A00170049 @%%@NL@%
  2407.  
  2408.  
  2409. %@4@%%@AB@%Phase 1. VM_Terminate%@AE@%%@EH@%%@NL@%
  2410.  
  2411. During this phase of normal VM termination. %@AB@%EBX%@AE@% = VM handle. Call cannot be
  2412. failed. VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is allowed.  %@NL@%
  2413.  
  2414.  
  2415. %@4@%%@AB@%Sys_VM_Terminate%@AE@%%@EH@%%@NL@%
  2416.  
  2417. Same as %@AB@%VM_Terminate%@AE@%, except terminates the System VM. System VM
  2418. %@AB@%Simulate_Int%@AE@%, %@AB@%Exec_Int%@AE@% activity is allowed. System VM will always be the
  2419. last VM terminated, and thereby indicates that enhanced Windows is
  2420. terminating. This call is only made during a normal exit, during a crash
  2421. exit this call is not made.  %@NL@%
  2422.  
  2423.  
  2424. %@4@%%@AB@%Phase 2. VM_Not_Executeable%@AE@%%@EH@%%@NL@%
  2425.  
  2426. During the second phase of VM termination. %@AB@%EBX%@AE@% = VM handle, %@AB@%EDX%@AE@% = Flags (see
  2427. VMM.INC). Notice that in the case of destroying a running VM, this is the
  2428. first call made (i.e., the %@AB@%VM_Terminate%@AE@% call does not occur). Call cannot be
  2429. failed. VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is %@AI@%not%@AE@% allowed. Flags for
  2430. %@AB@%VM_Not_Executeable%@AE@% control call (passed in %@AB@%EDX%@AE@%) are as follows:  %@NL@%
  2431.  
  2432. %@TH:   7   501 02 22 54 @%Flag                  Meaning%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@AB@%VNE_Crashed%@AE@%           VM has crashed.%@AB@%VNE_Nuked%@AE@%             VM was destroyed while active.%@AB@%VNE_CreateFail%@AE@%        Some device failed %@AB@%Create_VM%@AE@%.%@AB@%VNE_CrInitFail%@AE@%        Some device failed %@AB@%VM_Critical_Init%@AE@%.%@AB@%VNE_InitFail%@AE@%          Some device failed %@AB@%VM_Init%@AE@%.%@TE:   7   501 02 22 54 @%
  2433.  
  2434.  
  2435. %@4@%%@AB@%Phase 3. Destroy_VM%@AE@%%@EH@%%@NL@%
  2436.  
  2437. During this final phase of VM termination. %@AB@%EBX%@AE@% = VM handle. Notice that
  2438. considerable time can elapse between the %@AB@%VM_Not_Executeable%@AE@% call and this
  2439. call. Call cannot be failed. VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is not
  2440. allowed.  %@NL@%
  2441.  
  2442.  
  2443. %@2@%%@CR:C6A00170050 @%%@AB@%17.5  Exiting Windows%@AE@%%@EH@%%@NL@%
  2444.  
  2445. There are two calls that can alert a VxD that enhanced Windows is exiting:
  2446. %@AB@%System_Exit%@AE@% and %@AB@%Sys_Critical_Exit%@AE@%. They both come after %@AB@%Sys_VM_Terminate%@AE@%, is
  2447. Windows is exiting normally.  %@NL@%
  2448.  
  2449.  
  2450. %@4@%%@AB@%System_Exit%@AE@%%@EH@%%@NL@%
  2451.  
  2452. This call is made when Windows is exiting either normally or via a crash.
  2453. Interrupts are enabled. System VM %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is not
  2454. allowed. However, the VxD may modify the System VM memory to restore the
  2455. system state to allow a graceful exiting of Windows.  %@NL@%
  2456.  
  2457.  
  2458. %@4@%%@AB@%Sys_Critical_Exit%@AE@%%@EH@%%@NL@%
  2459.  
  2460. This call is made when enhanced Windows is exiting either normally or via a
  2461. crash. Interrupts are disabled. %@AB@%Simulate_Int%@AE@% and %@AB@%Exec_Int%@AE@% activity is not
  2462. allowed. VxDs should reset their associated hardware to a quiescent state to
  2463. allow a graceful return to real mode.  %@NL@%
  2464.  
  2465.  
  2466. %@2@%%@CR:C6A00170051 @%%@AB@%17.6  Debugging a VxD%@AE@%%@EH@%%@NL@%
  2467.  
  2468. Their are a number of features built into the WDEB386 debugger and the
  2469. debugging version of the 386 enhanced mode environment to aid you in
  2470. debugging your VxD. These features require a terminal hooked up to a COM
  2471. port, as described in the WDEB386 documentation in the Microsoft SDK. When
  2472. making use of these features in your code, be sure to remove them from your
  2473. final product. See DEBUG.INC for useful macros and the sample source for
  2474. usage.  %@NL@%
  2475.  
  2476.  
  2477. %@3@%%@CR:C6A00170052 @%%@AB@%17.6.1  Entering WDEB386%@AE@%%@EH@%%@NL@%
  2478.  
  2479. There are four ways to initially enter the debugger:  %@NL@%
  2480.  
  2481.  
  2482.   1.  Type CTL+ALT+SYSREQ.%@NL@%
  2483.  
  2484.   2.  Generate a non-maskable interrupt (this can be disabled with the "V2"
  2485.       command).%@NL@%
  2486.  
  2487.   3.  Place an "INT 1" instruction in your code. This method should be used
  2488.       when debugging the real-mode portion of your VxD. An "INT 3" may also
  2489.       be used but the debugger will not automatically pass over it. %@NL@%
  2490.  
  2491.   4.  Specify "\b" as a command line parameter to WDEB386. This will pass
  2492.       control to the debugger just prior to VMM initialization, after all
  2493.       VxDs have been loaded and the processor is running in protected mode.%@NL@%
  2494.  
  2495.  
  2496.  
  2497. %@3@%%@CR:C6A00170053 @%%@AB@%17.6.2  Tracing Paths of Execution%@AE@%%@EH@%%@NL@%
  2498.  
  2499. You can dump strings of text and registers in hexadecimal to the debug
  2500. terminal utilizing the %@AB@%TRACE_OUT%@AE@% and %@AB@%DEBUG_OUT%@AE@% macros.  %@NL@%
  2501.  
  2502. The %@AB@%Queue_out%@AE@% macro allows you to dump the same information to a trace
  2503. queue. You can also send VMM entry and exit information to the queue by
  2504. using the ".t" command, and send procedure logging information with the .VMM
  2505. command.  %@NL@%
  2506.  
  2507. %@AB@%Trace_Out%@AE@% and %@AB@%Debug_Out%@AE@% strings have the following special characters
  2508. defined:  %@NL@%
  2509.  
  2510. %@AS@%  #<register>, where 
  2511. %@AS@%  <register> is a 32 bit register, a 16 bit register
  2512. %@AS@%      or AL, BL, CL or DL. This will insert the hex value for
  2513. %@AS@%      the indicated register into the string that is output at
  2514. %@AS@%      the location where #<register> appears. 
  2515. %@AS@%  ?[<16 bit register>:]<32 bit register>, where the 16 bit register is
  2516. %@AS@%      a selector and the 32 bit register is an offset within
  2517. %@AS@%      that selector. If the 16 bit register is not specified,
  2518. %@AS@%      then 28h, the VxD code segment, is assumed. This will insert
  2519. %@AS@%      the symbol table name of the closest previous symbol
  2520. %@AS@%      corresponding to the address specified. If no symbol is
  2521. %@AS@%      found, nothing is printed (e.g. ?AX:EBX).%@AE@%
  2522.  
  2523. Additionally, a VxD can put data into the trace queue that is listed with
  2524. the .LQ command. To do this use the %@AB@%Queue_Out%@AE@% macro:  %@NL@%
  2525.  
  2526. %@AS@%  Queue_Out "<string>"[,<reg1>[,<reg2>»%@AE@%
  2527.  
  2528. where reg1 and reg2 are 32-bit registers. Reg1 will be in the %@AB@%EAX%@AE@% register
  2529. when the string is printed and Reg2 will be in the %@AB@%EBX%@AE@% register. You can use
  2530. the special "#" and "?" characters in the string, identifying %@AB@%EAX%@AE@% (or a
  2531. subset of E%@AB@%AX%@AE@%) and %@AB@%EBX%@AE@% (or a subset) to insert the values of reg1 and reg2
  2532. in the string. By default, reg1=%@AB@%EAX%@AE@% and reg2=%@AB@%EBX%@AE@%. The default is used if you
  2533. do not specify the parameters to the macro.  %@NL@%
  2534.  
  2535.  
  2536. %@3@%%@CR:C6A00170054 @%%@AB@%17.6.3  Querying the VxD State%@AE@%%@EH@%%@NL@%
  2537.  
  2538. As described previously, one of the messages sent to the %@AB@%VxD_Control%@AE@% routine
  2539. is %@AB@%Debug_Query%@AE@%. This message is passed when you type ". name" to WDEB386.
  2540. See the sample sources for examples on how to use trace-out and the
  2541. %@AB@%In_Debug_Chr%@AE@% service to generate useful debugging information.  %@NL@%
  2542.  
  2543. The .VMM command will give you a menu of useful information on the state of
  2544. the system as well as a way to toggle procedure logging.  %@NL@%
  2545.  
  2546.  
  2547.  
  2548.  
  2549.  
  2550.  
  2551. %@CR:C6A00180001 @%%@1@%%@AB@%Chapter 18  The VDD and Grabber DLL%@AE@%%@EH@%%@NL@%
  2552. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2553.  
  2554. This chapter describes the Virtual Display Device (VDD) and the Grabber DLL,
  2555. a Microsoft Windows dynamic-link library. Software writers should be
  2556. familiar with the terms and concepts covered in Chapter 16, "Overview of
  2557. Windows in 386 Enhanced Mode," and Chapter 17, "Virtual Device Programming
  2558. Topics," before continuing with this chapter.  %@NL@%
  2559.  
  2560. The topics in this chapter are presented in the following order:  %@NL@%
  2561.  
  2562.  
  2563.   ■   Introduction to VDDs and the Grabber DLL%@NL@%
  2564.  
  2565.   ■   VDD programming and the Grabber API%@NL@%
  2566.  
  2567.   ■   Grabber DLL interfaces
  2568. %@NL@%
  2569.  
  2570.  
  2571.  
  2572. %@2@%%@CR:C6A00180002 @%%@AB@%18.1  Introduction to VDDs and the Grabber DLL%@AE@%%@EH@%%@NL@%
  2573.  
  2574. The VDD and Grabber DLL are used by Windows when running in enhanced mode to
  2575. support a video adapter. The %@AI@%VDD%@AE@% is the virtual device that emulates display
  2576. hardware for applications running in virtual machines. The %@AI@%Grabber%@AE@%, like all
  2577. dynamic-link libraries, provides a library of routines available to
  2578. application programs. In this case, the application is the Windows WINOLDAP
  2579. program, and the routines are used primarily for rendering the video display
  2580. of a non-Windows application into a format that Windows can use.  %@NL@%
  2581.  
  2582. The Windows 3.0 DDK provides source code for a variety of VDDs and Grabbers.
  2583. These should prove valuable as stubs and examples.  %@NL@%
  2584.  
  2585.  
  2586. %@3@%%@CR:C6A00180003 @%%@AB@%18.1.1  VDD Interaction with WINOLDAP%@AE@%%@EH@%%@NL@%
  2587.  
  2588. When Windows detects the user starting a non-Windows application, it runs
  2589. the Windows program called WINOLDAP and passes the name of the application
  2590. to it. WINOLDAP searches for a .PIF file and, then, makes a call to the
  2591. Shell device with all the parameters necessary to execute the application in
  2592. a new VM. The Shell makes a series of system control calls with the
  2593. appropriate messages to create and start the VM. It also calls the
  2594. %@AB@%VDD_PIF_State%@AE@% and %@AB@%VDD_Set_VM_Type%@AE@% services to let the VDD know the user
  2595. preferences for this VM.  %@NL@%
  2596.  
  2597. WINOLDAP also loads the Grabber DLL, which it uses for rendering the VM's
  2598. display into the Windows display driver's bitmap format. The rendering is
  2599. done both for a full screen grab into the Clipboard (the VDD's grab routine
  2600. is called when this is done), and for displaying the VM in a window. This
  2601. rendering occurs in response to changes in video state caused by either the
  2602. VM's application or the user.  %@NL@%
  2603.  
  2604. %@TH:  29  1667 02 27 27 27 @%Cause of video state                                  change                     Example                    Effect%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%Application Program        Updating displayed         VDD sends WINOLDAP a                            information                screen update message.                                                      WINOLDAP calls the                                                       Grabber to update the                                                       window.                                                      Grabber calls the VDD to                                                       render the video state                                                       into the application's                                                       window.User Action                Resizing a window          Windows sends WINOLDAP a                                                       paint message.                                                      WINOLDAP calls the                                                       Grabber to paint the                                                       window.                                                      Grabber calls the VDD to                                                       render the video state                                                       into the application's                                                       window.%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@TE:  29  1667 02 27 27 27 @%
  2605.  
  2606. Notice that the Grabber can be reentered. WINOLDAP may be in the process of
  2607. handling a paint message when it receives an update message. Care must be
  2608. exercised to ensure the correct handling of all the possible cases.  %@NL@%
  2609.  
  2610.  
  2611. %@3@%%@CR:C6A00180004 @%%@AB@%18.1.2  VDD User Messages%@AE@%%@EH@%%@NL@%
  2612.  
  2613. When the VDD encounters a situation that requires a user's choice or
  2614. interaction, it uses the Shell message services to print messages. For
  2615. example, when there is not enough memory to save and restore a VM's video
  2616. state, the user is informed of the problem and that a portion of the display
  2617. may be lost.  %@NL@%
  2618.  
  2619. Messages are sent while in %@AI@%message mode%@AE@%, which is instigated with the
  2620. %@AB@%Begin_Message_Mode%@AE@% control call. Message mode enables the Shell device to
  2621. use the VDD message services to output text to the screen without changing
  2622. the VM's video state. When the message is complete, an %@AB@%End_Message_Mode%@AE@%
  2623. control call is made that restores the focus VM to the hardware. See Section
  2624. 18.2.3, "Environment State Change Requirements for a VDD," for a description
  2625. of the message mode services.%@CR:C6A00180005 @%%@AI@%  %@AE@%%@NL@%
  2626.  
  2627.  
  2628. %@3@%%@CR:C6A00180006 @%%@AB@%18.1.3  VDD I/O Trapping and Hooked Pages%@AE@%%@EH@%%@NL@%
  2629.  
  2630. When an application is running in the background, the VDD traps all the
  2631. video I/O, saving the output port values and emulating the input port
  2632. values. In some cases, the detection of a mode change can result. In this
  2633. case, the memory should be disabled and hooked to enable the page fault
  2634. service to remap the memory.  %@NL@%
  2635.  
  2636. A VDD should detect mode changes and illegal memory accesses. This is done
  2637. by disabling and hooking page faults that occur when the video memory is
  2638. accessed by the VM. The page fault service determines how to map the
  2639. accessed memory by both determining whether or not the VM has the display
  2640. focus and by examining the VM's virtual controller state. The page fault
  2641. service can also be used to demand page the video memory. It restores and
  2642. maps the video pages needed to create the physical display and to satisfy
  2643. the application's video memory accesses.  %@NL@%
  2644.  
  2645.  
  2646. %@3@%%@CR:C6A00180007 @%%@AB@%18.1.4  Grabber Naming Conventions%@AE@%%@EH@%%@NL@%
  2647.  
  2648. The names of the various supplied grabbers indicate in which mode they are
  2649. designed to run. For real and standard mode Windows, grabbers are named
  2650. %@AI@%FOO.GR2%@AE@%. For 386 enhanced mode Windows, they are named %@AI@%FOO.GR3.  %@AE@%%@NL@%
  2651.  
  2652.  
  2653. %@2@%%@CR:C6A00180008 @%%@AB@%18.2  VDD Programming%@AE@%%@EH@%%@NL@%
  2654.  
  2655. In addition to Chapter 17, "Virtual Device Programming Topics," which
  2656. discusses the general requirements for writing a VxD, valuable information
  2657. for the VDD author is located in Chapter 35, "Virtual Display Device (VDD)
  2658. Services."  %@NL@%
  2659.  
  2660. The following are the recommended steps for developing a VDD:  %@NL@%
  2661.  
  2662.  
  2663.   1.  Build a skeleton. Using the supplied sources as a guide, build a
  2664.       skeleton of the VDD with all the services and API procedures defined
  2665.       but not functional.%@NL@%
  2666.  
  2667.   2.  Add the initialization functionality, including the control block
  2668.       allocation, global memory needed, physical page hooking, I/O hooking,
  2669.       and interrupt hooking.%@NL@%
  2670.  
  2671.   3.  Fill out the services that handle the various hooks.%@NL@%
  2672.  
  2673.   4.  Test it while running Windows and other VMs, full screen.%@NL@%
  2674.  
  2675.   5.  Implement the Grabber API, including the procedures that report
  2676.       controller state, return video memory structures, and report video
  2677.       state modifications.%@NL@%
  2678.  
  2679.   6.  Test it while running VMs in a window. Do a thorough test, running
  2680.       many different applications in all the different states (i.e.,
  2681.       exclusive, background, and windowed), while using ALT+TAB and directed
  2682.       hot keys to switch VMs. Be sure to test various error conditions such
  2683.       as being out of memory.%@AI@%%@AE@%%@NL@%
  2684.  
  2685.  
  2686.  
  2687. %@3@%%@CR:C6A00180009 @%%@AB@%18.2.1  VDD Efficiency%@AE@%%@EH@%%@NL@%
  2688.  
  2689. To maximize the efficiency of Windows, a VDD is, in many cases, tightly
  2690. coupled with the Windows 3.0 display driver. For instance, the EGA display
  2691. would normally have to be trapped at all times to maintain the controller
  2692. state properly. Instead, an API has been defined for communications between
  2693. the Windows display driver and the VDD. Additionally, the EGA Windows
  2694. display driver uses a special portion of video memory and a special
  2695. algorithm that allows for a subset of the video controller state to be saved
  2696. and restored without explicitly saving away the current register values.
  2697. When adapting a VDD to new displays, it is a good idea to look at
  2698. alternatives to trapping all the display adapter access to maintain the
  2699. video state. Notice also that the Grabber is usually tightly coupled to the
  2700. Windows display driver, specifically to the display-dependent bitmap format.
  2701. %@NL@%
  2702.  
  2703. There are three PIF bits that the user can specify to disable trapping in
  2704. VMs where the applications running in the VMs only modify registers that can
  2705. be read. The VDD designer should use these PIF bits, if possible. There are
  2706. additional PIF bits by which the user can specify the amount of video memory
  2707. a VM will need. See the %@AI@%Microsoft Windows User's Guide%@AE@% for more information
  2708. on PIF files.  %@NL@%
  2709.  
  2710. Another good area in which to consider optimizing is the API emulation,
  2711. especially the INT 10H %@AB@%Write TTY%@AE@% function. The user can specify this
  2712. emulation with a PIF bit.  %@NL@%
  2713.  
  2714.  
  2715. %@3@%%@CR:C6A00180010 @%%@AB@%18.2.2  Converting Your 2.x VDD%@AE@%%@EH@%%@NL@%
  2716.  
  2717. Even though the general structure of Windows 3.0 VxDs is significantly
  2718. different from 2.x versions, the low-level VDD routines of previous
  2719. versions, such as the saving, restoring, and trapping routines, should work
  2720. with little modification. However, significant changes have occured in how
  2721. VxDs interact with the operating environment. For example, the VDD is now a
  2722. separate .386 file linked dynamically to 386 enhanced mode Windows.
  2723. Therefore, a recommended development strategy is to insert the 2.x routines
  2724. into one of the supplied 3.0 VDD sources.  %@NL@%
  2725.  
  2726. The 3.0 Grabber's interface with WINOLDAP and the VDD is also different. The
  2727. most significant change is that in version 2.x the Grabber was not a DLL.
  2728. See Section 18.3, "Grabber DLL Interfaces," for more detailed information.  %@NL@%
  2729.  
  2730. The following topics describe areas of a 2.x VDD that will require
  2731. modification.  %@NL@%
  2732.  
  2733.  
  2734. %@4@%%@AB@%INCLUDE Files%@AE@%%@EH@%%@NL@%
  2735.  
  2736. Most of the modules only need VMM.INC, VDD.INC, DEBUG.INC, and a device
  2737. specific INCLUDE file (e.g., EGA.INC). Some modules also require a file
  2738. describing the interface between them and some external user of their
  2739. functions (e.g., VMDAEGA.INC for the Grabber). By changing over to the new
  2740. INCLUDE files, you will generate several undefined references. Modifying the
  2741. references to use the equivalent Windows 3.0 functionality is a first step
  2742. in creating your Windows 3.0 VDD.  %@NL@%
  2743.  
  2744.  
  2745. %@4@%%@AB@%System Interface%@AE@%%@EH@%%@NL@%
  2746.  
  2747. Examine the parts of the supplied Windows 3.0 VDD to understand the new
  2748. system interface. You will need the %@AB@%VDD_Init%@AE@%, %@AB@%VDD_New%@AE@%, %@AB@%VDD_Exit%@AE@%,
  2749. %@AB@%VDD_Destroy%@AE@%, %@AB@%VDD_SetType%@AE@%, and %@AB@%VDD_SetFocus%@AE@% services to use the new device
  2750. control interface. The functionality of %@AB@%VDD_Install%@AE@% should be handled by
  2751. scheduling VM events. The %@AB@%VDD_Mem_Check%@AE@% service is replaced by the VDD
  2752. specifically calling the Shell to give the user a message. %@AB@%VDD_CHK_Device%@AE@% is
  2753. also replaced by sending WINOLDAP a message when the display needs to be
  2754. updated and by scheduling time outs to do the detection. The register values
  2755. and what you can and cannot do in an I/O trap, page fault, and interrupt
  2756. trap are also changed. Mostly, there is much more flexibility allowed, and
  2757. there are changes in register save/restore and parameter passing
  2758. conventions.  %@NL@%
  2759.  
  2760. Previously, VDD provided a single %@AB@%VDD_Control%@AE@% with various subfunctions.
  2761. Most of the %@AB@%VDD_Control%@AE@% calls are replaced by the device API mechanism.  %@NL@%
  2762.  
  2763. Notice that the definition of %@AI@%exclusive%@AE@% is different for Windows 3.0 and
  2764. that the %@AB@%SetFocus%@AE@% service takes into account whether or not the VM is
  2765. running in a window (i.e., VDD will get a %@AB@%SetFocus%@AE@% call for the System VM on
  2766. a VM that is running in a window, instead of a %@AB@%SetFocus%@AE@% call to the VM
  2767. itself).  %@NL@%
  2768.  
  2769.  
  2770. %@4@%%@AB@%Shell%@AE@%%@EH@%%@NL@%
  2771.  
  2772. The Shell device requires a number of new functions that are implemented as
  2773. device services. Additionally, the old ID call is device service 0.  %@NL@%
  2774.  
  2775.  
  2776. %@4@%%@AB@%Grabber%@AE@%%@EH@%%@NL@%
  2777.  
  2778. Notice that the way that the services retrieve the Grabber DLL's registers
  2779. is different (i.e., by using %@AB@%EBP%@AE@% and the %@AB@%Client_Reg%@AE@% definitions). Also
  2780. notice the increased number of functions and other changes in the
  2781. functionality of the Grabber DLL interface.  %@NL@%
  2782.  
  2783.  
  2784. %@4@%%@AB@%Memory Access%@AE@%%@EH@%%@NL@%
  2785.  
  2786. Use the %@AB@%_MapPhysToLinear%@AE@% function rather than adding %@AB@%PhysToLinr%@AE@% to the
  2787. physical addresses. You should also add the control block value
  2788. %@AB@%CB_High_Linear%@AE@% to the BIOS memory address for accessing those memory
  2789. locations.  %@NL@%
  2790.  
  2791. Since memory in the control block is allocated dynamically, the address of
  2792. your portion of the control block must be formed at run time, not compile
  2793. time.  %@NL@%
  2794.  
  2795.  
  2796. %@3@%%@CR:C6A00180011 @%%@AB@%18.2.3  Environment State Change Requirements for a VDD%@AE@%%@EH@%%@NL@%
  2797.  
  2798. During Windows initialization, VM creation and termination, and other status
  2799. changes of the Windows environment, there are certain programming
  2800. requirements for display devices. The following includes descriptions of
  2801. typical requirements for various states. Use the EGA/VGA and CGA sources as
  2802. examples. Specific interfaces to the described routines are included in
  2803. Section 17.1, "Writing VxDs."  %@NL@%
  2804.  
  2805.  
  2806. %@4@%%@AB@%Real Mode Initialization%@AB@%%@AE@%%@AE@%%@EH@%%@NL@%
  2807.  
  2808. Most video adapters will not need any real-mode code to be functional.
  2809. However, a few developers will want to add some real-mode code to query
  2810. device state or to reserve portions of memory that may not be touched during
  2811. the initialization of other devices or used for general system purposes. For
  2812. example, you may have a memory-mapped interface that will be harmed by other
  2813. code reading and writing at those addresses (Windows in 386 enhanced mode
  2814. searches the area between C0000H and EFFFFH for the existence of RAM or
  2815. ROM). If the VDD supports multiple display adapters, display-adapter
  2816. detection can be done here by passing the result of the detection in the %@AB@%EDX%@AE@%
  2817. register to the protected-mode initialization.  %@NL@%
  2818.  
  2819.  
  2820. %@4@%%@AB@%Sys_Critical_Init%@AE@%%@EH@%%@NL@%
  2821.  
  2822. During %@AB@%Sys_Critical_Init%@AE@%, a VDD should allocate its control block data area,
  2823. allocate V86 address space, allocate memory needed globally, and initialize
  2824. any pointers or other data that are required for the VDD functionality.
  2825. Remember that interrupts are disabled during this call, so keep it as short
  2826. as possible.  %@NL@%
  2827.  
  2828.  
  2829. %@4@%%@AB@%Device_Init%@AE@%%@EH@%%@NL@%
  2830.  
  2831. During %@AB@%Device_Init%@AE@%, a VDD should finish initializing its global state, set
  2832. up the I/O and interrupt trapping needed, and specify instance data. As
  2833. noted in Chapter 16, "Overview of Windows in 386 Enhanced Mode," this
  2834. initialization call is equivalent to %@AB@%VMCreate%@AE@% for the System VM, along with
  2835. the global device initialization. Finally, the VDD should set the display
  2836. focus to the system VM internally.  %@NL@%
  2837.  
  2838.  
  2839. %@4@%%@AB@%Init_Complete%@AE@%%@EH@%%@NL@%
  2840.  
  2841. During %@AB@%Init_Complete%@AE@%, a VDD should do any consistency checks that have to be
  2842. done after all the other devices have completed their initialization.
  2843. Normally, a VDD will not need to do anything with this control call.  %@NL@%
  2844.  
  2845.  
  2846. %@4@%%@AB@%Sys_VM_Init%@AE@%%@EH@%%@NL@%
  2847.  
  2848. During %@AB@%Sys_VM_Init%@AE@%, a VDD should initialize the rest of the control block
  2849. data for the system VM, and set the display focus to the system VM.  %@NL@%
  2850.  
  2851.  
  2852. %@4@%%@AB@%VM_Create%@AE@%%@EH@%%@NL@%
  2853.  
  2854. During creation, initialize the control block and allocate any VM specific
  2855. memory. If the allocation fails, return the Carry flag set to abort the VM
  2856. creation.  %@NL@%
  2857.  
  2858.  
  2859. %@4@%%@AB@%VM_Init%@AE@%%@EH@%%@NL@%
  2860.  
  2861. During initialization, set the video state of the VM, typically by making
  2862. calls to the Video BIOS and trapping the I/O to set up the video state
  2863. structure.  %@NL@%
  2864.  
  2865.  
  2866. %@4@%%@AB@%Destroy_VM%@AE@%%@EH@%%@NL@%
  2867.  
  2868. During destruction, deallocate any memory allocated for the VM and make sure
  2869. that there are no pointers left that refer to the destroyed VM.  %@NL@%
  2870.  
  2871.  
  2872. %@4@%%@AB@%Set_Device_Focus%@AE@%%@EH@%%@NL@%
  2873.  
  2874. The %@AB@%SetFocus%@AE@% service is responsible for giving the specified VM the physical
  2875. display. Notice that there is display %@AB@%SetFocus%@AE@% and critical %@AB@%SetFocus%@AE@%. Both
  2876. should give the physical display to the indicated VM. Also notice that the
  2877. actual restoring of the physical display should occur by executing the
  2878. %@AB@%VDD_Restore%@AE@% service as an event.  %@NL@%
  2879.  
  2880.  
  2881. %@4@%%@AB@%VM_Suspend%@AE@%%@EH@%%@NL@%
  2882.  
  2883. During %@AB@%VM_Suspend%@AE@%, a VDD should unlock any memory associated with the VM,
  2884. such as the memory used to save and restore the video state.  %@NL@%
  2885.  
  2886.  
  2887. %@4@%%@AB@%VM_Resume%@AE@%%@EH@%%@NL@%
  2888.  
  2889. During %@AB@%VM_Resume%@AE@%, a VDD should lock the memory unlocked during suspend.  %@NL@%
  2890.  
  2891.  
  2892. %@4@%%@AB@%System_Exit%@AE@%%@EH@%%@NL@%
  2893.  
  2894. During %@AB@%System_Exit%@AE@%, a VDD should return the display to the state it should
  2895. be in when Windows returns to MS-DOS.  %@NL@%
  2896.  
  2897.  
  2898. %@4@%%@AB@%Sys_Critical_Exit%@AE@%%@EH@%%@NL@%
  2899.  
  2900. During %@AB@%Sys_Critical_Exit%@AE@%, a VDD should restore any hooks remaining in the
  2901. V86 memory.  %@NL@%
  2902.  
  2903.  
  2904. %@4@%%@AB@%Begin_Message_Mode%@AE@%%@EH@%%@NL@%
  2905.  
  2906. After saving the current VM's video state, the VDD should put the display
  2907. adapter into a known text mode. If this is called prior to the point in
  2908. initialization (System VM Initialization) at which a known text mode has
  2909. been saved, call the video BIOS to set up the correct mode.  %@NL@%
  2910.  
  2911. The message mode services, %@AB@%VDD_Msg_ClrScrn%@AE@%, %@AB@%VDD_Msg_ForColor%@AE@%,
  2912. %@AB@%VDD_Msg_BakColor%@AE@%, %@AB@%VDD_Msg_TextOut%@AE@%, and %@AB@%VDD_Msg_SetCursPos%@AE@% are only used
  2913. after the %@AB@%Begin_Message_Mode%@AE@% message has been received. See Chapter 35,
  2914. "Virtual Display Device (VDD) Services," for details.  %@NL@%
  2915.  
  2916.  
  2917. %@4@%%@AB@%End_Message_Mode%@AE@%%@EH@%%@NL@%
  2918.  
  2919. During %@AB@%End_Message_Mode%@AE@%, a VDD should restore the focus VM's video state.  %@NL@%
  2920.  
  2921.  
  2922. %@4@%%@AB@%Debug_Query%@AE@%%@EH@%%@NL@%
  2923.  
  2924. In a debug version of your VDD, use the %@AB@%Trace_Out%@AE@% macro to list the current
  2925. display owner, other potentially interesting global data, and the video
  2926. state for each VM.  %@NL@%
  2927.  
  2928.  
  2929. %@3@%%@CR:C6A00180012 @%%@AB@%18.2.4  Grabber API%@AE@%%@EH@%%@NL@%
  2930.  
  2931. The Grabber uses the VDD's %@AB@%Get_Version%@AE@% service to verify that it is matched
  2932. with the correct VDD. Whenever the Grabber needs access to the video memory
  2933. or the video controller state, it queries the VDD. The VDD returns a data
  2934. structure describing the requested memory or controller state.  %@NL@%
  2935.  
  2936. %@AB@%Get_Mem%@AE@% is used to get the current contents of the video memory while
  2937. updating the windowed display. %@AB@%Get_GrbMem%@AE@% is used to get a snapshot of the
  2938. entire screen in response to an ALT + PRTSCN command from the user in a full
  2939. screen VM. %@AB@%Free_Mem%@AE@% and %@AB@%Free_Grab%@AE@% are used to tell the VDD that the grabber
  2940. is no longer using this memory. %@AB@%Get_State%@AE@% and %@AB@%Get_GrbState%@AE@% return the
  2941. current and grabbed controller states, respectively.  %@NL@%
  2942.  
  2943. %@AB@%Get_Mod%@AE@% is used to update the windowed display incrementally. %@AB@%Get_Mod%@AE@%
  2944. returns a data structure that indicates modifications to the current
  2945. display. The Grabber DLL modifies only those parts of the window that have
  2946. changed and, then, issues a %@AB@%Clear_Mod%@AE@% call to inform the VDD that the
  2947. modifications have been carried out.  %@NL@%
  2948.  
  2949. To make sure that the video memory or state will not change when the Grabber
  2950. is accessing the memory, the VM should not be running after a %@AB@%Get_Mem%@AE@% or
  2951. %@AB@%Get_Mod%@AE@% call. The VM can continue to run only after a %@AB@%Free_Mem%@AE@% call or an
  2952. explicit %@AB@%Unlock_App%@AE@% call from the Grabber.  %@NL@%
  2953.  
  2954.  
  2955. %@2@%%@CR:C6A00180013 @%%@AB@%18.3  Grabber DLL Interfaces%@AE@%%@EH@%%@NL@%
  2956.  
  2957. The Grabber is a dynamic-link library (DLL) primarily responsible for
  2958. representing the VM's display state to the Windows display driver. It is the
  2959. library of functions used by WINOLDAP, the Windows program responsible for
  2960. creating, destroying, and changing the state of VMs. WINOLDAP makes private
  2961. calls to the Shell device, which in turn calls the necessary VMM services.
  2962. Therefore, it is WINOLDAP, using the Grabber (and through it the Windows
  2963. display driver), that is actually responsible for windowing the display
  2964. state of a VM.  %@NL@%
  2965.  
  2966. Each of the Grabber functions is a %@AB@%cProc%@AE@% and has to be exported. The
  2967. function code can be shared by several instances of WINOLDAP, and therefore,
  2968. the placement of VM-specific data must be deliberate. The Grabber DLL
  2969. functions provide support for the following:  %@NL@%
  2970.  
  2971.  
  2972.   ■   Screen grabbing%@NL@%
  2973.  
  2974.   ■   Marking and selecting%@NL@%
  2975.  
  2976.   ■   Painting non-Windows applications in a window%@NL@%
  2977.  
  2978.   ■   Doing other miscellaneous functions%@NL@%
  2979.  
  2980.  
  2981. The Grabber generates data in the following situations:  %@NL@%
  2982.  
  2983.  
  2984.   ■   When an Extended Paint structure (EXTPAINTSTRUC) is passed from
  2985.       WINOLDAP%@NL@%
  2986.  
  2987.   ■   When a procedure requires local data. (Local data is maintained on the
  2988.       stack.)%@CR:C6A00180014 @%%@CR:C6A00180015 @%%@NL@%
  2989.  
  2990.  
  2991.  
  2992. %@3@%%@CR:C6A00180016 @%%@AB@%18.3.1  On-Screen Selection Functions%@AE@%%@EH@%%@NL@%
  2993.  
  2994. The user can make on-screen selections with either the keyboard or mouse, or
  2995. through a hot key. The keyboard or mouse are used only while in a window; a
  2996. hot key (ALT+PRTSCRN) is used while in full-screen or windowed mode.  %@NL@%
  2997.  
  2998. The functions that handle on-screen selections are as follows:  %@NL@%
  2999.  
  3000.  
  3001.   ■   %@AB@%BeginSelection%@AE@%%@NL@%
  3002.  
  3003.   ■   %@AB@%EndSelection%@AE@%%@NL@%
  3004.  
  3005.   ■   %@AB@%KeySelection%@AE@%%@NL@%
  3006.  
  3007.   ■   %@AB@%AdjustInitEndPt%@AE@%%@NL@%
  3008.  
  3009.   ■   %@AB@%MakeSelctRect%@AE@%%@NL@%
  3010.  
  3011.  
  3012. To perform a selection by using the keyboard, the user performs the
  3013. following steps:  %@NL@%
  3014.  
  3015.  
  3016.   1.  Choose the Mark command.%@NL@%
  3017.  
  3018.   2.  Move the cursor to the start point of the selection.%@NL@%
  3019.  
  3020.   3.  Sweep through a selection using SHIFT + DIRECTION keys.%@NL@%
  3021.  
  3022.   4.  Press ENTER to end a selection and copy it to the Clipboard (or press
  3023.       ESC to end the selection without a copy).%@NL@%
  3024.  
  3025.  
  3026. On choosing Mark from the menu, %@AB@%BeginSelection%@AE@% gets called with argument
  3027. <0,0>.  %@NL@%
  3028.  
  3029. During the first phase, the cursor is moved to the actual start point.
  3030. %@AB@%KeySelection%@AE@% handles the cursor movement. It returns the new start point
  3031. every time a DIRECTION key is pressed. Notice that the selection could
  3032. potentially begin at each cursor position. Therefore, every time the start
  3033. point is changed, %@AB@%EndSelection%@AE@% is called to cancel the previous selection,
  3034. and %@AB@%BeginSelection%@AE@% is called with the new start point.  %@NL@%
  3035.  
  3036. Once the cursor is positioned at the actual start point, the user sweeps
  3037. through a selection area using SHIFT+DIRECTION keys. %@AB@%KeySelection%@AE@% handles
  3038. the cursor movement. It returns the new end point of the selection. Now each
  3039. call to %@AB@%KeySelection%@AE@% is followed by a call to %@AB@%MakeSelctRect%@AE@% to record the
  3040. current selection rectangle. On pressing ENTER, the actual end point and the
  3041. final selection rectangle are established.  %@NL@%
  3042.  
  3043. Therefore, the last call to %@AB@%BeginSelection%@AE@% establishes the actual start
  3044. point, the last call to %@AB@%KeySelection%@AE@% returns the actual end point, and the
  3045. final call to %@AB@%MakeSelctRect%@AE@% records the actual selection rectangle. If only
  3046. DIRECTION keys are pressed, the user is shifting the start point. If
  3047. SHIFT+DIRECTION keys are pressed, the user is changing the active end point.
  3048. %@NL@%
  3049.  
  3050. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3051. NOTE
  3052.  
  3053. %@AI@%The start point and the end point of a selection have to be aligned on
  3054. %@AI@%character boundaries in text mode. In graphics mode, the Grabber chooses
  3055. %@AI@%some granularity for cursor movement (e.g., DWORD of pixels).%@AE@%
  3056. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3057.  
  3058. The coordinates of the start point and the end point are given in screen
  3059. coordinates ─ a window client area position corrected by the scroll bar
  3060. position. Client area coordinate = <0,0> corresponds to the screen
  3061. coordinate <ColOrg,RowOrg>. (ColOrg and RowOrg are available in the extended
  3062. paint structure.)  %@NL@%
  3063.  
  3064.  
  3065. %@3@%%@CR:C6A00180017 @%%@AB@%18.3.2  Selection Functions%@AE@%%@EH@%%@NL@%
  3066.  
  3067. This section presents descriptions of the selection functions in
  3068. alphabetical order.  %@NL@%
  3069.  
  3070. %@CR:C6A00180018 @%
  3071. %@2@%%@CR:C6A00180019 @%%@AB@%AdjustInitEndPt%@CR:C6A00180020 @%%@AE@%%@EH@%%@NL@%
  3072. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3073.  
  3074.  
  3075. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3076.  
  3077. This function adjusts the initial selection end point. To start off, the
  3078. start point and the end point are the same. (This is how %@AB@%BeginSelection%@AE@%
  3079. records them). On the first SHIFT + DIRECTION key call to %@AB@%KeySelection%@AE@%,
  3080. notice that %@AB@%KeySelection%@AE@% returns the wrong end point. This function returns
  3081. the correct end point. It returns (X+DELTAx, Y+DELTAy) where <X,Y > is the
  3082. given end point. DELTAx and DELTAy are as defined in %@AB@%KeySelection%@AE@%.  %@NL@%
  3083.  
  3084.  
  3085. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3086.  
  3087. lpPntStruct = EXTPAINTSTRUC  %@NL@%
  3088.  
  3089. YCoOrd,XCoOrd = (Y,X) point to be adjusted  %@NL@%
  3090.  
  3091.  
  3092. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3093.  
  3094. %@AB@%DX%@AE@%,%@AB@%AX%@AE@% = (Y,X) end point adjust down and to right for initial selection.  %@NL@%
  3095.  
  3096. %@CR:C6A00180021 @%
  3097. %@2@%%@CR:C6A00180022 @%%@AB@%BeginSelection%@CR:C6A00180023 @%%@AE@%%@EH@%%@NL@%
  3098. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3099.  
  3100.  
  3101. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3102.  
  3103. This function starts the selection at the indicated point.  %@NL@%
  3104.  
  3105.  
  3106. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3107.  
  3108. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3109.  
  3110. YCoOrd,XCoOrd = (Y,X) screen coord of start pt  %@NL@%
  3111.  
  3112.  
  3113. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3114.  
  3115. [lpPntStruc.SelStruc.SelctSRect] Display rectangle in the EXTPAINTSTRUC
  3116. selection structure set  %@NL@%
  3117.  
  3118. %@CR:C6A00180024 @%
  3119. %@2@%%@CR:C6A00180025 @%%@AB@%ConsSelecRec%@CR:C6A00180026 @%%@AE@%%@EH@%%@NL@%
  3120. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3121.  
  3122.  
  3123. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3124.  
  3125. This function makes the display rectangle consistent with the selection.  %@NL@%
  3126.  
  3127.  
  3128. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3129.  
  3130. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3131.  
  3132.  
  3133. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3134.  
  3135. [lpPntStruc.SelStruc.SelctSRect] Display rectangle in the EXTPAINTSTRUC
  3136. selection structure set  %@NL@%
  3137.  
  3138. %@CR:C6A00180027 @%
  3139. %@2@%%@CR:C6A00180028 @%%@AB@%EndSelection%@CR:C6A00180029 @%%@AE@%%@EH@%%@NL@%
  3140. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3141.  
  3142.  
  3143. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3144.  
  3145. This function stops the selection.  %@NL@%
  3146.  
  3147.  
  3148. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3149.  
  3150. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3151.  
  3152.  
  3153. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3154.  
  3155. None  %@NL@%
  3156.  
  3157. %@CR:C6A00180030 @%
  3158. %@2@%%@CR:C6A00180031 @%%@AB@%InvertSelection%@CR:C6A00180032 @%%@AE@%%@EH@%%@NL@%
  3159. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3160.  
  3161.  
  3162. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3163.  
  3164. This function inverts the selection.  %@NL@%
  3165.  
  3166.  
  3167. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3168.  
  3169. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3170.  
  3171.  
  3172. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3173.  
  3174. %@AB@%DX%@AE@%,%@AB@%AX%@AE@% = (Y,X) screen CoOrd of "active" selection endpoint  %@NL@%
  3175.  
  3176. %@CR:C6A00180033 @%
  3177. %@2@%%@CR:C6A00180034 @%%@AB@%KeySelection%@CR:C6A00180035 @%%@AE@%%@EH@%%@NL@%
  3178. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3179.  
  3180.  
  3181. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3182.  
  3183. This function is for keyboard selection.  %@NL@%
  3184.  
  3185.  
  3186. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3187.  
  3188. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3189.  
  3190. StartType = 0 if SHIFT key UP  != 0 if SHIFT key DOWN  %@NL@%
  3191.  
  3192. %@TH:  11   479 01 34 42 @%%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%MFunc                             = 0 To Right                                  = 1 To Left                                  = 2 Down                                  = 3 UpMFunc                             = 0 To Right                                  = 1 To Left                                  = 2 Down                                  = 3 Up%@TE:  11   479 01 34 42 @%
  3193.  
  3194.  
  3195. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3196.  
  3197. %@AB@%DX%@AE@%,%@AB@%AY%@AE@% = (Y,X) screen CoOrd of new select end pt  %@NL@%
  3198.  
  3199. KeySelection responds to DIRECTION keys and SHIFT+DIRECTION keys.  %@NL@%
  3200.  
  3201. DIRECTION key response: (SHIFT key UP)  %@NL@%
  3202.  
  3203. if (LEFT Key)  return (X-DELTAx, Y) else if (RIGHT Key)  return (X+DELTAx,
  3204. Y) else if (DOWN Key)  return (X, Y+DELTAy) else if (UP Key)  return (X,
  3205. Y-DELTAy);  %@NL@%
  3206.  
  3207. where <X,Y> is current end point.  %@NL@%
  3208.  
  3209. DELTAx DELTAy are the font width and height in text mode and some
  3210. appropriate value in graphics mode.  %@NL@%
  3211.  
  3212. SHIFT+DIRECTION key response:  %@NL@%
  3213.  
  3214. Similar to above except <X,Y> is current end point.  %@NL@%
  3215.  
  3216. %@CR:C6A00180036 @%
  3217. %@2@%%@CR:C6A00180037 @%%@AB@%MakeSelctRect%@CR:C6A00180038 @%%@AE@%%@EH@%%@NL@%
  3218. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3219.  
  3220.  
  3221. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3222.  
  3223. This function sets a new selection. It is called after every call to
  3224. %@AB@%KeySelection%@AE@% in response to SHIFT+DIRECTION key. Given a new end point, it
  3225. adjusts the new end point to be character-aligned in text mode (and on a
  3226. convenient boundary in the video memory in graphics mode). It also adjusts
  3227. for screen maxima. It sets the Selection rectangle based on the current
  3228. start point and end point.  %@NL@%
  3229.  
  3230.  
  3231. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3232.  
  3233. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3234.  
  3235. YCoOrd,XCoOrd = (Y,X) screen CoOrd of new end point  %@NL@%
  3236.  
  3237.  
  3238. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3239.  
  3240. [lpPntStruc.SelStruc.SelctSRect], Display rect in extended paint selection
  3241. structure set  %@NL@%
  3242.  
  3243. %@AB@%AX%@AE@% == 0, if no change was made to selection parameters  %@NL@%
  3244.  
  3245. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3246. NOTE 
  3247.  
  3248. %@AI@%[lpPntStruc.SelStruc.SelctSRect] must still be set in this case.%@AE@%
  3249. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3250.  
  3251. %@CR:C6A00180039 @%
  3252. %@2@%%@CR:C6A00180040 @%%@AB@%RenderSelection%@CR:C6A00180041 @%%@AE@%%@EH@%%@NL@%
  3253. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3254.  
  3255.  
  3256. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3257.  
  3258. This function renders the selection into the Clipboard format.  %@NL@%
  3259.  
  3260.  
  3261. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3262.  
  3263. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3264.  
  3265. %@TH:   3   255 01 10 66 @%%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%wParam    Parameter from VDD message (= -1 if VMDOSAPP originlParam    Parameter from VDD message (=0 if VMDOSAPP origin) Event ID%@TE:   3   255 01 10 66 @%
  3266.  
  3267.  
  3268. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3269.  
  3270. if (DX < 0)  Error else if (DX = 0)  No Selection else if (DX > 0)  DX =
  3271. format, (CF_OEMTEXT or CF_BITMAP)  AX = Handle, (Memory Handle or Bitmap
  3272. Handle)  %@NL@%
  3273.  
  3274.  
  3275. %@3@%%@AB@%18.4.1  Application Painting Function%@AE@%%@EH@%%@NL@%
  3276.  
  3277. This section presents a description of the non-Windows application painting
  3278. function.  %@NL@%
  3279.  
  3280. %@CR:C6A00180042 @%
  3281. %@2@%%@CR:C6A00180043 @%%@AB@%GetDisplayUpd%@CR:C6A00180044 @%%@AE@%%@EH@%%@NL@%
  3282. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3283.  
  3284.  
  3285. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3286.  
  3287. This function calls the VDD to get a display update (if any) and stores it
  3288. in the PAINT structure.  %@NL@%
  3289.  
  3290. It prevents any further changes from occurring in the application. The
  3291. application restarts after a call to one of the following; %@AB@%UpdateScreen%@AE@%,
  3292. %@AB@%PaintScreen%@AE@%, or %@AB@%GrbUnLockApp%@AE@%.  %@NL@%
  3293.  
  3294.  
  3295. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3296.  
  3297. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3298.  
  3299. %@TH:   3   256 01 10 66 @%%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%wParam    Parameter from VDD message (= -1 if VMDOSAPP origin)lParam    Parameter from VDD message (=0 if VMDOSAPP origin) Event ID%@TE:   3   256 01 10 66 @%
  3300.  
  3301.  
  3302. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3303.  
  3304. %@AB@%AX%@AE@% = Display update flags (see grabpnt.inc for fDisp_ flags)  %@NL@%
  3305.  
  3306.  
  3307. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  3308.  
  3309. This call "locks" the application (prevents further changes from occuring).
  3310. The application can be started again by a call to one of the following:  %@NL@%
  3311.  
  3312.  
  3313.   ■   %@AB@%UpdateScreen%@AE@%%@NL@%
  3314.  
  3315.   ■   %@AB@%PaintScreen%@AE@%%@NL@%
  3316.  
  3317.   ■   %@AB@%GrgUnLockApp%@AE@%%@NL@%
  3318.  
  3319.  
  3320.  
  3321. %@3@%%@AB@%18.4.1  Miscellaneous Functions%@AE@%%@EH@%%@NL@%
  3322.  
  3323. This section presents descriptions of miscellaneous functions in
  3324. alphabetical order.  %@NL@%
  3325.  
  3326. %@CR:C6A00180045 @%
  3327. %@2@%%@CR:C6A00180046 @%%@AB@%CheckGRBVersion%@CR:C6A00180047 @%%@AE@%%@EH@%%@NL@%
  3328. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3329.  
  3330.  
  3331. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3332.  
  3333. This function checks out the VDD version.  %@NL@%
  3334.  
  3335.  
  3336. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3337.  
  3338. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3339.  
  3340.  
  3341. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3342.  
  3343. If (AX == 0)  OK AX == 1  Version # error AX == 2  Display type mismatch
  3344. (VDD and Grabber are not compatible)  DX = Grabber Version number  %@NL@%
  3345.  
  3346.  
  3347. %@2@%%@CR:C6A00180048 @%%@AB@%CursorOff%@CR:C6A00180049 @%%@CR:C6A00180050 @%%@AE@%%@EH@%%@NL@%
  3348. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3349.  
  3350.  
  3351. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3352.  
  3353. This function destroys the cursor for an application.  %@NL@%
  3354.  
  3355.  
  3356. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3357.  
  3358. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3359.  
  3360.  
  3361. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3362.  
  3363. Caret destroyed  %@NL@%
  3364.  
  3365.  
  3366. %@2@%%@CR:C6A00180051 @%%@AB@%CursorOn%@CR:C6A00180052 @%%@CR:C6A00180053 @%%@AE@%%@EH@%%@NL@%
  3367. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3368.  
  3369.  
  3370. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3371.  
  3372. This function creates the cursor for an application if it has one.  %@NL@%
  3373.  
  3374.  
  3375. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3376.  
  3377. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3378.  
  3379.  
  3380. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3381.  
  3382. Caret created  %@NL@%
  3383.  
  3384.  
  3385. %@2@%%@CR:C6A00180054 @%%@AB@%CursorPosit%@CR:C6A00180055 @%%@CR:C6A00180056 @%%@AE@%%@EH@%%@NL@%
  3386. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3387.  
  3388.  
  3389. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3390.  
  3391. This function returns the position of the cursor on the display.  %@NL@%
  3392.  
  3393.  
  3394. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3395.  
  3396. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3397.  
  3398.  
  3399. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3400.  
  3401. %@AB@%DX%@AE@%,%@AB@%AX%@AE@% = (Y,X) screen CoOrd of upper left of cursor  %@NL@%
  3402.  
  3403.  = (-1,-1) if no cursor  %@NL@%
  3404.  
  3405.  
  3406. %@2@%%@CR:C6A00180057 @%%@AB@%GetFontList%@CR:C6A00180058 @%%@CR:C6A00180059 @%%@AE@%%@EH@%%@NL@%
  3407. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3408.  
  3409.  
  3410. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3411.  
  3412. This function returns a pointer to the list of extra fonts you want loaded.
  3413. %@NL@%
  3414.  
  3415.  
  3416. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3417.  
  3418. lpFontBuf -> Buffer for font info  %@NL@%
  3419.  
  3420.  
  3421. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3422.  
  3423. Font Buffer filled in  %@NL@%
  3424.  
  3425. %@CR:C6A00180060 @%
  3426. %@2@%%@CR:C6A00180061 @%%@AB@%GrabComplete%@CR:C6A00180062 @%%@AE@%%@EH@%%@NL@%
  3427. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3428.  
  3429.  
  3430. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3431.  
  3432. This function signals that you are finished with the grab. This is called
  3433. after the grab is complete. It is time to call the VDD and have it free the
  3434. grab memory.  %@NL@%
  3435.  
  3436.  
  3437. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3438.  
  3439. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3440.  
  3441. %@TH:   3   248 01 12 64 @%%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%wParam %@AI@%%@AE@%     Parameter from VDD message (= -1 if VMDOSAPP origin)lParam      Parameter from VDD message EVENT ID%@TE:   3   248 01 12 64 @%
  3442.  
  3443.  
  3444. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3445.  
  3446. None  %@NL@%
  3447.  
  3448.  
  3449. %@2@%%@CR:C6A00180063 @%%@AB@%GrabEvent%@CR:C6A00180064 @%%@CR:C6A00180065 @%%@AE@%%@EH@%%@NL@%
  3450. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3451.  
  3452.  
  3453. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3454.  
  3455. This function provides a private channel of event communication between the
  3456. VDD and the Grabber to perform a hot key screen grab.  %@NL@%
  3457.  
  3458.  
  3459. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3460.  
  3461. lpPntStruc Extended paint structure  %@NL@%
  3462.  
  3463. %@TH:   3   235 01 18 58 @%%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%wParam %@AI@%%@AE@%           Parameter from VDD message lParam            Parameter from VDD message EVENT ID%@TE:   3   235 01 18 58 @%
  3464.  
  3465.  
  3466. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3467.  
  3468. None  %@NL@%
  3469.  
  3470. %@CR:C6A00180066 @%
  3471. %@2@%%@CR:C6A00180067 @%%@AB@%GrbUnLockApp%@CR:C6A00180068 @%%@AE@%%@EH@%%@NL@%
  3472. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3473.  
  3474.  
  3475. %@3@%%@AB@%Descripton%@AE@%%@EH@%%@NL@%
  3476.  
  3477. This function undoes the implied application lock of %@AB@%GetDisplayUpd%@AE@%.  %@NL@%
  3478.  
  3479.  
  3480. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3481.  
  3482. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3483.  
  3484.  
  3485. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3486.  
  3487. None  %@NL@%
  3488.  
  3489.  
  3490. %@2@%%@CR:C6A00180069 @%%@AB@%InitGrabber%@CR:C6A00180070 @%%@CR:C6A00180071 @%%@AE@%%@EH@%%@NL@%
  3491. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3492.  
  3493.  
  3494. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3495.  
  3496. This is the library initialization function.  %@NL@%
  3497.  
  3498.  
  3499. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3500.  
  3501. %@AB@%DI%@AE@% = Module handle of the library  %@NL@%
  3502.  
  3503. %@AB@%CX%@AE@% = Size of local heap (should be 0)  %@NL@%
  3504.  
  3505. %@AB@%DS%@AE@% = Seg addr of library data segment (isn't one)  %@NL@%
  3506.  
  3507.  
  3508. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3509.  
  3510. AX == 0  Init Error AX != 0  OK  %@NL@%
  3511.  
  3512.  
  3513. %@2@%%@CR:C6A00180072 @%%@AB@%PaintScreen%@CR:C6A00180073 @%%@CR:C6A00180074 @%%@AE@%%@EH@%%@NL@%
  3514. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3515.  
  3516.  
  3517. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3518.  
  3519. This function paints the indicated region of the screen.  %@NL@%
  3520.  
  3521. This procedure paints the non-Windows application screen into a window. The
  3522. origin of this is a Windows paint as opposed to a display update, which is
  3523. handled at %@AB@%UpdateScreen%@AE@%. When a non-Windows application receives a Windows
  3524. paint message, %@AB@%Paint Screen%@AE@% gets called.  %@NL@%
  3525.  
  3526.  
  3527. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3528.  
  3529. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3530.  
  3531.  
  3532. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3533.  
  3534. %@AB@%AX%@AE@% != 0 Screen Painted  %@NL@%
  3535.  
  3536. %@AB@%AX%@AE@% == 0 Screen not painted, probably insufficient Windows memory problem  %@NL@%
  3537.  
  3538.  
  3539. %@2@%%@CR:C6A00180075 @%%@AB@%ScreenFree%@CR:C6A00180076 @%%@CR:C6A00180077 @%%@AE@%%@EH@%%@NL@%
  3540. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3541.  
  3542.  
  3543. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3544.  
  3545. This function frees anything associated with this application.  %@NL@%
  3546.  
  3547.  
  3548. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3549.  
  3550. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3551.  
  3552.  
  3553. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3554.  
  3555. Any allocated stuff associated with the application is freed.  %@NL@%
  3556.  
  3557.  
  3558. %@2@%%@CR:C6A00180078 @%%@AB@%SetPaintFnt%@CR:C6A00180079 @%%@CR:C6A00180080 @%%@AE@%%@EH@%%@NL@%
  3559. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3560.  
  3561.  
  3562. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3563.  
  3564. This function sets the font for painting in the extended paint structure so
  3565. that WINOLDAP can compute the paint rectangle for use on %@AB@%PaintScreen%@AE@% calls.
  3566. This is called right before a call to %@AB@%PaintScreen%@AE@%. It is also called right
  3567. before a call to %@AB@%UpdateScreen%@AE@%.  %@NL@%
  3568.  
  3569.  
  3570. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3571.  
  3572. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3573.  
  3574. %@TH:   3   234 01 25 51 @%%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%lpWidFullScr             Word pointer for width returnlpHeightFullScr          Word pointer for height return%@TE:   3   234 01 25 51 @%
  3575.  
  3576.  
  3577. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3578.  
  3579. FntHgt and FntWid values in EXTPAINTSTRUC set  %@NL@%
  3580.  
  3581. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3582. NOTE
  3583.  
  3584. %@AI@%Values are set to 0 if it is a graphics screen.%@AE@%
  3585. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3586.  
  3587. [lpWidFullScr] = Width of full screen in pix (Text or Graphics)  %@NL@%
  3588.  
  3589. [lpHeightFullScr] = Height of full screen in pix (Text or Graphics)  %@NL@%
  3590.  
  3591. %@AB@%DX%@AE@% is height of full screen in scan lines if Graphics, in text lines if
  3592. Text.  %@NL@%
  3593.  
  3594. %@AB@%AX%@AE@% is width of full screen in pix if Graphics, in chars if Text.  %@NL@%
  3595.  
  3596. %@CR:C6A00180081 @%
  3597. %@2@%%@CR:C6A00180082 @%%@AB@%UpdateScreen%@CR:C6A00180083 @%%@AE@%%@EH@%%@NL@%
  3598. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3599.  
  3600.  
  3601. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  3602.  
  3603. This function updates changed portions of the screen. When a non-Windows
  3604. application modifies the display on its own, %@AB@%UpdateScreen%@AE@% is called.  %@NL@%
  3605.  
  3606.  
  3607. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  3608.  
  3609. lpPntStruc = EXTPAINTSTRUC  %@NL@%
  3610.  
  3611.  
  3612. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  3613.  
  3614. %@AB@%AX%@AE@% == 1 if Screen Paint, unless fGrbProb bit set in EPStatusFlags  %@NL@%
  3615.  
  3616. %@AB@%AX%@AE@% == 0 if Screen not painted, probably low Windows memory problem  %@NL@%
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623. %@CR:C6A-Part 04 @%%@1@%%@AB@%PART IV  Virtual Device Services%@AE@%%@EH@%%@NL@%
  3624. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3625.  
  3626. This part documents all the enhanced Windows virtual machine environment
  3627. services. They are grouped by service type and presented in the order shown
  3628. on the following page.  %@NL@%
  3629.  
  3630. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  3631. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638. %@CR:C6A00190001 @%%@1@%%@AB@%Chapter 19  Memory Management Services%@AE@%%@EH@%%@NL@%
  3639. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3640.  
  3641. Enhanced Windows supplies a rich set of memory management services. Since
  3642. many of the services are unnecessary for most VxD development, only a
  3643. commonly used subset is listed in this introduction. However, all the memory
  3644. management services are documented in either this chapter or in Chapter 40,
  3645. "V86 Mode Memory Manager Device Services."  %@NL@%
  3646.  
  3647. See also Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter
  3648. 17, "Virtual Device Programming Topics," for general environment
  3649. discussions. Memory management is also discussed in the %@AI@%Microsoft Windows
  3650. %@AI@%Software Development Kit, Programming Tools%@AE@% and in Chapter 6, "Network
  3651. Support," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@%.  %@NL@%
  3652.  
  3653. The enhanced Windows environment uses a virtual memory scheme capable of
  3654. overcoming the limits of actual physical memory. Though it may not be
  3655. physically present, a virtual memory of 4 gigabytes is theoretically
  3656. addressable. This is done by swapping (paging) code and data to and from RAM
  3657. and a secondary storage device. Since VxDs reside within the 32-bit
  3658. protected-mode portion of the environment, they can directly access all of
  3659. the memory, but should only access memory whose address was obtained through
  3660. the memory management services.  %@NL@%
  3661.  
  3662. Windows determines the amount of virtual memory actually available based on
  3663. the total amount of physical memory on the system and the amount of disk
  3664. space available. This can be changed (downward) by modifying the swap file
  3665. size specified in the SYSTEM.INI file, or by running the SWAPFILE program
  3666. (documented in the %@AI@%Microsoft Windows User Guide%@AE@%).  %@NL@%
  3667.  
  3668. The memory manager will continue to allocate physical memory until it has
  3669. been used up. Then, it will begin moving 4-kilobyte pages of code and data
  3670. from physical memory to disk to make additional physical memory available.
  3671. Windows pages in 4-kilobyte blocks, rather than unequal-sized code and data
  3672. segments. The swapped 4-kilobyte block may be only part of a given code or
  3673. data segment, or it may cross over two or more code or data segments.  %@NL@%
  3674.  
  3675. This memory paging is transparent to a program. If an attempt is made to
  3676. access a code or data segment of which some part has been paged out to disk,
  3677. the 80386 issues a page fault interrupt. The memory manager then swaps other
  3678. pages out of memory and restores the pages that the program needs.  %@NL@%
  3679.  
  3680. The Windows memory management services are presented in the following
  3681. categories. The services listed comprise the commonly used subset.  %@NL@%
  3682.  
  3683.  
  3684.   ■   System Data Object Management%@NL@%
  3685.  
  3686. %@STUB@%      Allocate_Device_CB_Area%@AB@%%@AE@%%@NL@%
  3687.  
  3688.   ■   Device V86 Page Management %@NL@%
  3689.  
  3690. %@STUB@%      Assign_Device_V86_Pages%@AB@%%@AE@%%@NL@%
  3691.  
  3692.   ■   GDT/LDT Management %@NL@%
  3693.  
  3694.   ■   System Heap Allocator %@NL@%
  3695.  
  3696. %@STUB@%      HeapAllocate%@AB@%%@AE@%%@NL@%
  3697.  
  3698. %@STUB@%      HeapFree%@AB@%%@AE@%%@NL@%
  3699.  
  3700.   ■   System Page Allocator %@NL@%
  3701.  
  3702. %@STUB@%      CopyPageTable%@AB@%%@AE@%%@NL@%
  3703.  
  3704. %@STUB@%      MapIntoV86%@AB@%%@AE@%%@NL@%
  3705.  
  3706. %@STUB@%      ModifyPageBits%@AB@%%@AE@%%@NL@%
  3707.  
  3708. %@STUB@%      PageAllocate%@AB@%%@AE@%%@NL@%
  3709.  
  3710. %@STUB@%      PageFree%@AB@%%@AE@%%@NL@%
  3711.  
  3712. %@STUB@%      PageLock%@AB@%%@AE@%%@NL@%
  3713.  
  3714. %@STUB@%      PageUnlock%@AB@%%@AE@%%@NL@%
  3715.  
  3716. %@STUB@%      PageGetAllocInfo%@AB@%%@AE@%%@NL@%
  3717.  
  3718. %@STUB@%      PhysIntoV86%@AB@%%@AE@%%@NL@%
  3719.  
  3720.   ■   Looking at Physical Device Memory in Protected Mode %@NL@%
  3721.  
  3722. %@STUB@%      MapPhysToLinear %@AB@%%@AE@%%@NL@%
  3723.  
  3724.   ■   Data Access Services%@NL@%
  3725.  
  3726. %@STUB@%      GetFirstV86Page%@AB@%%@AE@%%@NL@%
  3727.  
  3728.   ■   Special Services for Protected Mode APIs %@NL@%
  3729.  
  3730.   ■   Instance Data Management %@NL@%
  3731.  
  3732.   ■   Looking at V86 Address Space 
  3733. %@NL@%
  3734.  
  3735.  
  3736.  
  3737. %@2@%%@CR:C6A00190002 @%%@AB@%19.1  System Data Object Management%@AE@%%@EH@%%@NL@%
  3738.  
  3739. These services provide support for allocating special system areas. The two
  3740. areas managed are the Control Block and the Global V86 Addressable Area.  %@NL@%
  3741.  
  3742. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3743. NOTE
  3744.  
  3745. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  3746. %@AI@%procedure has an underscore in front (i.e., %@AB@%Allocate_Device_CB_Area%@AE@%%@AI@% is
  3747. %@AI@%actually %@AE@%%@AI@%%@AB@%_Allocate_Device_CB_Area%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to
  3748. %@AI@%left (unlike the PL/M calling convention used by Windows, which is left to
  3749. %@AI@%right). The return value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the
  3750. %@AI@%responsibility of the caller%@AE@%%@AI@%to clear the arguments off the stack. Registers
  3751. %@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@%
  3752. %@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. 
  3753. %@AI@%%@AE@%%@AE@%
  3754. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3755. %@CR:C6A00190003 @%%@CR:C6A00190004 @%
  3756. %@2@%%@CR:C6A00190005 @%%@AB@%Allocate_Device_CB_Area%@AE@%%@EH@%%@NL@%
  3757. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3758.  
  3759. %@AS@%  unsigned Allocate_Device_CB_Area(nBytes,flags) 
  3760. %@AS@%  unsigned nBytes; 
  3761. %@AS@%  unsigned flags;%@AE@%
  3762.  
  3763. This call is used to allocate a region of the Control Block data structure
  3764. to a particular device. Devices typically want some data that is "per VM".
  3765. For example, a device which is virtualizing a particular set of I/O ports
  3766. for the VM needs a place to store each VMs "instance" of the I/O port state.
  3767. This is done by allocating a region of the VM Control Block large enough to
  3768. hold a device specific data structure which contains the state. For example,
  3769. if the device specific data structure looks like this:  %@NL@%
  3770.  
  3771. %@AS@%  FooDeviceCB Struc 
  3772. %@AS@%   FooDevReg1  db ? ; Dev I/O register 1 
  3773. %@AS@%   FooDevReg2  db ? ; Dev I/O register 2 
  3774. %@AS@%   FooDevReg3  db ? ; Dev I/O register 3 
  3775. %@AS@%   FooDevReg4  db ? ; Dev I/O register 4 
  3776. %@AS@%   FooDevState  dd ? ; State flags for device 
  3777. %@AS@%  FooDeviceCB Ends%@AE@%
  3778.  
  3779. Space in the VM Control Block would be allocated like this:  %@NL@%
  3780.  
  3781. %@AS@%  VxD_DATA_SEG 
  3782. %@AS@%  FooDevCBOffset dd ? 
  3783. %@AS@%  VxD_DATA_ENDS 
  3784. %@AS@%  VxD_ICODE_SEG 
  3785. %@AS@%  ; 
  3786. %@AS@%  ; Allocate the Control Block space. This is in Foo's INIT routine 
  3787. %@AS@%  ; 
  3788. %@AS@%   VMMCall _Allocate_Device_CB_Area,<<SIZE FooDeviceCB>,0>
  3789. %@AS@%    or eax,eax
  3790. %@AS@%    jz short No_CB_Space_Error ; Probably FATAL error
  3791. %@AS@%    mov [FooDevCBOffset],eax
  3792. %@AS@%  
  3793. %@AS@%  VxD_ICODE_ENDS
  3794. %@AS@%  
  3795. %@AS@%  VxD_CODE_SEG 
  3796. %@AS@%  ; 
  3797. %@AS@%  ; In VxD procedures the Control Block pointer is passed 
  3798. %@AS@%  ;   in EBX the control block may be pointed to like this. 
  3799. %@AS@%  ; 
  3800. %@AS@%   mov edx,ebx
  3801. %@AS@%    add edx,[FooDevCBOffset]
  3802. %@AS@%    mov al,[edx.FooDevReg1]
  3803. %@AS@%    ...
  3804. %@AS@%  
  3805. %@AS@%  VxD_CODE_ENDS%@AE@%
  3806.  
  3807. The %@AI@%nBytes%@AE@% parameter specifies the number of bytes of space to be allocated.
  3808. There are currently no bits defined in the flags, this parameter must be set
  3809. to 0.  %@NL@%
  3810.  
  3811.  
  3812. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  3813.  
  3814. Returns nonzero Control Block Offset of the block allocated if successful,
  3815. returns zero if the space could not be allocated (This is probably a fatal
  3816. error, it is up to the caller to decide what is to be done in this case).  %@NL@%
  3817.  
  3818.  
  3819. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  3820.  
  3821. Control block Offsets returned from this call will be DWORD aligned. The
  3822. %@AI@%nBytes%@AE@% parameter does not have to be a multiple of 4, but if it isn't, it
  3823. will currently be rounded up to a multiple of 4. This may change in a later
  3824. releases, so do no depending one rounding.  %@NL@%
  3825.  
  3826. The above code sample is not the only way to do things. There are many other
  3827. ways the control block offset value can be used to access your devices
  3828. specific region of the control block.  %@NL@%
  3829.  
  3830. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3831. NOTE 
  3832.  
  3833. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  3834. %@AI@%therefore only be called during system initialization. Trying to call it
  3835. %@AI@%after system initialization and the system INIT segment space has been
  3836. %@AI@%reclaimed will result in a fatal page fault.%@AE@%
  3837. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3838.  
  3839. When Control Block regions are allocated they are initialized with value 0
  3840. in all bytes. When new VMs are created, all bytes of the Control Block are
  3841. set to 0.  %@NL@%
  3842.  
  3843. %@CR:C6A00190006 @%%@CR:C6A00190007 @%
  3844. %@2@%%@CR:C6A00190008 @%%@AB@%Allocate_Global_V86_Data_Area%@AE@%%@EH@%%@NL@%
  3845. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3846.  
  3847. %@AS@%  unsigned Allocate_Global_V86_Data_Area(nBytes,flags) 
  3848. %@AS@%  unsigned nBytes; 
  3849. %@AS@%  unsigned flags;%@AE@%
  3850.  
  3851. This call is used to allocate a region of the Global V86 Addressable Area to
  3852. a particular device. This area is used for device specific objects which
  3853. must also be addressable by the Virtual mode code running in the Virtual
  3854. Machine.  %@NL@%
  3855.  
  3856. An example is a Virtual mode software interrupt which is trapped by the
  3857. device and causes the return of a Virtual mode pointer to some data
  3858. associated with the device. The data must be in the VM's V86 address space
  3859. since a Virtual mode pointer to it is returned. In this case there is no
  3860. reason for the interrupt hook code to also be in the Global V86 Addressable
  3861. Area, that can all be in the protected mode device.  %@NL@%
  3862.  
  3863. The %@AI@%nBytes%@AE@% parameter specifies the number of bytes of space to be allocated.
  3864. Current flags bits:  %@NL@%
  3865.  
  3866. %@AS@%  GVDAWordAlign EQU 00000000000000000000000000000001B GVDADWordAlign EQU
  3867. %@AS@%00000000000000000000000000000010B GVDAParaAlign EQU
  3868. %@AS@%00000000000000000000000000000100B GVDAPageAlign EQU
  3869. %@AS@%00000000000000000000000000001000B GVDAInstance EQU
  3870. %@AS@%00000000000000000000000100000000B GVDAZeroInit EQU
  3871. %@AS@%00000000000000000000001000000000B GVDAReclaim EQU
  3872. %@AS@%00000000000000000000010000000000B%@AE@%
  3873.  
  3874. All unused bits must be zero. %@AB@%GVDA%@AE@%xxxx%@AB@%Align%@AE@% bits specify the indicated
  3875. alignment (WORD, DWORD, PARAGRAPH, PAGE) for the start of the block. If none
  3876. are set, BYTE alignment is assumed. %@AB@%GVDAInstance%@AE@%, if set, indicates that the
  3877. block is an item of VM instance data for which each different VM has its own
  3878. private values. If %@AB@%GVDAInstance%@AE@% is clear, the block is global data and all
  3879. VMs share the same value setting. %@AB@%GVDAZeroInit%@AE@%, if set, indicates that the
  3880. block is to initialized with value 0 in all bytes of the block. If
  3881. %@AB@%GVDAZeroInit%@AE@% is clear, the block will have random values in it.  %@NL@%
  3882.  
  3883. %@AB@%GVDAReclaim%@AE@% is only valid if %@AB@%GVDAPageAlign%@AE@% is set. IF %@AB@%GVDAReclaim%@AE@% is set,
  3884. then the physical pages of the region should be "reclaimed" by the MMGR
  3885. (memory manager) and placed on the free list, and the NUL page should be
  3886. mapped in the region.  %@NL@%
  3887.  
  3888.  
  3889. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  3890.  
  3891. Returns nonzero linear address of the block allocated if successful, returns
  3892. zero if the space could not be allocated. This is probably a fatal error; it
  3893. is up to the caller to decide what is to be done in this case.  %@NL@%
  3894.  
  3895.  
  3896. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  3897.  
  3898. The Flag bit equates are defined by including VMM.INC. The equates should be
  3899. used.  %@NL@%
  3900.  
  3901. For blocks allocated with %@AB@%GVDAInstance%@AE@% set, the %@AB@%AddInstanceItem%@AE@% call is made
  3902. by this routine for you.  %@NL@%
  3903.  
  3904. Note the interaction with %@AB@%Allocate_Temp_V86_Data_Area%@AE@%.  %@NL@%
  3905.  
  3906. Specifying multiple %@AB@%GVDA%@AE@%xxxx%@AB@%Align%@AE@% bits will result in random behavior. At
  3907. most ONE of these bits must be set.  %@NL@%
  3908.  
  3909. The returned linear address is a ring 0 linear address. It is up to the
  3910. caller to convert this into a Virtual mode SEG:OFFSET form if that is
  3911. needed.  %@NL@%
  3912.  
  3913. The linear addresses returned by this call will be %@NL@%
  3914.  
  3915. Generally only data needs to be placed in these blocks, but code can be
  3916. placed if desired.  %@NL@%
  3917.  
  3918. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3919. %@AU@%WARNING%@AE@%
  3920.  
  3921. You must be %@AI@%very careful%@AE@% if allocating two blocks, one for code which is %@AI@%not
  3922. %@AI@%%@AE@% instanced, and one for data which %@AI@%is%@AE@% Instanced because you %@AI@%cannot%@AE@% assume
  3923. that the two blocks will be within 64K of each other and thus addressable
  3924. with the same segment register in virtual-80 mode.
  3925. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3926.  
  3927. If the VxD desires the values of Instance fields allocated with this call to
  3928. have a set initial value whenever a new VM is created, the field must be
  3929. initialized with the desired values immediately after making this call. The
  3930. contents of the instance blocks at the time VxD initialization is completed
  3931. is what each new VM is created with.  %@NL@%
  3932.  
  3933. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3934. NOTE 
  3935.  
  3936. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  3937. %@AI@%therefore only be called during system initialization. Trying to call it
  3938. %@AI@%after system initialization and the system INIT segment space has been
  3939. %@AI@%reclaimed will result in a fatal page fault.%@AE@%
  3940. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3941.  
  3942.  
  3943. %@3@%%@AB@%Special notes for GVDAPageAlign%@AE@%%@EH@%%@NL@%
  3944.  
  3945. This type of allocation is intended to support Vxds which need a global page
  3946. aligned piece of V86 address space where they can %@AB@%MapIntoV86%@AE@% data. The best
  3947. example of such a VxD is the %@AB@%PageSwap%@AE@% device.  %@NL@%
  3948.  
  3949. The %@AI@%nBytes%@AE@% parameter should be a multiple of 4096 (page size).  %@NL@%
  3950.  
  3951. Note that this page is global but that %@AB@%MapIntoV86%@AE@%, %@AB@%PhysIntoV86%@AE@%, and
  3952. %@AB@%LinMapIntoV86%@AE@% are calls which are local to a specific VM. This means that a
  3953. VxD which wishes to globally change the mapping of this region must traverse
  3954. the VM list with %@AB@%Get_Next_VM_Handle%@AE@% and perform the map in each VM
  3955. individually.  %@NL@%
  3956.  
  3957. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3958. %@AU@%WARNING%@AE@%
  3959.  
  3960. Do not issue any of the map calls on this region before SYS_VM_Init device
  3961. call time. Failure to follow this rule can cause the page type bits in the
  3962. page table to get set improperly.
  3963. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3964.  
  3965. VxDs using this should set the correct initial VM state in their %@AB@%Create_VM%@AE@%
  3966. device call code. The initial state of the region is actually a copy of the
  3967. current state of %@AB@%SYS_VM_Handle%@AE@%, but you should not rely on this. Set the
  3968. initial state you want explicitly by making a %@AB@%MapIntoV86,%@AE@% or %@AB@%PhysIntoV86%@AE@%
  3969. call.  %@NL@%
  3970.  
  3971. The physical page(s) which are mapped into this region at the time you
  3972. allocate it are not pages that the MMGR worries about. It is up to the VxD
  3973. to put the physical pages to good use. The addresses of these physical
  3974. pages(s) is found by doing a %@AB@%CopyPageTable%@AE@% call on the %@AB@%SYS_VM_Handle%@AE@% and
  3975. looking at the physical address in the page table entries.  %@NL@%
  3976.  
  3977. Do not assume that the physical addresses of these pages equals the linear
  3978. address returned. This will be true on most machines, but not on some. These
  3979. pages by using are mapped with %@AB@%PhysIntoV86%@AE@%.  %@NL@%
  3980.  
  3981. If %@AB@%GVDAReclaim%@AE@% is set, then the physical pages that currently are mapped in
  3982. the region will be reclaimed by the MMGR and placed on the free list. The
  3983. NUL page will then be mapped in the region.  %@NL@%
  3984.  
  3985. If %@AB@%GVDAReclaim%@AE@% is clear, the %@AI@%physical%@AE@% page(s) which are mapped into this
  3986. region at the time you allocate it are not pages that the MMGR worries
  3987. about. It is up to the VxD to use these physical pages for something useful.
  3988. Avoid wasting them. The addresses of these %@AI@%physical%@AE@% pages(s) is found by
  3989. doing a %@AB@%CopyPageTable%@AE@% call on the %@AB@%SYS_VM_Handle%@AE@% and looking at the physical
  3990. address in the page table entries.  %@NL@%
  3991.  
  3992. It is invalid to assume that the physical addresses of these pages = the
  3993. linear address returned. This will be true on most machines, but on some it
  3994. will not. These pages are mapped using %@AB@%PhysIntoV86%@AE@%.  %@NL@%
  3995.  
  3996. You will not be able to %@AB@%Assign_Device_V86_Pages%@AE@% the pages of this region.
  3997. They are already marked as globally owned because they are below
  3998. %@AB@%FirstV86Page%@AE@%.  %@NL@%
  3999.  
  4000. You cannot set both %@AB@%GVDAReclaim%@AE@% and %@AB@%GVDAInstance%@AE@%. Attempting to do so will
  4001. result in an error.  %@NL@%
  4002.  
  4003. %@CR:C6A00190009 @%%@CR:C6A00190010 @%
  4004. %@2@%%@CR:C6A00190011 @%%@AB@%Allocate_Temp_V86_Data_Area%@AE@%%@EH@%%@NL@%
  4005. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4006.  
  4007. %@AS@%  unsigned Allocate_Temp_V86_Data_Area(nBytes,flags)
  4008. %@AS@%  unsigned nBytes; 
  4009. %@AS@%  unsigned flags;%@AE@%
  4010.  
  4011. This call is used to allocate a region of the Global V86 Addressable Area to
  4012. a particular device during system initialization.  %@NL@%
  4013.  
  4014. The primary reason for allocating this area is to create a buffer into which
  4015. data associated with some %@AB@%Simulate_Int%@AE@% activity (like an INT 21H MS-DOS
  4016. system call) can be placed. The area allocated with this call only exists
  4017. for a short period of time during initialization. The %@AI@%nBytes%@AE@% parameter
  4018. specifies the number of bytes of space to be allocated. There are currently
  4019. no bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4020.  
  4021.  
  4022. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4023.  
  4024. Returns nonzero linear address of the block allocated if successful, returns
  4025. zero if the space could not be allocated (insufficient memory, or temp area
  4026. already allocated).  %@NL@%
  4027.  
  4028.  
  4029. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4030.  
  4031. There is only one Temp area, therefore only one allocation will be allowed
  4032. to be outstanding at a time. Attempts to allocate the Temp area when it is
  4033. already allocated will result in an error.  %@NL@%
  4034.  
  4035. The %@AB@%Allocate_Global_V86_Data_Area%@AE@% call does not function while the Temp Area
  4036. is allocated. The Temp Area must be released with %@AB@%Free_Temp_V86_Data_Area%@AE@%
  4037. before the%@AB@% Allocate_Global_V86_Data_Area%@AE@% call can be made again.  %@NL@%
  4038.  
  4039. Make sure you %@AB@%Free_Temp_V86_Data_Area%@AE@% the temp area as soon as possible.  %@NL@%
  4040.  
  4041. The returned linear address is a ring 0 linear address. It is up to the
  4042. caller to convert this into a Virtual mode SEG:OFFSET form if that is
  4043. needed.  %@NL@%
  4044.  
  4045. The linear address returned by this call will be %@NL@%
  4046.  
  4047. Since this area exists only temporarily, it doesn't make sense to instance
  4048. any of it.  %@NL@%
  4049.  
  4050. The linear address returned from this call is paragraph aligned.  %@NL@%
  4051.  
  4052. The contents of the block will always be zero initialized by this call.  %@NL@%
  4053.  
  4054. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4055. NOTE 
  4056.  
  4057. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  4058. %@AI@%therefore only be called during system initialization. Trying to call it
  4059. %@AI@%after system initialization and the system INIT segment space has been
  4060. %@AI@%reclaimed will result in a fatal page fault.%@AE@%
  4061. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4062.  
  4063. %@CR:C6A00190012 @%%@CR:C6A00190013 @%
  4064. %@2@%%@CR:C6A00190014 @%%@AB@%Free_Temp_V86_Data_Area%@AE@%%@EH@%%@NL@%
  4065. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4066.  
  4067. %@AS@%  unsigned Free_Temp_V86_Data_Area()%@AE@%
  4068.  
  4069. This call is used to free the %@AB@%Temp_V86_Data_Area%@AE@% allocated with
  4070. %@AB@%Allocate_Temp_V86_Data_Area.%@AE@%  %@NL@%
  4071.  
  4072.  
  4073. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4074.  
  4075. Returns nonzero if successful, returns zero if unsuccessful (Temp Area not
  4076. allocated).  %@NL@%
  4077.  
  4078.  
  4079. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4080.  
  4081. The %@AB@%Allocate_Global_V86_Data_Area%@AE@% call does not function while the Temp Area
  4082. is allocated. The Temp Area must be released with%@AB@% Free_Temp_V86_Data_Area%@AE@%
  4083. before the %@AB@%Allocate_Global_V86_Data_Area%@AE@% call can be made again.  %@NL@%
  4084.  
  4085. Once this call is issued, the Linear Address that was returned from
  4086. %@AB@%Allocate_Temp_V86_Data_Area%@AE@% can no longer be used for anything. The system
  4087. will probably crash if this is attempted.  %@NL@%
  4088.  
  4089. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4090. NOTE 
  4091.  
  4092. %@AI@%This routine itself is in the init segment of enhanced Windows. It can
  4093. %@AI@%therefore only be called during system initialization. Trying to call it
  4094. %@AI@%after system initialization and the system INIT segment space has been
  4095. %@AI@%reclaimed will result in a fatal page fault. %@AE@%
  4096. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4097.  
  4098.  
  4099. %@2@%%@CR:C6A00190015 @%%@AB@%19.2  Device V86 Page Management%@AE@%%@EH@%%@NL@%
  4100. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4101.  
  4102. Certain types of VxDs may want to take control of certain regions of the
  4103. VM's virtual-86 address space for use by the VxD. The best examples of this
  4104. are as follows:  %@NL@%
  4105.  
  4106.  
  4107.   ■   The display device (VDD), which wants to reserve those areas of the
  4108.       A0H to BFH page address range that are used by the display device.%@NL@%
  4109.  
  4110.   ■   The EMM device (part of V86MMGR), which wants to use a region of VM
  4111.       V86 address space between pages A0H and 100H for the high memory EMM
  4112.       3.20 Mapping Window.%@NL@%
  4113.  
  4114.   ■   The device responsible for management of the EBIOS page, page 9FH, on
  4115.       machines like the IBM PS/2(R) Model 80. %@NL@%
  4116.  
  4117.  
  4118. The following calls enable VxDs to allocate VM V86 address ranges for such
  4119. purposes and cooperate with other VxDs that also might want to use them.
  4120. There are two types of assignment that can be used: global, which applies to
  4121. all VMs in the system, and local, which applies to only one VM. The VDD
  4122. video and EBIOS page assignments are examples of global assignment (although
  4123. these could be local depending on the specifics of the implementation). The
  4124. EMM assignments are an example of local assignments. The EMM driver does not
  4125. want to take over VM V86 page assignment in VMs that are not using EMM
  4126. because then all those pages cannot be used by any other device. Thus, it
  4127. waits until a specific VM makes an EMM call of a certain type at which point
  4128. the EMM driver %@AI@%may%@AE@% do a local page assignment in that particular VM to
  4129. assign the EMM pages of the V86 address space to the EMM device. The global
  4130. versus local assignment is specified via the %@AI@%VMHandle%@AE@% parameter on the
  4131. calls. If the handle is nonzero, it is local; if the handle is zero, it is
  4132. global.  %@NL@%
  4133.  
  4134. No protection is provided with this mechanism; all that is provided is
  4135. information so that devices can cooperate. There is nothing to prevent a VxD
  4136. from mapping pages that it does not own or a page owned by some other VxD. A
  4137. device that does these things is simply uncooperative and not correctly
  4138. implemented.  %@NL@%
  4139.  
  4140. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4141. NOTE
  4142.  
  4143. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  4144. %@AI@%procedure has an underscore in front (i.e., %@AB@%Assign_Device _V86_Pages%@AE@%%@AI@% is
  4145. %@AI@%actually %@AE@%%@AI@%%@AB@%_Assign_Device_V86_Pages%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to
  4146. %@AI@%left (unlike the PL/M calling convention used by Windows, which is left to
  4147. %@AI@%right). The return value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the
  4148. %@AI@%responsibility of the caller%@AE@%%@AI@% to clear the arguments off the stack. Registers
  4149. %@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@%
  4150. %@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@%
  4151. %@AE@%
  4152. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4153. %@CR:C6A00190016 @%
  4154. %@2@%%@CR:C6A00190017 @%%@AB@%Assign_Device_V86_Pages Assign_Device_V86_Pages service%@AE@%%@EH@%%@NL@%
  4155. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4156.  
  4157. %@AS@%  unsigned Assign_Device_V86_Pages(VMLinrPage,nPages,VMHandle,flags)
  4158. %@AS@%  unsigned VMLinrPage; 
  4159. %@AS@%  unsigned nPages; 
  4160. %@AS@%  unsigned VMHandle; 
  4161. %@AS@%  unsigned flags;%@AE@%
  4162.  
  4163. This call is used to assign a region of VM V86 address space to a device.
  4164. %@AI@%VMLinrPage%@AE@% specifies the linear page number (>=0, <=10Fh) of the first page
  4165. of V86 address space to be assigned. %@AI@%nPages%@AE@% specifies the number of pages to
  4166. be assigned starting at %@AI@%VMLinrPage%@AE@%. The entire specified range must be >=0,
  4167. <=10Fh, an error will occur if it is not. All of the specified pages must be
  4168. un-assigned, or an error will occur. %@AI@%VMHandle%@AE@% specifies the VM to Local
  4169. assign the pages in, if this parameter is 0, it means the pages are to be
  4170. Global assigned. There are currently no bits defined in the %@AI@%flags%@AE@%, this
  4171. parameter must be set to 0.  %@NL@%
  4172.  
  4173.  
  4174. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4175.  
  4176. Returns nonzero if the assignment was successful, returns zero if the
  4177. assignment failed (at least one page in the specified range is already
  4178. assigned, or invalid page range).  %@NL@%
  4179.  
  4180.  
  4181. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4182.  
  4183. During device initialization only Global Assignments are allowed, and there
  4184. are restrictions on the pages which can be assigned. Pages between
  4185. %@AB@%FirstV86Page%@AE@% and page 0A0h can only be top down, in order assigned during
  4186. device initialization. Local Assignments, and General assignment between
  4187. %@AB@%FirstV86Page%@AE@% and page 0A0h must wait until device initialization is
  4188. complete.  %@NL@%
  4189.  
  4190. Note that Global Assignment of a page that is already assigned, either Local
  4191. to any VM, or Global assigned will fail. Global assignment can only work on
  4192. pages which are not currently assigned in any VM.  %@NL@%
  4193.  
  4194. %@CR:C6A00190018 @%%@CR:C6A00190019 @%
  4195. %@2@%%@CR:C6A00190020 @%%@AB@%Deassign_Device_V86_Pages%@AE@%%@EH@%%@NL@%
  4196. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4197.  
  4198. %@AS@%  unsigned DeAssign_Device_V86_Pages(VMLinrPage,nPages,VMHandle,flags)
  4199. %@AS@%  unsigned VMLinrPage; 
  4200. %@AS@%  unsigned nPages; 
  4201. %@AS@%  unsigned VMHandle; 
  4202. %@AS@%  unsigned flags;%@AE@%
  4203.  
  4204. This call is used to deassign a region of VM V86 address which was
  4205. previously assigned with %@AB@%Assign_Device_V86_Pages%@AE@%. %@AI@%VMLinrPage%@AE@% specifies the
  4206. linear page number (>=0, <=10Fh) of the first page to be deassigned. %@AI@%nPage%@AE@%s
  4207. specifies the number of pages to be deassigned starting at %@AI@%VMLinrPage%@AE@%. The
  4208. entire specified range must be >=0, <=10Fh, an error will occur if it is
  4209. not. All of the specified pages must be assigned, or an error will occur.
  4210. %@AI@%VMHandle%@AE@% specifies the VM to Local deassign the pages in, if this parameter
  4211. is 0, it means the pages are to be Global deassigned. There are currently no
  4212. bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4213.  
  4214.  
  4215. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4216.  
  4217. Returns nonzero if the deassignment was successful, returns zero if the
  4218. deassignment failed (at least one page in the specified range is already
  4219. deassigned, or invalid page range).  %@NL@%
  4220.  
  4221.  
  4222. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4223.  
  4224. During device initialization this call will always fail. This call only
  4225. works after device initialization is complete.  %@NL@%
  4226.  
  4227. An extreme amount of chaos will occur if someone Global DeAssigns a range
  4228. which is actually Local Assigned, or DeAssigns a region which was not
  4229. obtained via a successful%@AB@% Assign_Device_V86_Pages. %@AE@%  %@NL@%
  4230.  
  4231. %@CR:C6A00190021 @%%@CR:C6A00190022 @%
  4232. %@2@%%@CR:C6A00190023 @%%@AB@%Get_Device_V86_Pages_Array%@AE@%%@EH@%%@NL@%
  4233. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4234.  
  4235. %@AS@%  unsigned Get_Device_V86_Pages_Array(VMHandle,ArrayBufPTR,flags)
  4236. %@AS@%  unsigned VMHandle; 
  4237. %@AS@%  unsigned ArrayBufPTR; 
  4238. %@AS@%  unsigned flags;%@AE@%
  4239.  
  4240. This call is used to obtain a copy of the assignment bit map array for
  4241. %@AB@%Device_V86_Pages%@AE@%. This allows the caller to determine which regions of the
  4242. VM V86 address space are currently assigned, and which are available.
  4243. %@AI@%VMHandle%@AE@% specifies the VM to get the assignment bit map of, if this
  4244. parameter is 0, it means to get the Global assignment array. %@AI@%ArrayBufPTR%@AE@%
  4245. points to a buffer large enough to contain the array. The assignment array
  4246. is an array of 110h bits, one bit for each page in the range 0-10Fh. Thus
  4247. the size of the array is ((110h/8)+3)/4 = 9 DWORDS.  %@NL@%
  4248.  
  4249. Bits in the array which are set (=1) indicate pages which are assigned, bits
  4250. which are clear (=0) indicate pages which are not assigned. Thus to test the
  4251. bit for page number N (0 N 10Fh) you could use code like this:  %@NL@%
  4252.  
  4253. %@AS@%  mov ebx, N MOD 32   ; Bit number in DWORD
  4254. %@AS@%    mov eax, N / 32  ; DWORD index into array
  4255. %@AS@%    bt dword ptr ArrayBufPTR[eax*4],ebx ; Test bit for page N
  4256. %@AS@%    jnc short PageUnAssigned      PageAssigned:%@AE@%
  4257.  
  4258. Note that this code is mearly intended to illustrate how the bit array
  4259. works. This code is not the most efficient, or the only way to implement
  4260. this test. There are currently no bits defined in the %@AI@%flags%@AE@%, this parameter
  4261. must be set to 0.  %@NL@%
  4262.  
  4263.  
  4264. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4265.  
  4266. Returns nonzero if successful, returns zero if the bit array could not be
  4267. returned (Invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  4268.  
  4269.  
  4270. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4271.  
  4272. The Global Bit Array only indicates those pages which are currently Globally
  4273. owned. Bits with 0 in them do not necessarily indicate pages which can be
  4274. %@AB@%Global Assign_Device_V86_Paged%@AE@%. The reason is that one of the VMs in the
  4275. system may have that page Local %@AB@%Assign_Device_V86_Paged%@AE@%. In order to
  4276. determine if a page can be globally assigned, the Global array must be
  4277. examined, AND all of the VM Local arrays must be examined.  %@NL@%
  4278.  
  4279. %@CR:C6A00190024 @%%@CR:C6A00190025 @%
  4280. %@2@%%@CR:C6A00190026 @%%@AB@%Hook_V86_Page%@AE@%%@EH@%%@NL@%
  4281. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4282.  
  4283. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4284. NOTE
  4285.  
  4286. %@AI@%This service does not use the C-calling Convention%@AE@%
  4287.  
  4288. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4289.  
  4290.  
  4291. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  4292.  
  4293. This service allows VxDs to intercept page faults in portions of the V86
  4294. address space of every virtual machine. It is used by devices such as the
  4295. Virtual Display Device to detect when particular address ranges are
  4296. accessed.  %@NL@%
  4297.  
  4298. You must specify a page number and address of a call-back routine to this
  4299. service. If it is installed successfully, your "hook" will be called every
  4300. time a page fault occurs in ANY VM on that page. See the memory manager
  4301. _Modify_Pages documentation for making hooked pages not present and for
  4302. registering ownership of pages.  %@NL@%
  4303.  
  4304. The callback routine is responsible for mapping an memory at the location of
  4305. the page fault or crashing the VM. In unusual circumstances it may be
  4306. appropriate to map a null page at the faulting faulting address page. See
  4307. the memory manager documentation for details on mapping memory and mapping
  4308. null pages.  %@NL@%
  4309.  
  4310. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4311. NOTE
  4312.  
  4313. %@AI@%Do not rely on the contents of the CR2 (page fault) register. Use the value
  4314. %@AI@%passed to your call-back in EAX.%@AE@%
  4315. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4316.  
  4317.  
  4318. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  4319.  
  4320. EAX = Page number (A0h - 0FFh) ESI = Address of trap routine  %@NL@%
  4321.  
  4322.  
  4323. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  4324.  
  4325. If carry flag set then ERROR: Invalid page number or page already hooked
  4326. else Page hooked  %@NL@%
  4327.  
  4328.  
  4329. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  4330.  
  4331. Flags  %@NL@%
  4332.  
  4333.  
  4334. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  4335.  
  4336. EAX = Faulting page number EBX = Current VM handle EBP does NOT point to the
  4337. client register structure.  %@NL@%
  4338.  
  4339.  
  4340. %@2@%%@CR:C6A00190027 @%%@AB@%19.3  GDT/LDT Management%@AE@%%@EH@%%@NL@%
  4341. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4342.  
  4343. These services provide a way for VxDs to allocate Global Descriptor Table
  4344. (GDT) selectors and set up a Local Descriptor Table (LDT) for protected-mode
  4345. execution. Notice that the intent of these services is to support segmented
  4346. environments in protected mode. In general, VxDs should never need to
  4347. allocate GDT selectors or set up an LDT. The only reason these services are
  4348. needed is to support protected-mode applications. Notice that the LDT is a
  4349. per-VM object; each VM may have its own LDT. Since enhanced Windows is a
  4350. flat model system, do not create multiple segments.%@CR:C6A00190028 @%%@CR:C6A00190029 @%%@CR:C6A00190030 @%%@NL@%
  4351.  
  4352. %@CR:C6A00190031 @%%@CR:C6A00190032 @%
  4353. %@2@%%@CR:C6A00190033 @%%@AB@%Allocate_GDT_Selector%@AE@%%@EH@%%@NL@%
  4354. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4355.  
  4356. %@AS@%  unsigned Allocate_GDT_Selector(DescDWORD1,DescDWORD2,flags)
  4357. %@AS@%  unsigned DescDWORD1; 
  4358. %@AS@%  unsigned DescDWORD2; 
  4359. %@AS@%  unsigned flags;%@AE@%
  4360.  
  4361. This call is used to create a new GDT selector. %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@%
  4362. form the 8 bytes of information to be placed in the new descriptor.
  4363. %@AI@%DescDWORD1%@AE@% is the high order 4 bytes of the descriptor containing the high
  4364. 16 bits of the base, the high 4 bits of the limit and the status and type
  4365. bits. %@AI@%DescDWORD2%@AE@% is the low order 4 bytes for the descriptor containing the
  4366. low 16 bits of the base and limit. Use %@AB@%BuildDescDWORDs%@AE@% to help you set up
  4367. these arguments. There are currently no bits defined in the %@AI@%flags%@AE@%, this
  4368. parameter must be set to 0.  %@NL@%
  4369.  
  4370.  
  4371. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4372.  
  4373. Returns a 64 bit long which is actually two 32 bit DWORDs. The low DWORD
  4374. (%@AB@%EAX%@AE@%) is the non-zero selector if succesfull. The high DWORD (%@AB@%EDX%@AE@%) is split
  4375. into two 16 bit word returns. The low 16 bits of %@AB@%EDX%@AE@% is the GDT descriptor
  4376. which describes the GDT itself. Unlike the LDT, it is strongly recommended
  4377. that this selector %@AI@%not %@AE@%be used to edit the GDT. If you mess up editing the
  4378. LDT, you will probably just crash one app, but if you mess up editing the
  4379. GDT, you will crash the whole system. The high 16 bits of %@AB@%EDX%@AE@% is the number
  4380. of selectors currently in the GDT (the "limit" of the GDT expressed as a
  4381. number of selectors, (LIMIT+1)/8). Both DWORDS have value 0 if the
  4382. allocation failed (Bad DescDWORD arguments, GDT is full, insufficient memory
  4383. to grow GDT).  %@NL@%
  4384.  
  4385.  
  4386. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4387.  
  4388. The RPL of the selector returned from this call will be set to the DPL of
  4389. the selector set in %@AI@%DescDWORD1%@AE@%.  %@NL@%
  4390.  
  4391. The low 16 bits of the %@AB@%EDX%@AE@% return does not change, but it is safest to save
  4392. the value of the GDT selector after each %@AB@%Allocate_GDT_Selector%@AE@% call. This
  4393. selector will have DPL = RPL = 0, and the TI bit (bit 2) will be clear.  %@NL@%
  4394.  
  4395. The high 16 bits of the %@AB@%EDX%@AE@% return must be saved after each call, if its
  4396. value is important, because the size of the GDT may change on each call.  %@NL@%
  4397.  
  4398. The prefered method of changing a GDT descriptor is to use %@AB@%SetDescriptor%@AE@%,
  4399. rather than using the GDT selector which is returned by this call.  %@NL@%
  4400.  
  4401. %@CR:C6A00190034 @%%@CR:C6A00190035 @%
  4402. %@2@%%@CR:C6A00190036 @%%@AB@%Allocate_LDT_Selector%@AE@%%@EH@%%@NL@%
  4403. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4404.  
  4405. %@AS@%  unsigned long
  4406. %@AS@%  Allocate_LDT_Selector(VMHandle,DescDWORD1,DescDWORD2,Count,flags)
  4407. %@AS@%  unsigned VMHandle; 
  4408. %@AS@%  unsigned DescDWORD1; 
  4409. %@AS@%  unsigned DescDWORD2; 
  4410. %@AS@%  unsigned Count; 
  4411. %@AS@%  unsigned flags;%@AE@%
  4412.  
  4413. This call is used to create new LDT selector(s) in the specified VM context.
  4414. %@AI@%VMHandle%@AE@% is a valid VM handle and indicates the VM context for which the
  4415. selector(s) will be valid. %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@% form the 8 bytes of
  4416. information to be placed in the new descriptor(s). %@AI@%DescDWORD1%@AE@% is the high
  4417. order 4 bytes of the descriptor containing the high 16 bits of the base, the
  4418. high 4 bits of the limit and the status and type bits. %@AI@%DescDWORD2%@AE@% is the low
  4419. order 4 bytes for the descriptor containing the low 16 bits of the base and
  4420. limit. Use %@AB@%BuildDescDWORDs%@AE@% to help you set up these arguments. The %@AI@%Count
  4421. %@AI@%%@AE@%parameter specifies the number of contiguous LDT selectors to allocate. This
  4422. parameter supports Block Selector Assignment strategies. USE16 segmented
  4423. applications cannot address objects larger than 64K Bytes in size without
  4424. having multiple selectors that describe the sequential 64K Byte blocks of
  4425. the object. For an object <=64K bytes in size, or instances where it is
  4426. inappropriate, Count = 1. For an object >64K bytes in size, Count = (Size +
  4427. (64K - 1))/64K. Notice that the selectors allocated for count >1 all have
  4428. the same descriptor DWORDs in them. It is up to the caller to edit the base
  4429. and limits of the individual selectors in a Block Selector Assignment using
  4430. the LDT selector returned in the low 16 bits of %@AB@%EDX%@AE@%. There are currently no
  4431. bits defined in the flags, this parameter must be set to 0.  %@NL@%
  4432.  
  4433.  
  4434. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4435.  
  4436. Returns a 64 bit long which is actually two 32 bit DWORDs. The low DWORD
  4437. (%@AB@%EAX%@AE@%) is the nonzero selector if successful, if Count was >1, this is the
  4438. FIRST selector, the second is %@AB@%EAX%@AE@%+8, the third %@AB@%EAX%@AE@%+16, etc. The high DWORD
  4439. (%@AB@%EDX%@AE@%) is split into two 16 bit word returns. The low 16 bits of %@AB@%EDX%@AE@% is the
  4440. LDT descriptor which describes the LDT itself. The allows the caller to do
  4441. things such as change the present bit of LDT selectors and change the base
  4442. and limit. The high 16 bits of %@AB@%EDX%@AE@% is the number of selectors currently in
  4443. the LDT (the "limit" of the LDT expressed as a number of selectors,
  4444. (LIMIT+1)/8). Both DWORDS have value 0 if the allocation failed (Bad
  4445. DescDWORD arguments, LDT is full, invalid %@AI@%VMHandle%@AE@% insufficient memory to
  4446. grow LDT).  %@NL@%
  4447.  
  4448.  
  4449. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4450.  
  4451. The RPL of the selector returned from this call will be set to the DPL of
  4452. the selector set in %@AI@%DescDWORD1%@AE@% and the TI bit (bit 2) will be set.  %@NL@%
  4453.  
  4454. The high 16 bits of the %@AB@%EAX%@AE@% return are zero since selectors are 16 bit
  4455. quantities.  %@NL@%
  4456.  
  4457. Note that LDT selectors are PER VM and only valid in that VM context (VM
  4458. must be current VM for selector to be valid). Use %@AB@%SelectorMapFlat%@AE@% to look at
  4459. regions described by LDT selectors in VMs which are not the current VM.  %@NL@%
  4460.  
  4461. The low 16 bits of the %@AB@%EDX%@AE@% return does not change once the LDT of a
  4462. particular VM is created, but it is safest to save the value of the LDT
  4463. selector after each %@AB@% Allocate_LDT_Selector call.%@AE@% This selector will have DPL
  4464. = RPL = Protected Mode Application Privilege, and the TI bit (bit 2) will be
  4465. set.  %@NL@%
  4466.  
  4467. The high 16 bits of the %@AB@%EDX%@AE@% return %@AI@%must be saved%@AE@% after each call, if its
  4468. value is important, because the size of the LDT may change on each call.  %@NL@%
  4469.  
  4470. The multiple selectors allocated with Count >1 must be individually freed.
  4471. %@AB@%_Free_LDT_Selector%@AE@% does not have a count.  %@NL@%
  4472.  
  4473. The prefered method of changing an LDT descriptor is to use %@AB@%SetDescriptor%@AE@%.  %@NL@%
  4474.  
  4475. Use of ALDTSpecSel is not advised. Reliance on specific "hard coded" LDT
  4476. selectors is contrary to good system design principals. Note that a bit like
  4477. this does not exist for %@AB@%Allocate_GDT_Selector%@AE@%, this is intentional. A call
  4478. with this bit set may always fail for some values of the Count parameter,
  4479. and it may start failing for all values of the Count parameter in a later
  4480. release of the product.  %@NL@%
  4481.  
  4482. %@CR:C6A00190037 @%%@CR:C6A00190038 @%
  4483. %@2@%%@CR:C6A00190039 @%%@AB@%BuildDescDWORDs%@AE@%%@EH@%%@NL@%
  4484. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4485.  
  4486. %@AS@%  unsigned  long BuildDescDWORDs(DESCBase,DESCLimit,DESCType,DESCSize,flags)
  4487. %@AS@%  unsigned  DESCBase; 
  4488. %@AS@%  unsigned  DESCLimit; 
  4489. %@AS@%  unsigned  DESCType; 
  4490. %@AS@%  unsigned  DESCSize;
  4491. %@AS@%  unsigned Flags%@AE@%
  4492.  
  4493. This call is used to help you build the %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@% arguments
  4494. for calls to %@AB@%Allocate_LDT/GDT_Selector%@AE@%. DESCBase is the 32 bit BASE for the
  4495. descriptor. DESCLimit is the 20 bit LIMIT for the descriptor. %@AI@%DESCType%@AE@%
  4496. specifies the type BYTE (Only low 8 bits of the parameter are valid, other
  4497. bits must be 0) for the descriptor. This is the byte that occupies bits 8-15
  4498. of the high DWORD of the descriptor (Present bit, DPL and TYPE fields).
  4499. %@AI@%DESCSize%@AE@% specifies bits 20-23 of the high DWORD of the descriptor
  4500. (Granularity, Big/Default). Notice that these bits occupy bits 4-7 of the
  4501. %@AI@%DESCSize%@AE@% parameter, other bits must be 0. In other words %@AI@%DESCSize%@AE@% specifies
  4502. a byte just like DESCType where only the high 4 bits of the byte are
  4503. specified.  %@NL@%
  4504.  
  4505. Current flags bits:  %@NL@%
  4506.  
  4507. %@AS@%  BDDExplicitDPL EQU 00000000000000000000000000000001B%@AE@%
  4508.  
  4509. All unused bits must be zero. BDDExplicitDPL, if set, indicates that the DPL
  4510. value specified in the DESCType field is to be used. If this bit is clear,
  4511. then the DPL specified in the DESCType field is ignored and the DPL returned
  4512. will be set to the protected mode application RPL. Since most selectors are
  4513. built for the use by protected mode applications, this provides a
  4514. convienient way to build descriptors without having to actually know which
  4515. ring protected mode applications run in.  %@NL@%
  4516.  
  4517.  
  4518. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4519.  
  4520. Returns the low DWORD of the descriptor (%@AI@%DescDWORD2%@AE@%) in %@AB@%EAX%@AE@%, and the high
  4521. DWORD of the descriptor (%@AI@%DescDWORD1%@AE@%) in %@AB@%EDX%@AE@%.  %@NL@%
  4522.  
  4523.  
  4524. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4525.  
  4526. If you are building selectors for use by Protected Mode applications use the
  4527. built-in capability provided by not setting the BDDExplicitDPL bit. Do not
  4528. make assumptions about which ring protected mode applications run in. The
  4529. selection of a ring for PM applications will be changed in future revs of
  4530. Windows.  %@NL@%
  4531.  
  4532. %@CR:C6A00190040 @%%@CR:C6A00190041 @%
  4533. %@2@%%@CR:C6A00190042 @%%@AB@%Free_GDT_Selector%@AE@%%@EH@%%@NL@%
  4534. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4535.  
  4536. %@AS@%  unsigned Free_GDT_Selector(Selector,flags) 
  4537. %@AS@%  unsigned Selector; 
  4538. %@AS@%  unsigned flags;%@AE@%
  4539.  
  4540. This call is used to free a GDT selector allocated with a previous
  4541. %@AB@%Allocate_GDT_Selector%@AE@% call. %@AI@%Selector%@AE@% is the return from a previous
  4542. %@AB@%Allocate_GDT_Selector%@AE@% call. There are currently no bits defined in the
  4543. %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4544.  
  4545.  
  4546. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4547.  
  4548. Returns nonzero value if successful, returns zero if the free failed
  4549. (invalid %@AI@%Selector%@AE@%).  %@NL@%
  4550.  
  4551.  
  4552. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4553.  
  4554. Certain system selectors cannot be freed since they are required for
  4555. operation of enhanced Windows.  %@NL@%
  4556.  
  4557. %@CR:C6A00190043 @%%@CR:C6A00190044 @%
  4558. %@2@%%@CR:C6A00190045 @%%@AB@%Free_LDT_Selector%@AE@%%@EH@%%@NL@%
  4559. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4560.  
  4561. %@AS@%  unsigned Free_LDT_Selector(VMHandle,Selector,flags) 
  4562. %@AS@%  unsigned VMHandle; 
  4563. %@AS@%  unsigned Selector; 
  4564. %@AS@%  unsigned flags;%@AE@%
  4565.  
  4566. This call is used to free a LDT selector allocated with a previous
  4567. %@AB@%Allocate_LDT_Selector%@AE@% call. %@AI@%VMHandle%@AE@% indicates the VM context of the
  4568. selector. %@AI@%Selector%@AE@% is the return from a previous %@AB@%Allocate_LDT_Selector%@AE@% call.
  4569. There are currently no bits defined in the %@AI@%flags%@AE@%, this parameter must be set
  4570. to 0.  %@NL@%
  4571.  
  4572.  
  4573. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4574.  
  4575. Returns nonzero value if successful, returns zero if the free failed
  4576. (invalid %@AI@%Selector%@AE@%, invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  4577.  
  4578.  
  4579. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4580.  
  4581. The RPL bits of the passed Selector are ignored by this call.  %@NL@%
  4582.  
  4583.  
  4584. %@2@%%@CR:C6A00190046 @%%@AB@%GetDescriptor%@AE@%%@EH@%%@NL@%
  4585. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4586.  
  4587. %@AS@%  unsigned long GetDescriptor(Selector,VMHandle,flags) unsigned Selector;
  4588. %@AS@%  unsigned VMHandle;
  4589. %@AS@%  unsigned flags;%@AE@%
  4590.  
  4591. This call is used to get a copy of the two descriptor DWORDs associated with
  4592. the given LDT or GDT Selector. Selector is a GDT or LDT selector value to
  4593. get the descriptor of. The %@AI@%VMHandle%@AE@% parameter is ignored if Selector is a
  4594. GDT selector. If Selector is an LDT selector, then %@AI@%VMHandle%@AE@% indicates the
  4595. appropriate VM context for the Selector. There are currently no bits defined
  4596. in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4597.  
  4598.  
  4599. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4600.  
  4601. Returns the low DWORD of the descriptor (%@AI@%DescDWORD2%@AE@%) in %@AB@%EAX%@AE@%, and the high
  4602. DWORD of the descriptor (%@AI@%DescDWORD1%@AE@%) in %@AB@%EDX%@AE@%. Returns zero in both DWORDs if
  4603. there was an error (invalid selector, invalid VM handle).  %@NL@%
  4604.  
  4605.  
  4606. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4607.  
  4608. The high 16 bits of the Selector argument are ignored (this is because the
  4609. 80386 CPU often sets them to somewhat random values when DWORD operations
  4610. are performed on segment registers).  %@NL@%
  4611.  
  4612. The RPL bits of Selector are ignored.  %@NL@%
  4613.  
  4614. The %@AI@%VMHandle%@AE@% parameter must be valid for LDT selectors.  %@NL@%
  4615.  
  4616.  
  4617. %@2@%%@CR:C6A00190047 @%%@AB@%SetDescriptor%@AE@%%@EH@%%@NL@%
  4618. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4619.  
  4620. %@AS@%  unsigned SetDescriptor(Selector,VMHandle,DescDWORD1,DescDWORD2,flags)
  4621. %@AS@%unsigned Selector;
  4622. %@AS@%  unsigned VMHandle;
  4623. %@AS@%  unsigned DescDWORD1;
  4624. %@AS@%  unsigned DescDWORD2;
  4625. %@AS@%  unsigned flags;%@AE@%
  4626.  
  4627. This call is used to set (change) the descriptor of the given Selector.
  4628. Selector is a GDT or LDT selector value to set the descriptor of. The
  4629. %@AI@%VMHandle%@AE@% parameter is ignored if Selector is a GDT selector. If Selector is
  4630. an LDT selector, then VMHandle indicates the appropriate VM context for the
  4631. Selector. %@AI@%DescDWORD1%@AE@% and %@AI@%DescDWORD2%@AE@% form the 8 bytes of information to be
  4632. placed in the descriptor. %@AI@%DescDWORD1%@AE@% is the high ORDER 4 bytes of the
  4633. descriptor containing the high 16 bits of the base, the high 4 bits of the
  4634. limit and the status and type bits. %@AI@%DescDWORD2%@AE@% is the low ORDER 4 bytes for
  4635. the descriptor containing the low 16 bits of the base and limit. Use
  4636. %@AB@%BuildDescriptorDWORDs%@AE@% to help you set up these arguments. There are
  4637. currently no bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4638.  
  4639.  
  4640. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4641.  
  4642. Returns non-zero value if succesfull, returns zero if it failed (invalid
  4643. %@AI@%Selector%@AE@%, invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  4644.  
  4645.  
  4646. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4647.  
  4648. The high 16 bits of the Selector argument are ignored (this is because the
  4649. 80386 CPU often sets them to somewhat random values when DWORD operations
  4650. are performed on segment registers).  %@NL@%
  4651.  
  4652. The RPL bits of Selector are ignored.  %@NL@%
  4653.  
  4654. The %@AI@%VMHandle%@AE@% parameter must be valid for LDT selectors.  %@NL@%
  4655.  
  4656.  
  4657. %@2@%%@CR:C6A00190048 @%%@AB@%19.4  System Heap Allocator%@AE@%%@EH@%%@NL@%
  4658. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4659.  
  4660. The purpose of the heap allocator is to provide a memory manager service to
  4661. system components to allocate small (i.e., less than a page size) blocks of
  4662. memory for long term or short term use.  %@NL@%
  4663.  
  4664. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4665. NOTE
  4666.  
  4667. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  4668. %@AI@%procedure has an underscore in front (i.e., %@AB@%HeapAllocate%@AE@%%@AI@% is actually
  4669. %@AI@%%@AE@%%@AI@%%@AB@%_HeapAllocate%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to left (unlike the PL/M
  4670. %@AI@%calling convention used by Windows, which is left to right). The return
  4671. %@AI@%value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the responsibility of the
  4672. %@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
  4673. %@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
  4674. %@AB@%%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%ESI%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved.%@AE@%%@AE@%
  4675. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4676. The heap uses a boundary tag allocation scheme similar to the one used by
  4677. the MS-DOS operating system. This has the benefit of not placing some fixed
  4678. limit on the total number of heap blocks. It has the disadvantage of having
  4679. a fixed overhead of extra space per block. The heap overhead is about 16
  4680. bytes per block. Users should keep this in mind when allocating lots of
  4681. objects of small size. Try to combine such needs into larger heap blocks to
  4682. cut down on the overhead.  %@NL@%
  4683.  
  4684. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4685. %@AU@%WARNING %@AE@%
  4686.  
  4687. You are strongly warned against making assumptions about the placement and
  4688. size of the heap boundary tag structures. Future versions of enhanced
  4689. Windows may change this behavior of the heap.
  4690. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4691.  
  4692. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4693. NOTE
  4694.  
  4695. %@AI@%4 byte (DWORD) alignment is maintained on heap blocks. This could be
  4696. %@AI@%increased in a later version, but at least DWORD alignment is guaranteed. %@AE@%
  4697. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4698.  
  4699. %@CR:C6A00190049 @%%@CR:C6A00190050 @%
  4700. %@2@%%@CR:C6A00190051 @%%@AB@%HeapAllocate%@AE@%%@EH@%%@NL@%
  4701. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4702.  
  4703. %@AS@%  unsigned HeapAllocate(nbytes,flags) 
  4704. %@AS@%     unsigned nbytes;
  4705. %@AS@%     unsigned flags;%@AE@%
  4706.  
  4707. This is the call to allocate a block from the heap. %@AI@%nbytes%@AE@% is a 32 bit
  4708. unsigned integer which is the size, in bytes, of the block. Current flags
  4709. bits:  %@NL@%
  4710.  
  4711. %@AS@%  HeapZeroInit EQU  00000000000000000000000000000001B%@AE@%
  4712.  
  4713. All unused bits %@AI@%must be zero%@AE@%. HeapZeroInit, if set, indicates that if the
  4714. allocation is succesful, the memory is to be initialized with value 0 in all
  4715. bytes of the block. If HeapZeroInit is clear, the block will have completely
  4716. random values in it.  %@NL@%
  4717.  
  4718.  
  4719. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4720.  
  4721. The return value is the 32 bit RING 0 address (offset relative to standard
  4722. enhanced Windows RING 0 DS) of the block. Value is 0 if the allocation
  4723. failed (insufficient memory).  %@NL@%
  4724.  
  4725.  
  4726. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4727.  
  4728. Blocks are DWORD aligned as noted, but sizes do not have to be a multiple of
  4729. 4.  %@NL@%
  4730.  
  4731. There is no "protection" of the heap. Care must be taken not to overrun the
  4732. size of your block. Failure to do this will result in odd behavior and
  4733. crashes.  %@NL@%
  4734.  
  4735. There is no "motion" of blocks in the heap (heap blocks are all fixed),
  4736. except via %@AB@% HeapReAllocate%@AE@%, and therefore no compaction. You are advised not
  4737. to use the heap in such a way as to severely fragment it. You will end up
  4738. wasting lots of memory by doing this.  %@NL@%
  4739.  
  4740. The Flag bit equates are defined by including VMM.INC, please use the
  4741. equates.  %@NL@%
  4742.  
  4743. Allocation of 0 length heap blocks is not allowed.  %@NL@%
  4744.  
  4745. %@CR:C6A00190052 @%%@CR:C6A00190053 @%
  4746. %@2@%%@CR:C6A00190054 @%%@AB@%HeapFree%@AE@%%@EH@%%@NL@%
  4747. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4748.  
  4749. %@AS@%  unsigned HeapFree(hAddress,flags) 
  4750. %@AS@%     unsigned hAddress;
  4751. %@AS@%     unsigned flags;%@AE@%
  4752.  
  4753. This call is used to free an existing block of heap. %@AI@%hAddress%@AE@% is the value
  4754. returned from a previous call to %@AB@%HeapAllocate%@AE@% or %@AB@%HeapReAllocate%@AE@% and
  4755. indicates the block to be freed. There are currently no bits defined in the
  4756. %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4757.  
  4758.  
  4759. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4760.  
  4761. Returns nonzero value if the block was succesfully freed, zero if the free
  4762. was unsuccesful (invalid %@AI@%hAddress%@AE@%).  %@NL@%
  4763.  
  4764. %@CR:C6A00190055 @%%@CR:C6A00190056 @%
  4765. %@2@%%@CR:C6A00190057 @%%@AB@%HeapGetSize%@AE@%%@EH@%%@NL@%
  4766. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4767.  
  4768. %@AS@%  unsigned HeapGetSize(hAddress,flags)
  4769. %@AS@%     unsigned hAddress;
  4770. %@AS@%     unsigned flags;%@AE@%
  4771.  
  4772. This call is used to get the size of an existing block of heap.%@AI@% hAddress%@AE@% is
  4773. the value returned from a previous call to %@AB@%HeapAllocate%@AE@% or %@AB@%HeapReAllocate%@AE@%
  4774. and indicates the block to get the size of. There are currently no bits
  4775. defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4776.  
  4777.  
  4778. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4779.  
  4780. Returns the size, in bytes, of the block. Returns zero if there was an error
  4781. (invalid %@AI@%hAddress%@AE@%).  %@NL@%
  4782.  
  4783. %@CR:C6A00190058 @%%@CR:C6A00190059 @%
  4784. %@2@%%@CR:C6A00190060 @%%@AB@%HeapReAllocate%@AE@%%@EH@%%@NL@%
  4785. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4786.  
  4787. %@AS@%  unsigned HeapReAllocate(hAddress,nbytes,flags)
  4788. %@AS@%     unsigned hAddress;
  4789. %@AS@%     unsigned nbytes;
  4790. %@AS@%     unsigned flags;%@AE@%
  4791.  
  4792. This call is used to grow or shrink or reinitialize an existing block of
  4793. heap. %@AI@%hAddress%@AE@% is the value returned from a previous %@AB@%HeapAllocate%@AE@% or
  4794. %@AB@%HeapReAllocate%@AE@% call and indicates the block to be reallocated. %@AI@%nbytes%@AE@% is a
  4795. 32 bit unsigned integer which is the new size in bytes of the block. Current
  4796. flags bits:  %@NL@%
  4797.  
  4798. %@AS@%  HeapZeroInit  EQU 00000000000000000000000000000001B HeapZeroReInit  EQU
  4799. %@AS@%00000000000000000000000000000010B HeapNoCopy  EQU
  4800. %@AS@%00000000000000000000000000000100B%@AE@%
  4801.  
  4802. All unused bits %@AI@%must be zero.%@AE@% %@AB@%HeapZeroInit%@AE@%, if set, indicates that if the
  4803. reallocation is succesful, and the reallocation is growing the size of the
  4804. block, the "grow area" of the block is to be initialized with value 0 in all
  4805. bytes. This bit is ignored on a reallocation which is not growing the size
  4806. of the block. %@AB@%HeapZeroReInit%@AE@%, if set, indicates that the ENTIRE block is to
  4807. be reinitialized with value zero in all bytes of the block. HeapNoCopy, if
  4808. set, indicates that the previous contents of the block are irrelevant, and
  4809. don't need to be copied into the newly sized block. There is no reason that
  4810. more than one of these bits should be set. If none of the bits are set, the
  4811. previous contents of the block are copied into the new block, up to the
  4812. lesser of the size of the new block, and the size of the old block, and the
  4813. "grow area", if any, is not initialized with anything.  %@NL@%
  4814.  
  4815.  
  4816. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4817.  
  4818. The return value is the 32 bit RING 0 address (offset relative to standard
  4819. enhanced Windows RING 0 DS) of the new block. Value is 0 if the reallocation
  4820. failed (insufficient memory, or invalid %@AI@%hAddress%@AE@%).  %@NL@%
  4821.  
  4822.  
  4823. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4824.  
  4825. Do not make assumptions about the relationship between the passed in
  4826. %@AI@%hAddress%@AE@% and the %@AI@%hAddress%@AE@% returned. Assume that the returned%@AI@% hAddress%@AE@% is
  4827. always different than the passed in %@AI@%hAddress%@AE@%.  %@NL@%
  4828.  
  4829. In the case where this call fails, the passed in %@AI@%hAddress%@AE@% block remains
  4830. valid. In the case where this call works and returns a new %@AI@%hAddress%@AE@%, the
  4831. passed in %@AI@%hAddress%@AE@% is no longer valid (old block has been HeapFreed).  %@NL@%
  4832.  
  4833. There is no "protection" of the heap. Care must be taken not to overrun the
  4834. size of your block. Failure to do this will result in odd behavior and
  4835. crashes.  %@NL@%
  4836.  
  4837. There is no "motion" of blocks in the heap (heap blocks are all fixed), and
  4838. therefore no compaction. You are advised not to use the heap in such a way
  4839. as to severely fragment it. You will end up wasting lots of memory by doing
  4840. this.  %@NL@%
  4841.  
  4842. Note that this call can be used to reset the contents of an existing heap
  4843. block to 0 by setting nbytes to the current size of the block and setting
  4844. %@AB@%HeapZeroReInit%@AE@%.  %@NL@%
  4845.  
  4846. You cannot %@AB@%HeapReAllocate%@AE@% a block to size 0, use %@AB@%HeapFree%@AE@%.  %@NL@%
  4847.  
  4848. The Flag bit equates are defined by including VMM.INC, please use the
  4849. equates.  %@NL@%
  4850.  
  4851.  
  4852. %@2@%%@CR:C6A00190061 @%%@AB@%19.5  System Page Allocator%@AE@%%@EH@%%@NL@%
  4853. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4854.  
  4855. The page allocator is the set of services by which system memory is
  4856. allocated and mapped into a VM's linear address space. VxD's can also
  4857. examine and modify the status of mapped pages and lock or unlock pages into
  4858. physical memory. VxD's can also allocate pages for the VxD's exclusive use.
  4859. For example, the current state of the video memory can be saved for
  4860. clipboard operations.  %@NL@%
  4861.  
  4862. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4863. NOTE
  4864.  
  4865. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  4866. %@AI@%procedure has an underscore in front (i.e., %@AB@%PageAllocate%@AE@%%@AI@% is actually
  4867. %@AI@%%@AE@%%@AI@%%@AB@%_PageAllocate%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to left (unlike the PL/M
  4868. %@AI@%calling convention used by Windows, which is left to right). The return
  4869. %@AI@%value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the responsibility of the
  4870. %@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
  4871. %@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
  4872. %@AI@%@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved.%@AE@%%@AE@%
  4873. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4874.  
  4875. %@CR:C6A00190062 @%%@CR:C6A00190063 @%
  4876. %@2@%%@CR:C6A00190064 @%%@AB@%CopyPageTable%@AE@%%@EH@%%@NL@%
  4877. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4878.  
  4879. %@AS@%  unsigned CopyPageTable(LinPgNum,nPages,PageBufPTR,flags)
  4880. %@AS@%     unsigned LinPgNum;
  4881. %@AS@%     unsigned nPages;
  4882. %@AS@%     unsigned *PageBufPTR;
  4883. %@AS@%     unsigned flags;%@AE@%
  4884.  
  4885. This call is used to obtain a copy of an enhanced Windows page table. This
  4886. call is intended as an assist to enhanced Windows system components that
  4887. need to analyze the linear to physical mapping (such as DMA devices).
  4888. %@AI@%LinPgNum%@AE@% is the page number of the first page of the range. This can be
  4889. anything in the range 0 - 0FFFFFh. Thus addresses in the range 0-3FFh refer
  4890. to addresses in the 1M V86 address space of the current VM. To compute the
  4891. page number of any region simply take the address relative to the standard
  4892. enhanced Windows RING 0 DS and shift it right by 12 bits. For example, the
  4893. linear address 60001AB6h is in page number 60001h. Alignment considerations
  4894. of this address (beyond 4K alignment) are the responsibility of the caller.
  4895. %@AI@%nPages%@AE@% is the number of page table entries to copy. %@AI@%PageBufPTR%@AE@% is a 32 bit
  4896. RING 0 offset relative to the standard RING 0 DS which is the address of a
  4897. buffer where the page table will be copied. Caller must insure that this
  4898. buffer is large enough. Each page table entry is a DWORD, so the buffer must
  4899. be at least nPages*4 bytes long. There are currently no bits defined in the
  4900. %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4901.  
  4902.  
  4903. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4904.  
  4905. Returns a nonzero value if the copy is succesful, returns 0 value if the
  4906. copy was succesful, %@AI@%but%@AE@% at least a part of the range overlapped a region
  4907. where the corresponding page directory entry is not present.  %@NL@%
  4908.  
  4909.  
  4910. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4911.  
  4912. You get a copy of the page table; writing to your buffer has no effect.  %@NL@%
  4913.  
  4914. Note that V86 page tables stop at page 10Fh.  %@NL@%
  4915.  
  4916. To look at the page table of a VM that is not the current VM simply use the
  4917. high linear address of the VM. For instance, to look at the page table
  4918. starting at V86 address 0A000:0 of a VM which is not the current VM:  %@NL@%
  4919.  
  4920. %@AS@%  mov eax,0A0000h   ; V86 linear adress of 0A000:0 
  4921. %@AS@%  add eax,[ebx.CB_High_Linear] ; High linear address
  4922. %@AS@%  shr eax,12   ; Convert to page number%@AE@%
  4923.  
  4924. Note that the above sequence always works correctly (works if the VM is the
  4925. current VM as well). So simply doing this in all cases avoids the
  4926. complication of worrying about whether the VM is the current VM.  %@NL@%
  4927.  
  4928. The intent of this call is for you to look at the physical addresses in the
  4929. high 20 bits of the entries. The low 12 bits of system information may be
  4930. examined however.  %@NL@%
  4931.  
  4932. You are warned to be careful about keeping this buffer for any length of
  4933. time. The actual page table entries can change while the copy you have
  4934. won't. The information in the copy should be analyzed quickly.  %@NL@%
  4935.  
  4936. %@CR:C6A00190065 @%%@CR:C6A00190066 @%
  4937. %@2@%%@CR:C6A00190067 @%%@AB@%GetDemandPageInfo%@AE@%%@EH@%%@NL@%
  4938. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4939.  
  4940. %@AS@%  void GetDemandPageInfo(BufPtr,flags)
  4941. %@AS@%     DemandInfoStruc *BufPtr;
  4942. %@AS@%     unsigned flags;%@AE@%
  4943.  
  4944. This call is for use by the demand paging device. It provides information
  4945. for the demand pager.  %@NL@%
  4946.  
  4947. %@AS@%  DemandInfoStruc struc
  4948. %@AS@%    DILin_Total_Count  dd ?   ; Size of linear address space in pages
  4949. %@AS@%    DIPhys_Count   dd ?   ; Count of phys pages
  4950. %@AS@%    DIFree_Count   dd ?   ; Count of free phys pages
  4951. %@AS@%    DIUnlock_Count   dd ?   ; Count of unlocked phys Pages
  4952. %@AS@%    DILinear_Base_Addr  dd ?   ; Base of pageable address space
  4953. %@AS@%    DILin_Total_Free  dd ?   ; Total free linear pages
  4954. %@AS@%    DIReserved   dd 12 DUP(?) ; Reserved 
  4955. %@AS@%  DemandInfoStruc ends%@AE@%
  4956.  
  4957. DILin_Total_Count is the size in pages of the linear address space subject
  4958. to demand paging. DILinear_Base_Addr is the linear address of the start of
  4959. the demand pageable region. Thus there are DILin_Total_Count pages starting
  4960. at address DILinear_Base_Addr which are subject to demand paging.
  4961. DILin_Total_Free is the number of the DILin_Total_Count pages which are
  4962. currently free. Notice that this space may not be allocatable in a single
  4963. block, it is the total free, not the size of the largest free block. Note
  4964. that if DILinear_Base_Addr == 0, this means that the demand pageable region
  4965. of the system is not contiguous. DIPhys_Count is the total number of
  4966. physical pages under the control of the memory manager. DIFree_Count is the
  4967. number of pages currently on the free list. DIUnlock_Count is the count of
  4968. pages which are currently unlocked, notice that free pages are unlocked.
  4969. There are currently no bits defined in the flags, this parameter must be set
  4970. to 0.  %@NL@%
  4971.  
  4972.  
  4973. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4974.  
  4975. This call does not have a return value. It simply fills in the structure
  4976. pointed to by %@AI@%BufPtr%@AE@%.  %@NL@%
  4977.  
  4978.  
  4979. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  4980.  
  4981. The reserved field is exactly that, reserved. Do not make any assumptions
  4982. about what is in this region. Behavior will change in later releases.  %@NL@%
  4983.  
  4984. %@CR:C6A00190068 @%%@CR:C6A00190069 @%
  4985. %@2@%%@CR:C6A00190070 @%%@AB@%GetFreePageCount%@AE@%%@EH@%%@NL@%
  4986. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4987.  
  4988. %@AS@%  unsigned long (flags)
  4989. %@AS@%     unsigned flags;%@AE@%
  4990.  
  4991. This call is used to obtain the count of free 4K pages. And the count of
  4992. pages that can be allocated as PageLocked. There are currently no bits
  4993. defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  4994.  
  4995.  
  4996. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  4997.  
  4998. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  4999. Low DWORD (%@AB@%EAX%@AE@%) is the 32 bit count of free 4K pages in the system which
  5000. could be allocated with the %@AB@%PageAllocate%@AE@% call. The High DWORD (%@AB@%EDX%@AE@%) is the
  5001. 32 bit count of pages available for allocation as PageLocked pages at the
  5002. current time.  %@NL@%
  5003.  
  5004.  
  5005. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5006.  
  5007. You should be careful about making assumptions about being able to turn
  5008. around and issue a call to allocate all of the pages returned by this call.
  5009. Besides any alignment considerations, it is possible someone could get in
  5010. and allocate some or all of the pages before you. This call is intended to
  5011. be advisory in nature.  %@NL@%
  5012.  
  5013. Note that, in a demand paged virtual memory system such as enhanced Windows,
  5014. the free pages count is usually very close to 0. It is more relevant to use
  5015. the %@AB@%EDX%@AE@% return to make judgements about allocation possibility. %@AB@%EDX%@AE@% contains
  5016. the count of pages currently available for allocation as %@AB@%PageLocked%@AE@% pages.
  5017. Note that many assumptions are not valid. %@AB@%EAX%@AE@%<=%@AB@%EDX%@AE@% is %@AI@%not%@AE@% a valid assumption
  5018. for instance.  %@NL@%
  5019.  
  5020. Note that in a virtual memory environment it is not a good idea to go
  5021. soaking up tons of virtual address space. Start with some, then
  5022. %@AB@%PageReAllocate%@AE@% it to make it bigger if needed.  %@NL@%
  5023.  
  5024. %@CR:C6A00190071 @%%@CR:C6A00190072 @%
  5025. %@2@%%@CR:C6A00190073 @%%@AB@%GetSetPageOutCount%@AE@%%@EH@%%@NL@%
  5026. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5027.  
  5028. %@AS@%  unsigned GetSetPageOutCount(NewCount,flags)
  5029. %@AS@%     unsigned NewCount;
  5030. %@AS@%     unsigned flags;%@AE@%
  5031.  
  5032. This call is for use by the demand paging device. It allows the paging
  5033. device to manipulate a memory manager parameter associated with demand
  5034. paging. This parameter is the "page out ahead" count. Whenever a page is
  5035. paged out to satisfy a page in, an additional PageOutCount-1 pages are also
  5036. paged out and put on the free list (if possible).There is one bit in the
  5037. flags:  %@NL@%
  5038.  
  5039. %@AS@%  GSPOC_F_Get  equ   00000000000000000000000000000001B%@AE@%
  5040.  
  5041. All other bits must be zero. If GSPOC_F_Get is set, the call returns the
  5042. current value of the page out count in %@AB@%EAX%@AE@%, and the %@AI@%NewCount%@AE@% parameter is
  5043. ignored. If GSPOC_F_Get is not set, the call sets the value of the page out
  5044. count to %@AI@%NewCount%@AE@%.  %@NL@%
  5045.  
  5046.  
  5047. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5048.  
  5049. Returns the page out count if GSPOC_F_Get is set, else it has no return.  %@NL@%
  5050.  
  5051. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5052. %@AU@%WARNING%@AE@%
  5053.  
  5054. This call is intended for use by the PageSwap device, others should not be
  5055. calling it. Others making this call can disturb the operation of the
  5056. PageSwap device.
  5057. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5058.  
  5059.  
  5060. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5061.  
  5062. There is an equate for the flag bit in VMM.INC, use the equate.  %@NL@%
  5063.  
  5064. %@CR:C6A00190074 @%%@CR:C6A00190075 @%
  5065. %@2@%%@CR:C6A00190076 @%%@AB@%GetSysPageCount%@AE@%%@EH@%%@NL@%
  5066. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5067.  
  5068. %@AS@%  unsigned GetSysPageCount(flags)
  5069. %@AS@%     unsigned flags;%@AE@%
  5070.  
  5071. This call is used to obtain the current count of system (PG_SYS) 4K pages.
  5072. There are currently no bits defined in the %@AI@%flags%@AE@%, and this parameter must be
  5073. set to 0.  %@NL@%
  5074.  
  5075.  
  5076. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5077.  
  5078. The return value is the 32 bit count of 4K pages allocated as PG_SYS pages
  5079. in the system.  %@NL@%
  5080.  
  5081.  
  5082. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5083.  
  5084.  It is generally true that this number is the size of enhanced Windows.
  5085. However, this is the general case only.  %@NL@%
  5086.  
  5087. %@CR:C6A00190077 @%%@CR:C6A00190078 @%
  5088. %@2@%%@CR:C6A00190079 @%%@AB@%GetVMPgCount%@AE@%%@EH@%%@NL@%
  5089. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5090.  
  5091. %@AS@%  unsigned long GetVMPgCount(VMHandle,flags)
  5092. %@AS@%     unsigned VMHandle;
  5093. %@AS@%     unsigned flags;%@AE@%
  5094.  
  5095. This call is used to get the current count of 4K pages allocated to a
  5096. particular VM. The %@AI@%VMHandle%@AE@% parameter must be a valid VM handle and
  5097. indicates the VM to get the allocated page count of. There are currently no
  5098. bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5099.  
  5100.  
  5101. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5102.  
  5103. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5104. Low DWORD (%@AB@%EAX%@AE@%) is the total count of pages (of all types but PG_SYS) in the
  5105. system allocated for this VM. The High DWORD (%@AB@%EDX%@AE@%) is the count of pages
  5106. which are allocated to this VM, but which are not mapped into the VM's 1Meg
  5107. address space at the current time. Value (both dwords) is 0 if the call
  5108. failed (invalid %@AI@%VMHandle%@AE@%).  %@NL@%
  5109.  
  5110.  
  5111. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5112.  
  5113. You should be careful about assuming that %@AB@%EAX-EDX%@AE@% is the size of the VM. It
  5114. is in one sense, but not in the standard MS-DOS senses.  %@NL@%
  5115.  
  5116. %@CR:C6A00190080 @%%@CR:C6A00190081 @%
  5117. %@2@%%@CR:C6A00190082 @%%@AB@%MapIntoV86%@AE@%%@EH@%%@NL@%
  5118. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5119.  
  5120. %@AS@%  unsigned MapIntoV86(hMem,VMHandle,VMLinPgNum,nPages,PageOff,flags)
  5121. %@AS@%     unsigned hMem;
  5122. %@AS@%     unsigned VMHandle;
  5123. %@AS@%     unsigned VMLinPgNum;
  5124. %@AS@%     unsigned nPages;
  5125. %@AS@%     unsigned PageOff;
  5126. %@AS@%     unsigned flags;%@AE@%
  5127.  
  5128. This call is used to map some or all of the pages of a memory block into a
  5129. specific VM's Virtual 8086 address space.%@AI@% hMem%@AE@% is the value returned from a
  5130. previous call to %@AB@%PageAllocate%@AE@% or %@AB@%PageReAllocate%@AE@% and indicates the block to
  5131. be mapped. %@AI@%VMHandle%@AE@% parameter must be a valid VM handle and indicates the VM
  5132. into which the map is to occur. %@AI@%VMLinPgNum%@AE@% is the address in the 1M V86
  5133. address space where the map will start (this is a page number, thus linear
  5134. address 60000h = page 60h). Alignment considerations of this address (beyond
  5135. 4K alignment) are the responsibility of the caller. Map addresses below page
  5136. 10h, or above 10Fh will cause an error. %@AI@%nPages%@AE@% is the number of pages to
  5137. map. %@AI@%PageOff %@AE@%is the number of pages into the %@AI@%hMem%@AE@% block to the first page of
  5138. the block which is to be mapped at %@AI@%VMLinPgNum%@AE@% (thus PageOff is 0 to map the
  5139. first page of %@AI@%hMem%@AE@% at VMLinPgNum). %@AI@%nPages%@AE@% and %@AI@%PageOff%@AE@% allow one %@AI@%hMem%@AE@% block
  5140. to be scatter mapped into different VM locations. An error will occur if
  5141. %@AI@%PageOff%@AE@% +%@AI@% nPages%@AE@% is greater than the size of %@AI@%hMem%@AE@%.  %@NL@%
  5142.  
  5143. Current flags bits:  %@NL@%
  5144.  
  5145. %@AS@%  PageDEBUGNulFault  EQU 00000000000000000000000000010000B%@AE@%
  5146.  
  5147. All unused bits must be zero. PageDEBUGNulFault, if set, indicates that if
  5148. %@AI@%hMem%@AE@% is the handle of the NUL system page, and this is the DEBUG version of
  5149. enhanced Windows, access to these pages should cause a page fault DEBUG
  5150. exception. This bit is ignored if %@AI@%hMem%@AE@% is not the system NUL page handle, or
  5151. this is not enhanced Windows DEBUG.  %@NL@%
  5152.  
  5153. It is generally true that %@AI@%hMem%@AE@% blocks mapped with this call should not be
  5154. composed of PG_SYS pages. This is not disallowed, but is not advised.  %@NL@%
  5155.  
  5156. There is a special %@AI@%hMem%@AE@% handle that can be used with this call. The value of
  5157. this handle is obtained by calling the routine %@AB@%GetNulPageHandle%@AE@% (actual name
  5158. %@AB@%_GetNulPageHandle%@AE@%) which will return you this special %@AI@%hMem%@AE@% handle in %@AB@%EAX%@AE@%.
  5159. This is the %@AI@%hMem %@AE@%of the system NUL page. This page is used to occupy regions
  5160. of the address space which are "unused" but for which it is not desirable to
  5161. cause a page fault if they are accessed. The NUL page is multiply mapped at
  5162. many locations in the system, so its contents are always random. Under
  5163. enhanced Windows DEBUG, a fault occurs if the NUL page is touched and the
  5164. PageDEBUGNulFault bit was set on the call which mapped the page.  %@NL@%
  5165.  
  5166. If the %@AB@%PageSwap%@AE@% device is type one (%@AI@%not%@AE@% direct to hardware), there is an
  5167. %@AI@%implied%@AE@% PageLock on the pages mapped with this call, and an %@AI@%implied%@AE@%
  5168. %@AB@%PageUnlock%@AE@% on the pages which this call is mapping over. This is consistent
  5169. with the fact that pages mapped into V86 address space must be locked (V86
  5170. memory cannot be demand paged). If the %@AB@%PageSwap%@AE@% device is type two (direct
  5171. to hardware) than the implied lock and unlock done by this call are disabled
  5172. because in the case of a type two %@AB@%PageSwap%@AE@% device V86 memory CAN be demand
  5173. paged. See the %@AB@%PageAllocate%@AE@% documentation for a description of the different
  5174. %@AB@%PageSwap%@AE@% device types and their relevance.  %@NL@%
  5175.  
  5176.  
  5177. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5178.  
  5179. Returns a nonzero value if the map is succesful, returns 0 value if the map
  5180. was unsuccesful (invalid %@AI@%hMem,%@AE@% invalid %@AI@%VMHandle%@AE@%, map range illegal, size
  5181. discrepancy, insufficient memory on implied PageLock).  %@NL@%
  5182.  
  5183.  
  5184. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5185.  
  5186. The implied %@AB@%PageLock%@AE@%, which is performed on all of the pages mapped if the
  5187. %@AB@%PageSwap%@AE@% device is type oneAg, is consistent with the fact that V86 memory
  5188. cannot be Demand Paged while the VM is in a runable state. Whenever the V86
  5189. memory mapping is changed via %@AB@%MapIntoV86%@AE@%, the previous memory that was
  5190. mapped in that region of the VM is unlocked. The correct way to think of
  5191. this is that there is an implied %@AB@%PageLock%@AE@% whenever memory is mapped into a
  5192. V86 context, and an implied %@AB@%PageUnlock%@AE@% whenever it is "unmapped" from the
  5193. V86 context. This "unmapping" can occur when: A different handle (including
  5194. the NulPageHandle) is %@AB@%MapIntoV86ed %@AE@%or %@AB@%LinMapIntoV86ed%@AE@% to the region, or a
  5195. %@AB@%PhysIntoV86%@AE@% is performed to the region.  %@NL@%
  5196.  
  5197. There is nothing to prevent you from mapping the same block, or piece of a
  5198. block, into multiple places in a VM, or into multiple VMs. Such operations
  5199. are not particularly advisable though. For one thing, the reporting of
  5200. memory owned by a VM will be disturbed. For this reason it is also not
  5201. generally a good idea to map pages that were allocated as belonging to one
  5202. VM into a different VM. The one exception to this general rule is the
  5203. request for a map by one VM to look at the memory of a different VM. Such
  5204. maps should be of a relatively short duration.  %@NL@%
  5205.  
  5206. The page attributes for these pages will be P_USER+P_PRES+P_WRITE. P_DIRTY
  5207. and P_ACC will be cleared by the call. PG_TYPE will be set to whatever the
  5208. type of the hMem pages are.  %@NL@%
  5209.  
  5210. The Flag bit equates are defined by including VMM.INC, please use the
  5211. equates.  %@NL@%
  5212.  
  5213. The intent of %@AB@%MapIntoV86 %@AE@%support for pages between page 10h and FirstV86Page
  5214. is to support WIN386 devices which have %@AB@%Allocate_Global_V86_Data_Area%@AE@% a
  5215. %@AB@%GVDAPageAlign%@AE@% region. Use of mapping in this region to other addresses can
  5216. easily crash the system and should be avoided.  %@NL@%
  5217.  
  5218. Regions which span across %@AB@%FirstV86Page%@AE@% are not allowed.  %@NL@%
  5219.  
  5220. The reason for the page 10h limitation is that on most versions of the Intel
  5221. 80386 CPU there is an errata which prevents you from setting up a Linear !=
  5222. Physical address mapping in the first 64K of the address space.  %@NL@%
  5223.  
  5224. %@CR:C6A00190083 @%%@CR:C6A00190084 @%
  5225. %@2@%%@CR:C6A00190085 @%%@AB@%ModifyPageBits%@AE@%%@EH@%%@NL@%
  5226. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5227.  
  5228. %@AS@%  unsigned
  5229. %@AS@%ModifyPageBits(VMHandle,VMLinPgNum,nPages,bitAND,bitOR,pType,flags)
  5230. %@AS@%     unsigned VMHandle;
  5231. %@AS@%     unsigned VMLinPgNum;
  5232. %@AS@%     unsigned nPages;
  5233. %@AS@%     unsigned bitAND;
  5234. %@AS@%     unsigned bitOR;
  5235. %@AS@%     unsigned pType;
  5236. %@AS@%     unsigned flags;%@AE@%
  5237.  
  5238. This call is used to modify the page protection bits associated with
  5239. PG_HOOKED pages in the V86 address space of a VM. It allows the P_PRES,
  5240. P_WRITE, and P_USER bits of the pages to be modified along with PG_TYPE if
  5241. appropriate. The %@AI@%VMHandle %@AE@%parameter must be a valid VM Handle and indicates
  5242. the VM whose page bits are to be modified. %@AI@%VMLinPgNum%@AE@% is the page number in
  5243. the 1M V86 VM address space where the modification will start (this is a
  5244. page number, thus linear address A0000h = page A0h). When clearing the
  5245. P_PRES bit (making pages not present), all of the pages specified (%@AI@%nPages%@AE@%
  5246. starting at %@AI@%VMLinPgNum%@AE@%) must be PG_HOOKED pages for which a HOOK Page Fault
  5247. handler has been registered, and %@AI@%pType%@AE@% must be PG_HOOKED. %@AI@%nPages%@AE@% is the
  5248. number of pages to modify the bits of. Addresses below the start of VM
  5249. specific memory, or above 10Fh will cause an error. %@AI@%bitAND%@AE@% is an AND mask
  5250. for the bits, %@AI@%bitOR%@AE@% is an OR mask. Thus to clear P_PRES, P_WRITE, and
  5251. P_USER, %@AI@%bitAND%@AE@% would be (%@AI@%not%@AE@% P_PRES+P_WRITE+P_USER), and %@AI@%bitOR%@AE@% would be
  5252. zero. To set P_USER, and clear P_WRITE, leaving P_PRES unchanged, bitAND
  5253. would be (NOT P_WRITE), and %@AI@%bitOR%@AE@% would be P_USER. Having bits other than
  5254. P_WRITE, and P_USER set in %@AI@%bitOR%@AE@% will cause an error. Having bits other than
  5255. P_PRES, P_WRITE, and P_USER clear in %@AI@%bitAND%@AE@% will cause an error.  %@NL@%
  5256.  
  5257. This call always has the side effect of clearing P_DIRTY and P_ACC. Thus to
  5258. just clear these two bits, give a %@AI@%bitAND%@AE@% of 0FFFFFFFFh, and a %@AI@%bitOR%@AE@% of 0.%@AI@%
  5259. %@AI@%pType%@AE@% indicates a value to be placed in the PG_TYPE field. The allowed
  5260. values are:  %@NL@%
  5261.  
  5262. %@AS@%  PG_HOOKED   EQU 7
  5263. %@AS@%  PG_IGNORE   EQU -1 (0FFFFFFFFh)%@AE@%
  5264.  
  5265. Any other value will cause an error. PG_IGNORE indicates that the PG_TYPE
  5266. field is not to be modified by the call. This is the value that %@AI@%must%@AE@% be set
  5267. if P_PRES bit is being set (or being left set). PG_HOOKED must be specified
  5268. if the P_PRES bit is being cleared by the call. Recall that making a
  5269. PhysIntoVM call sets the type field for the physical pages to PG_SYS. This
  5270. parameter is provided so that the page types can be reset to PG_HOOKED when
  5271. the mapping is changed to not present. Recall that MapIntoVM also resets the
  5272. PG_TYPE field to the type of the pages of %@AI@%hMem.%@AE@% There are currently no bits
  5273. defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5274.  
  5275.  
  5276. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5277.  
  5278. Returns a nonzero value if successful, returns 0 value if unsuccessful
  5279. (invalid %@AI@%VMHandle,%@AE@% invalid bits in %@AI@%bitAND%@AE@% or %@AI@%bitOR,%@AE@% invalid %@AI@%pType,%@AE@% page
  5280. range bad).  %@NL@%
  5281.  
  5282.  
  5283. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5284.  
  5285. You cannot use this call to set the Present bit. You may either clear the
  5286. present bit, or leave it unaffected. Use %@AB@%MapIntoV86 %@AE@%or %@AB@%PhysIntoV86%@AE@% to make
  5287. pages present.  %@NL@%
  5288.  
  5289. %@CR:C6A00190086 @%%@CR:C6A00190087 @%
  5290. %@2@%%@CR:C6A00190088 @%%@AB@%PageAllocate%@AE@%%@EH@%%@NL@%
  5291. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5292.  
  5293. %@AS@%  unsigned PageAllocate(nPages,pType,VMHandle,AlignMask,minPhys,
  5294. %@AS@%maxPhys,PhysAddrPTR,flags)
  5295. %@AS@%    unsigned nPages;
  5296. %@AS@%    unsigned pType;
  5297. %@AS@%    unsigned VMHandle;
  5298. %@AS@%    unsigned AlignMask;
  5299. %@AS@%    unsigned minPhys;
  5300. %@AS@%    unsigned maxPhys;
  5301. %@AS@%    unsigned *PhysAddrPTR;
  5302. %@AS@%    unsigned flags;%@AE@%
  5303.  
  5304. This is the call to allocate a block of memory. The memory allocated is
  5305. actually just linear address space, whether there is actually physical
  5306. memory mapped for this block as part of the allocation is specified by the
  5307. flags.%@AI@% nPages%@AE@% is a 32 bit unsigned integer which is the size in 4K pages of
  5308. the block. %@AI@%pType%@AE@% indicates the type of page(s) being allocated:  %@NL@%
  5309.  
  5310. %@AS@%  PG_VM  EQU  0 
  5311. %@AS@%  PG_SYS  EQU  1 
  5312. %@AS@%  PG_HOOKED EQU  7 %@AE@%
  5313.  
  5314. PG_VM pages are pages which are specific to a particular VM context. The
  5315. handle of PG_VM memory blocks will typically be placed in the VM Control
  5316. Block someplace. PG_HOOKED pages are pages which will be mapped into the VM
  5317. at locations where the component has registered a HookPageFault handler.
  5318. Like PG_VM pages, PG_HOOKED pages are specific to a particular VM context.
  5319. The %@AI@%VMHandle%@AE@% parameter must be a valid VM Handle for all page types except
  5320. PG_SYS. PG_SYS pages are global system pages which are valid in all VM
  5321. contexts (pages are specific to the enhanced Windows system component which
  5322. allocates them, rather than to a VM). The %@AI@%VMHandle%@AE@% parameter is not relevant
  5323. to PG_SYS pages and it %@AI@%must%@AE@% be set to 0 when allocating PG_SYS pages.  %@NL@%
  5324.  
  5325. Current flags bits:  %@NL@%
  5326.  
  5327. %@AS@%  PageZeroInit  EQU 00000000000000000000000000000001B 
  5328. %@AS@%  PageUseAlign  EQU 00000000000000000000000000000010B
  5329. %@AS@%  PageContig  EQU 00000000000000000000000000000100B
  5330. %@AS@%  PageFixed  EQU 00000000000000000000000000001000B
  5331. %@AS@%  PageLocked  EQU 00000000000000000000000010000000B PageLockedIfDP  EQU
  5332. %@AS@%00000000000000000000000100000000B%@AE@%
  5333.  
  5334. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLocked%@AE@%, if set, indicates that a %@AB@%PageLock%@AE@%
  5335. is implied as part of the %@AB@%PageAllocate%@AE@% operation. This forces the allocate
  5336. to make all pages of the handle present when the handle is allocated
  5337. consistent with the implied %@AB@%PageLock%@AE@%. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that
  5338. a %@AB@%PageLock%@AE@% is implied as part of the %@AB@%PageAllocate%@AE@% %@AI@%only if the%@AE@% %@AB@%PageSwap
  5339. %@AS@%%@AE@%%@AI@%device is not direct to hardware%@AE@%. There are two basic behavior types for the
  5340. %@AB@%PageSwap%@AE@% device. Type one pages through MS-DOS and/or the ROM BIOS. This
  5341. type of %@AB@%PageSwap%@AE@% device places restrictions on the ability to demand page
  5342. certain types of system memory because of the fact that it runs partly in
  5343. V86 mode as part of its operation. %@AB@%PageSwap%@AE@% type two pages by talking
  5344. directly to the disk hardware. This second type of %@AB@%PageSwap%@AE@% device removes
  5345. some of the restrictions because it runs completely in protected mode when
  5346. accessing the paging device. %@AB@%PageLocked%@AE@% indicates that the memory should be
  5347. locked regardless of which type of %@AB@%PageSwap%@AE@% device is present.
  5348. %@AB@%PageLockedIfDP%@AE@% indicates that this memory only needs to be locked if the
  5349. %@AB@%PageSwap%@AE@% device is type one. PageFixed, if set, indicates behavior similar
  5350. to %@AB@%PageLocked%@AE@% as far as the implied %@AB@%PageLock%@AE@% is concerned, and in addition a
  5351. Fixed handle can %@AI@%never%@AE@% be unlocked, and its linear address will %@AI@%never %@AE@%change
  5352. (via %@AB@%PageReAllocate%@AE@%). Note that ReAllocation of a Fixed handle will
  5353. generally not succeed due to the Fixed restriction on the ability to change
  5354. the linear address of the handle. Note that an allocation without an implied
  5355. %@AB@%PageLock%@AE@% via %@AB@%PageLocked%@AE@%, %@AB@%PageLockedIfDP%@AE@%, or %@AB@%PageFixed%@AE@% will simply allocate
  5356. linear address space. The pages of such a handle will be made present "on
  5357. demand" when the address space is touched. If it is desired to make part of
  5358. the handle present to perform some function, use %@AB@%PageLock%@AE@% to force the
  5359. contents to be loaded. PageUseAlign, if set, indicates that the %@AI@%AlignMask%@AE@%,
  5360. %@AI@%minPhys%@AE@%, %@AI@%maxPhys%@AE@%, and %@AI@%PhysAddrPTR%@AE@% parameters are specified. If PageUseAlign
  5361. is clear, the %@AI@%AlignMask%@AE@%, %@AI@%minPhys%@AE@%, %@AI@%maxPhys%@AE@%, and %@AI@%PhysAddrPTR%@AE@% parameters are
  5362. set to 0 and ignored. Note that if PageUseAlign is set, PageFixed must also
  5363. be specified. It makes no sense to have an aligned memory handle which is
  5364. not fixed. PageZeroInit, if set, indicates that if the allocation is
  5365. succesful, the memory is to be initialized with value 0 in all bytes of the
  5366. block. If PageZeroInit is clear, the block will have completely random
  5367. values in it. PageContig, if set, indicates that the Physical memory pages
  5368. of the block are to occupy sequential Physical memory addresses (memory is
  5369. "physically contiguous"). %@AI@%PageContig is ignored if PageUseAlign is not set.%@AE@%
  5370. %@NL@%
  5371.  
  5372. PageUseAlign is provided to assist device drivers that wish to allocate
  5373. buffers for use by the device which have additional alignment restrictions
  5374. enforced by the hardware (such as 64K and 128K alignment for DMA). If the
  5375. PageUseAlign bit is set, AlignMask specifies an alignment (power of 2> 4k)
  5376. requirement for the first physical page of the block. Physical page numbers
  5377. are the physical address of the page shifted right by 12. Correct alignment
  5378. is tested for by ANDing %@AI@%AlignMask%@AE@% with the first physical page number and
  5379. testing for zero. If the AND is zero, the page has the correct alignment.
  5380. Thus:  %@NL@%
  5381.  
  5382. %@AS@%  00000000h    =       4K alignment (ignore AlignMask)
  5383. %@AS@%  00000001h    =       8K alignment
  5384. %@AS@%  00000003h    =      16K alignment
  5385. %@AS@%  00000007h    =      32K alignment
  5386. %@AS@%  0000000Fh    =      64K alignment
  5387. %@AS@%  0000001Fh    =     128K alignment%@AE@%
  5388.  
  5389. Remember that you will probably also want to set the PageContig bit. %@AI@%minPhys%@AE@%
  5390. and %@AI@%maxPhys%@AE@% place additional physical address restrictions on the physical
  5391. pages of the memory block. These specify the minimum and maximum allowed
  5392. physical page numbers. All physical page numbers of the block must be
  5393. >=minPhys, and <maxPhys. For instance, for setting up a DMA buffer for an
  5394. 80386 accelerator card in a PC XT, the buffer needs to be physically
  5395. restricted to pages less than 1 MB since the XT DMA controller cannot DMA
  5396. into pages above 1 MB. In this case, minPhys would be 0, and maxPhys would
  5397. be 100h.  If you don't want to specify this (i.e. you just want %@AI@%AlignMask%@AE@%),
  5398. set %@AI@%minPhys%@AE@% to 0, and maxPhys to 0FFFFFFFFh. Note that when PageUseAlign is
  5399. set, the physical page address (physical page number shifted left by 12) of
  5400. the start of the block will be returned via the %@AI@%PhysAddrPTR%@AE@% pointer
  5401. parameter.  %@NL@%
  5402.  
  5403. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5404. NOTE
  5405.  
  5406. %@AI@%PageUseAlign PageAllocations can only be performed during device
  5407. %@AI@%initialization. Aligned PageAllocations will fail if done after device
  5408. %@AI@%initialization.%@AE@%
  5409.  
  5410. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5411.  
  5412.  
  5413. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5414.  
  5415. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5416. Low DWORD (%@AB@%EAX%@AE@%) is the memory handle of the block. The High DWORD (%@AB@%EDX%@AE@%) is
  5417. the 32 bit RING 0 address (offset relative to standard enhanced Windows Ring
  5418. 0 DS) of the block. If %@AB@%PageUseAlign%@AE@% was specified, the physical address of
  5419. the start of the block is placed in the DWORD pointed to by %@AB@%PhysAddrPTR%@AE@%.
  5420. Value (both DWORDs) is 0 if the allocation failed (insufficient memory).  %@NL@%
  5421.  
  5422.  
  5423. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5424.  
  5425. You should be careful about making assumptions about any apparent
  5426. relationship between the memory handle and the blocks RING 0 or physical
  5427. address. Any such apparent relationship is subject to change in a later
  5428. release.  %@NL@%
  5429.  
  5430. PhysAddrPTR had better point somewhere reasonable when PageUseAlign is
  5431. specified. There is no way to check its validity, if it's garbage you'll
  5432. either cause a page fault or stomp on something you shouldn't.  %@NL@%
  5433.  
  5434. %@AB@%PageAllocation%@AE@% of 0 length blocks is not allowed.  %@NL@%
  5435.  
  5436. %@AB@%PageLocked%@AE@% and %@AB@%PageLockedIfDP%@AE@% should not both be set. Only one, or the
  5437. other, or neither are valid settings. %@AI@%Note also that%@AE@% %@AB@%PageLockedIfDP%@AE@% %@AI@%cannot
  5438. %@AI@%be set on calls made before the init complete system control call is made%@AE@%.
  5439. This is because it is not possible to ask the %@AB@%PageSwap%@AE@% device what type it
  5440. is before it has been initialized.  %@NL@%
  5441.  
  5442. The Flag bit equates are defined by including VMM.INC, please use the
  5443. equates.  %@NL@%
  5444.  
  5445. %@CR:C6A00190089 @%%@CR:C6A00190090 @%
  5446. %@2@%%@CR:C6A00190091 @%%@AB@%PageFree%@AE@%%@EH@%%@NL@%
  5447. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5448.  
  5449. %@AS@%  unsigned PageFree(hMem,flags)
  5450. %@AS@%     unsigned hMem;
  5451. %@AS@%     unsigned flags;%@AE@%
  5452.  
  5453. This call is used to free an existing block of pages. %@AI@%hMem%@AE@% is the value
  5454. returned from a previous call to %@AB@%PageAllocate%@AE@% or %@AB@%PageReAllocate%@AE@% and
  5455. indicates the block to be freed. There are currently no bits defined in the
  5456. flags, this parameter must be set to 0.  %@NL@%
  5457.  
  5458.  
  5459. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5460.  
  5461. Returns nonzero value if the block was succesfully freed, zero if the free
  5462. was unsuccesful (invalid %@AI@%hMem%@AE@%).  %@NL@%
  5463.  
  5464.  
  5465. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5466.  
  5467. It is the responsibility of the enhanced Windows system components which
  5468. allocate non-PG_SYS pages to free them when the VM they are associated with
  5469. is destroyed. There is no "automatic" freeing of such memory done by the
  5470. memory manager. PG_SYS pages do not need to be freed before enhanced Windows
  5471. exits.  %@NL@%
  5472.  
  5473. It is not an error to %@AB@%PageFree%@AE@% a handle which is all or partially locked.  %@NL@%
  5474.  
  5475. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5476. %@AU@%WARNING%@AE@%
  5477.  
  5478. Be very careful about PageFreeing blocks which are currently MapIntoV86ed to
  5479. some VM context. Doing this can result in a crash.
  5480. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5481.  
  5482. %@CR:C6A00190092 @%%@CR:C6A00190093 @%
  5483. %@2@%%@CR:C6A00190094 @%%@AB@%PageGetAllocInfo%@AE@%%@EH@%%@NL@%
  5484. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5485.  
  5486. %@AS@%  unsigned long PageGetAllocInfo(flags)
  5487. %@AS@%   unsigned flags;%@AE@%
  5488.  
  5489. This call is used to obtain information prior to a %@AB@%PageAllocate%@AE@% or
  5490. %@AB@%PageReallocate%@AE@% call. It returns the largest block of linear address space
  5491. that could be allocated, together with information relating to allocation of
  5492. Locked or Fixed memory. There are currently no bits defined in the flags,
  5493. this parameter must be set to 0.  %@NL@%
  5494.  
  5495.  
  5496. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5497.  
  5498. The return value is a 64 bit long which is actually two 32 bit DWORDs. The
  5499. Low DWORD (%@AB@%EAX%@AE@%) is the 32 bit count of free 4K pages in the system which
  5500. could be allocated with the %@AB@%PageAllocate%@AE@% as %@AI@%not %@AE@%%@AB@%PageLocked%@AE@% or %@AB@%PageFixed%@AE@%
  5501. memory. The High DWORD (%@AB@%EDX%@AE@%) is the 32 bit count of pages available for
  5502. allocation as %@AB@%PageLocked%@AE@% pages at the current time.  %@NL@%
  5503.  
  5504.  
  5505. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5506.  
  5507. You should be careful about making assumptions about being able to turn
  5508. around and issue a call to allocate all of the pages returned by this call.
  5509. Besides any alignment considerations, it is possible someone could get in
  5510. and allocate some or all of the pages before you. This call is intended to
  5511. be advisory in nature.  %@NL@%
  5512.  
  5513. %@AB@%EAX%@AE@% contains the size of the largest available region of linear address
  5514. space. %@AB@%EDX%@AE@% contains the count of pages currently available for allocation as
  5515. %@AB@%PageLocked%@AE@% pages. Notice that many assumptions are not valid. %@AB@%EAX%@AE@% >= %@AB@%EDX%@AE@% is
  5516. %@AI@%not%@AE@% a valid assumption for instance.  %@NL@%
  5517.  
  5518. You should be very careful about turning around and doing a %@AB@%PageAllocate%@AE@%
  5519. with the %@AB@%EAX%@AE@% return from this call. You can cause all sorts of odd behavior
  5520. if you take up all of the linear address space. You should allocate memory
  5521. on an as needed basis instead of allocating huge blocks of memory most of
  5522. which you do not use.  %@NL@%
  5523.  
  5524. %@CR:C6A00190095 @%%@CR:C6A00190096 @%
  5525. %@2@%%@CR:C6A00190097 @%%@AB@%PageGetSizeAddr%@AE@%%@EH@%%@NL@%
  5526. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5527.  
  5528. %@AS@%  unsigned long PageGetSizeAddr(hMem,flags)
  5529. %@AS@%     unsigned hMem;
  5530. %@AS@%     unsigned flags;%@AE@%
  5531.  
  5532. This call is used to get the size and linear address of an existing block of
  5533. pages. %@AI@%hMem%@AE@% is the value returned from a previous call to %@AB@%PageAllocate%@AE@% or
  5534. %@AB@%PageReAllocate%@AE@% and indicates the block to get the size and address of. There
  5535. are currently no bits defined in the flags, this parameter must be set to 0.
  5536. %@NL@%
  5537.  
  5538.  
  5539. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5540.  
  5541. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5542. Low DWORD (%@AB@%EAX%@AE@%) is the size in 4K pages of the block. The High DWORD (%@AB@%EDX%@AE@%)
  5543. is the 32 bit RING 0 address (offset relative to standard enhanced Windows
  5544. Ring 0 DS) of the block. Value (both DWORDs) is 0 if the call failed
  5545. (invalid %@AI@%hMem%@AE@%).  %@NL@%
  5546.  
  5547.  
  5548. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5549.  
  5550. Note that the size of a handle is the total size of the handle and has
  5551. nothing to do with what pieces of the handle may or may not be present.  %@NL@%
  5552.  
  5553. %@CR:C6A00190098 @%%@CR:C6A00190099 @%
  5554. %@2@%%@CR:C6A00190100 @%%@AB@%PageLock%@AE@%%@EH@%%@NL@%
  5555. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5556.  
  5557. %@AS@%  unsigned PageLock(hMem,nPages,PageOff,flags)
  5558. %@AS@%     unsigned hMem;
  5559. %@AS@%     unsigned nPages;
  5560. %@AS@%     unsigned PageOff;
  5561. %@AS@%     unsigned flags;%@AE@%
  5562.  
  5563. This call is used to lock (make present) all or part of an existing memory
  5564. handle. %@AI@%hMem%@AE@% is the value returned from a previous call to %@AB@%PageAllocate%@AE@% or
  5565. %@AB@%PageReAllocate%@AE@% and indicates the block to be locked. %@AI@%nPages%@AE@% specifies the
  5566. count of pages to be locked. %@AI@%PageOff%@AE@% specifies the page offset from the
  5567. start of the block of the first page to be locked. %@AI@%nPages%@AE@% together with
  5568. %@AI@%PageOff%@AE@% allow all or only part of the%@AI@% hMem%@AE@% block to be locked. An error will
  5569. occur if %@AI@%PageOff%@AE@%+%@AI@%nPages%@AE@% is greater than the size of %@AI@%hMem%@AE@%. There are
  5570. currently no bits defined in the %@AI@%flags%@AE@%, this parameter must be set to 0.  %@NL@%
  5571.  
  5572. Current flags bits:  %@NL@%
  5573.  
  5574. %@AS@%  PageLockedIfDP EQU 00000000000000000000000100000000B%@AE@%
  5575.  
  5576. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  5577. lock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to hardware.
  5578. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to hardware),
  5579. calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively NOPs. See the
  5580. %@AB@%PageAllocate%@AE@% documentation for a description of the different %@AB@%PageSwap
  5581. %@AB@%%@AE@%device types and their relevance.  %@NL@%
  5582.  
  5583.  
  5584. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5585.  
  5586. Returns nonzero value if the block was succesfully locked, zero if the lock
  5587. was unsuccesful (invalid %@AI@%hMem%@AE@%, insufficient memory).  %@NL@%
  5588.  
  5589.  
  5590. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5591.  
  5592. This call may be issued on %@AI@%hMem%@AE@% blocks which are %@AB@%PageFixed%@AE@%, but this is a
  5593. wasted call since %@AB@%PageFixed%@AE@% blocks are always locked (present).  %@NL@%
  5594.  
  5595. Because of the overcommit associated with demand paging, callers must be
  5596. prepared for this call to fail due to unavailability of sufficient memory to
  5597. make the region present.  %@NL@%
  5598.  
  5599. %@AI@%Note that%@AE@% %@AB@%PageLockedIfDP%@AE@% %@AI@%cannot be set on calls made before the init
  5600. %@AI@%complete system control call is made%@AE@%. This is because it is not possible to
  5601. ask the %@AB@%PageSwap%@AE@% device what type it is before it has been initialized.  %@NL@%
  5602.  
  5603. Each Page of a handle has an individual lock count. Each lock increments the
  5604. counter. The counter must go to 0 for the page to be unlocked. This means
  5605. that if the handle is locked 5 times, it has to be unlocked 5 times.  %@NL@%
  5606.  
  5607. Do not leave handles locked when they don't need to be, unlock handles as
  5608. soon as possible to make the physical memory associated available for use by
  5609. demand paging.  %@NL@%
  5610.  
  5611. The Flag bit equates are defined by including VMM.INC, please use the
  5612. equates.  %@NL@%
  5613.  
  5614. %@CR:C6A00190101 @%%@CR:C6A00190102 @%
  5615. %@2@%%@CR:C6A00190103 @%%@AB@%PageOutDirtyPages%@AE@%%@EH@%%@NL@%
  5616. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5617.  
  5618. %@AS@%  unsigned PageOutDirtyPages(nPages,flags)
  5619. %@AS@%     unsigned nPages;
  5620. %@AS@%     unsigned flags;%@AE@%
  5621.  
  5622. This call is for use by the demand paging device. It allows the paging
  5623. device to periodically "flush" out dirty pages to prevent a large number of
  5624. dirty pages from accumulating in the system. %@AI@%nPages%@AE@% is the maximum number of
  5625. dirty pages to flush at this time.  %@NL@%
  5626.  
  5627. Current flags bits:  %@NL@%
  5628.  
  5629. %@AS@%  PagePDPSetBase  EQU 00000000000000000100000000000000B 
  5630. %@AS@%  PagePDPClearBase  EQU 00000000000000001000000000000000B 
  5631. %@AS@%  PagePDPQueryDirty  EQU 00000000000000100000000000000000B%@AE@%
  5632.  
  5633. All unused bits %@AI@%must be zero%@AE@%. The %@AB@%PageSwap%@AE@% device may wish to flush out all
  5634. dirty pages in the system as part of a "background" activity ("write out
  5635. ahead"). These two bits allow this to be done, it allows the caller to
  5636. manipulate a variable associated with the page out scan which will cause the
  5637. scan to stop. This "base" page number that is set allows the %@AB@%PageSwap%@AE@% device
  5638. to tell when the %@AB@%PageOutDirtyPages%@AE@% call has completed a scan of the entire
  5639. address space looking for dirty pages. %@AB@%PagePDPSetBase%@AE@% tells
  5640. %@AB@%PageOutDirtyPages%@AE@% to set the base page number to the current scan start
  5641. point. %@AB@%PagePDPClearBase%@AE@% tells %@AB@%PageOutDirtyPages%@AE@% to clear the base page
  5642. number, setting it to NONE. A return value of 0 is used to detect when a
  5643. %@AB@%PageOutDirtyPages%@AE@% call has stoped because it has hit the base page. This is
  5644. not totally reliable, but is a reasonable approximation, since
  5645. %@AB@%PageOutDirtyPages%@AE@% can return 0 because there are no dirty pages (this is
  5646. rather unlikely). %@AB@%PagePDPQueryDirty%@AE@%, if set, indicates that the call is to
  5647. return the current count of DIRTY demand pageable pages, the %@AI@%nPages %@AE@%argument
  5648. and all other flags are ignored if this bit is set (call returns the count
  5649. of dirty pages as its sole function).  %@NL@%
  5650.  
  5651.  
  5652. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5653.  
  5654. Returns the actual count of dirty pages flushed by the call (0 is valid).  %@NL@%
  5655.  
  5656. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5657. %@AU@%WARNING%@AE@%
  5658.  
  5659. This call is intended for use by the PageSwap device, others should not be
  5660. calling it. Others making this call can disturb the operation of the
  5661. PageSwap device.
  5662. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5663.  
  5664.  
  5665. %@3@%%@AB@%Notes%@AE@%%@EH@%%@NL@%
  5666.  
  5667. This call functions something like a partial "commit" of the dirty pages in
  5668. the system. Note that ALL of the dirty demand pages can be flushed by
  5669. specifying a large value for %@AI@%nPages%@AE@% (like 0FFFFFFFFh).  %@NL@%
  5670.  
  5671. This call operates only on current page out candidates.  %@NL@%
  5672.  
  5673. The Flag bit equates are defined by including VMM.INC, please use the
  5674. equates.  %@NL@%
  5675.  
  5676. %@CR:C6A00190104 @%%@CR:C6A00190105 @%
  5677. %@2@%%@CR:C6A00190106 @%%@AB@%PageReAllocate%@AE@%%@EH@%%@NL@%
  5678. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5679.  
  5680. %@AS@%  unsigned PageReAllocate(hMem,nPages,flags)
  5681. %@AS@%     unsigned hMem;
  5682. %@AS@%     unsigned nPages;
  5683. %@AS@%     unsigned flags;%@AE@%
  5684.  
  5685. This call is used to grow or shrink or reinitialize an existing block of
  5686. memory. %@AI@%hMem%@AE@% is the value returned from a previous %@AB@%PageAllocate%@AE@% or
  5687. %@AB@%PageReAllocate%@AE@% call and indicates the block to be reallocated. %@AI@%Note that
  5688. %@AI@%handles allocated with%@AE@% %@AB@%PageUseAlign%@AE@% %@AI@%set cannot be%@AE@% %@AB@%PageReAllocated%@AE@%. %@AI@%nPages%@AE@% is
  5689. a 32 bit unsigned integer which is the new size in 4K pages of the block.  %@NL@%
  5690.  
  5691. Current flags bits:  %@NL@%
  5692.  
  5693. %@AS@%  PageZeroInit  EQU 00000000000000000000000000000001B 
  5694. %@AS@%  PageZeroReInit  EQU 00000000000000000000000000100000B 
  5695. %@AS@%  PageNoCopy  EQU 00000000000000000000000001000000B
  5696. %@AS@%  PageLocked  EQU 00000000000000000000000010000000B
  5697. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B%@AE@%
  5698.  
  5699. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLocked%@AE@% and %@AB@%PageLockedIfDP%@AE@%, if set,
  5700. indicates that if this %@AB@%PageReAllocation%@AE@% is growing the size of the handle,
  5701. the pages added to the handle are to be %@AB@%PageLocked%@AE@% or %@AB@%PageLockedIfDP%@AE@% (see
  5702. %@AB@%PageAllocate%@AE@% for explanation). If the %@AB@%PageReAllocation%@AE@% is not growing the
  5703. handle these bits are ignored. %@AI@%Note that%@AE@% %@AB@%PageFixed%@AE@% %@AI@%is not%@AE@% %@AI@%specified%@AE@%,
  5704. %@AB@%PageReAllocation%@AE@% of a %@AB@%PageFixed%@AE@% handle is implied as %@AB@%PageFixed%@AE@% by the handle
  5705. itself. %@AB@%PageZeroInit%@AE@%, if set, indicates that if the reallocation is
  5706. succesful, and the re-allocation is growing the size of the block, the "grow
  5707. area" of the block is to be initialized with value 0 in all bytes. This bit
  5708. is ignored on a re-allocation which is not growing the size of the block.
  5709. %@AB@%PageZeroReInit%@AE@% , if set, indicates that the entire block is to be
  5710. reinitialized with value zero in all bytes of the block. %@AB@%PageNoCopy%@AE@%, if set,
  5711. indicates that the previous contents of the block are irrelevant, and don't
  5712. need to be copied into the newly sized block. There is no reason that more
  5713. than one of these three bits should be set. If none of the bits are set, the
  5714. previous contents of the block are copied into the new block, up to the
  5715. lesser of the size of the new block, and the size of the old block, and the
  5716. "grow area", if any, is not initialized with anything.  %@NL@%
  5717.  
  5718.  
  5719. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5720.  
  5721. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  5722. Low DWORD (%@AB@%EAX%@AE@%) is the memory handle of the new block. The High DWORD (%@AB@%EDX%@AE@%)
  5723. is the 32 bit RING 0 address (offset relative to standard enhanced Windows
  5724. Ring 0 DS) of the block. Value (both DWORDs) is 0 if the reallocation failed
  5725. (insufficient memory, handle wrong type, invalid handle).  %@NL@%
  5726.  
  5727.  
  5728. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5729.  
  5730. Do not make assumptions about the relationship between the passed in %@AI@%hMem%@AE@%
  5731. and the Address returned, if specified. Assume that the returned %@AI@%hMem%@AE@% and
  5732. address are always different than the passed in %@AI@%hMem%@AE@% and previous address.  %@NL@%
  5733.  
  5734. In the case where this call fails, the passed in %@AI@%hMem%@AE@% and previous address
  5735. of the block remain valid. In the case where this call works and returns a
  5736. new %@AI@%hMem%@AE@% and address, the passed in%@AI@% hMem%@AE@% and previous address are no longer
  5737. valid (old block has been PageFreed).  %@NL@%
  5738.  
  5739. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5740. %@AU@%WARNING%@AE@%
  5741.  
  5742. Be very careful about PageReAllocating blocks which are currently
  5743. MapIntoV86ed to some VM context. Doing this can result in a crash.
  5744. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5745.  
  5746. %@AB@%PageLocked%@AE@% and %@AB@%PageLockedIfDP%@AE@% should not both be set. Only one, or the
  5747. other, or neither are valid settings. Note also that %@AB@%PageLockedIfDP%@AE@% cannot
  5748. be set on calls made before the init complete system control call is made.
  5749. This is because it is not possible to ask the %@AB@%PageSwap%@AE@% device what type it
  5750. is before it has been initialized.  %@NL@%
  5751.  
  5752. Note that this call can be used to reset the contents of an existing block
  5753. to 0 by setting %@AI@%nPages%@AE@% to the current size of the block and setting
  5754. PageZeroReInit.  %@NL@%
  5755.  
  5756. You cannot %@AB@%PageReAllocate%@AE@% a block to size 0, use %@AB@%PageFree%@AE@%.  %@NL@%
  5757.  
  5758. The Flag bit equates are defined by including VMM.INC, please use the
  5759. equates.  %@NL@%
  5760.  
  5761. %@CR:C6A00190107 @%%@CR:C6A00190108 @%
  5762. %@2@%%@CR:C6A00190109 @%%@AB@%PageUnLock%@AE@%%@EH@%%@NL@%
  5763. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5764.  
  5765. %@AS@%  unsigned PageUnLock(hMem,nPages,PageOff,flags)
  5766. %@AS@%     unsigned hMem;
  5767. %@AS@%     unsigned nPages;
  5768. %@AS@%     unsigned PageOff;
  5769. %@AS@%     unsigned flags;%@AE@%
  5770.  
  5771. This call is used to unlock all or part of an existing memory handle that
  5772. was previously locked. %@AI@%hMem%@AE@% is the value returned from a previous call to
  5773. %@AB@%PageAllocate%@AE@% or %@AB@%PageReAllocate%@AE@% and indicates the block to be unlocked.
  5774. %@AI@%nPages%@AE@% specifies the count of pages to be unlocked.%@AI@% PageOff%@AE@% specifies the
  5775. page offset from the start of the block of the first page to be unlocked.
  5776. %@AI@%nPages%@AE@% together with %@AI@%PageOff %@AE@%allow all or only part of the %@AI@%hMem%@AE@% block to be
  5777. unlocked. An error will occur if %@AI@%PageOff%@AE@%+%@AI@%nPages %@AE@%is greater than the size of
  5778. %@AI@%hMem%@AE@%.  %@NL@%
  5779.  
  5780. Current flags bits:  %@NL@%
  5781.  
  5782. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B 
  5783. %@AS@%  PageMarkPageOut  EQU 00000000000000000010000000000000B%@AE@%
  5784.  
  5785. All unused bits must be zero. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  5786. unlock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to
  5787. hardware. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to
  5788. hardware), calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively
  5789. NOPs. See the %@AB@%PageAllocat%@AE@%e documentation for a description of the different
  5790. %@AB@%PageSwap%@AE@% device types and their relevance. %@AB@%PageMarkPageOut%@AE@%, if set,
  5791. indicates that if this unlock actually does unlock the pages (lock count
  5792. goes to 0) the pages are to be made prime candidates for page out. This flag
  5793. should only be set if it is unlikely that these pages are going to be
  5794. touched for a while. Effectively what this does is clear the P_ACC bits of
  5795. the pages which causes them to be first level page out candidates.  %@NL@%
  5796.  
  5797.  
  5798. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5799.  
  5800. Returns nonzero value if the block was succesfully unlocked, zero if the
  5801. lock was unsuccesful (invalid %@AI@%hMem,%@AE@% no part of range is locked).  %@NL@%
  5802.  
  5803.  
  5804. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5805.  
  5806. This call %@AI@%may%@AE@% be issued on %@AI@%hMem%@AE@% blocks which are %@AB@%PageFixed%@AE@%, but this is a
  5807. wasted call since %@AB@%PageFixed%@AE@% blocks cannot be unlocked.  %@NL@%
  5808.  
  5809. Note that %@AB@%PageLockedIfDP%@AE@% cannot be set on calls made before the init
  5810. complete system control call is made. This is because it is not possible to
  5811. ask the %@AB@%PageSwap%@AE@% device what type it is before it has been initialized.  %@NL@%
  5812.  
  5813. Each page of a handle has an individual lock count. Each lock increments the
  5814. counter. The counter must go to 0 for the page to be unlocked. This means
  5815. that if the handle is locked 5 times, it has to be unlocked 5 times.  %@NL@%
  5816.  
  5817. The Flag bit equates are defined by including VMM.INC, please use the
  5818. equates.  %@NL@%
  5819.  
  5820. %@CR:C6A00190110 @%%@CR:C6A00190111 @%
  5821. %@2@%%@CR:C6A00190112 @%%@AB@%PhysIntoV86%@AE@%%@EH@%%@NL@%
  5822. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5823.  
  5824. %@AS@%  unsigned PhysIntoV86(PhysPage,VMHandle,VMLinPgNum,nPages,flags)
  5825. %@AS@%     unsigned PhysPage;
  5826. %@AS@%     unsigned VMHandle;
  5827. %@AS@%     unsigned VMLinPgNum;
  5828. %@AS@%     unsigned nPages;
  5829. %@AS@%     unsigned flags;%@AE@%
  5830.  
  5831. This call is very similar to the %@AB@%MapIntoV86%@AE@% call only instead of taking a
  5832. memory handle argument, it takes a Physical address (page number). The
  5833. intent of this call is to "hook up" a particular VM to the actual Physical
  5834. device memory of a device (such as the video memory of a display adaptor).
  5835. %@AI@%PhysPage%@AE@% is the physical page number of the start of the region to be
  5836. mapped, and indicates the block of physical memory to be mapped. For
  5837. instance, to hook up to the 64K of video memory at A000:000, PhysPage would
  5838. be A0h and %@AI@%nPage%@AE@%s would be 10h. The %@AI@%VMHandle%@AE@% parameter must be a valid %@AI@%VM
  5839. %@AI@%handle%@AE@% and indicates the VM into which the map is to occur. %@AI@%VMLinPgNum%@AE@% is
  5840. the address in the 1Meg V86 address space of the VM where the map will start
  5841. (this is a page number, thus linear address A0000h = page A0h). Alignment
  5842. considerations of this address (beyond 4K alignment) are the responsibility
  5843. of the caller. Map addresses below page 10h, or above 10Fh will cause an
  5844. error. %@AI@%nPages%@AE@% is the number of pages to map. The physical region is assumed
  5845. to be contiguous (thus if mapping three pages, they will be PhysPage,
  5846. PhysPage+1 and PhysPage+2 in that order). If the physical region is not
  5847. contiguous, you will have to issue multiple calls in succession. There are
  5848. currently no bits defined in the flags, this parameter must be set to 0.  %@NL@%
  5849.  
  5850.  
  5851. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5852.  
  5853. Returns a nonzero value if the map is succesful, returns 0 value if the map
  5854. was unsuccesful (invalid %@AI@%VMHandle%@AE@%, map range illegal).  %@NL@%
  5855.  
  5856.  
  5857. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5858.  
  5859. You are warned to be careful with this call. Very strange things will happen
  5860. if you specify a physical region which is unoccupied, or belongs to some
  5861. other device.  %@NL@%
  5862.  
  5863. The page attributes for these pages will be P_USER+P_PRES+P_WRITE. P_DIRTY
  5864. and P_ACC will be cleared by the call. PG_TYPE will be set to PG_SYS.  %@NL@%
  5865.  
  5866. The intent of %@AB@%PhysIntoV86%@AE@% support for pages between page 10h and
  5867. FirstV86Page is to support enhanced Windows devices which have
  5868. %@AB@%Allocate_Global_V86_Data_Area%@AE@% a %@AB@%GVDAPageAlign%@AE@% region. Use of mapping in this
  5869. region to other addresses can easily crash the system and should be avoided.
  5870. %@NL@%
  5871.  
  5872. Regions which span across %@AB@%FirstV86Page%@AE@% are not allowed.  %@NL@%
  5873.  
  5874. The reason for the page 10h limitation is that on most versions of the Intel
  5875. 80386 CPU there is an errata which prevents you from setting up a Linear
  5876. Physical address mapping in the first 64k of the address space.  %@NL@%
  5877.  
  5878. %@CR:C6A00190113 @%%@CR:C6A00190114 @%
  5879. %@2@%%@CR:C6A00190115 @%%@AB@%TestGlobalV86Mem%@AE@%%@EH@%%@NL@%
  5880. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5881.  
  5882. %@AS@%  unsigned TestGlobalV86Mem(VMLinAddr,nBytes,flags)
  5883. %@AS@%     unsigned VMLinAddr;
  5884. %@AS@%     unsigned nBytes;
  5885. %@AS@%     unsigned flags;%@AE@%
  5886.  
  5887. Some enhanced Windows devices wish to test whether a given piece of V86
  5888. address space is LOCAL to a particular VM, or GLOBAL. The reason for this
  5889. test is that GLOBAL V86 address ranges are valid and identical in ALL VM
  5890. contexts, while LOCAL V86 address ranges are valid in only one VM context.
  5891. This difference can yield optimizations. For instance, operations involving
  5892. GLOBAL address ranges will typically not need to be "virtualized" in any way
  5893. since the range is valid and addressable in ALL VM contexts. LOCAL address
  5894. range operations may have to be "virtualized" though since it is possible
  5895. for a piece of Virtual Mode code to try and use the address in the "wrong"
  5896. VM context where the address range is invalid, or points to the wrong
  5897. memory. This call can be used to test whether a V86 address range is GLOBAL
  5898. or LOCAL. %@AI@%VMLinAddr%@AE@% is the linear address of the first byte of the V86
  5899. address range. This address is relative to the standard RING 0 DS (ie. the
  5900. linear address of 02C1:0FC5 would be 02C10 + 0FC5 = 3BD5). %@AI@%nBytes%@AE@% is the
  5901. length of the V86 address range in bytes. There are currently no bits
  5902. defined in the flags, this parameter must be set to 0.  %@NL@%
  5903.  
  5904.  
  5905. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5906.  
  5907. Returns 0 if the address is not a valid V86 address range, or the address
  5908. range is LOCAL. Returns 1 if the address range is GLOBAL. Returns 2 if the
  5909. address range is partly LOCAL and partly GLOBAL (range overlaps a
  5910. GLOBAL/LOCAL boundary). Returns 3 if the address range is GLOBAL but
  5911. overlaps with an Instance data region.  %@NL@%
  5912.  
  5913.  
  5914. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5915.  
  5916. The distinction between GLOBAL and INSTANCE is rather subtle because
  5917. INSTANCE pages are "physically global" even though their content is LOCAL.
  5918. The physical address of instance data pages never changes, thus instance
  5919. pages are GLOBAL in the physical address sense. The content of instance data
  5920. regions is per VM though which means they are LOCAL in the sense of "what is
  5921. in them".  %@NL@%
  5922.  
  5923. The MMGR does not know any of the specifics about what is going on in the
  5924. regions above FirstV86Page. This routine will return LOCAL for all regions
  5925. above FirstV86Page, INCLUDING the A0-FF adapter/ROM BIOS area. Some pieces
  5926. of this region may actually be GLOBAL in terms of how they are used, but
  5927. this service doesn't know any of the details so it cannot determine this.  %@NL@%
  5928.  
  5929.  
  5930. %@2@%%@CR:C6A00190116 @%%@AB@%19.6  Looking At Physical Device Memory From a VxD%@AE@%%@EH@%%@NL@%
  5931. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5932.  
  5933. VxDs, such as virtual display drivers, that have a certain region of
  5934. physical address space associated with them, such as Video Memory, need a
  5935. way to look at the device-specific memory when the device is running. The
  5936. method by which this is done is by using a service that returns the correct
  5937. linear address (relative to the standard Ring 0 %@AB@%DS%@AE@%).  %@NL@%
  5938.  
  5939. It may seem to be possible for a VxD together with a Protected Mode
  5940. application to implement its own private "virtual memory" system by hooking
  5941. into the IDT and handling page faults itself. You are strongly warned not to
  5942. try and undertake an implementation of this sort at this time. It is
  5943. realized that support of such an architecture is a desirable feature for
  5944. implementation of such things as "virtual files" and "virtual memory mapped
  5945. devices". This feature will be addressed in a future version of Windows by
  5946. adding new VMM services, and/or modifying existing services to support it.
  5947. Since support for this is planned, any and all work that you might undertake
  5948. on the current version of Windows to implement this will be rendered
  5949. obsolete when support for it is added to the VMM.  %@NL@%
  5950.  
  5951. %@CR:C6A00190117 @%%@CR:C6A00190118 @%
  5952. %@2@%%@CR:C6A00190119 @%%@AB@%MapPhysToLinear%@AE@%%@EH@%%@NL@%
  5953. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5954.  
  5955. %@AS@%  unsigned MapPhysToLinear(PhysAddr,nBytes,flags)
  5956. %@AS@%     unsigned PhysAddr;
  5957. %@AS@%     unsigned nBytes;
  5958. %@AS@%     unsigned flags;%@AE@%
  5959.  
  5960. %@AI@%PhysAddr %@AE@%is the physical address of the start of the region to be looked at.
  5961. This is simply the 32 bit physical address, there are no alignment
  5962. considerations. Physical addresses start at 0, thus the address of physical
  5963. page 0A0h is 0A0000h. %@AI@%nBytes%@AE@% is the length of the physical region in bytes
  5964. starting from %@AI@%PhysAddr.%@AE@% This parameter is used to verify that the entire
  5965. range is addressable. There are currently no bits defined in the %@AI@%flags,%@AE@% this
  5966. parameter must be set to 0.  %@NL@%
  5967.  
  5968.  
  5969. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  5970.  
  5971. Returns the RING 0 DS offset of the first byte of the physical region. Will
  5972. return 0FFFFFFFFh if the specified range is not addressable.  %@NL@%
  5973.  
  5974. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5975. %@AU@%WARNING%@AE@%
  5976.  
  5977. You are warned to be careful with this method. Use of this for purposes
  5978. beyond looking at device specific physical memory is extremely dangerous and
  5979. is not approved.
  5980. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5981.  
  5982.  
  5983. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  5984.  
  5985. Physical addresses do not move. It is perfectly fine to get the linear
  5986. address of a physical region at Device_Init device call time and then use it
  5987. later. You do not have to keep recalling %@AB@%MapPhysToLinear%@AE@% every time you want
  5988. to look at the region.  %@NL@%
  5989.  
  5990. For instance to look at physical page A0h you would do this:  %@NL@%
  5991.  
  5992. %@AS@%  VMMCall _MapPhysToLinear,<0A0000h,10000h,0>%@AE@%
  5993.  
  5994. %@AB@%DS:[EAX]%@AE@% now addresses this physical page. Physical memory is mapped
  5995. contiguously at this selector so Page 0A1h would be 4096 bytes beyond the
  5996. above address.  %@NL@%
  5997.  
  5998.  
  5999. %@2@%%@CR:C6A00190120 @%%@AB@%19.7  Data Access Services%@AE@%%@EH@%%@NL@%
  6000. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6001.  
  6002. These services are used to get the contents of public memory manager
  6003. variables. All of these services return the value of the associated variable
  6004. in %@AB@%EAX%@AE@%.  %@NL@%
  6005.  
  6006. %@CR:C6A00190121 @%%@CR:C6A00190122 @%
  6007. %@2@%%@CR:C6A00190123 @%%@AB@%GetFirstV86Page%@AE@%%@EH@%%@NL@%
  6008. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6009.  
  6010. %@AS@%  unsigned GetFirstV86Page()%@AE@%
  6011.  
  6012. This call returns the page number of the first page of VM specific V86
  6013. memory.  %@NL@%
  6014.  
  6015.  
  6016. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6017.  
  6018. %@AB@%FirstV86Page%@AE@% MOVES during device initialization. Do not get the value at
  6019. device init time, and then use it later, as the value is invalid.  %@NL@%
  6020.  
  6021. %@CR:C6A00190124 @%%@CR:C6A00190125 @%
  6022. %@2@%%@CR:C6A00190126 @%%@AB@%GetNulPageHandle%@AE@%%@EH@%%@NL@%
  6023. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6024.  
  6025. %@AS@%  unsigned GetNulPageHandle()%@AE@%
  6026.  
  6027. This call returns the memory handle of the system NUL page.  %@NL@%
  6028.  
  6029. %@CR:C6A00190127 @%%@CR:C6A00190128 @%
  6030. %@2@%%@CR:C6A00190129 @%%@AB@%GetAppFlatDSAlias()%@AE@%%@EH@%%@NL@%
  6031. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6032.  
  6033. %@AS@%  unsigned GetAppFlatDSAlias()%@AE@%
  6034.  
  6035. This call returns a selector which can be used by protected mode
  6036. applications to look at the same data that the standard RING 0 DS looks at.
  6037. This is useful when a VxD wishes to provide a protected mode service to
  6038. applications and wants the application to be able to address the same memory
  6039. that the VxD does.  %@NL@%
  6040.  
  6041.  
  6042. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6043.  
  6044. This selector is %@AI@%read only%@AE@%. This is so that the Windows address space is
  6045. protected from a misbehaved application. It is not recommended that you
  6046. build a read/write version of this selector. If the application needs to
  6047. WRITE you should build a descriptor with a much more restricted Base and
  6048. Limit so that the application can only modify those things which it is
  6049. allowed to modify.  %@NL@%
  6050.  
  6051. This selector is RPL = DPL = Protected Mode Application Privilege. Notice
  6052. that a VxD can also use this selector if desired even though the devices run
  6053. at a different privilege level. Its type is "USE 16", this doesn't mean much
  6054. since it is a data selector.  %@NL@%
  6055.  
  6056. This is a GDT selector.  %@NL@%
  6057.  
  6058. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6059. %@AU@%WARNING%@AE@%
  6060.  
  6061. You must not do a Free_GDT_Selector on this selector. It is not protected,
  6062. and so it will get freed. Then anyone using it will fault and crash the
  6063. system. This selector is provided to prevent multiple devices from creating
  6064. multiple versions of the same selector and wasting GDT entries
  6065. unnecessarily. 
  6066. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6067.  
  6068. Notice that enhanced Windows is "USE 32", therefore a protected application,
  6069. which is "USE 16", will have to use the DB 67h addressing mode override on
  6070. its instructions to get 32 bit addressing (MASM will do this for you
  6071. automatically if you set things up correctly).  %@NL@%
  6072.  
  6073. This service can be used to discover what protection ring protectedmode
  6074. applications run at by doing a LAR on the returned selector. Be very careful
  6075. about what you do with this bit of information.  %@NL@%
  6076.  
  6077.  
  6078. %@2@%%@CR:C6A00190130 @%%@AB@%19.8  Special Services For Protected Mode APIs%@AE@%%@EH@%%@NL@%
  6079. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6080.  
  6081. These services are provided to support VxDs that need to manipulate
  6082. protected-mode address space. For example, applications running in protected
  6083. mode need a way to map regions of protected mode, segmented address space
  6084. into the virtual machine's virtual 8086 context. A specific example is the
  6085. MS-DOS INT 21 API. The data pointed to on the INT 21 calls needs to be
  6086. mapped into the VM's V86 address space so that MS-DOS can access it and
  6087. perform the requested operation.  %@NL@%
  6088.  
  6089. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6090. %@AU@%WARNING%@AE@%
  6091.  
  6092. Do not use these services for purposes other than their intended use. These
  6093. calls can be quite dangerous and can result in strange behavior or crashes
  6094. if misused.
  6095. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6096.  
  6097.  
  6098. %@2@%%@CR:C6A00190131 @%%@AB@%GetV86PageableArray%@AE@%%@EH@%%@NL@%
  6099. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6100.  
  6101. %@AS@%  unsigned GetV86PageableArray(VMHandle,ArrayBufPTR,flags)
  6102. %@AS@%  unsigned VMHandle;
  6103. %@AS@%  unsigned ArrayBufPTR;
  6104. %@AS@%  unsigned flags;%@AE@%
  6105.  
  6106. This call is used to obtain a copy of the bit array of pages whose behavior
  6107. has been modified via %@AB@%SetResetV86Pageable%@AE@%. This allows the caller to
  6108. determine which regions of the VM V86 address space have had the normal
  6109. lock/unlock behavior modified. VMHandle specifies the VM to get the bit map
  6110. of. ArrayBufPTR points to a buffer large enough to contain the array. The
  6111. assignment array is an array of 100h bits, one bit for each page in the
  6112. range 0-100h. Thus the size of the array is ((100h/8)+3)/4 = 8 DWORDS. Bits
  6113. in the array which are set (=1) indicate pages whose normal lock/unlock
  6114. behavior is disabled, bits which are clear (=0) indicate pages whose
  6115. behavior is normal. Thus to test the bit for page number N (0 %@NL@%
  6116.  
  6117. %@AS@%  mov ebx, N MOD 32    ; Bit number in DWORD
  6118. %@AS@%  mov eax, N / 32    ; DWORD index into array
  6119. %@AS@%  bt dword ptr ArrayBufPTR[eax*4],ebx  ; Test bit for page N
  6120. %@AS@%  jnc short PageNormal
  6121. %@AS@%      PageModified:%@AE@%
  6122.  
  6123. Note that this code is mearly intended to illustrate how the bit array
  6124. works. This code is not the most efficient, or the only way to implement
  6125. this test. There are currently no bits defined in the flags, this parameter
  6126. must be set to 0.  %@NL@%
  6127.  
  6128.  
  6129. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6130.  
  6131. Returns non-zero if succesfull, returns zero if the bit array could not be
  6132. returned (Invalid VMHandle).  %@NL@%
  6133.  
  6134.  
  6135. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6136.  
  6137. Making this call on a VM whose %@AB@%VMStat_PageableV86%@AE@% bit is clear is not an
  6138. error, it simply returns a bit array whose bits are all 0.  %@NL@%
  6139.  
  6140. %@CR:C6A00190132 @%%@CR:C6A00190133 @%
  6141. %@2@%%@CR:C6A00190134 @%%@AB@%LinMapIntoV86%@AE@%%@EH@%%@NL@%
  6142. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6143.  
  6144. %@AS@%  unsigned long LinMapIntoV86(HLinPgNum,VMHandle,VMLinPgNum,nPages,flags)
  6145. %@AS@%     unsigned HLinPgNum;
  6146. %@AS@%     unsigned VMHandle;
  6147. %@AS@%     unsigned VMLinPgNum;
  6148. %@AS@%     unsigned nPages;
  6149. %@AS@%     unsigned flags;%@AE@%
  6150.  
  6151. This call is provided to assist the interface address mapper functions. Its
  6152. purpose is to provide a way for the address mapper to map regions of
  6153. protected mode address space into a VM V86 address space so that API calls
  6154. can be performed. This calls operation is very similar to %@AB@%MapIntoV86%@AE@%, the
  6155. difference being that instead of taking a memory handle, it takes a linear
  6156. address. The call duplicates the memory map down into the indicated VM's V86
  6157. address range. %@AI@%HLinPgNum%@AE@%, together with %@AI@%nPages%@AE@%, indicates the region of
  6158. protected mode address space, or V86 address space that is to be mapped.
  6159. This is a page number, linear address 60610000h would be passed in as
  6160. 60610h. As with %@AB@%MapIntoV86%@AE@% there are implied %@AB@%PageLock%@AE@% and %@AB@%PageUnlocks%@AE@%. Note
  6161. that the linear address is relative to the standard enhanced Windows Ring 0
  6162. DS selector. The %@AI@%VMHandle%@AE@% parameter must be a valid %@AI@%VM handle%@AE@% and indicates
  6163. the V86 space into which the map is to occur. %@AI@%VMLinPgNum%@AE@% is the address in
  6164. the 1Meg VM V86 address space where the map will start (this is a page
  6165. number, thus linear address 60000h = page 60h). Alignment considerations of
  6166. this address (beyond 4K alignment) are the responsibility of the caller. Map
  6167. addresses below page 10h, or above 10Fh will cause an error. %@AI@%nPages%@AE@% is the
  6168. number of pages to map. Note that if %@AI@%HLinPgNum%@AE@% is a V86 page number (at the
  6169. LOW V86 address (at the LOW V86 address <= page 100h) the call does nothing
  6170. except return the %@AI@%HLinPgNum%@AE@% parameter in %@AB@%EDX%@AE@%. There are currently no bits
  6171. defined in the flags. This parameter must be 0.  %@NL@%
  6172.  
  6173.  
  6174. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6175.  
  6176. The return value is a 64 bit long which is actually two 32 bit DWORDS. The
  6177. Low DWORD (%@AB@%EAX%@AE@%) is a nonzero value if the map is succesful, returns 0 in eax
  6178. if the map was unsuccesful (invalid address range, invalid %@AI@%VMHandle%@AE@%, map
  6179. range illegal, size discrepancy, insufficient memory for implied %@AB@%PageLock%@AE@%).
  6180. The High DWORD (%@AB@%EDX%@AE@%) is only valid if %@AB@%EAX%@AE@% is nonzero. It is set to the
  6181. %@AI@%VMLinPgNum%@AE@% parameter if the %@AI@%HLinPgNum%@AE@% parameter was not a LOW V86 space
  6182. address, otherwise it is set to the %@AI@%HLinPgNum%@AE@% parameter. In short, %@AB@%EDX%@AE@% is
  6183. the V86 address where the memory is mapped.  %@NL@%
  6184.  
  6185.  
  6186. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6187.  
  6188. As with %@AB@%MapIntoV86%@AE@% there is an implied %@AB@%PageLock%@AE@% which is performed on all of
  6189. the pages mapped. This is consistent with the fact that V86 memory cannot be
  6190. Demand Paged while the VM is in a runable state. Whenever the V86 memory
  6191. mapping is changed via %@AB@%LinMapIntoV86%@AE@%, the previous memory that was mapped in
  6192. the VM is unlocked. The correct way to think of this is that there is an
  6193. implied %@AB@%PageLock%@AE@% whenever memory is mapped into a V86 context, and an
  6194. implied %@AB@%PageUnlock%@AE@% whenever it is "unmapped" from the V86 context. This
  6195. "unmapping" can occur when: A different handle (including the NulPageHandle)
  6196. is MapIntoV86ed to the region, or a %@AB@%PhysIntoV86%@AE@% is performed to the region.
  6197. %@NL@%
  6198.  
  6199. The V86 region mappped into by this call should be %@AB@%MapIntoV86ed %@AE@%with the
  6200. NulPageHandle when the V86 mapping region is no longer needed. There is
  6201. nothing to prevent you from mapping the same protected mode linear address
  6202. into multiple places in a VM, or into multiple VMs. Such operations are not
  6203. particularly advisable though. For one thing, the reporting of memory owned
  6204. by a VM will be disturbed.  %@NL@%
  6205.  
  6206. The reason this call exists is because a protected mode API mapper does not
  6207. have access to the memory handles associated with the various regions of
  6208. protected mode address space. VxDs which do have access to the memory
  6209. handles of the memory to be mapped should be using %@AB@%MapIntoV86%@AE@% to map the
  6210. memory, not this routine.  %@NL@%
  6211.  
  6212. For regions in the Physical addressing region this call will convert into a
  6213. %@AB@%PhysIntoV86%@AE@% call.  %@NL@%
  6214.  
  6215. For regions in the HIGH VM Linear addressing region this call will perform a
  6216. map of the memory from one VM into another VM (or into a different location
  6217. in the same VM). NOTE CAREFULLY: The intent of this support is to provide a
  6218. way for the V86MMGR device to map a region of V86 address space which is
  6219. currently LOCAL to one VM into a GLOBAL region that is addressable by all
  6220. VMs. This type of API is needed by network API mappers. Do not use this
  6221. capability in your VxD, use the V86MMGR service. The details of this aspect
  6222. of operation will change in a later release and code using the old method
  6223. will not function properly.  %@NL@%
  6224.  
  6225. The page attributes for these pages will be P_USER+P_PRES+P_WRITE. P_DIRTY
  6226. and P_ACC will be cleared by the call. PG_TYPE will be set to whatever the
  6227. type of the pages are at its protected mode linear address.  %@NL@%
  6228.  
  6229. The intent of %@AB@%LinMapIntoV86 %@AE@%support for pages between page 10h and
  6230. %@AB@%FirstV86Page%@AE@% is to support enhanced Windows devices which have
  6231. %@AB@%Allocate_Global_V86_Data_Area%@AE@% a GVDAPageAlign region. Use of mapping in this
  6232. region to other addresses can easily crash the system and should be avoided.
  6233. %@NL@%
  6234.  
  6235. Regions which span across %@AB@%FirstV86Page%@AE@% are not allowed.  %@NL@%
  6236.  
  6237. The reason for the page 10h limitation is that on most versions of the Intel
  6238. 80386 CPU there is an errata which prevents you from setting up a Linear !=
  6239. Physical address mapping in the first 64k of the address space.  %@NL@%
  6240.  
  6241. %@CR:C6A00190135 @%%@CR:C6A00190136 @%
  6242. %@2@%%@CR:C6A00190137 @%%@AB@%LinPageLock%@AE@%%@EH@%%@NL@%
  6243. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6244.  
  6245. %@AS@%  unsigned LinPageLock(HLinPgNum,nPages,flags)
  6246. %@AS@%     unsigned HLinPgNum;
  6247. %@AS@%     unsigned nPages;
  6248. %@AS@%     unsigned flags;%@AE@%
  6249.  
  6250. This call is provided to assist the interface address mapper functions. Its
  6251. purpose is to provide a way for the address mapper to lock regions of
  6252. protected mode address space so that API calls can be performed. This calls
  6253. operation is very similar to %@AB@%PageLock%@AE@%, the difference being that instead of
  6254. taking a memory handle, it takes a linear address. %@AI@%HLinPgNum%@AE@%, together with
  6255. %@AI@%nPages%@AE@%, indicates the region of protected mode address space that is to be
  6256. locked. This is a page number, linear address 60610000h would be passed in
  6257. as 60610h. Note that the linear address is relative to the standard enhanced
  6258. Windows Ring 0 DS selector.  %@NL@%
  6259.  
  6260. Current flags bits:  %@NL@%
  6261.  
  6262. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B%@AE@%
  6263.  
  6264. All unused bits must be zero. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  6265. lock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to hardware.
  6266. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to hardware),
  6267. calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively NOPs. See the
  6268. %@AB@%PageAllocate%@AE@% documentation for a description of the different %@AB@%PageSwap%@AE@%
  6269. device types and their relevance.  %@NL@%
  6270.  
  6271.  
  6272. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6273.  
  6274. Returns a nonzero value if the lock is succesful, returns 0 value if the
  6275. lock was unsuccesful (invalid address range, insufficient memory for lock).
  6276. %@NL@%
  6277.  
  6278.  
  6279. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6280.  
  6281. SEE %@AB@%PageLock%@AE@%.  %@NL@%
  6282.  
  6283. %@CR:C6A00190138 @%%@CR:C6A00190139 @%
  6284. %@2@%%@CR:C6A00190140 @%%@AB@%LinPageUnLock%@AE@%%@EH@%%@NL@%
  6285. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6286.  
  6287. %@AS@%  unsigned LinPageUnLock(HLinPgNum,nPages,flags)
  6288. %@AS@%     unsigned HLinPgNum;
  6289. %@AS@%     unsigned nPages;
  6290. %@AS@%     unsigned flags;%@AE@%
  6291.  
  6292. This call is provided to assist the interface address mapper functions. Its
  6293. purpose is to provide a way for the address mapper to unlock regions of
  6294. protected mode address space after API calls are performed. This calls
  6295. operation is very similar to %@AB@%PageUnLock%@AE@%, the difference being that instead
  6296. of taking a memory handle, it takes a linear address.%@AI@% HLinPgNum%@AE@%, together
  6297. with %@AI@%nPages%@AE@%, indicates the region of protected mode address space that is to
  6298. be unlocked. This is a page number, linear address 60610000h would be passed
  6299. in as 60610h. Note that the linear address is relative to the standard
  6300. enhanced Windows Ring 0 DS selector.  %@NL@%
  6301.  
  6302. Current flags bits:  %@NL@%
  6303.  
  6304. %@AS@%  PageLockedIfDP  EQU 00000000000000000000000100000000B
  6305. %@AS@%  PageMarkPageOut  EQU 00000000000000000010000000000000B%@AE@%
  6306.  
  6307. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageLockedIfDP%@AE@%, if set, indicates that the
  6308. unlock only needs to be done if the %@AB@%PageSwap%@AE@% device is not direct to
  6309. hardware. In the case where the %@AB@%PageSwap%@AE@% device is of type two (direct to
  6310. hardware), calls to this routine with %@AB@%PageLockedIfDP%@AE@% set are effectively
  6311. NOPs. See the %@AB@%PageAllocate%@AE@% documentation for a description of the different
  6312. %@AB@%PageSwap%@AE@% device types and their relevance. %@AB@%PageMarkPageOut%@AE@%, if set,
  6313. indicates that if this unlock actually does unlock the pages (lock count
  6314. goes to 0) the pages are to be made prime candidates for page out. This flag
  6315. should only be set if it is unlikely that these pages are going to be
  6316. touched for a while. Effectively what this does is clear the P_ACC bits of
  6317. the pages which causes them to be first level page out candidates.  %@NL@%
  6318.  
  6319.  
  6320. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6321.  
  6322. Returns a nonzero value if the unlock is succesful, returns 0 value if the
  6323. unlock was unsuccesful (invalid address range).  %@NL@%
  6324.  
  6325.  
  6326. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6327.  
  6328. SEE %@AB@%PageUnLock%@AE@%.  %@NL@%
  6329.  
  6330. %@CR:C6A00190141 @%%@CR:C6A00190142 @%
  6331. %@2@%%@CR:C6A00190143 @%%@AB@%PageCheckLinRange%@AE@%%@EH@%%@NL@%
  6332. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6333.  
  6334. %@AS@%  unsigned PageCheckLinRange(HLinPgNum,nPages,flags)
  6335. %@AS@%     unsigned HLinPgNum;
  6336. %@AS@%     unsigned nPages;
  6337. %@AS@%     unsigned flags;%@AE@%
  6338.  
  6339. This call is provided to assist the interface address mapper functions. Its
  6340. purpose is to provide a way for the address mapper to validate an intended
  6341. range for %@AB@%LinPageLock%@AE@% or %@AB@%LinMapIntoV86%@AE@%. Sometimes a MAXIMUM length range is
  6342. specified because the true range is unknown. This call will return an
  6343. adjusted %@AI@%nPages%@AE@% argument which will be adjusted down in size if the
  6344. specified range crosses an unreasonable boundary. %@AI@%HLinPgNum%@AE@%, together with
  6345. %@AI@%nPages%@AE@%, indicates the region of protected mode address space that is to be
  6346. checked. This is a page number, linear address 60610000h would be passed in
  6347. as 60610h. Note that the linear address is relative to the standard enhanced
  6348. Windows Ring 0 DS selector. There are currently no bits defined in the
  6349. flags, this parameter must be 0.  %@NL@%
  6350.  
  6351.  
  6352. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6353.  
  6354. Returns an adjusted %@AI@%nPages%@AE@% agrument. This will be %@AI@%zero%@AE@% if the range is
  6355. totally unreasonable, and will return %@AI@%nPages%@AE@% if no adjustment was needed.  %@NL@%
  6356.  
  6357.  
  6358. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6359.  
  6360. The end of a handle is a boundary that will result in an adjustment.  %@NL@%
  6361.  
  6362.  
  6363. %@2@%%@CR:C6A00190144 @%%@AB@%PageDiscardPages%@AE@%%@EH@%%@NL@%
  6364. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6365.  
  6366. %@AS@%  unsigned PageDiscardPages(LinPgNum,VMHandle,nPages,flags)
  6367. %@AS@%  unsigned LinPgNum;
  6368. %@AS@%  unsigned VMHandle;
  6369. %@AS@%  unsigned nPages;
  6370. %@AS@%  unsigned flags;%@AE@%
  6371.  
  6372. This call is provided to assist management of PM applications by providing a
  6373. way to mark pages as "no longer in use". What this does is allow regions
  6374. which were previously "in use" to be "discarded". This means that the page
  6375. does not have to be "paged in" to make it present, thus eliminating the disk
  6376. access required for the page in. LinPgNum and nPages together specify the
  6377. range to be discarded. LinPgNum is a page NUMBER. If LinPgNum is < 110h, or
  6378. at a VM high linear address, then the range lies in a VM and the %@AI@%VMHandle%@AE@%
  6379. parameter specifies the VM. In this case, all pages of the range must be
  6380. marked V86Pageable or the call will fail. Pages in the range which are not
  6381. present or are locked are ignored, this call effects only demand pageable
  6382. pages.  %@NL@%
  6383.  
  6384. Current flags bits:  %@NL@%
  6385.  
  6386. %@AS@%  PageZeroInit  EQU 00000000000000000000000000000001B
  6387. %@AS@%  PageDiscard  EQU 00000000000000010000000000000000B%@AE@%
  6388.  
  6389. Setting PageDiscard indicates that a full discard is to take place, the
  6390. P_ACC and P_DIRTY bits in the page table entrys for the pages are both
  6391. cleared. If PageDiscard is clear, all the call does is clear the P_ACC bit
  6392. in the page table entrys for the pages making them primary page out
  6393. candidates (the DIRTYness and content of the pages is preserved in this
  6394. case). Setting PageZeroInit is relevant only if PageDiscard is also set, and
  6395. it indicates that the pages are to be marked "zero the contents of this page
  6396. the next time it is paged in". In this case this subsequent page in is a NOP
  6397. since the pages have been discarded, this simply causes the pages to come
  6398. back in with a known value (0) in them instead of random garbage.  %@NL@%
  6399.  
  6400.  
  6401. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6402.  
  6403. Returns a non-zero value if successful, otherwise it returns zero (invalid
  6404. range or VM handle).  %@NL@%
  6405.  
  6406.  
  6407. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6408.  
  6409. The Flag bit equates are defined by including VMM.INC, please use the
  6410. equates.  %@NL@%
  6411.  
  6412. %@CR:C6A00190145 @%%@CR:C6A00190146 @%
  6413. %@2@%%@CR:C6A00190147 @%%@AB@%SelectorMapFlat%@AE@%%@EH@%%@NL@%
  6414. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6415.  
  6416. %@AS@%  unsigned SelectorMapFlat(VMHandle,Selector,flags)
  6417. %@AS@%     unsigned VMHandle;
  6418. %@AS@%     unsigned Selector;
  6419. %@AS@%     unsigned flags;%@AE@%
  6420.  
  6421. This call is provided to assist the interface address mapper functions. Its
  6422. purpose is to provide a way for the address mapper to get the RING 0 DS
  6423. offset of the base of a particular GDT or LDT selector. This call assists
  6424. the address mapper in converting a Selector:Offset16 or Selector:Offset32
  6425. pointer into its "flat model" linear address which can then be passed to
  6426. %@AB@%LinMapIntoVM%@AE@%. Selector is a GDT or LDT selector (note that the argument is a
  6427. DWORD not a WORD) value to get the base address of. The %@AI@%VMHandle%@AE@% parameter
  6428. is ignored if Selector is a GDT selector. If Selector is an LDT selector,
  6429. then %@AI@%VMHandle%@AE@% indicates the appropriate VM context for the Selector. There
  6430. are currently no bits defined in the flags, this parameter must be 0.  %@NL@%
  6431.  
  6432.  
  6433. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6434.  
  6435. Returns the linear address of the base of the selector if succesful, returns
  6436. FFFFFFFFh if it is unsuccesful (invalid selector).  %@NL@%
  6437.  
  6438.  
  6439. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6440.  
  6441. You can pass this routine the standard enhanced Windows RING 0 DS selector,
  6442. and it will return 0 as the base. This is a silly thing to do, but it does
  6443. work.  %@NL@%
  6444.  
  6445. The %@AI@%VMHandle%@AE@% parameter must be valid for LDT selectors.  %@NL@%
  6446.  
  6447.  
  6448. %@2@%%@CR:C6A00190148 @%%@AB@%SetResetV86Pageable%@AE@%%@EH@%%@NL@%
  6449. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6450.  
  6451. %@AS@%  unsigned SetResetV86Pageable(VMHandle,VMLinPgNum,nPages,flags)
  6452. %@AS@%  unsigned VMHandle;
  6453. %@AS@%  unsigned VMLinPgNum;
  6454. %@AS@%  unsigned nPages;
  6455. %@AS@%  unsigned flags;%@AE@%
  6456.  
  6457. This call allows the normal locking/unlocking behavior associated with a
  6458. specific range of V86 memory to be modified. %@AI@%VMHandle%@AE@% is the VM in which the
  6459. behavior is being modified. %@AI@%VMLinPgNum%@AE@% is the address in the 1Meg V86
  6460. address space where the behavior modification will start (this is a page
  6461. number, thus linear address 60000h = page 60h). Alignment considerations of
  6462. this address (beyond 4K alignment) are the responsibility of the caller. Map
  6463. addresses below %@AB@%FirstV86Page%@AE@%, or above 100h will cause an error. %@AI@%nPages%@AE@% is
  6464. the number of pages to modify the behavior of. Normally a %@AB@%MapIntoV86%@AE@% causes
  6465. the memory that is mapped to be locked. In the case where this particular VM
  6466. is currently running a Protected Mode application, it is desirable to undo
  6467. the lock, and change this normal lock/unlock behavior. This allows those
  6468. unused pieces of the V86 address space to be paged out and the memory they
  6469. are using to be used by someone else. Note that we can only undo this normal
  6470. behavior because the behavior of the protected mode application is well
  6471. known. In particular, we know that none of the V86 memory that is being
  6472. unlocked contains code that is executed, or data that is touched, at
  6473. interrupt time (including software interrupt time). The typical use of this
  6474. call is by the enhanced Windows device which loads a protected mode
  6475. application. When the PM app is loaded, the device calls %@AB@%SetRestV86Pageable%@AE@%
  6476. with the %@AB@%PageSetV86Pageable%@AE@% bit set on those pieces of the V86 address space
  6477. above %@AB@%FirstV86Page%@AE@% which can be unlocked; this is typically all of the V86
  6478. memory above FirstV86Page which is currently MS-DOS Free. NOTE that MS-DOS
  6479. data areas such as the 100h byte Program Header Prefix %@AI@%must not be included%@AE@%
  6480. in the ranges because they are accessed by MS-DOS. Similarly, when the
  6481. Protected Mode application Exits, the application loader calls
  6482. %@AB@%SetResetV86Pageable%@AE@% with PageClearV86Pageable set, on the V86 memory it had
  6483. initially modified during the load.  %@NL@%
  6484.  
  6485. The other aspect of the behavior that can be modified has to do with the
  6486. "other memory" (the memory that is %@AI@%not%@AE@% V86Pageable) in the VM. Normally this
  6487. memory is locked, except when the pager is type 2 (direct to hardware). Not
  6488. locking the V86 memory allows VM's V86 pages to also be Demand Paged. This
  6489. has the benefit of allowing MS-DOS applications to also run in a Demand
  6490. Paged environment. Sometimes though, this is an undesired behavior because
  6491. of the paging latency which it introduces in the VM. The V86IntsLocked bit
  6492. of a VM allows this aspect to be controled. Setting the V86IntsLocked
  6493. behavior causes the "other memory" to %@AI@%always%@AE@% be locked, even if the pager is
  6494. type 2. Setting this behavior has two important effects:  %@NL@%
  6495.  
  6496.  
  6497.   ■   There is never any "paging latency" while the virtual mode code in
  6498.       this VM is running. This prevents time critical V86 code from having
  6499.       its timing severly disturbed due to the paging overhead.%@NL@%
  6500.  
  6501.   ■   The paging device can enable interrupts in this VM when it is
  6502.       performing paging operations because %@AI@%it knows%@AE@% that a nested page fault
  6503.       will not occur from this VM since all of its interrupt time code is
  6504.       always locked.%@NL@%
  6505.  
  6506.  
  6507. Current flags bits:  %@NL@%
  6508.  
  6509. %@AS@%  PageSetV86Pageable  EQU 00000000000000000000001000000000B
  6510. %@AS@%  PageClearV86Pageable  EQU 00000000000000000000010000000000B
  6511. %@AS@%  PageSetV86IntsLocked  EQU 00000000000000000000100000000000B
  6512. %@AS@%  PageClearV86IntsLocked  EQU 00000000000000000001000000000000B%@AE@%
  6513.  
  6514. All unused bits %@AI@%must be zero%@AE@%. %@AB@%PageSetV86Pageable%@AE@%, if set, indicates that the
  6515. normal locking behavior of %@AB@%MapIntoV86%@AE@% is to be disabled (V86 memory can be
  6516. paged) for the indicated region. %@AB@%PageClearV86Pageable%@AE@%, if set, indicates
  6517. that the normal locking behavior is to be enabled on the indicated region.
  6518. %@AB@%PageSetV86IntsLocked%@AE@%, if set, indicates that the "lock all V86 memory that
  6519. is not V86Pageable regardless of pager type" behavior is to be enabled.
  6520. PageClearV86IntsLocked, if set, indicates that the "lock all V86 memory that
  6521. is not V86Pageable regardless of pager type" behavior is to be disabled.
  6522. %@AI@%Note%@AE@% that only %@AI@%one %@AE@%of these bits can be set on a call. Setting more than one
  6523. bit will result in an error. There are two bits in %@AB@%CB_VM_Status%@AE@% that
  6524. indicate the current state of these behaviors:  %@NL@%
  6525.  
  6526. %@AS@%  VMStat_PageableV86  EQU 00000000000000000000100000000000B
  6527. %@AS@%  VMStat_V86IntsLocked  EQU 00000000000000000001000000000000B%@AE@%
  6528.  
  6529. The %@AB@%VMStat_PageableV86%@AE@% bit is set if any regions behavior has been modified
  6530. (there is at least one non zero bit in the array returned by
  6531. %@AB@%GetV86PageableArray%@AE@%). The %@AB@%VMStat_V86IntsLocked%@AE@% bit is set if the "lock
  6532. regardless of pager type" behavior has been enabled in this VM.  %@NL@%
  6533.  
  6534.  
  6535. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6536.  
  6537. Returns non-zero value if the set or clear worked, zero if the current state
  6538. of the VM was not consistent with the call (invalid VMHandle,
  6539. %@AB@%VMStat_PageableV86%@AE@% or %@AB@%VMStat_V86IntsLocked%@AE@% state inconsistent with setting
  6540. of %@AB@%PageSet/ClearV86Pageable%@AE@% or %@AB@%PageSet/ClearV86IntsLocked%@AE@% bit in flags,
  6541. range invalid) or the lock of the memory associated with
  6542. %@AB@%PageClearV86Pageable%@AE@% or %@AB@%PageSetV86IntsLocked%@AE@% failed.  %@NL@%
  6543.  
  6544.  
  6545. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6546.  
  6547. The intent of this call is to better support Protected mode applications
  6548. running in a VM, not to allow you to randomly make v86 parts of VMs
  6549. pageable! Do not issue this call on a VM unless you are loading a Protected
  6550. mode app into it.  %@NL@%
  6551.  
  6552. The V86MMGR device makes a %@AB@%PageSetV86IntsLocked%@AE@% call on VMs which are
  6553. created with their base memory specified as %@AI@%locked%@AE@%.  %@NL@%
  6554.  
  6555. Extreme care must be used when manipulating the PageableV86 behavior of
  6556. regions above A000:0. This should not be done unless the region is GLOBAL or
  6557. LOCAL %@AB@%Assign_Device_V86_Pages%@AE@% owned by the caller.  %@NL@%
  6558.  
  6559. There is no REGION associated with %@AB@%PageSetV86IntsLocked%@AE@% and
  6560. %@AB@%PageClearV86IntsLocked%@AE@% calls. The IMPLIED region is always "everything that
  6561. isn't V86Pageable". For this reason the %@AI@%HLinPgNum%@AE@% and %@AI@%nPages%@AE@% arguments
  6562. should be set to 0 on these calls.  %@NL@%
  6563.  
  6564. VMM.INC contains equates for all of the flag bits described, use the
  6565. equates.  %@NL@%
  6566.  
  6567.  
  6568. %@2@%%@CR:C6A00190149 @%%@AB@%19.9  Instance Data Management%@AE@%%@EH@%%@NL@%
  6569. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6570.  
  6571. The purpose of these services is to provide a means of identifying to the
  6572. system those areas of virtual 8086 mode memory (V86 memory) that contain per
  6573. Virtual Machine or "Instance" data. Each of the VMs in the system has its
  6574. own, private instance of this data and anything the VM does to the values in
  6575. these locations has no effect on other VMs since the values are different in
  6576. each VM.  %@NL@%
  6577.  
  6578. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6579. NOTE
  6580.  
  6581. %@AI@%All of these calls use the USE32 C calling convention. The true name of the
  6582. %@AI@%procedure has an underscore in front (i.e., %@AB@%AddInstanceItem%@AE@%%@AI@% is actually%@AE@%%@AI@%%@AB@%
  6583. %@AB@%_AddInstanceItem%@AE@%%@AE@%%@AI@%), and the arguments are pushed right to left (unlike the
  6584. %@AI@%PL/M calling convention used by Windows, which is left to right). The return
  6585. %@AI@%value(s) is returned in C standard %@AE@%%@AI@%%@AB@%EDX:EAX%@AE@%%@AE@%%@AI@%. It is the responsibility of the
  6586. %@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
  6587. %@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
  6588. %@AI@%@AE@%%@AI@%%@AB@%EBX%@AE@%%@AE@%%@AI@% are preserved.%@AE@%%@AE@%
  6589. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6590.  
  6591. %@CR:C6A00190150 @%%@CR:C6A00190151 @%
  6592. %@2@%%@CR:C6A00190152 @%%@AB@%AddInstanceItem%@AE@%%@EH@%%@NL@%
  6593. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6594.  
  6595. %@AS@%  unsigned AddInstanceItem(InstStrucPTR,flags)
  6596. %@AS@%     unsigned InstStrucPTR;
  6597. %@AS@%     unsigned flags;%@AE@%
  6598.  
  6599. This call is used to identify a region of instance data in the V86 address
  6600. space. %@AI@%InstStrucPTR%@AE@% is a pointer to an instance data identification
  6601. structure which has this form:  %@NL@%
  6602.  
  6603. %@AS@%  InstDataStruc struc
  6604. %@AS@%     InstLinkF  dd ? ; RESERVED SET TO 0
  6605. %@AS@%     InstLinkB  dd ? ; RESERVED SET TO 0
  6606. %@AS@%     InstLinAddr  dd ? ; Linear address of start of block
  6607. %@AS@%     InstSize  dd ? ; Size of block in bytes
  6608. %@AS@%     InstType  dd ? ; Type of the block 
  6609. %@AS@%  InstDataStruc ends%@AE@%
  6610.  
  6611. The InstLinkF and InstLinkB fields are filled in by the Instance data
  6612. manager and cannot be used by the caller. InstLinAddr defines the start of
  6613. the block of instance data, NOTE THAT THIS IS NOT IN SEG:OFFSET FORM, it is
  6614. a linear address. Thus the correct value for 40:2F would be 42F. InstSize is
  6615. the size of the instance data block in bytes starting at InstLinAddr.
  6616. InstType defines one of two types of instance data:  %@NL@%
  6617.  
  6618. %@AS@%  INDOS_Field   equ  100h ; Bit indicating INDOS switch requirements 
  6619. %@AS@%  ALWAYS_Field  equ  200h ; Bit indicating ALWAYS switch requirements%@AE@%
  6620.  
  6621. ALWAYS_Field type indicates that the field must always be switched when a VM
  6622. is switched. All instance data sepcified by VxDs should be of this type.
  6623. INDOS_Field type is reserved for special types of MS-DOS internal data which
  6624. only need to be switched with the VM if the VM is currently INDOS.  %@NL@%
  6625.  
  6626. There are currently no bits defined in the flags, this parameter must be set
  6627. to 0.  %@NL@%
  6628.  
  6629.  
  6630. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6631.  
  6632. Returns nonzero value if the instance data block was succesfully added to
  6633. the instance list, zero if the block was unsuccesful added (This is probably
  6634. a FATAL error).  %@NL@%
  6635.  
  6636. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6637. NOTE
  6638.  
  6639. %@AI@%There are two basic ways to allocate the space for the InstDataStrucs
  6640. %@AI@%pointed to with InstStrucPTR. The first is to simply staticly allocate them
  6641. %@AI@%in the INIT data segment. The space they occupy will then be reclaimed when
  6642. %@AI@%the INIT space is reclaimed. The other way is to allocate them on the System
  6643. %@AI@%heap using HeapAllocate. The space can then be freed by HeapFreeing all of
  6644. %@AI@%the heap handles in the device Sys_VM_Init code which is called after all of
  6645. %@AI@%the system initialization (including the instance data initialization) is
  6646. %@AI@%done.%@AE@%
  6647.  
  6648. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6649. %@AU@%WARNING%@AE@%
  6650.  
  6651.  
  6652. If you allocate space for InstDataStrucs on the heap you must be sure NOT to
  6653. HeapReAllocate the heap blocks after passing the address to AddInstanceItem
  6654. because this will invalidate the InstStrucPTR value you previously passed to
  6655. AddInstanceItem.
  6656. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6657.  
  6658.  
  6659. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6660. NOTE 
  6661.  
  6662. %@AI@%This routine is in the init segment of enhanced Windows. It can therefore
  6663. %@AI@%only be called during system initialization. Trying to call it after system
  6664. %@AI@%initialization and the system INIT segment space has been reclaimed will
  6665. %@AI@%result in a fatal page fault.%@AE@%
  6666. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6667.  
  6668. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6669.  
  6670. Once this call is made, the caller %@AB@%must not %@AE@%ever touch the InstDataStruc
  6671. pointed to again. The caller has passed control of this data block to the
  6672. instrance data manager and tampering with it will result in the instance
  6673. data manager failing to identify the instance data correctly.  %@NL@%
  6674.  
  6675. Note that only one, contiguous region of instance data can be identified
  6676. with each structure. It is a good idea for the caller to coalesce adjacent
  6677. blocks of instance data it is identifying in order to cut down the call
  6678. overhead and data space requirements, but this is not required.  %@NL@%
  6679.  
  6680. There is a declaration of the InstDataStruc data structure in VMM.INC.  %@NL@%
  6681.  
  6682. %@CR:C6A00190153 @%%@CR:C6A00190154 @%
  6683. %@2@%%@CR:C6A00190155 @%%@AB@%MMGR_Toggle_HMA%@AE@%%@EH@%%@NL@%
  6684. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6685.  
  6686. %@AS@%  unsigned MMGR_Toggle_HMA(VMHandle,flags)
  6687. %@AS@%   unsigned VMHandle;
  6688. %@AS@%   unsigned flags;%@AE@%
  6689.  
  6690. This call is an interface to the Instance data manager which allows devices
  6691. such as the V86MMGR XMS device to control the behavior of the "highmem"
  6692. memory area, or "HMA", of a VM (V86 linear pages 100h through 10Fh). Any
  6693. device which wishes to modify the "1Meg Address Wrap" behavior of a VM MUST
  6694. use this call to inform the Instance data manager what is going on. This is
  6695. because the Instance manager must know whether 1Meg Address Wrap is on or
  6696. off to manage the instance data correctly for a VM. %@AI@%VMHandle%@AE@% is a valid
  6697. enhanced Windows VM handle which indicates the VM to which the call is to be
  6698. applied. Current flags bits:  %@NL@%
  6699.  
  6700. %@AS@%  MMGRHMAPhysical  EQU 00000000000000000000000000000001B 
  6701. %@AS@%  MMGRHMAEnable  EQU 00000000000000000000000000000010B 
  6702. %@AS@%  MMGRHMADisable  EQU 00000000000000000000000000000100B 
  6703. %@AS@%  MMGRHMAQuerry  EQU 00000000000000000000000000001000B%@AE@%
  6704.  
  6705. All unused bits must be zero. One, and only one of MMGRHMAEnable,
  6706. MMGRHMADisable, MMGRHMAQuerry BITS must be specified, the call will have
  6707. random results if this is not true. MMGRHMAPhysical bit is a modifier which
  6708. modifies the operation of the MMGRHMAEnable bit: See discussion of
  6709. MMGRHMAEnable. MMGRHMADisable, if set, causes the Instance manager to
  6710. restore the normal Wrap mapping for pages 100 through 10F thus Disabling the
  6711. HMA. This is a REMAP of pages 00h through 0Fh of the VM and causes the VMs
  6712. address space to "wrap" back to address zero for addresses >1Meg as it does
  6713. on an 8086 processor. MMGRHMAEnable, if set, disables 1Meg address wrap in
  6714. the VM, thus Enabling the HMA. Exactly what this does is controlled by the
  6715. MMGRHMAPhysical bit. If MMGRHMAPhysical is set, MMGRHMAEnable causes
  6716. PHYSICAL pages 100h through 10Fh to be mapped in Linear pages 100h through
  6717. 10Fh of the VM consistent with the operation of a Global HMA which is shared
  6718. by all VMs. If MMGRHMAPhysical is not set, Linear pages 100h through 10Fh
  6719. will be marked as not present System Pages in the VM. It is then up to the
  6720. CALLER to map some other memory handle into this region of the VM after this
  6721. call. This is consistent with the operation of a per VM HMA. Note that if
  6722. the VM accesses these pages before this mapping is set up, an erroneaous
  6723. page fault will occur which will crash the VM, or the system. MMGRHMAQuerry,
  6724. if set, returns the current state of the HMA in the VM.  %@NL@%
  6725.  
  6726.  
  6727. %@3@%%@AB@%Return Value%@AE@%%@EH@%%@NL@%
  6728.  
  6729. This call has no return value unless MMGRHMAQuerry was specified in the
  6730. flags. In this case the call will return value 0 if the HMA is Disabled
  6731. (1Meg address wrap is enabled), and it will return a nonzero value if the
  6732. HMA is Enabled (1Meg address wrap is disabled).  %@NL@%
  6733.  
  6734.  
  6735. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  6736.  
  6737. This call is reserved for the V86MMGR XMS device. Other devices should not
  6738. be using this call. Modifying the Wrap state of a VM without the V86MMGR XMS
  6739. device knowing about it will probably result in a state error and a crash.  %@NL@%
  6740.  
  6741. The device issuing this call must be a device which has succesfully Globally
  6742. or Locally %@AB@%Assign_Device_VM_Paged%@AE@% pages 100h through 10Fh in the indicated
  6743. VM. This is not a call which multiple devices should make for a VM as doing
  6744. so will cause confusion between the devices.  %@NL@%
  6745.  
  6746. When VMs are created, they are created with the HMA Disabled (1Meg Address
  6747. Wrap enabled) consistent with normal operation on an 8086 processor. The
  6748. device responsible for the HMA in a VM must adjust this in its %@AB@%Create_VM%@AE@%
  6749. device call if needed.  %@NL@%
  6750.  
  6751. Note that no distinction is drawn on the MMGRHMAQuerry return between
  6752. MMGRHMAPhysical being specified, or not specified on a previous
  6753. MMGRHMADisable call.  %@NL@%
  6754.  
  6755. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6756. NOTE 
  6757.  
  6758. %@AI@%Instance data is not allowed in the hma.%@AE@%
  6759. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6760.  
  6761. The flag bit equates are in VMM.INC, please use the equates.  %@NL@%
  6762.  
  6763.  
  6764. %@2@%%@CR:C6A00190156 @%%@AB@%19.10  Looking At V86 Address Space%@AE@%%@EH@%%@NL@%
  6765. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6766.  
  6767. From time to time, VxDs may wish to look at or modify some piece of the
  6768. virtual 8086 mode address space of a VM that is not the current VM. The
  6769. documented way to do this is as follows.  %@NL@%
  6770.  
  6771. %@CR:C6A00190157 @%%@CR:C6A00190158 @%
  6772. %@2@%%@CR:C6A00190159 @%%@AB@%CB_High_Linear%@AE@%%@EH@%%@NL@%
  6773. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6774.  
  6775. There is a Control Block variable which is a linear address of the start of
  6776. the VM's address space. Thus to look at VM linear adress 40:17 with %@AB@%EBX%@AE@%
  6777. being the VM Handle of the VM you're interested in you would do this:  %@NL@%
  6778.  
  6779. %@AS@%  mov esi,(40h SHL 4) + 17h
  6780. %@AS@%  add esi,[ebx.CB_High_Linear]%@AE@%
  6781.  
  6782. %@AB@%ESI%@AE@% now points to this location in the V86 address space. This can be used
  6783. to look at, modify any V86 address including instance data addresses.  %@NL@%
  6784.  
  6785. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6786. NOTE 
  6787.  
  6788. %@AI@%No code should EVER touch a part of V86 address space at its "low" address
  6789. %@AI@%(>=0,<=400000h) EVEN FOR THE CURRENT VM. There is NO REASON to do this, use
  6790. %@AI@%CB_High_Linear in ALL cases to look at V86 addresses.%@AE@%
  6791. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6792.  
  6793.  
  6794.  
  6795.  
  6796.  
  6797.  
  6798. %@CR:C6A00200001 @%%@1@%%@AB@%Chapter 20  I/O Services and Macros%@AE@%%@EH@%%@NL@%
  6799. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6800.  
  6801. This chapter documents the services available for I/O. Also included are two
  6802. macros and a discussion explaining their usefulness.  %@NL@%
  6803.  
  6804. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  6805. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  6806.  
  6807. When a virtual machine executes an instruction that reads or writes data
  6808. from an I/O port, the 80386 looks up the port number in the I/O Permission
  6809. Map (IOPM). If the corresponding bit in the IOPM is set, then the
  6810. instruction will cause a protection fault.  %@NL@%
  6811.  
  6812. Enhanced Windows provides services that virtual devices use to trap I/O. The
  6813. first thing a virtual device must do is hook the port while the device is
  6814. being initialized. This is done by calling a service called
  6815. %@AB@%Install_IO_Handler%@AE@%. It takes two parameters: the number of the I/O port to
  6816. hook and the address of a callback procedure.  %@NL@%
  6817.  
  6818. The I/O services and macros supported by enhanced Windows are described in
  6819. this chapter in the following order:  %@NL@%
  6820.  
  6821.  
  6822.   ■   %@AB@%Enable_Global_Trapping%@AE@%%@NL@%
  6823.  
  6824.   ■   %@AB@%Disable_Global_Trapping%@AE@%%@NL@%
  6825.  
  6826.   ■   %@AB@%Enable_Local_Trapping%@AE@%%@NL@%
  6827.  
  6828.   ■   %@AB@%Disable_Local_Trapping%@AE@%%@NL@%
  6829.  
  6830.   ■   %@AB@%Install_IO_Handler%@AE@%%@NL@%
  6831.  
  6832.   ■   %@AB@%Install_Mult_IO_Handlers%@AE@%%@NL@%
  6833.  
  6834.   ■   %@AB@%Simulate_IO%@AE@%%@NL@%
  6835.  
  6836.  
  6837.  
  6838. %@2@%%@CR:C6A00200002 @%%@AB@%20.1  Handling Different I/O Types%@AE@%%@EH@%%@NL@%
  6839.  
  6840. The value passed in %@AB@%ECX%@AE@% determines the type of input or output as specified
  6841. by Table 20.1.  %@NL@%
  6842.  
  6843. Table 20.1  I/O Register Values
  6844.  
  6845. %@TH:   9   464 02 22 54 @%Value                 Type of input/output%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%00H                   Byte input04H                   Byte output08H                   WORD input0CH                   WORD output10H                   DWORD input14H                   DWORD output%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@TE:   9   464 02 22 54 @%
  6846.  
  6847. Masks that apply only to string I/O are shown in Table 20.2.  %@NL@%
  6848.  
  6849. Table 20.2  String I/O Register Values
  6850.  
  6851. %@TH:   7   417 02 13 63 @%Value        Type of input/output%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%20H          String I/O40H          Repeated string I/O80H          32-bit addressing mode string I/O100H         Reverse string I/O (VM's direction flag is set)%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@TE:   7   417 02 13 63 @%
  6852.  
  6853. For all string I/O operations, the high WORD of %@AB@%ECX%@AE@% contains the segment for
  6854. the string I/O. This allows VxDs to ignore the issues of segment overrides
  6855. on these instructions; VMM has already determined the correct segment value.
  6856. Thus, a value of 3247016CH would specify that the VM is doing word reverse
  6857. repeated string output from 3247:SI.  %@NL@%
  6858.  
  6859. For example:  %@NL@%
  6860.  
  6861. High word = segment 3247 0Ch = Word output 20h = String I/O 40h = Repeated
  6862. string I/O 100h = Reverse I/O  %@NL@%
  6863.  
  6864. It would be unreasonable to expect every VxD to support 48 different types
  6865. of I/O. Therefore, the VxD environment only requires VxDs to support byte
  6866. input and output, even though a VxD can directly support any type of I/O
  6867. that is appropriate. For example, there is no reason for the Virtual Printer
  6868. Device (VPD) to support WORD input and output since printer ports are only
  6869. 8-bits wide.  %@NL@%
  6870.  
  6871. However, the VxDs for devices with 16-bit ports can directly support WORD
  6872. I/O as well as byte I/O.  %@NL@%
  6873.  
  6874. Furthermore, devices such as disk drives might need to directly emulate
  6875. string I/O for some ports to achieve acceptable performance. A device can
  6876. emulate some types of I/O and ignore others.  %@NL@%
  6877.  
  6878. But what happens if someone does WORD string output to a printer port? You
  6879. canot just throw the I/O away! For this reason, enhanced Windows has a
  6880. catch-all routine called %@AB@%Simulate_IO%@AE@% that converts I/O into something the
  6881. virtual device can understand. Notice in the port trap code of the VPD
  6882. example that entry points start with the %@AB@%Emulate_Non_Byte_IO%@AE@% macro. This
  6883. macro generates the following code:  %@NL@%
  6884.  
  6885. %@AS@%  cmp ecx, 4 
  6886. %@AS@%   jbe SHORT Foo 
  6887. %@AS@%   VMMjmp Simulate_IO 
  6888. %@AS@%  
  6889. %@AS@%  Foo:%@AE@%
  6890.  
  6891. So, if a VM attempted to do non-repeated forward %@AB@%word%@AE@% string I/O, the
  6892. following sequence of calls to the VPD trap code would be issued:  %@NL@%
  6893.  
  6894. Call VPD trap with:  %@NL@%
  6895.  
  6896. %@AB@%EBX%@AE@% = VM handle %@AB@%EDX%@AE@% = 358h (Port #) %@AB@%ECX%@AE@% = 23A8002Ch (String I/O from segment
  6897. 23A8h) %@AB@%EBP%@AE@% = Client register structure  %@NL@%
  6898.  
  6899. VPD jumps to %@AB@%Simulate_I/O%@AE@% which calls VPD again with:  %@NL@%
  6900.  
  6901. %@AB@%EBX%@AE@% = VM handle %@AB@%EDX%@AE@% = 358h (Port #) %@AB@%ECX%@AE@% = 0Ch (0Ch = Word output) %@AB@%AX %@AE@%= Word
  6902. to output %@AB@%EBP%@AE@% = Client register structure  %@NL@%
  6903.  
  6904. VPD jumps to %@AB@%Simulate_I/O%@AE@% which calls VPD again with:  %@NL@%
  6905.  
  6906. %@AB@%EBX%@AE@% = VM handle %@AB@%EDX%@AE@% = 358h (Port #) %@AB@%ECX%@AE@% = 04h (04h = Byte output) %@AB@%AL%@AE@% = Byte
  6907. to output %@AB@%EBP%@AE@% = Client register structure  %@NL@%
  6908.  
  6909. VPD then simulates the byte output and returns.  %@NL@%
  6910.  
  6911. Notice that the high-order byte of the word output would be sent to the trap
  6912. routine for VPD trap port # +1. So, if VPD is trapping port 358H, then word
  6913. output to this port will be converted into byte output to ports 358H and
  6914. 359H (exactly the way the hardware works).  %@NL@%
  6915.  
  6916.  
  6917. %@2@%%@CR:C6A00200003 @%%@AB@%20.2  I/O Macros%@AE@%%@EH@%%@NL@%
  6918.  
  6919. There are two useful macros for I/O trap routines. The first macro,
  6920. %@AB@%Emulate_Non_Byte_IO%@AE@%, generates the following code:  %@NL@%
  6921.  
  6922. %@AS@%  cmp ecx, Byte_Output
  6923. %@AS@%    jbe SHORT Is_Byte_IO
  6924. %@AS@%    VMMjmp Simulate_IO
  6925. %@AS@%    jnz Is_Byte_Input
  6926. %@AS@%  Is_Byte_IO:%@AE@%
  6927.  
  6928. %@AB@%Dispatch_Byte_IO%@AE@%, the second useful macro, takes two arguments. The first is
  6929. the destination for byte input, and the second is the destination for byte
  6930. output. This macro passes back all non-byte I/O to %@AB@%Simulate_IO%@AE@%. A typical
  6931. I/O trap routine looks like the following:  %@NL@%
  6932.  
  6933. %@AS@%  BeginProc VfooD_Trap_Data
  6934. %@AS@%    Dispatch_Byte_IO Fall_Through, VFood_Out_Data
  6935. %@AS@%     ...
  6936. %@AS@%    (Code for byte input)
  6937. %@AS@%    ...
  6938. %@AS@%    ret 
  6939. %@AS@%  
  6940. %@AS@%  VfooD_Out_Data:
  6941. %@AS@%    ...
  6942. %@AS@%    (Code for byte output)
  6943. %@AS@%    ...
  6944. %@AS@%    ret
  6945. %@AS@%  EndProc VfooD_Trap_Data%@AE@%
  6946.  
  6947. Notice the special value %@AB@%Fall_Through%@AE@% that instructs the %@AB@%Dispatch_Byte_IO%@AE@%
  6948. macro that byte input should fall through to the following code. You can
  6949. substitute %@AB@%Fall_Through%@AE@% for either the input or output parameter (but not
  6950. both) or specify two labels.  %@NL@%
  6951.  
  6952.  
  6953. %@2@%%@CR:C6A00200004 @%%@AB@%20.3  I/O Services%@AE@%%@EH@%%@NL@%
  6954.  
  6955. This section presents detailed information on each of the following I/O
  6956. services:  %@NL@%
  6957.  
  6958.  
  6959.   ■   %@AB@%Enable_Global_Trapping%@AE@%%@NL@%
  6960.  
  6961.   ■   %@AB@%Disable_Global_Trapping%@AE@%%@NL@%
  6962.  
  6963.   ■   %@AB@%Enable_Local_Trapping%@AE@%%@NL@%
  6964.  
  6965.   ■   %@AB@%Disable_Local_Trapping%@AE@%%@NL@%
  6966.  
  6967.   ■   %@AB@%Install_IO_Handler%@AE@%%@NL@%
  6968.  
  6969.   ■   %@AB@%Install_Mult_IO_Handlers%@AE@%%@NL@%
  6970.  
  6971.   ■   %@AB@%Simulate_IO%@AE@%%@NL@%
  6972.  
  6973.  
  6974. %@CR:C6A00200005 @%%@CR:C6A00200006 @%%@CR:C6A00200007 @%%@CR:C6A00200008 @%
  6975. %@2@%%@CR:C6A00200009 @%%@AB@%Enable_Global_Trapping, Disable_Global_Trapping%@AE@%%@EH@%%@NL@%
  6976. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6977.  
  6978.  
  6979. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  6980.  
  6981. These services enable and disable I/O port trapping in every VM. A callback
  6982. hook must have been installed during initialization before either of these
  6983. services is used.  %@NL@%
  6984.  
  6985. The global trapping state is by default enabled. When a VM is created, it
  6986. will be created with the current global trapping state.  %@NL@%
  6987.  
  6988.  
  6989. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  6990.  
  6991. %@AB@%EDX%@AE@% = I/O port number  %@NL@%
  6992.  
  6993.  
  6994. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  6995.  
  6996. None  %@NL@%
  6997.  
  6998.  
  6999. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7000.  
  7001. Flags  %@NL@%
  7002.  
  7003. %@CR:C6A00200010 @%%@CR:C6A00200011 @%%@CR:C6A00200012 @%%@CR:C6A00200013 @%
  7004. %@2@%%@CR:C6A00200014 @%%@AB@%Enable_Local_Trapping, Disable_Local_Trapping%@AE@%%@EH@%%@NL@%
  7005. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7006.  
  7007.  
  7008. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7009.  
  7010. These services enable and disable I/O port trapping in a specific VM. A
  7011. callback hook must have been installed during initialization before either
  7012. of these services is used.  %@NL@%
  7013.  
  7014.  
  7015. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7016.  
  7017. %@AB@%EBX %@AE@%= VM handle %@AB@%EDX%@AE@% = I/O port number  %@NL@%
  7018.  
  7019.  
  7020. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7021.  
  7022. None  %@NL@%
  7023.  
  7024.  
  7025. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7026.  
  7027. Flags  %@NL@%
  7028.  
  7029. %@CR:C6A00200015 @%%@CR:C6A00200016 @%
  7030. %@2@%%@CR:C6A00200017 @%%@AB@%Install_IO_Handler (Initialization only)%@AE@%%@EH@%%@NL@%
  7031. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7032.  
  7033.  
  7034. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7035.  
  7036. This service installs a callback procedure for I/O port trapping and enables
  7037. trapping for the specified port in all VM's. Only one procedure may be
  7038. installed for each port.  %@NL@%
  7039.  
  7040. When an I/O callback is installed, the default global trapping state is
  7041. enabled. You can disable trapping of a port for every or specific VMs using
  7042. the %@AB@%Enable/Disable_Global_Trapping%@AE@% and %@AB@%Enable/Disable_Local_Trapping%@AE@%
  7043. services.  %@NL@%
  7044.  
  7045.  
  7046. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7047.  
  7048. %@AB@%ESI%@AE@% = Address of procedure to call %@AB@%EDX%@AE@% = I/O port  %@NL@%
  7049.  
  7050.  
  7051. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7052.  
  7053. If carry set then  ERROR: Port already hooked by another device or  unable
  7054. to hook any more ports (out of hooks) else  Port hooked successfully  %@NL@%
  7055.  
  7056.  
  7057. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7058.  
  7059. Flags  %@NL@%
  7060.  
  7061.  
  7062. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7063.  
  7064. %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = Type of I/O %@AB@%EDX%@AE@% = Port number %@AB@%EBP%@AE@% -> Client
  7065. register structure  %@NL@%
  7066.  
  7067. If output then  EAX/AX/AL = Data output to port els e (input)  Callback
  7068. procedure must return EAX/AX/AL for data input from  port  %@NL@%
  7069.  
  7070. %@CR:C6A00200018 @%%@CR:C6A00200019 @%
  7071. %@2@%%@CR:C6A00200020 @%%@AB@%Install_Mult_IO_Handlers (Initialization only)%@AE@%%@EH@%%@NL@%
  7072. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7073.  
  7074.  
  7075. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7076.  
  7077. This service makes repeated calls to the %@AB@%Install_IO_Handler%@AE@% service with the
  7078. entries in a table built using macros as follows:  %@NL@%
  7079.  
  7080. Begin_Vxd_IO_Table Table_Name  Vxd_IO <port#>, <procedure name>     ...
  7081. Vxd_IO <port #>, <procedure name>  Vxd_IO <port #>, <procedure name>
  7082. End_Vxd_IO_Table Table_Name  %@NL@%
  7083.  
  7084.  
  7085. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7086.  
  7087. %@AB@%EDI%@AE@% = Address of VxD_IO_Table  %@NL@%
  7088.  
  7089.  
  7090. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7091.  
  7092. If carry set then  ERROR: One or more ports already hooked by another device
  7093. or unable to hook any more ports (out of hooks)  EDX = Number of port that
  7094. could not be hooked  else  Ports hooked successfully  %@NL@%
  7095.  
  7096.  
  7097. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7098.  
  7099. Flags  %@NL@%
  7100.  
  7101.  
  7102. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7103.  
  7104. %@AB@%EAX%@AE@% = Data for output instructions %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = Type of I/O
  7105. %@AB@%EDX%@AE@% = Port number %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  7106.  
  7107. Callback procedure must return EAX/AX/AL for data input from port  %@NL@%
  7108.  
  7109. %@CR:C6A00200021 @%%@CR:C6A00200022 @%
  7110. %@2@%%@CR:C6A00200023 @%%@AB@%Simulate_IO%@AE@%%@EH@%%@NL@%
  7111. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7112.  
  7113.  
  7114. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7115.  
  7116. This service is used to break complex I/O instructions into simpler types of
  7117. I/O. An I/O handler should jump to this service using %@AB@%VMMjmp Simulate_IO%@AE@%
  7118. whenever the handler is called with a type of I/O that it does not directly
  7119. support. A typical I/O trap handler would start with code similar to the
  7120. following:  %@NL@%
  7121.  
  7122. %@AS@%  Sample_IO_Handler:
  7123. %@AS@%    cmp ecx, Byte_Output
  7124. %@AS@%    je SHORT SIH_Simulate_Output
  7125. %@AS@%    jb SHORT SIH_Simulate_Input
  7126. %@AS@%    VMMjmp Simulate_IO %@AE@%
  7127.  
  7128. Since byte input is 0 and byte output is 4, a single compare can be used to
  7129. determine if the I/O is byte input, output, or not supported. When
  7130. %@AB@%Simulate_IO%@AE@% is invoked, it will break the I/O into simpler I/O types and
  7131. recursively call %@AB@%Sample_IO_Handler%@AE@%.  %@NL@%
  7132.  
  7133. For example, assume %@AB@%Sample_IO_Handler%@AE@% is the I/O trap handler for port 534H.
  7134. If it was called with %@AB@%ECX = Word_Output%@AE@%, then it would immediately jump to
  7135. the %@AB@%Simulate_IO%@AE@% service. %@AB@%Simulate_IO%@AE@% would then break the I/O instruction
  7136. into byte output to ports 534H and 535H. When %@AB@%Sample_IO_Handler%@AE@% was called
  7137. again, it would be able to virtualize the byte output to port 534H. The
  7138. output to port 535H would be handled by another port trap routine, or, if
  7139. there was not one installed, the output would be reflected directly to
  7140. hardware port 535H.  %@NL@%
  7141.  
  7142. Two macros, %@AB@%Emulate_Non_Byte_IO%@AE@% and %@AB@%Dispatch_Byte_IO%@AE@%, are provided as
  7143. convenient ways to invoke this service.  %@NL@%
  7144.  
  7145. %@AB@%Emulate_Non_Byte_IO%@AE@% is usually the first line of an I/O trap handler. It
  7146. simply compares %@AB@%ECX%@AE@% to %@AB@%Byte_Output%@AE@% and, if it is greater, it jumps to the
  7147. %@AB@%Simulate_IO%@AE@% service. For example:  %@NL@%
  7148.  
  7149. %@AS@%  Sample_IO_Handler:
  7150. %@AS@%   Emulate_Non_Byte_IO
  7151. %@AS@%   (Here ECX will be 0 for byte input or 4 for byte output) %@AE@%
  7152.  
  7153. %@AB@%Dispatch_Byte_IO%@AE@% is usually more convenient since it will also jump to the
  7154. appropriate code for byte input or output. The macro takes two parameters.
  7155. The first parameter specifies the label to jump to for byte input, and the
  7156. second specifies the label to jump to for byte output. Either parameter (but
  7157. not both) can have the special value %@AB@%Fall_Through%@AE@%, which specifies that the
  7158. code to handle that I/O type immediately follows the macro. For example:  %@NL@%
  7159.  
  7160. %@AS@%  Sample_IO_Handler:
  7161. %@AS@%   Dispatch_Byte_IO Fall_Through, <SHORT  SIH_Output>
  7162. %@AS@%   (...Code here for handling byte input...)
  7163. %@AS@%   ret %@AE@%
  7164.  
  7165. %@AS@%  SIH_Output:
  7166. %@AS@%   (...Code here for handling byte output...)
  7167. %@AS@%   ret %@AE@%
  7168.  
  7169. If, for efficiency reasons, you want to provide code to virtualize I/O other
  7170. than byte input and output, test for the types that you can handle and then
  7171. jump to this service to emulate other types of I/O.  %@NL@%
  7172.  
  7173. Notice that the entry parameters to this service are identical to the
  7174. parameters passed to your I/O trap routine. You should jump to this service
  7175. using the %@AB@%VMMjmp%@AE@% macro with all of the registers in the same state as when
  7176. your I/O trap routine was called (although you may modify %@AB@%ESI%@AE@% and %@AB@%EDI%@AE@% since
  7177. they are not parameters).  %@NL@%
  7178.  
  7179.  
  7180. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7181.  
  7182. %@AB@%EAX%@AE@% = Data for output instructions %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX %@AE@%= Type of I/O
  7183. (same as passed to I/O trap routine) %@AB@%EDX%@AE@% = I/O port %@AB@%EBP%@AE@% -> Client Register
  7184. Structure  %@NL@%
  7185.  
  7186.  
  7187. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7188.  
  7189. All registers modified. If input, then %@AB@%AX%@AE@% or %@AB@%EAX%@AE@% will contain virtualized
  7190. input value.  %@NL@%
  7191.  
  7192.  
  7193. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7194.  
  7195. %@AB@%EAX%@AE@%,%@AB@% EBX%@AE@%, %@AB@%ECX%@AE@%,%@AB@% EDX%@AE@%,%@AB@% ESI, EDI%@AE@%, Flags  %@NL@%
  7196.  
  7197.  
  7198.  
  7199.  
  7200.  
  7201.  
  7202. %@CR:C6A00210001 @%%@1@%%@AB@%Chapter 21  VM Interrupt and Call Services%@AE@%%@EH@%%@NL@%
  7203. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7204.  
  7205. The VM Interrupt and Call Services supported by enhanced Windows are
  7206. described in this chapter in the following order:  %@NL@%
  7207.  
  7208.  
  7209.   ■   %@AB@%Build_Int_Stack_Frame%@AE@%%@NL@%
  7210.  
  7211.   ■   %@AB@%Call_When_Idle%@AE@%%@NL@%
  7212.  
  7213.   ■   %@AB@%Call_When_VM_Ints_Enabled%@AE@%%@NL@%
  7214.  
  7215.   ■   %@AB@%Disable_VM_Ints%@AE@%%@NL@%
  7216.  
  7217.   ■   %@AB@%Enable_VM_Ints%@AE@%%@NL@%
  7218.  
  7219.   ■   %@AB@%Get_PM_Int_Type%@AE@%%@NL@%
  7220.  
  7221.   ■   %@AB@%Get_V86_Int_Vector%@AE@%%@NL@%
  7222.  
  7223.   ■   %@AB@%Get_PM_Int_Vector%@AE@%%@NL@%
  7224.  
  7225.   ■   %@AB@%Hook_V86_Int_Chain%@AE@%%@NL@%
  7226.  
  7227.   ■   %@AB@%Set_PM_Int_Type%@AE@%%@NL@%
  7228.  
  7229.   ■   %@AB@%Set_V86_Int_Vector%@AE@%%@NL@%
  7230.  
  7231.   ■   %@AB@%Set_PM_Int_Vector%@AE@%%@NL@%
  7232.  
  7233.   ■   %@AB@%Simulate_Far_Call%@AE@%%@NL@%
  7234.  
  7235.   ■   %@AB@%Simulate_Far_Jmp%@AE@%%@NL@%
  7236.  
  7237.   ■   %@AB@%Simulate_Far_Ret%@AE@%%@NL@%
  7238.  
  7239.   ■   %@AB@%Simulate_Far_Ret_N%@AE@%%@NL@%
  7240.  
  7241.   ■   %@AB@%Simulate_Int%@AE@%%@NL@%
  7242.  
  7243.   ■   %@AB@%Simulate_Iret%@AE@%%@NL@%
  7244.  
  7245.  
  7246. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  7247. "Virtual Device (VxD) Programming Topics," for general discussions on VM
  7248. Interrupts and Call Services.  %@NL@%
  7249.  
  7250. %@CR:C6A00210002 @%%@CR:C6A00210003 @%
  7251. %@2@%%@CR:C6A00210004 @%%@AB@%Build_Int_Stack_Frame%@AE@%%@EH@%%@NL@%
  7252. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7253.  
  7254.  
  7255. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7256.  
  7257. This service will save the current %@AB@%CS:IP%@AE@% and flags on the VM's stack and,
  7258. then, set the %@AB@%CS:IP%@AE@% to the value passed to the routine. The next time the VM
  7259. is entered, the effect will be that an interrupt occurred, directing control
  7260. to the procedure specified.  %@NL@%
  7261.  
  7262. The procedure that is called must do an IRET to return.  %@NL@%
  7263.  
  7264. Sample code:  %@NL@%
  7265.  
  7266. %@AS@%  VMMcall Begin_Nest_Exec
  7267. %@AS@%        mov      cx, [My_Private_VM_Proc_Segment]
  7268. %@AS@%        mov      edx, [My_Private_VM_Proc_Offset]
  7269. %@AS@%        VMMcall  Build_Int_Stack_Frame
  7270. %@AS@%        VMMcall  Resume_exec
  7271. %@AS@%        VMMcall End_Nest_Exec%@AE@%
  7272.  
  7273.  
  7274. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7275.  
  7276. %@AB@%CX%@AE@% = Code segment of procedure to call %@AB@%EDX%@AE@% = Offset of procedure to call
  7277. (high word must be 0 for 16-bit apps)  %@NL@%
  7278.  
  7279.  
  7280. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7281.  
  7282. None  %@NL@%
  7283.  
  7284.  
  7285. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7286.  
  7287. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  7288.  
  7289. %@CR:C6A00210005 @%%@CR:C6A00210006 @%
  7290. %@2@%%@CR:C6A00210007 @%%@AB@%Call_When_Idle%@AE@%%@EH@%%@NL@%
  7291. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7292.  
  7293.  
  7294. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7295.  
  7296. This service is used by devices that want to perform background operations
  7297. with the system is "idle". For example, this service is used by the pageswap
  7298. device to asynchronously write dirty pages to the swap file. Windows is
  7299. considered idle when all VMs have released their time-slice. When the
  7300. Windows kernel signals that Windows is idle and all other VMs are idle, the
  7301. idle callback procedures will be called. Each callback can either consume
  7302. the idle call or pass it on to the next idle callback in the list. Idle
  7303. calls should be consumed if the device performs an operation that takes a
  7304. significant amount of time. For example, if the pageswap device writes a
  7305. dirty page to the swap file then it will consume the idle call to prevent
  7306. sluggish performance.  %@NL@%
  7307.  
  7308.  
  7309. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7310.  
  7311. %@AB@%ESI%@AE@% -> Procedure to call when all VMs idle  %@NL@%
  7312.  
  7313.  
  7314. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7315.  
  7316. If carry clear then  Callback procedure installed else  Error: Could not
  7317. install call-back procedure  %@NL@%
  7318.  
  7319.  
  7320. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7321.  
  7322. Flags  %@NL@%
  7323.  
  7324.  
  7325. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7326.  
  7327. %@AB@%EBX %@AE@%= System VM Handle (current VM is always the system VM) %@AB@%EBP%@AE@% -> Client
  7328. register structure Return with carry SET to pass the call to next handler
  7329. Return with carry CLEAR to consume the callback and indicate Sys VM is not
  7330. 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.
  7331. %@NL@%
  7332.  
  7333. %@CR:C6A00210008 @%%@CR:C6A00210009 @%
  7334. %@2@%%@CR:C6A00210010 @%%@AB@%Call_When_VM_Ints_Enabled%@AE@%%@EH@%%@NL@%
  7335. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7336.  
  7337.  
  7338. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7339.  
  7340. If a VxD needs to be called when interrupts are enabled, it can use this
  7341. service to be notified when the VM enables interrupts. If the current VM's
  7342. interrupts are already enabled when this service is called, your callback
  7343. procedure will be called immediately.  %@NL@%
  7344.  
  7345. It is usually more convenient to use the %@AB@%Call_Priority_VM_event%@AE@% service
  7346. instead of calling this service directly. However, this service is faster.  %@NL@%
  7347.  
  7348.  
  7349. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7350.  
  7351. %@AB@%EDX%@AE@% = Reference data %@AB@%ESI%@AE@% = Offset of procedure to call  %@NL@%
  7352.  
  7353.  
  7354. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7355.  
  7356. None  %@NL@%
  7357.  
  7358.  
  7359. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7360.  
  7361. %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  7362.  
  7363.  
  7364. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7365.  
  7366. %@AB@%EBX%@AE@% = Handle of current VM %@AB@%EDX%@AE@% = Reference data passed to this service %@AB@%EBP%@AE@%
  7367. -> Client register structure Called procedure may destroy %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  7368. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  7369.  
  7370. %@CR:C6A00210011 @%%@CR:C6A00210012 @%
  7371. %@2@%%@CR:C6A00210013 @%%@AB@%Disable_VM_Ints%@AE@%%@EH@%%@NL@%
  7372. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7373.  
  7374.  
  7375. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7376.  
  7377. This service will disable interrupts during VM execution for the current
  7378. virtual machine. This has the same effect as the VM executing a CLI
  7379. instruction.  %@NL@%
  7380.  
  7381.  
  7382. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7383.  
  7384. None  %@NL@%
  7385.  
  7386.  
  7387. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7388.  
  7389. None  %@NL@%
  7390.  
  7391.  
  7392. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7393.  
  7394. Flags  %@NL@%
  7395.  
  7396. %@CR:C6A00210014 @%%@CR:C6A00210015 @%
  7397. %@2@%%@CR:C6A00210016 @%%@AB@%Enable_VM_Ints%@AE@%%@EH@%%@NL@%
  7398. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7399.  
  7400.  
  7401. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7402.  
  7403. This service will enable interrupts during VM execution for the current
  7404. virtual machine. This has the same effect as the VM executing an STI
  7405. instruction. This service allows events scheduled using the
  7406. %@AB@%Call_When_Ints_Enabled%@AE@% or %@AB@%Call_Proirity_VM_Event%@AE@% services to be serviced.
  7407. Note, however, that they will not be serviced immediately. They will be
  7408. serviced at event time. This means that VxDs calling this service do not
  7409. need to worry about the VM's state changing during this call.  %@NL@%
  7410.  
  7411.  
  7412. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7413.  
  7414. None  %@NL@%
  7415.  
  7416.  
  7417. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7418.  
  7419. None  %@NL@%
  7420.  
  7421.  
  7422. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7423.  
  7424. Flags  %@NL@%
  7425.  
  7426. %@CR:C6A00210017 @%
  7427. %@2@%%@CR:C6A00210018 @%%@AB@%Get_PM_Int_Type%@CR:C6A00210019 @%%@AE@%%@EH@%%@NL@%
  7428. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7429.  
  7430.  
  7431. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7432.  
  7433. This service is used to determine if a PM interrupt vector is an interrupt
  7434. gate or trap gate type interrupt. Interrupt gate interrupts clear the
  7435. interrupt flag bit to disable interrupts when the interrupt occurs. Trap
  7436. gate interrupts don't modify the interrupt bit. All PM interrupts default to
  7437. the trap gate type, but VxD's such as VPICD need to change some of them to
  7438. interrupt gates so that hardware interrupts disable interrupts. Other
  7439. software interrupts such as INT 21h are left as trap gates, so that their
  7440. handlers don't need to execute an STI and thus avoid the extra overhead of
  7441. an unnecessary ring transition.  %@NL@%
  7442.  
  7443.  
  7444. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7445.  
  7446. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  7447.  
  7448.  
  7449. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7450.  
  7451. %@AB@%EDX%@AE@% = 0 if vector is a trap gate (interrupt flag is not changed)  0 if
  7452. vector is an interupt gate (interrupt flag is cleared)  %@NL@%
  7453.  
  7454.  
  7455. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7456.  
  7457. %@AB@%EDX%@AE@%, Flags  %@NL@%
  7458.  
  7459. %@CR:C6A00210020 @%%@CR:C6A00210021 @%%@CR:C6A00210022 @%%@CR:C6A00210023 @%
  7460. %@2@%%@CR:C6A00210024 @%%@AB@%Get_V86_Int_Vector, Get_PM_Int_Vector%@AE@%%@EH@%%@NL@%
  7461. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7462.  
  7463.  
  7464. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7465.  
  7466. These services return the current VM's interrupt vector for the mode
  7467. specified. For V86 mode, this is the DWORD located in the real mode
  7468. interrupt vector. A PM interrupt vector table is maintained by the VMM for
  7469. every virtual machine.  %@NL@%
  7470.  
  7471. Notice that for PM interrupts, a return with ZF set indicates that the
  7472. interrupt has not been hooked. The %@AB@%CS:EIP%@AE@% returned will point to a PM
  7473. callback break point. The break point will invoke code that reflects the
  7474. interrupt to V86 mode. VxDs can chain to this break point just as they would
  7475. any other protected mode address (using Simulate_Far_Jmp or
  7476. Build_Int_Stack_Frame) although it is also acceptable to reflect the
  7477. interrupt to V86 immediately for optimal performance.  %@NL@%
  7478.  
  7479.  
  7480. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7481.  
  7482. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  7483.  
  7484.  
  7485. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7486.  
  7487. %@AB@%CX%@AE@% = %@AB@%CS%@AE@% in vector (high word zero) %@AB@%EDX%@AE@% = %@AB@%EIP%@AE@% in interrupt vector (for V86
  7488. mode and 16-bit protected mode programs the high word will be zero) For PM
  7489. vectors, if interrupt vector points to reflection code (default) then  Zero
  7490. flag is set  else  Zero flag is clear  %@NL@%
  7491.  
  7492.  
  7493. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7494.  
  7495. %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  7496.  
  7497. %@CR:C6A00210025 @%
  7498. %@2@%%@CR:C6A00210026 @%%@AB@%Hook_V86_Int_Chain (Initialization only)%@AE@%%@EH@%%@NL@%
  7499. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7500.  
  7501. %@CR:C6A00210027 @%Description  %@NL@%
  7502.  
  7503. These services are used to monitor software interrupts and simulated
  7504. hardware interrupts in Virtual-8086 mode. More than one VxD is allowed to
  7505. hook an interrupt. The last interrupt hook will be the first one called.
  7506. Every interrupt hook can either service the interrupt or allow the interrupt
  7507. to be reflected to the next handler in the chain. If no interrupt hook
  7508. procedure consumes the interrupt, then it will be reflected to the virtual
  7509. machine.  %@NL@%
  7510.  
  7511. To consume an interrupt, a hook procedure must return with the Carry flag
  7512. clear. If the Carry flag is set when an interrupt hook returns, then the
  7513. interrupt will be passed on to the next handler in the chain or, if the end
  7514. of the chain is reached, reflected to the current virtual machine.  %@NL@%
  7515.  
  7516. If a VxD calls the %@AB@%Simulate_Int%@AE@% service, then all interrupt chain hooks will
  7517. be called before the interrupt is reflected into the virtual machine.
  7518. Simulated hardware interrupts will also be routed through the interrupt
  7519. hooks. Therefore, your code should not assume that the VM has just executed
  7520. a software interrupt instruction.  %@NL@%
  7521.  
  7522. Notice that there is no corresponding service to hook Protected Mode
  7523. interrupts. PM interrupts must be hooked by hooking the interrupt vector.
  7524. This service is faster than hooking the V86 interrupt vector since the VMM
  7525. must intercept every V86 interrupt. This prevents a switch to V86 mode and
  7526. then back to Ring 0 for every V86 interrupt hook.  %@NL@%
  7527.  
  7528.  
  7529. %@3@%%@AB@%Example%@AE@%%@EH@%%@NL@%
  7530.  
  7531. Windows running in enhanced mode supports an API using software interrupt
  7532. 2FH. The code to handle the Release Time-Slice API looks like this:  %@NL@%
  7533.  
  7534. %@AS@%  Win386_Partial_API_initialization:
  7535. %@AS@%   mov      eax, 2fh
  7536. %@AS@%   mov      esi, OFFSET32 Win386_Partial_API_Hook
  7537. %@AS@%   VMMcall  Hook_V86_Int_Chain
  7538. %@AS@%   clc
  7539. %@AS@%   ret
  7540. %@AS@%  
  7541. %@AS@%  Win386_Partial_API_Hook
  7542. %@AS@%   cmp      [epb.Client_AX], 1680h
  7543. %@AS@%   je       SHORT W386_PA_Our_Call
  7544. %@AS@%   stc
  7545. %@AS@%   ret
  7546. %@AS@%  W386_PA_Our_Call:
  7547. %@AS@%   VMMcall  Release_Time_Slice
  7548. %@AS@%   clc
  7549. %@AS@%   ret%@AE@%
  7550.  
  7551. When %@AB@%Win386_Partial_API_Hook%@AE@% is called, it checks for 1680H in the VM's %@AB@%AX%@AE@%
  7552. register. If %@AB@%Client_AX%@AE@% <> 1680H, then it returns with Carry set, and the
  7553. interrupt will be reflected to the next handler in the interrupt chain.
  7554. However, if %@AB@%Client_AX%@AE@% = 1680H, then it releases the current virtual
  7555. machine's time-slice and consumes the interrupt by returning with Carry
  7556. clear.  %@NL@%
  7557.  
  7558.  
  7559. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7560.  
  7561. %@AB@%EAX%@AE@% = Interrupt # %@AB@%ESI%@AE@% Procedure to call  %@NL@%
  7562.  
  7563.  
  7564. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7565.  
  7566. If carry set then   ERROR: Invalid interrupt number else   Interrupt hook
  7567. installed  %@NL@%
  7568.  
  7569.  
  7570. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7571.  
  7572. Flags  %@NL@%
  7573.  
  7574.  
  7575. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  7576.  
  7577. %@AB@%EAX%@AE@% = Interrupt # %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  7578.  
  7579. If the callback procedure returns with carry clear then   The interrupt is
  7580. NOT passed to the next interrupt hook else (if carry set)   The interrupt is
  7581. passed to the next interrupt hook  %@NL@%
  7582.  
  7583. %@CR:C6A00210028 @%%@CR:C6A00210029 @%
  7584. %@2@%%@CR:C6A00210030 @%%@AB@%Set_PM_Int_Type%@AE@%%@EH@%%@NL@%
  7585. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7586.  
  7587.  
  7588. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7589.  
  7590. This service is used to specify if a PM interrupt vector should either be an
  7591. interrupt gate or trap gate type interrupt. Interrupt gate interrupts clear
  7592. the interrupt flag bit to disable interrupts when the interrupt occurs. Trap
  7593. gate interrupts don't modify the interrupt bit.  %@NL@%
  7594.  
  7595. All PM interrupts default to the trap gate type, but VxD's such as VPICD
  7596. need to change some of them to interrupt gates so that hardware interrupts
  7597. disable interrupts.  %@NL@%
  7598.  
  7599. Other software interrupts such as INT 21H are left as trap gates, so that
  7600. their handlers don't need to execute an STI and thus avoid the extra
  7601. overhead of an unnecessary ring transition.  %@NL@%
  7602.  
  7603.  
  7604. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7605.  
  7606. %@AB@%EAX%@AE@% = Interrupt number %@AB@%EDX%@AE@% = 0, if vector is a trap gate (interrupt flag is
  7607. not changed)   0, if vector is an interupt gate (interrupt flag is cleared)
  7608. %@NL@%
  7609.  
  7610.  
  7611. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7612.  
  7613. None  %@NL@%
  7614.  
  7615.  
  7616. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7617.  
  7618. Flags  %@NL@%
  7619.  
  7620. %@CR:C6A00210031 @%%@CR:C6A00210032 @%%@CR:C6A00210033 @%%@CR:C6A00210034 @%
  7621. %@2@%%@CR:C6A00210035 @%%@AB@%Set_V86_Int_Vector, Set_PM_Int_Vector%@AE@%%@EH@%%@NL@%
  7622. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7623.  
  7624.  
  7625. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7626.  
  7627. This service sets the current interrupt vector for the mode specified. If a
  7628. VxD calls %@AB@%Set_%@AE@%xxx%@AB@%_Int_Vector%@AE@% before the %@AB@%Sys_VM_Int%@AE@% control call is made,
  7629. then the installed handler will become part of the default interrupt vector
  7630. table. In other words, every VM will be created with interrupt vectors set
  7631. during enhanced Windows initialization. If this service is called after
  7632. %@AB@%Sys_VM_Init%@AE@%, then the handler will only be installed in the current virtual
  7633. machine.  %@NL@%
  7634.  
  7635.  
  7636. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7637.  
  7638. %@AB@%EAX%@AE@% = Interrupt number %@AB@%CX%@AE@% = CS to set into vector %@AB@%EDX%@AE@% = EIP to set interrupt
  7639. vector (for V86 mode and 16-bit protected mode programs the   `1`high word
  7640. should be zero)  %@NL@%
  7641.  
  7642.  
  7643. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7644.  
  7645. None  %@NL@%
  7646.  
  7647.  
  7648. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7649.  
  7650. Flags  %@NL@%
  7651.  
  7652. %@CR:C6A00210036 @%%@CR:C6A00210037 @%
  7653. %@2@%%@CR:C6A00210038 @%%@AB@%Simulate_Far_Call%@AE@%%@EH@%%@NL@%
  7654. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7655.  
  7656.  
  7657. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7658.  
  7659. This service places the current VM's %@AB@%CS:IP%@AE@% on the VM's stack and puts the
  7660. %@AB@%CS:IP%@AE@% specified in %@AB@%CX:EDX%@AE@% in the client frame. The next time the VM is
  7661. executed, it will be as if a FAR call had been inserted in the VM's
  7662. instruction stream.  %@NL@%
  7663.  
  7664. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  7665.  
  7666.  
  7667. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7668.  
  7669. %@AB@%CX%@AE@% = Segment of procedure to call %@AB@%EDX%@AE@% = Offset of procedure to call (high
  7670. word 0 if 16-bit application)  %@NL@%
  7671.  
  7672.  
  7673. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7674.  
  7675. %@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@%
  7676.  
  7677.  
  7678. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7679.  
  7680. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_SP%@AE@%, Flags ;  %@NL@%
  7681.  
  7682. %@CR:C6A00210039 @%%@CR:C6A00210040 @%
  7683. %@2@%%@CR:C6A00210041 @%%@AB@%Simulate_Far_Jmp%@AE@%%@EH@%%@NL@%
  7684. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7685.  
  7686.  
  7687. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7688.  
  7689. This service places the specified %@AB@%CS:IP%@AE@% into the VM's %@AB@%CS:IP%@AE@% to simulate a
  7690. FAR jmp instruction.  %@NL@%
  7691.  
  7692.  
  7693. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7694.  
  7695. %@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
  7696. or V86 apps)  %@NL@%
  7697.  
  7698.  
  7699. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7700.  
  7701. None  %@NL@%
  7702.  
  7703.  
  7704. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7705.  
  7706. %@AB@%Client_EIP%@AE@%, %@AB@%Client_CS%@AE@%, Flags  %@NL@%
  7707.  
  7708. %@CR:C6A00210042 @%%@CR:C6A00210043 @%
  7709. %@2@%%@CR:C6A00210044 @%%@AB@%Simulate_Far_Ret%@AE@%%@EH@%%@NL@%
  7710. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7711.  
  7712.  
  7713. %@3@%%@AB@%Decsription%@AE@%%@EH@%%@NL@%
  7714.  
  7715. This procedure pops the top two WORDs orDWORDs on the current VM's stack
  7716. into the client's %@AB@%CS:(E)IP%@AE@%.  %@NL@%
  7717.  
  7718. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  7719.  
  7720.  
  7721. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7722.  
  7723. None  %@NL@%
  7724.  
  7725.  
  7726. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7727.  
  7728. None  %@NL@%
  7729.  
  7730.  
  7731. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7732.  
  7733. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  7734.  
  7735. %@CR:C6A00210045 @%%@CR:C6A00210046 @%
  7736. %@2@%%@CR:C6A00210047 @%%@AB@%Simulate_Far_Ret_N%@AE@%%@EH@%%@NL@%
  7737. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7738.  
  7739.  
  7740. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7741.  
  7742. This procedure pops the top two WORDs or DWORDs on the current VM's stack
  7743. into the client's %@AB@%CS:(E)IP%@AE@%, then subtracts %@AB@%EAX%@AE@% from the VM's stack pointer.
  7744. %@NL@%
  7745.  
  7746. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  7747.  
  7748.  
  7749. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7750.  
  7751. %@AB@%EAX%@AE@% = Number of bytes to pop after far ret  %@NL@%
  7752.  
  7753.  
  7754. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7755.  
  7756. None  %@NL@%
  7757.  
  7758.  
  7759. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7760.  
  7761. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  7762.  
  7763. %@CR:C6A00210048 @%
  7764. %@2@%%@CR:C6A00210049 @%%@AB@%Simulate_Int%@CR:C6A00210050 @%%@AE@%%@EH@%%@NL@%
  7765. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7766.  
  7767.  
  7768. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7769.  
  7770. This service is used mainly by the Virtual Programmable Interrupt Controller
  7771. Device (VPICD) to simulate hardware interrupts. Most VxD writers will want
  7772. to use the %@AB@%Exec_Int%@AE@% service to simulate interrupts.  %@NL@%
  7773.  
  7774. This service has exactly the same effect as a VM executing an %@AB@%Int nn%@AE@%
  7775. instruction. All VxD interrupt chain hooks are called and, if the interrupt
  7776. is not consumed by one of these hooks, an IRET frame is built on the VM's
  7777. stack. Notice, however, that the VM interrupt code will not be executed
  7778. until the enhanced Windows environment returns to the virtual machine. If
  7779. you want to %@AI@%execute%@AE@% an interrupt, then you should use the nested execution
  7780. services (%@AB@%Exec_Int%@AE@%).  %@NL@%
  7781.  
  7782. This service is mode sensitive. Therefore, if the VM is currently in V86
  7783. mode, then a V86 interrupt will be simulated. Otherwise, a PM interrupt will
  7784. be simulated. Since reflecting a PM interrupt may force a mode change to V86
  7785. mode, VxD writers must be very careful when calling this service while
  7786. running a protected-mode application.  %@NL@%
  7787.  
  7788.  
  7789. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7790.  
  7791. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  7792.  
  7793.  
  7794. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7795.  
  7796. If %@AB@%Simulate_Int%@AE@% is called while running a PM application and the PM
  7797. interrupt vector is not hooked, then the mode is changed to V86.  %@NL@%
  7798.  
  7799.  
  7800. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7801.  
  7802. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  7803.  
  7804. %@CR:C6A00210051 @%%@CR:C6A00210052 @%
  7805. %@2@%%@CR:C6A00210053 @%%@AB@%Simulate_Iret%@AE@%%@EH@%%@NL@%
  7806. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7807.  
  7808.  
  7809. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7810.  
  7811. This service pops the values at the top of the current VM's stack into the
  7812. current VM's %@AB@%CS:IP%@AE@% and flags. If the current VM is a 32-bit protected-mode
  7813. application, then this service will pop three DWORDs instead of WORDs
  7814. (simulate an IRETD).  %@NL@%
  7815.  
  7816. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  7817.  
  7818.  
  7819. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7820.  
  7821. None  %@NL@%
  7822.  
  7823.  
  7824. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7825.  
  7826. None  %@NL@%
  7827.  
  7828.  
  7829. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7830.  
  7831. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, %@AB@%Client_ESP%@AE@%, %@AB@%Client_Flags%@AE@%, Flags  %@NL@%
  7832.  
  7833.  
  7834.  
  7835.  
  7836.  
  7837.  
  7838. %@CR:C6A00220001 @%%@1@%%@AB@%Chapter 22  Nested Execution Services%@AE@%%@EH@%%@NL@%
  7839. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7840.  
  7841. These services provide a way for VxDs to call routines in a VM. Notice that
  7842. the VxD must make sure that the service being called is in a callable state
  7843. (i.e., you must not reenter services that do not expect to be reentered).
  7844. The services are described here in alphabetical order.  %@NL@%
  7845.  
  7846.  
  7847.   ■   %@AB@%Begin_Nest_Exec%@AE@%%@NL@%
  7848.  
  7849.   ■   %@AB@%Begin_Nest_V86_Exec%@AE@%%@NL@%
  7850.  
  7851.   ■   %@AB@%Begin_Use_Locked_PM_Stack%@AE@%%@NL@%
  7852.  
  7853.   ■   %@AB@%End_Nest_Exec%@AE@%%@NL@%
  7854.  
  7855.   ■   %@AB@%End_Use_Locked_PM_Stack%@AE@%%@NL@%
  7856.  
  7857.   ■   %@AB@%Exec_Stack%@AE@%%@NL@%
  7858.  
  7859.   ■   %@AB@%Exec_VxD_Int%@AE@%%@NL@%
  7860.  
  7861.   ■   %@AB@%Restore_Client_State%@AE@%%@NL@%
  7862.  
  7863.   ■   %@AB@%Resume_Exec%@AE@%%@NL@%
  7864.  
  7865.   ■   %@AB@%Save_Client_State%@AE@%%@NL@%
  7866.  
  7867.   ■   %@AB@%Set_PM_Exec_Mode%@AE@%%@NL@%
  7868.  
  7869.   ■   %@AB@%Set_V86_Exec_Mode%@AE@%%@NL@%
  7870.  
  7871.  
  7872. %@CR:C6A00220002 @%%@CR:C6A00220003 @%
  7873. %@2@%%@CR:C6A00220004 @%%@AB@%Begin_Nest_Exec%@AE@%%@EH@%%@NL@%
  7874. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7875.  
  7876.  
  7877. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7878.  
  7879. This service is used by VxDs that need to call software in a VM.  %@NL@%
  7880.  
  7881. For example:  %@NL@%
  7882.  
  7883. %@AS@%  VMMcall Begin_Nest_Exec   ; Start nested execution
  7884. %@AS@%   mov     [ebp.Client_AH], 30h  ; 30h = Get MS-DOS Version #
  7885. %@AS@%   mov     eax, 21h    ; Execute an Int 21h in the
  7886. %@AS@%   VMMcall Exec_Int    ; current VM to call MS-DOS
  7887. %@AS@%   VMMcall End_Nest_Exec   ; End of nested exec calls%@AE@%
  7888.  
  7889. This will make the MS-DOS %@AB@%Get_Version%@AE@% call. The version will be in the
  7890. %@AB@%Client_AH%@AE@% and %@AB@%Client_AL%@AE@% registers.  %@NL@%
  7891.  
  7892. This service only works for the current VM. The VM registers changed by the
  7893. call Will be changes in the VM. If you want to save and restore a VM's
  7894. registers you should use the %@AB@%Save_Client_ State%@AE@% and %@AB@%Restore_Client_State%@AE@%
  7895. services or the %@AB@%Push_Client_State%@AE@% and %@AB@%Pop_Client_State%@AE@% macros documneted
  7896. under %@AB@%Save_Client_State%@AE@% and %@AB@%Restore_Client_State%@AE@%.  %@NL@%
  7897.  
  7898. You may execute any number of interrupts between a %@AB@%Begin/End_Nest_Exec%@AE@% pair.
  7899. For example the following is valid:  %@NL@%
  7900.  
  7901. %@AS@%  Push_Client_State
  7902. %@AS@%      VMMcall Begin_Nest_Exec
  7903. %@AS@%      ...
  7904. %@AS@%      VMMcall Exec_Int
  7905. %@AS@%      ...
  7906. %@AS@%      VMMcall Exec_Int
  7907. %@AS@%      ...
  7908. %@AS@%      VMMcall Simulate_Far_Call
  7909. %@AS@%      VMMcall Resume_Exec
  7910. %@AS@%      ...
  7911. %@AS@%      VMMcall Exec_Int
  7912. %@AS@%      VMMcall End_Nest_Exec
  7913. %@AS@%      Pop_Client_State%@AE@%
  7914.  
  7915. This service will force the VM into protected-mode execution if there is a
  7916. protected-mode application running in the current VM. If there is no
  7917. protected mode application, then the VM will remain in V86 mode. When
  7918. %@AB@%End_Nest_Exec%@AE@% is called, the VM will be returned to whatever mode it was in
  7919. when %@AB@%Begin_Nest_Exec %@AE@%was called. For more information on what is entailed in
  7920. a mode switch refer to the documentation for %@AB@%Set_PM_Exec_Mode%@AE@% and
  7921. %@AB@%Set_V86_Exec_Mode%@AE@% later in this chapter.  %@NL@%
  7922.  
  7923. If there is a protected-mode application in the current VM, then this
  7924. service will automatically switch the VM to the locked PM stack (and
  7925. %@AB@%End_Nest_Exec%@AE@% will switch it back). This allows most devices to change
  7926. execution modes without worrying about demand paging issues.  %@NL@%
  7927.  
  7928.  
  7929. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7930.  
  7931. None  %@NL@%
  7932.  
  7933.  
  7934. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7935.  
  7936. %@AB@%Client_CS:IP%@AE@% contains a break point (used by nested exec services).  %@NL@%
  7937.  
  7938. If a protected mode application is running then  VM execution mode is
  7939. protected mode else  VM execution mode is Virtual-8086 mode %@AB@%Exec_Int%@AE@% and
  7940. %@AB@%Resume_Exec%@AE@% services may be called.  %@NL@%
  7941.  
  7942.  
  7943. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  7944.  
  7945. %@AB@%Client_CS%@AE@%, %@AB@%Client_IP%@AE@%, Flags  %@NL@%
  7946.  
  7947. %@CR:C6A00220005 @%%@CR:C6A00220006 @%
  7948. %@2@%%@CR:C6A00220007 @%%@AB@%Begin_Nest_V86_Exec%@AE@%%@EH@%%@NL@%
  7949. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7950.  
  7951.  
  7952. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7953.  
  7954. This service will set the the current VM in Virtual-8086 mode and prepare
  7955. the VM for nested execution. This service is normally used by VxDs that want
  7956. to convert protected mode calls into V86 calls. For example, the DOSMGR
  7957. device uses this call to map INT 21H MS-DOS calls issued from protected mode
  7958. programs into Virtual-8086 mode MS-DOS calls.  %@NL@%
  7959.  
  7960. This call, like %@AB@%Begin_Nest_Exec%@AE@%, saves the current execution mode of the
  7961. virtual machine (either V86 or PM), and %@AB@%End_Nest_Exec%@AE@% will restore the mode.
  7962. %@NL@%
  7963.  
  7964.  
  7965. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  7966.  
  7967. None  %@NL@%
  7968.  
  7969.  
  7970. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  7971.  
  7972. %@AB@%Client_CS:IP%@AE@% contains a break point (used by nested exec services) VM is in
  7973. Virtual 8086 mode. %@AB@%Exec_Int%@AE@% and %@AB@%Resume_Exec %@AE@%services may be called.  %@NL@%
  7974.  
  7975.  
  7976. %@3@%%@AB@%USES%@AE@%%@EH@%%@NL@%
  7977.  
  7978. %@AB@%Client_CS%@AE@%, %@AB@%Client_IP%@AE@%, Flags  %@NL@%
  7979.  
  7980. %@CR:C6A00220008 @%%@CR:C6A00220009 @%
  7981. %@2@%%@CR:C6A00220010 @%%@AB@%Begin_Use_Locked_PM_Stack%@AE@%%@EH@%%@NL@%
  7982. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7983.  
  7984.  
  7985. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  7986.  
  7987. This service is used by VxDs that need to ensure that a protectedmode
  7988. program is running on a stack that will not be demand paged. Most devices
  7989. can rely on %@AB@%Begin_Nest_Exec%@AE@% to switch stacks automatically, and so this
  7990. service is only important for devices, such as the Virtual Programmable
  7991. Interrupt Controller Device (VPICD), which explicitly changes the execution
  7992. mode of a VM.  %@NL@%
  7993.  
  7994. A call to this service must be followed by a call to
  7995. %@AB@%End_Use_Locked_PM_Stack%@AE@%. Note that this service may be called repeatedly,
  7996. but only the first call will switch stacks. Subsequent calls will increment
  7997. a counter but remain on the current locked stack.  %@NL@%
  7998.  
  7999.  
  8000. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8001.  
  8002. Current execution mode of VM must be protected mode (%@AB@%VMStat_PM_Exec%@AE@% status
  8003. bit must be set).  %@NL@%
  8004.  
  8005.  
  8006. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8007.  
  8008. If locked stack not already in use then  Client's SS:SP will be changed to
  8009. locked protected mode stack else  Client's SS:SP will be unchanged  %@NL@%
  8010.  
  8011.  
  8012. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8013.  
  8014. Flags  %@NL@%
  8015.  
  8016. %@CR:C6A00220011 @%
  8017. %@2@%%@CR:C6A00220012 @%%@AB@%End_Nest_Exec%@CR:C6A00220013 @%%@AE@%%@EH@%%@NL@%
  8018. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8019.  
  8020.  
  8021. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8022.  
  8023. This service must be called after a call to %@AB@%Begin_Nest_Exec%@AE@%. A VxD must
  8024. never return to the VMM while still in nested execution. If %@AB@%Begin_Nest_Exec%@AE@%
  8025. changed the execution mode of the VM then this service will restore it to
  8026. the previous mode. Notice that this service %@AI@%will%@AE@% %@AI@%not%@AE@% restore the client's
  8027. registers (except %@AB@%CS:IP%@AE@%) to the values they were when %@AB@%Begin_Nest_Exec %@AE@%was
  8028. called. If you need to preserve the VM's registers, you must use the
  8029. %@AB@%Push_Client_State%@AE@% and %@AB@%Pop_Client_State%@AE@% macros.  %@NL@%
  8030.  
  8031.  
  8032. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8033.  
  8034. None  %@NL@%
  8035.  
  8036.  
  8037. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8038.  
  8039. VM execution mode restored to previous execution mode (before
  8040. %@AB@%Begin_Nest_Exec%@AE@% was called) Client's original %@AB@%CS:IP%@AE@% restored  %@NL@%
  8041.  
  8042.  
  8043. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8044.  
  8045. %@AB@%Client_CS%@AE@%, %@AB@%Client_IP%@AE@%, Flags  %@NL@%
  8046.  
  8047. %@CR:C6A00220014 @%%@CR:C6A00220015 @%
  8048. %@2@%%@CR:C6A00220016 @%%@AB@%End_Use_Locked_PM_Stack%@AE@%%@EH@%%@NL@%
  8049. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8050.  
  8051.  
  8052. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8053.  
  8054. This service must be called once for every call made to
  8055. %@AB@%Begin_Use_Locked_PM_Stack.%@AE@% It will decrement the locked stack use counter
  8056. and, if it is decremented to zero then it will switch the VM back to its
  8057. original %@AB@%SS:SP%@AE@%.  %@NL@%
  8058.  
  8059.  
  8060. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8061.  
  8062. None  %@NL@%
  8063.  
  8064.  
  8065. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8066.  
  8067. If locked stack count decremented to 0 then  Client's SS:SP will be restored
  8068. to original values before  %@AB@%Begin_Use_Locked_PM_Stack%@AE@% was called. else
  8069. Client's SS:SP will be unchanged  %@NL@%
  8070.  
  8071.  
  8072. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8073.  
  8074. Flags  %@NL@%
  8075.  
  8076. %@CR:C6A00220017 @%
  8077. %@2@%%@CR:C6A00220018 @%%@AB@%Exec_Int%@CR:C6A00220019 @%%@AE@%%@EH@%%@NL@%
  8078. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8079.  
  8080.  
  8081. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8082.  
  8083. You must call %@AB@%Begin_Nest_Exec%@AE@% or %@AB@%Begin_Nest_V86_Exec%@AE@% before calling this
  8084. service. It may be called any number of times between a %@AB@%Begin_Nest_Exec%@AE@% and
  8085. %@AB@%End_Nest_Exec%@AE@% pair.  %@NL@%
  8086.  
  8087. This service simulates an interrupt and then resumes VM execution. It has
  8088. exactly the same effect as calling:  %@NL@%
  8089.  
  8090. %@AS@%  mov     eax, (Int #)
  8091. %@AS@%      VMMcall Simulate_Int
  8092. %@AS@%      VMMcall Resume_Exec%@AE@%
  8093.  
  8094. Since most nested execution calls simulate interrupts, this service is
  8095. provided for convenience. See %@AB@%Resume_Exec%@AE@% later in this chapter for more
  8096. details on how this service is used.  %@NL@%
  8097.  
  8098.  
  8099. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8100.  
  8101. %@AB@%EAX%@AE@% = # of interrupt to execute  %@NL@%
  8102.  
  8103.  
  8104. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8105.  
  8106. Interrupt has been executed  %@NL@%
  8107.  
  8108.  
  8109. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8110.  
  8111. Flags  %@NL@%
  8112.  
  8113. %@CR:C6A00220020 @%
  8114. %@2@%%@CR:C6A00220021 @%%@AB@%Exec_VxD_Int%@CR:C6A00220022 @%%@AE@%%@EH@%%@NL@%
  8115. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8116.  
  8117.  
  8118. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8119.  
  8120. This service is used by virtual devices to call MS-DOS or BIOS services as
  8121. though they were an application program. For example, the following code
  8122. gets the current MS-DOS version:  %@NL@%
  8123.  
  8124. %@AS@%  mov     ax, 3000h
  8125. %@AS@%      push    DWORD PTR 21h
  8126. %@AS@%      VMMcall Exec_VxD_Int
  8127. %@AS@%      (AL = Major MS-DOS version, AL = Minor MS-DOS version)%@AE@%
  8128.  
  8129. All MS-DOS and BIOS calls that are supported in protected-mode programs will
  8130. be supported by this service. The VM's registers and flags will not be
  8131. changed by this service so there is no need for the caller to save and
  8132. restore the client register structure. The interrupt number on the stack
  8133. will be removed by this service so the caller should %@AI@%not%@AE@% add four to %@AB@%ESP%@AE@%
  8134. after calling this service.  %@NL@%
  8135.  
  8136. To make calling this service easier, a macro called %@AB@%VxDint%@AE@% is defined in
  8137. VMM.INC as follows:  %@NL@%
  8138.  
  8139. %@AS@%  VxDint  MACRO   Int_Number
  8140. %@AS@%        push    Int_Number
  8141. %@AS@%        VMMcall Exec_VxD_Int
  8142. %@AS@%        ENDM %@AE@%
  8143.  
  8144. This service makes it possible to write code in a VxD that is very similar
  8145. to real mode code. For example, below is the code that opens a file named
  8146. "FOO.TXT" and reads the first 100 bytes:  %@NL@%
  8147.  
  8148. %@AS@%  VxD_DATA_SEG
  8149. %@AS@%   Foo_File_Name   db "FOO.TXT", 0
  8150. %@AS@%   Read_Buffer     db 100 dup (?)
  8151. %@AS@%  VxD_DATA_ENDS%@AE@%
  8152.  
  8153. %@AS@%  VxD_CODE_SEG
  8154. %@AS@%   BeginProc Sample_File_Read
  8155. %@AS@%     mov     ax, 3D00h   ; Open file with handle
  8156. %@AS@%     mov     edx, OFFSET32 Foo_File_Name  ; DS:EDX - File name
  8157. %@AS@%      VxDint  21h     ; Call MS-DOS
  8158. %@AS@%     jc      Error   ; If carry then error
  8159. %@AS@%          ; else AX = File handle
  8160. %@AS@%      mov     bx, ax    ; BX = File handle
  8161. %@AS@%     mov     ecx, 100    ; Read 100 bytes
  8162. %@AS@%     mov     edx, OFFSET32 Read_Buffer ; Into this buffer
  8163. %@AS@%      mov     ah, 3Fh    ; MS-DOS Read
  8164. %@AS@%     VxDint  21h     ; Call MS-DOS
  8165. %@AS@%      jc      Error   ; Error if carry else
  8166. %@AS@%          ; EAX = # bytes read
  8167. %@AS@%     (Do stuff with the data here)%@AE@%
  8168.  
  8169. %@AS@%  EndProc Sample_File_Read
  8170. %@AS@%  VxD_CODE_ENDS%@AE@%
  8171.  
  8172.  
  8173. %@3@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  8174.  
  8175. Interrupts will only be routed through VxD interrupt hooks. They will bypass
  8176. any hook the application has installed in protected mode. This may be a
  8177. problem, for example, if an application hooks INT 21h to watch for a file
  8178. open and, then, a VxD uses this service to open a file (the application
  8179. would not see the file open). Do not use this service until the
  8180. %@AB@%Init_Complete%@AE@% control call is made.  %@NL@%
  8181.  
  8182. Do not change %@AB@%DS%@AE@% or %@AB@%ES%@AE@% before calling this service. You should always use
  8183. the ring 0 linear address of the data instead of changing the selector
  8184. value. This may require using the %@AB@%_SelectorMapFlat%@AE@% service to determine the
  8185. base of a selector.  %@NL@%
  8186.  
  8187. Do not call services that will change %@AB@%DS%@AE@% or %@AB@%ES%@AE@%. Mappers should return valid
  8188. pointers without changing the segment register value, but calls that
  8189. explicitly change the %@AB@%DS%@AE@% or %@AB@%ES%@AE@% selectors should never be called. For
  8190. example, if a call returns a pointer in %@AB@%DS:(E)DX%@AE@% then this would be OK to
  8191. call since the mapper would convert the ponter to use the ring 0 linear
  8192. address in %@AB@%EDX%@AE@% without modifying %@AB@%DS%@AE@%. However, if a service returns a
  8193. selector only then you should not use %@AB@%Exec_VxD_Int %@AE@%to call it. This can
  8194. normally be made to work by using code similar to the following:  %@NL@%
  8195.  
  8196. %@AS@%  Push_Client_State
  8197. %@AS@%    VMMcall Begin_Nest_(V86_)Exec
  8198. %@AS@%    . . .
  8199. %@AS@%    (Fiddle with client registers)
  8200. %@AS@%    . . .
  8201. %@AS@%    VMMcall Exec_Int
  8202. %@AS@%    . . .
  8203. %@AS@%    (Get segments/selectors)
  8204. %@AS@%    . . .
  8205. %@AS@%    VMMcall End_Nest_Exec
  8206. %@AS@%    Pop_Client_State%@AE@%
  8207.  
  8208.  
  8209. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8210.  
  8211. DWORD at [ESP+4] is number of interrupt to execute  %@NL@%
  8212.  
  8213.  
  8214. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8215.  
  8216. All registers and flags modified by interrupt will be changed. The interrupt
  8217. number on the stack will have been removed.  %@NL@%
  8218.  
  8219.  
  8220. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8221.  
  8222. All registers and flags modified by interrupt will be changed.  %@NL@%
  8223.  
  8224. %@CR:C6A00220023 @%%@CR:C6A00220024 @%
  8225. %@2@%%@CR:C6A00220025 @%%@AB@%Restore_Client_State%@AE@%%@EH@%%@NL@%
  8226. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8227.  
  8228.  
  8229. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8230.  
  8231. This service restores a VM execution state that was saved using the
  8232. %@AB@%Save_Client_State%@AE@% service. If the client state was saved using the
  8233. %@AB@%Push_Client_State%@AE@% macro then you should use %@AB@%Pop_Client_State%@AE@% to restore the
  8234. VM's execution state. The %@AB@%Pop_Client_State%@AE@% macro looks like:  %@NL@%
  8235.  
  8236. %@AS@%  Pop_Client_State MACRO
  8237. %@AS@%       push    esi
  8238. %@AS@%       lea     esi, [esp+4]
  8239. %@AS@%       VMMcall Restore_Client_State
  8240. %@AS@%       pop     esi
  8241. %@AS@%       add     esp, SIZE Client_Reg_Struc
  8242. %@AS@%      ENDM%@AE@%
  8243.  
  8244. Notice that this service can have side effects if it is not used carefully.
  8245. For instance, it will change modes from V86 to protected mode or from
  8246. protected to V86 mode if the state being restored is in a different
  8247. execution mode from the current one. Also, it may change the state of the
  8248. current virtual machine's interrupt flag and so it may cause callbacks to
  8249. events scheduled through the %@AB@%Call_When_VM_Ints_Enabled%@AE@% or
  8250. %@AB@%Call_Priority_VM_Event%@AE@% services.  %@NL@%
  8251.  
  8252.  
  8253. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8254.  
  8255. %@AB@%ESI %@AE@%-> Buffer  %@NL@%
  8256.  
  8257.  
  8258. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8259.  
  8260. VM execution state is restored  %@NL@%
  8261.  
  8262.  
  8263. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8264.  
  8265. Flags  %@NL@%
  8266.  
  8267. %@CR:C6A00220026 @%
  8268. %@2@%%@CR:C6A00220027 @%%@AB@%Resume_Exec%@CR:C6A00220028 @%%@AE@%%@EH@%%@NL@%
  8269. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8270.  
  8271.  
  8272. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8273.  
  8274. You must call %@AB@%Begin_Nest_Exec%@AE@% or %@AB@%Begin_Nest_V86_Exec%@AE@% before calling this
  8275. service. It may be called any number of times between a %@AB@%Begin_Nest_Exec%@AE@% and
  8276. %@AB@%End_Nest_Exec%@AE@% pair.  %@NL@%
  8277.  
  8278. This service immediately executes the current VM. When the VM returns to the
  8279. same point it was at when %@AB@%Begin_ Nest_Exec%@AE@% was called, this service will
  8280. return. The following example:  %@NL@%
  8281.  
  8282. %@AS@%  Push_Client_State
  8283. %@AS@%   VMMcall  Begin_Nest_Exec
  8284. %@AS@%   mov  cx, [Target_CS]
  8285. %@AS@%   mov  eax, [Target_CS_EIP]
  8286. %@AS@%   VMMcall  Simulate_Far_Call
  8287. %@AS@%   VMMcall Resume_Exec
  8288. %@AS@%    (Examine results returnd in Client registers) 
  8289. %@AS@%   VMMcall End_Nest_Exec
  8290. %@AS@%  Pop_Client_State%@AE@%
  8291.  
  8292. will return when the called procedure returns.The following code will
  8293. process any outstanding events and immediately return:  %@NL@%
  8294.  
  8295. %@AS@%  VMMcall Begin_Nest_Exec
  8296. %@AS@%   VMMcall Resume_Exec
  8297. %@AS@%   VMMcall End_Nest_Exec%@AE@%
  8298.  
  8299. Since the %@AB@%Resume_Exec%@AE@% resumes execution at the same point that
  8300. %@AB@%Begin_Nest_Exec%@AE@% was called it will return immediately.  %@NL@%
  8301.  
  8302. This service is also useful for VxDs that must wait for an external event
  8303. (such as a hardware interrupt) to occur before returning to the VM. Since
  8304. %@AB@%Resume_Exec%@AE@% allows outstanding events to be processed, simulated harware
  8305. interrupts can be sent to the VM while waiting:  %@NL@%
  8306.  
  8307. %@AS@%  (Push_Client_State is not needed)
  8308. %@AS@%   VMMcall Begin_Nest_Exec
  8309. %@AS@%   Wait_Loop:
  8310. %@AS@%   test  [My_Status], Done
  8311. %@AS@%   je  Exit_My_Wait_Loop
  8312. %@AS@%   VMMcall Resume_Exec
  8313. %@AS@%   VMMcall Release_Time_Slice
  8314. %@AS@%   jmp  My_Wait_Loop 
  8315. %@AS@%   Exit_Wait_Loop:
  8316. %@AS@%   VMMcall  End_Nest_Exec
  8317. %@AS@%   (Pop_Client_State is not needed)%@AE@%
  8318.  
  8319. Notice that you do not need to save and restore the client registers in this
  8320. loop since simulated hardware interrupts and events will not modify the
  8321. client registers. You should only use the %@AB@%Push/ Pop_Client_State%@AE@% macros when
  8322. your VxD code explicitly calls code in a VM or directly modifies any client
  8323. register.  %@NL@%
  8324.  
  8325. This service and %@AB@%Exec_Int%@AE@% may be called multiple times in between calls to
  8326. Begin/End nest exec. For example the following code is valid:  %@NL@%
  8327.  
  8328. %@AS@%  Push_Client_State
  8329. %@AS@%    VMMcall Begin_Nest_Exec
  8330. %@AS@%    mov eax, (Int #)
  8331. %@AS@%    VMMcall Exec_Int
  8332. %@AS@%    mov cx, [Target_CS]
  8333. %@AS@%    mov eax, [Target_CS_EIP]
  8334. %@AS@%    VMMcall Simulate_Far_Call
  8335. %@AS@%    VMMcall Resume_Exec
  8336. %@AS@%    VMMcall End_Nest_Exec
  8337. %@AS@%    Pop_Client_State%@AE@%
  8338.  
  8339. Since events are processed when %@AB@%Resume_Exec%@AE@% (or %@AB@%Exec_Int%@AE@%) is called, a task
  8340. switch may occur.  %@NL@%
  8341.  
  8342.  
  8343. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8344.  
  8345. None  %@NL@%
  8346.  
  8347.  
  8348. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8349.  
  8350. None  %@NL@%
  8351.  
  8352.  
  8353. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8354.  
  8355. Flags  %@NL@%
  8356.  
  8357. %@CR:C6A00220029 @%%@CR:C6A00220030 @%
  8358. %@2@%%@CR:C6A00220031 @%%@AB@%Save_Client_State%@AE@%%@EH@%%@NL@%
  8359. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8360.  
  8361.  
  8362. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8363.  
  8364. This service will copy the contents of the current VM's Client Register
  8365. Structure to the specified buffer. The buffer must be the size of the
  8366. structure named %@AB@%Client_Reg_Struc%@AE@% which is defined in VMM.INC. The saved
  8367. state can later be restored by calling %@AB@%Restore_Client_State.%@AE@%  %@NL@%
  8368.  
  8369. Most of the time, it is easier to use the %@AB@%Push_Client_State %@AE@%macro than to
  8370. call this service directly. %@AB@%Push_Client_State%@AE@% copies the client's state onto
  8371. the protected mode stack. The macro code is as follows:  %@NL@%
  8372.  
  8373. %@AS@%  Push_Client_State MACRO
  8374. %@AS@%    sub     esp, SIZE Client_Reg_Struc
  8375. %@AS@%    push    edi
  8376. %@AS@%    lea     edi, [esp+4]
  8377. %@AS@%    VMMcall Save_Client_State
  8378. %@AS@%    pop     edi
  8379. %@AS@%    ENDM%@AE@%
  8380.  
  8381. As you can see, this macro will reserve space on the caller's stack for the
  8382. buffer. You must use the %@AB@%Pop_Client_State%@AE@% macro to get rid of the contents
  8383. saved on your stack. The macro will not change any registers.  %@NL@%
  8384.  
  8385. This service is typically used by VxDs that need to make calls to code in a
  8386. virtual machine that are unrelated to the current VM's thread of execution.
  8387. For example, the demand paging device (PageSwap) does the following:  %@NL@%
  8388.  
  8389. %@AS@%  Push_Client_State
  8390. %@AS@%      VMMcall Begin_Nest_Exec
  8391. %@AS@%      . . .
  8392. %@AS@%      (Perform disk I/O)
  8393. %@AS@%      . . .
  8394. %@AS@%      VMMcall End_Nest_Exec
  8395. %@AS@%      Pop_Client_State%@AE@%
  8396.  
  8397. Notice that the %@AB@%Push_Client_State%@AE@% macro is placed %@AI@%before%@AE@% the call to
  8398. %@AB@%Begin_Nest_Exec%@AE@% and the %@AB@%Pop_Client_State%@AE@% macro is %@AI@%after%@AE@% the call to
  8399. %@AB@%End_Nest_Exec%@AE@%. Any other combination would probably crash enhanced Windows.
  8400. %@NL@%
  8401.  
  8402. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8403. %@AU@%WARNING%@AE@%
  8404.  
  8405. Always use this service to save the client state. Don't just copy the VM's
  8406. client register structure and later copy it back as this will almost
  8407. certianly cause enhanced Windows to hang or crash. 
  8408. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8409.  
  8410.  
  8411. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8412.  
  8413. %@AB@%EDI%@AE@% -> Buffer  %@NL@%
  8414.  
  8415.  
  8416. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8417.  
  8418. Buffer contains a copy of the current VM's client register structure  %@NL@%
  8419.  
  8420.  
  8421. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8422.  
  8423. Flags  %@NL@%
  8424.  
  8425. %@CR:C6A00220032 @%%@CR:C6A00220033 @%
  8426. %@2@%%@CR:C6A00220034 @%%@AB@%Set_PM_Exec_Mode%@AE@%%@EH@%%@NL@%
  8427. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8428.  
  8429.  
  8430. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8431.  
  8432. This service forces the current VM into protected mode. Most devices will
  8433. want to use %@AB@%Begin_Nest_Exec%@AE@% instead of this service.  %@NL@%
  8434.  
  8435. Changing the execution mode of a VM will not change the VM's %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  8436. %@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
  8437. 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
  8438. previous values for protected mode.  %@NL@%
  8439.  
  8440. If the current VM is already in protected mode, then this service has no
  8441. effect.  %@NL@%
  8442.  
  8443.  
  8444. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8445.  
  8446. None  %@NL@%
  8447.  
  8448.  
  8449. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8450.  
  8451. VM is in PM execution mode  %@NL@%
  8452.  
  8453.  
  8454. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8455.  
  8456. Flags  %@NL@%
  8457.  
  8458. %@CR:C6A00220035 @%%@CR:C6A00220036 @%
  8459. %@2@%%@CR:C6A00220037 @%%@AB@%Set_V86_Exec_Mode%@AE@%%@EH@%%@NL@%
  8460. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8461.  
  8462.  
  8463. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8464.  
  8465. This service forces the current VM into V86 mode. Most VxDs will want to use
  8466. %@AB@%Begin_Nest_V86_Exec%@AE@% instead of this service.  %@NL@%
  8467.  
  8468. Changing the execution mode of a VM will not change the VM's %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  8469. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and %@AB@%EBP%@AE@% registers or most flags. The VM flag and IOPL flags
  8470. 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
  8471. previous values for V86 mode.  %@NL@%
  8472.  
  8473. If the current VM is already in V86 mode, then this service has no effect.  %@NL@%
  8474.  
  8475.  
  8476. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8477.  
  8478. None  %@NL@%
  8479.  
  8480.  
  8481. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8482.  
  8483. VM is in V86 execution mode  %@NL@%
  8484.  
  8485.  
  8486. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8487.  
  8488. Flags  %@NL@%
  8489.  
  8490.  
  8491.  
  8492.  
  8493.  
  8494.  
  8495. %@CR:C6A00230001 @%%@1@%%@AB@%Chapter 23  Break Point and Callback Services%@AE@%%@EH@%%@NL@%
  8496. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8497.  
  8498. The services described in this chapter are used to handle breakpoint and
  8499. callback procedures.  %@NL@%
  8500.  
  8501. The discussion of these services is presented in the following order:  %@NL@%
  8502.  
  8503.  
  8504.   ■   %@AB@%Allocate_V86_Call_Back%@AE@%%@NL@%
  8505.  
  8506.   ■   %@AB@%Allocate_PM_Call_Back%@AE@%%@NL@%
  8507.  
  8508.   ■   %@AB@%Call_When_Idle%@AE@%%@NL@%
  8509.  
  8510.   ■   %@AB@%Call_When_VM_Returns%@AE@%%@NL@%
  8511.  
  8512.   ■   %@AB@%Install_V86_Break_Point%@AE@%%@NL@%
  8513.  
  8514.   ■   %@AB@%Remove_V86_Break_Point%@AE@%%@NL@%
  8515.  
  8516.  
  8517. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  8518. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  8519.  
  8520. %@CR:C6A00230002 @%%@CR:C6A00230003 @%%@CR:C6A00230004 @%%@CR:C6A00230005 @%
  8521. %@2@%%@CR:C6A00230006 @%%@AB@%Allocate_V86_Call_Back, Allocate_PM_Call_Back%@AE@%%@EH@%%@NL@%
  8522. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8523.  
  8524.  
  8525. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8526.  
  8527. A %@AI@%V86 callback%@AE@% is used to transition from V86 mode into a protected mode
  8528. VxD. The callback is a SEGMENT:OFFSET that, when executed by a V86 machine,
  8529. will cause a procedure in a virtual device to be called.  %@NL@%
  8530.  
  8531. A %@AI@%PM callback%@AE@% is used to transition from a protected-mode application to a
  8532. VxD. The callback is a SELECTOR:OFFSET that, when executed, will cause a
  8533. procedure in a virtual device to be called.  %@NL@%
  8534.  
  8535. These services are typically used by devices that need to be called by
  8536. software running in a virtual machine. When the VM software calls the
  8537. callback address, the VxD gets control and can service the VM's request.  %@NL@%
  8538.  
  8539. %@AS@%  Initialization:
  8540. %@AS@%    mov edx, My_Ref_Data
  8541. %@AS@%    mov esi, OFFSET33 My_API_Procedure
  8542. %@AS@%    VMMcall Allocate_V86_Call_Back
  8543. %@AS@%    mov [My_V86_Call_Back], eax
  8544. %@AS@%    mov [ebp.Client_DI], ax
  8545. %@AS@%    shr eax, 16
  8546. %@AS@%    mov [ebp.Client_ES], ax 
  8547. %@AS@%   ret%@AE@%
  8548.  
  8549. %@AS@%  My_API_Procedure:
  8550. %@AS@%   . . . (Do something here) . . .
  8551. %@AS@%   VMMcall Simulate_Far_Ret
  8552. %@AS@%   ret%@AE@%
  8553.  
  8554.  
  8555. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8556.  
  8557. %@AB@%EDX%@AE@% = Reference data (any DWORD) %@AB@%ESI%@AE@% = Procedure to call  %@NL@%
  8558.  
  8559.  
  8560. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8561.  
  8562. %@AB@%EAX%@AE@% = CS:IP of V86 callback address  %@NL@%
  8563.  
  8564.  
  8565. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8566.  
  8567. %@AB@%EAX%@AE@%, Flags  %@NL@%
  8568.  
  8569.  
  8570. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8571.  
  8572. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Current VM's client
  8573. register structure  %@NL@%
  8574.  
  8575. %@CR:C6A00230007 @%%@CR:C6A00230008 @%
  8576. %@2@%%@CR:C6A00230009 @%%@AB@%Call_When_Idle%@AE@%%@EH@%%@NL@%
  8577. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8578.  
  8579.  
  8580. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8581.  
  8582. This service is used by devices that want to perform background operations
  8583. with the system is "idle". For example, this service is used by the pageswap
  8584. device to asynchronously write dirty pages to the backing store. Windows is
  8585. considered idle when all VMs have released their time-slice. When the
  8586. Windows kernel signals that Windows is idle and all other VMs are idle, the
  8587. idle callback procedures will be called. Each callback can either consume
  8588. the idle call or pass it on to the next idle callback in the list. Idle
  8589. calls should be consumed if the device performs an operation that takes a
  8590. significant amount of time. For example, if the pageswap device writes a
  8591. dirty page to the backing store then it will consume the idle call to
  8592. prevent slugish performance.  %@NL@%
  8593.  
  8594.  
  8595. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8596.  
  8597. ESI -> Procedure to call when all VMs idle  %@NL@%
  8598.  
  8599.  
  8600. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8601.  
  8602. If carry clear then  Callback procedure installed else  Error: Could not
  8603. install call-back procedure  %@NL@%
  8604.  
  8605.  
  8606. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8607.  
  8608. Flags  %@NL@%
  8609.  
  8610.  
  8611. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8612.  
  8613. EBX = System VM Handle (current VM is always the system VM) EBP -> Client
  8614. register structure Return with carry SET to pass the call to next handler
  8615. Return with carry CLEAR to consume the callback and indicate Sys VM is not
  8616. idle. Callback procedure can modify EAX, EBX, ECX, EDX, ESI, EDI, and Flags.
  8617. %@NL@%
  8618.  
  8619. %@CR:C6A00230010 @%%@CR:C6A00230011 @%
  8620. %@2@%%@CR:C6A00230012 @%%@AB@%Call_When_VM_Returns%@AE@%%@EH@%%@NL@%
  8621. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8622.  
  8623.  
  8624. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8625.  
  8626. This service is normally used to watch the "back end" of a software
  8627. interrupt. For example, assume that the procedure %@AB@%I16_Hook%@AE@% has been placed
  8628. in the V86 interrupt chain (using the %@AB@%Hook_V86_Int_Chain%@AE@% service). If the
  8629. procedure wants to look at the return value from INT 16H, it would use the
  8630. following code:  %@NL@%
  8631.  
  8632. %@AS@%  I16_Hook:
  8633. %@AS@%    xor eax, eax    ; No time-out
  8634. %@AS@%    mov esi, OFFSET32 I16_Return   ; Call this when iret executed
  8635. %@AS@%    VMMcall Call_When_VM_Returns    ; Hook the return
  8636. %@AS@%    stc     ; Reflect to next int handler
  8637. %@AS@%    ret%@AE@%
  8638.  
  8639. %@AS@%  I16_Return:
  8640. %@AS@%    (Examine results of Int 16h)
  8641. %@AS@%    ret%@AE@%
  8642.  
  8643. This service actually replaces the client's %@AB@%CS:IP%@AE@% with a callback. Since at
  8644. the point %@AB@%I16_Hook%@AE@% is executed the interrupt IRET frame has not yet been
  8645. built on the client's stack, the callback will be pushed on the client's
  8646. IRET frame. When the VM executes an IRET to return from the interrupt, the
  8647. callback break point will be executed and control will be transferred to
  8648. %@AB@%I16_Return%@AE@%. This service will take care of restoring the client's %@AB@%CS:IP%@AE@%
  8649. registers to their original value.  %@NL@%
  8650.  
  8651.  
  8652. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8653.  
  8654. %@AB@%EAX%@AE@% = Milliseconds until time-out (0 if no time-out)  If negative value then
  8655. callback will be called for both time out AND return (unless return before
  8656. time-out). %@AB@%EDX%@AE@% = Reference data %@AB@%ESI%@AE@% = Address of procedure to call  %@NL@%
  8657.  
  8658.  
  8659. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8660.  
  8661. %@AB@%Client_CS:EIP%@AE@% replaced with callback address  %@NL@%
  8662.  
  8663.  
  8664. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8665.  
  8666. %@AB@%Client_CS%@AE@%, %@AB@%Client_EIP%@AE@%, Flags  %@NL@%
  8667.  
  8668.  
  8669. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8670.  
  8671. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  8672. structure  %@NL@%
  8673.  
  8674. If carry set then  Time-out occurred before VM returned else  %@AB@%Client_CS:IP%@AE@%
  8675. restored to original value  VM returned and executed break point  If
  8676. time-out value specified was negative then  If Zero flag set then  Time-out
  8677. DID occur. Second call to this callback  else  Time-out did not and will not
  8678. occur.  %@NL@%
  8679.  
  8680. %@CR:C6A00230013 @%%@CR:C6A00230014 @%
  8681. %@2@%%@CR:C6A00230015 @%%@AB@%Install_V86_Break_Point%@AE@%%@EH@%%@NL@%
  8682. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8683.  
  8684.  
  8685. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8686.  
  8687. This service is used to patch V86 code in a VM. It is primarily used by the
  8688. DOSMGR device to place patches in the MS-DOS BIOS. Most VxD will have no use
  8689. for this service. A good example of a typical use for this service is the
  8690. Windows XMS virtual device. Since there is already a real mode XMS driver
  8691. when the enhanced Windows environment starts, the virtual XMS device must
  8692. place a V86 break point at the real XMS driver entry point so that it can
  8693. intercept all XMS calls.  %@NL@%
  8694.  
  8695. This service places an enhanced Windows V86 break point instruction at the
  8696. specified SEGMENT:OFFSET in the current virtual machine. V86 break points
  8697. will normally be placed in global VM memory during device initialization.
  8698. V86 break points must be placed only in RAM that will have a constant linear
  8699. address (they cannot move or be placed in ROM).  %@NL@%
  8700.  
  8701. When a VM executes the break point, control will be passed to the VxD that
  8702. installed it. The client's (VM's) %@AB@%CS:IP%@AE@% will still point to the break point
  8703. that caused the fault. Therefore, the virtual device must change the %@AB@%CS:IP%@AE@%
  8704. or else the break point will be executed again when the VxD environment
  8705. returns to the VM. In the case of the virtual XMS device, it would call
  8706. %@AB@%Simulate_Far_Ret%@AE@% to return to the code that called the XMS driver. Other
  8707. devices may want to simulate the instruction that was patched out and
  8708. increment the %@AB@%IP%@AE@% past the patch, jump to another %@AB@%CS:IP%@AE@% using
  8709. %@AB@%Simulate_Far_Jmp%@AE@%, or return from an interrupt handler using %@AB@%Simulate_Iret%@AE@%.  %@NL@%
  8710.  
  8711. If a particular V86 break point is no longer needed, then the VxD should
  8712. call %@AB@%Remove_V86_Break_Point%@AE@%. Also, any break points that are placed in
  8713. global V86 code (code loaded before Windows/386 was loaded) %@AI@%must%@AE@% be removed
  8714. at %@AB@%System_Exit%@AE@% time.  %@NL@%
  8715.  
  8716. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8717. NOTE 
  8718.  
  8719. %@AI@%The segment used to install a V86 break point must be the code segment the
  8720. %@AI@%virtual machine will use when it executes the code that is being patched.
  8721. %@AI@%For example, if you place a patch at 0100:0010 and the virtual machine hits
  8722. %@AI@%the break point at 0101:0000h (which is the same linear address as
  8723. %@AI@%0100:0010), then an error will occur even though the VM executed a valid
  8724. %@AI@%break point. %@AE@%
  8725. ────────────────────────────────────────────────────────────────────────────%@NL@%
  8726.  
  8727.  
  8728. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8729.  
  8730. %@AB@%EAX %@AE@% = %@AB@%CS:IP%@AE@% %@AB@%EDX%@AE@% = Reference data (any DWORD) %@AB@%ESI%@AE@% = Offset of procedure to
  8731. call  %@NL@%
  8732.  
  8733.  
  8734. %@3@%%@AB@%Exit:%@AE@%%@EH@%%@NL@%
  8735.  
  8736. %@AS@%  If carry set then
  8737. %@AS@%      Could not install break point
  8738. %@AS@%   else
  8739. %@AS@%      V86 break point successfully installed%@AE@%
  8740.  
  8741.  
  8742. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8743.  
  8744. Flags  %@NL@%
  8745.  
  8746.  
  8747. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  8748.  
  8749. %@AB@%EAX%@AE@% = %@AB@%Client CS:IP%@AE@% that faulted %@AB@%EBX %@AE@%= Handle of current VM %@AB@%EDX%@AE@% = Reference
  8750. data %@AB@%ESI%@AE@% = Linear address of break point (CS << 4 + IP)  %@AB@%EBP%@AE@% -> Client
  8751. register structure  %@NL@%
  8752.  
  8753. %@CR:C6A00230016 @%%@CR:C6A00230017 @%
  8754. %@2@%%@CR:C6A00230018 @%%@AB@%Remove_V86_Break_Point%@AE@%%@EH@%%@NL@%
  8755. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8756.  
  8757.  
  8758. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8759.  
  8760. This service is used to remove a V86 break point that was installed using
  8761. the %@AB@%Install_V86_Break_Point%@AE@% service. It will restore the original contents
  8762. of the memory automatically.  %@NL@%
  8763.  
  8764.  
  8765. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8766.  
  8767. %@AB@%EAX%@AE@% = %@AB@%CS:IP%@AE@% of break point to remove  %@NL@%
  8768.  
  8769.  
  8770. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8771.  
  8772. %@AS@%  If carry set then
  8773. %@AS@%      ERROR: Not a valid V86 break point
  8774. %@AS@%   else
  8775. %@AS@%      Previous value restored at break point SEG:OFFSET%@AE@%
  8776.  
  8777.  
  8778. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8779.  
  8780. Flags  %@NL@%
  8781.  
  8782.  
  8783.  
  8784.  
  8785.  
  8786.  
  8787. %@CR:C6A00240001 @%%@1@%%@AB@%Chapter 24  Primary Scheduler Services%@AE@%%@EH@%%@NL@%
  8788. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8789.  
  8790. Each virtual machine is a separate task in the enhanced Windows environment.
  8791. There are several services that are used to control the scheduling of
  8792. virtual machines.  %@NL@%
  8793.  
  8794. Every VM has an execution priority. The VM with the highest execution
  8795. priority is allowed to run unless the VM is suspended or is blocked waiting
  8796. for a critical section to be freed. A VM's execution priority can be raised
  8797. or lowered using the %@AB@%Adjust_Execution_Priority %@AE@%service.  %@NL@%
  8798.  
  8799. A VxD can force a particular virtual machine to run by boosting its
  8800. execution priority. However, VxD authors should take care when changing the
  8801. priority of a VM since doing so can radically effect the behavior of the
  8802. Windows time-slicer.%@CR:C6A00240002 @%%@NL@%
  8803.  
  8804. To allow the mutual exclusion of non-reentrant code, the scheduler supports
  8805. a single critical section. The current VM can claim the critical section at
  8806. any time by calling %@AB@%Begin_Critical_Section%@AE@%. If another VM owns the critical
  8807. section, then the current VM will block until the critical section is
  8808. released. Once the critical section is claimed, the VM's execution priority
  8809. is boosted. However, VMs with higher priorities will still be allowed to
  8810. execute. Normally, VMs are only boosted higher than the critical section
  8811. priority when a hardware interrupt is simulated.  %@NL@%
  8812.  
  8813. A VM may be suspended if it is not in a critical section. However, the
  8814. system VM can never be suspended. A suspended VM will never be scheduled,
  8815. regardless of its execution priority, until it is resumed.  %@NL@%
  8816.  
  8817. An important thing to keep in mind is that since the enhanced Windows
  8818. environment is a single-threaded operating system, you do not have to be
  8819. concerned with a task switch from within a procedure. For example, another
  8820. VM will not be scheduled while in a virtual device I/O trap handler. Task
  8821. switches take place when a VxD makes an explicit call to the scheduler
  8822. (i.e., %@AB@%End_Critical_Section%@AE@%) or at event processing time. Notice that since
  8823. events are processed when %@AB@%Resume_Exec%@AE@% or %@AB@%Exec_Int%@AE@% are called, a task switch
  8824. may occur while performing nested VM execution. Also, touching or locking
  8825. unlocked demand-paged memory may cause a task-switch. In summary, the times
  8826. when a task switch may occur are as follows:%@CR:C6A00240003 @%%@NL@%
  8827.  
  8828.  
  8829.   ■   Explicit calls to the scheduler%@NL@%
  8830.  
  8831.   ■   Performing nested execution (%@AB@%Resume_Exec%@AE@% or %@AB@%Exec_Int)%@AE@% %@NL@%
  8832.  
  8833.   ■   Touching or locking demand-paged memory %@NL@%
  8834.  
  8835.  
  8836. The discussion of services providing support for the Primary Scheduler is
  8837. presented in the following order:  %@NL@%
  8838.  
  8839.  
  8840.   ■   %@AB@%Adjust_Exec_Priority%@AE@%%@NL@%
  8841.  
  8842.   ■   %@AB@%Begin_Critical_Section%@AE@%%@NL@%
  8843.  
  8844.   ■   %@AB@%Call_When_Not_Critical%@AE@%%@NL@%
  8845.  
  8846.   ■   %@AB@%Call_When_Task_Switched%@AE@%%@NL@%
  8847.  
  8848.   ■   %@AB@%Claim_Critical_Section%@AE@%%@NL@%
  8849.  
  8850.   ■   %@AB@%Create_Semaphore%@AE@%%@NL@%
  8851.  
  8852.   ■   %@AB@%Destroy_Semaphore,D%@AE@%%@NL@%
  8853.  
  8854.   ■   %@AB@%End_Crit_And_Suspend%@AE@%%@NL@%
  8855.  
  8856.   ■   %@AB@%End_Critical_Section%@AE@%%@NL@%
  8857.  
  8858.   ■   %@AB@%Get_Crit_Section_Status%@AE@%%@NL@%
  8859.  
  8860.   ■   %@AB@%No_Fail_Resume_VM%@AE@%%@NL@%
  8861.  
  8862.   ■   %@AB@%Nuke_VM%@AE@%%@NL@%
  8863.  
  8864.   ■   %@AB@%Release_Critical_Section%@AE@%%@NL@%
  8865.  
  8866.   ■   %@AB@%Resume_VM%@AE@%%@NL@%
  8867.  
  8868.   ■   %@AB@%Signal_Semaphore%@AE@%%@NL@%
  8869.  
  8870.   ■   %@AB@%Suspend_VM%@AE@%%@NL@%
  8871.  
  8872.   ■   %@AB@%Wait_Semaphore%@AE@% %@NL@%
  8873.  
  8874.  
  8875. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  8876. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  8877.  
  8878. %@CR:C6A00240004 @%%@CR:C6A00240005 @%
  8879. %@2@%%@CR:C6A00240006 @%%@AB@%Adjust_Exec_Priority%@AE@%%@EH@%%@NL@%
  8880. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8881.  
  8882.  
  8883. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8884.  
  8885. This service is used to raise or lower the execution priority of the
  8886. specified VM. Since the non-suspended VM with the highest execution priority
  8887. is always the current VM, this service will cause a task switch under two
  8888. circumstances:  %@NL@%
  8889.  
  8890.  
  8891.   1.  The execution priority of the current VM is lowered (%@AB@%EAX%@AE@% is negative),
  8892.       and there is another VM with a higher priority that is not suspended.%@NL@%
  8893.  
  8894.   2.  The execution priority of a non-suspended VM which is not the current
  8895.       VM is raised (%@AB@%EAX%@AE@% is positive) higher than the current VM's execution
  8896.       priority. %@NL@%
  8897.  
  8898.  
  8899. Note that even if the current VM is in a critical section, a task switch
  8900. will still occur if the priority of another non-suspended VM is raised
  8901. higher than the current VM's priority. However, this will only happen when a
  8902. VM is given a time-critical boost, for example, to simulate a hardware
  8903. interrupt. There are equates defined in VMM.INC that should be used when
  8904. adjusting a VM's priority. They are listed below in order from lowest to
  8905. highest.  %@NL@%
  8906.  
  8907. %@TH:  27  1535 02 34 44 @%Equate Name                       Description%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@AB@%Reserved_Low_Boost%@AE@%                Reserved for use by system.%@AB@%Cur_Run_VM_Boost%@AE@%                  Time-slice scheduler boosts each VM in                                   turn by this value to force them to run                                   for their alloted time-slice.%@AB@%Low_Pri_Device_Boost%@AE@%              Used by VxDs that need an event to be                                   processed in a timely fashion but that are                                  not extremely time critical.%@AB@%High_Pri_Device_Boost%@AE@%             Time critical operations that should not                                   circumvent the critical section boost                                   should use this boost.%@AB@%Critical_Section_Boost%@AE@%            VM priority is boosted by this value when %@AB@%%@AE@%                                  %@AB@%%@AE@%                                  %@AB@%Begin_Critical_Section%@AE@% is called.%@AB@%Time_Critical_Boost%@AE@%               Events that must be processed even when                                   another VM is in a critical section should                                  use this boost. For example, VPICD uses                                   this when simulating hardware interrupts.%@AB@%Reserved_High_Boost%@AE@%               Reserved for use by system.%@TE:  27  1535 02 34 44 @%
  8908.  
  8909. It is often more convienient to call %@AB@%Call_Priority_VM_Event%@AE@% than to call
  8910. this service directly.  %@NL@%
  8911.  
  8912.  
  8913. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8914.  
  8915. %@AB@%EAX%@AE@%  = + or - priority boost (signed long integer) %@AB@%EBX%@AE@%  = VM handle  %@NL@%
  8916.  
  8917.  
  8918. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8919.  
  8920. None  %@NL@%
  8921.  
  8922.  
  8923. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8924.  
  8925. Flags  %@NL@%
  8926.  
  8927. %@CR:C6A00240007 @%%@CR:C6A00240008 @%
  8928. %@2@%%@CR:C6A00240009 @%%@AB@%Begin_Critical_Section%@AE@%%@EH@%%@NL@%
  8929. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8930.  
  8931.  
  8932. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  8933.  
  8934. Use of this service causes the current VM to enter a global critical
  8935. section. Only one VM can own the critical section at a time. If a VM calls
  8936. this service while another VM owns the critical section, then the current VM
  8937. will block until the critical section is released.  %@NL@%
  8938.  
  8939. The critical section is maintained as a count and so %@AI@%n %@AE@%calls to
  8940. %@AB@%Begin_Critical_Section%@AE@% must be followed by%@AI@% n%@AE@% calls to %@AB@%End_Critical_Section%@AE@%
  8941. before the VM will leave the critical section.  %@NL@%
  8942.  
  8943. When the critical section is first claimed, the execution priority of the
  8944. current VM is boosted by the %@AB@%Critical_Section_Boost%@AE@% value defined in
  8945. VMM.INC. This means that task switches to other VMs will only occur for
  8946. time-critical operations such as simulating hardware interrupts.  %@NL@%
  8947.  
  8948. Critical sections are used for code that must not be entered in more than
  8949. one VM. For example, while in MS-DOS, the DOSMGR VxD places the VM in a
  8950. critical section. If another VM makes a MS-DOS call, then it will block
  8951. until the critical section owner's MS-DOS call completes. However, this
  8952. scenario is unlikely since a VM has an extremely high execution priority
  8953. while it owns the critical section, and, therefore, other VMs will not run
  8954. until the critical section is released. A scenario that%@AI@% would %@AE@%cause a VM to
  8955. block  is as follows:  %@NL@%
  8956.  
  8957. %@AS@%  VM X calls MS-DOS to read a file.
  8958. %@AS@%  The DOSMGR calls Begin_Critical_Section for VM X. This raises
  8959. %@AS@%    VM X's priority by the Critical_Section_Boost.   
  8960. %@AS@%  The Virtual Keyboard Device simulates an interrupt to VM Y.   
  8961. %@AS@%  VM Y is sceduled since it has a higher execution priority 
  8962. %@AS@%   (simulated interrupts use the Time_Critical_Boost).   
  8963. %@AS@%  A T&SR program "wakes up" on the keyboard interrupt and calls DOS.
  8964. %@AS@%  The DOSMGR calls Begin_Critical_Section for VM Y.   
  8965. %@AS@%  VM Y blocks since another VM owns the critical section.   
  8966. %@AS@%  VM X is scheduled since it has the highest exectution priority.
  8967. %@AS@%  The MS-DOS read for VM X completes.   
  8968. %@AS@%  DOSMGR calls End_Critical_Section for VM X. This lowers
  8969. %@AS@%    VM X's priority by the Critical_Section_Boost.   
  8970. %@AS@%  VM Y is un-blocked and scheduled since it has the highest priority.
  8971. %@AS@%  VM Y continues execution at the instruction immediately after the
  8972. %@AS@%    call to Begin_Critical_Section and executes the MS-DOS call.%@AE@%
  8973.  
  8974. Sometimes it is preferable to boost the current VM by the
  8975. %@AB@%Time_Critical_Boost%@AE@% value instead of entering a critical section. This
  8976. prevents the main thread of execution from running in all but the current VM
  8977. but avoids blocking a VM when it is not really necessary.  %@NL@%
  8978.  
  8979.  
  8980. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  8981.  
  8982. None  %@NL@%
  8983.  
  8984.  
  8985. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  8986.  
  8987. None  %@NL@%
  8988.  
  8989.  
  8990. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  8991.  
  8992. Flags  %@NL@%
  8993.  
  8994. %@CR:C6A00240010 @%%@CR:C6A00240011 @%
  8995. %@2@%%@CR:C6A00240012 @%%@AB@%Call_When_Not_Critical%@AE@%%@EH@%%@NL@%
  8996. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8997.  
  8998.  
  8999. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9000.  
  9001. This service will call a VxD when the critical section is released. Notice
  9002. that it will not execute the callback until the current VM's execution
  9003. priority is less than the %@AB@%Critical_Section_Boost%@AE@% even when the current VM is
  9004. %@AI@%not%@AE@% in a critical section. This is done because most VxDs that use this
  9005. service will want to wait until the critical section is free and no hardware
  9006. interrupts are being simulated.  %@NL@%
  9007.  
  9008. Normally it is more convenient to use the %@AB@%Call_Priority_VM_Event %@AE@%service
  9009. than to call this service directly. %@AB@%  %@AE@%%@NL@%
  9010.  
  9011.  
  9012. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9013.  
  9014. %@AB@%ESI%@AE@% = Address of call-back procedure %@AB@%EDX%@AE@% = Reference data to pass to
  9015. callback procedure  %@NL@%
  9016.  
  9017.  
  9018. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9019.  
  9020. None  %@NL@%
  9021.  
  9022.  
  9023. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9024.  
  9025. Flags  %@NL@%
  9026.  
  9027.  
  9028. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  9029.  
  9030. %@AB@%EBX %@AE@%= Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  9031. structure  %@NL@%
  9032.  
  9033. Procedure can corrupt %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@% ECX%@AE@%,%@AB@% EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  9034.  
  9035. %@CR:C6A00240013 @%%@CR:C6A00240014 @%
  9036. %@2@%%@CR:C6A00240015 @%%@AB@%Call_When_Task_Switched%@AE@%%@EH@%%@NL@%
  9037. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9038.  
  9039.  
  9040. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9041.  
  9042. This service provides a way to be informed each time a different VM is to be
  9043. executed. The specified procedure will be called %@AI@%every time%@AE@% a task switch
  9044. occurs. Since this is a frequent operation in most environments, this
  9045. service should be used sparingly, and the callback procedure should be
  9046. optimized for speed.  %@NL@%
  9047.  
  9048. VxDs must sometimes save the state of a hardware device every time a task
  9049. switch occurs and restore the hardware state for the VM that is about to be
  9050. run. However, VM events can often be used in place of using this service.  %@NL@%
  9051.  
  9052.  
  9053. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9054.  
  9055. %@AB@%ESI%@AE@% = Pointer to procedure to call at task switch time  %@NL@%
  9056.  
  9057.  
  9058. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9059.  
  9060. None  %@NL@%
  9061.  
  9062.  
  9063. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9064.  
  9065. Flags  %@NL@%
  9066.  
  9067.  
  9068. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  9069.  
  9070. %@AB@%EAX%@AE@% = Handle of VM switching away from (old %@AB@%Cur_VM_Handle%@AE@%)  %@AB@%EBX%@AE@% = Current VM
  9071. (just switched to)  %@NL@%
  9072.  
  9073. Procedure can destroy %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@% and Flags  %@NL@%
  9074.  
  9075. %@CR:C6A00240016 @%%@CR:C6A00240017 @%
  9076. %@2@%%@CR:C6A00240018 @%%@AB@%Claim_Critical_Section%@AE@%%@EH@%%@NL@%
  9077. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9078.  
  9079.  
  9080. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9081.  
  9082. This service will increment the critical section count by the specified
  9083. value. It has the same effect as calling %@AB@%Begin_Critical_Section%@AE@% repeatedly
  9084. but is faster. Refer to the documentation for %@AB@%Begin_Critical_Section%@AE@% for
  9085. more information on the various side effects of entering a critical section.
  9086. %@NL@%
  9087.  
  9088.  
  9089. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9090.  
  9091. %@AB@%ECX%@AE@% = # of times to claim the critical section (0 is valid & ignored)  %@NL@%
  9092.  
  9093.  
  9094. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9095.  
  9096. None  %@NL@%
  9097.  
  9098.  
  9099. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9100.  
  9101. Flags  %@NL@%
  9102.  
  9103. %@CR:C6A00240019 @%%@CR:C6A00240020 @%
  9104. %@2@%%@CR:C6A00240021 @%%@AB@%Create_Semaphore%@AE@%%@EH@%%@NL@%
  9105. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9106.  
  9107.  
  9108. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9109.  
  9110. Do not use. Reserved for future release.  %@NL@%
  9111.  
  9112. %@CR:C6A00240022 @%%@CR:C6A00240023 @%
  9113. %@2@%%@CR:C6A00240024 @%%@AB@%Destroy_Semaphore%@AE@%%@EH@%%@NL@%
  9114. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9115.  
  9116.  
  9117. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9118.  
  9119. Do not use. Reserved for future release.  %@NL@%
  9120.  
  9121. %@CR:C6A00240025 @%%@CR:C6A00240026 @%
  9122. %@2@%%@CR:C6A00240027 @%%@AB@%End_Crit_And_Suspend%@AE@%%@EH@%%@NL@%
  9123. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9124.  
  9125.  
  9126. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9127.  
  9128. This service will release the critical section and immediately suspend the
  9129. current VM. It is used to block a VM until another event can be processed.
  9130. This service is used by the Shell VxD to display Windows dialog boxes using
  9131. code similar to this:  %@NL@%
  9132.  
  9133. %@AS@%  Show_Dialog_Box:
  9134. %@AS@%    VMMcall  Get_Crit_Section_Status
  9135. %@AS@%   jc  Cant_Do_It!
  9136. %@AS@%    VMMcall  Begin_Critical_Section
  9137. %@AS@%   mov  eax, Low_Pri_Device_Boost
  9138. %@AS@%   VMMcall  Get_Sys_VM_Handle
  9139. %@AS@%    mov  ecx, 11b
  9140. %@AS@%   mov  edx, OFFSET32 (Dialog_Box_Data_Structure)
  9141. %@AS@%    mov  esi, OFFSET32 Show_Dialog_Event
  9142. %@AS@%   VMMcall  Call_Priority_VM_Event
  9143. %@AS@%    VMMcall  End_Crit_And_Suspend
  9144. %@AS@%    jc  Did_Not_Work!
  9145. %@AS@%     ; (When End_Crit_And_Suspend returns the dialog box
  9146. %@AS@%     ; will have been displayed)%@AE@%
  9147.  
  9148. %@AS@%  Show_Dialog_Event:
  9149. %@AS@%    (Call Windows to display the dialog box)
  9150. %@AS@%    mov ebx, [Handle_Of_VM_That_Called_Show_Dialog_Box]
  9151. %@AS@%    VMMcall Resume_VM
  9152. %@AS@%    jc  Error!
  9153. %@AS@%    ret%@AE@%
  9154.  
  9155. The %@AB@%Show_Dialog_Box%@AE@% procedure enters a critical section to prevent the
  9156. %@AB@%Call_Priority_VM_Event %@AE@%service from switching to the system VM immediately.
  9157. It then calls%@AB@% End_Crit_And_Suspend%@AE@%, which blocks the current VM. The
  9158. %@AB@%Show_Dialog_Event%@AE@% procedure runs in the system (Windows) VM and actually
  9159. displays the dialog box. When it is finished, it resumes the VM that called
  9160. %@AB@%Show_Dialog_Box%@AE@%. %@AB@%  %@AE@%%@NL@%
  9161.  
  9162. This service must only be called when the critical section has been claimed
  9163. %@AI@%once%@AE@%. That is the reason for the initial test of the critical section state
  9164. in the %@AB@%Show_Dialog_Box%@AE@% procedure in the sample code.  %@NL@%
  9165.  
  9166.  
  9167. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9168.  
  9169. None  %@NL@%
  9170.  
  9171.  
  9172. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9173.  
  9174. If carry set then  ERROR: Could not suspend VM or could not release critical
  9175. section (crit claim count != 1) else  Call worked. VM execution restarted by
  9176. another VM calling  "Resume_VM".  %@NL@%
  9177.  
  9178.  
  9179. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9180.  
  9181. Flags  %@NL@%
  9182.  
  9183. %@CR:C6A00240028 @%%@CR:C6A00240029 @%
  9184. %@2@%%@CR:C6A00240030 @%%@AB@%End_Critical_Section%@AE@%%@EH@%%@NL@%
  9185. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9186.  
  9187.  
  9188. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9189.  
  9190. This service is used to release the global critical section after a call to
  9191. %@AB@%Begin_Critical_Section%@AE@% has been issued. If the critical section ownership
  9192. count is decremented to 0, then ownership of the critical section is
  9193. released. Since releasing the critical section lowers the execution priority
  9194. of the current VM, this service will cause a task switch if a non-suspended
  9195. VM has a higher priority.  %@NL@%
  9196.  
  9197.  
  9198. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9199.  
  9200. None  %@NL@%
  9201.  
  9202.  
  9203. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9204.  
  9205. None  %@NL@%
  9206.  
  9207.  
  9208. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9209.  
  9210. Flags  %@NL@%
  9211.  
  9212. %@CR:C6A00240031 @%%@CR:C6A00240032 @%
  9213. %@2@%%@CR:C6A00240033 @%%@AB@%Get_Crit_Section_Status%@AE@%%@EH@%%@NL@%
  9214. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9215.  
  9216.  
  9217. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9218.  
  9219. This service returns the critical section claim count in %@AB@%ECX%@AE@% and the owner
  9220. of the critical section in %@AB@%EBX%@AE@%. If %@AB@%ECX%@AE@% is 0, then the current VM handle will
  9221. be returned in %@AB@%EBX%@AE@%.  %@NL@%
  9222.  
  9223. If this service returns with the Carry flag set, then the VM is in a
  9224. time-critical operation such as a hardware interrupt simulation. (It has an
  9225. execution priority = %@AB@%Critical_Section_Boost%@AE@%.)  %@NL@%
  9226.  
  9227.  
  9228. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9229.  
  9230. None  %@NL@%
  9231.  
  9232.  
  9233. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9234.  
  9235. %@AB@%EBX %@AE@%= VM handle of current owner (Current VM if %@AB@%ECX%@AE@% = 0) %@AB@%ECX%@AE@% = # of times
  9236. critical section claimed If carry set then VM is in a time-critical
  9237. operation or critical section.  %@NL@%
  9238.  
  9239.  
  9240. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9241.  
  9242. Flags  %@NL@%
  9243.  
  9244. %@CR:C6A00240034 @%
  9245. %@2@%%@CR:C6A00240035 @%%@AB@%No_Fail_Resume_VM%@CR:C6A00240036 @%%@AE@%%@EH@%%@NL@%
  9246. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9247.  
  9248.  
  9249. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9250.  
  9251. This service is used to resume the execution of a VM that was previously
  9252. suspended by a call to %@AB@%Suspend_VM%@AE@%. It differs from the normal %@AB@%Resume_VM%@AE@%
  9253. service in that it will never return an error. If theVM can not be resumed,
  9254. the scheduler will handle the error condition automatically and the user
  9255. will be notified of the problem. The VM will then be resumed when there is
  9256. sufficient memory available. A task switch will occur to the resumed VM if
  9257. it has a higher priority than the current VM.  %@NL@%
  9258.  
  9259.  
  9260. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9261.  
  9262. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9263.  
  9264.  
  9265. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9266.  
  9267. None  %@NL@%
  9268.  
  9269.  
  9270. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9271.  
  9272. Flags  %@NL@%
  9273.  
  9274. %@CR:C6A00240037 @%
  9275. %@2@%%@CR:C6A00240038 @%%@AB@%Nuke_VM%@CR:C6A00240039 @%%@AE@%%@EH@%%@NL@%
  9276. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9277.  
  9278.  
  9279. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9280.  
  9281. This service is used to close a VM that has not yet terminated normally. It
  9282. is usually called by the Shell VxD to close VMs that the user has selected
  9283. to terminate using the Window Close option on the VM's system menu.  %@NL@%
  9284.  
  9285. Needless to say, this service should be used very cautiously.  %@NL@%
  9286.  
  9287.  
  9288. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9289.  
  9290. %@AB@%EBX%@AE@% = Handle of VM to destroy  %@NL@%
  9291.  
  9292.  
  9293. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9294.  
  9295. If entry EBX = Current VM handle then  This service will never return (same
  9296. as Crash_Cur_VM)  else  If EBX = System VM handle then  This service will
  9297. never return (fatal error─crash to DOS)   else  VM has been nuked  %@NL@%
  9298.  
  9299.  
  9300. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9301.  
  9302. Flags  %@NL@%
  9303.  
  9304. %@CR:C6A00240040 @%%@CR:C6A00240041 @%
  9305. %@2@%%@CR:C6A00240042 @%%@AB@%Release_Critical_Section%@AE@%%@EH@%%@NL@%
  9306. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9307.  
  9308.  
  9309. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9310.  
  9311. This service will decrement the critical section count by the specified
  9312. value. It has the same effect as calling %@AB@%End_Critical_Section%@AE@% repeatedly but
  9313. is faster.  %@NL@%
  9314.  
  9315.  
  9316. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9317.  
  9318. %@AB@%ECX%@AE@% = # of times to release ownership of critical section (0 valid)  %@NL@%
  9319.  
  9320.  
  9321. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9322.  
  9323. None  %@NL@%
  9324.  
  9325.  
  9326. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9327.  
  9328. Flags  %@NL@%
  9329.  
  9330. %@CR:C6A00240043 @%
  9331. %@2@%%@CR:C6A00240044 @%%@AB@%Resume_VM%@CR:C6A00240045 @%%@AE@%%@EH@%%@NL@%
  9332. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9333.  
  9334.  
  9335. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9336.  
  9337. This service is used to resume the execution of a VM that was previously
  9338. suspended by a call to %@AB@%Suspend_VM.%@AE@% If the suspend count is decremented to 0,
  9339. the VM will be placed on the queue of ready processes. A task switch will
  9340. occur to the resumed VM if it has a higher priority than the current VM.  %@NL@%
  9341.  
  9342. It is sometimes not possible to resume a VM. Normally, this is because a VxD
  9343. is unable to lock the VM's memory handles. Every VxD is notified when a VM
  9344. is resumed and can fail the call. In this case, this service will return
  9345. with Carry set, and the VM will remain suspended with a suspend count of 1.
  9346. %@NL@%
  9347.  
  9348.  
  9349. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9350.  
  9351. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9352.  
  9353.  
  9354. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9355.  
  9356. If carry clear then  If suspend count decremented to 0 then VM is runnable
  9357. else  Error could not resume (Suspend count remains 1)  %@NL@%
  9358.  
  9359.  
  9360. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9361.  
  9362. Flags  %@NL@%
  9363.  
  9364. %@CR:C6A00240046 @%%@CR:C6A00240047 @%
  9365. %@2@%%@CR:C6A00240048 @%%@AB@%Signal_Semaphore%@AE@%%@EH@%%@NL@%
  9366. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9367.  
  9368.  
  9369. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9370.  
  9371. Do not use. Reserved for future release.  %@NL@%
  9372.  
  9373. %@CR:C6A00240049 @%
  9374. %@2@%%@CR:C6A00240050 @%%@AB@%Suspend_VM%@CR:C6A00240051 @%%@AE@%%@EH@%%@NL@%
  9375. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9376.  
  9377.  
  9378. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9379.  
  9380. This service will suspend the execution of a specified Virtual Machine. Any
  9381. VM, except the system VM, that is not in a critical section can be
  9382. suspended. This service will fail if the specified VM is the critical
  9383. section owner or the system VM. The system VM can never be suspended.  %@NL@%
  9384.  
  9385. This service maintains a count that is incremented each time a VM is
  9386. suspended. Therefore, if this service is called %@AI@%n%@AE@% times for a given VM,
  9387. %@AB@%Resume_VM%@AE@% must be called %@AI@%n %@AE@%times before the VM will be executed.  %@NL@%
  9388.  
  9389. When a VM is being suspended for the first time (its suspend count is
  9390. incremented from 0 to 1), all devices will receive a control call with %@AB@%EAX%@AE@% =
  9391. %@AB@%VM_Suspend%@AE@%. Devices may %@AI@%not%@AE@% refuse to suspend a VM. However, VxDs are
  9392. allowed to fail the %@AB@%VM_Resume%@AE@% control call. Subsequent calls to %@AB@%Suspend_VM%@AE@%
  9393. will not result in a %@AB@%VM_Suspend%@AE@% control call until the VM has been resumed.
  9394. %@NL@%
  9395.  
  9396. When a VM is suspended, the %@AB@%CB_VM_Status%@AE@% field in the control block will
  9397. have the %@AB@%VMStat_Suspended%@AE@% bit set. When a VM is suspended, VxDs should not
  9398. touch any memory owned by that VM unless the VxD has previously locked the
  9399. memory. You %@AI@%may, %@AE@%however, examine or modify the contents of a suspended VM's
  9400. control block.  %@NL@%
  9401.  
  9402.  
  9403. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9404.  
  9405. %@AB@%EBX %@AE@%= VM handle  %@NL@%
  9406.  
  9407.  
  9408. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9409.  
  9410. If carry flag clear then  VM suspended  else  Error: Could not suspend VM
  9411. (VM is in a critical section or  is the system VM)  %@NL@%
  9412.  
  9413.  
  9414. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9415.  
  9416. Flags  %@NL@%
  9417.  
  9418. %@CR:C6A00240052 @%%@CR:C6A00240053 @%
  9419. %@2@%%@CR:C6A00240054 @%%@AB@%Wait_Semaphore%@AE@%%@EH@%%@NL@%
  9420. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9421.  
  9422.  
  9423. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9424.  
  9425. Do not use. Reserved for future release.  %@NL@%
  9426.  
  9427.  
  9428.  
  9429.  
  9430.  
  9431.  
  9432. %@CR:C6A00250001 @%%@1@%%@AB@%Chapter 25  Time-Slice Scheduler Services%@AE@%%@EH@%%@NL@%
  9433. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9434.  
  9435. The enhanced Windows time-slice scheduler is the preemptive multitasking
  9436. portion of the scheduler. It relies on time-slice priorities and flags to
  9437. determine how much CPU time should be allocated to various virtual machines.
  9438. %@NL@%
  9439.  
  9440. Every VM has a %@AB@%foreground%@AE@% (focus) and a %@AB@%background%@AE@% time-slice priority.
  9441. These should be distinguished from a VM's Execution Priority (described in
  9442. previous chapter). A VM with the largest Execution Priority will run,
  9443. preventing other VMs from executing. The VM with the largest time-slice
  9444. priority will run more often than other VMs but it will not necessarily
  9445. prevent other VMs from executing.  %@NL@%
  9446.  
  9447. There are three flags that affect the way the time-slicer schedules virtual
  9448. machines: %@AB@%VMStat_Exclusive%@AE@%, %@AB@%VMStat_Background%@AE@%, and
  9449. %@AB@%VMStat_High_Pri_Background%@AE@%. These flags are saved in the %@AB@%CB_VM_Status%@AE@% field
  9450. of each VM's control block. You may examine these flags but you must never
  9451. modify them directly. To change any of the flags, you must call the
  9452. %@AB@%Set_Time_Slice_Priority%@AE@% service.  %@NL@%
  9453.  
  9454. If a VM that has the %@AB@%VMStat_Exclusive%@AE@% bit set is assigned the execution
  9455. focus, then it will become the only VM that is allowed to run. In this case,
  9456. foreground and background priorities are meaningless since the VM is using
  9457. 100 percent of the CPU time. The %@AB@%Release_Time_Slice%@AE@% service has no effect on
  9458. an exclusive virtual machine. High-priority background VMs will not run when
  9459. an exclusive VM has the execution focus.  %@NL@%
  9460.  
  9461. The only exception to this is that Windows must be notified of certain
  9462. operations in a VM and will run momentarily in the background when these
  9463. operations occur. For example, if an exclusive VM is running in a window the
  9464. Windows VM will wake up occasionally to update the display.  %@NL@%
  9465.  
  9466. The only exception to this is that Windows must be notified of certain
  9467. operations in a VM and will run momentarily in the background when these
  9468. operations occur. For example, if an exclusive VM is running in a window,
  9469. the Windows VM will wake up occasionally to update the display.  %@NL@%
  9470.  
  9471. If the VM with the focus is %@AI@%not%@AE@% exclusive, then any VM that has the
  9472. %@AB@%VMStat_Background%@AE@% flag set will be allowed to run based on their background
  9473. time-slice priority. The VM with the focus will be scheduled based on its
  9474. foreground time-slice priority.  %@NL@%
  9475.  
  9476. For this scheduler, a higher priority indicates that the VM should get %@AI@%more%@AE@%
  9477. CPU time. The larger the priority, the faster the VM will run.  %@NL@%
  9478.  
  9479. The algorithm used to allocate time determines the percentage of CPU time
  9480. each VM should get based on their percentage of the total of all the
  9481. time-slice priorities. For example, assume the following VMs exist:  %@NL@%
  9482.  
  9483. %@TH:  14   624 02 04 20 20 32 @%    Foreground          Background          VM  Priority            Priority            Flags%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%1   100                 50                  Exclusive, Background2   100                 50                  Background3   50                  25                  (None ─ Foreground,                                             non-exclusive)4   250                 75                  Background%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@TE:  14   624 02 04 20 20 32 @%
  9484.  
  9485. If the execution focus is set to VM 1, then it will use 100 percent of the
  9486. CPU time since it has the exclusive flag set. If the execution focus is set
  9487. to VM 2, then VMs 1, 2, and 4 will run.VM 3 would not be scheduled since it
  9488. does not have the background flag set.  %@NL@%
  9489.  
  9490. To determine how much time each VM should be allocated, the time-slicer
  9491. first sums all the VM priorities and, then, calculates the percentage of CPU
  9492. time each VM should receive as follows:  %@NL@%
  9493.  
  9494. VM 2 foreground pri = 100 / 225 * 100 = 45% of CPU  %@NL@%
  9495.  
  9496. VM 1 background pri = 50 / 225 * 100 = 22% of CPU  %@NL@%
  9497.  
  9498. VM 4 background pri = 75 / 225 * 100 = 33% of CPU  ───  Total 225  %@NL@%
  9499.  
  9500. Notice that a foreground priority of 10,000 (the maximum allowed) is
  9501. special. When a VM with priority 10,000 is the execution focus VM, only
  9502. high-priority background VMs will run unless the focus VM explicitly
  9503. releases its time slice. This is different from an exclusive VM since other
  9504. VMs %@AI@%can%@AE@% run if the focus gives up its time.  %@NL@%
  9505.  
  9506. When a VM has the %@AB@%VMStat_High_Pri_Back%@AE@% flag set it will execute in the
  9507. background even if the current-focus VM has a priority of 10,000 or is
  9508. exclusive.  %@NL@%
  9509.  
  9510. The discussion of services providing support for the Time-Slice Scheduler is
  9511. presented in the following order:  %@NL@%
  9512.  
  9513.  
  9514.   ■   %@AB@%Adjust_Execution_Time%@AE@%%@NL@%
  9515.  
  9516.   ■   %@AB@%Call_When_Idle%@AE@%%@NL@%
  9517.  
  9518.   ■   %@AB@%Get_Execution_Focus %@AE@%%@NL@%
  9519.  
  9520.   ■   %@AB@%Get_Time_Slice_Granularity%@AE@%%@NL@%
  9521.  
  9522.   ■   %@AB@%Get_Time_Slice_Info%@AE@%%@NL@%
  9523.  
  9524.   ■   %@AB@%Get_Time_Slice_Priority%@AE@%%@NL@%
  9525.  
  9526.   ■   %@AB@%Release_Time_Slice%@AE@%%@NL@%
  9527.  
  9528.   ■   %@AB@%Set_Execution_Focus%@AE@%%@NL@%
  9529.  
  9530.   ■   %@AB@%Set_Time_Slice_Granularity%@AE@%%@NL@%
  9531.  
  9532.   ■   %@AB@%Set_Time_Slice_Priority%@AE@%%@NL@%
  9533.  
  9534.   ■   %@AB@%Wake_Up_VM%@AE@%%@NL@%
  9535.  
  9536.  
  9537. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  9538. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  9539.  
  9540. %@CR:C6A00250002 @%%@CR:C6A00250003 @%
  9541. %@2@%%@CR:C6A00250004 @%%@AB@%Adjust_Execution_Time%@AE@%%@EH@%%@NL@%
  9542. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9543.  
  9544.  
  9545. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9546.  
  9547. This service allows a VxD to change the amount of time a VM will be allowed
  9548. to execute regardless of the VM's time-slice priority. Usually this service
  9549. is used by VxDs such as the Virtual COM Device to boost temporarily the
  9550. priority of a VM that is receiving lots of interrupts. This service can also
  9551. be used to reduce the amount of time a VM will be allowed to run by passing
  9552. a negative value in %@AB@%EAX%@AE@%. However, this is likely to cause execution
  9553. starvation and is discouraged.  %@NL@%
  9554.  
  9555. The value specified in %@AB@%EAX%@AE@% is the number of additional (or fewer)
  9556. milliseconds the VM will be allowed to run. It has the same effect on all
  9557. VMs regardless of their time-slice priority. This means that if a VxD calls
  9558. this service with %@AB@%EAX%@AE@% = 1000, then the specified VM will be allowed to run
  9559. an additional second regardless of its time-slice priority.  %@NL@%
  9560.  
  9561. Notice that if the specified VM is not on the time-slice execution list,
  9562. then this service will do nothing. It will %@AI@%not%@AE@% force a non-runnable VM to
  9563. execute. In other words, a non-background VM cannot be forced to run in the
  9564. background by boosting its execution time.  %@NL@%
  9565.  
  9566. Be careful using this service. It can result in starvation for other
  9567. processes.  %@NL@%
  9568.  
  9569.  
  9570. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9571.  
  9572. %@AB@%EAX%@AE@% = + or - milliseconds to adjust execution time by %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9573.  
  9574.  
  9575. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9576.  
  9577. None  %@NL@%
  9578.  
  9579.  
  9580. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9581.  
  9582. Flags  %@NL@%
  9583.  
  9584. %@CR:C6A00250005 @%%@CR:C6A00250006 @%
  9585. %@2@%%@CR:C6A00250007 @%%@AB@%Call_When_Idle%@AE@%%@EH@%%@NL@%
  9586. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9587.  
  9588.  
  9589. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9590.  
  9591. This service is used by VxDs that want to perform background operations when
  9592. the system is "idle". For example, this service is used by the pageswap
  9593. device to asynchronously write dirty pages to the backing store. Windows is
  9594. considered idle when all VMs have released their time-slice. When the
  9595. Windows kernel signals that Windows is idle and all other VMs are idle, the
  9596. idle call-back procedures will be called. Each call-back can either consume
  9597. the idle call or pass it on to the next idle call-back in the list. Idle
  9598. calls should be consumed if the VxD performs an operation that takes a
  9599. significant amount of time. For example, if the pageswap device writes a
  9600. dirty page to the backing store then it will consume the idle call to
  9601. prevent sluggish performance.  %@NL@%
  9602.  
  9603.  
  9604. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9605.  
  9606. %@AB@%ESI%@AE@% - Procedure to call when all VMs idle  %@NL@%
  9607.  
  9608.  
  9609. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9610.  
  9611. If carry clear then  Call-back procedure installed else  Error: Could not
  9612. install call-back procedure  %@NL@%
  9613.  
  9614.  
  9615. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9616.  
  9617. Flags  %@NL@%
  9618.  
  9619.  
  9620. %@3@%%@AB@%Call-Back%@AE@%%@EH@%%@NL@%
  9621.  
  9622. %@AB@%EBX%@AE@% = System VM Handle (current VM is always the system VM) %@AB@%EBP%@AE@% - Client
  9623. register structure Return with carry SET to pass the call to next handler
  9624. Return with carry CLEAR to "eat" the call-back and indicate Sys VM is not
  9625. 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
  9626. Flags.  %@NL@%
  9627.  
  9628. %@CR:C6A00250008 @%%@CR:C6A00250009 @%
  9629. %@2@%%@CR:C6A00250010 @%%@AB@%Get_Execution_Focus%@AE@%%@EH@%%@NL@%
  9630. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9631.  
  9632.  
  9633. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9634.  
  9635. This service returns the handle of the VM that is the focus (foreground) VM.
  9636. This service can be called from an interrupt handler.  %@NL@%
  9637.  
  9638.  
  9639. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9640.  
  9641. None  %@NL@%
  9642.  
  9643.  
  9644. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9645.  
  9646. %@AB@%EBX%@AE@% = Handle of VM with execution focus  %@NL@%
  9647.  
  9648.  
  9649. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9650.  
  9651. %@AB@%EBX%@AE@%, Flags  %@NL@%
  9652.  
  9653. %@CR:C6A00250011 @%%@CR:C6A00250012 @%
  9654. %@2@%%@CR:C6A00250013 @%%@AB@%Get_Time_Slice_Granularity%@AE@%%@EH@%%@NL@%
  9655. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9656.  
  9657.  
  9658. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9659.  
  9660. This service returns the current time-slice granularity in %@AB@%EAX%@AE@%. The value
  9661. returned is the minimum number of milliseconds a VM will be allowed to run
  9662. before being rescheduled.  %@NL@%
  9663.  
  9664.  
  9665. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9666.  
  9667. None  %@NL@%
  9668.  
  9669.  
  9670. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9671.  
  9672. %@AB@%EAX%@AE@% = Minimum time-slice size in milliseconds  %@NL@%
  9673.  
  9674.  
  9675. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9676.  
  9677. %@AB@%EAX%@AE@%, Flags  %@NL@%
  9678.  
  9679. %@CR:C6A00250014 @%%@CR:C6A00250015 @%
  9680. %@2@%%@CR:C6A00250016 @%%@AB@%Get_Time_Slice_Info%@AE@%%@EH@%%@NL@%
  9681. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9682.  
  9683.  
  9684. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9685.  
  9686. This service returns information about the number of virtual machines
  9687. currently scheduled by the time-slicer and the number of VMs that are idle.
  9688. %@NL@%
  9689.  
  9690. This service can be called at interrupt time.  %@NL@%
  9691.  
  9692.  
  9693. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9694.  
  9695. None  %@NL@%
  9696.  
  9697.  
  9698. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9699.  
  9700. %@AB@%EAX%@AE@% = Number of VMs scheduled %@AB@%EBX%@AE@% = Handle of VM currently scheduled %@AB@%ECX%@AE@% =
  9701. Number of scheduled VMs that are currently idle  %@NL@%
  9702.  
  9703.  
  9704. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9705.  
  9706. Nothing  %@NL@%
  9707.  
  9708. %@CR:C6A00250017 @%%@CR:C6A00250018 @%
  9709. %@2@%%@CR:C6A00250019 @%%@AB@%Get_Time_Slice_Priority%@AE@%%@EH@%%@NL@%
  9710. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9711.  
  9712.  
  9713. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9714.  
  9715. This service returns the time-slice execution flags, the foreground and
  9716. background priorities, and the percent of CPU usage for a specified VM.
  9717. Notice that the percent of CPU time returned indicates the amount of time
  9718. the VM is allowed to run, but this number will not reflect the actual amount
  9719. of CPU time if any VM releases its time slice since other VMs will be
  9720. allowed to execute during that VM's time slice.  %@NL@%
  9721.  
  9722.  
  9723. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9724.  
  9725. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9726.  
  9727.  
  9728. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9729.  
  9730. %@AB@%EAX%@AE@% = Flags    (Appropriate flags from CB_VM_Status control block
  9731. field)          %@AB@%VMMStat_Exclusive%@AE@%          %@AB@%VMStat_Background%@AE@%
  9732. %@AB@%VMStat_High_Pri_Back%@AE@% %@AB@%ECX %@AE@%= Foreground time-slice priority (high word 0) %@AB@%EDX%@AE@%
  9733. = Background time-slice priority (high word 0) %@AB@%ESI%@AE@% = % of total CPU time
  9734. used by VM  %@NL@%
  9735.  
  9736.  
  9737. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9738.  
  9739. Flags  %@NL@%
  9740.  
  9741. %@CR:C6A00250020 @%%@CR:C6A00250021 @%
  9742. %@2@%%@CR:C6A00250022 @%%@AB@%Release_Time_Slice%@AE@%%@EH@%%@NL@%
  9743. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9744.  
  9745.  
  9746. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9747.  
  9748. This service causes the current VM to give up any time remaining in its
  9749. current time slice and allows the next VM in the time-slice queue to run.
  9750. This service should be called whenever a VM is idle to allow other VMs to
  9751. execute faster. If there is only one VM in the time-slice queue, this
  9752. service will do nothing.  %@NL@%
  9753.  
  9754. When this service is called for a background VM, it will release the VM's
  9755. time-slice, and adjust the VM's execution time by -500 milliseconds. This
  9756. assures that idle background-VMs will take up very little CPU time.  %@NL@%
  9757.  
  9758. If the focus VM or a high priority background VM calls this service, it will
  9759. only give up it's time slice. It's execution time will not be adjusted.  %@NL@%
  9760.  
  9761.  
  9762. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9763.  
  9764. None  %@NL@%
  9765.  
  9766.  
  9767. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9768.  
  9769. None  %@NL@%
  9770.  
  9771.  
  9772. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9773.  
  9774. Flags  %@NL@%
  9775.  
  9776. %@CR:C6A00250023 @%%@CR:C6A00250024 @%
  9777. %@2@%%@CR:C6A00250025 @%%@AB@%Set_Execution_Focus%@AE@%%@EH@%%@NL@%
  9778. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9779.  
  9780.  
  9781. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9782.  
  9783. This service changes the time-slice exection focus to the specified virtual
  9784. machine. The VM with the focus executes with its foreground priority. If the
  9785. %@AB@%VMStat_Exclusive%@AE@% flag is set, then it will be the only VM scheduled.
  9786. Otherwise, background VMs will be allowed to run. All VMs except the focus
  9787. VM, background VMs, and the system VM will be suspended.  %@NL@%
  9788.  
  9789. This service must only be called in the system VM or when the new focus is
  9790. the same as the current VM (%@AB@%EBX%@AE@% = Cur_VM_Handle).  %@NL@%
  9791.  
  9792.  
  9793. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9794.  
  9795. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  9796.  
  9797.  
  9798. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9799.  
  9800. If carry set then  ERROR: Could not set focus else  Focus set successfully  %@NL@%
  9801.  
  9802.  
  9803. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9804.  
  9805. Flags  %@NL@%
  9806.  
  9807. %@CR:C6A00250026 @%%@CR:C6A00250027 @%
  9808. %@2@%%@CR:C6A00250028 @%%@AB@%Set_Time_Slice_Granularity%@AE@%%@EH@%%@NL@%
  9809. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9810.  
  9811.  
  9812. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9813.  
  9814. This service is used to change the minimum amount of time the time-slice
  9815. scheduler will allocate to a VM. Smaller values will make multitasking
  9816. appear smoother but will increase overhead due to the large number of task
  9817. switches required. Larger values will allow more time for the VMs to execute
  9818. but may make execution appear sporadic to the user.  %@NL@%
  9819.  
  9820.  
  9821. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9822.  
  9823. %@AB@%EAX%@AE@% = Minimum time-slice size in milliseconds  %@NL@%
  9824.  
  9825.  
  9826. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9827.  
  9828. None  %@NL@%
  9829.  
  9830.  
  9831. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9832.  
  9833. Flags  %@NL@%
  9834.  
  9835. %@CR:C6A00250029 @%%@CR:C6A00250030 @%
  9836. %@2@%%@CR:C6A00250031 @%%@AB@%Set_Time_Slice_Priority%@AE@%%@EH@%%@NL@%
  9837. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9838.  
  9839.  
  9840. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9841.  
  9842. This service sets the time-slice execution flags and the foreground and
  9843. background priorities for a specified VM.  %@NL@%
  9844.  
  9845. To change part of a VM's time-slice priority status, first call
  9846. %@AB@%Get_Time_Slice_Priority%@AE@%, then change only the values you are interested in
  9847. and call this service. For example, to set a VM into background mode, you
  9848. would do the following:  %@NL@%
  9849.  
  9850. %@AS@%  mov ebx, [Handle_Of_VM_To_Change] 
  9851. %@AS@%  VMMcall  Get_Time_Slice_Priority 
  9852. %@AS@%  or eax, VMStat_Background 
  9853. %@AS@%  VMMcall  Set_Time_Slice_Priority%@AE@%
  9854.  
  9855.  
  9856. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9857.  
  9858. %@AB@%EAX%@AE@% = Flags  %@AB@%VMStat_Exclusive%@AE@%  %@AB@%VMStat_Background%@AE@%  %@AB@%VMStat_High_Pri_Back%@AE@% %@AB@%EBX%@AE@% =
  9859. VM handle %@AB@%ECX%@AE@% = Foreground priority (high word must be 0) %@AB@%EDX%@AE@% = Background
  9860. priority (high word must be 0)  %@NL@%
  9861.  
  9862.  
  9863. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9864.  
  9865. If carry set then  ERROR: Could not change priority / flags for VM else
  9866. Priority and flags changed  %@NL@%
  9867.  
  9868.  
  9869. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9870.  
  9871. Flags  %@NL@%
  9872.  
  9873. %@CR:C6A00250032 @%%@CR:C6A00250033 @%
  9874. %@2@%%@CR:C6A00250034 @%%@AB@%Wake_Up_VM%@AE@%%@EH@%%@NL@%
  9875. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9876.  
  9877.  
  9878. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9879.  
  9880. This service is used to "wake up" a VM that called the %@AB@%Release_Time_Slice%@AE@%
  9881. service and has the VMStat_Idle flag set. If the specified VM is not idle,
  9882. this service will do nothing.  %@NL@%
  9883.  
  9884.  
  9885. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9886.  
  9887. %@AB@%EBX%@AE@% = Handle of VM begin woken up  %@NL@%
  9888.  
  9889.  
  9890. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9891.  
  9892. None  %@NL@%
  9893.  
  9894.  
  9895. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  9896.  
  9897. Flags  %@NL@%
  9898.  
  9899.  
  9900.  
  9901.  
  9902.  
  9903.  
  9904. %@CR:C6A00260001 @%%@1@%%@AB@%Chapter 26  Event Services%@AE@%%@EH@%%@NL@%
  9905. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9906.  
  9907. Enhanced Windows is a single-threaded, non-reentrant operating environment.
  9908. Because it is non-reentrant, VxDs that hook hardware interrupts must have
  9909. some method of synchronizing their calls to VMM. For this reason, enhanced
  9910. Windows has the concept of "event" processing.%@CR:C6A00260002 @%%@NL@%
  9911.  
  9912. When a VxD is entered due to an asynchronous interrupt, such as a hardware
  9913. interrupt, the VxD is limited to a very specific subset of functions. It is
  9914. allowed to do only the following:  %@NL@%
  9915.  
  9916.  
  9917.   ■   Call any Virtual PIC Device (VPICD) service%@NL@%
  9918.  
  9919.   ■   Call any asynchronous VMM service (see individual services for
  9920.       details)%@NL@%
  9921.  
  9922.   ■   Schedule events%@NL@%
  9923.  
  9924.  
  9925. Obviously, VxDs that service hardware interrupts will often need to use
  9926. services other than the ones listed above. When this is the case, the VxD
  9927. will need to schedule an event. When an event is scheduled, the caller
  9928. defines a procedure to call when it is OK to make any VMM call. When VMM
  9929. calls this procedure, the VxD can finish processing the asynchronous event.
  9930. %@NL@%
  9931.  
  9932. VM events are often useful for VxDs that do not service hardware interrupts
  9933. and can be scheduled at any time except during a Non-Maskable Interrupt
  9934. (NMI).  %@NL@%
  9935.  
  9936. When an event service routine is called, it is entered with the following:  %@NL@%
  9937.  
  9938.  
  9939.   ■   %@AB@%EBX%@AE@% = Current VM handle %@NL@%
  9940.  
  9941.   ■   %@AB@%EDX%@AE@% = Reference data passed when the routine was set up%@NL@%
  9942.  
  9943.   ■   %@AB@%EBP%@AE@% -> Client register structure%@NL@%
  9944.  
  9945.  
  9946. 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@%
  9947.  
  9948. The discussion of services providing support for events is presented in the
  9949. following order:  %@NL@%
  9950.  
  9951.  
  9952.   ■   %@AB@%Call_Global_Event%@AE@%%@NL@%
  9953.  
  9954.   ■   %@AB@%Call_Priority_VM_Event%@AE@%%@NL@%
  9955.  
  9956.   ■   %@AB@%Call_VM_Event%@AE@%%@NL@%
  9957.  
  9958.   ■   %@AB@%Cancel_Global_Event%@AE@%%@NL@%
  9959.  
  9960.   ■   %@AB@%Cancel_Priority_VM_Event%@AE@%%@NL@%
  9961.  
  9962.   ■   %@AB@%Cancel_VM_Event%@AE@%%@NL@%
  9963.  
  9964.   ■   %@AB@%Hook_NMI_Event%@AE@%%@NL@%
  9965.  
  9966.   ■   %@AB@%Schedule_Global_Event%@AE@%%@NL@%
  9967.  
  9968.   ■   %@AB@%Schedule_VM_Event%@AE@%%@NL@%
  9969.  
  9970.  
  9971. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  9972. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  9973.  
  9974. %@CR:C6A00260003 @%
  9975. %@2@%%@CR:C6A00260004 @%%@AB@%Call_Global_Event%@CR:C6A00260005 @%%@AE@%%@EH@%%@NL@%
  9976. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9977.  
  9978.  
  9979. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  9980.  
  9981. This procedure is a faster method of servicing asynchronous events. If the
  9982. current thread of execution begins in a VM (it was %@AI@%not%@AE@% an interrupt from
  9983. within the VMM), then the event procedure will be called immediately.
  9984. Otherwise, the event will be scheduled.  %@NL@%
  9985.  
  9986.  
  9987. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  9988.  
  9989. %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will be passed back
  9990. to procedure)  %@NL@%
  9991.  
  9992.  
  9993. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  9994.  
  9995. If %@AB@%ESI %@AE@%= 0 then  Event procedure was called else  %@AB@%ESI%@AE@% = Event handle (can be
  9996. used to cancel events)  %@NL@%
  9997.  
  9998.  
  9999. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10000.  
  10001. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10002.  
  10003.  
  10004. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10005.  
  10006. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client Register
  10007. Structure  %@NL@%
  10008.  
  10009. %@CR:C6A00260006 @%%@CR:C6A00260007 @%
  10010. %@2@%%@CR:C6A00260008 @%%@AB@%Call_Priority_VM_Event%@AE@%%@EH@%%@NL@%
  10011. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10012.  
  10013.  
  10014. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10015.  
  10016. This service combines the functionality of %@AB@%Call_VM_Event,
  10017. %@AB@%Call_When_VM_Ints_Enabled, Call_When_Not_Critical%@AE@%, and %@AB@%Adjust_Exec_Priority%@AE@%
  10018. into one, easy to use service. As with all event services, this service can
  10019. be called from an interrupt handler.  %@NL@%
  10020.  
  10021. %@AB@%Call_Priority_VM_Event%@AE@% is used by VxDs for several purposes. The most common
  10022. uses are as follows:  %@NL@%
  10023.  
  10024.  
  10025.   ■   To wait until a VM enables interrupts and the critical section is free
  10026.       so the VxD can call DOS or some other non-reentrant code. %@NL@%
  10027.  
  10028.   ■   To boost a VM's priority and wait until the VM enables interrupts to
  10029.       simulate an interrupt type event. For example, the VNETBIOS uses this
  10030.       service for asynchronous network request POST callbacks. %@NL@%
  10031.  
  10032.   ■   To force an event to be processed in another VM by boosting the VM's
  10033.       Execution Priority.%@NL@%
  10034.  
  10035.  
  10036.  
  10037. %@3@%%@AB@%Example%@AE@%%@EH@%%@NL@%
  10038.  
  10039. Assume a VxD implements a print spooler that will call a VM back when a
  10040. buffer has been sent to the printer. It could use this service to notify the
  10041. appropriate VM that its buffer has been printed as follows:  %@NL@%
  10042.  
  10043. %@AS@%  VxD_Code_SEG
  10044. %@AS@%   BeginProc Print_Buff_Empty
  10045. %@AS@%   mov  eax, Low_pri_Device_boost
  10046. %@AS@%   mov  ebx, [Call_Back_VM_Handle]
  10047. %@AS@%   mov  ecx, PEF_Wait_ForSTI or PEF_Wait_Not_Crit
  10048. %@AS@%   mov  edx, [Call_back_CS_IP]
  10049. %@AS@%   mov  esi, Buff_Empty_Call_Back_Event
  10050. %@AS@%   VMMcall   Call_Priority_Event
  10051. %@AS@%   ret
  10052. %@AS@%   EndProc  Print_Buff_Empty
  10053. %@AS@%   BeginProc  Buff_Empty_Call_Back_Event
  10054. %@AS@%   VMMcall  Begin_Nest_Exec  ;Get ready to call VM
  10055. %@AS@%   mov   ecx,  edx
  10056. %@AS@%   shr   edx,  16   ;ECX = Segment to call
  10057. %@AS@%   movzx  edx, dx   ;EDX = Offset to call
  10058. %@AS@%   VMMcall    Build_Int_Stack_Frame
  10059. %@AS@%   VMMcall    Resume_Exec  ;call the VMM's callback
  10060. %@AS@%   VMMcall End_Nest_Exec
  10061. %@AS@%   ret
  10062. %@AS@%   EndProc    Buff_Empty_Call_Back_Event%@AE@%
  10063.  
  10064. The %@AB@%Print_Buff_Empty%@AE@% procedure could be called from a hardware interrupt
  10065. handler in any VM. It uses %@AB@%Call_Priority_VM_Event%@AE@% to force the correct VM to
  10066. be scheduled. The priority boost specified in %@AB@%EAX %@AE@%will force the event to be
  10067. processed quickly although not as fast as a hardware interrupt. The options
  10068. specified in the %@AB@%ECX%@AE@% register will force the event to be delayed until the
  10069. critical section is free and the VM's interrupts are enabled. The reference
  10070. data in %@AB@%EDX%@AE@% contains the %@AB@%CS:IP %@AE@%of the procedure to call in the VM.  %@NL@%
  10071.  
  10072. When %@AB@%Buff_Empty_Call_Back_Event%@AE@% is called it can make several assumptions:
  10073. it is running in the desired VM, the critical section is not owned, and the
  10074. VM has enabled interrupts. It uses the %@AB@%CS:IP%@AE@% value passed in %@AB@%EDX%@AE@% to simulate
  10075. a pseudo-interrupt in the VM. The procedure called in the VM would have to
  10076. execute an IRET to return from the callback. When %@AB@%Buff_Empty_Call_Back_Event%@AE@%
  10077. returns, the execution priority boost is automatically deducted.  %@NL@%
  10078.  
  10079. Notice this example is incomplete ─ An actual VxD handler would need to do
  10080. more work. It does not address several problems. For example
  10081. %@AB@%Buff_Empty_Call_Back_Event%@AE@% does not take into account whether the call
  10082. should be made to a V86 CS:IP or protected mode CS:IP. It also would not
  10083. work for 32-bit protected mode programs since it would need to pass a 32-bit
  10084. offset (EIP) to Simulate_Far_Call.  %@NL@%
  10085.  
  10086.  
  10087. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10088.  
  10089. %@AB@%EAX%@AE@% = Priority boost (can be 0) %@AB@%EBX%@AE@% = VM handle %@AB@%ECX%@AE@% = Option flags (defined
  10090. in VMM.INC)  PEF_Wait_For_STI - Event will not be called until  VM enables
  10091. interrupts  PEF_Wait_Not_Crit - Event will not be called until  VM is not in
  10092. a critical section  or time-critical operation.  PEF_Dont_Unboost - Priority
  10093. of VM will not be reduced  after return from event procedure.
  10094. PEF_Always_Sched - Always schedule the event. This means  the event
  10095. procedure will never be called immediately.  All other bits are reserved and
  10096. must be 0. %@AB@%EDX%@AE@% = Reference data (will be passed back to procedure) %@AB@%ESI%@AE@% =
  10097. Offset of procedure to call  %@NL@%
  10098.  
  10099.  
  10100. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10101.  
  10102. If ESI = 0 then  Event procedure already called  else  Event procedure will
  10103. be called later ESI = Event handle (can cancel using
  10104. Cancel_Priority_VM_Event)  %@NL@%
  10105.  
  10106.  
  10107. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10108.  
  10109. Flags  %@NL@%
  10110.  
  10111.  
  10112. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10113.  
  10114. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  10115. structure  %@NL@%
  10116.  
  10117. Procedure can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,%@AB@% EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  10118.  
  10119. %@CR:C6A00260009 @%
  10120. %@2@%%@CR:C6A00260010 @%%@AB@%Call_VM_Event%@CR:C6A00260011 @%%@AE@%%@EH@%%@NL@%
  10121. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10122.  
  10123.  
  10124. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10125.  
  10126. This procedure is a faster method of servicing asynchronous events. If the
  10127. current thread of execution begins in a virtual machine (it was %@AI@%not %@AE@%an
  10128. interrupt from within the VMM) %@AI@%and%@AE@% the event is for the current VM, then the
  10129. event procedure will be called immediately. Otherwise, the event will be
  10130. scheduled.  %@NL@%
  10131.  
  10132.  
  10133. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10134.  
  10135. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will
  10136. be passed back to procedure)  %@NL@%
  10137.  
  10138.  
  10139. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10140.  
  10141. If ESI = 0 then  Event procedure was called else  ESI = Event handle (can be
  10142. used to cancel events)  %@NL@%
  10143.  
  10144.  
  10145. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10146.  
  10147. Flags  %@NL@%
  10148.  
  10149.  
  10150. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10151.  
  10152. %@AB@%EBX %@AE@%= Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  10153. structure  %@NL@%
  10154.  
  10155. %@CR:C6A00260012 @%%@CR:C6A00260013 @%
  10156. %@2@%%@CR:C6A00260014 @%%@AB@%Cancel_Global_Event%@AE@%%@EH@%%@NL@%
  10157. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10158.  
  10159.  
  10160. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10161.  
  10162. This service is used to cancel an event that was previously scheduled by
  10163. %@AB@%Schedule_Global_Event%@AE@% or %@AB@%Call_Global_Event%@AE@%. Notice that, once a scheduled
  10164. event is serviced, you must not attempt to cancel that event.  %@NL@%
  10165.  
  10166. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10167. NOTE 
  10168.  
  10169. %@AI@%It is valid to pass %@AB@%ESI%@AE@%%@AI@% = 0 to this service (it will do nothing). This is
  10170. %@AI@%provided so that code that uses this service can use 0 to indicate no event
  10171. %@AI@%scheduled and not have to perform a test every time it wants to cancel an
  10172. %@AI@%event. For example: %@AE@%%@AE@%
  10173. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10174.  
  10175. %@AS@%  xor     esi, esi
  10176. %@AS@%      xchg    esi, [My_Event_Handle]
  10177. %@AS@%      VMMcall Cancel_Global_Event%@AE@%
  10178.  
  10179. %@AI@%will always work even if no event was scheduled. You will also need to set
  10180. [%@AB@%My_Event_Handle%@AE@%] to 0 in your event procedure. %@AE@%
  10181.  
  10182. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10183.  
  10184. %@AB@%ESI%@AE@% = Event handle (0 is acceptable)  %@NL@%
  10185.  
  10186.  
  10187. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10188.  
  10189. Global event has been canceled  %@NL@%
  10190.  
  10191.  
  10192. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10193.  
  10194. Flags  %@NL@%
  10195.  
  10196. %@CR:C6A00260015 @%%@CR:C6A00260016 @%
  10197. %@2@%%@CR:C6A00260017 @%%@AB@%Cancel_Priority_VM_Event%@AE@%%@EH@%%@NL@%
  10198. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10199.  
  10200.  
  10201. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10202.  
  10203. This service is used to cancel an event that was previously scheduled by
  10204. %@AB@%Call_Priority_VM_Event.%@AE@% Notice that once a scheduled event is serviced, you
  10205. must not attempt to cancel that event.  %@NL@%
  10206.  
  10207. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10208. NOTE 
  10209.  
  10210. %@AI@%It is valid to pass %@AB@%ESI%@AE@%%@AI@% = 0 to this service (it will do nothing). This is
  10211. %@AI@%provided so that code that uses this service can use 0 to indicate no event
  10212. %@AI@%scheduled and not have to perform a test every time it wants to cancel an
  10213. %@AI@%event. For example: %@AE@%%@AE@%
  10214. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10215.  
  10216. %@AS@%  xor     esi, esi
  10217. %@AS@%      xchg    esi, [My_Event_Handle]
  10218. %@AS@%      VMMcall Cancel_VM_Event%@AE@%
  10219.  
  10220. %@AI@%will always work even if no event was scheduled. You will also need to set
  10221. [%@AB@%My_Event_Handle%@AE@%] to 0 in your event procedure. %@AE@%
  10222. Any priority boost associated with this event will be canceled even if the
  10223. %@AB@%PEF_DONT_UNBOOST%@AE@% flag was set when the event was scheduled.  %@NL@%
  10224.  
  10225. Do not use this service to cancel events scheduled using the %@AB@%Call_VM_Event
  10226. %@AB@%%@AE@%or %@AB@%Schedule_VM_Event%@AE@% services. You must cancel normal VM events using the
  10227. %@AB@%Cancel_VM_Event%@AE@% service.  %@NL@%
  10228.  
  10229.  
  10230. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10231.  
  10232. %@AB@%ESI%@AE@% = Priority event handle (0 is valid)  %@NL@%
  10233.  
  10234.  
  10235. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10236.  
  10237. Event canceled, %@AB@%ESI%@AE@% contains garbage  %@NL@%
  10238.  
  10239.  
  10240. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10241.  
  10242. Flags, %@AB@%ESI%@AE@%  %@NL@%
  10243.  
  10244. %@CR:C6A00260018 @%
  10245. %@2@%%@CR:C6A00260019 @%%@AB@%Cancel_VM_Event%@CR:C6A00260020 @%%@AE@%%@EH@%%@NL@%
  10246. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10247.  
  10248.  
  10249. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10250.  
  10251. This service is used to cancel an event that was previously scheduled by
  10252. %@AB@%Schedule_VM_Event%@AE@% or %@AB@%Call_VM_Event%@AE@%. Notice that, once a scheduled event is
  10253. serviced, you must not attempt to cancel that event.  %@NL@%
  10254.  
  10255. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10256. NOTE 
  10257.  
  10258. %@AI@%It is valid to pass %@AB@%ESI%@AE@%%@AI@% = 0 to this service (it will do nothing). This is
  10259. %@AI@%provided so that code that uses this service can use 0 to indicate no event
  10260. %@AI@%scheduled and not have to perform a test every time it wants  to cancel an
  10261. %@AI@%event. For example:%@AE@%%@AE@%
  10262. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10263.  
  10264. %@AS@%  xor     esi, esi
  10265. %@AS@%      xchg    esi, [My_Event_Handle]
  10266. %@AS@%      VMMcall Cancel_VM_Event%@AE@%
  10267.  
  10268. %@AI@%will always work even if no event was scheduled. You will also need to set
  10269. [%@AB@%My_Event_Handle%@AE@%] to 0 in your event procedure. %@AE@%
  10270. Do not use this service to cancel events scheduled using the
  10271. %@AB@%Call_Priority_VM_Event%@AE@% service. You must cancel priority events using the
  10272. %@AB@%Cancel_Priority_VM_Event%@AE@% service.  %@NL@%
  10273.  
  10274.  
  10275. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10276.  
  10277. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Event handle (0 is acceptable)  %@NL@%
  10278.  
  10279.  
  10280. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10281.  
  10282. None  %@NL@%
  10283.  
  10284.  
  10285. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10286.  
  10287. Flags  %@NL@%
  10288.  
  10289. %@CR:C6A00260021 @%
  10290. %@2@%%@CR:C6A00260022 @%%@AB@%Hook_NMI_Event%@CR:C6A00260023 @%%@AE@%%@EH@%%@NL@%
  10291. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10292.  
  10293.  
  10294. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10295.  
  10296. See documentation for Get_NMI_Handler_Addr for information on this service.
  10297. This service must only be called during initialization.  %@NL@%
  10298.  
  10299.  
  10300. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10301.  
  10302. %@AB@%ESI%@AE@% = Address of NMI event procedure  %@NL@%
  10303.  
  10304.  
  10305. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10306.  
  10307. None  %@NL@%
  10308.  
  10309.  
  10310. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10311.  
  10312. Flags  %@NL@%
  10313.  
  10314.  
  10315. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10316.  
  10317. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client Register Structure  %@NL@%
  10318.  
  10319. %@CR:C6A00260024 @%%@CR:C6A00260025 @%
  10320. %@2@%%@CR:C6A00260026 @%%@AB@%Schedule_Global_Event%@AE@%%@EH@%%@NL@%
  10321. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10322.  
  10323.  
  10324. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10325.  
  10326. This procedure is used to schedule asynchronous events that are not VM
  10327. specific. The events will be processed immediately before the VMM IRETs to
  10328. any VM.  %@NL@%
  10329.  
  10330.  
  10331. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10332.  
  10333. %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will be passed back
  10334. to procedure)  %@NL@%
  10335.  
  10336.  
  10337. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10338.  
  10339. %@AB@%ESI %@AE@%= Event handle (can be used to cancel event)  %@NL@%
  10340.  
  10341.  
  10342. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10343.  
  10344. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10345.  
  10346.  
  10347. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10348.  
  10349. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EDX%@AE@% = Reference data %@AB@%EBP%@AE@% -> Client register
  10350. structure  %@NL@%
  10351.  
  10352. %@CR:C6A00260027 @%
  10353. %@2@%%@CR:C6A00260028 @%%@AB@%Schedule_VM_Event%@CR:C6A00260029 @%%@AE@%%@EH@%%@NL@%
  10354. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10355.  
  10356.  
  10357. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10358.  
  10359. This procedure is used to schedule asynchronous events that are VM specific.
  10360. The events will be processed immediately before the VMM IRETs to the
  10361. specified VM.  %@NL@%
  10362.  
  10363. VM events will only be executed in the VM for which they were scheduled for.
  10364. Therefore, if a VM event is scheduled for a VM other than the current
  10365. virtual machine, it will not be processed until a task switch occurs to that
  10366. VM.  %@NL@%
  10367.  
  10368.  
  10369. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10370.  
  10371. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Offset of procedure to call %@AB@%EDX%@AE@% = Reference data (will
  10372. be passed back to procedure)  %@NL@%
  10373.  
  10374.  
  10375. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10376.  
  10377. %@AB@%ESI%@AE@% = Event handle (can be used to cancel event)  %@NL@%
  10378.  
  10379.  
  10380. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10381.  
  10382. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10383.  
  10384.  
  10385. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10386.  
  10387. %@AB@%EBX%@AE@% = Current VM handle (VM event was scheduled for) %@AB@%EDX%@AE@% = Reference data
  10388. %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  10389.  
  10390.  
  10391.  
  10392.  
  10393.  
  10394.  
  10395. %@CR:C6A00270001 @%%@1@%%@AB@%Chapter 27  Timing Services%@AE@%%@EH@%%@NL@%
  10396. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10397.  
  10398. Timing services are provided for use by VxDs that need to perform periodic
  10399. operations or need to establish the amount of time elapsed since a
  10400. particular event. They are described here in the following order:  %@NL@%
  10401.  
  10402.  
  10403.   ■   %@AB@%Cancel_Time_Out%@AE@%%@NL@%
  10404.  
  10405.   ■   %@AB@%Get_Last_Updated_System_Time%@AE@%%@NL@%
  10406.  
  10407.   ■   %@AB@%Get_Last_Updated_VM_Exec_Time%@AE@%%@NL@%
  10408.  
  10409.   ■   %@AB@%Get_System_Time%@AE@%%@NL@%
  10410.  
  10411.   ■   %@AB@%Get_VM_Exec_Time%@AE@%%@NL@%
  10412.  
  10413.   ■   %@AB@%Set_Global_Time_Out%@AE@%%@NL@%
  10414.  
  10415.   ■   %@AB@%Set_VM_Time_Out%@AE@%%@NL@%
  10416.  
  10417.   ■   %@AB@%Update_System_Clock%@AE@%%@NL@%
  10418.  
  10419.  
  10420. See Chapter 16, "Overview of Windows in Enhanced Mode," and Chapter 17,
  10421. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  10422.  
  10423. %@CR:C6A00270002 @%
  10424. %@2@%%@CR:C6A00270003 @%%@AB@%Cancel_Time_Out%@CR:C6A00270004 @%%@AE@%%@EH@%%@NL@%
  10425. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10426.  
  10427.  
  10428. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10429.  
  10430. This service is used to cancel a time-out that was scheduled through either
  10431. %@AB@%Set_VM_Time_Out%@AE@% or %@AB@%Set_Global_Time_Out%@AE@%.  %@NL@%
  10432.  
  10433. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10434. NOTE
  10435.  
  10436. %@AI@%It is valid to pass ESI = 0 to this service (it will do nothing). This is
  10437. %@AI@%provided so that code that uses this service can use 0 to indicate no
  10438. %@AI@%time-out scheduled and not have to perform a test every time it wants  to
  10439. %@AI@%cancel a time-out. For example:%@AE@%
  10440. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10441.  
  10442. %@AS@%  xor      esi, esi
  10443. %@AS@%    xchg     esi, [Local_Time_Out_Handle]
  10444. %@AS@%    call      Cancel_Time_Out %@AE@%
  10445.  
  10446. %@AI@%will always work even if no time-out was scheduled. %@AE@%
  10447.  
  10448. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10449.  
  10450. %@AB@%ESI%@AE@% = Time-out handle to cancel OR 0 if no time-out to be canceled  %@NL@%
  10451.  
  10452.  
  10453. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10454.  
  10455. Time-out is canceled, old time-out handle now invalid  %@NL@%
  10456.  
  10457.  
  10458. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10459.  
  10460. Flags  %@NL@%
  10461.  
  10462. %@CR:C6A00270005 @%%@CR:C6A00270006 @%
  10463. %@2@%%@CR:C6A00270007 @%%@AB@%Get_Last_Updated_System_Time%@AE@%%@EH@%%@NL@%
  10464. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10465.  
  10466. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10467. NOTE
  10468.  
  10469. %@AI@%The description for this service has been identified as out of date and the
  10470. %@AI@%updated information was unavailable for this release.%@AE@%
  10471. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10472.  
  10473. %@CR:C6A00270008 @%%@CR:C6A00270009 @%
  10474. %@2@%%@CR:C6A00270010 @%%@AB@%Get_Last_Updated_VM_Exec_Time%@AE@%%@EH@%%@NL@%
  10475. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10476.  
  10477. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10478. NOTE
  10479.  
  10480. %@AI@%The description for this service has been identified as out of date and the
  10481. %@AI@%updated information was unavailable for this release.%@AE@%
  10482. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10483.  
  10484. %@CR:C6A00270011 @%
  10485. %@2@%%@CR:C6A00270012 @%%@AB@%Get_System_Time%@CR:C6A00270013 @%%@AE@%%@EH@%%@NL@%
  10486. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10487.  
  10488.  
  10489. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10490.  
  10491. This service will return the time in milliseconds since the enhanced Windows
  10492. environment was started. There is no way to detect rollover of the clock
  10493. through this function but the clock will take 49.5 days to roll over.  %@NL@%
  10494.  
  10495. If you are concerned about rollover, you should schedule a time-out every 30
  10496. days.  %@NL@%
  10497.  
  10498.  
  10499. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10500.  
  10501. None  %@NL@%
  10502.  
  10503.  
  10504. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10505.  
  10506. %@AB@%EAX%@AE@% = Elapsed time in milliseconds since enhanced Windows was started  %@NL@%
  10507.  
  10508.  
  10509. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10510.  
  10511. %@AB@%EAX%@AE@%, Flags  %@NL@%
  10512.  
  10513. %@CR:C6A00270014 @%
  10514. %@2@%%@CR:C6A00270015 @%%@AB@%Get_VM_Exec_Time%@CR:C6A00270016 @%%@AE@%%@EH@%%@NL@%
  10515. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10516.  
  10517.  
  10518. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10519.  
  10520. This service returns the amount of time that a particular VM has executed.
  10521. Every VM starts with an %@AB@%Exec_Time%@AE@% of 0 when it is created, and the %@AB@%Exec_Time%@AE@%
  10522. is only increased when the VM is actually executed. Therefore, the value
  10523. returned does %@AI@%not%@AE@% reflect the length of time the VM has existed. Instead, it
  10524. indicates the amount of time that task has actually been the currently
  10525. running VM.  %@NL@%
  10526.  
  10527.  
  10528. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10529.  
  10530. None  %@NL@%
  10531.  
  10532.  
  10533. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10534.  
  10535. %@AB@%EAX %@AE@%= Amount of time in milliseconds that VM has executed  %@NL@%
  10536.  
  10537.  
  10538. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10539.  
  10540. %@AB@%EAX,%@AE@% Flags  %@NL@%
  10541.  
  10542. %@CR:C6A00270017 @%%@CR:C6A00270018 @%
  10543. %@2@%%@CR:C6A00270019 @%%@AB@%Set_Global_Time_Out%@AE@%%@EH@%%@NL@%
  10544. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10545.  
  10546.  
  10547. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10548.  
  10549. Schedules a time-out that will occur after %@AB@%EAX%@AE@% milliseconds have elapsed.  %@NL@%
  10550.  
  10551. The callback procedure will be called with %@AB@%ECX%@AE@% equal to the number of
  10552. milliseconds that have elapsed since the actual time-out occurred. Time-outs
  10553. are often delayed by 10 milliseconds or more since the normal system timer
  10554. runs at 20 milliseconds or slower. If you need more accurate time-outs, then
  10555. you must increase the timer interrupt frequency. See the VTD documentation
  10556. for more details on setting the timer interrupt period.  %@NL@%
  10557.  
  10558.  
  10559. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10560.  
  10561. %@AB@%EAX%@AE@% = Number of milliseconds to wait until time-out %@AB@%EDX%@AE@% = Reference data to
  10562. return to procedure %@AB@%ESI%@AE@% = Address of procedure to call when time-out occurs
  10563. %@NL@%
  10564.  
  10565.  
  10566. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10567.  
  10568. If time-out was NOT scheduled then  ESI = 0 (This is useful since 0 = NO
  10569. TIME-OUT SCHEDULED)  else  ESI = Time-out handle (used to cancel time-out)  %@NL@%
  10570.  
  10571.  
  10572. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10573.  
  10574. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10575.  
  10576.  
  10577. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10578.  
  10579. %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = Number of EXTRA milliseconds that have elapsed
  10580. %@AB@%EDX %@AE@%= Reference data %@AB@%EBP%@AE@% -> Client register structure Procedure may corrupt
  10581. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  10582.  
  10583. %@CR:C6A00270020 @%
  10584. %@2@%%@CR:C6A00270021 @%%@AB@%Set_VM_Time_Out%@CR:C6A00270022 @%%@AE@%%@EH@%%@NL@%
  10585. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10586.  
  10587.  
  10588. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10589.  
  10590. Schedules a time-out that will occur after a VM has executed for the
  10591. specified length of time. Notice that the time-out will occur after the VM
  10592. has run for %@AB@%EAX%@AE@% milliseconds. Therefore, if there is more that one VM
  10593. executing, it may take more than%@AB@% EAX%@AE@% milliseconds to occur.  %@NL@%
  10594.  
  10595. The callback procedure will be called with %@AB@%ECX%@AE@% equal to the number of
  10596. milliseconds that have elapsed since the actual time-out occurred. Time-outs
  10597. are often delayed by 10 milliseconds or more since the normal system timer
  10598. runs at 20 milliseconds or slower. If you need more accurate time-outs, then
  10599. you must increase the timer interrupt frequency. See the VTD documentation
  10600. for more details on setting the timer interrupt period.  %@NL@%
  10601.  
  10602.  
  10603. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10604.  
  10605. %@AB@%EAX%@AE@% = Number of milliseconds to wait until time-out %@AB@%EBX %@AE@%= VM handle %@AB@%EDX%@AE@% =
  10606. Reference data to return to procedure %@AB@%ESI%@AE@% = Address of procedure to call
  10607. when time-out occurs  %@NL@%
  10608.  
  10609.  
  10610. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10611.  
  10612. %@AS@%  If time-out was NOT scheduled then
  10613. %@AS@%      ESI = 0 (This is useful since 0 = NO TIME-OUT SCHEDULED) 
  10614. %@AS@%  else
  10615. %@AS@%      ESI = Time-out handle (used to cancel time-out)%@AE@%
  10616.  
  10617.  
  10618. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10619.  
  10620. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10621.  
  10622.  
  10623. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10624.  
  10625. %@AB@%EBX%@AE@% = Current VM handle (VM time-out was scheduled for) %@AB@%ECX%@AE@% = Number of
  10626. EXTRA milliseconds that have elapsed %@AB@%EDX %@AE@%= Reference data %@AB@%EBP%@AE@% -> Client
  10627. 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
  10628. Flags.  %@NL@%
  10629.  
  10630. %@CR:C6A00270023 @%%@CR:C6A00270024 @%
  10631. %@2@%%@CR:C6A00270025 @%%@AB@%Update_System_Clock%@AE@%%@EH@%%@NL@%
  10632. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10633.  
  10634.  
  10635. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10636.  
  10637. This service must be called only by the Virtual Timer Device. If more than
  10638. one device calls this service, then the VMM timing services will not behave
  10639. correctly. The timer calls this procedure to update the current system time
  10640. and the current VM's execution time. The value passed in %@AB@%ECX%@AE@% is the number
  10641. of milliseconds that have elapsed since the last call to this service. In
  10642. other words, if the current system time is%@AI@% n%@AE@%, then, after a call to
  10643. %@AB@%Update_System_Clock,%@AE@% the current system time would be %@AI@%n%@AE@%+%@AB@%ECX%@AE@%.  %@NL@%
  10644.  
  10645. This service assumes interrupts are disabled!  %@NL@%
  10646.  
  10647.  
  10648. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10649.  
  10650. %@AB@%ECX%@AE@% = Elapsed time in milliseconds  %@NL@%
  10651.  
  10652.  
  10653. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10654.  
  10655. Flags  %@NL@%
  10656.  
  10657.  
  10658.  
  10659.  
  10660.  
  10661.  
  10662. %@CR:C6A00280001 @%%@1@%%@AB@%Chapter 28  Processor Fault and Interrupt Services%@AE@%%@EH@%%@NL@%
  10663. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10664.  
  10665. The discussion of services providing general support for processor faults
  10666. and interrupts are presented in the following order:  %@NL@%
  10667.  
  10668.  
  10669.   ■   %@AB@%Get_Fault_Hook_Addrs%@AE@%%@NL@%
  10670.  
  10671.   ■   %@AB@%Get_NMI_Handler_Addr%@AE@%%@NL@%
  10672.  
  10673.  
  10674. @lb1 = %@AB@%Hook_PM_Fault%@AE@%  %@NL@%
  10675.  
  10676.  
  10677.   ■   %@AB@%Hook_NMI_Event%@AE@%%@NL@%
  10678.  
  10679.  
  10680. @lb1 = %@AB@%Hook_V86_Fault  %@AE@%%@NL@%
  10681.  
  10682.  
  10683.   ■   %@AB@%Hook_V86_Page%@AE@%%@NL@%
  10684.  
  10685.  
  10686. @lb1 = %@AB@%Hook_VMM_Fault  %@AE@%%@NL@%
  10687.  
  10688.  
  10689.   ■   %@AB@%Set_NMI_Handler_Addr%@AE@%%@NL@%
  10690.  
  10691.  
  10692. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  10693. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  10694.  
  10695. %@CR:C6A00280002 @%
  10696. %@2@%%@CR:C6A00280003 @%%@AB@%Get_Fault_Hook_Addrs%@AE@%%@EH@%%@NL@%
  10697. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10698.  
  10699.  
  10700. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10701.  
  10702. Returns the address of the V86 mode, PM application, and VMM reenter fault
  10703. handlers for a specified fault. If the fault does not have a handler, then
  10704. this procedure will return 0. You cannot get the hook address for interrupt
  10705. 2 (NMI). You must use the %@AB@%Get/Set_NMI_Handler_Addr%@AE@% services to hook
  10706. interrupt 2.  %@NL@%
  10707.  
  10708.  
  10709. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10710.  
  10711. %@AB@%EAX%@AE@% = Interrupt number  %@NL@%
  10712.  
  10713.  
  10714. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10715.  
  10716. If carry clear then  EDX = Address of V86 Mode App fault handler (0 if none
  10717. installed)  ESI = Address of Prot Mode App fault handler (0 if none
  10718. installed)  EDI = Address of VMM Re-enter fault handler (0 if none
  10719. installed)  else  ERROR: Invalid fault number  %@NL@%
  10720.  
  10721.  
  10722. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10723.  
  10724. Flags  %@NL@%
  10725.  
  10726. %@CR:C6A00280004 @%
  10727. %@2@%%@CR:C6A00280005 @%%@AB@%Get_NMI_Handler_Addr%@AE@%%@EH@%%@NL@%
  10728. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10729.  
  10730.  
  10731. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10732.  
  10733. If a VxD needs to hook the Non-Maskable Interrupt (NMI), it must first call
  10734. this service to get the current NMI handler address, save the address so the
  10735. current handler can be chained to it, and then set the new address.  %@NL@%
  10736.  
  10737. Notice that your NMI interrupt handler can only touch local data in the
  10738. device's VxD_LOCKED_DATA_SEG. It cannot touch memory in a VM handle, V86
  10739. memory, or any other memory. It also cannot call %@AI@%any%@AE@% services, %@AI@%including%@AE@%
  10740. services that can be called during normal hardware interrupts. Because an
  10741. NMI can occur at any time, it is difficult to do much of anything during
  10742. interrupt time that is guaranteed not to reenter a non-reentrant procedure
  10743. or affect a data structure.  %@NL@%
  10744.  
  10745. Most NMI handlers will want to have an NMI event handler. This handler is
  10746. similar to a normal event handler except that you only need to hook the NMI
  10747. event chain once instead of scheduling an event every time. Every NMI event
  10748. handler will be called every time an NMI occurs. Thus, most NMI interrupt
  10749. routines simply detect that the NMI is for them and set a variable that
  10750. their NMI event handler uses to perform some function. For example:  %@NL@%
  10751.  
  10752. %@AS@%  Initialization:
  10753. %@AS@%      VMMcall Get_NMI_Handler_Addr
  10754. %@AS@%      mov     [NMI_Chain_Addr], esi
  10755. %@AS@%      mov     esi, OFFSET32 My_NMI_Handler
  10756. %@AS@%      VMMcall Set_NMI_Handler_Addr
  10757. %@AS@%      mov     esi, OFFSET32 My_NMI_Event
  10758. %@AS@%      VMMcall Hook_NMI_Event
  10759. %@AS@%      clc
  10760. %@AS@%      ret%@AE@%
  10761.  
  10762. %@AS@%  My_NMI_Handler:
  10763. %@AS@%      in    al, My_Stat_Port
  10764. %@AS@%      test  al, My_Int_Mask
  10765. %@AS@%      jz    SHORT MNH_Exit
  10766. %@AS@%      inc   [NMI_From_Me]
  10767. %@AS@%  MNH_Chain:
  10768. %@AS@%      jmp   [NMI_Chain_Addr]%@AE@%
  10769.  
  10770. %@AS@%  My_NMI_Event:
  10771. %@AS@%      xor   al, al
  10772. %@AS@%      xchg  al, [NMI_From_Me]
  10773. %@AS@%      test  al, al
  10774. %@AS@%      jz    SHORT NME_Exit
  10775. %@AS@%   (Do something here ─ NMI from my device) 
  10776. %@AS@%  MNE_Exit:
  10777. %@AS@%      ret%@AE@%
  10778.  
  10779.  
  10780. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10781.  
  10782. None  %@NL@%
  10783.  
  10784.  
  10785. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10786.  
  10787. %@AB@%ESI%@AE@% = Offset of current NMI handler  %@NL@%
  10788.  
  10789.  
  10790. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10791.  
  10792. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10793.  
  10794. %@CR:C6A00280006 @%
  10795. %@2@%%@CR:C6A00280007 @%%@AB@%Hook_NMI_Event%@AE@%%@EH@%%@NL@%
  10796. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10797.  
  10798.  
  10799. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10800.  
  10801. See the documentation mentioned earlier in this chapter on
  10802. %@AB@%Get_NMI_Handler_Addr%@AE@% for information on this service.  %@NL@%
  10803.  
  10804.  
  10805. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10806.  
  10807. %@AB@%ESI %@AE@%= Address of NMI event procedure  %@NL@%
  10808.  
  10809.  
  10810. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10811.  
  10812. None  %@NL@%
  10813.  
  10814.  
  10815. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10816.  
  10817. Flags  %@NL@%
  10818.  
  10819.  
  10820. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10821.  
  10822. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure  %@NL@%
  10823.  
  10824. Procedure may corrupt %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%  %@NL@%
  10825.  
  10826. %@CR:C6A00280008 @%%@CR:C6A00280009 @%%@CR:C6A00280010 @%
  10827. %@2@%%@CR:C6A00280011 @%%@AB@%Hook_V86_Fault, Hook_PM_Fault, Hook_VMM_Fault%@AE@%%@EH@%%@NL@%
  10828. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10829.  
  10830.  
  10831. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10832.  
  10833. These services replace the fault handler procedure address with the
  10834. procedure supplied. They will return the old fault handler's address or 0 to
  10835. indicate that there was no previous fault handler. If the value returned in
  10836. ESI is non-zero, then you may chain to the next handler with ALL REGISTERS
  10837. PRESERVED. Your handler can "eat" a fault without chaining by executing a
  10838. 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@%
  10839.  
  10840. If you hook a fault during the %@AB@%Sys_Critical_Init%@AE@% phase of device
  10841. initialization, your fault handler will be "behind" any VMM fault handler.
  10842. If the VMM cannot properly handle a fault (for example, a General Protection
  10843. fault), then it will chain to the next handler. By hooking GP faults during
  10844. %@AB@%Sys_Critical_Init%@AE@% your VxD can intercept any GP fault that would otherwise
  10845. crash the current VM. Any hooks installed after %@AB@%Sys_Critical_Init%@AE@% will be
  10846. placed "in front of" the default VMM fault handlers. This allows devices to
  10847. examine faults before they are processed by the VMM.  %@NL@%
  10848.  
  10849. Note that the processor Non-Maskable Interrupt (NMI) must be hooked using
  10850. the %@AB@%Get/Set_NMI_Addr%@AE@% services (do not call Hook_xxx_Fault with %@AB@%EAX%@AE@% = 2).
  10851. Also, hardware interrupts should be hooked using the Virtual Programmable
  10852. Interrupt Controller Device (VPICD). A VxD should NOT attempt to circumvent
  10853. the VPICD using these services.  %@NL@%
  10854.  
  10855. For version 3.0 of enhanced Windows, the largest interrupt number available
  10856. is 4FH. Interrupts 00H-1FH are reserved by Intel for processor faults.
  10857. Interrupts 20H-2FH are reserved by enhanced Windows. Interrupts 50H-5FH are
  10858. used by the VPICD. Interrupts 40H and 41H are used by the debugger.
  10859. Interrupts 42H-4FH are free for use by VxDs.  %@NL@%
  10860.  
  10861.  
  10862. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10863.  
  10864. %@AB@%EAX%@AE@% = Interrupt number %@AB@%ESI%@AE@% = Procedure offset  %@NL@%
  10865.  
  10866.  
  10867. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10868.  
  10869. If carry clear then  %@AB@%ESI%@AE@% = Old procedure offset (0 if none) else  ERROR:
  10870. Invalid fault number in EAX  %@NL@%
  10871.  
  10872.  
  10873. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10874.  
  10875. %@AB@%ESI%@AE@%, Flags  %@NL@%
  10876.  
  10877.  
  10878. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10879.  
  10880. Interrupts disabled %@AB@%EBX%@AE@% = Current VM handle If fault from V86 or PM app then
  10881. %@AB@%EBP%@AE@% -> Client_Register_Strucuture else  VMM reentered ─ Only asynchronous
  10882. services may be called.  %@AB@%EBP%@AE@% -> VMM re-entrant fault stack frame  %@NL@%
  10883.  
  10884. If your handler chains, then it must preserve %@AI@%all%@AE@% registers (even registers
  10885. %@AI@%not%@AE@% documented as entry conditions to this callback).  %@NL@%
  10886.  
  10887. %@CR:C6A00280012 @%
  10888. %@2@%%@CR:C6A00280013 @%%@AB@%Hook_V86_Page%@AE@%%@EH@%%@NL@%
  10889. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10890.  
  10891.  
  10892. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10893.  
  10894. This service allows VxDs to intercept page faults in portions of the V86
  10895. address space of every virtual machine. It is used by devices such as the
  10896. Virtual Display Device to detect when particular address ranges are
  10897. accessed.  %@NL@%
  10898.  
  10899. You must specify a page number and address of a callback routine to this
  10900. service. If it is installed successfully, your hook will be called every
  10901. time a page fault occurs in %@AI@%any%@AE@% VM on that page. See the memory manager
  10902. %@AB@%_Modify_Pages%@AE@% documentation in Chapter 19, "Memory Management Services," for
  10903. making hooked pages not present and for registering the ownership of pages.
  10904. %@NL@%
  10905.  
  10906. The callback routine is responsible for mapping memory at the location of
  10907. the page fault or crashing the VM. In unusual circumstances, it may be
  10908. appropriate to map a NULL page at the faulting address page. See the memory
  10909. manager documentation for details on mapping memory and mapping NULL pages.
  10910. %@NL@%
  10911.  
  10912. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10913. NOTE 
  10914.  
  10915. %@AI@%Do not rely on the contents of the %@AB@%CR2%@AE@%%@AI@% (page fault) register. Use the value
  10916. %@AI@%passed to your callback in %@AE@%%@AI@%%@AB@%EAX%@AE@%%@AE@%%@AI@%. %@AE@%%@AE@%
  10917. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10918.  
  10919.  
  10920. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10921.  
  10922. %@AB@%EAX%@AE@% = Page number (A0h - FFh) %@AB@%ESI = Address of trap routine  %@AE@%%@NL@%
  10923.  
  10924.  
  10925. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10926.  
  10927. If carry flag set then  ERROR: Invalid page number or page already hooked
  10928. else  Page hooked  %@NL@%
  10929.  
  10930.  
  10931. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10932.  
  10933. Procedure may corrupt %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  10934.  
  10935.  
  10936. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  10937.  
  10938. %@AB@%EAX%@AE@% = Faulting page number %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% does NOT point to the
  10939. client register structure.  %@NL@%
  10940.  
  10941. %@CR:C6A00280014 @%
  10942. %@2@%%@CR:C6A00280015 @%%@AB@%Set_NMI_Handler_Addr%@AE@%%@EH@%%@NL@%
  10943. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10944.  
  10945.  
  10946. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  10947.  
  10948. See the documentation mentioned earlier in this chapter on
  10949. %@AB@%Get_NMI_Handler_Addr%@AE@% for information on this service.  %@NL@%
  10950.  
  10951.  
  10952. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  10953.  
  10954. %@AB@%ESI%@AE@% = Offset of new NMI handler  %@NL@%
  10955.  
  10956.  
  10957. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  10958.  
  10959. None  %@NL@%
  10960.  
  10961.  
  10962. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  10963.  
  10964. Flags  %@NL@%
  10965.  
  10966.  
  10967.  
  10968.  
  10969.  
  10970.  
  10971. %@CR:C6A00290001 @%%@1@%%@AB@%Chapter 29  Information Services%@AE@%%@EH@%%@NL@%
  10972. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10973.  
  10974. These services return the requested information without instigating any
  10975. other action.  %@NL@%
  10976.  
  10977. They provide information on the following:  %@NL@%
  10978.  
  10979.  
  10980.   ■   VM handles%@NL@%
  10981.  
  10982.   ■   The VMM reenter count%@NL@%
  10983.  
  10984.   ■   HMA XMS%@NL@%
  10985.  
  10986.   ■   Installation status of the debugger%@NL@%
  10987.  
  10988.  
  10989. They are described here in the following order:  %@NL@%
  10990.  
  10991.  
  10992.   ■   %@AB@%Get_Cur_VM_Handle%@AE@%%@NL@%
  10993.  
  10994.   ■   %@AB@%Get_Next_VM_Handle%@AE@%%@NL@%
  10995.  
  10996.   ■   %@AB@%Get_Sys_VM_Handle%@AE@%%@NL@%
  10997.  
  10998.   ■   %@AB@%Get_VMM_Reenter_Count%@AE@%%@NL@%
  10999.  
  11000.   ■   %@AB@%Get_VMM_Version%@AE@%%@NL@%
  11001.  
  11002.   ■   %@AB@%GetSet_HMA_Info%@AE@%%@NL@%
  11003.  
  11004.   ■   %@AB@%Test_Cur_VM_Handle%@AE@%%@NL@%
  11005.  
  11006.   ■   %@AB@%Test_Debug_Installed%@AE@%%@NL@%
  11007.  
  11008.   ■   %@AB@%Test_Sys_VM_Handle%@AE@%%@NL@%
  11009.  
  11010.   ■   %@AB@%Validate_VM_Handle%@AE@%%@NL@%
  11011.  
  11012.  
  11013. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  11014. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  11015.  
  11016. %@CR:C6A00290002 @%%@CR:C6A00290003 @%
  11017. %@2@%%@CR:C6A00290004 @%%@AB@%Get_Cur_VM_Handle%@AE@%%@EH@%%@NL@%
  11018. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11019.  
  11020.  
  11021. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11022.  
  11023. This service returns the handle to the currently running VM. It is valid to
  11024. call this service at interrupt time.  %@NL@%
  11025.  
  11026.  
  11027. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11028.  
  11029. None  %@NL@%
  11030.  
  11031.  
  11032. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11033.  
  11034. %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  11035.  
  11036.  
  11037. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11038.  
  11039. %@AB@%EBX%@AE@%, Flags  %@NL@%
  11040.  
  11041. %@CR:C6A00290005 @%%@CR:C6A00290006 @%
  11042. %@2@%%@CR:C6A00290007 @%%@AB@%Get_Next_VM_Handle%@AE@%%@EH@%%@NL@%
  11043. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11044.  
  11045.  
  11046. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11047.  
  11048. VMM maintains a list of all valid VM handles. This service provides a means
  11049. of scanning the list easily. Normally, code that uses this service looks
  11050. something like this:  %@NL@%
  11051.  
  11052. %@AS@%  VMMcall Get_Cur_VM_Handle
  11053. %@AS@%   Scan_Loop:
  11054. %@AS@%   ...
  11055. %@AS@%   (Do something to VM state)
  11056. %@AS@%   ...
  11057. %@AS@%   VMMcall Get_Next_VM_Handle
  11058. %@AS@%   VMMcall  Test_Cur_VM_Handle
  11059. %@AS@%   jne Scan_Loop%@AE@%
  11060.  
  11061. This allows the state of every VM to be modified. However, there are also
  11062. other uses for this service. There is no guaranteed ordering of the list
  11063. other than the fact that each VM will appear in the list only once. Notice
  11064. also that the list is circular so you will need to test for the end case
  11065. (Next VM = First VM). It is valid to call this service at interrupt time.  %@NL@%
  11066.  
  11067.  
  11068. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11069.  
  11070. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  11071.  
  11072.  
  11073. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11074.  
  11075. %@AB@%EBX%@AE@% = Next VM handle in VM list  %@NL@%
  11076.  
  11077.  
  11078. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11079.  
  11080. %@AB@%EBX%@AE@%, Flags  %@NL@%
  11081.  
  11082. %@CR:C6A00290008 @%%@CR:C6A00290009 @%
  11083. %@2@%%@CR:C6A00290010 @%%@AB@%Get_Sys_VM_Handle%@AE@%%@EH@%%@NL@%
  11084. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11085.  
  11086.  
  11087. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11088.  
  11089. This service returns the System VM handle. It is valid to call this service
  11090. at interrupt time.  %@NL@%
  11091.  
  11092.  
  11093. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11094.  
  11095. None  %@NL@%
  11096.  
  11097.  
  11098. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11099.  
  11100. %@AB@%EBX%@AE@% = System VM handle  %@NL@%
  11101.  
  11102.  
  11103. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11104.  
  11105. %@AB@%EBX%@AE@%, Flags  %@NL@%
  11106.  
  11107. %@CR:C6A00290011 @%%@CR:C6A00290012 @%
  11108. %@2@%%@CR:C6A00290013 @%%@AB@%Get_VMM_Reenter_Count%@AE@%%@EH@%%@NL@%
  11109. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11110.  
  11111.  
  11112. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11113.  
  11114. This service is used to determine if the VMM has been reentered from an
  11115. interrupt. The normal situation for reentering VMM is from a hardware
  11116. interrupt, page fault, or other processor exception. Since most VMM services
  11117. are non-reentrant, this test should be used to determine if other VMM
  11118. services can be called or if a global event should be scheduled. Notice that
  11119. the %@AB@%Call_Global_Event%@AE@% service tests this condition automatically and will
  11120. schedule an event if VMM has been reentered.  %@NL@%
  11121.  
  11122.  
  11123. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11124.  
  11125. None  %@NL@%
  11126.  
  11127.  
  11128. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11129.  
  11130. %@AB@%ECX%@AE@% = 0 indicates VMM has NOT been re-entered. If  0 then %@AB@%ECX%@AE@% = # of times
  11131. re-entered  %@NL@%
  11132.  
  11133.  
  11134. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11135.  
  11136. Flags  %@NL@%
  11137.  
  11138. %@CR:C6A00290014 @%
  11139. %@2@%%@CR:C6A00290015 @%%@AB@%Get_VMM_Version%@CR:C6A00290016 @%%@AE@%%@EH@%%@NL@%
  11140. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11141.  
  11142.  
  11143. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11144.  
  11145. This service returns the Windows VMM version.  %@NL@%
  11146.  
  11147.  
  11148. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11149.  
  11150. None  %@NL@%
  11151.  
  11152.  
  11153. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11154.  
  11155. %@AB@%AH%@AE@% = Major version number (3) %@AB@%AL%@AE@% = Minor version number (0) Carry flag clear
  11156. %@NL@%
  11157.  
  11158.  
  11159. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11160.  
  11161. %@AB@%EAX%@AE@% , Flags  %@NL@%
  11162.  
  11163. %@CR:C6A00290017 @%
  11164. %@2@%%@CR:C6A00290018 @%%@AB@%GetSet_HMA_Info%@CR:C6A00290019 @%%@AE@%%@EH@%%@NL@%
  11165. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11166.  
  11167.  
  11168. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11169.  
  11170. This service returns and sets information related to the HMA XMS region.  %@NL@%
  11171.  
  11172. This service is intended to assist the XMS driver that is part of the
  11173. V86MMGR device. It allows the protected-mode XMS code to find out if there
  11174. was a global HMA user in before enhanced Windows was started and allows
  11175. access to the Enable count variable (Get and Set). This service is always
  11176. valid (i.e., not restricted to initialization).  %@NL@%
  11177.  
  11178.  
  11179. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11180.  
  11181. %@AB@%ECX%@AE@% == 0 Get %@AB@%ECX%@AE@%  0 Set  %@AB@%DX%@AE@% = A20 enable count to set for enhanced Windows
  11182. loader  NOTE THAT THE GLOBAL HMA FLAG CANNOT BE SET. It is not  appropriate
  11183. or valid to set this.  %@NL@%
  11184.  
  11185.  
  11186. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11187.  
  11188. If Get  %@AB@% EAX%@AE@% == 0 if enhanced Windows DID NOT allocate the HMA (GLOBAL HMA
  11189. User)  %@AB@% EAX%@AE@%  0 if enhanced Windows allocated the HMA (NO GLOBAL HMA User)
  11190. %@AB@%EDX%@AE@% = A20 enable count before enhanced Windows came in If Set  %@NL@%
  11191.  
  11192.  
  11193. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11194.  
  11195. %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11196.  
  11197. %@CR:C6A00290020 @%%@CR:C6A00290021 @%
  11198. %@2@%%@CR:C6A00290022 @%%@AB@%Test_Cur_VM_Handle%@AE@%%@EH@%%@NL@%
  11199. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11200.  
  11201.  
  11202. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11203.  
  11204. This routine tests to see if the given VM handle is the handle of the
  11205. currently running VM. It is valid to call this service at interrupt time.  %@NL@%
  11206.  
  11207.  
  11208. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11209.  
  11210. %@AB@%EBX%@AE@% = VM handle to test  %@NL@%
  11211.  
  11212.  
  11213. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11214.  
  11215. Zero flag is set if VM handle passed in is currently running VM's handle.  %@NL@%
  11216.  
  11217.  
  11218. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11219.  
  11220. Flags  %@NL@%
  11221.  
  11222. %@CR:C6A00290023 @%%@CR:C6A00290024 @%
  11223. %@2@%%@CR:C6A00290025 @%%@AB@%Test_Debug_Installed%@AE@%%@EH@%%@NL@%
  11224. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11225.  
  11226.  
  11227. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11228.  
  11229. Tests internal flag that indicates whether a debugger exists or not. It is
  11230. valid to call this service at interrupt time.  %@NL@%
  11231.  
  11232.  
  11233. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11234.  
  11235. None  %@NL@%
  11236.  
  11237.  
  11238. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11239.  
  11240. Zero flag = Debugger NOT installed (i.e., jz No_Debug_Installed)  %@NL@%
  11241.  
  11242.  
  11243. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11244.  
  11245. Flags  %@NL@%
  11246.  
  11247. %@CR:C6A00290026 @%%@CR:C6A00290027 @%
  11248. %@2@%%@CR:C6A00290028 @%%@AB@%Test_Sys_VM_Handle%@AE@%%@EH@%%@NL@%
  11249. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11250.  
  11251.  
  11252. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11253.  
  11254. This routine tests to see if the given VM handle is the handle of the system
  11255. VM. It is valid to call this service at interrupt time.  %@NL@%
  11256.  
  11257.  
  11258. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11259.  
  11260. %@AB@%EBX%@AE@% = VM handle to test  %@NL@%
  11261.  
  11262.  
  11263. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11264.  
  11265. Zero flag is set if VM handle passed in is system VM's handle. (je
  11266. %@AB@%Is_Sys_VM%@AE@%)  %@NL@%
  11267.  
  11268.  
  11269. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11270.  
  11271. Flags  %@NL@%
  11272.  
  11273. %@CR:C6A00290029 @%%@CR:C6A00290030 @%
  11274. %@2@%%@CR:C6A00290031 @%%@AB@%Validate_VM_Handle%@AE@%%@EH@%%@NL@%
  11275. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11276.  
  11277.  
  11278. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11279.  
  11280. This service is used to test the validity of a VM handle. This service can
  11281. be called at interrupt time.  %@NL@%
  11282.  
  11283.  
  11284. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11285.  
  11286. %@AB@%EBX%@AE@% = VM handle to test  %@NL@%
  11287.  
  11288.  
  11289. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11290.  
  11291. If carry flag set then    ERROR:VM handle is invalid else    Value in %@AB@%EBX%@AE@% is
  11292. a valid VM handle  %@NL@%
  11293.  
  11294.  
  11295. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11296.  
  11297. Flags  %@NL@%
  11298.  
  11299.  
  11300.  
  11301.  
  11302.  
  11303.  
  11304. %@CR:C6A00300001 @%%@1@%%@AB@%Chapter 30  Initialization Information Services%@AE@%%@EH@%%@NL@%
  11305. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11306.  
  11307. These services provide access to the SYSTEM.INI file and the environment
  11308. variables. Configurable VxDs will use these services to get their
  11309. configuration parameters. They are described here in the following order:  %@NL@%
  11310.  
  11311.  
  11312.   ■   %@AB@%Convert_Boolean_String%@AE@%%@NL@%
  11313.  
  11314.   ■   %@AB@%Convert_Decimal_String%@AE@%%@NL@%
  11315.  
  11316.   ■   %@AB@%Convert_Fixed_Point_String%@AE@%%@NL@%
  11317.  
  11318.   ■   %@AB@%Convert_Hex_String%@AE@%%@NL@%
  11319.  
  11320.   ■   %@AB@%Get_Config_Directory%@AE@%%@NL@%
  11321.  
  11322.   ■   %@AB@%GetDOSVectors%@AE@%%@NL@%
  11323.  
  11324.   ■   %@AB@%Get_Environment_String%@AE@%%@NL@%
  11325.  
  11326.   ■   %@AB@%Get_Exec_Path%@AE@%%@NL@%
  11327.  
  11328.   ■   %@AB@%Get_Machine_Info%@AE@%%@NL@%
  11329.  
  11330.   ■   %@AB@%Get_Next_Profile_String%@AE@%%@NL@%
  11331.  
  11332.   ■   %@AB@%Get_Profile_Boolean%@AE@%%@NL@%
  11333.  
  11334.   ■   %@AB@%Get_Profile_Decimal_Int%@AE@%%@NL@%
  11335.  
  11336.   ■   %@AB@%Get_Profile_Fixed_Point%@AE@%%@NL@%
  11337.  
  11338.   ■   %@AB@%Get_Profile_Hex_Int%@AE@%%@NL@%
  11339.  
  11340.   ■   %@AB@%Get_Profile_String%@AE@%%@NL@%
  11341.  
  11342.   ■   %@AB@%Get_PSP_Segment%@AE@%%@NL@%
  11343.  
  11344.   ■   %@AB@%OpenFile%@AE@%%@NL@%
  11345.  
  11346.  
  11347. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  11348. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  11349.  
  11350. %@CR:C6A00300002 @%%@CR:C6A00300003 @%
  11351. %@2@%%@CR:C6A00300004 @%%@AB@%Convert_Boolean_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11352. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11353.  
  11354.  
  11355. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11356.  
  11357. This service attempts to determine if the string pointed to by%@AB@% EDX%@AE@% is TRUE
  11358. or FALSE. There are many valid values for TRUE and FALSE. A short list of
  11359. valid values for TRUE are:  %@NL@%
  11360.  
  11361.  True, Yes, On, 1  %@NL@%
  11362.  
  11363. For false they include:  %@NL@%
  11364.  
  11365.  False, No, Off, 0  %@NL@%
  11366.  
  11367. This list may grow to include other words such as "oui" and "ja." This
  11368. service is only valid during initialization.  %@NL@%
  11369.  
  11370.  
  11371. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11372.  
  11373. %@AB@%EDX%@AE@% = Pointer to ASCIIZ string to convert to boolean  %@NL@%
  11374.  
  11375.  
  11376. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11377.  
  11378. If carry clear then  EAX = 0 if FALSE, -1 if TRUE, zero flag NOT set else
  11379. String was not a valid boolean (EAX not changed)  %@NL@%
  11380.  
  11381.  
  11382. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11383.  
  11384. Flags, %@AB@%EAX%@AE@%  %@NL@%
  11385.  
  11386. %@CR:C6A00300005 @%%@CR:C6A00300006 @%
  11387. %@2@%%@CR:C6A00300007 @%%@AB@%Convert_Decimal_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11388. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11389.  
  11390.  
  11391. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11392.  
  11393. This service converts a string that contains a decimal value and returns the
  11394. value in %@AB@%EAX%@AE@%. It also returns a pointer to the character that terminated the
  11395. decimal integer value. This is useful for parsing entries such as:  %@NL@%
  11396.  
  11397.  FOO=100,300  %@NL@%
  11398.  
  11399. since the 100 would be returned with %@AB@%EDX %@AE@%pointing to the ",". The pointer
  11400. could be incremented one byte and, then, this service called again to
  11401. evaluate the second number.  %@NL@%
  11402.  
  11403. Notice that a NULL string or a string that does not contain a valid decimal
  11404. integer will return 0 and %@AB@%EDX%@AE@% will not be advanced since the first character
  11405. of the string terminated the analysis. This service is only valid during
  11406. initialization.  %@NL@%
  11407.  
  11408.  
  11409. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11410.  
  11411. %@AB@%EDX %@AE@%= Pointer to ASCIIZ string to convert to integer  %@NL@%
  11412.  
  11413.  
  11414. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11415.  
  11416. %@AB@%EAX%@AE@% = Value of decimal string %@AB@%EDX%@AE@% = Pointer to terminating character
  11417. (non-valid decimal char)  %@NL@%
  11418.  
  11419.  
  11420. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11421.  
  11422. %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11423.  
  11424. %@CR:C6A00300008 @%%@CR:C6A00300009 @%
  11425. %@2@%%@CR:C6A00300010 @%%@AB@%Convert_Fixed_Point_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11426. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11427.  
  11428.  
  11429. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11430.  
  11431. This service returns the value of a fixed point decimal number string
  11432. pointed to by %@AB@%EDX.%@AE@% Use %@AB@%Get_Profile_String%@AE@% to initialize %@AB@%EDX%@AE@% to point to the
  11433. string to be parsed. Fixed Point is zero or more decimal digits followed by
  11434. a terminator or a decimal point followed by zero or more decimal digits. The
  11435. value returned is %@AB@%ECX%@AE@%*10*>. Note that decimal digits beyond the accuracy
  11436. specified by %@AB@%ECX%@AE@% are ignored in the value returned in %@AB@%EAX,%@AE@% but %@AB@%EDX%@AE@% points to
  11437. the byte following the last valid ASCII decimal digit. Values that begin
  11438. with a minus will evaluate to negative numbers. Positive values may
  11439. optionally begin with a plus sign.  %@NL@%
  11440.  
  11441. This service is only valid during initialization.  %@NL@%
  11442.  
  11443.  
  11444. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11445.  
  11446. %@AB@%ECX%@AE@% = Number of decimal places %@AB@%EDX%@AE@% = Pointer to ASCIIZ string to convert to
  11447. integer  %@NL@%
  11448.  
  11449.  
  11450. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11451.  
  11452. %@AB@%EAX%@AE@% = Value of fixed point string %@AB@%EDX%@AE@% = Pointer to terminating character
  11453. (non-valid character)  %@NL@%
  11454.  
  11455.  
  11456. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11457.  
  11458. %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11459.  
  11460. %@CR:C6A00300011 @%%@CR:C6A00300012 @%
  11461. %@2@%%@CR:C6A00300013 @%%@AB@%Convert_Hex_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11462. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11463.  
  11464.  
  11465. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11466.  
  11467. This service converts the string pointed to by %@AB@%EDX%@AE@% to Hexadecimal.
  11468. Hexadecimal is zero or more hexadecimal digits (0-9, A-F) followed by a
  11469. terminating character or a small or capital letter "h". The "h" has no
  11470. effect on the value. %@AB@%EDX%@AE@% is left pointing to the next byte after the "h" or,
  11471. if the "h" is not present, after the last valid hexadecimal digit. Use
  11472. %@AB@%Get_Profile_String%@AE@% to set up %@AB@%EDX%@AE@% to point to the string to be parsed. This
  11473. service is only valid during initialization.  %@NL@%
  11474.  
  11475.  
  11476. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11477.  
  11478. %@AB@%EDX%@AE@% -> ASCIIZ string to convert to integer  %@NL@%
  11479.  
  11480.  
  11481. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11482.  
  11483. %@AB@%EAX%@AE@% = Value of hexadecimal string %@AB@%EDX%@AE@% advanced to terminating character
  11484. (non-valid hex char)  %@NL@%
  11485.  
  11486.  
  11487. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11488.  
  11489. Flags  %@NL@%
  11490.  
  11491. %@CR:C6A00300014 @%%@CR:C6A00300015 @%
  11492. %@2@%%@CR:C6A00300016 @%%@AB@%Get_Config_Directory (Initialization only)%@AE@%%@EH@%%@NL@%
  11493. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11494.  
  11495.  
  11496. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11497.  
  11498. This service returns a pointer to the directory that contains the
  11499. configuration files for the enhanced Windows environment (such as
  11500. SYSTEM.INI). The string returned is guaranteed to be a valid, fully
  11501. qualified pathname that ends with a terminating "\" followed by a NULL (0)
  11502. byte.  %@NL@%
  11503.  
  11504.  
  11505. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11506.  
  11507. None  %@NL@%
  11508.  
  11509.  
  11510. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11511.  
  11512. %@AB@%EDX%@AE@% = Pointer to ASCIIZ directory name  %@NL@%
  11513.  
  11514.  
  11515. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11516.  
  11517. %@AB@%EDX%@AE@%, Flags  %@NL@%
  11518.  
  11519. %@CR:C6A00300017 @%%@CR:C6A00300018 @%
  11520. %@2@%%@CR:C6A00300019 @%%@AB@%Get_Environment_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11521. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11522.  
  11523.  
  11524. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11525.  
  11526. This service takes a pointer to an ASCIIZ string that is the name of an
  11527. environment variable and returns a pointer to an ASCIIZ string that is the
  11528. value of that environment variable. Environment variables are set using the
  11529. MS-DOS %@AB@%SET%@AE@% command and should be of the format "%@AB@%SET%@AE@% <%@AI@%variable
  11530. %@AS@%name%@AE@%>=<%@AI@%variable value%@AE@%>" with no intervening spaces between the variable
  11531. name, the equal sign, and the variable value. Environment strings are an
  11532. alternative way of setting parameters for virtual device drivers. In
  11533. general, these should be used sparingly, as the environment is of limited
  11534. size. Use environment strings only when the value is a global entity, used
  11535. by more than one program or device driver. This service is only valid during
  11536. initialization.  %@NL@%
  11537.  
  11538.  
  11539. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11540.  
  11541. %@AB@%ESI%@AE@% = pointer to ASCIIZ string environment variable name  %@NL@%
  11542.  
  11543.  
  11544. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11545.  
  11546. If carry is set then  Environment string was not found else  EDX = pointer
  11547. to ASCIIZ string value of environment variable  %@NL@%
  11548.  
  11549.  
  11550. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11551.  
  11552. %@AB@%EDX%@AE@%, Flags  %@NL@%
  11553.  
  11554. %@CR:C6A00300020 @%%@CR:C6A00300021 @%
  11555. %@2@%%@CR:C6A00300022 @%%@AB@%Get_Exec_Path (Initialization only)%@AE@%%@EH@%%@NL@%
  11556. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11557.  
  11558.  
  11559. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11560.  
  11561. This service returns a pointer to an ASCIIZ string that gives the full path
  11562. by which WIN386.EXE was executed. It is used to locate files associated with
  11563. the enhanced Windows environment or the virtual device drivers that are not
  11564. in subdirectories indicated by the PATH environment variable. This service
  11565. is only valid during initialization.  %@NL@%
  11566.  
  11567.  
  11568. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11569.  
  11570. None  %@NL@%
  11571.  
  11572.  
  11573. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11574.  
  11575. %@AB@%EDX%@AE@% = Pointer to ASCIIZ string of full path name + program name (program
  11576. name is  "WIN386.EXE") %@AB@%ECX%@AE@% = Number of characters in string up to and
  11577. including the last "\"  %@NL@%
  11578.  
  11579. %@CR:C6A00300023 @%
  11580. %@2@%%@CR:C6A00300024 @%%@AB@%GetDOSVectors (Initialization only)%@CR:C6A00300025 @%%@AE@%%@EH@%%@NL@%
  11581. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11582.  
  11583.  
  11584. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11585.  
  11586. This service returns the "true" INT 23 and INT 24 MS-DOS vectors. The
  11587. enhanced Windows loader points these vectors at its own handlers which have
  11588. the correct behavior for the enhanced Windows LOAD. When a VM is started up
  11589. we wish to reset these vectors to the handlers that were in place before the
  11590. loader changed them.  %@NL@%
  11591.  
  11592. THIS SERVICE SHOULD ONLY BE USED BY THE DOSMGR DEVICE.  %@NL@%
  11593.  
  11594.  
  11595. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11596.  
  11597.  
  11598. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11599.  
  11600. EAX = Segment:Offset (V86 address) that INT 23 pointed to before loader EDX
  11601. = Segment:Offset (V86 address) that INT 24 pointed to before loader  %@NL@%
  11602.  
  11603.  
  11604. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11605.  
  11606. %@CR:C6A00300026 @%%@CR:C6A00300027 @%
  11607. %@2@%%@CR:C6A00300028 @%%@AB@%Get_Machine_Info (Initialization only)%@AE@%%@EH@%%@NL@%
  11608. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11609.  
  11610.  
  11611. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11612.  
  11613. This service returns information about the computer system running enhanced
  11614. Windows.  %@NL@%
  11615.  
  11616.  
  11617. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11618.  
  11619. None  %@NL@%
  11620.  
  11621.  
  11622. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11623.  
  11624. %@AB@%AH%@AE@% = MS-DOS Major Version %@AB@%AL%@AE@%   = MS-DOS Minor Version %@AB@%BH%@AE@%   = MS-DOS OEM
  11625. serial number %@AB@%BL%@AE@%   = Machine Model Byte (at F000:FFFE in system ROM) HIGH 16
  11626. bits of %@AB@%EBX%@AE@% are other flags  GMIF_80486 EQU 10000h 80486 processor
  11627. GMIF_PCXT EQU 20000h PC/XT(tm) accelerator  GMIF_MCA EQU 40000h Micro
  11628. Channel(tm)  GMIF_EISA EQU 80000h EISA %@AB@%EDX%@AE@% = Equipment flags (as returned
  11629. from Int 11h) %@AB@%ECX%@AE@% = 0 if not PS/2 or extended BIOS, else %@AB@%ECX%@AE@% contains a
  11630. ring 0 linear address to System Configuration Parameters  returned from BIOS
  11631. service Int 15h, AH=C0h. See the PS/2  BIOS documentation for details on
  11632. this structure.  %@NL@%
  11633.  
  11634.  
  11635. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11636.  
  11637. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  11638.  
  11639. %@CR:C6A00300029 @%%@CR:C6A00300030 @%
  11640. %@2@%%@CR:C6A00300031 @%%@AB@%Get_Next_Profile_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11641. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11642.  
  11643.  
  11644. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11645.  
  11646. This service, given a pointer to a profile string, will return a pointer to
  11647. the next profile string with the key name provided. It is used by devices
  11648. that have multiple entries with the same key name. First, use
  11649. %@AB@%Get_Profile_String%@AE@% to get the first entry with a given key name and, then,
  11650. use this service to get subsequent entries. Do not modify the string
  11651. returned. This service is only valid during initialization.  %@NL@%
  11652.  
  11653.  
  11654. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11655.  
  11656. %@AB@%EDX%@AE@% = Pointer returned from previous %@AB@%Get_(Next)_Profile_String %@AE@% %@AB@%EDI %@AE@%  =
  11657. Pointer to key name string  %@NL@%
  11658.  
  11659.  
  11660. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11661.  
  11662. If carry clear then  EDX = NEXT string from SYSTEM.INI else  No more
  11663. matching entries found  %@NL@%
  11664.  
  11665.  
  11666. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11667.  
  11668. %@AB@%EDX%@AE@%, Flags  %@NL@%
  11669.  
  11670. %@CR:C6A00300032 @%%@CR:C6A00300033 @%
  11671. %@2@%%@CR:C6A00300034 @%%@AB@%Get_Profile_Boolean (Initialization only)%@AE@%%@EH@%%@NL@%
  11672. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11673.  
  11674.  
  11675. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11676.  
  11677. This service returns the value of a Boolean profile entry from the
  11678. SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then %@AB@%EAX%@AE@% will
  11679. not be modified. Profile entries are of the form:  %@NL@%
  11680.  
  11681.  [SectionName]   KeyName=>  %@NL@%
  11682.  
  11683. That is, Section Name is delineated by square brackets and KeyName is
  11684. followed by an equal sign. Neither name should have any spaces or
  11685. nonprintable characters. The value following the equal sign can be in a
  11686. number of formats. Boolean is "Yes," "No," "Y," "N," "True," "False," "On,"
  11687. "Off," "1," or "0"(foreign versions of Windows may add other language
  11688. equivalents to the above). Logical TRUE returns -1 and logical FALSE returns
  11689. 0.  %@NL@%
  11690.  
  11691. This service is only valid during initialization.  %@NL@%
  11692.  
  11693.  
  11694. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11695.  
  11696. %@AB@%EAX %@AE@%= Default value %@AB@%ESI%@AE@% = Pointer to section name string or 0 for [386enh]
  11697. %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  11698.  
  11699.  
  11700. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11701.  
  11702. If carry set  Entry not found or invalid boolean value  EAX = Default value
  11703. else  If value string was null,  zero flag is set and  EAX = Default value
  11704. else  EAX = 0 if FALSE, -1 if TRUE SYSTEM.INI entry value  %@NL@%
  11705.  
  11706.  
  11707. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11708.  
  11709. Flags  %@NL@%
  11710.  
  11711. %@CR:C6A00300035 @%%@CR:C6A00300036 @%
  11712. %@2@%%@CR:C6A00300037 @%%@AB@%Get_Profile_Decimal_Int (Initialization only)%@AE@%%@EH@%%@NL@%
  11713. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11714.  
  11715.  
  11716. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11717.  
  11718. This service returns the value of a decimal profile entry from the
  11719. SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then %@AB@%EAX%@AE@% will
  11720. not be modified. Profile entries are of the form:  %@NL@%
  11721.  
  11722.  [SectionName]  KeyName=>  %@NL@%
  11723.  
  11724. That is, SectionName is delineated by square brackets and KeyName is
  11725. followed by an equal sign. Neither name should have any spaces or
  11726. non-printable characters. The value following the equal sign must be a
  11727. decimal value. It can begin optionally with a plus (+) or minus (-) and must
  11728. contain all decimal digits with no embedded spaces or decimal points.  %@NL@%
  11729.  
  11730. This service is only valid during initialization.  %@NL@%
  11731.  
  11732.  
  11733. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11734.  
  11735. %@AB@%EAX %@AE@%= Default value (optional) %@AB@%ESI %@AE@%= Pointer to section name string or 0 for
  11736. [386enh] %@AB@%EDI %@AE@%= Pointer to key name string  %@NL@%
  11737.  
  11738.  
  11739. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11740.  
  11741. If carry is set  Entry was NOT found  EAX = Default value (value passed to
  11742. this procedure) else  If value string was null, zero flag is set and  EAX =
  11743. Default value  else  EAX = Value of SYSTEM.INI entry  %@NL@%
  11744.  
  11745.  
  11746. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11747.  
  11748. Flags  %@NL@%
  11749.  
  11750. %@CR:C6A00300038 @%%@CR:C6A00300039 @%
  11751. %@2@%%@CR:C6A00300040 @%%@AB@%Get_Profile_Fixed_Point (Initialization only)%@AE@%%@EH@%%@NL@%
  11752. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11753.  
  11754.  
  11755. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11756.  
  11757. This service returns the value of a fixed point decimal number profile entry
  11758. from the SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then
  11759. %@AB@%EAX%@AE@% will not be modified. Profile entries are of the form:  %@NL@%
  11760.  
  11761.  [SectionName]  KeyName=>  %@NL@%
  11762.  
  11763. That is, SectionName is delineated by square brackets and KeyName is
  11764. followed by an equal sign. Neither name should have any spaces or
  11765. nonprintable characters. The value following the equal sign can be in a
  11766. number of formats. Fixed Point values may begin with an optional plus (+) or
  11767. minus (-) followed by zero or more decimal digits followed by a terminating
  11768. character or by a decimal point followed by zero or more decimal digits. The
  11769. value returned is 10^%@AB@%ECX%@AE@%*>.  %@NL@%
  11770.  
  11771. This service is only valid during initialization.  %@NL@%
  11772.  
  11773.  
  11774. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11775.  
  11776. %@AB@%EAX%@AE@% = Default value %@AB@%ECX%@AE@% = Number of decimal places %@AB@%ESI%@AE@% = Pointer to section
  11777. name string or 0 for [386enh] %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  11778.  
  11779.  
  11780. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11781.  
  11782. If carry is set  Entry was NOT found  EAX = Default value (value passed to
  11783. this procedure) else  If value string was null, zero flag is set and  EAX =
  11784. Default value else  EAX = Value of SYSTEM.INI entry  %@NL@%
  11785.  
  11786. %@CR:C6A00300041 @%%@CR:C6A00300042 @%
  11787. %@2@%%@CR:C6A00300043 @%%@AB@%Get_Profile_Hex_Int (Initialization only)%@AE@%%@EH@%%@NL@%
  11788. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11789.  
  11790.  
  11791. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11792.  
  11793. This service returns the value of a hexadecimal number profile entry from
  11794. the SYSTEM.INI file in %@AB@%EAX%@AE@%. If the profile string is not found, then %@AB@%EAX%@AE@%
  11795. will not be modified. Profile entries are of the form:  %@NL@%
  11796.  
  11797.  [SectionName]  KeyName=>  %@NL@%
  11798.  
  11799. That is, SectionName is delineated by square brackets and KeyName is
  11800. followed by an equal sign. Neither name should have any spaces or
  11801. nonprintable characters. The value following the equal sign can be in a
  11802. number of formats. Hexadecimal is zero or more hexadecimal digits (0-9, A-F)
  11803. followed by a terminating character or a small or capital letter "h." The
  11804. "h" has no effect on the value. If the value following the equal sign is not
  11805. a valid hexadecimal number, %@AB@%EAX%@AE@% is unchanged.  %@NL@%
  11806.  
  11807. This service is only valid during initialization.  %@NL@%
  11808.  
  11809.  
  11810. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11811.  
  11812. %@AB@%EAX%@AE@% = Default value (optional) %@AB@%ESI%@AE@% = Pointer to section name string or 0 for
  11813. [386enh] %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  11814.  
  11815.  
  11816. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11817.  
  11818. If carry is set  Entry was NOT found  EAX = Default value (value passed to
  11819. this procedure) else  If value string was null  zero flag is set  EAX =
  11820. Default value  else  EAX = Value of SYSTEM.INI entry  %@NL@%
  11821.  
  11822.  
  11823. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11824.  
  11825. Flags  %@NL@%
  11826.  
  11827. %@CR:C6A00300044 @%%@CR:C6A00300045 @%
  11828. %@2@%%@CR:C6A00300046 @%%@AB@%Get_Profile_String (Initialization only)%@AE@%%@EH@%%@NL@%
  11829. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11830.  
  11831.  
  11832. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11833.  
  11834. This service searches the initialization file for a specified entry and
  11835. returns a pointer to a string. Do %@AI@%not%@AE@% modify the string in place. The
  11836. pointer returned points into the initialization file data area. If you need
  11837. to modify the string, you must first copy it and, then, modify it. This
  11838. service is only valid during initialization.  %@NL@%
  11839.  
  11840.  
  11841. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11842.  
  11843. %@AB@%EDX%@AE@% = Pointer to default string (optional) %@AB@%ESI%@AE@% = Pointer to program name
  11844. string or 0 for [386enh] %@AB@%EDI%@AE@% = Pointer to key name string  %@NL@%
  11845.  
  11846.  
  11847. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11848.  
  11849. If carry clear  EDX = Pointer to ASCIIZ string from SYSTEM.INI else  EDX is
  11850. unchanged  %@NL@%
  11851.  
  11852.  
  11853. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11854.  
  11855. Flags, may change %@AB@%EDX%@AE@%  %@NL@%
  11856.  
  11857. %@CR:C6A00300047 @%%@CR:C6A00300048 @%
  11858. %@2@%%@CR:C6A00300049 @%%@AB@%Get_PSP_Segment (Initialization only)%@AE@%%@EH@%%@NL@%
  11859. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11860.  
  11861.  
  11862. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11863.  
  11864. This service returns the segment of the WIN386.EXE PSP. Use it to locate PSP
  11865. values other than the EXEC path and environment variables since separate
  11866. services are available for retrieving those ASCIIZ strings. Notice that a
  11867. segment value is returned. To convert the segment to an address, shift the
  11868. value left by 4 bits. This service is only valid during initialization.  %@NL@%
  11869.  
  11870.  
  11871. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11872.  
  11873. None  %@NL@%
  11874.  
  11875.  
  11876. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11877.  
  11878. %@AB@%EAX %@AE@%= Segment of WIN386.EXE PSP (high word always = 0)  %@NL@%
  11879.  
  11880.  
  11881. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11882.  
  11883. %@AB@%EAX%@AE@%, Flags  %@NL@%
  11884.  
  11885. %@CR:C6A00300050 @%
  11886. %@2@%%@CR:C6A00300051 @%%@AB@%OpenFile (Initialization only)%@CR:C6A00300052 @%%@AE@%%@EH@%%@NL@%
  11887. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11888.  
  11889.  
  11890. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11891.  
  11892. Open a file via searching in the standard Windows Places:  %@NL@%
  11893.  
  11894. WINDIR= ARGV[0] Current Working Directory Path  %@NL@%
  11895.  
  11896.  
  11897. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11898.  
  11899. EDX -> Name to open. If this string contains a drive letter or  path seps
  11900. this routine does not search. Else the above search  strategy is employed.
  11901. EDI -> Buffer to hold name of file opened (at least 128 bytes)  Notice that
  11902. this buffer should contain a correctly formed path  for the file but this is
  11903. not guarenteed. This aspect of the behavior is dependent on the WINDIR and
  11904. PATH environment  variables being well formed.  %@NL@%
  11905.  
  11906. Must be able to do Exec_Int activity in the current VM. Temp_V86_Data_Area
  11907. must not be allocated.  %@NL@%
  11908.  
  11909.  
  11910. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11911.  
  11912. Carry Set  File could not be opened (file not found) Carry Clear  EAX = DOS
  11913. File handle (low 16 bits) OPEN IN MODE 0 (for read only)  %@NL@%
  11914.  
  11915.  
  11916. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11917.  
  11918. EAX, FLAGS  %@NL@%
  11919.  
  11920.  
  11921.  
  11922.  
  11923.  
  11924.  
  11925. %@CR:C6A00310001 @%%@1@%%@AB@%Chapter 31  Linked List Services%@AE@%%@EH@%%@NL@%
  11926. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11927.  
  11928. These services provide a convenient set of routines for managing a
  11929. linked-list data structure. They are described here in the following order:
  11930. %@NL@%
  11931.  
  11932.  
  11933.   ■   %@AB@%List_Allocate%@AE@%%@NL@%
  11934.  
  11935.   ■   %@AB@%List_Attach%@AE@%%@NL@%
  11936.  
  11937.   ■   %@AB@%List_Attach_Tail%@AE@%%@NL@%
  11938.  
  11939.   ■   %@AB@%List_Create%@AE@%%@NL@%
  11940.  
  11941.   ■   %@AB@%List_Deallocate%@AE@%%@NL@%
  11942.  
  11943.   ■   %@AB@%List_Destroy%@AE@%%@NL@%
  11944.  
  11945.   ■   %@AB@%List_Get_First%@AE@%%@NL@%
  11946.  
  11947.   ■   %@AB@%List_Get_Next%@AE@%%@NL@%
  11948.  
  11949.   ■   %@AB@%List_Insert%@AE@%%@NL@%
  11950.  
  11951.   ■   %@AB@%List_Remove%@AE@%%@NL@%
  11952.  
  11953.   ■   %@AB@%List_Remove_First%@AE@%%@NL@%
  11954.  
  11955.  
  11956. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  11957. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  11958.  
  11959. %@CR:C6A00310002 @%
  11960. %@2@%%@CR:C6A00310003 @%%@AB@%List_Allocate%@CR:C6A00310004 @%%@AE@%%@EH@%%@NL@%
  11961. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11962.  
  11963.  
  11964. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11965.  
  11966. This service allocates a new node for the list specified by %@AB@%ESI%@AE@%. The
  11967. contents of the node are undefined (probably nonzero). Normally, a node is
  11968. immediately attached to the list through the %@AB@%List_Attach%@AE@% or %@AB@%List_Insert%@AE@%
  11969. services after it has been allocated.  %@NL@%
  11970.  
  11971.  
  11972. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  11973.  
  11974. %@AB@%ESI%@AE@% = List handle  %@NL@%
  11975.  
  11976.  
  11977. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  11978.  
  11979. If list was created with LF_Alloc_Error flag then  If carry clear then  EAX
  11980. -> New node  else  Error:Could not allocate node else  EAX -> New node
  11981. (Current VM crashed if node can not be allocated ─ Service  never returns to
  11982. caller)  %@NL@%
  11983.  
  11984.  
  11985. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  11986.  
  11987. %@AB@%EAX%@AE@%, Flags  %@NL@%
  11988.  
  11989. %@CR:C6A00310005 @%
  11990. %@2@%%@CR:C6A00310006 @%%@AB@%List_Attach%@CR:C6A00310007 @%%@AE@%%@EH@%%@NL@%
  11991. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11992.  
  11993.  
  11994. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  11995.  
  11996. This service attaches a list node to the head (i.e., front) of a list.
  11997. Notice that %@AB@%EAX%@AE@% must point to a node that was allocated using %@AB@%List_Allocate%@AE@%.
  11998. %@NL@%
  11999.  
  12000. Nodes can be attached to any list that has the same size node. This can be
  12001. used, for example, to move a node from one list to another.  %@NL@%
  12002.  
  12003. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12004.  
  12005.  
  12006. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12007.  
  12008. %@AB@%ESI%@AE@% = List handle %@AB@%EAX %@AE@%-> Node  %@NL@%
  12009.  
  12010.  
  12011. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12012.  
  12013. Node attached to list  %@NL@%
  12014.  
  12015.  
  12016. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12017.  
  12018. Flags  %@NL@%
  12019.  
  12020. %@CR:C6A00310008 @%%@CR:C6A00310009 @%
  12021. %@2@%%@CR:C6A00310010 @%%@AB@%List_Attach_Tail%@AE@%%@EH@%%@NL@%
  12022. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12023.  
  12024.  
  12025. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12026.  
  12027. This service attaches a list node to the tail (i.e., end) of a list. %@AB@%EAX%@AE@%
  12028. must point to a node that was allocated using %@AB@%List_Allocate%@AE@%.  %@NL@%
  12029.  
  12030. Nodes can be attached to any list that has the same size node. This can be
  12031. used, for example, to move a node from one list to another.  %@NL@%
  12032.  
  12033. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12034.  
  12035.  
  12036. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12037.  
  12038. %@AB@%ESI%@AE@% = List handle %@AB@%EAX %@AE@%-> Node to insert  %@NL@%
  12039.  
  12040.  
  12041. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12042.  
  12043. Node inserted at tail (end) of list  %@NL@%
  12044.  
  12045.  
  12046. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12047.  
  12048. Flags  %@NL@%
  12049.  
  12050. %@CR:C6A00310011 @%
  12051. %@2@%%@CR:C6A00310012 @%%@AB@%List_Create%@CR:C6A00310013 @%%@AE@%%@EH@%%@NL@%
  12052. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12053.  
  12054.  
  12055. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12056.  
  12057. This service is used to create a new list structure. This service returns a
  12058. list handle that is used when calling all subsequent list services.  %@NL@%
  12059.  
  12060. Lists normally allocate nodes from a "pool" of free nodes. This prevents the
  12061. overhead that would be incurred by calling %@AB@%_HeapAlloc%@AE@% and%@AB@% _HeapFree%@AE@% for
  12062. every list allocation and deallocation. Once a node is created, it is never
  12063. destroyed. Instead, %@AB@%List_Deallocate%@AE@% places the node back in the free pool.
  12064. The node can then be reclaimed quickly when %@AB@%List_Allocate%@AE@% is called.  %@NL@%
  12065.  
  12066. If the size of the list nodes are large, you should force them to be
  12067. allocated from the system heap by setting the %@AB@%LF_Use_Heap%@AE@% flag. All
  12068. allocate/deallocate calls for lists created in this way will use %@AB@%_HeapAlloc%@AE@%
  12069. and %@AB@%_HeapFree%@AE@% to create and destroy nodes.  %@NL@%
  12070.  
  12071. If you want to be able to access a list during hardware interrupts, you
  12072. should set the %@AB@%LF_Async%@AE@% flag. This forces list operations to be atomic
  12073. operations (they cannot be re-entered). If you select this option, you must
  12074. call list services with %@AI@%INTERRUPTS DISABLED%@AE@% or an error will occur. You must
  12075. disable interrupts even if you are not calling the list service from an
  12076. interrupt. Remember, always use %@AB@%pushf/CLI/popf%@AE@% to disable interrupts. Never
  12077. explicitly use STI unless other documentation states that this is
  12078. permissable. Notice that since %@AB@%_HeapAllocate%@AE@% and %@AB@%_HeapFree%@AE@% cannot be called
  12079. from a hardware interrupt, you cannot select this option and %@AB@%LF_Use_Heap%@AE@%.  %@NL@%
  12080.  
  12081. The%@AB@% LF_Alloc_Error%@AE@% flag should be used if you would like to recover from an
  12082. allocation error (i.e., out of memory). The default behavior for a failed
  12083. allocation is to crash the current VM. However, if your VxD would like to
  12084. have the allocation return an error, set this flag. If this option is
  12085. selected, then %@AB@%List_Allocate%@AE@% will return with the Carry flag set when an
  12086. allocation fails. Otherwise, it will crash the current virtual machine
  12087. whenever it cannot allocate a new node.  %@NL@%
  12088.  
  12089.  
  12090. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12091.  
  12092. %@AB@%EAX%@AE@% = Flags  LF_Use_Heap - All data on system heap (Can't use with LF_Async)
  12093. LF_Async - List services can be called at interrupt time  LF_Alloc_Error -
  12094. Return from alloc with carry set if can't allocate  %@AB@%ECX%@AE@% = Node size  %@NL@%
  12095.  
  12096.  
  12097. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12098.  
  12099. If Carry Flag is clear then  ESI = List handle else  Error: Unable to create
  12100. list  %@NL@%
  12101.  
  12102.  
  12103. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12104.  
  12105. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12106.  
  12107. %@CR:C6A00310014 @%
  12108. %@2@%%@CR:C6A00310015 @%%@AB@%List_Deallocate%@CR:C6A00310016 @%%@AE@%%@EH@%%@NL@%
  12109. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12110.  
  12111.  
  12112. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12113.  
  12114. This service places a list node in the free memory pool. Once a node has
  12115. been deallocated, it should not be referenced again. You must remove the
  12116. node from any list to which it is attached before deallocating it.  %@NL@%
  12117.  
  12118.  
  12119. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12120.  
  12121. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> List node  %@NL@%
  12122.  
  12123.  
  12124. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12125.  
  12126. %@AB@%EAX%@AE@% is undefined  %@NL@%
  12127.  
  12128.  
  12129. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12130.  
  12131. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12132.  
  12133. %@CR:C6A00310017 @%
  12134. %@2@%%@CR:C6A00310018 @%%@AB@%List_Destroy%@CR:C6A00310019 @%%@AE@%%@EH@%%@NL@%
  12135. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12136.  
  12137.  
  12138. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12139.  
  12140. This service deallocates all nodes on a list and destroys the list handle.
  12141. Once a list has been destroyed, its handle is no longer valid.  %@NL@%
  12142.  
  12143.  
  12144. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12145.  
  12146. %@AB@%ESI%@AE@% = List handle  %@NL@%
  12147.  
  12148.  
  12149. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12150.  
  12151. %@AB@%ESI %@AE@%is undefined List is destroyed, all nodes deallocated.  %@NL@%
  12152.  
  12153.  
  12154. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12155.  
  12156. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12157.  
  12158. %@CR:C6A00310020 @%
  12159. %@2@%%@CR:C6A00310021 @%%@AB@%List_Get_First%@CR:C6A00310022 @%%@AE@%%@EH@%%@NL@%
  12160. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12161.  
  12162.  
  12163. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12164.  
  12165. This service returns a pointer to the first node in a list. If the list is
  12166. empty, it will return 0 and the Zero Flag will be set.  %@NL@%
  12167.  
  12168.  
  12169. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12170.  
  12171. %@AB@%ESI%@AE@% = List handle  %@NL@%
  12172.  
  12173.  
  12174. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12175.  
  12176. %@AS@%  If ZF is clear then
  12177. %@AS@%      EAX -> First node in list 
  12178. %@AS@%  else
  12179. %@AS@%      List is empty. EAX = 0.%@AE@%
  12180.  
  12181.  
  12182. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12183.  
  12184. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12185.  
  12186. %@CR:C6A00310023 @%
  12187. %@2@%%@CR:C6A00310024 @%%@AB@%List_Get_Next%@CR:C6A00310025 @%%@AE@%%@EH@%%@NL@%
  12188. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12189.  
  12190.  
  12191. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12192.  
  12193. This service returns the next node in a list. It is used to traverse the
  12194. list when searching for a specific element. If the end of the list is
  12195. reached, it will return 0 and the Zero Flag will be set.  %@NL@%
  12196.  
  12197. Typically, this service is used in conjunction with %@AB@%List_Get_First%@AE@% to scan
  12198. an entire list.  %@NL@%
  12199.  
  12200. %@AS@%  EXAMPLE:
  12201. %@AS@%    BeginProc Scan_My_List
  12202. %@AS@%    mov  esi, [My_List_Handle]
  12203. %@AS@%    VMMcall List_Get_First
  12204. %@AS@%    jz  SHORT Scan_Done 
  12205. %@AS@%    Scan_Loop:
  12206. %@AS@%    (Do something with EAX here)
  12207. %@AS@%    VMMcall List_Get_Next
  12208. %@AS@%    jnz  Scan_Loop 
  12209. %@AS@%    Scan_Done:
  12210. %@AS@%    ret 
  12211. %@AS@%    EndProc Scan_My_List%@AE@%
  12212.  
  12213.  
  12214. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12215.  
  12216. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> Node  %@NL@%
  12217.  
  12218.  
  12219. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12220.  
  12221. If ZF is clear then  %@AB@%EAX%@AE@% -> Next node in list else  End of list reached. %@AB@%EAX%@AE@%
  12222. = 0.  %@NL@%
  12223.  
  12224.  
  12225. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12226.  
  12227. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12228.  
  12229. %@CR:C6A00310026 @%
  12230. %@2@%%@CR:C6A00310027 @%%@AB@%List_Insert%@CR:C6A00310028 @%%@AE@%%@EH@%%@NL@%
  12231. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12232.  
  12233.  
  12234. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12235.  
  12236. This service inserts a node at a specified point in a list. The caller must
  12237. specify two nodes: the node to be inserted in %@AB@%EAX%@AE@%, and a position to insert
  12238. the node %@AI@%after%@AE@% in %@AB@%ECX%@AE@%. This means that node %@AB@%EAX%@AE@% will occupy the position in
  12239. the list immediately after node %@AB@%ECX%@AE@%. If %@AB@%ECX%@AE@% is zero, then node %@AB@%EAX%@AE@% will be
  12240. inserted at the head of the list.  %@NL@%
  12241.  
  12242. Nodes can be inserted in any list that has the same size node. This can be
  12243. used, for example, to move a node from one list to another.  %@NL@%
  12244.  
  12245. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12246.  
  12247.  
  12248. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12249.  
  12250. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> Node to insert %@AB@%ECX%@AE@% -> Node to insert after (0 to
  12251. attach to head)  %@NL@%
  12252.  
  12253.  
  12254. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12255.  
  12256. Node inserted in list  %@NL@%
  12257.  
  12258.  
  12259. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12260.  
  12261. Flags  %@NL@%
  12262.  
  12263. %@CR:C6A00310029 @%
  12264. %@2@%%@CR:C6A00310030 @%%@AB@%List_Remove%@CR:C6A00310031 @%%@AE@%%@EH@%%@NL@%
  12265. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12266.  
  12267.  
  12268. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12269.  
  12270. This service removes a specified node from a list.The node will %@AI@%not%@AE@% be
  12271. deallocated by this service. It is up to the caller to deallocate the node
  12272. or attach it to another list (it can only be attached to a list with node
  12273. size equal to the original list).  %@NL@%
  12274.  
  12275. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12276.  
  12277.  
  12278. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12279.  
  12280. %@AB@%ESI%@AE@% = List handle %@AB@%EAX%@AE@% -> Node to remove from list  %@NL@%
  12281.  
  12282.  
  12283. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12284.  
  12285. Node removed from list  %@NL@%
  12286.  
  12287.  
  12288. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12289.  
  12290. Flags  %@NL@%
  12291.  
  12292. %@CR:C6A00310032 @%%@CR:C6A00310033 @%
  12293. %@2@%%@CR:C6A00310034 @%%@AB@%List_Remove_First%@AE@%%@EH@%%@NL@%
  12294. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12295.  
  12296.  
  12297. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12298.  
  12299. This service removes the first node from a list. Notice that the node is %@AI@%not%@AE@%
  12300. deallocated by this service. It is up to the caller to deallocate the node
  12301. or attach it to another list (it can only be attached to a list with node
  12302. size equal to the original list).  %@NL@%
  12303.  
  12304. %@AU@%(This figure may be found in the printed book).%@AE@%%@NL@%
  12305.  
  12306.  
  12307. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12308.  
  12309. %@AB@%ESI %@AE@%= List handle  %@NL@%
  12310.  
  12311.  
  12312. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12313.  
  12314. If Zero Flag is clear then  EAX -> Node that has been removed from list else
  12315. List is empty and EAX = 0  %@NL@%
  12316.  
  12317.  
  12318. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12319.  
  12320. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12321.  
  12322.  
  12323.  
  12324.  
  12325.  
  12326.  
  12327. %@CR:C6A00320001 @%%@1@%%@AB@%Chapter 32  Error Condition Services%@AE@%%@EH@%%@NL@%
  12328. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12329.  
  12330. These error services are used by VxDs when they have detected the VM to be
  12331. in an unrecoverable state. Examples of situations that might lead to such a
  12332. state include an attempted VM execution of a protected instruction or an
  12333. operation which might fail due to lack of memory. The services are described
  12334. here in the following order:  %@NL@%
  12335.  
  12336.  
  12337.   ■   %@AB@%Crash_Cur_VM%@AE@%%@NL@%
  12338.  
  12339.   ■   %@AB@%Fatal_Error_Handler%@AE@%%@NL@%
  12340.  
  12341.   ■   %@AB@%Fatal_Memory_Error%@AE@%%@NL@%
  12342.  
  12343.  
  12344. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  12345. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  12346.  
  12347. %@CR:C6A00320002 @%
  12348. %@2@%%@CR:C6A00320003 @%%@AB@%Crash_Cur_VM%@CR:C6A00320004 @%%@AE@%%@EH@%%@NL@%
  12349. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12350.  
  12351.  
  12352. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12353.  
  12354. This service will crash the current VM. It is to be called when a
  12355. catastrophic error has occured in the VM, such as executing an illegal
  12356. instruction or attempting to program a piece of hardware in a way
  12357. incompatible with the device virtualization.  %@NL@%
  12358.  
  12359. If the system VM is the current VM, enhanced Windows will exit with a fatal
  12360. error without explicitly crashing the other VMs.  %@NL@%
  12361.  
  12362.  
  12363. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12364.  
  12365. None  %@NL@%
  12366.  
  12367.  
  12368. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12369.  
  12370. None  %@NL@%
  12371.  
  12372. %@CR:C6A00320005 @%%@CR:C6A00320006 @%
  12373. %@2@%%@CR:C6A00320007 @%%@AB@%Fatal_Error_Handler%@AE@%%@EH@%%@NL@%
  12374. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12375.  
  12376.  
  12377. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12378.  
  12379. This service is called (or jumped to) when a fatal error is detected. It
  12380. returns to real mode and, optionally, prints out an error message. You can
  12381. hang the computer by selecting the "EF_Hang_On_Exit" flag (defined in
  12382. VMM.INC). All of the devices that have been initialized are informed about
  12383. the exit before returning to real mode.  %@NL@%
  12384.  
  12385. The "Fatal_Error" macro supplied in VMM.INC is a convienient way of calling
  12386. this service. Examples:  %@NL@%
  12387.  
  12388. %@AS@%  Fatal_Error                     ; 
  12389. %@AS@%  This exits with no error message
  12390. %@AS@%  Fatal_Error OFFSET32 My_Err_Msg ; 
  12391. %@AS@%  Exits and prints error message%@AE@%
  12392.  
  12393. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12394. NOTE
  12395.  
  12396. %@AI@%Since this routine can be called by _InitializeMemoryManager, no assumptions
  12397. %@AI@%about the contents of any registers or data structures should be made.%@AE@%
  12398. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12399.  
  12400.  
  12401. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12402.  
  12403. ESI = Ptr ASCIIZ string to display (0 if none) EAX = Exit flags to send to
  12404. the loader (real mode exit code)  Bit 0 = 1 - Hang system on exit to real
  12405. mode  Others undefined and must be 0  %@NL@%
  12406.  
  12407.  
  12408. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12409.  
  12410. Does not return  %@NL@%
  12411.  
  12412.  
  12413. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12414.  
  12415. All registers  %@NL@%
  12416.  
  12417. %@CR:C6A00320008 @%%@CR:C6A00320009 @%
  12418. %@2@%%@CR:C6A00320010 @%%@AB@%Fatal_Memory_Error%@AE@%%@EH@%%@NL@%
  12419. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12420.  
  12421.  
  12422. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12423.  
  12424. This routine calls the Fatal_Error_Handler with exit flags equal to zero and
  12425. the message "Insufficient Memory to Initialize Windows in 386 enhanced
  12426. mode." It should be called during intialization if there is not enough
  12427. memory to initialize.  %@NL@%
  12428.  
  12429. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12430. NOTE
  12431.  
  12432. %@AI@%Since this routine can be called by _InitializeMemoryManager, no assumptions
  12433. %@AI@%about the contents of any registers or data structures should be made.%@AE@%
  12434. ────────────────────────────────────────────────────────────────────────────%@NL@%
  12435.  
  12436.  
  12437. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12438.  
  12439. None  %@NL@%
  12440.  
  12441.  
  12442. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12443.  
  12444. None  %@NL@%
  12445.  
  12446.  
  12447. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12448.  
  12449. All registers  %@NL@%
  12450.  
  12451.  
  12452.  
  12453.  
  12454.  
  12455.  
  12456. %@CR:C6A00330001 @%%@1@%%@AB@%Chapter 33  Miscellaneous Services%@AE@%%@EH@%%@NL@%
  12457. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12458.  
  12459. The services discussed in this chapter provide functions not easily
  12460. categorized such as hooking another VxDs API and sending system control
  12461. messages. They are provided here in the following order:  %@NL@%
  12462.  
  12463.  
  12464.   ■   %@AB@%Begin_Reentrant_Execution%@AE@%%@NL@%
  12465.  
  12466.   ■   %@AB@%End_Reentrant_Execution%@AE@%%@NL@%
  12467.  
  12468.   ■   %@AB@%Hook_Device_Service%@AE@%%@NL@%
  12469.  
  12470.   ■   %@AB@%Hook_Device_V86_API%@AE@%%@NL@%
  12471.  
  12472.   ■   %@AB@%Hook_PM_Device_API%@AE@%%@NL@%
  12473.  
  12474.   ■   %@AB@%Map_Flat%@AE@%%@NL@%
  12475.  
  12476.   ■   %@AB@%Map_Lin_To_VM_Addr%@AE@%%@NL@%
  12477.  
  12478.   ■   %@AB@%MMGR_SetNULPageAddr%@AE@%%@NL@%
  12479.  
  12480.   ■   %@AB@%Set_System_Exit_Code%@AE@%%@NL@%
  12481.  
  12482.   ■   %@AB@%Simulate_Pop%@AE@%%@NL@%
  12483.  
  12484.   ■   %@AB@%Simulate_Push%@AE@%%@NL@%
  12485.  
  12486.   ■   %@AB@%System_Control%@AE@%%@NL@%
  12487.  
  12488.  
  12489. See Chapter 16. "Overview of Windows in 386 Enhanced Mode" and Chapter 17,
  12490. "Virtual Device Programming Topics" for general environment discussions.  %@NL@%
  12491.  
  12492. %@CR:C6A00330002 @%%@CR:C6A00330003 @%
  12493. %@2@%%@CR:C6A00330004 @%%@AB@%Begin_Reentrant_Execution%@AE@%%@EH@%%@NL@%
  12494. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12495.  
  12496.  
  12497. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12498.  
  12499. THIS IS A VERY DANGEROUS SERVICE. BE VERY CAREFUL WHEN CALLING IT. Most
  12500. virtual devices have no reason to use this service. Do NOT use this service
  12501. to avoid scheduling events on hardware interrupts.  %@NL@%
  12502.  
  12503. It is intended to be used by devices that hook VMM Faults (re-entrant
  12504. processor exeptions) that must call non-asynchronous VMM or VxD services or
  12505. execute a VM. This would be valid to use, for example, if a VxD provided a
  12506. ring 0 software interrupt interface (although this is not recommended ─ You
  12507. should provide device services through the enhanced Windows dynamic-linking
  12508. mechanism). It would be INVALID to use this service during a hardware
  12509. interrupt (such as a timer or disk interrupt).  %@NL@%
  12510.  
  12511.  
  12512. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12513.  
  12514. None  %@NL@%
  12515.  
  12516.  
  12517. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12518.  
  12519. %@AB@%ECX%@AE@% = Old reentrancy count (must be passed to %@AB@%End_Reentrant_Execution%@AE@%)  %@NL@%
  12520.  
  12521.  
  12522. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12523.  
  12524. %@AB@%ECX%@AE@%, Flags  %@NL@%
  12525.  
  12526. %@CR:C6A00330005 @%%@CR:C6A00330006 @%
  12527. %@2@%%@CR:C6A00330007 @%%@AB@%End_Reentrant_Execution%@AE@%%@EH@%%@NL@%
  12528. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12529.  
  12530.  
  12531. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12532.  
  12533. A VxD that calls %@AB@%Begin_Reentrant_Execution%@AE@% must call this service before
  12534. returning.  %@NL@%
  12535.  
  12536.  
  12537. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12538.  
  12539. %@AB@%ECX%@AE@% = Reentrancy count returned from %@AB@%Begin_Reentrant_Execution%@AE@%  %@NL@%
  12540.  
  12541.  
  12542. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12543.  
  12544. None  %@NL@%
  12545.  
  12546.  
  12547. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12548.  
  12549. Flags  %@NL@%
  12550.  
  12551. %@CR:C6A00330008 @%%@CR:C6A00330009 @%
  12552. %@2@%%@CR:C6A00330010 @%%@AB@%Hook_Device_Service%@AE@%%@EH@%%@NL@%
  12553. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12554.  
  12555.  
  12556. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12557.  
  12558. This service allows one device to monitor or replace a device service.
  12559. %@AI@%extreme care%@AE@% must be taken here not to destroy the functionality of the
  12560. device whose routine is being monitored or replaced. This service also
  12561. allows VMM services to be hooked (the VMM is device 1).  %@NL@%
  12562.  
  12563. Hooking a service is often useful for monitoring the activities of other
  12564. devices. For example, if a device needed to know whenever a VM was set into
  12565. background mode, it could use the following code:  %@NL@%
  12566.  
  12567. %@AS@%  (Initialization code)
  12568. %@AS@%        mov    eax, Set_Time_Slice_Priority
  12569. %@AS@%        mov    esi, OFFSET32 My_Hook_Proc
  12570. %@AS@%        VMMcall Hook_Device_Service
  12571. %@AS@%        jc    Error!
  12572. %@AS@%        mov    [Real_Proc], esi%@AE@%
  12573.  
  12574. %@AS@%  BeginProc My_Hook_Proc
  12575. %@AS@%        test    eax, VMStat_Background
  12576. %@AS@%        jz    SHORT MHP_Chain
  12577. %@AS@%        pushad
  12578. %@AS@%        (Do something here)
  12579. %@AS@%        popad
  12580. %@AS@%  MHP_Chain:
  12581. %@AS@%        jmp     [Real_Proc]
  12582. %@AS@%  EndProc My_Hook_Proc%@AE@%
  12583.  
  12584. Every time a VxD calls %@AB@%Set_Time_Slice_Priority%@AE@%, the %@AB@%My_Hook_Proc%@AE@% procedure
  12585. will be called. The hook procedure should normally chain to the actual
  12586. device or VMM service although this is not required. Also, be sure to save
  12587. and restore any registers in your hook procedure.  %@NL@%
  12588.  
  12589. You will notice that the sample initialization code moves
  12590. %@AB@%Set_Time_Slice_Priority%@AE@% into %@AB@%EAX%@AE@%. Remember, services are defined as EQUATES,
  12591. not external procedure references. Thus, %@AB@%Set_Time_Slice_Priority%@AE@% is just a
  12592. number. (VMM device ID%@NL@%
  12593.  
  12594. Your hook must preserve all registers that are not modified by the service
  12595. you have hooked. Also, if flags are passed as an entry or exit parameter,
  12596. your hook procedure must also preserve the flags.  %@NL@%
  12597.  
  12598. Be careful about hooking C calling convention (stack-based) services. If you
  12599. want to examine the "back end" of a C calling convention service, you will
  12600. need to copy the entire parameter stack frame before calling the actual
  12601. service.  %@NL@%
  12602.  
  12603. More than one VxD can hook a device service. The last hook installed will be
  12604. the first one called.  %@NL@%
  12605.  
  12606.  
  12607. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12608.  
  12609. %@AB@%EAX%@AE@% = Device ID  %@AB@%ESI%@AE@% = New procedure  %@NL@%
  12610.  
  12611.  
  12612. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12613.  
  12614. If carry clear then  ESI = Old dynalink procedure else  ERROR. Invalid
  12615. Device or Service number  %@NL@%
  12616.  
  12617.  
  12618. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12619.  
  12620. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12621.  
  12622. %@CR:C6A00330011 @%%@CR:C6A00330012 @%%@CR:C6A00330013 @%%@CR:C6A00330014 @%
  12623. %@2@%%@CR:C6A00330015 @%%@AB@%Hook_Device_V86_API, Hook_PM_Device_API%@AE@%%@EH@%%@NL@%
  12624. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12625.  
  12626.  
  12627. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12628.  
  12629. These services allow a VxD to hook another virtual device's V86 or protected
  12630. mode API interface.You are responsible for chaining to the real API handler.
  12631. Be careful to preserve the %@AB@%EBX%@AE@% and %@AB@%EBP%@AE@% registers when calling the next
  12632. handler in the chain.  %@NL@%
  12633.  
  12634. Most VxDs will never need to hook another virtual device's API procedure.
  12635. These services are provided mainly as a mechanism for devices that may be
  12636. developed in the future to intercept API calls to other virtual devices. For
  12637. example, a new version of the Virtual Mouse Device may need to intercept
  12638. calls to the Virtual Display Device so that it can save and restore the
  12639. mouse cursor. In such a case, these services could be used.  %@NL@%
  12640.  
  12641.  
  12642. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12643.  
  12644. %@AB@%EAX%@AE@% = Device ID %@AB@%ESI %@AE@%= Offset of new API handler  %@NL@%
  12645.  
  12646.  
  12647. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12648.  
  12649. If carry clear then  ESI = Offset of previous API handler (used to chain to
  12650. next  handler) else  ERROR: Device does not support API interface  %@NL@%
  12651.  
  12652.  
  12653. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12654.  
  12655. %@AB@%ESI%@AE@%, Flags  %@NL@%
  12656.  
  12657.  
  12658. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  12659.  
  12660. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure (Same parameters as
  12661. standard API entry point)  %@NL@%
  12662.  
  12663. %@CR:C6A00330016 @%
  12664. %@2@%%@CR:C6A00330017 @%%@AB@%Map_Flat%@CR:C6A00330018 @%%@AE@%%@EH@%%@NL@%
  12665. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12666.  
  12667.  
  12668. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12669.  
  12670. This service provides a convenient way of converting a SEGMENT:OFFSET or
  12671. SELECTOR:OFFSET pair into a linear address. %@AB@%Map_Flat%@AE@% works only for the
  12672. current VM. It determines whether the value passed to it is a V86 segment or
  12673. a PM selector by the execution mode of the current VM. This allows VxDs to
  12674. use identical code for PM and V86 handlers. For example, assume a VxD wanted
  12675. to simulate MS-DOS reads in both V86 and protected mode. It would hook both
  12676. the V86 and PM %@AB@%int%@AE@% chains with the same procedure:  %@NL@%
  12677.  
  12678. %@AS@%  VxD_DOS_Read_Hook:
  12679. %@AS@%    cmp [ebp.Client_AH], 3Fh ; Q: Is it a read
  12680. %@AS@%    jne SHORT VxD_DRH_Reflect ;    N: Reflect it
  12681. %@AS@%        ;    Y: DS:DX -> Read buffer
  12682. %@AS@%    mov ax, (Client_DS SHL 8) + Client_DX
  12683. %@AS@%    VMMcall Map_Flat  ; EAX = Lin addr of DS:DX
  12684. %@AS@%    . . .
  12685. %@AS@%    (Do something useful here)
  12686. %@AS@%    . . .
  12687. %@AS@%    clc    ; Eat this int 21h
  12688. %@AS@%    ret 
  12689. %@AS@%  VxD_DRH_Reflect:
  12690. %@AS@%    stc
  12691. %@AS@%    ret%@AE@%
  12692.  
  12693. Notice that the above procedure does not need to examine the VM's execution
  12694. state. By calling %@AB@%Map_Flat%@AE@% it converts the DS:DX pointer into a valid linear
  12695. address regardless of the VM's execution mode. If the VM was running a
  12696. 32-bit protected mode application, it would convert the client's DS:EDX into
  12697. a linear address. For V86 and 16-bit protected-mode applications, it would
  12698. ignore the high word of the Client_EDX.  %@NL@%
  12699.  
  12700. There is a macro called %@AB@%Client_Ptr_Flat%@AE@% that will generate this code
  12701. automatically. For the example above you would use:  %@NL@%
  12702.  
  12703. %@AS@%  Client_Ptr_Flat eax, DS, DX%@AE@%
  12704.  
  12705. The first parameter specifies the 32-bit register to contain the linear
  12706. address. The second parameter specifies the client's segment. The third
  12707. parameter is optional and specifies the offset register (if blank then an
  12708. offset of 0 is assumed).  %@NL@%
  12709.  
  12710. You must set %@AB@%AH%@AE@% to the equate for the client segment register you want to
  12711. map flat and AL to the offset register to add to the pointer base.
  12712. Alternately, if you do not want an offset added to the segment base you
  12713. should set AL to -1 (0FFh). This will just convert the segment to a linear
  12714. address.  %@NL@%
  12715.  
  12716. Notice that during the running of 32-bit protected mode applications, or
  12717. while in "VxD_Exec" mode, pointers will use the 32-bit offset register.
  12718. Therefore, the above example would use %@AB@%DS:EDX%@AE@% when the %@AB@%CB_VM_Status%@AE@% field of
  12719. a VM's control block has either bit set in %@AB@%VMStat_Use32_Mask%@AE@%. This makes
  12720. %@AB@%Map_Flat%@AE@% work for V86, 16-bit protected mode, and 32-bit protected mode
  12721. programs.  %@NL@%
  12722.  
  12723.  
  12724. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12725.  
  12726. AH = Offset in client structure of segment register to use. AL = Offset in
  12727. client structure of offset register to use  OR -1 if no offset to be added
  12728. to segment base  %@NL@%
  12729.  
  12730.  
  12731. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12732.  
  12733. %@AB@%EAX%@AE@% = Ring 0 linear address  %@NL@%
  12734.  
  12735.  
  12736. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12737.  
  12738. Flags, %@AB@%EAX%@AE@%  %@NL@%
  12739.  
  12740. %@CR:C6A00330019 @%%@CR:C6A00330020 @%
  12741. %@2@%%@CR:C6A00330021 @%%@AB@%MMGR_SetNULPageAddr%@AE@%%@EH@%%@NL@%
  12742. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12743.  
  12744.  
  12745. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12746.  
  12747. This call is used to set the physical address of the system nul page.  %@NL@%
  12748.  
  12749. It can be called at device INIT time to set the address of a KNOWN
  12750. non-existant page in the system. This is usually called by the V86MMGR
  12751. device because he does memory scans and therefore has a good idea about what
  12752. a good page will be.  %@NL@%
  12753.  
  12754.  
  12755. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12756.  
  12757. %@AB@%EAX%@AE@% is PHYSICAL address for NUL Page (Page number %@NL@%
  12758.  
  12759.  
  12760. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12761.  
  12762. None  %@NL@%
  12763.  
  12764.  
  12765. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12766.  
  12767. Flags  %@NL@%
  12768.  
  12769. %@CR:C6A00330022 @%%@CR:C6A00330023 @%
  12770. %@2@%%@CR:C6A00330024 @%%@AB@%Set_System_Exit_Code%@AE@%%@EH@%%@NL@%
  12771. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12772.  
  12773.  
  12774. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12775.  
  12776. This service sets the DOS system call 4Ch return code value passed in AL on
  12777. the EXIT call made by the loader. Thus this sets the MS-DOS exit code that
  12778. Windows Enhanced Mode exits with. This service is intended for use by the
  12779. SHELL device.  %@NL@%
  12780.  
  12781. Notice that this exit code is associated only with the EXIT of the the
  12782. system (i.e. the SYS VM).  %@NL@%
  12783.  
  12784. Nice that in the case of an abnormal termination the LOADER may set its own
  12785. exit code, which will cause the one set with this service to be ignored.  %@NL@%
  12786.  
  12787.  
  12788. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12789.  
  12790. AL == Exit Code to set  %@NL@%
  12791.  
  12792.  
  12793. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12794.  
  12795. None  %@NL@%
  12796.  
  12797.  
  12798. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12799.  
  12800. EDX,FLAGS  %@NL@%
  12801.  
  12802. %@CR:C6A00330025 @%
  12803. %@2@%%@CR:C6A00330026 @%%@AB@%Simulate_Pop%@CR:C6A00330027 @%%@AE@%%@EH@%%@NL@%
  12804. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12805.  
  12806.  
  12807. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12808.  
  12809. Returns the WORD or DWORD at the top of the current VM's client stack and
  12810. adds 2 or 4 to the client's %@AB@%SP%@AE@%.  %@NL@%
  12811.  
  12812.  
  12813. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12814.  
  12815. None  %@NL@%
  12816.  
  12817.  
  12818. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12819.  
  12820. %@AB@%EAX%@AE@% = Word popped from application's stack (high word 0 if use 16 app)  %@NL@%
  12821.  
  12822.  
  12823. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12824.  
  12825. %@AB@%EAX%@AE@%, %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  12826.  
  12827. %@CR:C6A00330028 @%
  12828. %@2@%%@CR:C6A00330029 @%%@AB@%Simulate_Push%@CR:C6A00330030 @%%@AE@%%@EH@%%@NL@%
  12829. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12830.  
  12831.  
  12832. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12833.  
  12834. Pushes a WORD or DWORD onto the current VM's client stack and decrements the
  12835. VM's %@AB@%SP%@AE@% by 2 or 4.  %@NL@%
  12836.  
  12837.  
  12838. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12839.  
  12840. If in V86 mode or 16 bit PM application then  AX = WORD to push else  EAX =
  12841. DWORD to push  %@NL@%
  12842.  
  12843.  
  12844. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12845.  
  12846. (D)WORD pushed on application program's stack  %@NL@%
  12847.  
  12848.  
  12849. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12850.  
  12851. %@AB@%Client_ESP%@AE@%, Flags  %@NL@%
  12852.  
  12853. %@CR:C6A00330031 @%
  12854. %@2@%%@CR:C6A00330032 @%%@AB@%System_Control%@CR:C6A00330033 @%%@AE@%%@EH@%%@NL@%
  12855. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12856.  
  12857.  
  12858. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12859.  
  12860. This service sends system control messages to all the VxD's and for some
  12861. messages, to parts of VMM as well. Notice that incorrect usage of the system
  12862. control messages can cause erratic behavior by the system. For example, only
  12863. the Shell device should initiate %@AB@%Create_VM%@AE@% and %@AB@%Destroy_VM%@AE@% messages. Also
  12864. notice that when a %@AB@%Set_Device_Focus%@AE@% message is done with a device ID of
  12865. zero, all devices with a settable focus must set their focus to the VM
  12866. indicated.  %@NL@%
  12867.  
  12868. The valid %@AB@%System_Control %@AE@%messages are as follows:  %@NL@%
  12869.  
  12870. %@TH:  26  1162 02 23 53 @%Initialization         %@AB@%Sys_Critical_Init%@AE@%%@AB@%%@AE@%                       %@AB@%Device_Init%@AE@%%@AB@%%@AE@%                       %@AB@%Init_Complete%@AE@%%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%System VM creation     %@AB@%Sys_VM_Init%@AE@%%@AB@%%@AE@%                       %@AB@%Sys_VM_Terminate%@AE@%System VM destruction  %@AB@%System_Exit%@AE@%%@AB@%%@AE@%(enhanced Windows      %@AB@%Sys_Critical_Exit%@AE@%exit)                  Other VM creation      %@AB@%Create_VM%@AE@%%@AB@%%@AE@%                       %@AB@%VM_Critical_Init%@AE@%%@AB@%%@AE@%                       %@AB@%VM_Init%@AE@%Other VM destruction   %@AB@%VM_Terminate%@AE@%%@AB@%%@AE@%                       %@AB@%VM_Not_Executable%@AE@%%@AB@%%@AE@%                       %@AB@%Destroy_VM%@AE@%VM state changes       %@AB@%VM_Suspend%@AE@%%@AB@%%@AE@%                       %@AB@%VM_Resume%@AE@%%@AB@%%@AE@%                       %@AB@%Set_Device_Focus%@AE@%Special messages       %@AB@%Reboot_Processor%@AE@%%@AB@%%@AE@%                       %@AB@%Debug_Query%@AE@%%@TE:  26  1162 02 23 53 @%
  12871.  
  12872. The control calls that are valid for devices to issue are as follows:  %@NL@%
  12873.  
  12874. %@AB@%Create_VM %@AE@%  (used by SHELL) %@AB@%Destroy_VM%@AE@% (used by SHELL) %@AB@%Set_Device_Focus%@AE@%  %@NL@%
  12875.  
  12876.  
  12877. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12878.  
  12879. %@AB@%EAX%@AE@% = System control message %@AB@%EBX%@AE@% = VM handle (if needed by message)
  12880. %@AB@%ESI%@AE@%,%@AB@%EDI%@AE@%,%@AB@%EDX%@AE@% = message specific parameter, such as Device ID (for
  12881. Set_Device_Focus message) %@AB@%ECX%@AE@% register is used by this service and cannot
  12882. contain any parameter that  will be passed through to the devices.  %@NL@%
  12883.  
  12884.  
  12885. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12886.  
  12887. Carry Set  Call failed Carry Clear  Call Succeeded  If Entry EAX = %@AB@%Create_VM%@AE@%
  12888. EBX = New VM handle created  %@NL@%
  12889.  
  12890.  
  12891. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12892.  
  12893. Flags, %@AB@%EBX%@AE@% if %@AB@%Create_VM%@AE@%  %@NL@%
  12894.  
  12895.  
  12896.  
  12897.  
  12898.  
  12899.  
  12900. %@CR:C6A00340001 @%%@1@%%@AB@%Chapter 34  Shell Services%@AE@%%@EH@%%@NL@%
  12901. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12902.  
  12903. The Shell services provide a way for VxDs to communicate with the user. This
  12904. chapter presents descriptions of the Shell services in the following order:
  12905. %@NL@%
  12906.  
  12907.  
  12908.   ■   %@AB@%SHELL_Event%@AE@%%@NL@%
  12909.  
  12910.   ■   %@AB@%SHELL_Get_Version%@AE@%%@NL@%
  12911.  
  12912.   ■   %@AB@%SHELL_Message%@AE@%%@NL@%
  12913.  
  12914.   ■   %@AB@%SHELL_Resolve_Contention%@AE@%%@NL@%
  12915.  
  12916.   ■   %@AB@%SHELL_SYSMODAL_Message%@AE@%%@NL@%
  12917.  
  12918.  
  12919. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  12920. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  12921.  
  12922.  
  12923. %@2@%%@CR:C6A00340002 @%%@AB@%SHELL_Event%@CR:C6A00340003 @%%@AE@%%@EH@%%@NL@%
  12924. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12925.  
  12926.  
  12927. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12928.  
  12929. This procedure posts an event occuring in the windows shell to VMDOSAPP.
  12930. This service is primarily for SHELL to WINOLDAPP communication. The VDD also
  12931. sends a couple messages to WINOLDAPP, other VxDs should have no use for this
  12932. service.  %@NL@%
  12933.  
  12934.  
  12935. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12936.  
  12937. %@AB@%EBX%@AE@% is VM Handle for Event %@AB@%ECX%@AE@% is event # %@AB@%AX%@AE@% = wParam for event High 16 bits
  12938. %@AB@%EAX%@AE@% special boost flags %@AB@%ESI%@AE@% is callback procedure for event (==0 if none)
  12939. %@AB@%EDX%@AE@% is reference data for event callback  %@NL@%
  12940.  
  12941.  
  12942. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12943.  
  12944. Carry Clear  Event placed in queue  %@AB@%EAX%@AE@% is "Event Handle" of event (only if
  12945. valid entry %@AB@%ESI %@AE@%  0) Carry Set  Event not placed  VMDOSAPP not present
  12946. Insufficient memory for placement  %@NL@%
  12947.  
  12948.  
  12949. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  12950.  
  12951. Carry Set  Event could not be placed in VMDOSAPP queue  %@AB@%EDX%@AE@% = reference data
  12952. NOTE THAT %@AB@%EBX%@AE@% != VM Handle of event! Carry Clear  Called when VMDOSAPP
  12953. signals event processing complete  %@AB@%EBP%@AE@% -> VMDOSAPP Client frame so registers
  12954. can be accessed  %@AB@%EDX%@AE@% = reference data  NOTE THAT %@AB@%EBX%@AE@% != VM Handle of event!
  12955. %@NL@%
  12956.  
  12957.  
  12958. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12959.  
  12960. Flags, %@AB@%EAX%@AE@%  %@NL@%
  12961.  
  12962.  
  12963. %@2@%%@CR:C6A00340004 @%%@AB@%SHELL_Get_Version%@CR:C6A00340005 @%%@AE@%%@EH@%%@NL@%
  12964. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12965.  
  12966.  
  12967. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12968.  
  12969. This procedure returns the version of the Shell VxD.  %@NL@%
  12970.  
  12971.  
  12972. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12973.  
  12974. None  %@NL@%
  12975.  
  12976.  
  12977. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  12978.  
  12979. %@AB@%AH%@AE@% = Major version %@AB@%AL%@AE@% = Minor version Carry Flag clear  %@NL@%
  12980.  
  12981.  
  12982. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  12983.  
  12984. %@AB@%EAX%@AE@%, Flags  %@NL@%
  12985.  
  12986.  
  12987. %@2@%%@CR:C6A00340006 @%%@AB@%SHELL_Message%@CR:C6A00340007 @%%@AE@%%@EH@%%@NL@%
  12988. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12989.  
  12990.  
  12991. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  12992.  
  12993. This procedure is called to put up messages. Refer to SHELL.INC and the
  12994. %@AI@%Microsoft Windows Software Development Kit%@AE@% for information on message box
  12995. parameters.  %@NL@%
  12996.  
  12997.  
  12998. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  12999.  
  13000. %@AB@%EBX%@AE@% = VM Handle of VM responsible for message %@AB@%EAX%@AE@% = Message box flags (SEE
  13001. MB_xxxx in SHELL.INC) %@AB@%ECX%@AE@% -> NUL terminated Message Text %@AB@%EDI%@AE@% -> NUL
  13002. terminated caption Text == 0 for standard caption  -> NUL for No caption %@AB@%ESI%@AE@%
  13003. -> Callback procedure to call with response when dialog is finished == 0 if
  13004. no call back desired %@AB@%EDX%@AE@% = Reference data for callback  %@NL@%
  13005.  
  13006.  
  13007. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13008.  
  13009. Carry Clear  %@AB@%EAX%@AE@% is "Event Handle" of message Carry Set  Message cannot be
  13010. displayed (insufficient memory)  Caller may wish to call
  13011. %@AB@%SHELL_SYSMODAL_MESSAGE%@AE@% in this csae.  %@AB@%SHELL_Sysmodal_Message%@AE@% will not fail.
  13012. %@NL@%
  13013.  
  13014.  
  13015. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  13016.  
  13017. Called when message box is complete %@AB@%EAX%@AE@% = Response code from dialog box (SEE
  13018. IDxx in SHELL.INC)  %@AB@%EDX%@AE@% = reference data %@AB@%EBX%@AE@%  VM Handle of message VM  %@NL@%
  13019.  
  13020.  
  13021. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13022.  
  13023. Flags,%@AB@% EAX%@AE@%  %@NL@%
  13024.  
  13025. %@CR:C6A00340008 @%
  13026. %@2@%%@CR:C6A00340009 @%%@AB@%SHELL_Resolve_Contention%@AE@%%@EH@%%@NL@%
  13027. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13028.  
  13029.  
  13030. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13031.  
  13032. This procedure is called to resolve contention. It displays a dialog box in
  13033. which the user chooses which VM should get ownership of the device.  %@NL@%
  13034.  
  13035.  
  13036. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13037.  
  13038. %@AB@%EAX%@AE@% = VM handle of current device owner %@AB@%EBX%@AE@% = VM handle of contending VM
  13039. (Must be %@AB@%Cur_VM_Handle%@AE@%) %@AB@%ESI%@AE@% -> 8 byte device name SPACE PADDED!!!  %@NL@%
  13040.  
  13041.  
  13042. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13043.  
  13044. %@AB@%EBX%@AE@% = VM handle of contention winner If carry is set then contention could
  13045. not be resolved  %@NL@%
  13046.  
  13047.  
  13048. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13049.  
  13050. %@AB@%EBX%@AE@%, Flags  %@NL@%
  13051.  
  13052.  
  13053. %@2@%%@CR:C6A00340010 @%%@AB@%SHELL_SYSMODAL_Message%@AE@%%@EH@%%@NL@%
  13054. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13055.  
  13056.  
  13057. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13058.  
  13059. This procedure is called to put up SYSMODAL messages. Refer to SHELL.INC and
  13060. the %@AI@%Windows SDK%@AE@% for information on message box parameters.  %@NL@%
  13061.  
  13062.  
  13063. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13064.  
  13065. %@AB@%EBX%@AE@% = VM Handle of VM responsible for message %@AB@%EAX%@AE@% = Message box flags (SEE
  13066. MB_xxxx in SHELL.INC)  NOTE THAT MB_SYSTEMMODAL MUST BE SET. %@AB@%ECX%@AE@% -> NUL
  13067. terminated Message Text %@AB@%EDI%@AE@% -> NUL terminated Caption Text == 0 for standard
  13068. caption  -> NUL for No caption  %@NL@%
  13069.  
  13070.  
  13071. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13072.  
  13073. %@AB@%EAX%@AE@% = Response code from dialog box (SEE IDxx in SHELL.INC)  %@NL@%
  13074.  
  13075.  
  13076. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13077.  
  13078. Flags, %@AB@%EAX%@AE@%  %@NL@%
  13079.  
  13080.  
  13081.  
  13082.  
  13083.  
  13084.  
  13085. %@CR:C6A00350001 @%%@1@%%@AB@%Chapter 35  Virtual Display Device (VDD) Services%@AE@%%@EH@%%@NL@%
  13086. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13087.  
  13088. These are the Virtual Display Device (VDD) services. See Chapter 18, "The
  13089. VDD and Grabber DLL," for a more detailed explanation.%@CR:C6A00350002 @%%@NL@%
  13090.  
  13091. The services are described in the following order:  %@NL@%
  13092.  
  13093.  
  13094.   ■   %@AB@%VDD_Msg_BakColor%@AE@%%@NL@%
  13095.  
  13096.   ■   %@AB@%VDD_Msg_ClrScrn%@AE@%%@NL@%
  13097.  
  13098.   ■   %@AB@%VDD_Msg_ForColor%@AE@%%@NL@%
  13099.  
  13100.   ■   %@AB@%VDD_Msg_SetCursorPos%@AE@%%@NL@%
  13101.  
  13102.   ■   %@AB@%VDD_Msg_TextOut%@AE@%%@NL@%
  13103.  
  13104.   ■   %@AB@%VDD_Get_GrabRtn%@AE@%%@NL@%
  13105.  
  13106.   ■   %@AB@%VDD_Get_ModTime%@AE@%%@NL@%
  13107.  
  13108.   ■   %@AB@%VDD_Get_Version%@AE@%%@NL@%
  13109.  
  13110.   ■   %@AB@%VDD_Hide_Cursor%@AE@%%@NL@%
  13111.  
  13112.   ■   %@AB@%VDD_PIF_State%@AE@%%@NL@%
  13113.  
  13114.   ■   %@AB@%VDD_Query_Access%@AE@%%@NL@%
  13115.  
  13116.   ■   %@AB@%VDD_Set_HCurTrk%@AE@%%@NL@%
  13117.  
  13118.   ■   %@AB@%VDD_Set_VMType%@AE@%%@NL@%
  13119.  
  13120.   ■   %@AB@%VDD_Query_Access%@AE@%%@NL@%
  13121.  
  13122.  
  13123.  
  13124. %@2@%%@CR:C6A00350003 @%%@AB@%35.1  Displaying a VM's Video Memory in a Window%@AE@%%@EH@%%@NL@%
  13125.  
  13126. There are several API services supplied to render efficiently a VM's video
  13127. memory into a window. These routines are called by the Grabber. Since the
  13128. Grabber runs in the Windows virtual machine, parameters are passed in the
  13129. Client Registers and in VM memory pointed to by the Client Registers.  %@NL@%
  13130.  
  13131. The first step in updating windowed VMs is for the Shell to call %@AB@%Set_VMState%@AE@%
  13132. with a parameter indicating that the VM is to be windowed. This will enable
  13133. the VDD controller and memory state tracking and reporting of changes. When
  13134. the VM is no longer windowed, %@AB@%Set_VMState%@AE@% is called again. When the VMState
  13135. is not windowed, the %@AB@%Get_Mod%@AE@% call will always return no changes, and the
  13136. video update message will never be generated.  %@NL@%
  13137.  
  13138. The Grabber has to be assured that the call to get the video memory is
  13139. consistent with the call to get the video state; for example, displaying a
  13140. mode 3 VM in mode 10 is inconsistent. To support this, the VM will not run
  13141. after a %@AB@%Get_Mod%@AE@% or %@AB@%Get_Mem%@AE@% call (an exception is hardware interrupts). The
  13142. VM resumes only after a %@AB@%Free_Mem%@AE@% or %@AB@%UnLock_App%@AE@% call. This way the VM's state
  13143. will not change during the process of window updating.  %@NL@%
  13144.  
  13145. An exception is a VM that may update it's video memory during a timer
  13146. interrupt.  %@NL@%
  13147.  
  13148. Notice that when a VM's video state changes, including controller state
  13149. changes such as cursor movement and memory modification, the VDD will send
  13150. WINOLDAPP a display update message. All the changes made to the video state
  13151. will accumulate and be reported by %@AB@%Get_Mod%@AE@% until a %@AB@%Clear_Mod%@AE@% call is made.
  13152. There will only be one display update message per %@AB@%Clear_Mod%@AE@% call.  %@NL@%
  13153.  
  13154.  
  13155. %@2@%%@CR:C6A00350004 @%%@AB@%35.2  Message Mode Services%@AE@%%@EH@%%@NL@%
  13156.  
  13157. When a %@AB@%Begin_Message_Mode%@AE@% control call is made, the VDD goes into a special
  13158. mode that allows the Shell device to use the VDD message services to output
  13159. text to the screen without changing the VM's video state. When the message
  13160. is complete, an %@AB@%End_Message_Mode%@AE@% control call is made that restores the
  13161. focus VM to the hardware.  %@NL@%
  13162.  
  13163. %@CR:C6A00350005 @%
  13164. %@2@%%@CR:C6A00350006 @%%@AB@%VDD_Msg_BakColor%@AE@%%@EH@%%@NL@%
  13165. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13166.  
  13167.  
  13168. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13169.  
  13170. After calling %@AB@%Begin_Message_Mode%@AE@%, this service sets up the background
  13171. attribute.  %@NL@%
  13172.  
  13173.  
  13174. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13175.  
  13176. %@AB@%EAX%@AE@% = Color (for EGA/VGA driver, a text mode attribute) %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13177.  
  13178.  
  13179. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13180.  
  13181. None  %@NL@%
  13182.  
  13183.  
  13184. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13185.  
  13186. Flags  %@NL@%
  13187.  
  13188. %@CR:C6A00350007 @%
  13189. %@2@%%@CR:C6A00350008 @%%@AB@%VDD_Msg_ClrScrn%@AE@%%@EH@%%@NL@%
  13190. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13191.  
  13192.  
  13193. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13194.  
  13195. This routine is called by the Shell to initialize the screen for putting up
  13196. messages. If the focus VM is the current VM, it will clear the screen
  13197. immediately. Otherwise, the screen will be initialized when the focus
  13198. changes. A %@AB@%Begin_Message_Mode%@AE@% device control must be issued before this
  13199. service is used.  %@NL@%
  13200.  
  13201.  
  13202. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13203.  
  13204. %@AB@%EBX%@AE@% = VM handle %@AB@%EAX%@AE@% = background attribute  %@NL@%
  13205.  
  13206.  
  13207. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13208.  
  13209. %@AB@%EAX%@AE@% = width in columns %@AB@%EDX%@AE@% = height in rows  %@NL@%
  13210.  
  13211.  
  13212. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13213.  
  13214. Flags, %@AB@%EAX%@AE@%, %@AB@%EDX%@AE@%  %@NL@%
  13215.  
  13216. %@CR:C6A00350009 @%
  13217. %@2@%%@CR:C6A00350010 @%%@AB@%VDD_Msg_ForColor%@AE@%%@EH@%%@NL@%
  13218. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13219.  
  13220.  
  13221. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13222.  
  13223. After calling %@AB@%Begin_Message_Mode%@AE@%, this service sets up the foreground
  13224. attribute.  %@NL@%
  13225.  
  13226.  
  13227. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13228.  
  13229. %@AB@%EAX%@AE@% = Color (for EGA/VGA driver, a text mode attribute) %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13230.  
  13231.  
  13232. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13233.  
  13234. None  %@NL@%
  13235.  
  13236.  
  13237. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13238.  
  13239. Flags  %@NL@%
  13240.  
  13241. %@CR:C6A00350011 @%
  13242. %@2@%%@CR:C6A00350012 @%%@AB@%VDD_Msg_SetCursPos%@AE@%%@EH@%%@NL@%
  13243. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13244.  
  13245.  
  13246. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13247.  
  13248. After calling %@AB@%Begin_Message_Mode%@AE@%, this routine sets the cursor position.  %@NL@%
  13249.  
  13250.  
  13251. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13252.  
  13253. %@AB@%EAX%@AE@% = row %@AB@%EDX%@AE@% = column %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13254.  
  13255.  
  13256. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13257.  
  13258. None  %@NL@%
  13259.  
  13260.  
  13261. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13262.  
  13263. Flags  %@NL@%
  13264.  
  13265. %@CR:C6A00350013 @%
  13266. %@2@%%@CR:C6A00350014 @%%@AB@%VDD_Msg_TextOut%@AE@%%@EH@%%@NL@%
  13267. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13268.  
  13269.  
  13270. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13271.  
  13272. After calling %@AB@%Begin_Message_Mode%@AE@% and setting up the foreground and
  13273. background colors, this service puts characters on the screen.  %@NL@%
  13274.  
  13275.  
  13276. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13277.  
  13278. %@AB@%ESI%@AE@% = address of string %@AB@%ECX%@AE@% = length of string %@AB@%EAX%@AE@% = row start %@AB@%EDX%@AE@% = column
  13279. start %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13280.  
  13281.  
  13282. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13283.  
  13284. None  %@NL@%
  13285.  
  13286.  
  13287. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13288.  
  13289. Flags  %@NL@%
  13290.  
  13291.  
  13292. %@2@%%@CR:C6A00350015 @%%@AB@%35.3  Miscellaneous VDD Services%@AE@%%@EH@%%@NL@%
  13293. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13294.  
  13295. The services discussed in this section provide other VDD functions not
  13296. easily catagorized, such as hiding the cursor. They are provided here in
  13297. alphabetical order.  %@NL@%
  13298.  
  13299. %@CR:C6A00350016 @%
  13300. %@2@%%@CR:C6A00350017 @%%@AB@%VDD_Get_GrabRtn%@AE@%%@EH@%%@NL@%
  13301. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13302.  
  13303.  
  13304. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13305.  
  13306. This service returns the address of video grab routine. The grab routine is
  13307. called by the Shell device when the appropriate hot key is pressed by the
  13308. user. It makes a copy of the visible screen and controller state of the
  13309. current VM. That copy is then accessible via the %@AB@%GRB_Get_GrbState%@AE@% and
  13310. %@AB@%GRB_Get_GrbMem%@AE@% services.  %@NL@%
  13311.  
  13312.  
  13313. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13314.  
  13315. None  %@NL@%
  13316.  
  13317.  
  13318. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13319.  
  13320. %@AB@%ESI%@AE@% = address of grab routine  %@NL@%
  13321.  
  13322.  
  13323. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13324.  
  13325. Flags, %@AB@%ESI%@AE@%  %@NL@%
  13326.  
  13327. %@CR:C6A00350018 @%
  13328. %@2@%%@CR:C6A00350019 @%%@AB@%VDD_Get_ModTime%@AE@%%@EH@%%@NL@%
  13329. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13330.  
  13331.  
  13332. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13333.  
  13334. This routine is used to determine if any video activity has occurred. The
  13335. poll device uses it to determine if the VM is idle.  %@NL@%
  13336.  
  13337.  
  13338. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13339.  
  13340. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13341.  
  13342.  
  13343. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13344.  
  13345. %@AB@%EAX%@AE@% = System Timer at last video modification  %@NL@%
  13346.  
  13347.  
  13348. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13349.  
  13350. Flags, %@AB@%EAX%@AE@%  %@NL@%
  13351.  
  13352. %@CR:C6A00350020 @%
  13353. %@2@%%@CR:C6A00350021 @%%@AB@%VDD_Get_Version%@AE@%%@EH@%%@NL@%
  13354. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13355.  
  13356.  
  13357. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13358.  
  13359. This service returns the version number and device ID.  %@NL@%
  13360.  
  13361.  
  13362. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13363.  
  13364. None  %@NL@%
  13365.  
  13366.  
  13367. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13368.  
  13369. %@AB@%ESI %@AE@%= ptr to 8 byte ID string %@AB@%AH%@AE@% = major version %@AB@%AL%@AE@% = minor version Carry
  13370. Flag clear  %@NL@%
  13371.  
  13372.  
  13373. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13374.  
  13375. Flags, %@AB@%AX%@AE@%, %@AB@%ESI%@AE@%  %@NL@%
  13376.  
  13377. %@CR:C6A00350022 @%
  13378. %@2@%%@CR:C6A00350023 @%%@AB@%VDD_Hide_Cursor%@AE@%%@EH@%%@NL@%
  13379. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13380.  
  13381.  
  13382. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13383.  
  13384. This service hides/shows the cursor in a window. If %@AB@%EAX%@AE@% is nonzero, then
  13385. this service sets a hide cursor flag or else clears the flag. This is so
  13386. that, if the mouse is using a hardware cursor, it can turn off that cursor
  13387. while the VM is windowed (since the VM will no longer own the mouse).  %@NL@%
  13388.  
  13389.  
  13390. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13391.  
  13392. %@AB@%EAX%@AE@% = 0 if cursor SHOULD be displayed in a window   0 if cursor SHOULD NOT
  13393. be displayed in a window  %@AB@%EBX%@AE@% = control block pointer  %@NL@%
  13394.  
  13395.  
  13396. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13397.  
  13398. None  %@NL@%
  13399.  
  13400.  
  13401. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13402.  
  13403. Flags  %@NL@%
  13404.  
  13405. %@CR:C6A00350024 @%
  13406. %@2@%%@CR:C6A00350025 @%%@AB@%VDD_PIF_State%@AE@%%@EH@%%@NL@%
  13407. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13408.  
  13409.  
  13410. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13411.  
  13412. This service informs the VDD about PIF bits for the VM just created.  %@NL@%
  13413.  
  13414.  
  13415. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13416.  
  13417. %@AB@%EBX%@AE@% = VM handle %@AB@%AX%@AE@% = PIF bits  %@NL@%
  13418.  
  13419.  
  13420. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13421.  
  13422. None  %@NL@%
  13423.  
  13424.  
  13425. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13426.  
  13427. Flags  %@NL@%
  13428.  
  13429. %@CR:C6A00350026 @%
  13430. %@2@%%@CR:C6A00350027 @%%@AB@%VDD_Query_Access%@AE@%%@EH@%%@NL@%
  13431. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13432.  
  13433.  
  13434. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13435.  
  13436. Returns error if there is an attempt by the specified VM by the specified VM
  13437. to access the video memory. This is used by the Virtual Mouse Device to
  13438. decide whether or not to turn off the mouse cursor when a VM no longer has
  13439. the mouse focus. This service should only be called in a VM Event just
  13440. before returning to the VM, e.g. %@AB@%Exec_Int%@AE@% to the mouse driver.  %@NL@%
  13441.  
  13442.  
  13443. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13444.  
  13445. %@AB@%EBX%@AE@% = VM Handle  %@NL@%
  13446.  
  13447.  
  13448. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13449.  
  13450. If video access OK  Carry Flag Clear else  Carry Flag Set  %@NL@%
  13451.  
  13452.  
  13453. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13454.  
  13455. Flags Returns error if an attempt  %@NL@%
  13456.  
  13457. %@CR:C6A00350028 @%
  13458. %@2@%%@CR:C6A00350029 @%%@AB@%VDD_Set_HCurTrk%@AE@%%@EH@%%@NL@%
  13459. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13460.  
  13461.  
  13462. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13463.  
  13464. This service sets flag passed to VMDOSAPP indicating that VMDOSAPP should
  13465. maintain the cursor position within the display window for this application.
  13466. This is called by the Keyboard driver when a keyboard interrupt is simulated
  13467. into a VM.  %@NL@%
  13468.  
  13469.  
  13470. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13471.  
  13472. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13473.  
  13474.  
  13475. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13476.  
  13477. None  %@NL@%
  13478.  
  13479.  
  13480. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13481.  
  13482. Flags  %@NL@%
  13483.  
  13484. %@CR:C6A00350030 @%
  13485. %@2@%%@CR:C6A00350031 @%%@AB@%VDD_Set_VMType%@AE@%%@EH@%%@NL@%
  13486. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13487.  
  13488.  
  13489. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13490.  
  13491. This service is used to inform the VDD of a VM's type. The parameter
  13492. explicitly passed is the windowed flag. The VM status flags, Exclusive and
  13493. Background, are implicity passed. This should be called prior to running the
  13494. VM and each time thereafter that any of the VM parameters are modified.
  13495. Notice that, for a system critical %@AB@%Set_Focus%@AE@%, this routine may not be called
  13496. before the %@AB@%Set_Focus%@AE@%. In that case, the VDD is responsible for doing an
  13497. implied %@AB@%Set_VMType%@AE@% (not windowed).  %@NL@%
  13498.  
  13499.  
  13500. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13501.  
  13502. %@AB@%EAX%@AE@% = state flag (= nonzero if changing to windowed VM) %@AB@%EBX%@AE@% = VM handle
  13503. whose state is to change  %@NL@%
  13504.  
  13505.  
  13506. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13507.  
  13508. None  %@NL@%
  13509.  
  13510.  
  13511. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13512.  
  13513. Flags  %@NL@%
  13514.  
  13515. %@CR:C6A00350032 @%
  13516. %@2@%%@CR:C6A00350033 @%%@AB@%VDD_Query_Access%@AE@%%@EH@%%@NL@%
  13517. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13518.  
  13519.  
  13520. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13521.  
  13522. This service is used by the other VxDs when they want to access video
  13523. memory. The VxD should not access video memory unless this routine says it
  13524. is OK.  %@NL@%
  13525.  
  13526.  
  13527. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13528.  
  13529. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13530.  
  13531.  
  13532. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13533.  
  13534. if access is OK, carry flag = 0  else carry flag = 1  %@NL@%
  13535.  
  13536.  
  13537. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13538.  
  13539. Flags  %@NL@%
  13540.  
  13541.  
  13542.  
  13543.  
  13544.  
  13545.  
  13546. %@CR:C6A00360001 @%%@1@%%@AB@%Chapter 36  Virtual Keyboard Device (VKD) Services%@AE@%%@EH@%%@NL@%
  13547. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13548.  
  13549. The Virtual Keyboard Device (VKD) provides services that support hot keys,
  13550. Message Mode key handling, and keyed input to VMs. The services are
  13551. presented in the following order:%@CR:C6A00360002 @%%@NL@%
  13552.  
  13553.  
  13554.   ■   %@AB@%VKD_Cancel_Hot_Key_State%@AE@%%@NL@%
  13555.  
  13556.   ■   %@AB@%VKD_Cancel_Paste%@AE@%%@NL@%
  13557.  
  13558.   ■   %@AB@%VKD_Define_Hot_Key%@AE@%%@NL@%
  13559.  
  13560.   ■   %@AB@%VKD_Define_Paste_Mode%@AE@%%@NL@%
  13561.  
  13562.   ■   %@AB@%VKD_Flush_Msg_Key_Queue%@AE@%%@NL@%
  13563.  
  13564.   ■   %@AB@%VKD_Force_Keys%@AE@%%@NL@%
  13565.  
  13566.   ■   %@AB@%VKD_Get_Kbd_Owner%@AE@%%@NL@%
  13567.  
  13568.   ■   %@AB@%VKD_Get_Msg_Key%@AE@%%@NL@%
  13569.  
  13570.   ■   %@AB@%VKD_Get_Version%@AE@%%@NL@%
  13571.  
  13572.   ■   %@AB@%VKD_Local_Disable_Hot_Key%@AE@%%@NL@%
  13573.  
  13574.   ■   %@AB@%VKD_Local_Enable_Hot_Key%@AE@%%@NL@%
  13575.  
  13576.   ■   %@AB@%VKD_Peek_Msg_Key%@AE@%%@NL@%
  13577.  
  13578.   ■   %@AB@%VKD_Reflect_Hot_Key%@AE@%%@NL@%
  13579.  
  13580.   ■   %@AB@%VKD_Remove_Hot_Key%@AE@%%@NL@%
  13581.  
  13582.   ■   %@AB@%VKD_Start_Paste%@AE@%%@NL@%
  13583.  
  13584.  
  13585. These are protected-mode API services used by WINOLDAP to send keys to a
  13586. windowed VM.  %@NL@%
  13587.  
  13588. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  13589. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  13590.  
  13591. %@CR:C6A00360003 @%
  13592. %@2@%%@CR:C6A00360004 @%%@AB@%VKD_Cancel_Hot_Key_State%@AE@%%@EH@%%@NL@%
  13593. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13594.  
  13595.  
  13596. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13597.  
  13598. This service causes the VKD to exit the hot key state.  %@NL@%
  13599.  
  13600.  
  13601. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13602.  
  13603. None  %@NL@%
  13604.  
  13605.  
  13606. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13607.  
  13608. Keys will start being passed into the focus VM again  %@NL@%
  13609.  
  13610.  
  13611. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13612.  
  13613. None  %@NL@%
  13614.  
  13615. %@CR:C6A00360005 @%
  13616. %@2@%%@CR:C6A00360006 @%%@AB@%VKD_Cancel_Paste%@AE@%%@EH@%%@NL@%
  13617. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13618.  
  13619.  
  13620. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13621.  
  13622. This service cancels the paste that was started in the VM with
  13623. %@AB@%VKD_Start_Paste%@AE@%.  %@NL@%
  13624.  
  13625.  
  13626. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13627.  
  13628. %@AB@%EBX%@AE@% is VM handle  %@NL@%
  13629.  
  13630.  
  13631. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13632.  
  13633. None  %@NL@%
  13634.  
  13635.  
  13636. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13637.  
  13638. Flags  %@NL@%
  13639.  
  13640. %@CR:C6A00360007 @%
  13641. %@2@%%@CR:C6A00360008 @%%@AB@%VKD_Define_Hot_Key%@AE@%%@EH@%%@NL@%
  13642. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13643.  
  13644.  
  13645. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13646.  
  13647. This service defines a hot key notification routine. Hot keys are detected
  13648. by ANDing the shift state mask with the global shift state, then comparing
  13649. the resulting state with the shift state compare value. If this matches, and
  13650. the key code matches, then the callback routine is called with the specified
  13651. reference data in %@AB@%EDX%@AE@%.  %@NL@%
  13652.  
  13653.  
  13654. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13655.  
  13656. %@AB@%AL%@AE@% = scan code of the main key %@AB@%AH%@AE@% = 0, if normal code %@AB@%AH%@AE@% = 1, if extended
  13657. code (ExtendedKey_B) %@AB@%AH%@AE@% = 0FFh, if either (AllowExtended_B) %@AB@%EBX%@AE@% = shift
  13658. state  high word is mask that is ANDed with the global shift state  when
  13659. checking for this hot key; low word is masked shift state  compare value.
  13660. Equates for common shift mask and compare values are    defined in VKD.INC:
  13661. HKSS_Shift for either shift key      HKSS_Ctrl for either control key
  13662. HKSS_Alt for either ALT key    The macro ShiftState is also defined to load
  13663. %@AB@%EBX%@AE@% with the mask    and compare value. e.g.,      ShiftState <SS_ALT +
  13664. SS_Toggle_mask>, SS_RAlt    loads %@AB@%EBX%@AE@% so that the hot key will only be
  13665. recognized when the    Right ALT key is held down.    VKD>INC also defines
  13666. "SS_" equates for the different shift state    bits and common combinations
  13667. of bits. %@AB@%CL%@AE@% = flags  CallOnPress - Call callback when key press is detected
  13668. CallOnRelease - Call callback when key release is  detected  (keyboard may
  13669. still be in hot-key hold  state)  CallOnRepeat - Call callback when repeated
  13670. press is  detected  CallOnComplete - Call callback when the hot key state is
  13671. ended(all shift modifier keys are  released) or when a different hot key is
  13672. entered (i.e. pressing ALT 1 2, if both  ALT+1 and ALT+2 are defined hot
  13673. keys,  then ALT+1's callback will be called  before ALT+2's to indicate that
  13674. the ALT+1  is complete even though the ALT key is  still down)  CallOnUpDwn
  13675. - Call on both press and release  CallOnAll  - Call on press, release and
  13676. repeats  PriorityNotify - Used with one of the call options to  specify that
  13677. the callback can only be  called when interrupts are enabled and the
  13678. critical section is un-owned  Local_Key - Key can be locally
  13679. enabled/disabled  %@NL@%
  13680.  
  13681. %@AB@%ESI%@AE@% = offset of callback routine %@AB@%EDX%@AE@% = reference data %@AB@%EDI%@AE@% = maximum
  13682. notification delay if PriorityNotify is set,  0, means always notify
  13683. (milliseconds)  %@NL@%
  13684.  
  13685.  
  13686. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13687.  
  13688. If Carry clear then  EAX = definition handle else the definition failed (no
  13689. more room)  %@NL@%
  13690.  
  13691.  
  13692. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13693.  
  13694. Flags  %@NL@%
  13695.  
  13696.  
  13697. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  13698.  
  13699. Called when hot key is detected, and detection meets mask requirements.
  13700. (CallOnPress, CallOnRelease, CallOnRepeat, CallOnUpDwn, or CallOnAll)  %@AB@%AL%@AE@% =
  13701. scan code of key  %@AB@%AH%@AE@% = 0, if key just pressed (Hot_Key_Pressed)  = 1, if key
  13702. just released (Hot_Key_Released)  = 2, if key is an auto-repeat press
  13703. (Hot_Key_Repeated)  = 3, hot key state ended (Hot_Key_Completed)  %@AB@%EBX%@AE@% is hot
  13704. key handle  %@AB@%ECX%@AE@% = global shift state  %@AB@%EDX%@AE@% is reference data  %@AB@%EDI%@AE@% = elapsed
  13705. time for delayed notification (milliseconds) (normally 0, but if
  13706. PriorityNotify is specified then this value could be larger) This procedure
  13707. 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@%
  13708.  
  13709. %@CR:C6A00360009 @%
  13710. %@2@%%@CR:C6A00360010 @%%@AB@%VKD_Define_Paste_Mode%@AE@%%@EH@%%@NL@%
  13711. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13712.  
  13713.  
  13714. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13715.  
  13716. This service selects the VM's paste mode, whether INT 16 pasting can be
  13717. attempted or not. Some applications hook INT 9 and do things that will not
  13718. allow pasting to be done through INT 16H. Normally, VKD can detect this by
  13719. setting a timeout to see if any INT 16s are being done by the application,
  13720. and if not, then switching to INT 9 paste. But, some applications may do
  13721. some INT 16s, in which case the paste would be broken. Therefore, this
  13722. service is provided to allow the Shell device to force a VM into INT 9
  13723. paste, based only on a PIF bit.  %@NL@%
  13724.  
  13725.  
  13726. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13727.  
  13728. %@AB@%AL%@AE@% = 0 allow INT 16 paste attempts %@AB@%AL%@AE@% = 1 force INT 9 pasting %@AB@%EBX%@AE@% = VM
  13729. handle  %@NL@%
  13730.  
  13731.  
  13732. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13733.  
  13734. None  %@NL@%
  13735.  
  13736.  
  13737. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13738.  
  13739. Flags  %@NL@%
  13740.  
  13741. %@CR:C6A00360011 @%
  13742. %@2@%%@CR:C6A00360012 @%%@AB@%VKD_Flush_Msg_Key_Queue%@AE@%%@EH@%%@NL@%
  13743. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13744.  
  13745.  
  13746. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13747.  
  13748. This service flushes any available keys from the special message mode input
  13749. buffer.  %@NL@%
  13750.  
  13751.  
  13752. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13753.  
  13754. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13755.  
  13756.  
  13757. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13758.  
  13759. Input buffer has been cleared  %@NL@%
  13760.  
  13761.  
  13762. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13763.  
  13764. Flags  %@NL@%
  13765.  
  13766. %@CR:C6A00360013 @%
  13767. %@2@%%@CR:C6A00360014 @%%@AB@%VKD_Force_Keys%@AE@%%@EH@%%@NL@%
  13768. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13769.  
  13770.  
  13771. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13772.  
  13773. This service forces scan codes into the keyboard buffer that look exactly
  13774. like they had been typed on the physical keyboard. These keys will be
  13775. processed in the context of the focus VM.  %@NL@%
  13776.  
  13777.  
  13778. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13779.  
  13780. %@AB@%ESI%@AE@% points to a buffer of scan codes %@AB@%ECX%@AE@% is # of scan codes in the buffer  %@NL@%
  13781.  
  13782.  
  13783. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13784.  
  13785. If the keyboard buffer was overflowed, then  Carry set  ECX is # of
  13786. remaining scan codes that did not fit  %@NL@%
  13787.  
  13788.  
  13789. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13790.  
  13791. %@AB@%ECX%@AE@%,Flags  %@NL@%
  13792.  
  13793. %@CR:C6A00360015 @%
  13794. %@2@%%@CR:C6A00360016 @%%@AB@%VKD_Get_Kbd_Owner%@AE@%%@EH@%%@NL@%
  13795. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13796.  
  13797.  
  13798. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13799.  
  13800. This service gets the VM Handle of the keyboard focus VM.  %@NL@%
  13801.  
  13802.  
  13803. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13804.  
  13805. None  %@NL@%
  13806.  
  13807.  
  13808. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13809.  
  13810. %@AB@%EBX%@AE@% = VM Handle of keyboard owner  %@NL@%
  13811.  
  13812.  
  13813. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13814.  
  13815. Flags, %@AB@%EBX%@AE@%  %@NL@%
  13816.  
  13817. %@CR:C6A00360017 @%
  13818. %@2@%%@CR:C6A00360018 @%%@AB@%VKD_Get_Msg_Key%@AE@%%@EH@%%@NL@%
  13819. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13820.  
  13821.  
  13822. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13823.  
  13824. This service returns the next available key from the special message mode
  13825. input buffer and removes it from the buffer. If no key is available, then it
  13826. returns with the Z flag set. (This is not a blocking read!)  %@NL@%
  13827.  
  13828.  
  13829. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13830.  
  13831. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13832.  
  13833.  
  13834. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13835.  
  13836. Z flag clear, if key was read  AL = scan code  AH = modifier flags  MK_Shift
  13837. - a SHIFT key is down  MK_Ctrl - a CTRL key is down  MK_Alt - an ALT key is
  13838. down  MK_Extended - the key is an extended key  Z flag set, if no key
  13839. available  %@NL@%
  13840.  
  13841.  
  13842. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13843.  
  13844. %@AB@%EAX%@AE@%, Flags  %@NL@%
  13845.  
  13846. %@CR:C6A00360019 @%
  13847. %@2@%%@CR:C6A00360020 @%%@AB@%VKD_Get_Version%@AE@%%@EH@%%@NL@%
  13848. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13849.  
  13850.  
  13851. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13852.  
  13853. This service gets the VKD version number.  %@NL@%
  13854.  
  13855.  
  13856. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13857.  
  13858. None  %@NL@%
  13859.  
  13860.  
  13861. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13862.  
  13863. %@AB@%AH%@AE@% = major, %@AB@%AL%@AE@% = minor Carry Flag clear  %@NL@%
  13864.  
  13865.  
  13866. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13867.  
  13868. %@AB@%EAX%@AE@%, Flags  %@NL@%
  13869.  
  13870. %@CR:C6A00360021 @%
  13871. %@2@%%@CR:C6A00360022 @%%@AB@%VKD_Local_Disable_Hot_Key%@AE@%%@EH@%%@NL@%
  13872. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13873.  
  13874.  
  13875. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13876.  
  13877. This service disables a hot key in the specified VM. It is only allowed on
  13878. hot keys which were declared with the Local_Key bit set in CL.  %@NL@%
  13879.  
  13880.  
  13881. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13882.  
  13883. %@AB@%EAX%@AE@% is hot key handle %@AB@%EBX%@AE@% is VM handle  %@NL@%
  13884.  
  13885.  
  13886. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13887.  
  13888. None  %@NL@%
  13889.  
  13890.  
  13891. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13892.  
  13893. Flags  %@NL@%
  13894.  
  13895. %@CR:C6A00360023 @%
  13896. %@2@%%@CR:C6A00360024 @%%@AB@%VKD_Local_Enable_Hot_Key%@AE@%%@EH@%%@NL@%
  13897. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13898.  
  13899.  
  13900. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13901.  
  13902. This service enables a hot key in the specified VM. It is only allowed on
  13903. hot keys which were declared with the local key bit set in CL.  %@NL@%
  13904.  
  13905.  
  13906. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13907.  
  13908. %@AB@%EAX%@AE@% is hot key handle %@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:C6A00360025 @%
  13921. %@2@%%@CR:C6A00360026 @%%@AB@%VKD_Peek_Msg_Key%@AE@%%@EH@%%@NL@%
  13922. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13923.  
  13924.  
  13925. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13926.  
  13927. This service returns the next available key from the special message mode
  13928. input buffer without removing it from the buffer. If no key is available,
  13929. then it returns with the Z flag set.  %@NL@%
  13930.  
  13931.  
  13932. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13933.  
  13934. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  13935.  
  13936.  
  13937. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13938.  
  13939. Z flag clear, if key available  AL = scan code  AH = modifier flags
  13940. MK_Shift - a shift key is down  MK_Ctrl - a control key is down  MK_Alt - an
  13941. alt key is down  MK_Extended - the key is an extended key Z flag set, if no
  13942. key available  %@NL@%
  13943.  
  13944.  
  13945. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13946.  
  13947. %@AB@%EAX%@AE@%, Flags  %@NL@%
  13948.  
  13949. %@CR:C6A00360027 @%
  13950. %@2@%%@CR:C6A00360028 @%%@AB@%VKD_Reflect_Hot_Key%@AE@%%@EH@%%@NL@%
  13951. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13952.  
  13953.  
  13954. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13955.  
  13956. This service reflects a hot key into a specified VM and exits the hot key
  13957. state. This service is normally called by a hot key notification callback
  13958. routine. It enables the callback to send the hot key into a VM and pretend
  13959. that it wasn't really recognized as a hot key. VKD will simulate the
  13960. required key strokes to get the VM into the state of this specified shift
  13961. state, then it will simulate the key strokes for the hot key itself, and
  13962. finally simulate key strokes to get the VM to match the current global shift
  13963. state.  %@NL@%
  13964.  
  13965.  
  13966. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13967.  
  13968. %@AB@%EAX%@AE@% is hot key handle %@AB@%EBX%@AE@% is VM handle %@AB@%CX%@AE@% is required shift state  %@NL@%
  13969.  
  13970.  
  13971. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13972.  
  13973. Hot key has been reflected, and VKD is no longer in hot key state  %@NL@%
  13974.  
  13975.  
  13976. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  13977.  
  13978. Flags  %@NL@%
  13979.  
  13980. %@CR:C6A00360029 @%
  13981. %@2@%%@CR:C6A00360030 @%%@AB@%VKD_Remove_Hot_Key%@AE@%%@EH@%%@NL@%
  13982. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13983.  
  13984.  
  13985. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  13986.  
  13987. This service removes a defined hot key.  %@NL@%
  13988.  
  13989.  
  13990. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  13991.  
  13992. %@AB@%EAX%@AE@% is hot key definition handle to be removed  %@NL@%
  13993.  
  13994.  
  13995. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  13996.  
  13997. None  %@NL@%
  13998.  
  13999.  
  14000. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14001.  
  14002. Flags  %@NL@%
  14003.  
  14004. %@CR:C6A00360031 @%
  14005. %@2@%%@CR:C6A00360032 @%%@AB@%VKD_Start_Paste%@AE@%%@EH@%%@NL@%
  14006. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14007.  
  14008.  
  14009. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14010.  
  14011. This service puts a VM into paste mode by simulating keyboard activity with
  14012. keystrokes taken from the specified paste buffer. Depending on the mode set
  14013. with the service %@AB@%VKD_Define_Paste_Mode%@AE@% (default is to try INT 16 pasting),
  14014. VKD waits for the VM to poll the keyboard BIOS through its INT 16 interface.
  14015. If the VM does keyboard input through the BIOS, then VKD will simulate the
  14016. keyboard input at this high level (plugging in ASCII codes.) If the VM fails
  14017. to perform any INT 16s within in a timeout period, or the mode has been set
  14018. to avoid INT 16 pasting, then VKD will simulate the necessary hardware
  14019. interrupts to perform the pasting. Physically typed hot keys are still
  14020. processed while pasting is in progress.  %@NL@%
  14021.  
  14022.  
  14023. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14024.  
  14025. %@AB@%EAX%@AE@% is linear address of paste buffer  the paste buffer contains an array of
  14026. key structures:  OEM_ASCII_value db ?  scan_code db ?  shift_state dw ?
  14027. shift state bits are:  0000000000000010b shift key depressed
  14028. 0000000000000100b ctrl key depressed The scan code should be FFh and the
  14029. shift state FFFFh, if VKD should convert the key to a ALT+numpad sequence.
  14030. (this information is identical to what is given by the Window's keyboard
  14031. routine %@AB@%OEMKeyScan%@AE@%)   %@AB@%EBX%@AE@% is VM handle  %@AB@%ECX%@AE@% is number of paste entries in
  14032. the paste buffer  %@AB@%ESI%@AE@% is call back address (can be 0)  %@AB@%EDX%@AE@% is reference data
  14033. %@NL@%
  14034.  
  14035.  
  14036. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14037.  
  14038. Carry clear paste is started  Carry set paste failed, unable to allocate
  14039. memory for buffer copy  %@NL@%
  14040.  
  14041.  
  14042. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14043.  
  14044. Flags  %@NL@%
  14045.  
  14046.  
  14047. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  14048.  
  14049. Called when paste is completed or cancelled   %@AB@%EAX%@AE@% is completion flags
  14050. %@AB@%Paste_Complete%@AE@% - paste completed successfully   %@AB@%Paste_Aborted%@AE@% - paste
  14051. cancelled by user   %@AB@%Paste_VM_Term%@AE@% - paste aborted because VM terminated
  14052. %@AB@%EBX%@AE@% is VM handle of VM that was receiving the paste   %@AB@%EDX%@AE@% is reference data
  14053. Procedure can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and Flags  %@NL@%
  14054.  
  14055.  
  14056.  
  14057.  
  14058.  
  14059.  
  14060. %@CR:C6A00370001 @%%@1@%%@AB@%Chapter 37  Virtual PIC Device (VPICD) Services%@AE@%%@EH@%%@NL@%
  14061. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14062.  
  14063. The Virtual Programmable Interrupt Controller Device (VPICD) routes hardware
  14064. interrupts to other virtual devices, provides services that allow virtual
  14065. devices to request interrupts, and simulates hardware interrupts into
  14066. virtual machines. See Chapter 16, "Overview of Windows in 386 Enhanced
  14067. Mode," and Chapter 17, "Virtual Device Programming Topics," for general
  14068. discussions of the VPICD.%@CR:C6A00370002 @%%@NL@%
  14069.  
  14070. Peripherals, such as disk drives and COM ports, use hardware (physical)
  14071. interrupts to notify software of changes in their status.  %@NL@%
  14072.  
  14073. The topics in this chapter are presented in the following order:  %@NL@%
  14074.  
  14075.  
  14076.   ■   Default Interrupt Handling%@NL@%
  14077.  
  14078.   ■   Virtualizing an IRQ%@NL@%
  14079.  
  14080.   ■   Virtualized IRQ Callback Procedures%@NL@%
  14081.  
  14082.   ■   VPICD Services%@NL@%
  14083.  
  14084.   ■   Grabber
  14085. %@NL@%
  14086.  
  14087.  
  14088.  
  14089. %@2@%%@CR:C6A00370003 @%%@AB@%37.1  Default Interrupt Handling%@AE@%%@EH@%%@NL@%
  14090.  
  14091. The most basic function of VPICD is to emulate the functions of the physical
  14092. interrupt controller (PIC). This entails reflecting interrupts into virtual
  14093. machines and simulating I/O such as recognizing when a VM issues an EOI (End
  14094. Of Interrupt), reading the mask register, etc. When VPICD is initialized, it
  14095. sets up a default interrupt handler for every Interrupt ReQuest (IRQ). These
  14096. handlers determine which VM an interrupt should be reflected into, and they
  14097. arbitrate conflicts between virtual machines that attempt to unmask the same
  14098. interrupt.  %@NL@%
  14099.  
  14100. An interrupt that is unmasked when enhanced Windows is initialized is
  14101. considered a global interrupt. A global interrupt will always be reflected
  14102. into the currently executing virtual machine, and any VM can mask or unmask
  14103. the IRQ. If a virtual machine unmasks an IRQ that was masked when the
  14104. enhanced Windows environment was initialized, it will own that IRQ. All
  14105. interrupts for an owned IRQ will be reflected only to the IRQ's owner. If
  14106. another virtual machine attempts to unmask the interrupt, the second VM will
  14107. be terminated and the user will see a dialog box that tells him to reboot
  14108. his computer.  %@NL@%
  14109.  
  14110. It is important to remember that this is only the default behavior of VPICD.
  14111. If another virtual device virtualizes an IRQ it is up to the device that
  14112. virtualized the interrupt to determine which VMs receive interrupts and
  14113. arbitrate conflicts. Once an IRQ is virtualized, VPICD's default handling
  14114. for that IRQ stops.  %@NL@%
  14115.  
  14116.  
  14117. %@2@%%@CR:C6A00370004 @%%@AB@%37.2  Virtualizing an IRQ%@AE@%%@EH@%%@NL@%
  14118.  
  14119. When a virtual device needs to hook a specific IRQ (Interrupt ReQuest), it
  14120. must ask VPICD for permission. If another device has already virtualized the
  14121. IRQ, then the call will fail if either of the VxDs is unable to share the
  14122. IRQ (both must have the %@AB@%Can_Share%@AE@% option set for two VxDs to use the same
  14123. IRQ).  %@NL@%
  14124.  
  14125. When a VxD calls%@AB@% VPICD_Virtualize_IRQ%@AE@%, it passes a pointer to a structure
  14126. called an IRQ Descriptor that contains the number of the IRQ and the address
  14127. of several callback procedures. This structure is included in the file
  14128. VPICD.INC:  %@NL@%
  14129.  
  14130. %@AS@%  VPICD_IRQ_Descriptor  STRUC     
  14131. %@AS@%   VID_IRQ_Number       dw   ?     
  14132. %@AS@%   VID_Options          dw   0     
  14133. %@AS@%   VID_Hw_Int_Proc      dd   ?     
  14134. %@AS@%   VID_Virt_Int_Proc    dd   0     
  14135. %@AS@%   VID_EOI_Proc         dd   0     
  14136. %@AS@%   VID_Mask_Change_Proc dd   0     
  14137. %@AS@%   VID_IRET_Proc        dd   0     
  14138. %@AS@%   VID_IRET_Time_Out    dd   500     
  14139. %@AS@%  VPICD_IRQ_Descriptor  ENDS%@AE@%
  14140.  
  14141. The %@AB@%VID_IRQ_Number%@AE@% contains the number of the IRQ the VxD wishes to
  14142. virtualize. %@AB@%VID_Options%@AE@% is a bit field that is used to specify special
  14143. options. The next five fields specify the address of various callback
  14144. procedures. The final field determines the maximum amount of time in
  14145. milliseconds that VPICD will allow before the interrupt is timed-out.
  14146. Time-outs are very important to prevent the enhanced Windows environment
  14147. from hanging while simulating a hardware interrupt.  %@NL@%
  14148.  
  14149.  
  14150. %@2@%%@CR:C6A00370005 @%%@AB@%37.3  Virtualized IRQ Callback Procedures%@AE@%%@EH@%%@NL@%
  14151.  
  14152. A virtual device may specify up to five callback procedures in its
  14153. %@AB@%IRQ_Descriptor%@AE@% structure. One of these, %@AB@%Hw_Int_Proc%@AE@%, is required. The other
  14154. callback procedures are optional and are simply used to inform a virtual
  14155. device whenever the state of the virtualized IRQ changes. For example, the
  14156. %@AB@%Virt_Int_Proc%@AE@% procedure will be called whenever an interrupt is simulated
  14157. into a VM; the %@AB@%Mask_Change_Proc%@AE@% is called whenever a virtual machine masks
  14158. or unmasks the interrupt, etc. Each of the callback procedures is described
  14159. in this section in detail and in alphabetical order. Callback procedures may
  14160. modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, and Flags. Although they will be called with
  14161. interrupts disabled, they are allowed to enable them. If the procedures
  14162. perform a lot of processing, interrupts should be executed.  %@NL@%
  14163.  
  14164. %@CR:C6A00370006 @%
  14165. %@2@%%@CR:C6A00370007 @%%@AB@%VID_Hw_Int_Proc%@AE@%%@EH@%%@NL@%
  14166. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14167.  
  14168.  
  14169. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14170.  
  14171. The %@AB@%VID_Hw_Int_Proc%@AE@% procedure is called whenever a hardware interrupt
  14172. occurs. Notice that the procedure is just that, a procedure that returns
  14173. using a near return ─ not an IRET. Since the the VxD environment kernel is
  14174. single-threaded, the services that this procedure is allowed to call are
  14175. limited because it is possible for an interrupt to occur while executing in
  14176. the VMM. Therefore, many interrupt procedures will need to use the
  14177. %@AB@%Schedule_Call_Global_Event%@AE@% services to perform additional processing of an
  14178. interrupt. A typical %@AB@%VID_Hw_Int_Proc%@AE@% will service the physical device, call
  14179. %@AB@%VPICD_Phys_EOI%@AE@% to end the physical interrupt, and set the virtual IRQ
  14180. request for a specific virtual machine. Some VxDs may never request an
  14181. interrupt for a virtual machine and others may request more than one
  14182. interrupt per physical interrupt. In any case, every physical interrupt does
  14183. not need to be reflected 1-1 into a virtual machine.  %@NL@%
  14184.  
  14185.  
  14186. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14187.  
  14188. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  14189.  
  14190.  
  14191. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14192.  
  14193. If the IRQ is shareable then Carry Set indicates that the interrupt was not
  14194. handled by VxD Carry Clear indicates that the interrupt was handled by VxD  %@NL@%
  14195.  
  14196.  
  14197. %@2@%%@CR:C6A00370008 @%%@AB@%VID_EOI_Proc%@CR:C6A00370009 @%%@AE@%%@EH@%%@NL@%
  14198. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14199.  
  14200.  
  14201. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14202.  
  14203. The %@AB@%VID_EOI_Proc%@AE@% callback is normally used for devices that are partially
  14204. virtualized. For example, the Virtual Mouse Device (VMD) lets the MS-DOS
  14205. mouse driver handle all I/O with the mouse hardware. The VMD just reflects
  14206. the interrupt to the VM that owns the mouse. Since it doesn't service the
  14207. device during the %@AB@%VMD_Hw_Int%@AE@% procedure, it can't call %@AB@%VPICD_Phys_EOI%@AE@% at this
  14208. point (since it's not the end of the interrupt). Once a virtual machine has
  14209. serviced the interrupt, it will issue an EOI and, at this point, the VMD
  14210. calls %@AB@%VPICD_Clear_Int_Request%@AE@% followed by %@AB@%VPICD_Phys_EOI%@AE@%. The default
  14211. interrupt routines need the %@AB@%VID_EOI_Proc%@AE@% callback for the same reason ─ they
  14212. have to wait for the VM to service the interrupting device before they
  14213. physically signal an EOI to the IRQ.  %@NL@%
  14214.  
  14215.  
  14216. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14217.  
  14218. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  14219.  
  14220.  
  14221. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14222.  
  14223. None  %@NL@%
  14224.  
  14225. %@CR:C6A00370010 @%
  14226. %@2@%%@CR:C6A00370011 @%%@AB@%VID_Virt_Int_Proc%@AE@%%@EH@%%@NL@%
  14227. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14228.  
  14229.  
  14230. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14231.  
  14232. The %@AB@%VID_Virt_Int_Proc%@AE@% callback can be useful for implementing critical
  14233. sections around a simulated hardware interrupt. A VxD will request an
  14234. interrupt, and that interrupt may be simulated at a later point in time.
  14235. This callback is issued at the point when the interrupt is actually being
  14236. simulated into the virtual machine. This call is made after the "point of no
  14237. return" has been passed. Therefore, it is impossible for a virtual device to
  14238. stop the interrupt once this call has been issued. A VxD that uses this
  14239. callback will usually also use the %@AB@%VID_Virt_IRET_Proc%@AE@% callback to detect the
  14240. end of the simulated interrupt.  %@NL@%
  14241.  
  14242.  
  14243. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14244.  
  14245. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle  %@NL@%
  14246.  
  14247.  
  14248. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14249.  
  14250. None  %@NL@%
  14251.  
  14252.  
  14253. %@2@%%@CR:C6A00370012 @%%@AB@%VID_IRET_Proc%@CR:C6A00370013 @%%@AE@%%@EH@%%@NL@%
  14254. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14255.  
  14256.  
  14257. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14258.  
  14259. This callback is useful for devices that must simulate large numbers of
  14260. interrupts in a short period of time. For example, the Virtual COM Device
  14261. will simulate an interrupt, allow one character to be read from the COM
  14262. port, and wait for the virtual machine to IRET before putting more data into
  14263. the virtual COM receive buffer. This is because many programs would crash if
  14264. too many bytes of data were queued and shovelled into the virtual machine
  14265. too quickly. The crash would occur because the program's stack would
  14266. overflow. For example, assume that a terminal program has an interrupt
  14267. routine that looks like this:  %@NL@%
  14268.  
  14269. %@AS@%  push      ax               ; (Push AX, DX is the
  14270. %@AS@%       push      dx               ; minimum possible)
  14271. %@AS@%       (Read a byte from the COM port)
  14272. %@AS@%       mov       al, 20h          ; Non-Specific EOI
  14273. %@AS@%       out       20h, al          ; EOI the PIC
  14274. %@AS@%       sti                        ; Enable interrupts
  14275. %@AS@%       (Do other stuff)
  14276. %@AS@%       pop       dx
  14277. %@AS@%       pop       ax
  14278. %@AS@%       iret%@AE@%
  14279.  
  14280. This is a perfectly valid interrupt procedure and, in fact, it is very
  14281. common in actual terminal programs. Now consider what would happen if the
  14282. Virtual COM Device (VCD) had 500 bytes of data queued, and it did not use
  14283. the %@AB@%VID_IRET_Proc%@AE@% callback. When the VM reads a byte of data, VCD puts the
  14284. next byte of data into the receive buffer and request another interrupt.
  14285. When the terminal program executes the STI instruction, VPICD immediately
  14286. simulates another COM interrupt. This sequence of events is repeated 499
  14287. times, each time nesting an interrupt while in the terminal program's
  14288. interrupt routine. The problem is that the IRET frame on the stack requires
  14289. 6 bytes per interrupt, and the 2 pushed registers take up 4 more bytes for a
  14290. total of 10 bytes per interrupt. Since we would nest 500 interrupts, 5K
  14291. bytes of stack space would be required.  %@NL@%
  14292.  
  14293. Since this is obviously unacceptable, VCD waits for the terminal program to
  14294. IRET before simulating another interrupt. The Virtual Timer uses similar
  14295. logic to prevent shoving too many timer interrupts into a virtual machine.  %@NL@%
  14296.  
  14297.  
  14298. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14299.  
  14300. Interrupts Disabled %@AB@%EAX %@AE@%= IRQ handle %@AB@%EBX%@AE@% = Current VM handle If carry is set
  14301. then interrupt timed-out  %@NL@%
  14302.  
  14303.  
  14304. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14305.  
  14306. None  %@NL@%
  14307.  
  14308. %@CR:C6A00370014 @%
  14309. %@2@%%@CR:C6A00370015 @%%@AB@%VID_Mask_Change_Proc%@AE@%%@EH@%%@NL@%
  14310. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14311.  
  14312.  
  14313. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14314.  
  14315. The %@AB@%VID_Mask_Change_Proc%@AE@% is often used to detect contention for a device.
  14316. The default interrupt routines use this callback to detect conflicts with
  14317. nonglobal interrupts.  %@NL@%
  14318.  
  14319.  
  14320. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14321.  
  14322. Interrupts Disabled %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = Current VM handle %@AB@%ECX%@AE@% = 0 if VM
  14323. is unmasking IRQ,   0 if masking IRQ  %@NL@%
  14324.  
  14325.  
  14326. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14327.  
  14328. None  %@NL@%
  14329.  
  14330.  
  14331. %@2@%%@CR:C6A00370016 @%%@AB@%37.4  VPICD Services%@AE@%%@EH@%%@NL@%
  14332. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14333.  
  14334. This section presents descriptions of the VPICD services in alphabetical
  14335. order.  %@NL@%
  14336.  
  14337. %@CR:C6A00370017 @%
  14338. %@2@%%@CR:C6A00370018 @%%@AB@%VPICD_Call_When_Hw_Int%@AE@%%@EH@%%@NL@%
  14339. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14340.  
  14341.  
  14342. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14343.  
  14344. You must call this procedure with interrupts %@AI@%disabled%@AE@%. This service enables
  14345. other VxDs to be notified when every hardware interrupt occurs. It is
  14346. intended to be used by the Virtual DMA Device (VDMAD) to detect when a DMA
  14347. transfer is complete. However, any VxD can use this service. It should be
  14348. noted though, that since your callback will be called for every hardware
  14349. interrupt, it could have a major performance impact on systems with devices
  14350. that interrupt frequently. Therefore, you should avoid using this service.  %@NL@%
  14351.  
  14352. A callback installed by this service is responsible for chaining to the next
  14353. handler in the interrupt filter chain, and it must preserve the %@AB@%EBX%@AE@% register
  14354. for the next handler.  %@NL@%
  14355.  
  14356. %@AS@%  Sample_Hook_Init:
  14357. %@AS@%        pushfd
  14358. %@AS@%        cli
  14359. %@AS@%        mov     esi, OFFSET32 My_Int_Hook
  14360. %@AS@%        VxDcall VPICD_Call_When_Hw_Int
  14361. %@AS@%        popfd
  14362. %@AS@%        mov     [Next_Int_Hook_Addr], esi
  14363. %@AS@%        clc
  14364. %@AS@%        ret
  14365. %@AS@%  
  14366. %@AS@%      My_Int_Hook:
  14367. %@AS@%        push    ebx
  14368. %@AS@%        (Do something useful here)
  14369. %@AS@%        pop     ebx
  14370. %@AS@%        jmp     [Next_Int_Hook_Addr]%@AE@%
  14371.  
  14372.  
  14373. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14374.  
  14375. %@AB@%ESI%@AE@% -> Procedure to call  %@NL@%
  14376.  
  14377.  
  14378. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14379.  
  14380. %@AB@%ESI%@AE@% -> Procedure to chain to  %@NL@%
  14381.  
  14382.  
  14383. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14384.  
  14385. %@AB@%ESI%@AE@%, Flags  %@NL@%
  14386.  
  14387.  
  14388. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  14389.  
  14390. %@AB@%EBX%@AE@% = %@AB@%Cur_VM_Handle%@AE@%  %@NL@%
  14391.  
  14392. %@CR:C6A00370019 @%
  14393. %@2@%%@CR:C6A00370020 @%%@AB@%VPICD_Clear_Int_Request%@AE@%%@EH@%%@NL@%
  14394. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14395.  
  14396.  
  14397. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14398.  
  14399. This service resets an IRQ request that was previously set by a call to
  14400. %@AB@%VPICD_Set_Int_Request%@AE@%. If the IRQ is being shared with another device, then
  14401. this service may not reset the virtual request if another device has also
  14402. set the virtual IRQ. However, the request will be cleared when all devices
  14403. that have called %@AB@%Set_Int_Request%@AE@% call this service.  %@NL@%
  14404.  
  14405.  
  14406. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14407.  
  14408. %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14409.  
  14410.  
  14411. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14412.  
  14413. Virtual IRQ request is cleared  %@NL@%
  14414.  
  14415.  
  14416. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14417.  
  14418. Flags  %@NL@%
  14419.  
  14420. %@CR:C6A00370021 @%
  14421. %@2@%%@CR:C6A00370022 @%%@AB@%VPICD_Convert_Handle_To_IRQ%@AE@%%@EH@%%@NL@%
  14422. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14423.  
  14424.  
  14425. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14426.  
  14427. This service returns the number of the IRQ for the IRQ handle in %@AB@%EAX%@AE@%.  %@NL@%
  14428.  
  14429.  
  14430. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14431.  
  14432. %@AB@%EAX%@AE@% = IRQ Handle  %@NL@%
  14433.  
  14434.  
  14435. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14436.  
  14437. %@AB@%ESI%@AE@% = IRQ Number  %@NL@%
  14438.  
  14439.  
  14440. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14441.  
  14442. %@AB@%ESI%@AE@%, Flags  %@NL@%
  14443.  
  14444. %@CR:C6A00370023 @%
  14445. %@2@%%@CR:C6A00370024 @%%@AB@%VPICD_Convert_Int_To_IRQ%@AE@%%@EH@%%@NL@%
  14446. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14447.  
  14448.  
  14449. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14450.  
  14451. This service takes an interrupt vector number and returns the number of the
  14452. IRQ that is mapped to that interrupt. For example, INT 8 will typically be
  14453. converted to IRQ 0. However, VMs are allowed to remap the virtual PIC to any
  14454. interrupt vector they wish. Therefore, devices should never make assumptions
  14455. about to which interrupt vector a particular IRQ is mapped.  %@NL@%
  14456.  
  14457.  
  14458. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14459.  
  14460. %@AB@%EAX%@AE@% = Interrupt vector number  %@NL@%
  14461.  
  14462.  
  14463. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14464.  
  14465. If carry is clear then  EAX = IRQ number else  Interrupt vector not mapped
  14466. to any IRQ  %@NL@%
  14467.  
  14468.  
  14469. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14470.  
  14471. None  %@NL@%
  14472.  
  14473. %@CR:C6A00370025 @%
  14474. %@2@%%@CR:C6A00370026 @%%@AB@%VPICD_Convert_IRQ_To_Int%@AE@%%@EH@%%@NL@%
  14475. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14476.  
  14477.  
  14478. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14479.  
  14480. This service accepts an IRQ number and returns an interrupt vector number
  14481. for a specified VM. For example, typically IRQ 0 will be converted to INT 8
  14482. on an IBM PC. However, VMs are allowed to remap the virtual PIC to any
  14483. interrupt vector they wish. Therefore, devices should never make assumptions
  14484. about to which interrupt vector a particular IRQ is mapped.  %@NL@%
  14485.  
  14486.  
  14487. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14488.  
  14489. %@AB@%EAX%@AE@% = IRQ number ─ NOT HANDLE! %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14490.  
  14491.  
  14492. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14493.  
  14494. %@AB@%EAX%@AE@% = Interrupt vector  %@NL@%
  14495.  
  14496.  
  14497. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14498.  
  14499. %@AB@%EAX%@AE@%, Flags  %@NL@%
  14500.  
  14501. %@CR:C6A00370027 @%
  14502. %@2@%%@CR:C6A00370028 @%%@AB@%VPICD_Get_Complete_Status%@AE@%%@EH@%%@NL@%
  14503. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14504.  
  14505. Refer to %@AB@%VPICD_Get_Status%@AE@% for description.  %@NL@%
  14506.  
  14507. %@CR:C6A00370029 @%
  14508. %@2@%%@CR:C6A00370030 @%%@AB@%VPICD_Get_IRQ_Complete_Status%@AE@%%@EH@%%@NL@%
  14509. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14510.  
  14511.  
  14512. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14513.  
  14514. This service is similar to %@AB@%VPICD_Get_Complete_Status%@AE@% except that it takes an
  14515. IRQ number as a parameter instead of an IRQ handle. This is useful for
  14516. devices to inspect an IRQ before attempting to virtualize it or for
  14517. inspecting the state of another device's interrupt. Also, since it indicates
  14518. whether or not an IRQ has been virtualized already, it can be used by
  14519. devices to prevent conflicts when more than one device may want to use an
  14520. IRQ.  %@NL@%
  14521.  
  14522.  
  14523. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14524.  
  14525. %@AB@%EAX%@AE@% = IRQ number  %@NL@%
  14526.  
  14527.  
  14528. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14529.  
  14530. %@AB@%ECX%@AE@% = Status as described for %@AB@%VPICD_Get_Complete_Status%@AE@%  %@NL@%
  14531.  
  14532. %@AS@%  If the carry flag is set then
  14533. %@AS@%      The IRQ has been virtualized 
  14534. %@AS@%  else
  14535. %@AS@%      The IRQ has not been virtualized%@AE@%
  14536.  
  14537.  
  14538. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14539.  
  14540. %@AB@%ECX%@AE@%, Flags  %@NL@%
  14541.  
  14542. %@CR:C6A00370031 @%
  14543. %@2@%%@CR:C6A00370032 @%%@AB@%VPICD_Get_Status%@AE@%%@EH@%%@NL@%
  14544. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14545.  
  14546.  
  14547. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14548.  
  14549. These services return the status of a virtual IRQ for a specified VM. The
  14550. status returned in %@AB@%ECX%@AE@% is defined by equates in the VPICD.INC file.
  14551. %@AB@%VPICD_Get_Status%@AE@% will only return the Virtual %@AB@%In_Service%@AE@% and %@AB@%IRET_Pending%@AE@%
  14552. status bits. %@AB@%VPICD_Get_Complete_Status%@AE@% will return with all status bits
  14553. defined. The shorter version is supplied because it is much faster, and the
  14554. status returned contains the most commonly used information.  %@NL@%
  14555.  
  14556.  
  14557. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14558.  
  14559. %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14560.  
  14561.  
  14562. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14563.  
  14564. %@AB@%ECX%@AE@% = Status flags (see equates VPICD.INI)  %@NL@%
  14565.  
  14566. %@TH:  10   518 02 16 60 @%Bit             Description%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%0 = 1           A Virtual IRET is pending1 = 1           The IRQ is virtually in service2 = 1           The IRQ is physically masked3 = 1           The IRQ is physically in service4 = 1           VM has masked the IRQ5 = 1           The Virtual IRQ is set (by any VxD)6 = 1           The physical IRQ is set7 = 1           Tha calling VxD's Virtual IRQ is set%@TE:  10   518 02 16 60 @%
  14567.  
  14568.  
  14569. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14570.  
  14571. %@AB@%ECX%@AE@%, Flags  %@NL@%
  14572.  
  14573. %@CR:C6A00370033 @%
  14574. %@2@%%@CR:C6A00370034 @%%@AB@%VPICD_Get_Version%@AE@%%@EH@%%@NL@%
  14575. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14576.  
  14577.  
  14578. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14579.  
  14580. This service returns the VPICD major and minor version numbers.  %@NL@%
  14581.  
  14582.  
  14583. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14584.  
  14585. None  %@NL@%
  14586.  
  14587.  
  14588. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14589.  
  14590. %@AB@%AH%@AE@% = Major version %@AB@%AL%@AE@% = Minor version %@AB@%EBX%@AE@% = Flags  Bit 0 = 1 - Master/Slave
  14591. PC/AT type configuration  0 - PC/XT type single PIC configuration  Other
  14592. bits reserved for future versions. %@AB@%ECX%@AE@% = Maximum IRQ supported (07H or 0FH)
  14593. Carry flag clear  %@NL@%
  14594.  
  14595.  
  14596. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14597.  
  14598. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, Flags  %@NL@%
  14599.  
  14600. %@CR:C6A00370035 @%
  14601. %@2@%%@CR:C6A00370036 @%%@AB@%VPICD_Phys_EOI%@AE@%%@EH@%%@NL@%
  14602. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14603.  
  14604.  
  14605. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14606.  
  14607. Calling this procedure will end a physical interrupt and will allow further
  14608. hardware interrupts from the specified IRQ. Notice that an interrupt that is
  14609. physically in service will %@AI@%not%@AE@% suppress interrupts to "lower priority" IRQs,
  14610. since VPICD does not prioritize hardware interrupts. Therefore, it is
  14611. acceptable for an interrupt to be physically in service for an arbitrary
  14612. length of time.  %@NL@%
  14613.  
  14614.  
  14615. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14616.  
  14617. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14618.  
  14619.  
  14620. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14621.  
  14622. None  %@NL@%
  14623.  
  14624.  
  14625. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14626.  
  14627. Flags  %@NL@%
  14628.  
  14629. %@CR:C6A00370037 @%
  14630. %@2@%%@CR:C6A00370038 @%%@AB@%VPICD_Physically_Mask%@AE@%%@EH@%%@NL@%
  14631. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14632.  
  14633.  
  14634. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14635.  
  14636. This service will mask the specified IRQ on the hardware PIC. This will
  14637. suppress all hardware interrupts on the IRQ until %@AB@%VPICD_Physically_Unmask%@AE@% or
  14638. %@AB@%VPICD_Set_Auto_Masking%@AE@% is called.  %@NL@%
  14639.  
  14640.  
  14641. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14642.  
  14643. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14644.  
  14645.  
  14646. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14647.  
  14648. IRQ is masked  %@NL@%
  14649.  
  14650.  
  14651. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14652.  
  14653. Flags  %@NL@%
  14654.  
  14655. %@CR:C6A00370039 @%
  14656. %@2@%%@CR:C6A00370040 @%%@AB@%VPICD_Physically_Unmask%@AE@%%@EH@%%@NL@%
  14657. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14658.  
  14659.  
  14660. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14661.  
  14662. This service will unmask the specified IRQ on the hardware PIC regardless of
  14663. the mask state of virtual machines. This means that even if every VM has
  14664. masked the virtual IRQ, the physical IRQ will remain unmasked.  %@NL@%
  14665.  
  14666.  
  14667. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14668.  
  14669. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14670.  
  14671.  
  14672. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14673.  
  14674. IRQ is masked  %@NL@%
  14675.  
  14676.  
  14677. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14678.  
  14679. Flags  %@NL@%
  14680.  
  14681. %@CR:C6A00370041 @%
  14682. %@2@%%@CR:C6A00370042 @%%@AB@%VPICD_Set_Auto_Masking%@AE@%%@EH@%%@NL@%
  14683. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14684.  
  14685.  
  14686. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14687.  
  14688. Automatic masking is the default state for every IRQ. It can be overridden
  14689. by %@AB@%VPICD_Physically_Mask/Unmask%@AE@%. When automatic masking is used, the state
  14690. of the physical mask is determined by the state of every virtual machine's
  14691. virtual mask. If at least one VM has the IRQ unmasked, then the physical IRQ
  14692. will remain unmasked. Otherwise, the IRQ will be masked on the hardware PIC.
  14693. %@NL@%
  14694.  
  14695.  
  14696. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14697.  
  14698. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14699.  
  14700.  
  14701. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14702.  
  14703. IRQ will be physically unmasked if at least one VM has unmasked the IRQ.  %@NL@%
  14704.  
  14705.  
  14706. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14707.  
  14708. Flags  %@NL@%
  14709.  
  14710. %@CR:C6A00370043 @%
  14711. %@2@%%@CR:C6A00370044 @%%@AB@%VPICD_Set_Int_Request%@AE@%%@EH@%%@NL@%
  14712. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14713.  
  14714.  
  14715. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14716.  
  14717. This service sets the virtual interrupt request for the specified IRQ and
  14718. VM. It may cause an interrupt to be simulated immediately. However, in many
  14719. cases, the interrupt will %@AI@%not%@AE@% be simulated until a later point in time. The
  14720. interrupt will not be simulated immediately if:  %@NL@%
  14721.  
  14722.  
  14723.   ■   The virtual machine has interrupts disabled. %@NL@%
  14724.  
  14725.   ■   The virtual machine has masked the IRQ. %@NL@%
  14726.  
  14727.   ■   A higher priority virtual IRQ is in service. %@NL@%
  14728.  
  14729.   ■   It is not possible to run the specified VM (it is suspended, etc). %@NL@%
  14730.  
  14731.   ■   There are other reasons the interrupt may be postponed.%@NL@%
  14732.  
  14733.  
  14734. However, since the interrupt may be simulated immediately, virtual devices
  14735. that have a virtual interrupt handler must be able to handle the case when
  14736. their virtual interrupt procedure is called before this service returns.  %@NL@%
  14737.  
  14738. Setting an interrupt request is not a guarantee that the interrupt will ever
  14739. be simulated. For example, if the VM has masked the interrupt and never
  14740. unmasks it, the interrupt will never be simulated. Also, a call to
  14741. %@AB@%VPICD_Clear_Int_Request%@AE@% that is made before the virtual interrupt is
  14742. simulated will prevent the interrupt simulation.  %@NL@%
  14743.  
  14744. It is important to keep in mind that VPICD simulates a level triggered PIC.
  14745. This means that once a virtual EOI occurs, another interrupt will be
  14746. simulated immediately unless the virtual interrupt request is cleared.  %@NL@%
  14747.  
  14748.  
  14749. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14750.  
  14751. %@AB@%EAX%@AE@% = IRQ handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  14752.  
  14753.  
  14754. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14755.  
  14756. Virtual IRQ request is set  %@NL@%
  14757.  
  14758.  
  14759. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14760.  
  14761. Flags  %@NL@%
  14762.  
  14763. %@CR:C6A00370045 @%
  14764. %@2@%%@CR:C6A00370046 @%%@AB@%VPICD_Test_Phys_Request%@AE@%%@EH@%%@NL@%
  14765. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14766.  
  14767.  
  14768. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14769.  
  14770. This service will return with Carry set if the physical (hardware PIC)
  14771. interrupt request is set for the specified IRQ.  %@NL@%
  14772.  
  14773.  
  14774. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14775.  
  14776. %@AB@%EAX%@AE@% = IRQ handle  %@NL@%
  14777.  
  14778.  
  14779. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14780.  
  14781. Carry flag = Physical Interrupt Request state  %@NL@%
  14782.  
  14783.  
  14784. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14785.  
  14786. Flags  %@NL@%
  14787.  
  14788. %@CR:C6A00370047 @%
  14789. %@2@%%@CR:C6A00370048 @%%@AB@%VPICD_Virtualize_IRQ%@AE@%%@EH@%%@NL@%
  14790. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14791.  
  14792.  
  14793. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14794.  
  14795. This is not an async service; it cannot be called during an interrupt. This
  14796. service is used to gain access to a specified virtual interrupt request. The
  14797. caller passes this procedure a pointer to the IRQ descriptor (the structure
  14798. declared in VPICD.INC) which specifies:  %@NL@%
  14799.  
  14800.  
  14801.   ■   IRQ number (required)%@NL@%
  14802.  
  14803.   ■   Options%@NL@%
  14804.  
  14805.   ■   Hardware interrupt handler (required)%@NL@%
  14806.  
  14807.   ■   Virtual interrupt handler%@NL@%
  14808.  
  14809.   ■   Virtual EOI handler%@NL@%
  14810.  
  14811.   ■   Virtual mask change handler%@NL@%
  14812.  
  14813.   ■   Virtual IRET handler%@NL@%
  14814.  
  14815.   ■   Virtual IRET time-out (0 for no time-out)%@NL@%
  14816.  
  14817.  
  14818. For more information on the various options and parameters to this service
  14819. see Section 37.3 "Virtualizing an IRQ," earlier in this chapter. When this
  14820. service returns, if Carry is set, then the IRQ cannot be virtualized.
  14821. Otherwise, %@AB@%EAX%@AE@% contains an IRQ handle. This handle is used for all
  14822. subsequent communication with VPICD.  %@NL@%
  14823.  
  14824. If every device that virtualizes the IRQ has the %@AB@%Can_Share%@AE@% option set then
  14825. the IRQ can be shared by up to 32 devices.  %@NL@%
  14826.  
  14827.  
  14828. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14829.  
  14830. %@AB@%EDI%@AE@% -> %@AB@%VPICD_IRQ_Descriptor%@AE@%  %@NL@%
  14831.  
  14832.  
  14833. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14834.  
  14835. If carry clear then  EAX = IRQ Handle else  Error ─ Handle already allocated
  14836. or invalid IRQ #  %@NL@%
  14837.  
  14838.  
  14839. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14840.  
  14841. %@AB@%EAX%@AE@% , Flags  %@NL@%
  14842.  
  14843.  
  14844.  
  14845.  
  14846.  
  14847.  
  14848. %@CR:C6A00380001 @%%@1@%%@AB@%Chapter 38  Virtual Sound Device (VSD) Services%@AE@%%@EH@%%@NL@%
  14849. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14850.  
  14851. These two services enable VxDs to generate a warning beep or return the VSD
  14852. version number:%@CR:C6A00380002 @%%@NL@%
  14853.  
  14854.  
  14855.   ■   %@AB@%VSD_Bell%@AE@%%@NL@%
  14856.  
  14857.   ■   %@AB@%VSD_Get_Version%@AE@%%@NL@%
  14858.  
  14859.  
  14860. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  14861. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  14862.  
  14863.  
  14864. %@2@%%@CR:C6A00380003 @%%@AB@%VSD_Bell%@CR:C6A00380004 @%%@AE@%%@EH@%%@NL@%
  14865. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14866.  
  14867.  
  14868. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14869.  
  14870. This service is provided so that devices can generate a warning beep. This
  14871. is normally used when the user presses an invalid key or when an error
  14872. occurs. Notice that this service will produce a 1/2-second tone, but it will
  14873. then return immediately (it does not busy wait).  %@NL@%
  14874.  
  14875.  
  14876. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14877.  
  14878. None  %@NL@%
  14879.  
  14880.  
  14881. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14882.  
  14883. None  %@NL@%
  14884.  
  14885.  
  14886. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14887.  
  14888. Flags  %@NL@%
  14889.  
  14890. %@CR:C6A00380005 @%
  14891. %@2@%%@CR:C6A00380006 @%%@AB@%VSD_Get_Version%@AE@%%@EH@%%@NL@%
  14892. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14893.  
  14894.  
  14895. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14896.  
  14897. This service returns the version number of the Virtual Sound Device.  %@NL@%
  14898.  
  14899.  
  14900. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14901.  
  14902. None  %@NL@%
  14903.  
  14904.  
  14905. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14906.  
  14907. AH = Major version number AL = Minor version number Carry flag clear  %@NL@%
  14908.  
  14909.  
  14910. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14911.  
  14912. %@AB@%EAX%@AE@%, Flags  %@NL@%
  14913.  
  14914.  
  14915.  
  14916.  
  14917.  
  14918.  
  14919. %@CR:C6A00390001 @%%@1@%%@AB@%Chapter 39  Virtual Timer Device (VTD) Services%@AE@%%@EH@%%@NL@%
  14920. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14921.  
  14922. This chapter presents descriptions of the following VTD services:%@CR:C6A00390002 @%%@NL@%
  14923.  
  14924.  
  14925.   ■   %@AB@%VTD_Begin_Min_Int_Period%@AE@%%@NL@%
  14926.  
  14927.   ■   %@AB@%VTD_Disable_Trapping%@AE@%%@NL@%
  14928.  
  14929.   ■   %@AB@%VTD_Enable_Trapping%@AE@%%@NL@%
  14930.  
  14931.   ■   %@AB@%VTD_End_Min_Int_Period%@AE@%%@NL@%
  14932.  
  14933.   ■   %@AB@%VTD_Get_Interrupt_Rate%@AE@%%@NL@%
  14934.  
  14935.   ■   %@AB@%VTD_Get_Version%@AE@%%@NL@%
  14936.  
  14937.   ■   %@AB@%VTD_Update_System_Clock%@AE@%%@NL@%
  14938.  
  14939.  
  14940. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  14941. "Virtual Device Programming Topics," for general environment discussions.  %@NL@%
  14942.  
  14943. %@CR:C6A00390003 @%
  14944. %@2@%%@CR:C6A00390004 @%%@AB@%VTD_Begin_Min_Int_Period%@AE@%%@EH@%%@NL@%
  14945. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14946.  
  14947.  
  14948. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14949.  
  14950. This service is used by VxDs to ensure a minimum accuracy for system timing.
  14951. When this service is called, if the interrupt period specified is lower than
  14952. the current timer interrupt period, the interrupt period will be set to the
  14953. new frequency.  %@NL@%
  14954.  
  14955. Until a matching %@AB@%VTD_End_Min_Int_Period%@AE@% call is made, the timer interrupt
  14956. period is guaranteed never to be slower than the value specified.  %@NL@%
  14957.  
  14958. A VxD should call this service only once before calling
  14959. %@AB@%VTD_End_Min_Int_Period%@AE@%.  %@NL@%
  14960.  
  14961. Typically the %@AB@%Begin/End_Min_Int_Period%@AE@% services are used by devices such as
  14962. execution profilers that need extremely accurate timing. VMM system time-out
  14963. services rely on the VTD to keep time. Therefore, more frequent timer
  14964. interrupts will allow the time out services to be more accurate.  %@NL@%
  14965.  
  14966. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14967. %@AU@%WARNING%@AE@%
  14968.  
  14969. Fast timer interrupt periods can be very, very expensive in terms of total
  14970. system performance. For example, on some machines a timer interrupt of 1
  14971. millisecond will degrade total machine throughput by 10 percent and disk I/O
  14972. by up to 50 percent.
  14973. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14974.  
  14975.  
  14976. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  14977.  
  14978. %@AB@%EAX %@AE@%= Desired interrupt period  %@NL@%
  14979.  
  14980.  
  14981. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  14982.  
  14983. If carry clear then  Interrupt period set else  Specified interrupt period
  14984. is not valid  %@NL@%
  14985.  
  14986.  
  14987. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  14988.  
  14989. Flags  %@NL@%
  14990.  
  14991. %@CR:C6A00390005 @%
  14992. %@2@%%@CR:C6A00390006 @%%@AB@%VTD_Disable_Trapping%@AE@%%@EH@%%@NL@%
  14993. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14994.  
  14995.  
  14996. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  14997.  
  14998. This service will force VTD to stop I/O trapping on the timer ports for a
  14999. specified virtual machine. %@AB@%VTD_Enable_Trapping%@AE@% must be called once for every
  15000. call made to this service. By default, timer port trapping is enabled when a
  15001. VM is created.  %@NL@%
  15002.  
  15003. It is sometimes necessary to disable temporarily I/O trapping for virtual
  15004. machine code that reads the timer in extremely tight timing loops. A good
  15005. example is the hard disk BIOS code that reads the ports hundreds of times
  15006. per disk transfer. The overhead for servicing the I/O traps would cause disk
  15007. performance to slow to a crawl.  %@NL@%
  15008.  
  15009. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15010. %@AU@%WARNING%@AE@%
  15011.  
  15012. This service must be used very carefully. If a VM reprograms the timer while
  15013. port trapping is disabled, system timing will behave randomly. Only
  15014. "trusted" code should be executed when timer port trapping is disabled.
  15015. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15016.  
  15017. If this service is called N times, then %@AB@%VTD_Enable_Trapping%@AE@% must also be
  15018. called N times before trapping is reenabled. This allows nested calls to
  15019. this service by more than one VxD.  %@NL@%
  15020.  
  15021.  
  15022. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15023.  
  15024. %@AB@%EBX %@AE@%= VM handle  %@NL@%
  15025.  
  15026.  
  15027. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15028.  
  15029. None  %@NL@%
  15030.  
  15031.  
  15032. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15033.  
  15034. Flags  %@NL@%
  15035.  
  15036. %@CR:C6A00390007 @%
  15037. %@2@%%@CR:C6A00390008 @%%@AB@%VTD_Enable_Trapping%@AE@%%@EH@%%@NL@%
  15038. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15039.  
  15040.  
  15041. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15042.  
  15043. This service must be called to re-enable timer I/O port trapping after
  15044. calling %@AB@%VTD_Disable_Trapping%@AE@%. Notice that this call must be made once for
  15045. every call to %@AB@%VTD_Disable_Trapping%@AE@%. Only when every disable call has been
  15046. matched by a call to this service will port trapping be reenabled.  %@NL@%
  15047.  
  15048.  
  15049. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15050.  
  15051. %@AB@%EBX%@AE@% = VM handle  %@NL@%
  15052.  
  15053.  
  15054. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15055.  
  15056. None  %@NL@%
  15057.  
  15058.  
  15059. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15060.  
  15061. Flags  %@NL@%
  15062.  
  15063. %@CR:C6A00390009 @%
  15064. %@2@%%@CR:C6A00390010 @%%@AB@%VTD_End_Min_Int_Period%@AE@%%@EH@%%@NL@%
  15065. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15066.  
  15067.  
  15068. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15069.  
  15070. This service allows a device to "unrequest" a timer interrupt period that it
  15071. set earlier through the %@AB@%VTD_Begin_Min_Int_Period%@AE@% service. See the
  15072. documentation for %@AB@%VTD_Begin_Min_Int_Period%@AE@% earlier in this chapter for more
  15073. information on the proper use of this service.  %@NL@%
  15074.  
  15075.  
  15076. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15077.  
  15078. %@AB@%EAX%@AE@% = Value passed earlier to %@AB@%Begin_Begin_Min_Int_Period%@AE@%  %@NL@%
  15079.  
  15080.  
  15081. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15082.  
  15083. %@AS@%  If carry clear then
  15084. %@AS@%      Interrupt period request removed successfully
  15085. %@AS@%  else 
  15086. %@AS@%      Specified interrupt period is not valid%@AE@%
  15087.  
  15088.  
  15089. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15090.  
  15091. Flags  %@NL@%
  15092.  
  15093. %@CR:C6A00390011 @%
  15094. %@2@%%@CR:C6A00390012 @%%@AB@%VTD_Get_Interrupt_Period%@AE@%%@EH@%%@NL@%
  15095. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15096.  
  15097.  
  15098. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15099.  
  15100. This service returns the current timer interrupt period.  %@NL@%
  15101.  
  15102.  
  15103. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15104.  
  15105. None  %@NL@%
  15106.  
  15107.  
  15108. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15109.  
  15110. %@AB@%EAX %@AE@%= Length of time between ticks in milliseconds  %@NL@%
  15111.  
  15112.  
  15113. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15114.  
  15115. Flags  %@NL@%
  15116.  
  15117. %@CR:C6A00390013 @%
  15118. %@2@%%@CR:C6A00390014 @%%@AB@%VTD_Get_Version%@AE@%%@EH@%%@NL@%
  15119. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15120.  
  15121.  
  15122. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15123.  
  15124. This service returns the version number and the range of interrupt periods
  15125. allowable by this device.  %@NL@%
  15126.  
  15127.  
  15128. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15129.  
  15130. None  %@NL@%
  15131.  
  15132.  
  15133. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15134.  
  15135. %@AB@%EAX%@AE@% = Version number (AH = Major, AL = Minor) %@AB@%EBX%@AE@% = Fastest possible
  15136. interrupt period in milliseconds %@AB@%ECX%@AE@% = Slowest possible interrupt period in
  15137. milliseconds Carry flag clear  %@NL@%
  15138.  
  15139.  
  15140. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15141.  
  15142. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, Flags  %@NL@%
  15143.  
  15144. %@CR:C6A00390015 @%
  15145. %@2@%%@CR:C6A00390016 @%%@AB@%VTD_Update_System_Clock%@AE@%%@EH@%%@NL@%
  15146. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15147.  
  15148.  
  15149. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15150.  
  15151. This service should %@AI@%only%@AE@% be called by the VMM. Devices should call the
  15152. %@AB@%Get_System_Time%@AE@% VMM service. The VMM will then call this service to update
  15153. the system clock.  %@NL@%
  15154.  
  15155.  
  15156. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15157.  
  15158. None  %@NL@%
  15159.  
  15160.  
  15161. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15162.  
  15163. None  %@NL@%
  15164.  
  15165.  
  15166. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15167.  
  15168. Flags  %@NL@%
  15169.  
  15170.  
  15171.  
  15172.  
  15173.  
  15174.  
  15175. %@CR:C6A00400001 @%%@1@%%@AB@%Chapter 40  V86 Mode Memory Manager Device Services%@AE@%%@EH@%%@NL@%
  15176. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15177.  
  15178. The V86MMGR is responsible for managing memory in the Virtual 8086 portion
  15179. of each VM. It supports EMS and XMS, is responsible for allocating the base
  15180. memory for VMs when they are created, and translates APIs from
  15181. protected-mode applications into V86 calls for other VxDs.%@CR:C6A00400002 @%%@NL@%
  15182.  
  15183. See Chapter 16, "Overview of Windows in 386 Enhanced Mode," and Chapter 17,
  15184. "Virtual Device Programming Topics," for general environment discussions.
  15185. Other chapters that discuss memory management are Chapter 19, "Memory
  15186. Management Services," and Chapter 6, "Network Support," in the %@AI@%Microsoft
  15187. %@AI@%Windows Device Driver Adaptation Guide%@AE@%. Memory management is also discussed
  15188. in the %@AI@%Microsoft Windows Software Development Kit, Programming Tools%@AE@%.  %@NL@%
  15189.  
  15190. The V86MMGR services are presented as follows:  %@NL@%
  15191.  
  15192.  
  15193.   ■   Initialization Services%@NL@%
  15194.  
  15195. %@STUB@%      %@AB@%V886MMGR_Get_Version%@AE@%%@NL@%
  15196.  
  15197. %@STUB@%      %@AB@%V86MMGR_Allocate_V86_Pages%@AE@%%@NL@%
  15198.  
  15199. %@STUB@%      %@AB@%V86MMGR_Set_EMS_XMS_Limits%@AE@%%@NL@%
  15200.  
  15201. %@STUB@%      %@AB@%V86MMGR_Get_EMS_XMS_Limits%@AE@%%@NL@%
  15202.  
  15203.   ■   API Translation and Mapping Services%@NL@%
  15204.  
  15205. %@STUB@%      %@AB@%V886MMGR_Set_Mapping_Info%@AE@%%@NL@%
  15206.  
  15207. %@STUB@%      %@AB@%V86MMGR_Xlat_API%@AE@%%@NL@%
  15208.  
  15209. %@STUB@%      %@AB@%V86MMGR_Load_Client_Ptr%@AE@%%@NL@%
  15210.  
  15211. %@STUB@%      %@AB@%V86MMGR_Allocate_Buffer%@AE@%%@NL@%
  15212.  
  15213. %@STUB@%      %@AB@%V886MMGR_Free_Buffer%@AE@%%@NL@%
  15214.  
  15215. %@STUB@%      %@AB@%V86MMGR_Get_Xlat_Buff_State%@AE@%%@NL@%
  15216.  
  15217. %@STUB@%      %@AB@%V86MMGR_Set_Xlat_Buff_State%@AE@%%@NL@%
  15218.  
  15219. %@STUB@%      %@AB@%V86MMGR_Get_VM_Flat_Sel%@AE@%%@NL@%
  15220.  
  15221. %@STUB@%      %@AB@%V86MMGR_Get_Mapping_Info%@AE@%%@NL@%
  15222.  
  15223. %@STUB@%      %@AB@%V86MMGR_Map_Pages%@AE@%%@NL@%
  15224.  
  15225. %@STUB@%      %@AB@%V86MMGR_Free_Page_Map_Region%@AE@%%@NL@%
  15226.  
  15227.  
  15228.  
  15229. %@2@%%@CR:C6A00400003 @%%@AB@%40.1  Initialization Services%@AE@%%@EH@%%@NL@%
  15230.  
  15231. These services are used when a VM is created except for the
  15232. %@AB@%V86MMGR_Get_Version%@AE@%, which may be used anytime.%@CR:C6A00400004 @%%@NL@%
  15233.  
  15234. %@CR:C6A00400005 @%
  15235. %@2@%%@CR:C6A00400006 @%%@AB@%V86MMGR_Get_Version%@AE@%%@EH@%%@NL@%
  15236. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15237.  
  15238.  
  15239. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15240.  
  15241. Returns the version of the V86MMGR VxD.  %@NL@%
  15242.  
  15243.  
  15244. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15245.  
  15246. None  %@NL@%
  15247.  
  15248.  
  15249. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15250.  
  15251. %@AB@%AH %@AE@%= Major version number %@AB@%AL%@AE@% = Minor version number Carry flag clear  %@NL@%
  15252.  
  15253.  
  15254. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15255.  
  15256. %@AB@%EAX%@AE@%, Flags  %@NL@%
  15257.  
  15258. %@CR:C6A00400007 @%
  15259. %@2@%%@CR:C6A00400008 @%%@AB@%V86MMGR_Allocate_V86_Pages%@AE@%%@EH@%%@NL@%
  15260. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15261.  
  15262.  
  15263. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15264.  
  15265. This service is used by the SHELL VxD to set up the initial base memory of a
  15266. VM when it is created. It allocates the memory, maps it into the virtual
  15267. machine, and does a local %@AB@%Assign_Device_V86_Pages%@AE@% for the region allocated.
  15268. %@NL@%
  15269.  
  15270.  
  15271. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15272.  
  15273. %@AB@%EBX%@AE@% = VM handle %@AB@%ESI%@AE@% = Desired size of VM address space in K bytes %@AB@%EDI %@AE@% =
  15274. Minimum size of VM address space in K bytes %@AB@%ECX%@AE@% = Flags, see bit definitions
  15275. in V86MMGR.INC  %@NL@%
  15276.  
  15277. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15278. NOTE
  15279.  
  15280. %@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
  15281. %@AI@%space.%@AE@%%@AE@%
  15282. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15283.  
  15284.  
  15285. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15286.  
  15287. If carry set then    ERROR: Could not allocate memory else    Memory
  15288. allocated and mapped into VM %@AB@%EAX%@AE@% = ACTUAL number of pages allocated and
  15289. mapped (size of VM). Notice that this size %@AI@%does not%@AE@% include the space from
  15290. 0-%@AB@%First_VM_Page%@AE@%  %@NL@%
  15291.  
  15292.  
  15293. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15294.  
  15295. %@AB@%EAX%@AE@%,Flags  %@NL@%
  15296.  
  15297. %@CR:C6A00400009 @%
  15298. %@2@%%@CR:C6A00400010 @%%@AB@%V86MMGR_Set_EMS_XMS_Limits%@AE@%%@EH@%%@NL@%
  15299. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15300.  
  15301.  
  15302. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15303.  
  15304. This service is used by the SHELL VxD to set the EMS and XMS limit
  15305. parameters for a VM.  %@NL@%
  15306.  
  15307.  
  15308. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15309.  
  15310. %@AB@%EBX%@AE@% = VM handle to set limits of %@AB@% EAX%@AE@% = Min EMS kilobytes %@AB@% EDX%@AE@% = Max EMS
  15311. kilobytes %@AB@% ESI%@AE@% = Min XMS kilobytes %@AB@% EDI %@AE@% = Max XMS kilobytes %@AB@% ECX%@AE@% = Flag
  15312. bits, see V86MMGR.INC  %@NL@%
  15313.  
  15314.  
  15315. %@3@%%@AB@%Notes%@AE@%%@EH@%%@NL@%
  15316.  
  15317. To disable access to XMS or EMS memory, set Max = Min = 0 To set only %@AI@%one%@AE@% of
  15318. the two limits, set the OTHER Max = Min = -1 The XMS Limit %@AI@%does not%@AE@% include
  15319. the HMA.  %@NL@%
  15320.  
  15321.  
  15322. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15323.  
  15324. If carry set then could not set limits    Insufficient memory for Min
  15325. allocation request    note that some of the limits may have been set. To
  15326. Find    out what happened, use %@AB@%V86MMGR_Get_EMS_XMS_Limits%@AE@% else limits set  %@NL@%
  15327.  
  15328.  
  15329. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15330.  
  15331. Flags  %@NL@%
  15332.  
  15333. %@CR:C6A00400011 @%
  15334. %@2@%%@CR:C6A00400012 @%%@AB@%V86MMGR_Get_EMS_XMS_Limits%@AE@%%@EH@%%@NL@%
  15335. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15336.  
  15337.  
  15338. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15339.  
  15340. This service is used by the SHELL VxD to get the EMS and XMS limit
  15341. parameters for a VM.  %@NL@%
  15342.  
  15343.  
  15344. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15345.  
  15346. %@AB@%EBX%@AE@% = VM handle to get limits of  %@NL@%
  15347.  
  15348.  
  15349. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15350.  
  15351. %@AB@%EAX%@AE@% = Min EMS kilobytes (always a multiple of 4) %@AB@%EDX%@AE@% = Max EMS kilobytes
  15352. (always a multiple of 4) %@AB@%ESI%@AE@% = Min XMS kilobytes (always a multiple of 4)
  15353. %@AB@%EDI%@AE@% = Max XMS kilobytes (always a multiple of 4) %@AB@%ECX%@AE@% = 0 if access to the
  15354. HMA is disabled %@AB@%ECX%@AE@% = 1 if access to the HMA is enabled  %@NL@%
  15355.  
  15356.  
  15357. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15358.  
  15359. %@AB@%EAX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, Flags  %@NL@%
  15360.  
  15361.  
  15362. %@2@%%@CR:C6A00400013 @%%@AB@%40.2  API Translation and Mapping%@AE@%%@EH@%%@NL@%
  15363. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15364.  
  15365. One of the major roles of the V86MMGR is to provide a mechanism for other
  15366. VxDs to translate API calls made from application software running in
  15367. protected mode into the V86 portion of the virtual machine. The term "API
  15368. translation" is used in this document to describe the conversion of an API
  15369. call in protected mode into a corresponding V86 mode call. Because enhanced
  15370. Windows runs under a standard MS-DOS, MS-DOS and BIOS calls must be
  15371. reflected to V86 mode code to handle the call. There is a layer of code in
  15372. the DOSMGR device that converts protected mode MS-DOS calls into V86 calls.%@CR:C6A00400014 @%%@CR:C6A00400015 @%%@NL@%
  15373.  
  15374. The main translation service, %@AB@%V86MMGR_Xlat_API%@AE@%, is a simple interpreter that
  15375. copies data into a buffer in the V86 address space and converts pointers to
  15376. point to the copied data. Note that the data is %@AI@%copied%@AE@%. The memory is not
  15377. mapped into V86 memory by changing page tables.  %@NL@%
  15378.  
  15379. Other services are provided to allocate buffer space, map memory into global
  15380. V86 address space, and perform other functions necessary for API
  15381. translation.  %@NL@%
  15382.  
  15383. Translations services work only for the current VM, and most are only
  15384. available from the protected-mode portion of a VM.  %@NL@%
  15385.  
  15386. Only one VxD should translate a given API call.  %@NL@%
  15387.  
  15388. DPMI provides a way for an application to do translation without installing
  15389. a VxD to do the transition.  %@NL@%
  15390.  
  15391.  
  15392. %@3@%%@AB@%40.2.1  Basic API Translation%@AE@%%@EH@%%@NL@%
  15393.  
  15394. Many APIs require little or no translation. Others are extremely complex and
  15395. require a great deal of coding. The simplest API is one that has no
  15396. pointers. A software interrupt based API, in which all parameters are passed
  15397. 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
  15398. no special translation software. By default, enhanced Windows will reflect
  15399. an interrupt that is executed in protected mode into V86 mode. For example,
  15400. the BIOS printer interface (Int 17h) requires no translation code since all
  15401. APIs are register-based with no pointers.  %@NL@%
  15402.  
  15403. However, most APIs have at least some calls that take pointers as
  15404. parameters. For example, to open a file through MS-DOS, you must point at
  15405. the name of the file to open with the %@AB@%DS:DX%@AE@% registers. Since the address
  15406. that a protected mode program will pass in %@AB@%DS:DX%@AE@% is not usually addressable
  15407. in the V86 portion of the VM, there must be code that copies the filename
  15408. into a buffer that is addressable in V86 mode so that MS-DOS can access the
  15409. filename.  %@NL@%
  15410.  
  15411.  
  15412. %@3@%%@AB@%40.2.2  Complex API Translation%@AE@%%@EH@%%@NL@%
  15413.  
  15414. Some APIs are too complex or their buffers are too large to be handled by
  15415. the %@AB@%V86MMGR_Xlat_API%@AE@% service. The MS-DOS Exec function takes a pointer to a
  15416. data structure that contains more pointers. This API requires special code
  15417. to translate the pointers in the data structure and to copy the data that
  15418. those pointers point to into V86 mode memory.  %@NL@%
  15419.  
  15420. The MS-DOS read and write file functions can have buffers as large as 64K.
  15421. The typical V86MMGR translation copy buffer is 4K. Therefore, these calls
  15422. require code to divide the call into several smaller reads or writes in V86
  15423. mode.  %@NL@%
  15424.  
  15425.  
  15426. %@3@%%@AB@%40.2.3  Hooking the Interrupt%@AE@%%@EH@%%@NL@%
  15427.  
  15428. Since the translation code should be the last protected mode handler you
  15429. will need to hook the PM interrupt vector (using the %@AB@%Hook_PM_Int_Vector%@AE@%
  15430. service) during the %@AB@%Sys_Critical_Init%@AE@% or %@AB@%Device_Init%@AE@% phases of
  15431. initialization. All translation code should be initialized before the
  15432. Init_Complete phase of initialization so that the %@AB@%Exec_VxD_Int%@AE@% service
  15433. (provided by the VMM) can be used during this phase. Note that the V86MMGR
  15434. translation services (except for %@AB@%Set_Mapping_Info%@AE@%) should not be called
  15435. during %@AB@%Sys_Critical_Init%@AE@% or %@AB@%Device_Init%@AE@%.  %@NL@%
  15436.  
  15437. By hooking the interrupt vector instead of using the %@AB@%Hook_PM_Int_Chain%@AE@%
  15438. service you will allow protected mode applications to hook software
  15439. interrupts "in front" of your translation code. This is very important for
  15440. the Windows kernel since it needs to monitor the activity of Windows
  15441. applications' API calls.  %@NL@%
  15442.  
  15443.  
  15444. %@4@%%@AB@%Sample Code%@AE@%%@EH@%%@NL@%
  15445.  
  15446. The code for a typical translation VxD looks like this:  %@NL@%
  15447.  
  15448. %@AS@%  VxD_ICODE_SEG
  15449. %@AS@%  BeginProc My_Xlat_Init
  15450. %@AS@%   mov eax, My_Translation_Int_Number
  15451. %@AS@%   VMMcall Get_PM_Int_Vector
  15452. %@AS@%   mov [Chain_Segment], cx
  15453. %@AS@%   mov [Chain_Offset], edx
  15454. %@AS@%   mov esi, OFFSET32 My_Xlat_Procedure
  15455. %@AS@%   VMMcall Allocate_PM_Call_Back
  15456. %@AS@%   mov ecx, eax
  15457. %@AS@%   movzx edx, cx
  15458. %@AS@%   shr ecx, 16
  15459. %@AS@%   mov eax, My_Translation_Int_Number
  15460. %@AS@%   VMMcall Set_PM_Int_Vector
  15461. %@AS@%   clc
  15462. %@AS@%   ret
  15463. %@AS@%  EndProc My_Xlat_Init
  15464. %@AS@%  VxD_ICODE_ENDS
  15465. %@AS@%  
  15466. %@AS@%  VxD_CODE_SEG
  15467. %@AS@%  BeginProc My_Xlat_Procedure
  15468. %@AS@%   movzx eax, [ebp.Client_AH]
  15469. %@AS@%   cmp eax, My_Max_API_Number
  15470. %@AS@%   ja Chain_To_Next_Handler
  15471. %@AS@%   VMMcall Simulate_Iret
  15472. %@AS@%   mov edx, My_Trans_Script_Table[eax*4]
  15473. %@AS@%   VxDcall V86MMGR_Xlat_API
  15474. %@AS@%   ret
  15475. %@AS@%  Chain_To_Next_Handler:
  15476. %@AS@%   movzx ecx, [Chain_Segment]
  15477. %@AS@%   jecxz Reflect_To_V86_Now
  15478. %@AS@%   mov edx, [Chain_Offset]
  15479. %@AS@%   VMMcall Simulate_Far_Jmp
  15480. %@AS@%   ret
  15481. %@AS@%  Reflect_To_V86_Now:
  15482. %@AS@%   VMMcall Begin_Nest_V86_Exec
  15483. %@AS@%   mov eax, My_Translation_Int_Number
  15484. %@AS@%   VMMcall Exec_Int
  15485. %@AS@%   VMMcall End_Nest_Exec
  15486. %@AS@%   ret
  15487. %@AS@%  EndProc My_Xlat_Procedure
  15488. %@AS@%  VxD_CODE_ENDS%@AE@%
  15489.  
  15490. If the value in AH is not translated by this handler then it will be
  15491. reflected to the next protected mode interrupt handler. If there is not
  15492. another PM interrupt handler (code segment is zero) then the interrupt is
  15493. immediately reflected to V86 mode.  %@NL@%
  15494.  
  15495. You will note that My_Xlat_Procedure calls the %@AB@%Simulate_Iret%@AE@% service before
  15496. it calls %@AB@%V86MMGR_Xlat_API%@AE@%. If you plan to "eat" an interrupt it is usually
  15497. best to call this service first. If the iret was simulated after the call to
  15498. %@AB@%V86MMGR_Xlat_API%@AE@% then any flags returned by the V86 interrupt handler would
  15499. be destroyed (an iret pops flags from the interrupt stack frame).  %@NL@%
  15500.  
  15501.  
  15502. %@3@%%@AB@%40.2.4  Mapping vs. Copying%@AE@%%@EH@%%@NL@%
  15503.  
  15504. Some VxDs need to use the paging mechanism of the 386 to map pages from
  15505. extended address space into the 1MB V86 address space of every virtual
  15506. machine. The Virtual NetBIOS Device uses the mapping services when an
  15507. asynchronous receive is issued so that the proper physical memory will be
  15508. updated regardless of which VM is currently running. When memory is mapped
  15509. using %@AB@%V86MMGR_Map_Pages%@AE@% it will be mapped to the same linear address in
  15510. every virtual machine. Thus it is best to avoid using these services.  %@NL@%
  15511.  
  15512. Do not use mapping as an alternative to copying just because you think
  15513. mapping seems easier. It is faster to copy memory than to map it since the
  15514. memory manager does not need to perform any page table mapping and locking.
  15515. Mapping also uses a lot of address space (although it requires no memory).
  15516. The mapping services should only be used for APIs that require memory mapped
  15517. to the same address in every VM.  %@NL@%
  15518.  
  15519. Note that the mapping services allow memory from one VM's V86 address space
  15520. to be mapped into all VMs at a common address. %@AI@%Don't use this for
  15521. %@AI@%interprocess communication.%@AE@% It will eat mapping space that may be required
  15522. by other devices. If you want to design an IPC interface, either make it
  15523. work for PM applications (which can share memory) or copy the data.  %@NL@%
  15524.  
  15525.  
  15526. %@3@%%@AB@%40.2.5  Writing Your Own Translation Procedures%@AE@%%@EH@%%@NL@%
  15527.  
  15528. Often, it is impossible to translate part or all of an API using the
  15529. supplied macro interpreter. Therefore you may need to write procedures that
  15530. do all or part of the translation. Examples of calls that require extra code
  15531. are the MS-DOS read and write commands and the get and set interrupt vector
  15532. commands. The MS-DOS commands to get and set interrupt vectors behave
  15533. differently in protected mode since they must hook the protected mode
  15534. interrupt vectors. These calls are never reflected to the "real" MS-DOS
  15535. running in V86 mode.  %@NL@%
  15536.  
  15537. The MS-DOS read and write file commands can use a buffer as large as 64K.
  15538. Since the translation buffers can be as small as 4K, reads and writes must
  15539. be divided before being reflected to MS-DOS.  %@NL@%
  15540.  
  15541. Since most APIs have some interfaces that can be handled by the
  15542. %@AB@%V86MMGR_Xlat_API%@AE@% script language and others that must be translated by
  15543. custom procedures you will probably want to dispatch to the custom
  15544. procedures using the %@AB@%Xlat_API_Jmp_To_Proc%@AE@% macro.  %@NL@%
  15545.  
  15546. To adjust V86 segment registers you should leave the VM in %@AB@%PM_Exec_Mode%@AE@% and
  15547. change the %@AB@%Alt_Client%@AE@% registers. When in %@AB@%PM_Exec_Mode%@AE@% these registers
  15548. contain the V86 segment registers and stack pointer. They will contain the
  15549. PM segment registers and stack pointer when the VM is in %@AB@%V86_Exec_Mode%@AE@%.  %@NL@%
  15550.  
  15551.  
  15552. %@3@%%@AB@%40.2.6  Sample API Translation%@AE@%%@EH@%%@NL@%
  15553.  
  15554. This sample API is for an imaginary, incredibly simple network. The
  15555. functions allow you to connect to a server and send or receive data. Assume
  15556. that the network supports the following API from software interrupt 92h:  %@NL@%
  15557.  
  15558.  
  15559. %@4@%%@AB@%%@AB@%Function 0: Get version%@AE@%%@AE@%%@EH@%%@NL@%
  15560.  
  15561.  
  15562. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15563.  
  15564. %@AB@%AH%@AE@% = 0  %@NL@%
  15565.  
  15566.  
  15567. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15568.  
  15569. %@AB@%AH%@AE@% = Major version %@AB@%AL%@AE@% = Minor version  %@NL@%
  15570.  
  15571.  
  15572. %@4@%%@AB@%%@AB@%Function 1: Get Server Name%@AE@%%@AE@%%@EH@%%@NL@%
  15573.  
  15574.  
  15575. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15576.  
  15577. %@AB@%AH %@AE@%= 1 %@AB@%DS:DX%@AE@% = Pointer to a 16 byte buffer to hold name  %@NL@%
  15578.  
  15579.  
  15580. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15581.  
  15582.  None  %@NL@%
  15583.  
  15584.  
  15585. %@4@%%@AB@%%@AB@%Function 2: Connect To New Server%@AE@%%@AE@%%@EH@%%@NL@%
  15586.  
  15587.  
  15588. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15589.  
  15590.  %@AB@%AH%@AE@% = 2  %@AB@%DS:DX%@AE@% = Pointer to null terminated string that is name of server  %@NL@%
  15591.  
  15592.  
  15593. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15594.  
  15595.  None  %@NL@%
  15596.  
  15597.  
  15598. %@4@%%@AB@%%@AB@%Function 3: Read/Write Data%@AE@%%@AE@%%@EH@%%@NL@%
  15599.  
  15600.  
  15601. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15602.  
  15603.  %@AB@%AH %@AE@%= 3  %@AB@%ES:BX%@AE@% = Pointer to command block with following structure:  %@NL@%
  15604.  
  15605. %@TH:   5   229 02 08 06 62 @%Offset  Size  Description%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%0       1     Command1       2     Buffer size3       4     Buffer pointer%@TE:   5   229 02 08 06 62 @%
  15606.  
  15607. Command field values:  0 = Read data from server  1 = Write data to server  %@NL@%
  15608.  
  15609.  
  15610. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15611.  
  15612. None  %@NL@%
  15613.  
  15614. Since function 0 is register based it requires no translation other than
  15615. reflecting the interrupt to V86 mode. Functions 1 and 2 both can be
  15616. translated by scripts using the %@AB@%V86MMGR_Xlat_API%@AE@% service. Function 3
  15617. requires a custom translation procedure.  %@NL@%
  15618.  
  15619. %@AS@%  VxD_DATA_SEG 
  15620. %@AS@%  Fctn_0_Script:
  15621. %@AS@%    Xlat_API_Exec_Int  92h 
  15622. %@AS@%  Fctn_1_Script:  Xlat_API_Fixed_Len ds, dx, 16
  15623. %@AS@%   Xlat_API_Exec_Int  92h 
  15624. %@AS@%  Fctn_2_Script:  Xlat_API_ASCIIZ   ds, dx 
  15625. %@AS@%   Xlat_API_Exec_Int 92h 
  15626. %@AS@%  Fctn_3_Script: 
  15627. %@AS@%   Xlat_API_Jmp_To_Proc Trans_Fctn_3
  15628. %@AS@%  Copy_Command_Block_Script: 
  15629. %@AS@%   Xlat_API_Fixed_Len es, bx, 7
  15630. %@AS@%   Xlat_API_Exec_Int  92h%@AE@%
  15631.  
  15632. %@AS@%  Xlat_Ptr_Table: 
  15633. %@AS@%   dd OFFSET32 Fctn_0_Script 
  15634. %@AS@%   dd OFFSET32 Fctn_1_Script  dd OFFSET32 Fctn_2_Script 
  15635. %@AS@%   dd OFFSET32 Fctn_3_Script 
  15636. %@AS@%  VxD_DATA_ENDS%@AE@%
  15637.  
  15638. %@AS@%  VxD_CODE_SEG 
  15639. %@AS@%  BeginProc Translate_Sample_API 
  15640. %@AS@%   movzx edx, [ebp.Client_AH]
  15641. %@AS@%   cmp edx, 3 
  15642. %@AS@%   ja Chain_To_Next_Handler 
  15643. %@AS@%   VMMcall Simulate_Iret 
  15644. %@AS@%   mov edx, Xlat_Ptr_Table[edx*4] 
  15645. %@AS@%   VxDcall V86MMGR_Xlat_API 
  15646. %@AS@%   jc Translation_Error  ret 
  15647. %@AS@%  Chain_To_Next_Handler: 
  15648. %@AS@%   movzx ecx, [Chain_Segment] 
  15649. %@AS@%   jecxz Reflect_To_V86_Now
  15650. %@AS@%   mov edx, [Chain_Offset] 
  15651. %@AS@%   VMMcall Simulate_Far_Jmp 
  15652. %@AS@%   ret 
  15653. %@AS@%  Reflect_To_V86_Now:
  15654. %@AS@%   VMMcall Begin_Nest_V86_Exec 
  15655. %@AS@%   mov eax, 92h 
  15656. %@AS@%   VMMcall Exec_Int VMMcall
  15657. %@AS@%   End_Nest_Exec
  15658. %@AS@%   ret 
  15659. %@AS@%  Translation_Error: 
  15660. %@AS@%   Debug_Out "Unable to translate sample API"
  15661. %@AS@%   VMMjmp Crash_Cur_VM 
  15662. %@AS@%  EndProc Translate_Sample_API%@AE@%
  15663.  
  15664. %@AS@%  BeginProc Trans_Fctn_3 
  15665. %@AS@%   push fs 
  15666. %@AS@%   push gs 
  15667. %@AS@%   pushad 
  15668. %@AS@%  ; Get pointer to command block 
  15669. %@AS@%   mov ax, (Client_ES*100h)+Client_BX 
  15670. %@AS@%   VxDcall V86MMGR_Load_Client_Ptr 
  15671. %@AS@%  ; If command is invalid then fail the call 
  15672. %@AS@%   mov al, BYTE PTR fs:[esi] 
  15673. %@AS@%   cmp al, 1 
  15674. %@AS@%   ja Can_Not_Translate 
  15675. %@AS@%  ; Get buffer size and pointer from command block 
  15676. %@AS@%   mov dx, fs 
  15677. %@AS@%   mov gs, dx 
  15678. %@AS@%   mov edx, esi movzx ecx, WORD PTR gs:[edx+1] 
  15679. %@AS@%   mov fs, WORD PTR gs:[edx+5] 
  15680. %@AS@%   movzx   esi, WORD PTR gs:[edx+3] 
  15681. %@AS@%  ; Allocate a buffer, copying data if command is a write
  15682. %@AS@%   bt eax, 0 
  15683. %@AS@%   VxDcall V86MMGR_Allocate_Buffer 
  15684. %@AS@%   jc Can_Not_Translate
  15685. %@AS@%   mov DWORD PTR gs:[edx+3], edi 
  15686. %@AS@%  ; Copy the command block and execute the interrupt 
  15687. %@AS@%   push edx 
  15688. %@AS@%   mov edx, OFFSET32 Copy_Command_Block_Script
  15689. %@AS@%   VxDcall V86MMGR_Xlat_API 
  15690. %@AS@%   pop edx 
  15691. %@AS@%   jc Can_Not_Translate 
  15692. %@AS@%  ; Free the buffer, copying data if command is a read 
  15693. %@AS@%   mov al, BYTE PTR gs:[edx]
  15694. %@AS@%   bt eax, 0 
  15695. %@AS@%   cmc 
  15696. %@AS@%   VxDcall V86MMGR_Free_Buffer 
  15697. %@AS@%  ; Restore original pointer in command block 
  15698. %@AS@%   mov WORD PTR gs:[edx+5], fs 
  15699. %@AS@%   mov WORD PTR gs:[edx+3], si 
  15700. %@AS@%   clc 
  15701. %@AS@%  Trans_F3_Exit: 
  15702. %@AS@%   popad 
  15703. %@AS@%   pop gs 
  15704. %@AS@%   pop fs 
  15705. %@AS@%   ret 
  15706. %@AS@%  Can_Not_Translate:  stc 
  15707. %@AS@%   jmp Trans_F3_Exit 
  15708. %@AS@%  EndProc Trans_Fctn_3
  15709. %@AS@%  
  15710. %@AS@%  VxD_CODE_ENDS%@AE@%
  15711.  
  15712. %@CR:C6A00400016 @%
  15713. %@2@%%@CR:C6A00400017 @%%@AB@%V86MMGR_Set_Mapping_Info%@AE@%%@EH@%%@NL@%
  15714. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15715.  
  15716.  
  15717. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15718.  
  15719. This service must be called during the %@AB@%Sys_Critical_Init %@AE@%or %@AB@%Device_Init
  15720. %@AB@%%@AE@%phase of device initialization. It is used to define the minimum amount of
  15721. translation buffer and global V86 map address space that will be required.
  15722. VxDs such as the VNETBIOS use this service to ensure that there will be
  15723. adequate global page mapping space to map network buffers. By default the
  15724. translation copy buffer size is 4K and there are no global mapping pages.  %@NL@%
  15725.  
  15726. Multiple VxDs may call this service. The V86MMGR will use the largest value
  15727. for each of the parameters when allocating buffer space. In other words, if
  15728. 10 VxDs request a two-page copy buffer then the copy buffer will be two
  15729. pages (not 20).  %@NL@%
  15730.  
  15731. Note that while a large copy buffer can speed up operations such as MS-DOS
  15732. reads, it requires extra memory to be allocated for every VM. Therefore, you
  15733. should try to get by with a copy buffer size of one page if possible.  %@NL@%
  15734.  
  15735.  
  15736. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15737.  
  15738. %@AB@%AL%@AE@% = Minimum number of pages required for default copy buffer %@AB@%AH%@AE@% = Maximum
  15739. number of pages desired for default copy buffer %@AB@%BL%@AE@% = Minimum number of pages
  15740. required for global page mapping region %@AB@%BH%@AE@% = Maximum number of pages desired
  15741. for global page mapping region  %@NL@%
  15742.  
  15743.  
  15744. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15745.  
  15746. None  %@NL@%
  15747.  
  15748.  
  15749. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15750.  
  15751. Flags  %@NL@%
  15752.  
  15753. %@CR:C6A00400018 @%
  15754. %@2@%%@CR:C6A00400019 @%%@AB@%V86MMGR_Xlat_API%@AE@%%@EH@%%@NL@%
  15755. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15756.  
  15757.  
  15758. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  15759.  
  15760. This service is actually a simple interpreter that executes scripts that are
  15761. created using macros defined in V86MMGR.INC. The macros are described in
  15762. detail below.  %@NL@%
  15763.  
  15764. You can combine any of the macros, although you should keep in mind that
  15765. %@AB@%Xlat_API_Exec_Int%@AE@% and %@AB@%Xlat_API_Jmp_To_Proc%@AE@% both terminate interpretation of
  15766. the current script.  %@NL@%
  15767.  
  15768. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15769. %@AU@%WARNING%@AE@%
  15770.  
  15771. You should always specify the exact length of a buffer or else strange
  15772. things may occur. For example, it is incorrect to translate an API that has
  15773. a maximum buffer size of 128 bytes by using the Xlat_API_Fixed_Len macro if
  15774. the buffer can be smaller than 128 bytes. This can cause bugs if the program
  15775. has data that is updated at interrupt time that is located past the end of
  15776. the buffer.
  15777. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15778.  
  15779. For example, assume a program has the following data:  %@NL@%
  15780.  
  15781. %@AS@%  Buffer_Length db 64
  15782. %@AS@%  Buffer_Data db 64 dup (?)
  15783. %@AS@%  Time_Of_Day dd 0
  15784. %@AS@%  Other_Stuff db 500 dup (?)%@AE@%
  15785.  
  15786.  
  15787. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  15788.  
  15789. %@AB@%EBX%@AE@% = Current VM handle %@AB@%EBP%@AE@% -> Client register structure %@AB@%EDX%@AE@% -> Script to
  15790. translate  %@NL@%
  15791.  
  15792.  
  15793. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  15794.  
  15795. %@AB@%EDX%@AE@% is destroyed If carry set then  Error while executing script else
  15796. Script has been executed successfully  %@NL@%
  15797.  
  15798.  
  15799. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  15800.  
  15801. %@AB@%EDX%@AE@%, Flags  %@NL@%
  15802.  
  15803.  
  15804. %@3@%%@AB@%Macro5%@AE@%%@EH@%%@NL@%
  15805.  
  15806. The following define the translation scripts.  %@NL@%
  15807.  
  15808.  
  15809. %@4@%%@AB@%Xlat_API_Exec_Int [Int Number]%@AE@%%@EH@%%@NL@%
  15810.  
  15811. Terminates the interpretation of the translation script and reflects the
  15812. specified interrupt into Virtual 8086 mode. When the interrupt returns then
  15813. it will return to the caller.  %@NL@%
  15814.  
  15815. %@AS@%  DOS_No_Xlat_API:
  15816. %@AS@%   Xlat_API_Exec_Int 21h%@AE@%
  15817.  
  15818.  
  15819. %@4@%%@AB@%Xlat_API_Fixed_Len [Segment], [Offset], [Length Constant]%@AE@%%@EH@%%@NL@%
  15820.  
  15821. Copies a fixed length buffer from extended memory into the translation
  15822. buffer and fixes up the V86 Seg:Offset.  %@NL@%
  15823.  
  15824. This service will fail if there is not enough room in the translation buffer
  15825. to copy the data.  %@NL@%
  15826.  
  15827. For example, the MS-DOS Get Current Directory function (%@AB@%AH%@AE@%=47h), must be
  15828. called with %@AB@%DS:SI%@AE@% pointing to a 64-byte buffer. The following script would
  15829. perform the appropriate translation:  %@NL@%
  15830.  
  15831. %@AS@%  DOS_Get_Current_Directory_API:
  15832. %@AS@%   Xlat_API_Fixed_Len ds, si, 64
  15833. %@AS@%   Xlat_API_Exec_Int  21h%@AE@%
  15834.  
  15835.  
  15836. %@4@%%@AB@%Xlat_API_Var_Len [Segment], [Offset], [Length Register]%@AE@%%@EH@%%@NL@%
  15837.  
  15838. Copies a variable number of bytes from extended memory into the translation
  15839. buffer. This is used for APIs where the caller places the buffer size in a
  15840. register.  %@NL@%
  15841.  
  15842. This service will fail if there is not enough room in the translation buffer
  15843. to copy the data.  %@NL@%
  15844.  
  15845. For example, the Int 10h write string function (AH=0Eh), must be called with
  15846. %@AB@%ES:BP%@AE@% pointing to the string to print and %@AB@%CX%@AE@% equal to the number of bytes to
  15847. display. The following script would translate this call:  %@NL@%
  15848.  
  15849. %@AS@%  Int_10h_Write_String:
  15850. %@AS@%   Xlat_API_Var_Len  es, bp, cx
  15851. %@AS@%   Xlat_API_Exec_Int 10h%@AE@%
  15852.  
  15853.  
  15854. %@4@%%@AB@%Xlat_API_Calc_Len [Segment], [Ptr_Off], [Calc_Proc_Addr]%@AE@%%@EH@%%@NL@%
  15855.  
  15856. Used to copy buffers that change in size. You must specify the
  15857. selector:offset register pair that points to the buffer and the name of a
  15858. procedure that will calculate the actual buffer size. The procedure will be
  15859. called with %@AB@%FS:ESI%@AE@% pointing to the buffer and must return with %@AB@%ECX%@AE@% equal to
  15860. the number of bytes to copy. The procedure must preserve all registers
  15861. except %@AB@%ECX%@AE@%.  %@NL@%
  15862.  
  15863. This service will fail if there is not enough room in the translation buffer
  15864. to copy the data.  %@NL@%
  15865.  
  15866. For example, the MS-DOS buffered keyboard input command (AH=0Ah) can have a
  15867. buffer size from 3 to 257 bytes long. The first byte of the buffer specifies
  15868. the length of the input buffer as follows:  %@NL@%
  15869.  
  15870. %@TH:  12   643 02 34 44 @%Byte                              Contents%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%0                                 Maximum number of characters to read                                   (1-255); this value must be set by the                                   process before Function 0Ah is called.1                                 Count of characters read.2-(n+2)                           Actual string of characters read,                                   including the carriage return;                                   n = number of bytes read.%@TE:  12   643 02 34 44 @%
  15871.  
  15872. The translation code for this API would look something like this:  %@NL@%
  15873.  
  15874. %@AS@%  VxD_DATA_SEG
  15875. %@AS@%  Buff_Keyboard_Input_API:
  15876. %@AS@%   Xlat_API_Calc_Len ds, dx, Calc_Input_Buff_Size
  15877. %@AS@%   Xlat_API_Exec_Int 21h
  15878. %@AS@%  VxD_DATA_ENDS
  15879. %@AS@%  
  15880. %@AS@%  VxD_CODE_SEG
  15881. %@AS@%  BeginProc Int_21_PM_To_V86_Translator
  15882. %@AS@%  
  15883. %@AS@%   cmp [ebp.Client_AH], 0Ah
  15884. %@AS@%   jne Not_Buffered_Keyboard_Input
  15885. %@AS@%   VMMcall Simulate_Iret
  15886. %@AS@%   mov edx, OFFSET32 Buff_Keyboard_Input_API
  15887. %@AS@%   VxDcall V86MMGR_Xlat_API
  15888. %@AS@%   ret
  15889. %@AS@%  
  15890. %@AS@%  EndProc Int_21_PM_To_V86_Translator
  15891. %@AS@%  
  15892. %@AS@%  BeginProc Calc_Input_Buff_Size
  15893. %@AS@%  
  15894. %@AS@%   movzx ecx, BYTE PTR fs:[esi]
  15895. %@AS@%   add ecx, 2
  15896. %@AS@%   ret
  15897. %@AS@%  
  15898. %@AS@%  EndProc Calc_Input_Buff_Size
  15899. %@AS@%  VxD_CODE_ENDS%@AE@%
  15900.  
  15901.  
  15902. %@4@%%@AB@%Xlat_API_ASCIIZ [Ptr_Seg], [Ptr_Off]%@AE@%%@EH@%%@NL@%
  15903.  
  15904. Copies a null-terminated string into V86 memory and adjusts the V86 pointer
  15905. appropriately. Note that the string will not be copied back after the call
  15906. is complete.  %@NL@%
  15907.  
  15908. This service will fail if there is not enough room in the translation buffer
  15909. to copy the string.  %@NL@%
  15910.  
  15911. For example, the MS-DOS Open File With Handle function (AH=3Dh), must be
  15912. called with %@AB@%DS:DX%@AE@% pointing to the name of the file to open. The following
  15913. script could be used translate the API:  %@NL@%
  15914.  
  15915. %@AS@%  DOS_Open_File_With_Handle:
  15916. %@AS@%   Xlat_API_ASCIIZ   ds, dx
  15917. %@AS@%   Xlat_API_Exec_Int 21h%@AE@%
  15918.  
  15919. The interpreter can copy multiple buffers. For example, the following
  15920. translation table translates the MS-DOS rename file call (AH = 56h):  %@NL@%
  15921.  
  15922. %@AS@%  Rename_API:
  15923. %@AS@%   Xlat_API_ASCIIZ   ds, dx
  15924. %@AS@%   Xlat_API_ASCIIZ   es, di
  15925. %@AS@%   Xlat_API_Exec_Int 21h%@AE@%
  15926.  
  15927. The first instruction copies the null-terminated string (ASCIIZ string) that
  15928. %@AB@%DS:DX%@AE@% points to into the translation buffer in V86 memory, sets the V86 DS
  15929. to the translation buffer segment, and changes %@AB@%DX%@AE@% to the offset in the
  15930. buffer.  %@NL@%
  15931.  
  15932. The second macro copies the ASCIIZ string that is pointed to by %@AB@%ES:(E)DI%@AE@%
  15933. into V86 memory and adjusts the pointer accordingly.  %@NL@%
  15934.  
  15935. The final macro terminates the interpretation of the script and reflects an
  15936. Int 21h into the V86 portion of the VM. When the Int 21h returns, both
  15937. buffers will be freed.  %@NL@%
  15938.  
  15939.  
  15940. %@4@%%@AB@%Xlat_API_Jmp_To_Proc [Proc_Name]%@AE@%%@EH@%%@NL@%
  15941.  
  15942. Terminates the interpretation of the translation script and transfers
  15943. control to a user defined procedure. The procedure can completely handle the
  15944. API translation or can call %@AB@%V86MMGR_Xlat_API%@AE@% again. This can be useful for
  15945. APIs that have several sub-APIs such as the DOS IOCTL calls.  %@NL@%
  15946.  
  15947. The procedure will be called with %@AB@%EBX%@AE@% equal to Current VM Handle, %@AB@%EBP%@AE@%
  15948. pointing to Client register structure, and %@AB@%EDX%@AE@% points to the next entry in
  15949. the translation script (if there is one). It must preserve every register
  15950. except for %@AB@%EDX%@AE@%. Therefore the procedure must preserve %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%ESI%@AE@%,
  15951. %@AB@%EDI%@AE@%, %@AB@%EBP%@AE@%, %@AB@%DS%@AE@%, %@AB@%ES%@AE@%, %@AB@%FS%@AE@%, and %@AB@%GS%@AE@%.  %@NL@%
  15952.  
  15953. Your procedure should return with the carry flag clear if the translation
  15954. was successful. Otherwise, it should return with carry set to indicate an
  15955. error.  %@NL@%
  15956.  
  15957.  
  15958. %@4@%%@AB@%Xlat_API_Return_Ptr [Ptr_Seg], [Ptr_Off]%@AE@%%@EH@%%@NL@%
  15959.  
  15960. Used for calls that return a pointer to a structure. For 16-bit protected
  15961. mode programs, if an appropriate selector does not exist to map the call,
  15962. then this service automatically creates one. For 32-bit protected mode
  15963. programs the selector returned will always be the %@AB@%V86MMGR_VM_Flat_Selector%@AE@%
  15964. and the offset will be adjusted. Note that although this macro is placed
  15965. before the %@AB@%Exec_Int%@AE@% macro in a translation script, the pointer is created
  15966. after the interrupt has been executed.  %@NL@%
  15967.  
  15968. This service will fail if it can not create an appropriate LDT selector.  %@NL@%
  15969.  
  15970. For example, this service is used to translate Int 15h with AH=C0h, which
  15971. returns a pointer in %@AB@%ES:BX%@AE@% that points to a hardware information structure
  15972. on PS/2 machines. The following script would return the appropriate pointer:
  15973. %@NL@%
  15974.  
  15975. %@AS@%  Get_Machine_Info:
  15976. %@AS@%   Xlat_API_Return_Ptr es, bx
  15977. %@AS@%   Xlat_API_Exec_Int   15h%@AE@%
  15978.  
  15979.  
  15980. %@4@%%@AB@%Xlat_API_Return_Seg [Ptr_Seg]%@AE@%%@EH@%%@NL@%
  15981.  
  15982. Used for calls that return a segment. If an appropriate selector does not
  15983. exist to map the call then this service automatically creates one. Note that
  15984. although this macro is placed before the %@AB@%Exec_Int%@AE@% macro in a translation
  15985. script, the selector is created after the interrupt has been executed.  %@NL@%
  15986.  
  15987. This service will fail if it can not create an appropriate LDT selector.  %@NL@%
  15988.  
  15989. For example, this service is used to translate Int 15h with %@AB@%AH%@AE@%=C1h, which
  15990. returns the segment of the EBIOS data area in %@AB@%ES%@AE@%. The following script would
  15991. return a selector that points to the EBIOS data area:  %@NL@%
  15992.  
  15993. %@AS@%  Get_EBIOS_Selector:
  15994. %@AS@%   Xlat_API_Return_Seg es
  15995. %@AS@%   Xlat_API_Exec_Int   15h%@AE@%
  15996.  
  15997. Assume the program updates the Time_Of_Day field from the timer interrupt.
  15998. If the translation code copies 128 bytes of data starting with Buffer_Length
  15999. into V86 mode memory and while processing the call a timer interrupt
  16000. executes then the Time_Of_Day field will be incremented. However, when the
  16001. buffer is copied back the old time will be copied on top of the current
  16002. (correct) Time_Of_Day field.  %@NL@%
  16003.  
  16004. %@CR:C6A00400020 @%
  16005. %@2@%%@CR:C6A00400021 @%%@AB@%V86MMGR_Load_Client_Ptr%@AE@%%@EH@%%@NL@%
  16006. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16007.  
  16008.  
  16009. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16010.  
  16011. This service will load %@AB@%FS:ESI%@AE@% with the specified Client_Seg:Offset. If the
  16012. VM is running a 16-bit protected mode then the high word of the offset in
  16013. %@AB@%ESI%@AE@% will be zeroed. Otherwise, if the VM is running a 32-bit program or is
  16014. in %@AB@%VxD_Exec_Mode%@AE@% then the high word of %@AB@%ESI%@AE@% will not be zeroed. This allows
  16015. most translation procedures to operate correctly without the need to test
  16016. the execution mode of the current VM.  %@NL@%
  16017.  
  16018. The value passed in %@AB@%AX%@AE@% should be formed from the Client Register Structure
  16019. equates. For example, to load the VM's %@AB@%DS:(E)DX%@AE@% you would use the following
  16020. code:  %@NL@%
  16021.  
  16022. %@AS@%  mov ax, (Client_DS * 100h) + Client_DX
  16023. %@AS@%  VxDcall V86MMGR_Load_Client_Ptr
  16024. %@AS@%  (FS:ESI -> Same address as Client_DS:(E)DX).%@AE@%
  16025.  
  16026.  
  16027. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16028.  
  16029. VM must be in protected mode %@AB@%AH%@AE@% = Client segment register equate %@AB@%AL%@AE@% = Client
  16030. offset register equate %@AB@%EBX%@AE@% = Current VM Handle %@AB@%EBP%@AE@% -> Client register
  16031. structure  %@NL@%
  16032.  
  16033.  
  16034. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16035.  
  16036. %@AB@%FS:ESI%@AE@% -> Client's buffer  %@NL@%
  16037.  
  16038.  
  16039. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16040.  
  16041. %@AB@%FS%@AE@%, %@AB@%ESI%@AE@%, Flags  %@NL@%
  16042.  
  16043. %@CR:C6A00400022 @%
  16044. %@2@%%@CR:C6A00400023 @%%@AB@%V86MMGR_Allocate_Buffer%@AE@%%@EH@%%@NL@%
  16045. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16046.  
  16047.  
  16048. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16049.  
  16050. Allocates a portion of the current VM's translation buffer and optionally
  16051. copies data from the PM pointer in %@AB@%FS:ESI%@AE@% into the allocated buffer.  %@NL@%
  16052.  
  16053. Note that this service will map fewer bytes than the value specified in the
  16054. %@AB@%ECX%@AE@% parameter if the length of the buffer extends past the FS segment limit.
  16055. Therefore, you need to preserve the value returned in ECX from this service
  16056. to use when deallocating the buffer using %@AB@%V86MMGR_Free_Buffer%@AE@%.  %@NL@%
  16057.  
  16058. The buffers are maintained as a stack. Therefore, the last buffer allocated
  16059. must be the first buffer freed.  %@NL@%
  16060.  
  16061.  
  16062. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16063.  
  16064. Current VM must be in protected mode %@AB@%EBX%@AE@% = Current VM Handle %@AB@%EBP%@AE@% -> Client
  16065. register structure %@AB@%ECX%@AE@% = Number of bytes to allocate %@AB@%FS:ESI %@AE@%= Pointer to
  16066. extended memory to copy If carry flag is set then  Source buffer will be
  16067. copied into V86 buffer else  Source buffer will not be copied into V86
  16068. memory  %@NL@%
  16069.  
  16070.  
  16071. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16072.  
  16073. If carry set then  ERROR: Could not allocate buffer (out of space) else  ECX
  16074. = Actual number of bytes allocated (<= original %@AB@%ECX%@AE@%)  High WORD of %@AB@%EDI%@AE@% = V86
  16075. segment of translation buffer  Low WORD of %@AB@%EDI%@AE@% = Offset of allocated buffer
  16076. %@NL@%
  16077.  
  16078.  
  16079. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16080.  
  16081. %@AB@%ECX%@AE@%, %@AB@%EDI%@AE@%, Flags  %@NL@%
  16082.  
  16083. %@CR:C6A00400024 @%
  16084. %@2@%%@CR:C6A00400025 @%%@AB@%V86MMGR_Free_Buffer%@AE@%%@EH@%%@NL@%
  16085. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16086.  
  16087.  
  16088. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16089.  
  16090. Deallocates a buffer that was allocated by the %@AB@%V86MMGR_Allocate_Buffer%@AE@%
  16091. service. It will optionally copy data from the translation buffer to the
  16092. buffer pointed to by %@AB@%FS:ESI%@AE@%.  %@NL@%
  16093.  
  16094. The buffers are maintained as a stack. Therefore, the last buffer allocated
  16095. must be the first buffer freed.  %@NL@%
  16096.  
  16097.  
  16098. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16099.  
  16100. Current VM must be in protected mode %@AB@%EBX%@AE@% = Current VM Handle %@AB@%EBP%@AE@% -> Client
  16101. register structure %@AB@%ECX%@AE@% = Number of bytes to free (returned from
  16102. Allocate_Buffer) %@AB@%FS:ESI%@AE@% = Pointer to extended memory buffer If carry flag is
  16103. set then  Buffer will be copied from V86 memory before buffer freed else
  16104. Buffer will not be copied  %@NL@%
  16105.  
  16106.  
  16107. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16108.  
  16109. None  %@NL@%
  16110.  
  16111.  
  16112. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16113.  
  16114. Flags  %@NL@%
  16115.  
  16116. %@CR:C6A00400026 @%
  16117. %@2@%%@CR:C6A00400027 @%%@AB@%V86MMGR_Get_Xlat_Buff_State%@AE@%%@EH@%%@NL@%
  16118. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16119.  
  16120.  
  16121. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16122.  
  16123. This service returns information about the current mapping buffer status.  %@NL@%
  16124.  
  16125. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16126. %@AU@%WARNING%@AE@%
  16127.  
  16128. Always call this service to find the segment of the translation buffer.
  16129. Since the buffer can move at any time you should never make any assumptions
  16130. about the size or location of the buffer.
  16131. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16132.  
  16133.  
  16134. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16135.  
  16136. %@AB@%EBX %@AE@%= VM handle (any VM handle valid)  %@NL@%
  16137.  
  16138.  
  16139. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16140.  
  16141. %@AB@%EAX%@AE@% = V86 segment of translation buffer (high word 0) %@AB@%ECX%@AE@% = Number of bytes
  16142. of buffer not in use %@AB@%EDX%@AE@% = Total size of buffer in bytes (max size 10000h)  %@NL@%
  16143.  
  16144.  
  16145. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16146.  
  16147. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, Flags  %@NL@%
  16148.  
  16149. %@CR:C6A00400028 @%
  16150. %@2@%%@CR:C6A00400029 @%%@AB@%V86MMGR_Set_Xlat_Buff_State%@AE@%%@EH@%%@NL@%
  16151. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16152.  
  16153.  
  16154. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16155.  
  16156. This service is used to switch to an alternate mapping buffer. This feature
  16157. is provided for protected mode terminated-and-stay resident programs which
  16158. may need to switch to a private translation buffer before executing
  16159. protected mode MS-DOS calls since the default buffer may be full.  %@NL@%
  16160.  
  16161. You should get the current translation buffer state, set the new state,
  16162. perform any MS-DOS call, and then set the state back to the original values.
  16163. %@NL@%
  16164.  
  16165.  
  16166. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16167.  
  16168. %@AB@%EBX%@AE@% = VM handle (any VM handle valid) %@AB@%EAX %@AE@%= V86 segment of translation
  16169. buffer (high word 0) %@AB@%ECX%@AE@% = Number of bytes of buffer not in use %@AB@%EDX%@AE@% = Total
  16170. size of buffer in bytes (max size 10000h)  %@NL@%
  16171.  
  16172.  
  16173. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16174.  
  16175. None  %@NL@%
  16176.  
  16177.  
  16178. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16179.  
  16180. Flags  %@NL@%
  16181.  
  16182. %@CR:C6A00400030 @%
  16183. %@2@%%@CR:C6A00400031 @%%@AB@%V86MMGR_Get_VM_Flat_Sel%@AE@%%@EH@%%@NL@%
  16184. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16185.  
  16186.  
  16187. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16188.  
  16189. This service returns a selector that points to the base of the specified
  16190. VM's V86 address space. This is useful for 32-bit applications since this
  16191. selector can be used to point to any address in the VM's V86 address space.
  16192. The selector is writeable and has a limit of 11,000h bytes so that the high
  16193. memory area is also addressable.  %@NL@%
  16194.  
  16195. The selector returned is in the specified VM's LDT. Therefore, the selector
  16196. is only valid to use when the VM is running (is the current VM).  %@NL@%
  16197.  
  16198.  
  16199. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16200.  
  16201. %@AB@%EBX %@AE@%= VM handle (any VM handle is valid)  %@NL@%
  16202.  
  16203.  
  16204. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16205.  
  16206. %@AB@%EAX %@AE@%= Selector with base at high linear addr of V86 memory (high word 0)  %@NL@%
  16207.  
  16208.  
  16209. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16210.  
  16211. %@AB@%EAX%@AE@%, Flags  %@NL@%
  16212.  
  16213. %@CR:C6A00400032 @%
  16214. %@2@%%@CR:C6A00400033 @%%@AB@%V86MMGR_Get_Mapping_Info%@AE@%%@EH@%%@NL@%
  16215. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16216.  
  16217.  
  16218. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16219.  
  16220. This service will return information about the current page mapping areas.  %@NL@%
  16221.  
  16222.  
  16223. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16224.  
  16225. None  %@NL@%
  16226.  
  16227.  
  16228. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16229.  
  16230. %@AB@%CH%@AE@% = Number of pages reserved for global mapping (total) %@AB@%CL%@AE@% = Number of
  16231. pages available (not in use) for global mapping  %@NL@%
  16232.  
  16233. %@CR:C6A00400034 @%
  16234. %@2@%%@CR:C6A00400035 @%%@AB@%V86MMGR_Map_Pages%@AE@%%@EH@%%@NL@%
  16235. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16236.  
  16237.  
  16238. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16239.  
  16240. This service maps the specified buffer into every VM at the same address
  16241. using page mapping. If the contents of memory are changed in one VM, the
  16242. change will be reflected in the original buffer as well in all other VMs.  %@NL@%
  16243.  
  16244.  
  16245. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16246.  
  16247. %@AB@%ESI %@AE@%-> Linear address to map %@AB@%ECX%@AE@% = Number of bytes to map  %@NL@%
  16248.  
  16249.  
  16250. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16251.  
  16252. If carry flag is set then  ERROR: Could not map memory else  Memory is
  16253. mapped  %@AB@%ESI%@AE@% = Map handle (used to free the map region)  %@AB@%EDI %@AE@%= Linear address
  16254. of map buffer (%@NL@%
  16255.  
  16256.  
  16257. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16258.  
  16259. %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, Flags  %@NL@%
  16260.  
  16261. %@CR:C6A00400036 @%
  16262. %@2@%%@CR:C6A00400037 @%%@AB@%V86MMGR_Free_Page_Map_Region%@AE@%%@EH@%%@NL@%
  16263. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16264.  
  16265.  
  16266. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16267.  
  16268. This service will "unmap" pages that were mapped by the %@AB@%V86MMGR_Map_Pages%@AE@%
  16269. service.  %@NL@%
  16270.  
  16271.  
  16272. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16273.  
  16274. %@AB@%ESI%@AE@% = Map handle to free  %@NL@%
  16275.  
  16276.  
  16277. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16278.  
  16279. Old map buffer address contains null memory %@AB@%ESI%@AE@% is undefined  %@NL@%
  16280.  
  16281.  
  16282. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16283.  
  16284. %@AB@%ESI%@AE@%, Flags  %@NL@%
  16285.  
  16286.  
  16287.  
  16288.  
  16289.  
  16290.  
  16291. %@CR:C6A00410001 @%%@1@%%@AB@%Chapter 41  Virtual DMA Device (VDMAD) Services%@AE@%%@EH@%%@NL@%
  16292. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16293.  
  16294. The VDMAD is the Microsoft Windows virtual device providing DMA services
  16295. according to the VDS specifications. This VxD should be used in the enhanced
  16296. Windows environment rather than using the VDS services directely. By
  16297. default, it handles all programmed I/O for the DMA controllers and
  16298. arbitrates I/O to the physical DMA ports so that more than one VM can be
  16299. using the same DMA channels at the same time. In some cases, the default
  16300. handling of DMA channels is not desirable. To handle these cases, VDMAD
  16301. provides a number of services to enable another VxD to take control of the
  16302. virtualization of specific DMA channels.%@CR:C6A00410002 @%%@NL@%
  16303.  
  16304. VDMAD also provides some services that can be used by Bus Master devices
  16305. that have their own DMA controllers. These devices still need to be able to
  16306. lock and unlock DMA regions in memory and determine the physical addresses
  16307. of these regions. Bus Master devices can also make use of the buffer
  16308. services, if they cannot otherwise scatter/gather a linear region that is
  16309. not physically contiguous.  %@NL@%
  16310.  
  16311. The VDMAD services available for Bus Master use are as follows:  %@NL@%
  16312.  
  16313.  
  16314.   ■   %@AB@%VDMAD_Copy_From_Buffer%@AE@%%@NL@%
  16315.  
  16316.   ■   %@AB@%VDMAD_Copy_To_Buffer%@AE@%%@NL@%
  16317.  
  16318.   ■   %@AB@%VDMAD_Default_Handler%@AE@%%@NL@%
  16319.  
  16320.   ■   %@AB@%VDMAD_Disable_Translation%@AE@%%@NL@%
  16321.  
  16322.   ■   %@AB@%VDMAD_Enable_Translation%@AE@%%@NL@%
  16323.  
  16324.   ■   %@AB@%VDMAD_Get_EISA_Adr_Mode%@AE@%%@NL@%
  16325.  
  16326.   ■   %@AB@%VDMAD_Get_Region_Info%@AE@%%@NL@%
  16327.  
  16328.   ■   %@AB@%VDMAD_Get_Version%@AE@%%@NL@%
  16329.  
  16330.   ■   %@AB@%VDMAD_Get_Virt_State%@AE@%%@NL@%
  16331.  
  16332.   ■   %@AB@%VDMAD_Lock_DMA_Region%@AE@%%@NL@%
  16333.  
  16334.   ■   %@AB@%VDMAD_Mask_Channel%@AE@%%@NL@%
  16335.  
  16336.   ■   %@AB@%VDMAD_Release_Buffer%@AE@%%@NL@%
  16337.  
  16338.   ■   %@AB@%VDMAD_Request_Buffer%@AE@%%@NL@%
  16339.  
  16340.   ■   %@AB@%VDMAD_Reserve_Buffer_Space%@AE@%%@NL@%
  16341.  
  16342.   ■   %@AB@%VDMAD_Scatter_Lock%@AE@%%@NL@%
  16343.  
  16344.   ■   %@AB@%VDMAD_Scatter_Unlock%@AE@%%@NL@%
  16345.  
  16346.   ■   %@AB@%VDMAD_Set_EISA_Adr_Mode%@AE@%%@NL@%
  16347.  
  16348.   ■   %@AB@%VDMAD_Set_Phys_State%@AE@%%@NL@%
  16349.  
  16350.   ■   %@AB@%VDMAD_Set_Region_Info%@AE@%%@NL@%
  16351.  
  16352.   ■   %@AB@%VDMAD_Set_Virt_State%@AE@%%@NL@%
  16353.  
  16354.   ■   %@AB@%VDMAD_Unlock_DMA_Region%@AE@%%@NL@%
  16355.  
  16356.   ■   %@AB@%VDMAD_UnMask_Channel%@AE@%%@NL@%
  16357.  
  16358.   ■   %@AB@%VDMAD_Virtualize_Channel%@AE@%%@NL@%
  16359.  
  16360.  
  16361. %@CR:C6A00410003 @%
  16362. %@2@%%@CR:C6A00410004 @%%@AB@%VDMAD_Copy_From_Buffer%@AE@%%@EH@%%@NL@%
  16363. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16364.  
  16365.  
  16366. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16367.  
  16368. This service allows another device to copy data from the VDMAD buffer to the
  16369. actual DMA region associated with the buffer. This service is called after
  16370. %@AB@%VDMAD_Request_Buffer%@AE@%, after a memory write transfer and before
  16371. %@AB@%VDMAD_Release_Buffer%@AE@%.  %@NL@%
  16372.  
  16373.  
  16374. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16375.  
  16376. %@AB@%EBX%@AE@% = buffer ID %@AB@%ESI%@AE@% = region linear %@AB@%EDI %@AE@%= offset within buffer for start of
  16377. copy %@AB@%ECX%@AE@% = size  %@NL@%
  16378.  
  16379.  
  16380. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16381.  
  16382. Carry clear  data copied from buffer into DMA region Carry set  %@AB@%AL%@AE@% = 0Ah
  16383. (DMA_Invalid_Buffer) - invalid buffer  id supplied  = 0Bh
  16384. (DMA_Copy_Out_Range) - (%@AB@%ESI %@AE@%+ %@AB@%ECX%@AE@%) is  greater than buffer size  %@NL@%
  16385.  
  16386.  
  16387. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16388.  
  16389. Flags  %@NL@%
  16390.  
  16391. %@CR:C6A00410005 @%
  16392. %@2@%%@CR:C6A00410006 @%%@AB@%VDMAD_Copy_To_Buffer%@AE@%%@EH@%%@NL@%
  16393. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16394.  
  16395.  
  16396. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16397.  
  16398. This service allows another device to copy data into the VDMAD buffer from
  16399. the actual DMA region associated with the buffer.This service is called
  16400. after %@AB@%VDMAD_Request_Buffer%@AE@% and before starting a memory read transfer.  %@NL@%
  16401.  
  16402.  
  16403. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16404.  
  16405. %@AB@%EBX%@AE@% = buffer id %@AB@%ESI %@AE@% = region linear %@AB@%EDI %@AE@%= offset within buffer for start of
  16406. copy %@AB@%ECX%@AE@% = size  %@NL@%
  16407.  
  16408.  
  16409. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16410.  
  16411. Carry clear  data copied from DMA region into buffer Carry set  %@AB@%AL%@AE@% = 0Ah
  16412. (DMA_Invalid_Buffer) - invalid buffer  id supplied  = 0Bh
  16413. (DMA_Copy_Out_Range) - (%@AB@%ESI%@AE@% + %@AB@%ECX%@AE@%) is  greater than buffer size  %@NL@%
  16414.  
  16415.  
  16416. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16417.  
  16418. Flags  %@NL@%
  16419.  
  16420. %@CR:C6A00410007 @%
  16421. %@2@%%@CR:C6A00410008 @%%@AB@%VDMAD_Default_Handler%@AE@%%@EH@%%@NL@%
  16422. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16423.  
  16424.  
  16425. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16426.  
  16427. Default DMA channel I/O callback routine. This routine receives
  16428. notifications of virtual state changes and handles setting up the physical
  16429. state to start DMA transfers.  %@NL@%
  16430.  
  16431. %@AS@%  get virtual state
  16432. %@AS@%  If channel virtually unmasked then
  16433. %@AS@%      lock region
  16434. %@AS@%      If lock fails then
  16435. %@AS@%         request buffer
  16436. %@AS@%         If memory read operation then
  16437. %@AS@%             copy data to buffer
  16438. %@AS@%      set phyical state
  16439. %@AS@%      physically unmask channel%@AE@%
  16440.  
  16441.  
  16442. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16443.  
  16444. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  16445.  
  16446.  
  16447. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16448.  
  16449. None  %@NL@%
  16450.  
  16451.  
  16452. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16453.  
  16454. Anything  %@NL@%
  16455.  
  16456. %@CR:C6A00410009 @%
  16457. %@2@%%@CR:C6A00410010 @%%@AB@%VDMAD_Disable_Translation%@AE@%%@EH@%%@NL@%
  16458. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16459.  
  16460.  
  16461. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16462.  
  16463. This service disables the automatic translation done for the standard DMA
  16464. channels.It is necessary, if a V86 app or driver, or a PM app uses the DMA
  16465. services thru INT 4BH to determine actual physical addresses for DMA
  16466. transfers. A disable count is maintained, so a matching call to
  16467. %@AB@%VDMAD_Enable_Translation%@AE@% is required for each call to this service to
  16468. re-enable translation.  %@NL@%
  16469.  
  16470.  
  16471. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16472.  
  16473. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM Handle  %@NL@%
  16474.  
  16475.  
  16476. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16477.  
  16478. Carry clear   automatic translation is disable for the channel Carry set
  16479. the disable count overflowed  %@NL@%
  16480.  
  16481.  
  16482. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16483.  
  16484. Flags  %@NL@%
  16485.  
  16486. %@CR:C6A00410011 @%
  16487. %@2@%%@CR:C6A00410012 @%%@AB@%VDMAD_Enable_Translation%@AE@%%@EH@%%@NL@%
  16488. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16489.  
  16490.  
  16491. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16492.  
  16493. This decrements the disable count associated with a standard DMA channel. If
  16494. the disable count goes to 0, then automatic translation is re-enabled. See
  16495. %@AB@%VDMAD_Disable_Translation%@AE@% for further information.  %@NL@%
  16496.  
  16497.  
  16498. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16499.  
  16500. %@AB@%EAX %@AE@%= DMA handle %@AB@%EBX%@AE@% = VM Handle  %@NL@%
  16501.  
  16502.  
  16503. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16504.  
  16505. Carry clear   service completed successfully   Z-flag clear, if automatic
  16506. translation is re-enabled Carry set   attempt to enable when translation
  16507. already enabled  %@NL@%
  16508.  
  16509.  
  16510. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16511.  
  16512. Flags  %@NL@%
  16513.  
  16514. %@CR:C6A00410013 @%
  16515. %@2@%%@CR:C6A00410014 @%%@AB@%VDMAD_Get_EISA_Adr_Mode%@AE@%%@EH@%%@NL@%
  16516. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16517.  
  16518.  
  16519. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16520.  
  16521. Get EISA extended mode - the hardware doesn't allow for reading the extended
  16522. mode for a channel, so VDMAD defaults to the ISA defaults (channels 0-3 are
  16523. byte channels and 5-7 are word channels with word addresses and counts) An
  16524. INI switch can specify an alternate setting.  %@NL@%
  16525.  
  16526.  
  16527. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16528.  
  16529. %@AB@%EAX%@AE@% = Channel # (0..7) or  DMA Handle  %@NL@%
  16530.  
  16531.  
  16532. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16533.  
  16534. %@AB@%CL%@AE@% = 0 - 8-bit I/O, with count in bytes %@AB@%CL%@AE@% = 1 - 16-bit I/O, with count in
  16535. words and adr shifted %@AB@%CL%@AE@% = 2 - 32-bit I/O, with count in bytes %@AB@%CL%@AE@% = 3 -
  16536. 16-bit I/O, with count in bytes  %@NL@%
  16537.  
  16538.  
  16539. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16540.  
  16541. %@AB@%ECX%@AE@%, Flags  %@NL@%
  16542.  
  16543. %@CR:C6A00410015 @%
  16544. %@2@%%@CR:C6A00410016 @%%@AB@%VDMAD_Get_Region_Info%@AE@%%@EH@%%@NL@%
  16545. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16546.  
  16547.  
  16548. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16549.  
  16550. Get information about the current region assigned to a DMA handle. This
  16551. information can be used by a handler to call the following services:  %@NL@%
  16552.  
  16553.  
  16554.   ■   %@AB@%VDMAD_Unlock_DMA_Region%@AE@%%@NL@%
  16555.  
  16556.   ■   %@AB@%VDMAD_Release_Buffer%@AE@%%@NL@%
  16557.  
  16558.   ■   %@AB@%VDMAD_Copy_To_Buffer%@AE@%%@NL@%
  16559.  
  16560.   ■   %@AB@%VDMAD_Copy_From_Buffer%@AE@%%@NL@%
  16561.  
  16562.  
  16563.  
  16564. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16565.  
  16566. %@AB@%EAX%@AE@% = DMA handle  %@NL@%
  16567.  
  16568.  
  16569. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16570.  
  16571. %@AB@%BL %@AE@%= buffer id %@AB@%BH%@AE@% = pages locked (0 = FALSE, else TRUE) %@AB@%ESI %@AE@% = region linear
  16572. %@AB@%ECX%@AE@% = size in bytes  %@NL@%
  16573.  
  16574.  
  16575. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16576.  
  16577. %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%ESI%@AE@%  %@NL@%
  16578.  
  16579. %@CR:C6A00410017 @%
  16580. %@2@%%@CR:C6A00410018 @%%@AB@%VDMAD_Get_Version%@AE@%%@EH@%%@NL@%
  16581. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16582.  
  16583.  
  16584. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16585.  
  16586. Returns the version of the Virtual DMA Device  %@NL@%
  16587.  
  16588.  
  16589. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16590.  
  16591. None  %@NL@%
  16592.  
  16593.  
  16594. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16595.  
  16596. %@AB@%AH%@AE@% = Major version number %@AB@%AL%@AE@% = Minor version number %@AB@%ECX%@AE@% = Buffer size in
  16597. bytes (0, if not allocated; a buffer will always  be allocated, but it
  16598. doesn't happen until %@AB@%Device_Init%@AE@%) Carry flag clear  %@NL@%
  16599.  
  16600.  
  16601. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16602.  
  16603. %@AB@%EAX%@AE@%, Flags  %@NL@%
  16604.  
  16605. %@CR:C6A00410019 @%
  16606. %@2@%%@CR:C6A00410020 @%%@AB@%VDMAD_Get_Virt_State%@AE@%%@EH@%%@NL@%
  16607. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16608.  
  16609.  
  16610. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16611.  
  16612. This service allows a channel owner to determine the current virtual state
  16613. of the channel. The virtual state consists of all the information necessary
  16614. to physically program the DMA channel for a DMA transfer (linear address of
  16615. target region, byte length of region, mode of transfer, and state of mask
  16616. bit and software request bit) This state information reflects how the VM
  16617. thinks the hardware is currently programmed.  %@NL@%
  16618.  
  16619.  
  16620. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16621.  
  16622. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM handle  %@NL@%
  16623.  
  16624.  
  16625. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16626.  
  16627. If translation is enabled  %@AB@%ESI%@AE@% = high linear address of the user's DMA
  16628. region    (high linear is used so that the DMA can proceed    even if a
  16629. different VM is actually running at the    time of the transfer) Else  %@AB@%ESI%@AE@% =
  16630. physical byte address programmed (shifted left 1,    for word ports) %@AB@%ECX%@AE@% =
  16631. count in bytes %@AB@%DL%@AE@%= mode (same as 8042 mode byte with channel # removed
  16632. and DMA_masked & DMA_requested set as    appropriate:      DMA_masked
  16633. channel masked and not ready            for a transfer      DMA_requested
  16634. software request flag set) %@AB@%DH%@AE@%= extended mode (ignored on non-PS2 machines
  16635. that don't       have extended DMA capabilities)  %@NL@%
  16636.  
  16637.  
  16638. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16639.  
  16640. %@AB@%ESI%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, flags  %@NL@%
  16641.  
  16642. %@CR:C6A00410021 @%
  16643. %@2@%%@CR:C6A00410022 @%%@AB@%VDMAD_Lock_DMA_Region%@AE@%%@EH@%%@NL@%
  16644. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16645.  
  16646.  
  16647. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16648.  
  16649. This service attempts to lock a region of memory for a DMA transfer. It is
  16650. called before a DMA transfer is started (before the physical state is set
  16651. for a channel and before it is unmasked.)  %@NL@%
  16652.  
  16653. It first verifies that the region is mapped to contiguous pages of physical
  16654. memory.  %@NL@%
  16655.  
  16656. Then it determines whether the region will result in a DMA bank (page)  %@NL@%
  16657.  
  16658. wrap  %@NL@%
  16659.  
  16660. %@STUB@%    On AT(R) class machines each channel has a base address register and a
  16661.     page address register. The base address register is incremented after
  16662.     each byte or word transfered. If the increment of this 16 bit register
  16663.     results in the roll over from FFFFh to 0, then the transfer wraps to the
  16664.     start of the DMA bank because the page register is not updated. Normally
  16665.     MS-DOS watches for this condition and adjusts INT 13h parameters to
  16666.     split transfers to avoid this wrap, but MS-DOS doesn't know anything
  16667.     about the difference between linear and physical addresses under
  16668.     enhanced Windows, so VDMAD checks again to prevent wrap from occurring
  16669.     undesirably.%@NL@%
  16670.  
  16671. If all of these checks are okay, then the service calls the memory manager
  16672. to lock the physical pages.  %@NL@%
  16673.  
  16674. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16675. NOTE
  16676.  
  16677. %@AI@%This routine does not check to see if the region is within some physical
  16678. %@AI@%maximum constraint. If the region is lockable, then it locks the memory, and
  16679. %@AI@%it is up to the caller to check to see if the physical region is acceptable.
  16680. %@AI@%If the region is not acceptable, then the caller should unlock the region
  16681. %@AI@%and perform a buffered DMA transfer.%@AE@%
  16682. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16683.  
  16684.  
  16685. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16686.  
  16687. %@AB@%ESI %@AE@% = linear address of actual DMA region %@AB@%ECX%@AE@% = # of bytes in DMA region %@AB@%DL
  16688. %@AB@%%@AE@%  = 1b, if region must be aligned on 64K page boundary  = 10b, if region
  16689. must be aligned on 128K page boundary  %@NL@%
  16690.  
  16691.  
  16692. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16693.  
  16694. Carry set, if lock failed   %@AB@%ECX%@AE@% = # of bytes that are lockable in the region
  16695. (starting from ESI)   %@AB@%AL%@AE@% = 1 (DMA_Not_Contiguous), region not contiguous  =
  16696. 2 (DMA_Not_Aligned), region crossed physical  alignment boundary  = 3
  16697. (DMA_Lock_Failed), unable to lock pages ELSE  %@AB@%EDX%@AE@% = physical address of the
  16698. DMA region  the region has been locked  %@NL@%
  16699.  
  16700.  
  16701. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16702.  
  16703. %@AB@%EAX%@AE@%, %@AB@%ECX%@AE@%, %@AB@%EDX%@AE@%, Flags  %@NL@%
  16704.  
  16705. %@CR:C6A00410023 @%
  16706. %@2@%%@CR:C6A00410024 @%%@AB@%VDMAD_Mask_Channel%@AE@%%@EH@%%@NL@%
  16707. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16708.  
  16709.  
  16710. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16711.  
  16712. This service physically masks a channel so that it will not attempt any
  16713. further DMA transfers.  %@NL@%
  16714.  
  16715.  
  16716. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16717.  
  16718. %@AB@%EAX%@AE@% = DMA handle  %@NL@%
  16719.  
  16720.  
  16721. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16722.  
  16723. None  %@NL@%
  16724.  
  16725.  
  16726. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16727.  
  16728. Flags  %@NL@%
  16729.  
  16730. %@CR:C6A00410025 @%%@CR:C6A00410026 @%
  16731. %@2@%%@CR:C6A00410027 @%%@AB@%VDMAD_Release_Buffer%@AE@%%@EH@%%@NL@%
  16732. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16733.  
  16734.  
  16735. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16736.  
  16737. Release the VDMAD buffer assigned to a DMA channel from a previous
  16738. %@AB@%VDMAD_Request_Buffer%@AE@% call. This routine exits from a critical section and
  16739. the DMA buffer will now be available for other users. Any data in the buffer
  16740. is not automatically copied, so %@AB@%VDMAD_Copy_From_Buffer%@AE@% must be called if the
  16741. data is important.  %@NL@%
  16742.  
  16743.  
  16744. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16745.  
  16746. %@AB@%EBX%@AE@% = Buffer ID  %@NL@%
  16747.  
  16748.  
  16749. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16750.  
  16751. Carry clear  buffer released Carry set  bad ID  %@NL@%
  16752.  
  16753.  
  16754. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16755.  
  16756. Flags  %@NL@%
  16757.  
  16758. %@CR:C6A00410028 @%%@CR:C6A00410029 @%
  16759. %@2@%%@CR:C6A00410030 @%%@AB@%VDMAD_Request_Buffer%@AE@%%@EH@%%@NL@%
  16760. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16761.  
  16762.  
  16763. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16764.  
  16765. This service reserves the DMA buffer for a DMA transfer.  %@NL@%
  16766.  
  16767.  
  16768. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16769.  
  16770. %@AB@%ESI%@AE@% = linear address of actual DMA region %@AB@%ECX%@AE@% = # of bytes in DMA region  %@NL@%
  16771.  
  16772.  
  16773. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16774.  
  16775. Carry clear  %@AB@%EBX%@AE@% = buffer ID  %@AB@%EDX%@AE@% = the physical address of the buffer Carry
  16776. set  AL = 5 (DMA_Buffer_Too_Small), region request is  too large for buffer
  16777. = 6 (DMA_Buffer_In_Use), buffer already in use  %@NL@%
  16778.  
  16779.  
  16780. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16781.  
  16782. %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ESI%@AE@%, Flags  %@NL@%
  16783.  
  16784. %@CR:C6A00410031 @%
  16785. %@2@%%@CR:C6A00410032 @%%@AB@%VDMAD_Reserve_Buffer_Space%@AE@%%@EH@%%@NL@%
  16786. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16787.  
  16788.  
  16789. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16790.  
  16791. This service allows other devices that are going to handle DMA to make sure
  16792. that VDMAD allocates a buffer large enough for any transfers that they might
  16793. require. It also allows a device to specify a maximum physical address that
  16794. would be valid for the device's DMA requests (such as 1Mb for an XT.) During
  16795. the %@AB@%Device_Init%@AE@% phase of initialization, VDMAD will allocate the DMA buffer
  16796. using all of the contraints specified by other devices.i.e. the buffer will
  16797. be at least as big as the largest size specified by the calls to this
  16798. service, and it will be allocate below the lowest maximum physical addresses
  16799. specified.  %@NL@%
  16800.  
  16801. This service is only available during %@AB@%Sys_Critical_Init%@AE@%.  %@NL@%
  16802.  
  16803.  
  16804. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16805.  
  16806. %@AB@%EAX%@AE@% = # of pages requested %@AB@%ECX%@AE@% = maximum physical address that can be
  16807. included in a  DMA transfer; 0, if no limit.  %@NL@%
  16808.  
  16809.  
  16810. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16811.  
  16812. None  %@NL@%
  16813.  
  16814.  
  16815. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16816.  
  16817. Flags  %@NL@%
  16818.  
  16819. %@CR:C6A00410033 @%
  16820. %@2@%%@CR:C6A00410034 @%%@AB@%VDMAD_Scatter_Lock%@AE@%%@EH@%%@NL@%
  16821. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16822.  
  16823.  
  16824. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16825.  
  16826. This service attempts to lock all pages mapped to a DMA region and return
  16827. the actual physical addresses of the pages.  %@NL@%
  16828.  
  16829.  
  16830. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16831.  
  16832. %@AB@%EBX%@AE@% = VM Handle %@AB@%AL%@AE@% = 0, if the DDS table should be filled with physical
  16833. addresses and sizes of the physical regions that  make up the DMA region %@AB@%AL%@AE@%
  16834. = 1, if the DDS table should be filled with the actual  page table entries
  16835. %@AB@%AL%@AE@% = 3, if the DDS table should be filled with the actual  page table
  16836. entries and not present pages should not  be locked %@AB@%EDI%@AE@% -> extended DDS (DMA
  16837. Descriptor Structure)  %@NL@%
  16838.  
  16839.  
  16840. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16841.  
  16842. Carry clear  Z-flag set  whole region was locked successfully  Z-flag clear
  16843. partial region locked Carry set  nothing locked  %@AB@%EDX %@AE@%= # of table entries
  16844. needed to describe whole region DDS_size = # of bytes locked DDS table has
  16845. been updated if request was for page table copy (AL=1 OR 3), then  %@AB@%ESI%@AE@% =
  16846. offset into first page for start of the region  %@NL@%
  16847.  
  16848.  
  16849. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16850.  
  16851. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, Flags  %@NL@%
  16852.  
  16853. %@CR:C6A00410035 @%
  16854. %@2@%%@CR:C6A00410036 @%%@AB@%VDMAD_Scatter_Unlock%@AE@%%@EH@%%@NL@%
  16855. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16856.  
  16857.  
  16858. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16859.  
  16860. This service attempts to unlock all pages locked by a previous call to
  16861. %@AB@%VDMAD_Scatter_Lock%@AE@%  %@NL@%
  16862.  
  16863.  
  16864. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16865.  
  16866. %@AB@%EBX%@AE@% = VM Handle %@AB@%AL%@AE@% = 0, if the DDS table should be filled with physical
  16867. addresses and sizes of the physical regions that  make up the DMA region %@AB@%AL
  16868. %@AB@%%@AE@%= 1, if the DDS table should be filled with the actual  page table entries
  16869. %@AB@%AL %@AE@%= 3, if the DDS table should be filled with the actual  page table
  16870. entries and not present pages should not  be locked %@AB@%EDI%@AE@% -> extended DDS (DMA
  16871. Descriptor Structure)  (The table at the end of the DDS is not required, so
  16872. it is not necessary to maintain the table for this  unlock call.)  %@NL@%
  16873.  
  16874.  
  16875. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16876.  
  16877. Carry clear  Lock counts have been decremented. If no other VxD's  had pages
  16878. locked, then the pages have been unlocked. Carry set  The memory was not
  16879. locked.  %@NL@%
  16880.  
  16881.  
  16882. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16883.  
  16884. Flags  %@NL@%
  16885.  
  16886. %@CR:C6A00410037 @%
  16887. %@2@%%@CR:C6A00410038 @%%@AB@%VDMAD_Set_EISA_Adr_Mode%@AE@%%@EH@%%@NL@%
  16888. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16889.  
  16890.  
  16891. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16892.  
  16893. Set EISA extended mode  %@NL@%
  16894.  
  16895.  
  16896. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16897.  
  16898. %@AB@%EAX%@AE@% = Channel # (0..7) or  DMA Handle %@AB@%CL%@AE@% = 0 - 8-bit I/O, with count in
  16899. bytes %@AB@%CL%@AE@% = 1 - 16-bit I/O, with count in words and adr shifted %@AB@%CL%@AE@% = 2 -
  16900. 32-bit I/O, with count in bytes %@AB@%CL %@AE@%= 3 - 16-bit I/O, with count in bytes  %@NL@%
  16901.  
  16902.  
  16903. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16904.  
  16905. None  %@NL@%
  16906.  
  16907.  
  16908. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16909.  
  16910. Flags  %@NL@%
  16911.  
  16912. %@CR:C6A00410039 @%
  16913. %@2@%%@CR:C6A00410040 @%%@AB@%VDMAD_Set_Phys_State%@AE@%%@EH@%%@NL@%
  16914. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16915.  
  16916.  
  16917. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16918.  
  16919. This service programs the DMA controller state for a channel. All that it
  16920. needs to know is the desired mode. The location and size of the buffer is
  16921. taken from the information passed to the service %@AB@%VDMAD_Set_Region_Info%@AE@% which
  16922. must be called previously.  %@NL@%
  16923.  
  16924.  
  16925. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16926.  
  16927. %@AB@%EAX %@AE@%= DMA handle %@AB@%EBX %@AE@%= VM handle %@AB@%DL%@AE@% = mode %@AB@%DH %@AE@%= extended mode  %@NL@%
  16928.  
  16929.  
  16930. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16931.  
  16932. None  %@NL@%
  16933.  
  16934.  
  16935. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16936.  
  16937. Flags  %@NL@%
  16938.  
  16939. %@CR:C6A00410041 @%
  16940. %@2@%%@CR:C6A00410042 @%%@AB@%VDMAD_Set_Region_Info%@AE@%%@EH@%%@NL@%
  16941. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16942.  
  16943.  
  16944. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16945.  
  16946. Set information about the current region assigned to a DMA handle. This
  16947. service must be called before calling %@AB@%VDMAD_Set_Phys_State%@AE@%.  %@NL@%
  16948.  
  16949.  
  16950. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16951.  
  16952. %@AB@%EAX %@AE@%= DMA handle %@AB@%BL %@AE@%= buffer id %@AB@%BH %@AE@%= pages locked (0 = FALSE, else TRUE) %@AB@%ESI%@AE@%
  16953. = region linear %@AB@%ECX %@AE@%= size in bytes %@AB@%EDX%@AE@% = physical address for transfer  %@NL@%
  16954.  
  16955.  
  16956. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16957.  
  16958. None  %@NL@%
  16959.  
  16960.  
  16961. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16962.  
  16963. Flags  %@NL@%
  16964.  
  16965. %@CR:C6A00410043 @%
  16966. %@2@%%@CR:C6A00410044 @%%@AB@%VDMAD_Set_Virt_State%@AE@%%@EH@%%@NL@%
  16967. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16968.  
  16969.  
  16970. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  16971.  
  16972. Modify the virtual state of a DMA channel. This is service is used when a
  16973. channel owner wants to change the virtual state of a channel from how the VM
  16974. programmed it.This might be used to split a DMA request into smaller pieces,
  16975. etc.  %@NL@%
  16976.  
  16977.  
  16978. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  16979.  
  16980. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX%@AE@% = VM handle If translation is enabled  %@AB@%ESI%@AE@% = high
  16981. linear address of the user's DMA region  (high linear is used so that the
  16982. DMA can proceed  even if a different VM is actually running at the  time of
  16983. the transfer) Else  %@AB@%ESI%@AE@% = physical byte address programmed (shifted left 1,
  16984. for word ports) %@AB@%ECX%@AE@% = count in bytes %@AB@%DL%@AE@%= mode (same as 8042 mode byte with
  16985. channel # removed  and DMA_masked & DMA_requested set as  appropriate:
  16986. DMA_masked channel masked and not ready  for a transfer  DMA_requested
  16987. software request flag set) %@AB@%DH%@AE@%= extended mode (ignored on non-PS2 machines
  16988. that don't  have extended DMA capabilities)  %@NL@%
  16989.  
  16990.  
  16991. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  16992.  
  16993. None  %@NL@%
  16994.  
  16995.  
  16996. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  16997.  
  16998. Flags  %@NL@%
  16999.  
  17000. %@CR:C6A00410045 @%
  17001. %@2@%%@CR:C6A00410046 @%%@AB@%VDMAD_Unlock_DMA_Region%@AE@%%@EH@%%@NL@%
  17002. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17003.  
  17004.  
  17005. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17006.  
  17007. This service unlocks the DMA region previously locked to a channel. It is
  17008. called after a DMA transfer is complete and the channel has been masked. So
  17009. that the controller will not attempt any further transfers to the programmed
  17010. address.  %@NL@%
  17011.  
  17012.  
  17013. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17014.  
  17015. %@AB@%ESI%@AE@% = linear address of actual DMA region %@AB@%ECX%@AE@% = # of bytes in DMA region  %@NL@%
  17016.  
  17017.  
  17018. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17019.  
  17020. Carry clear    memory unlocked Carry set    error  %@NL@%
  17021.  
  17022.  
  17023. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17024.  
  17025. Flags  %@NL@%
  17026.  
  17027. %@CR:C6A00410047 @%
  17028. %@2@%%@CR:C6A00410048 @%%@AB@%VDMAD_UnMask_Channel%@AE@%%@EH@%%@NL@%
  17029. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17030.  
  17031.  
  17032. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17033.  
  17034. This service physically unmasks a channel so that DMA transfers can proceed.
  17035. %@NL@%
  17036.  
  17037.  
  17038. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17039.  
  17040. %@AB@%EAX%@AE@% = DMA handle %@AB@%EBX %@AE@%= VM Handle  %@NL@%
  17041.  
  17042.  
  17043. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17044.  
  17045. None  %@NL@%
  17046.  
  17047.  
  17048. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17049.  
  17050. Flags  %@NL@%
  17051.  
  17052. %@CR:C6A00410049 @%
  17053. %@2@%%@CR:C6A00410050 @%%@AB@%VDMAD_Virtualize_Channel%@AE@%%@EH@%%@NL@%
  17054. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17055.  
  17056.  
  17057. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17058.  
  17059. This service allows another VxD to claim ownership of a standard DMA
  17060. channel. The new owner registers a callback routine that will be called
  17061. whenever the virtual state of the channel is changed as a result of I/O done
  17062. in a VM. In some cases a device doesn't want to allow a VM to perform DMA to
  17063. a channel at all (they will handle programming based on a private API, etc.
  17064. instead of virtualized hardware I/O), so it is possible to pass a 0 to
  17065. specify a null callback routine. VDMAD will continue to trap the I/O for the
  17066. channel, but won't ever change the physical state of the channel as a result
  17067. of any VM I/O.  %@NL@%
  17068.  
  17069.  
  17070. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17071.  
  17072. %@AB@%EAX%@AE@% is Channel # %@AB@%ESI%@AE@% is I/O Callback procedure (0 = none)  %@NL@%
  17073.  
  17074.  
  17075. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17076.  
  17077. Carry set if channel is already owned ELSE  %@AB@%EAX%@AE@% is DMA handle  %@NL@%
  17078.  
  17079.  
  17080. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17081.  
  17082. Flags  %@NL@%
  17083.  
  17084.  
  17085. %@3@%%@AB@%Callback%@AE@%%@EH@%%@NL@%
  17086.  
  17087. ENTRY   %@AB@%EAX%@AE@% = DMA handle   %@AB@%EBX%@AE@% = VM handle   Proc can modify %@AB@%EAX%@AE@%, %@AB@%EBX%@AE@%, %@AB@%ECX%@AE@%,
  17088. %@AB@%EDX%@AE@%, %@AB@%ESI%@AE@%, %@AB@%EDI%@AE@%, and flags  EXIT   None  %@NL@%
  17089.  
  17090.  
  17091.  
  17092.  
  17093.  
  17094.  
  17095. %@CR:C6A00420001 @%%@1@%%@AB@%Chapter 42  Virtual DOSNET Device Services%@AE@%%@EH@%%@NL@%
  17096. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17097.  
  17098. The DOSNET device manages the network drives. To do so, it has a service
  17099. (%@AB@%DOSNET_Do_PSP_Adjust%@AE@%) that enables it to indicate that the network server
  17100. uses PSP addresses to identify tasks uniquely. Therefore, each VM's address
  17101. space should start at a unique address. It has another service
  17102. (%@AB@%DOSNET_Send_FILESYSCHANGE%@AE@%) that enables the Shell to determine whether or
  17103. not a particular drive is redirected in the System VM. These services are
  17104. required when network software is loaded with Windows in 386 enhanced mode.
  17105. %@NL@%
  17106.  
  17107.  
  17108. %@2@%%@CR:C6A00420002 @%%@AB@%DOSNET_Get_Version%@CR:C6A00420003 @%%@AE@%%@EH@%%@NL@%
  17109. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17110.  
  17111.  
  17112. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17113.  
  17114. This service returns the DOSNET device version.  %@NL@%
  17115.  
  17116.  
  17117. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17118.  
  17119. None  %@NL@%
  17120.  
  17121.  
  17122. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17123.  
  17124. %@AB@%EAX%@AE@% = Version, Major in %@AB@%AH%@AE@%, Minor in %@AB@%AL%@AE@% Carry clear  %@NL@%
  17125.  
  17126.  
  17127. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17128.  
  17129. Flags, %@AB@%EAX%@AE@%  %@NL@%
  17130.  
  17131. %@CR:C6A00420004 @%
  17132. %@2@%%@CR:C6A00420005 @%%@AB@%DOSNET_Do_PSP_Adjust%@AE@%%@EH@%%@NL@%
  17133. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17134.  
  17135.  
  17136. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17137.  
  17138. This service enables the DOSMGR device to ask whether or not it should
  17139. perform adjustments to try to give each VM in the system a different
  17140. starting MS-DOS PSP address. This needs to be done on networks (such as
  17141. MSNET) that use the PSP address as part of an ID to identify uniquely
  17142. different processes talking to the server (this effects the behavior of DOS
  17143. SHARE on the server end). On a network that uses MS-DOS PSP addresses as
  17144. part of an ID, enhanced Windows can cause the ID to be non-unique since
  17145. there are now multiple VMs that can all have an application in them that has
  17146. the same PSP address. If the PSP adjust is enabled by this service, the
  17147. DOSMGR device causes each VM to start at a different paragraph address (VMID
  17148. is the basis of the adjustment value) and thus have a different PSP address.
  17149. This has the cost of wasting some memory and the benefit of making the PSP
  17150. addresses different in all the VMs.  %@NL@%
  17151.  
  17152. For a network that does not use MS-DOS PSP addresses for anything, or for
  17153. one that is enhanced-Windows aware and uses the %@AB@%Get_VMID%@AE@% INT 2F service of
  17154. enhanced Windows to deal with this problem, a return of Carry SET, %@AB@%EAX%@AE@%  0 is
  17155. appropriate.  %@NL@%
  17156.  
  17157. Notice that the uniqueness of PSPs is not guaranteed by this. It will deal
  17158. with the case on most configurations, but on some it will not. The only
  17159. absolutely correct solution is to make the network software enhanced-Windows
  17160. aware and work the VMID into the network ID, in addition to the PSP address,
  17161. by using the %@AB@%Get_VMID%@AE@% INT 2F service of enhanced Windows.  %@NL@%
  17162.  
  17163.  
  17164. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17165.  
  17166. None  %@NL@%
  17167.  
  17168.  
  17169. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17170.  
  17171. Carry Set  Do %@AI@%not%@AE@% do PSP adjustment  %@AB@% EAX%@AE@% == 0 if SYSTEM.INI override of
  17172. this is allowed  %@AB@%EAX%@AE@%  0 if SYSTEM.INI override of this is %@AI@%not%@AE@% allowed Carry
  17173. Clear  DO PSP adjustment  %@AB@%EAX%@AE@% == 0 if SYSTEM.INI override of this is allowed
  17174. %@AB@%EAX %@AE@%0 if SYSTEM.INI override of this is %@AI@%not%@AE@% allowed  %@NL@%
  17175.  
  17176. Notice that the behavior of DOSMGR, if the DOSNET device is not loaded, is a
  17177. return of carry Set, %@AB@%EAX %@AE@%= 0.  %@NL@%
  17178.  
  17179.  
  17180. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17181.  
  17182. Flags, %@AB@%EAX%@AE@%  %@NL@%
  17183.  
  17184. %@CR:C6A00420006 @%
  17185. %@2@%%@CR:C6A00420007 @%%@AB@%DOSNET_Send_FILESYSCHANGE%@AE@%%@EH@%%@NL@%
  17186. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17187.  
  17188.  
  17189. %@3@%%@AB@%Description%@AE@%%@EH@%%@NL@%
  17190.  
  17191. It is incorrect to send the WM_FILESYSCHANGE message to the Windows Shell on
  17192. drives about which Windows knows nothing. This routine tells the caller
  17193. whether this is a "local to this VM" drive or not. The message enables
  17194. Windows applications to be told when a change is made to the file volume
  17195. name space so that they can update portions of their display that may be
  17196. showing that part of the file volume.  %@NL@%
  17197.  
  17198. Sending a WM_FILESYSCHANGE message on a drive incorrectly can result in all
  17199. sorts of misbehavior. If the indicated drive letter is invalid in the System
  17200. VM, the Windows application may get an error that it is not expecting. If
  17201. the indicated drive letter actually maps a different file system volume in
  17202. the System VM, all sorts of other unexpected errors may occur.  %@NL@%
  17203.  
  17204. Notice that this is a DOSNET device service and cannot be implemented
  17205. directly in another VxD. Another VxD that also wishes to effect the
  17206. WM_FILESYSCHANGE behavior must hook this service. Notice also that the
  17207. DOSNET device does not install if there is no REDIR, so a VxD that wants to
  17208. hook this service must ship with a modified DOSNET device that always loads
  17209. (i.e., with the real-mode init code removed).  %@NL@%
  17210.  
  17211.  
  17212. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  17213.  
  17214. %@AB@%EAX%@AE@% (AL) = Drive number (0 = A) %@AB@%EBX%@AE@% is VM Handle of VM involved  %@NL@%
  17215.  
  17216.  
  17217. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  17218.  
  17219. Carry Set  WM_FILESYSCHANGE should %@AI@%not%@AE@% be sent on this drive Carry Clear
  17220. WM_FILESYSCHANGE %@AI@%should%@AE@% be sent on this drive  %@NL@%
  17221.  
  17222.  
  17223. %@3@%%@AB@%Uses%@AE@%%@EH@%%@NL@%
  17224.  
  17225. Flags  %@NL@%
  17226.  
  17227.  
  17228.  
  17229.  
  17230.  
  17231.  
  17232. %@CR:C6A-A0001   @%%@1@%%@AB@%Appendix A  Appendix A Terms and Acronyms%@AE@%%@EH@%%@NL@%
  17233. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17234.  
  17235. The following list explains the terms and acronyms that are found in the
  17236. %@AI@%Microsoft Windows Device Development Kit%@AE@% for Windows 3.0.  %@NL@%
  17237.  
  17238. %@2@%%@AB@%Banding%@AE@%%@EH@%%@NL@%
  17239. %@3@%The process of dividing a display surface such as a page into smaller%@EH@%
  17240. horizontal rectangles, composing those individual bands within memory, and
  17241. then sending the output to the printer one band at a time.%@NL@%
  17242.  
  17243. %@2@%%@AB@%Clipping%@AE@%%@EH@%%@NL@%
  17244. %@3@%The process of removing any portion of a graphic image that extends beyond a%@EH@%
  17245. specified boundary.%@NL@%
  17246.  
  17247. %@2@%%@AB@%Control Block%@AE@%%@EH@%%@NL@%
  17248. %@3@%A per Virtual Machine data structure in which Virtual Devices and the%@EH@%
  17249. Virtual Machine Manager can maintain the VM's state information. The control
  17250. block shares the flat segment with the VMM and VxDs. It is pointed to by the
  17251. VM Handle.%@NL@%
  17252.  
  17253. %@2@%%@AB@%Control Panel%@AE@%%@EH@%%@NL@%
  17254. %@3@%A Windows application that lets you change system settings, including%@EH@%
  17255. printer assignments and system characteristics.%@NL@%
  17256.  
  17257. %@2@%%@AB@%Descriptor Table%@AE@%%@EH@%%@NL@%
  17258. %@3@%An array of segment descriptors. There are two kinds of descriptor tables:%@EH@%
  17259. the unique Global Descriptor Table, and the per-VM Local Descriptor Table.%@NL@%
  17260.  
  17261. %@2@%%@AB@%Device Driver%@AE@%%@EH@%%@NL@%
  17262. %@3@%The dynamic-link library that provides the hardware-dependent, low-level%@EH@%
  17263. interface between Windows GDI functions and the graphics output device.%@NL@%
  17264.  
  17265. %@2@%%@AB@%Device Independent Bitmap (DIB)%@AE@%%@EH@%%@NL@%
  17266. %@3@%A bitmap format that can be interpreted and converted by a device driver%@EH@%
  17267. into its own specific format. It is called "device independent" because any
  17268. driver capable of using DIBs can display (or otherwise use) the DIB to the
  17269. best of its ability.%@NL@%
  17270.  
  17271. %@2@%%@AB@%Direct Memory Access (DMA) %@AE@%%@EH@%%@NL@%
  17272. %@3@%An accelerated memory access technique that enables peripheral devices to%@EH@%
  17273. take control of the bus. See also Virtual DMA Services (VDS).%@NL@%
  17274.  
  17275. %@2@%%@AB@%DOS Protected Mode Interface (DPMI) %@AE@%%@EH@%%@NL@%
  17276. %@3@%The industry standard for non-Windows applications using protected mode. It%@EH@%
  17277. is available from Intel at 1-800-548-4725.%@NL@%
  17278.  
  17279. %@2@%%@AB@%Dynamic Data Exchange (DDE)%@AE@%%@EH@%%@NL@%
  17280. %@3@%A protocol that cooperating programs can use to exchange data without user%@EH@%
  17281. intervention.%@NL@%
  17282.  
  17283. %@2@%%@AB@%Dynamic-Link Library (DLL) %@AE@%%@EH@%%@NL@%
  17284. %@3@%An executable module that contains functions available to applications and%@EH@%
  17285. that is linked at run time, rather than at link time.%@NL@%
  17286.  
  17287. %@2@%%@AB@%Enhanced Windows%@AE@%%@EH@%%@NL@%
  17288. %@3@%Windows 3.0 when running in 386 enhanced mode.%@NL@%%@EH@%
  17289.  
  17290. %@2@%%@AB@%Escape%@AE@%%@EH@%%@NL@%
  17291. %@3@%A device-dependent operation that is not supported by the device-independent%@EH@%
  17292. GDI module. The entry point in the device driver is called %@AB@%Control()%@AE@%; in GDI
  17293. (i.e., to the application), it is called %@AB@%Escape()%@AE@%.%@NL@%
  17294.  
  17295. %@2@%%@AB@%Extended Memory Specification (XMS)%@AE@%%@EH@%%@NL@%
  17296. %@3@%The XMS driver provides an API for managing extended memory. Windows uses%@EH@%
  17297. XMS to load its code and data into extended memory.%@NL@%
  17298.  
  17299. %@2@%%@AB@%Flat Model%@AE@%%@EH@%%@NL@%
  17300. %@3@%A memory organization in which there is only one segment.%@NL@%%@EH@%
  17301.  
  17302. %@2@%%@AB@%Font Resource%@AE@%%@EH@%%@NL@%
  17303. %@3@%A group of individual fonts that have various combinations of heights,%@EH@%
  17304. widths, and pitches.%@NL@%
  17305.  
  17306. %@2@%%@AB@%GDI Library%@AE@%%@EH@%%@NL@%
  17307. %@3@%A set of supporting functions for device drivers. These utilities include%@EH@%
  17308. versions of output functions such as %@AB@%BitBlt%@AE@% and %@AB@%StrBlt%@AE@%, a Transpose function
  17309. for banding devices, and priority queue functions for daisywheel printers.%@NL@%
  17310.  
  17311. %@2@%%@AB@%Global Descriptor Table (GDT)%@AE@%%@EH@%%@NL@%
  17312. %@3@%See Descriptor Table.%@NL@%%@EH@%
  17313.  
  17314. %@2@%%@AB@%Graphics Device Interface (GDI)%@AE@%%@EH@%%@NL@%
  17315. %@3@%A device-independent, high-level graphics manager. GDI provides the%@EH@%
  17316. interface that feeds graphics commands from Windows application programs to
  17317. the device driver.%@NL@%
  17318.  
  17319. %@2@%%@AB@%IOPM%@AE@%%@EH@%%@NL@%
  17320. %@3@%I/O Permission Map%@NL@%%@EH@%
  17321.  
  17322. %@2@%%@AB@%Local Descriptor Table (LDT)%@AE@%%@EH@%%@NL@%
  17323. %@3@%See Descriptor Table.%@NL@%%@EH@%
  17324.  
  17325. %@2@%%@AB@%Metafile%@AE@%%@EH@%%@NL@%
  17326. %@3@%A collection of GDI function calls stored in a binary coded form and used to%@EH@%
  17327. transfer device-independent pictures between programs.%@NL@%
  17328.  
  17329. %@2@%%@AB@%Microsoft Macro Assembler (MASM)%@AE@%%@EH@%%@NL@%
  17330. %@3@%An assembly language compiler.%@NL@%%@EH@%
  17331.  
  17332. %@2@%%@AB@%Non-Windows Application%@AE@%%@EH@%%@NL@%
  17333. %@3@%A program that does not make use of the Windows environment. Instead, it%@EH@%
  17334. calls MS-DOS and the BIOS, and accesses the hardware directly.%@NL@%
  17335.  
  17336. %@2@%%@AB@%Page%@AE@%%@EH@%%@NL@%
  17337. %@3@%A 4K block of contiguous memory locations.%@NL@%%@EH@%
  17338.  
  17339. %@2@%%@AB@%Paging%@AE@%%@EH@%%@NL@%
  17340. %@3@%A memory-management technique used by enhanced Windows to support virtual%@EH@%
  17341. memory. It simulates a large, unsegmented address space by using a small,
  17342. fragmented address space and some disk storage. Paging accomplishes this by
  17343. keeping the available memory space partly in memory and partly on disk.%@NL@%
  17344.  
  17345. %@2@%%@AB@%Palette%@AE@%%@EH@%%@NL@%
  17346. %@3@%The range of colors that the video adapter can display and manage.%@NL@%%@EH@%
  17347.  
  17348. %@2@%%@AB@%Pixel%@AE@%%@EH@%%@NL@%
  17349. %@3@%The smallest element of a physical display surface that can be independently%@EH@%
  17350. assigned color or intensity.%@NL@%
  17351.  
  17352. %@2@%%@AB@%Pixel Array%@AE@%%@EH@%%@NL@%
  17353. %@3@%A matrix of pixels that defines the color for a region on an actual display.%@EH@%
  17354. There is exactly one pixel definition for each addressable picture element
  17355. of a raster display covered by the pixel array.%@NL@%
  17356.  
  17357. %@2@%%@AB@%Primitive%@AE@%%@EH@%%@NL@%
  17358. %@3@%A basic graphic function to be performed.%@NL@%%@EH@%
  17359.  
  17360. %@2@%%@AB@%Print Manager%@AE@%%@EH@%%@NL@%
  17361. %@3@%The Windows utility that prints files without suspending the operation of%@EH@%
  17362. other programs. It also enables you to change the priority of print jobs or
  17363. to cancel them.%@NL@%
  17364.  
  17365. %@2@%%@AB@%Printer Command Language (PCL)%@AE@%%@EH@%%@NL@%
  17366. %@3@%The language used by Hewlett-Packard (R) Laserjet (R) and compatible%@EH@%
  17367. printers.%@NL@%
  17368.  
  17369. %@2@%%@AB@%Privilege Rings%@AE@%%@EH@%%@NL@%
  17370. %@3@%The protection value applied to segments and segment selectors. Enhanced%@EH@%
  17371. Windows uses the most privileged level (ring 0) for the VMM and VxDs. Code
  17372. and data for applications running in virtual-86 mode use the least
  17373. privileged level (ring 3). Protected-mode applications run in rings 1, 2, or
  17374. 3.%@NL@%
  17375.  
  17376. %@2@%%@AB@%Protected Mode (PM)%@AE@%%@EH@%%@NL@%
  17377. %@3@%A mode of the 80386 and 80486 processors that provides, among other%@EH@%
  17378. capabilities, arbitrary mapping of segment register values to physical
  17379. memory. See Appendix B, "Understanding Modes," for a detailed description.
  17380. Applications that want to use protected mode must conform to the DPMI
  17381. specification.%@NL@%
  17382.  
  17383. %@2@%%@AB@%Raster Device%@AE@%%@EH@%%@NL@%
  17384. %@3@%A device that uses a matrix of pixels covering the entire screen or page%@EH@%
  17385. area (display or printed surface) to draw graphics. Pixels (points) are
  17386. turned on and off, bit-by-bit.%@NL@%
  17387.  
  17388. %@2@%%@AB@%Real Mode%@AE@%%@EH@%%@NL@%
  17389. %@3@%An execution mode of an Intel processor that functions as an 8086; also%@EH@%
  17390. called "real-address mode." The 80286, 80386, and 80486 processors run in
  17391. this mode when started up. See also Appendix B, "Understanding Modes."%@NL@%
  17392.  
  17393. %@2@%%@AB@%Red, Green, Blue (RGB)%@AE@%%@EH@%%@NL@%
  17394. %@3@%Values from a color table. This color table is used in mapping from a color%@EH@%
  17395. index to corresponding color values.%@NL@%
  17396.  
  17397. %@2@%%@AB@%Resolution%@AE@%%@EH@%%@NL@%
  17398. %@3@%The number of visibly distinct dots that can be displayed in a given area of%@EH@%
  17399. the screen. Typical resolution is 100 dots per inch.%@NL@%
  17400.  
  17401. %@2@%%@AB@%Scaling%@AE@%%@EH@%%@NL@%
  17402. %@3@%Coordinate scaling transforms points from one level to another. GDI scales%@EH@%
  17403. coordinates from NDC space to values appropriate for your graphics device.%@NL@%
  17404.  
  17405. %@2@%%@AB@%%@AB@%SETUP.INF%@AE@%%@AE@%%@EH@%%@NL@%
  17406. %@3@%A file containing all the information needed to set up a device driver for%@EH@%
  17407. Windows. See also Appendix C, "Creating Distribution Disks for Drivers."%@NL@%
  17408.  
  17409. %@2@%%@AB@%%@AB@%SYSTEM.INI%@AE@%%@AE@%%@EH@%%@NL@%
  17410. %@3@%A file in the Windows directory that holds the Windows configuration%@EH@%
  17411. information that is used when starting up Windows. It differs from WIN.INI,
  17412. which is mainly for storing user preferences, by containing hardware and
  17413. software descriptions.%@NL@%
  17414.  
  17415. %@2@%%@AB@%System VM%@AE@%%@EH@%%@NL@%
  17416. %@3@%The first Virtual Machine (VM) under enhanced Windows. The VM in which%@EH@%
  17417. Windows runs.%@NL@%
  17418.  
  17419. %@2@%%@AB@%Task%@AE@%%@EH@%%@NL@%
  17420. %@3@%A program that is running or waiting to run.%@NL@%%@EH@%
  17421.  
  17422. %@2@%%@AB@%Task Switch%@AE@%%@EH@%%@NL@%
  17423. %@3@%A transfer of execution between tasks (i.e., a context switch). Unlike%@EH@%
  17424. procedure calls, which saves only the contents of the general registers, a
  17425. task switch saves most of the processor state. For example, the registers
  17426. used for address translation are reloaded, so that each task can have a
  17427. different logical-to-physical address mapping.%@NL@%
  17428.  
  17429. %@2@%%@AB@%TSRs%@AE@%%@EH@%%@NL@%
  17430. %@3@%Terminate-and-Stay Resident applications.%@NL@%%@EH@%
  17431.  
  17432. %@2@%%@AB@%VCD%@AE@%%@EH@%%@NL@%
  17433. %@3@%Virtual Comm Device%@NL@%%@EH@%
  17434.  
  17435. %@2@%%@AB@%VDD%@AE@%%@EH@%%@NL@%
  17436. %@3@%Virtual Display Device%@NL@%%@EH@%
  17437.  
  17438. %@2@%%@AB@%VDMAD%@AE@%%@EH@%%@NL@%
  17439. %@3@%Virtual DMA Device%@NL@%%@EH@%
  17440.  
  17441. %@2@%%@AB@%VFD%@AE@%%@EH@%%@NL@%
  17442. %@3@%Virtual Floppy Drive Device%@NL@%%@EH@%
  17443.  
  17444. %@2@%%@AB@%VHD%@AE@%%@EH@%%@NL@%
  17445. %@3@%Virtual Hard Disk Device%@NL@%%@EH@%
  17446.  
  17447. %@2@%%@AB@%VKD%@AE@%%@EH@%%@NL@%
  17448. %@3@%Virtual Keyboard Device%@NL@%%@EH@%
  17449.  
  17450. %@2@%%@AB@%VMD%@AE@%%@EH@%%@NL@%
  17451. %@3@%Virtual Mouse Device%@NL@%%@EH@%
  17452.  
  17453. %@2@%%@AB@%VPD%@AE@%%@EH@%%@NL@%
  17454. %@3@%Virtual Printer Device%@NL@%%@EH@%
  17455.  
  17456. %@2@%%@AB@%VPICD%@AE@%%@EH@%%@NL@%
  17457. %@3@%Virtual Programmable Interrupt Controller Device%@NL@%%@EH@%
  17458.  
  17459. %@2@%%@AB@%Vector Device%@AE@%%@EH@%%@NL@%
  17460. %@3@%A device that draws graphics with lines. Beginning and ending points are set%@EH@%
  17461. and a line is drawn between them.%@NL@%
  17462.  
  17463. %@2@%%@AB@%Virtual 8086 mode (V86)%@AE@%%@EH@%%@NL@%
  17464. %@3@%A mode of the 80386 processor by which the 80386 emulates the function of%@EH@%
  17465. the 8086 processor. In this mode, each segment has a linear address limit of
  17466. 64K, and the applications can address a total of 1M + 64K - 16 bytes.
  17467. Software running in V86 mode, however, can use the 80386's 32-bit registers.%@NL@%
  17468.  
  17469. %@2@%%@AB@%Virtual DMA Device (VDMAD) %@AE@%%@EH@%%@NL@%
  17470. %@3@%The VDMAD is the Windows virtual device that supports standard DMA devices%@EH@%
  17471. on ISA machines as well as the VDS API for non-ISA devices.%@NL@%
  17472.  
  17473. %@2@%%@AB@%Virtual DMA Services (VDS) %@AE@%%@EH@%%@NL@%
  17474. %@3@%The VDS specification describes how an MS-DOS DMA device driver can perform%@EH@%
  17475. DMA. VxD authors should use the services of the VDMAD rather than work
  17476. directly from this specification.%@NL@%
  17477.  
  17478. %@2@%%@AB@%Virtual "x" Device (VxD)%@AE@%%@EH@%%@NL@%
  17479. %@3@%The name of the device virtualized replaces the "x" in this name. There must%@EH@%
  17480. be a VxD for each piece of hardware that can have a different state in each
  17481. of the VMs. Any piece of hardware that does not have an associated VxD is
  17482. global. It must handle interleaved access from multiple VMs or have a global
  17483. piece of software (such as a DOS device driver or TSR) that serializes
  17484. access to the hardware. All the VxDs run in the same, flat-model, 32-bit
  17485. segment as the rest of the VMM. A VxD can also provide services that are not
  17486. directly associated with a piece of hardware (e.g., a piece of code that
  17487. replaces an MS-DOS or BIOS service).%@NL@%
  17488.  
  17489. %@2@%%@AB@%Virtual Machine (VM)%@AE@%%@EH@%%@NL@%
  17490. %@3@%The part of the enhanced Windows environment in which Windows and%@EH@%
  17491. non-Windows applications execute. A VM consists of all the resources
  17492. (physical and/or virtualized) available to the application, plus the state
  17493. of the application. The state of the application includes the memory, the
  17494. processor state, and the state of the VMM and VxDs as maintained in the VM
  17495. control block.%@NL@%
  17496.  
  17497. %@2@%%@AB@%Virtual Machine Manager (VMM)%@AE@%%@EH@%%@NL@%
  17498. %@3@%The core of enhanced Windows. It runs, along with all the VxDs, in one,%@EH@%
  17499. flat-model, 32-bit segment.%@NL@%
  17500.  
  17501. %@2@%%@AB@%Virtual Memory%@AE@%%@EH@%%@NL@%
  17502. %@3@%Memory that an application can access that is greater than the actual%@EH@%
  17503. physical memory present. To support this, enhanced Windows transparently
  17504. pages 4K memory blocks to and from physical memory on behalf of the
  17505. applications. %@NL@%
  17506.  
  17507. %@2@%%@AB@%WDEB386%@AE@%%@EH@%%@NL@%
  17508. %@3@%A Windows 3.0 debugger program that can be used in protected mode with%@EH@%
  17509. either an 80286, 80386, or 80486 processor.%@NL@%
  17510.  
  17511. %@2@%%@AB@%Window%@AE@%%@EH@%%@NL@%
  17512. %@3@%A rectangular region on a display screen in which the system displays the%@EH@%
  17513. contents of an application.%@NL@%
  17514.  
  17515. %@2@%%@AB@%Windows Application%@AE@%%@EH@%%@NL@%
  17516. %@3@%Any program that has been specifically designed to run under Microsoft%@EH@%
  17517. Windows.%@NL@%
  17518.  
  17519. %@2@%%@AB@%WIN.INI%@AE@%%@EH@%%@NL@%
  17520. %@3@%The Windows initialization file in which you maintain the system-wide%@EH@%
  17521. settings for user preferences. The SYSTEM.INI file contains the hardware and
  17522. software descriptions. WIN.INI is a text-based file that resides in the
  17523. Windows software directory.%@NL@%
  17524.  
  17525. %@2@%%@AB@%XMS%@AE@%%@EH@%%@NL@%
  17526. %@3@%See Extended Memory Specification. %@NL@%%@EH@%
  17527.  
  17528.  
  17529.  
  17530.  
  17531.  
  17532.  
  17533. %@CR:C6A-B0001   @%%@1@%%@AB@%Appendix B  Understanding Modes%@AE@%%@EH@%%@NL@%
  17534. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17535.  
  17536. Microsoft Windows 3.0 documentation uses the term "mode" in overlapping
  17537. ways. This appendix is provided to clarify the different uses.  %@NL@%
  17538.  
  17539.  
  17540. %@2@%%@CR:C6A-B0002   @%%@AB@%B.1  Windows Modes%@AE@%%@EH@%%@NL@%
  17541.  
  17542. To provide the greatest features for the available hardware, Windows 3.0 can
  17543. run in three software modes: real, standard, or 386 enhanced. The following
  17544. table compares the memory models and required microprocessor for each of
  17545. these Windows modes.%@CR:C6A-B0003   @%%@NL@%
  17546.  
  17547. %@TH:  15   715 02 13 11 15 37 @%Windows 3.0  Real Mode  Standard Mode  386 Enhanced Mode%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%Supported    Real Mode  Real Mode      Real Mode  Memory                  Protected      Protected Mode (32-bit) Model                  Mode (16-bit)   V86 Mode%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%Required     8086                      Hardware      80286      80286          80386              80386      80386          80486              80486      80486         %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@TE:  15   715 02 13 11 15 37 @%
  17548.  
  17549.  
  17550. %@2@%%@CR:C6A-B0004   @%%@AB@%B.2  Microprocessor Modes%@AE@%%@EH@%%@NL@%
  17551.  
  17552. As the Intel microprocessors evolved greater capabilities, they continued to
  17553. support the programs and operating systems of the earlier architectures. As
  17554. a result, the 80386 has no fewer than four modes. Each is compared below to
  17555. the earlier architectures.  %@NL@%
  17556.  
  17557. The first is the familiar %@AI@%real mode%@AE@%, wherein the 80386 functions as a fast
  17558. 8086/88-compatible processor with some bonus opcodes. Like the 80286, the
  17559. 80386 always powers up in real mode and can, therefore, run any existing
  17560. 8086 operating systems and software.%@CR:C6A-B0005   @%%@NL@%
  17561.  
  17562. In %@AI@%protected mode%@AE@%, the 80386 can take on two different personalities. It can
  17563. execute a logical superset of the 80286 protected-mode instructions and run
  17564. 16-bit programs. Or, while in its native protected mode, it can use 32-bit
  17565. instructions, registers, and stacks and can allow individual memory segments
  17566. as large as 4GB. The native protected mode also has an additional level of
  17567. address translation─supported in hardware by page tables─that allows much
  17568. greater flexibility in mapping the linear address onto physical memory. In
  17569. either protected mode, the 80386 translates selectors and offsets to linear
  17570. addresses using descriptor tables in much the same manner as the 80286.%@CR:C6A-B0006   @%%@NL@%
  17571.  
  17572. The forth operating mode, %@AI@%virtual 86 mode%@AE@% (V86), provides another form of
  17573. 8086 emulation. But now, instead of a single program running in a single
  17574. memory partition, the 80386 can create multiple partitions, each capable of
  17575. running a real-mode program. Each partition has its own address space, I/O
  17576. port space, and interrupt vector table. Enhanced Windows uses the V86-mode
  17577. partitions to create virtual machines, the fundamental components in its
  17578. virtual machine architecture. The architecture is described in Chapter 16,
  17579. "Overview of Windows in 386 Enhanced Mode."%@CR:C6A-B0007   @%%@NL@%
  17580.  
  17581. The following table summarizes the four modes of the 80386 microprocessor:  %@NL@%
  17582.  
  17583. %@TH:  18   963 02 40 40 @%Mode                                    Description%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%Real Mode                               Functions as a very fast                                         8086/88-compatible processor.Protected Mode (16-bit)                 Functions in protected mode as an                                         enhanced 286 processor.Protected Mode (32-bit, native mode)    Functions in protected mode using full                                        32-bit instructions, registers, and                                         stacks.Virtual 86 Mode                         Runs multiple, protected, virtual 8086                                        machines, each with its own 1MB of                                         memory space.%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@TE:  18   963 02 40 40 @%
  17584.  
  17585.  
  17586.  
  17587.  
  17588.  
  17589.  
  17590. %@CR:C6A-C0001   @%%@1@%%@AB@%Appendix C  Creating Distribution Disks for Drivers%@AE@%%@EH@%%@NL@%
  17591. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17592.  
  17593. Once you have developed your device driver and/or virtual device, you must
  17594. create a distribution disk for installing it into the user's Windows
  17595. environment.  %@NL@%
  17596.  
  17597. In Windows 3.0, we have included two Windows utilities (i.e., Setup and
  17598. Control Panel) that make installing device drivers and virtual devices that
  17599. are not available in the retail product much easier for the user. These
  17600. utilities do this by using the data stored in the Information (.INF) file
  17601. that is provided in the Windows retail product.  %@NL@%
  17602.  
  17603. This appendix provides information on the following topics:  %@NL@%
  17604.  
  17605.  
  17606.   ■   How Setup and Control Panel use Information files%@NL@%
  17607.  
  17608.   ■   The various components of the Information file %@NL@%
  17609.  
  17610.   ■   How to create an Information file for installing your device driver
  17611.       and/or virtual device%@NL@%
  17612.  
  17613.   ■   Syntax and examples of the data in an Information file, given by
  17614.       device type%@NL@%
  17615.  
  17616.   ■   How to use Setup and Control Panel to test the installation of your
  17617.       device driver and/or virtual device%@NL@%
  17618.  
  17619.   ■   How to inform Microsoft about the availability of your device driver
  17620.       and/or virtual device
  17621. %@NL@%
  17622.  
  17623.  
  17624.  
  17625. %@2@%%@CR:C6A-C0002   @%%@AB@%C.1  What is an Information File?%@AE@%%@EH@%%@NL@%
  17626.  
  17627. An Information (.INF) file provides the data required for Windows to install
  17628. drivers and virtual devices that are provided on a set of disks.  %@NL@%
  17629.  
  17630. It contains the following type of information:  %@NL@%
  17631.  
  17632.  
  17633.   ■   The location of the driver and virtual device files (e.g., disk)%@NL@%
  17634.  
  17635.   ■   The device description string to be presented to the end user%@NL@%
  17636.  
  17637.   ■   Which driver and/or virtual device or other dependent files to
  17638.       install, depending on the device. For example, which screen fonts to
  17639.       install for a particular display and the associated virtual device
  17640.       (when setting up on an 80386 machine)%@NL@%
  17641.  
  17642.   ■   System configuration data for various machine types%@NL@%
  17643.  
  17644.  
  17645. The Setup utility uses the data in the Information (.INF) file to install
  17646. the following types of configuration information, device drivers, and
  17647. virtual devices:  %@NL@%
  17648.  
  17649.  
  17650.   ■   Displays and associated font files%@NL@%
  17651.  
  17652.   ■   Mice or other pointing devices%@NL@%
  17653.  
  17654.   ■   Networks%@NL@%
  17655.  
  17656.   ■   Keyboard types, subtypes, and layouts%@NL@%
  17657.  
  17658.   ■   386 enhanced mode virtual devices%@NL@%
  17659.  
  17660.   ■   Machine dependent configurations:%@NL@%
  17661.  
  17662. %@STUB@%      Display%@NL@%
  17663.  
  17664. %@STUB@%      Mouse or other pointing device%@NL@%
  17665.  
  17666. %@STUB@%      Keyboard%@NL@%
  17667.  
  17668. %@STUB@%      Comm%@NL@%
  17669.  
  17670. %@STUB@%      Sound%@NL@%
  17671.  
  17672. %@STUB@%      System%@NL@%
  17673.  
  17674. %@STUB@%      Any required 386 enhanced mode virtual devices and switches %@NL@%
  17675.  
  17676.  
  17677. Control Panel uses the data in the Information (.INF) file to install
  17678. printer drivers and Windows raster (or screen) fonts.  %@NL@%
  17679.  
  17680.  
  17681. %@2@%%@CR:C6A-C0003   @%%@AB@%C.2  Different Types of Information Files%@AE@%%@EH@%%@NL@%
  17682.  
  17683. The .INF file provided with Windows is named SETUP.INF and is stored in the
  17684. Windows ..\SYSTEM subdirectory. The SETUP.INF filename is unique and used by
  17685. Setup and Control Panel for standard Windows operations. This name is
  17686. reserved for Windows and should not be used on your distribution disk.  %@NL@%
  17687.  
  17688. A second type of .INF file that is used by Setup and Control Panel is called
  17689. OEMSETUP.INF. This name is to be used specifically for installing additional
  17690. drivers on a distribution disk.  %@NL@%
  17691.  
  17692. Setup and Control Panel look for this filename, OEMSETUP.INF, when
  17693. installing drivers and virtual devices that are not part of the retail
  17694. package. In general, the OEMSETUP.INF file you create will contain a subset
  17695. of the information provided in the SETUP.INF file.  %@NL@%
  17696.  
  17697. You may want to print a copy of the SETUP.INF file to use as a reference for
  17698. the following sections. The file is in ASCII text format and can be printed
  17699. on most printers.  %@NL@%
  17700.  
  17701. The steps for installing additional drivers are described in more detail
  17702. later in Section C.7, "Testing the Installation of Your Information File."  %@NL@%
  17703.  
  17704.  
  17705. %@2@%%@CR:C6A-C0004   @%%@AB@%C.3  General Format and Syntax for Information Files%@AE@%%@EH@%%@NL@%
  17706.  
  17707. .INF files are broken up into %@AI@%sections%@AE@%, with each section generally
  17708. containing information pertaining to a specific set of Windows driver or
  17709. system files. Section names are always enclosed in square brackets ([]).  %@NL@%
  17710.  
  17711. Sections are further broken up into %@AI@%lines%@AE@%, with each line generally
  17712. containing information about a single Windows system or driver file.  %@NL@%
  17713.  
  17714. Finally, the lines within sections are further broken up into %@AI@%fields%@AE@%, with
  17715. each field within a line generally containing information specific to the
  17716. system or driver file listed on that line. Fields are always separated by
  17717. commas (,).  %@NL@%
  17718.  
  17719. The following is a generalized syntax line and, then, a sample section from
  17720. the SETUP.INF file:  %@NL@%
  17721.  
  17722. Profile_string = Disk:Filename,"Text_Description",Disk:Virtual_Device  %@NL@%
  17723.  
  17724. %@AS@%  [pointing.device]
  17725. %@AS@%  nomouse   = 2:nomouse.drv,   "No mouse or pointing device",     3:*vmd
  17726. %@AS@%  ps2mouse  = 1:mouse.drv,     "Microsoft, or IBM PS/2",          3:*vmd
  17727. %@AS@%  msmouse1  = 2:msmouse1.drv,  "Mouse Systems (or VisiOn) COM1:", 3:*vmd
  17728. %@AS@%  msmouse2  = 2:msmouse2.drv,  "Mouse Systems (or VisiOn) COM2:", 3:*vmd
  17729. %@AS@%  lmouse    = 2:lmouse.drv,    "Logitech",                        3:*vmd
  17730. %@AS@%  kbdmouse  = 2:kbdmouse.drv,  "AT&T/Olivetti Keyboard Mouse",    3:*vmd
  17731. %@AS@%  hpmouse   = 2:hpmouse.drv,   "HP Mouse (HP-HIL)",               3:*vmd%@AE@%
  17732.  
  17733. In the above example, the section name is [pointing.device]. Each line in
  17734. the section contains information pertaining to the mouse driver listed in
  17735. the first field of the line.  %@NL@%
  17736.  
  17737. The string on the lefthand side of the equal sign (=) in the first field is
  17738. a %@AI@%profile%@AE@% string. The profile string is the unique "handle" that Setup uses
  17739. to parse a line from the .INF file that matches the hardware for which Setup
  17740. is configuring Windows. For example, if Setup detects that a Logitech mouse
  17741. is connected to the computer for which it is configuring Windows, it will
  17742. look for the string "lmouse" in the [pointing.device] section of the .INF
  17743. file. Once found, Setup uses the information on that line to determine how
  17744. to configure Windows for the Logitech mouse. The profile string portion of
  17745. the first field is considered to be field zero or may be referred to as the
  17746. profile field. Profile strings are limited to 15 characters.  %@NL@%
  17747.  
  17748. The second field of each line is a %@AI@%Text_Description%@AE@% string for the mouse
  17749. driver on that line. Description strings are limited to 48 characters.  %@NL@%
  17750.  
  17751. The third field is the name of the %@AI@%Virtual_Device%@AE@% file required for that
  17752. mouse to operate correctly under the 386 enhanced mode of Windows. If the
  17753. first character of any virtual device name is an asterisk (*), then that
  17754. driver is part of the WIN386.EXE file. If the virtual device name does not
  17755. contain an asterisk, then that file is separate from WIN386.EXE. 386
  17756. enhanced mode VxD files generally have the file extension .386 to identify
  17757. then as 386 enhanced mode VxDs.  %@NL@%
  17758.  
  17759.  
  17760. %@2@%%@CR:C6A-C0005   @%%@AB@%C.4  File Location Information%@AE@%%@EH@%%@NL@%
  17761.  
  17762. All the files that are listed in the .INF file have associated with them a
  17763. logical disk ID. The logical disk ID is a single character (1-9 A-Z).
  17764. Therefore, there are 1-9 + A-Z = 35 possible logical disk IDs. The logical
  17765. disk ID is added to the beginning of every filename listed in the .INF file
  17766. and separated from the filename by a colon (:) in the form %@AI@%x:filename%@AE@% where
  17767. %@AI@%x%@AE@% is the logical disk ID. The logical disk ID zero (0) is reserved for use
  17768. by Setup.  %@NL@%
  17769.  
  17770. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17771. NOTE
  17772.  
  17773. %@AI@%You must use a unique filename. We also suggest that this name be different
  17774. %@AI@%from the names of files defined in SETUP.INF.%@AE@%
  17775. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17776.  
  17777. The logical disk ID is mapped to a physical disk in the [disks] section of
  17778. the .INF file. The following is a generalized syntax line and, then, a
  17779. sample of a .INF file's [disks] section that maps the logical to physical
  17780. disk location of the mouse drivers listed in the [pointing.device] section.
  17781. %@NL@%
  17782.  
  17783. Disk_ID = Drive,"Text_Description"  %@NL@%
  17784.  
  17785. %@AS@%  [disks]
  17786. %@AS@%  1 =.\,       "Microsoft Windows 3.0 Disk #1"
  17787. %@AS@%  2 =.\disk2,  "Microsoft Windows 3.0 Disk #2"%@AE@%
  17788.  
  17789. In the preceding [disks] section example, the profile string corresponds to
  17790. a logical disk ID. For every logical disk ID used in the .INF file, there
  17791. must be a line in the [disks] section that maps that logical disk ID to a
  17792. physical disk location.  %@NL@%
  17793.  
  17794. The first field in the [disks] section is the physical location that
  17795. corresponds to the logical disk ID in the profile string. In the preceding
  17796. example, all the filenames that start with logical disk ID 1 will exist in
  17797. the physical root of the current drive (.\). All the filenames that start
  17798. with logical disk ID 2 will exist in the physical subdirectory \disk2 of the
  17799. current drive.  %@NL@%
  17800.  
  17801. The second field is a %@AI@%Text_Description%@AE@% string used to identify the physical
  17802. disk location. This is used by Setup and Control Panel for disk prompting if
  17803. the physical disk locations for different logical disk IDs are on different
  17804. floppy disks, which is normal.  %@NL@%
  17805.  
  17806.  
  17807. %@2@%%@CR:C6A-C0006   @%%@AB@%C.5  Creating .INF File Entries%@AE@%%@EH@%%@NL@%
  17808.  
  17809. The following .INF file entries are examples to follow when creating an
  17810. OEMSETUP.INF file for displays, mice or other pointing devices, networks,
  17811. keyboards, and machine-dependent configurations.  %@NL@%
  17812.  
  17813. See Section C.6, "Creating .INF File Entries for Printer Drivers," for
  17814. information on how to create an OEMSETUP.INF file for printer devices.  %@NL@%
  17815.  
  17816. See Section C.3, "General Format and Syntax for Information Files," and
  17817. Section C.4, "File Location Information," for more information about profile
  17818. strings, text descriptions, driver filenames, and disk location
  17819. descriptions. These fields are referenced throughout the following examples.
  17820. %@NL@%
  17821.  
  17822. The colons, commas, and quotes shown in the following examples are required
  17823. as part of the format.  %@NL@%
  17824.  
  17825.  
  17826. %@3@%%@CR:C6A-C0007   @%%@AB@%C.5.1  Display Device%@AE@%%@EH@%%@NL@%
  17827.  
  17828. The following is a generalized example of the syntax used for display
  17829. devices along with definitions of each of the terms presented.  %@NL@%
  17830.  
  17831. [display] Profile_string = Disk:Filename,"Text_Description","Aspect_Ratio",
  17832. Disk:Grabber,Disk:Logo_Code,Disk:Virtual_Display_Device,
  17833. Disk:386_Grabber,[Disk:EGA_DOS_Driver],Disk:Logo_Data  %@NL@%
  17834.  
  17835. Where:  %@NL@%
  17836.  
  17837. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  17838.  
  17839. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  17840.  
  17841. %@AI@%Aspect_Ratio%@AE@% is information that is used to determine which raster (or
  17842. screen) fonts to install for use by the device. Any fonts found with
  17843. matching aspect values in the [sysfonts], [fixedfonts], [oemfonts], or
  17844. [fonts] sections of the .INF file will be installed in the [fonts] section
  17845. of the WIN.INI file.  %@NL@%
  17846.  
  17847. Aspect_Ratio includes the following three values:  %@NL@%
  17848.  
  17849.  
  17850.   ■   X and Y aspect ratio%@NL@%
  17851.  
  17852.   ■   X pixels-per-inch%@NL@%
  17853.  
  17854.   ■   Y pixels-per-inch%@NL@%
  17855.  
  17856.  
  17857. The three values are separated by commas and enclosed within quotation
  17858. marks. For example, for a VGA display, the values would be as follows:  %@NL@%
  17859.  
  17860. "100,96,96"  %@NL@%
  17861.  
  17862. Where:  %@NL@%
  17863.  
  17864. %@AI@%100%@AE@% is the X and Y aspect ratio (1-to-1).  %@NL@%
  17865.  
  17866. %@AI@%96%@AE@% is the X (horizontal) pixels-per-inch.  %@NL@%
  17867.  
  17868. %@AI@%96%@AE@% is the Y (vertical) pixels-per-inch.  %@NL@%
  17869.  
  17870. See the description of the GDIINFO data structure in Chapter 2, "Display
  17871. Drivers," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% for more
  17872. information on calculating these values.  %@NL@%
  17873.  
  17874. %@AI@%Grabber%@AE@% is the MS-DOS filename of the grabber used when Windows is running
  17875. in real and standard mode.  %@NL@%
  17876.  
  17877. %@AI@%Logo_Code%@AE@% is the MS-DOS filename of the logo display code that is used by
  17878. Setup to build the WIN.COM file.  %@NL@%
  17879.  
  17880. %@AI@%Virtual_Display_Device%@AE@% is the MS-DOS filename of the VDD that Windows will
  17881. use in 386 enhanced mode.  %@NL@%
  17882.  
  17883. %@AI@%386_Grabber%@AE@% is the MS-DOS filename of the grabber used when Windows is
  17884. running in 386 enhanced mode.  %@NL@%
  17885.  
  17886. %@AI@%EGA_DOS_Driver%@AE@% is an optional field. It is the MS-DOS filename of an MS-DOS
  17887. installable device driver used to virtualize the write-only registers on EGA
  17888. display cards so that they can be read.  %@NL@%
  17889.  
  17890. %@AI@%Logo_Data%@AE@% is the MS-DOS filename of the logo data that is used by Setup to
  17891. build the WIN.COM file.  %@NL@%
  17892.  
  17893. The following is an example of what a .INF file for a specific EGA display
  17894. driver would look like.  %@NL@%
  17895.  
  17896. %@AS@%  [data]
  17897. %@AS@%  defxlat = 437%@AE@%
  17898.  
  17899. %@AS@%  [disks]
  17900. %@AS@%  1 =. ,"OEM Display Driver Disk #1"%@AE@%
  17901.  
  17902. %@AS@%  [display]
  17903. %@AS@%  oemega = 1:ega.drv,"OEM EGA Color","133,96,72", 
  17904. %@AS@%  1:egacolor.gr2,1:egalogo.lgo,1:vddega.386, 
  17905. %@AS@%  1:ega.gr3,1:ega.sys,1:egalogo.rle%@AE@%
  17906.  
  17907. %@AS@%  [EGA.GR3]
  17908. %@AS@%  1:CGA40WOA.FON,1:CGA40850.FON
  17909. %@AS@%  1:CGA80WOA.FON,1:CGA80850.FON
  17910. %@AS@%  1:EGA40WOA.FON,1:EGA40850.FON
  17911. %@AS@%  1:EGA80WOA.FON,1:EGA80850.FON%@AE@%
  17912.  
  17913. %@AS@%  [codepages]
  17914. %@AS@%  ;       Xlat Table    OEM Font      description.
  17915. %@AS@%  863 = 2:xlat863.bin, 2:vga863.fon, "French Canadian (863)"
  17916. %@AS@%  861 = 2:xlat861.bin, 2:vga861.fon, "Icelandic (861)"
  17917. %@AS@%  865 = 2:xlat865.bin, 2:vga865.fon, "Norway & Denmark (865)"
  17918. %@AS@%  850 = 2:xlat850.bin, 2:vga850.fon, "International (850)"
  17919. %@AS@%  860 = 2:xlat860.bin, 2:vga860.fon, "Portuguese (860)"
  17920. %@AS@%  437 =              ,             , "Standard (437)"%@AE@%
  17921.  
  17922. %@AS@%  [sysfonts]
  17923. %@AS@%  1:egasys.fon,"EGA (640x350) resolution System Font","133,96,72"%@AE@%
  17924.  
  17925. %@AS@%  [fixedfonts]
  17926. %@AS@%  1:egafix.fon,"EGA (640x350) resolution Fixed System Font","133,96,72"%@AE@%
  17927.  
  17928. %@AS@%  [oemfonts]
  17929. %@AS@%  1:egaoem.fon,"EGA (640x350) resolution Terminal Font
  17930. %@AS@%(USA/Europe)","133,96,72",1%@AE@%
  17931.  
  17932. %@AS@%  [fonts]
  17933. %@AS@%  1:HELVB.FON,   "Helv 8,10,12,14,18,24 (EGA res)",    "133,96,72"
  17934. %@AS@%  1:COURB.FON,   "Courier 10,12,15 (EGA res)",         "133,96,72"
  17935. %@AS@%  1:TMSRB.FON,   "Tms Rmn 8,10,12,14,18,24 (EGA res)", "133,96,72"
  17936. %@AS@%  1:SYMBOLB.FON, "Symbol 8,10,12,14,18,24 (EGA res)",  "133,96,72"
  17937. %@AS@%  1:ROMAN.FON,   "Roman (All res)",  "CONTINUOUSSCALING"
  17938. %@AS@%  1:SCRIPT.FON,  "Script (All res)", "CONTINUOUSSCALING"
  17939. %@AS@%  1:MODERN.FON,  "Modern (All res)", "CONTINUOUSSCALING"%@AE@%
  17940.  
  17941. Because there are many display-dependent files, the .INF file for installing
  17942. display drivers is more complicated. For any given Windows display driver,
  17943. the following related files are also required by Windows 3.0.  %@NL@%
  17944.  
  17945. %@TH:  12   619 02 32 44 @%File                            Needed by%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%Display driver                  All modesStandard-mode grabber           Standard and real modeEnhanced-mode grabber           Enhanced modeLogo display code               All modesLogo display data               All modesSystem font                     All modesFixed font                      All modesOEM/Terminal font               Standard and real mode386 OEM/Terminal font           Enhanced modeUser fonts                      All modes%@TE:  12   619 02 32 44 @%
  17946.  
  17947. The profile string for the display driver must be unique from all the other
  17948. display profile strings, including those listed in the Microsoft Windows 3.0
  17949. SETUP.INF file.  %@NL@%
  17950.  
  17951. Setup selects fonts by matching the aspect ratio of the display to that of
  17952. the font. Setup will, however, ignore aspect ratio information for
  17953. configurations using a code page other than 437. For these configurations,
  17954. Setup asks MS-DOS for code page information and selects an OEM/Terminal font
  17955. from the [codepages] section based on that information. Since only MS-DOS
  17956. version 3.30 and higher supports the call for code page information, Setup
  17957. may (depending on the MS-DOS version) rely on the %@AI@%defxlat%@AE@% profile string
  17958. (under the [data] section) to get code page information.  %@NL@%
  17959.  
  17960. When preparing your distribution disks, you may choose one of the following
  17961. three methods for providing .FON font files:  %@NL@%
  17962.  
  17963.  
  17964.   ■   Include the appropriate Windows .FON font files from the Windows 3.0
  17965.       retail product.%@NL@%
  17966.  
  17967.   ■   Refer in the [disks] section of your OEMSETUP.INF file to the Windows
  17968.       3.0 retail disk(s) containing these files.%@NL@%
  17969.  
  17970.   ■   Distribute your own .FON font files if your display requires fonts
  17971.       that are tuned for a particular aspect ratio and not supported by the
  17972.       Windows .FON font files.%@NL@%
  17973.  
  17974.  
  17975. See the "Grant of License to Use" section, in the Microsoft License
  17976. Agreement that is printed on the DDK disk envelope, for information on your
  17977. rights to distribute these font files should you choose to include them on
  17978. your distribution disk.  %@NL@%
  17979.  
  17980.  
  17981. %@3@%%@CR:C6A-C0008   @%%@AB@%C.5.2  Mouse or Other Pointing Device%@AE@%%@EH@%%@NL@%
  17982.  
  17983. The following is a generalized example of the syntax used for mice or other
  17984. pointing devices along with definitions of each of the terms presented.  %@NL@%
  17985.  
  17986. [pointing.device] Profile_string =
  17987. Disk:Filename,"Text_Description",Disk:Virtual_Mouse_Driver  %@NL@%
  17988.  
  17989. Where:  %@NL@%
  17990.  
  17991. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  17992.  
  17993. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  17994.  
  17995. %@AI@%Virtual_Mouse_Driver%@AE@% is the MS-DOS filename of the associated virtual device
  17996. to be installed for running Windows in 386 enhanced mode.  %@NL@%
  17997.  
  17998. The following is an example of what a .INF file for a specific OEM mouse
  17999. driver would look like.  %@NL@%
  18000.  
  18001. %@AS@%  [disks]
  18002. %@AS@%  1 =. ,"OEM Mouse driver disk #1"%@AE@%
  18003.  
  18004. %@AS@%  [pointing.device]
  18005. %@AS@%  oemmouse = 1:oemmouse.drv,"OEM Mouse driver",1:oemvmd.386%@AE@%
  18006.  
  18007.  
  18008. %@3@%%@CR:C6A-C0009   @%%@AB@%C.5.3  Network Device%@AE@%%@EH@%%@NL@%
  18009.  
  18010. The following is a generalized example of the syntax used for network
  18011. devices along with definitions of each of the terms presented.  %@NL@%
  18012.  
  18013. Notice that all the fields in brackets ([ ]) are optional. All other fields
  18014. are required. The quotes, commas, and colons are required as well.  %@NL@%
  18015.  
  18016. Profile_string = Disk:Filename,"Text_Description", [Disk:Help_File],
  18017. [Disk:Optional_File],[WIN.INI_ Mods], [SYSTEM.INI_
  18018. Mods],[Disk:Virtual_Net_Device ...]  %@NL@%
  18019.  
  18020. Where:  %@NL@%
  18021.  
  18022. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  18023.  
  18024. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  18025.  
  18026. %@AI@%Help_File%@AE@% is the MS-DOS filename of an associated Help file. Setup copies
  18027. this file to the Windows installation directory. This file is optional.  %@NL@%
  18028.  
  18029. %@AI@%Optional_File%@AE@% is the MS-DOS filename of an optional file, which may be
  18030. necessary for your network. Setup copies this file to the Windows
  18031. installation directory. This file is optional.  %@NL@%
  18032.  
  18033. %@AI@%WIN.INI_Mods%@AE@% is the name of a section within the OEMSETUP.INF file that
  18034. describes modifications to be made to the user's WIN.INI file.  %@NL@%
  18035.  
  18036. %@AI@%SYSTEM.INI_Mods%@AE@% is the name of a section within the OEMSETUP.INF file that
  18037. describes modifications to be made to the user's SYSTEM.INI file.  %@NL@%
  18038.  
  18039. %@AI@%Virtual_Net_Device%@AE@% is the MS-DOS filename of an associated virtual device to
  18040. be installed for running Windows in 386 enhanced mode.  %@NL@%
  18041.  
  18042. The following is an example of what a .INF file for a specific network
  18043. driver would look like.  %@NL@%
  18044.  
  18045. %@AS@%  [disks]
  18046. %@AS@%  1 = . ,"Oem Network driver disk #1"%@AE@%
  18047.  
  18048. %@AS@%  [network]
  18049. %@AS@%  oem_net = 1:oem.drv,"OEM Network Driver",
  18050. %@AS@%1:oemnet.hlp,1:oem_app.exe,oem_winini,oem_sysini,
  18051. %@AS@%  1:oem1.386,1:oem2.386%@AE@%
  18052.  
  18053. %@AS@%  [oem_winini]
  18054. %@AS@%  Windows,load,oem_app.exe%@AE@%
  18055.  
  18056. %@AS@%  [oem_sysini]
  18057. %@AS@%  386enh,TimerCriticalSection,500%@AE@%
  18058.  
  18059. The %@AI@%oem_sysini%@AE@% and %@AI@%oem_winini%@AE@% sections describe modifications to be made in
  18060. the WIN.INI and SYSTEM.INI files. A .INI modification description section is
  18061. comprised of lines that contain three fields describing a new entry to be
  18062. made to the .INI file. The fields in each line are as follows:  %@NL@%
  18063.  
  18064.  
  18065.   ■   Field 1 = .INI file section name%@NL@%
  18066.  
  18067.   ■   Field 2 = Profile string or descriptor to the lefthand side of the
  18068.       equal sign%@NL@%
  18069.  
  18070.   ■   Field 3 = Descriptor to the righthand side of the equal sign%@NL@%
  18071.  
  18072.  
  18073. In the preceding example, Setup would add the string "load=oem_app.exe" to
  18074. the [windows] section of WIN.INI. If a "load=" line already existed in
  18075. WIN.INI, then Setup would add "oem_app.exe" to the righthand side of the
  18076. "load=" line.  %@NL@%
  18077.  
  18078. Setup would also add the string "TimerCriticalSection=500" to the [386enh]
  18079. section of SYSTEM.INI.  %@NL@%
  18080.  
  18081.  
  18082. %@3@%%@CR:C6A-C0010   @%%@AB@%C.5.4  Keyboard Device%@AE@%%@EH@%%@NL@%
  18083.  
  18084. The following are generalized examples of the layout, type, and subtype
  18085. syntax used for keyboard devices along with definitions of each of the terms
  18086. presented.  %@NL@%
  18087.  
  18088. The layout syntax is as follows:  %@NL@%
  18089.  
  18090. Profile_string = Disk:Filename,"Text_Description"  %@NL@%
  18091.  
  18092. The type and subtype syntax is as follows :  %@NL@%
  18093.  
  18094. Type_Subtype_Profile_string = "Text_Description"  %@NL@%
  18095.  
  18096. Where:  %@NL@%
  18097.  
  18098. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file.  %@NL@%
  18099.  
  18100. %@AI@%Text_Description%@AE@% is a character string describing the device on that line.  %@NL@%
  18101.  
  18102. %@AI@%Type_Subtype_Profile_string%@AE@% is a combination of type/subtype and profile
  18103. string information. The type/subtype information is represented in the form
  18104. of "t##s##." The remaining characters represent the profile string
  18105. information.  %@NL@%
  18106.  
  18107. The following is an example of what a .INF file for a specific keyboard
  18108. driver would look like.  %@NL@%
  18109.  
  18110. %@AS@%  [data]
  18111. %@AS@%  defkeydll = ussrdll%@AE@%
  18112.  
  18113. %@AS@%  [disks]
  18114. %@AS@%  1 = . ,"Oem Keyboard disk #1"%@AE@%
  18115.  
  18116. %@AS@%  [keyboard.types]
  18117. %@AS@%  t3s9oem  = "Russian OEM Keyboard"%@AE@%
  18118.  
  18119. %@AS@%  [keyboard.tables]
  18120. %@AS@%  ussrdll = 1:kbdussr.dll,"Russian"%@AE@%
  18121.  
  18122. The keyboard type entry is unique because it involves only SYSTEM.INI
  18123. settings. No driver files are copied. The keyboard type and subtype entries
  18124. in SYSTEM.INI are used by the Windows 3.0 keyboard driver during boot time
  18125. to determine the keyboard type.  %@NL@%
  18126.  
  18127. If the keyboard type is selected during a first time installation, Setup
  18128. will also select a keyboard layout (DLL or dynamic-link library). Setup
  18129. selects a keyboard DLL by looking at the data on the righthand side of the
  18130. equal sign of %@AI@%defkeydll%@AE@% in the [data] section of the .INF file. Using the
  18131. profile string obtained from this data, Setup selects a keyboard DLL from
  18132. the [keyboard.tables] section of the .INF file.  %@NL@%
  18133.  
  18134.  
  18135. %@3@%%@CR:C6A-C0011   @%%@AB@%C.5.5  Machine-Dependent Configuration%@AE@%%@EH@%%@NL@%
  18136.  
  18137. Setup installs machine-dependent configuration information for the display,
  18138. keyboard, mouse, sound, comm, system, and 386 enhanced-mode BIOS devices,
  18139. and their related files, other virtual devices, and special SYSTEM.INI
  18140. switches.  %@NL@%
  18141.  
  18142. The following is an example of how to define a machine-dependent
  18143. configuration in a .INF file by combining the information discussed in the
  18144. previous sections.  %@NL@%
  18145.  
  18146. %@AS@%  [data]
  18147. %@AS@%  defxlat = 437
  18148. %@AS@%  deflang = rus%@AE@%
  18149.  
  18150. %@AS@%  [disks]
  18151. %@AS@%  1 =. ,"OEM Display Driver Disk #1"%@AE@%
  18152.  
  18153. %@AS@%  [display]
  18154. %@AS@%  oemega = 1:ega.drv,"OEM EGA Color","133,96,72", 
  18155. %@AS@%  1:egacolor.gr2,1:egalogo.lgo,1:vddega.386, 
  18156. %@AS@%  1:ega.gr3,1:ega.sys,1:egalogo.rle%@AE@%
  18157.  
  18158. %@AS@%  [EGA.GR3]
  18159. %@AS@%  1:CGA40WOA.FON,1:CGA40850.FON
  18160. %@AS@%  1:CGA80WOA.FON,1:CGA80850.FON
  18161. %@AS@%  1:EGA40WOA.FON,1:EGA40850.FON
  18162. %@AS@%  1:EGA80WOA.FON,1:EGA80850.FON%@AE@%
  18163.  
  18164. %@AS@%  [sysfonts]
  18165. %@AS@%  1:egasys.fon,"EGA (640x350) resolution System Font","133,96,72"%@AE@%
  18166.  
  18167. %@AS@%  [fixedfonts]
  18168. %@AS@%  1:egafix.fon,"EGA (640x350) resolution Fixed System Font","133,96,72"%@AE@%
  18169.  
  18170. %@AS@%  [oemfonts]
  18171. %@AS@%  1:egaoem.fon,"EGA (640x350) resolution Terminal Font
  18172. %@AS@%(USA/Europe)","133,96,72",1%@AE@%
  18173.  
  18174. %@AS@%  [codepages]
  18175. %@AS@%  ;       Xlat Table    OEM Font      description.
  18176. %@AS@%  863 = 2:xlat863.bin, 2:vga863.fon, "French Canadian (863)"
  18177. %@AS@%  861 = 2:xlat861.bin, 2:vga861.fon, "Icelandic (861)"
  18178. %@AS@%  865 = 2:xlat865.bin, 2:vga865.fon, "Norway & Denmark (865)"
  18179. %@AS@%  850 = 2:xlat850.bin, 2:vga850.fon, "International (850)"
  18180. %@AS@%  860 = 2:xlat860.bin, 2:vga860.fon, "Portuguese (860)"
  18181. %@AS@%  437 =              ,             , "Standard (437)"%@AE@%
  18182.  
  18183. %@AS@%  [fonts]
  18184. %@AS@%  1:HELVB.FON,   "Helv 8,10,12,14,18,24 (EGA res)",    "133,96,72"
  18185. %@AS@%  1:COURB.FON,   "Courier 10,12,15 (EGA res)",         "133,96,72"
  18186. %@AS@%  1:TMSRB.FON,   "Tms Rmn 8,10,12,14,18,24 (EGA res)", "133,96,72"
  18187. %@AS@%  1:SYMBOLB.FON, "Symbol 8,10,12,14,18,24 (EGA res)",  "133,96,72"
  18188. %@AS@%  1:ROMAN.FON,   "Roman (All res)",  "CONTINUOUSSCALING"
  18189. %@AS@%  1:SCRIPT.FON,  "Script (All res)", "CONTINUOUSSCALING"
  18190. %@AS@%  1:MODERN.FON,  "Modern (All res)", "CONTINUOUSSCALING"%@AE@%
  18191.  
  18192. %@AS@%  [pointing.device]
  18193. %@AS@%  oemmouse = 1:oemmouse.drv, "Mouse driver for OEM machine", 1:oemvmd.386%@AE@%
  18194.  
  18195. %@AS@%  [language]
  18196. %@AS@%  rus = 1:langussr.dll, "Russian"%@AE@%
  18197.  
  18198. %@AS@%  [keyboard.types]
  18199. %@AS@%  t4s8enha = "Super OEM 200 key Keyboard"%@AE@%
  18200.  
  18201. %@AS@%  [keyboard.drivers]
  18202. %@AS@%  oemkbd = 1:oemkbd.drv%@AE@%
  18203.  
  18204. %@AS@%  [system]
  18205. %@AS@%  oemsys  = 1:oemsys.drv
  18206. %@AS@%  oemsnd  = 1:oemsnd.drv
  18207. %@AS@%  oemcomm = 1:oemcom.drv%@AE@%
  18208.  
  18209. %@AS@%  [ebios]
  18210. %@AS@%  oemebios = 1:oemebios.386,x:*ebios%@AE@%
  18211.  
  18212. %@AS@%  [machine]%@AE@%
  18213.  
  18214. %@AS@%  "386 OEM Machine","78"
  18215. %@AS@%    oemsys    ;1
  18216. %@AS@%    oemkbd    ;2
  18217. %@AS@%    t4s8enha    ;3
  18218. %@AS@%    oemmouse    ;4
  18219. %@AS@%    oemega    ;5
  18220. %@AS@%    oemsnd    ;6
  18221. %@AS@%    oemcomm    ;7
  18222. %@AS@%    nohimemswitch   ;8
  18223. %@AS@%    oemebios    ;9
  18224. %@AS@%    "emmexclude=c700-c800"  ;10
  18225. %@AS@%    "device=",1:oemvxd.386"  ;11
  18226. %@AS@%        ;n%@AE@%
  18227.  
  18228. Setup may or may not use all the configuration information given in the
  18229. [machine] section. It does use the information provided to install the
  18230. system, keyboard layout, sound, comm, and BIOS drivers. However, only if
  18231. Setup is unable to detect the hardware in question, is the information for
  18232. the mouse, display, and keyboard type/subtype used.  %@NL@%
  18233.  
  18234. In the preceding example, lines 10 and 11 under the [machine] section are
  18235. optional. These lines are provided for the installation of special virtual
  18236. devices or SYSTEM.INI [386enh] section switches. Up to six of these lines
  18237. may be added as needed.  %@NL@%
  18238.  
  18239. Setup also uses code page information (obtained either by means of an MS-DOS
  18240. call, on MS-DOS versions 3.30 or later, or from the %@AI@%defxlat%@AE@% profile string
  18241. in the [data] section) to install a keyboard translation table. This
  18242. information is obtained from the .INF file in the [codepages] section.  %@NL@%
  18243.  
  18244. Finally, Setup also selects a language driver based on the profile string
  18245. given on the righthand side of the equal sign of the %@AI@%deflang%@AE@% entry in the
  18246. [data] section of the .INF file.  %@NL@%
  18247.  
  18248.  
  18249. %@2@%%@CR:C6A-C0012   @%%@AB@%C.6  Creating .INF File Entries for Printer Drivers%@AE@%%@EH@%%@NL@%
  18250.  
  18251. Control Panel does not require an OEMSETUP.INF file for installing a printer
  18252. driver. In Windows 3.0, Control Panel only uses the OEMSETUP.INF file to
  18253. install more than one set of raster (or screen) fonts and to install
  18254. dependent files (e.g., Help files or a font installer). Otherwise, it is not
  18255. required.  %@NL@%
  18256.  
  18257. Control Panel scans the driver files for the driver description regardless
  18258. of whether an OEMSETUP.INF file is present or not. Therefore, it is
  18259. important for you to properly define your driver description in the
  18260. definition (.DEF) file.  %@NL@%
  18261.  
  18262. The following subsections contain information on creating .INF entries for
  18263. OEMSETUP.INF and on the format of the driver's description string in the
  18264. .DEF file.  %@NL@%
  18265.  
  18266.  
  18267. %@3@%%@CR:C6A-C0013   @%%@AB@%C.6.1  .INF File Entries%@AE@%%@EH@%%@NL@%
  18268.  
  18269. The following are generalized examples of the syntax used for printer
  18270. devices along with definitions of each of the terms presented. The colons,
  18271. commas, and quotes shown in the examples are required as part of the format.
  18272. The brackets ([ ]) represent optional fields, except in the case of section
  18273. names.  %@NL@%
  18274.  
  18275. [io.device] Disk:Filename,"Text_Description",
  18276. "Aspect_Ratio"[,"Aspect_Ratio"...]  %@NL@%
  18277.  
  18278. [io.dependent] Filename=Disk:File1[,Disk:File2...]  %@NL@%
  18279.  
  18280. Where:  %@NL@%
  18281.  
  18282. %@AI@%Filename%@AE@% is the MS-DOS filename of the driver file. It is used by Control
  18283. Panel to check on whether or not the driver has been installed previously
  18284. and to copy the driver from the distribution disk to the Windows ..\SYSTEM
  18285. directory. This driver name is also the first element on the righthand side
  18286. of the equal sign (=) in the entries under the [devices] and [PrinterPorts]
  18287. sections of the WIN.INI file. %@AI@%Filename%@AE@% in the [io.dependent] section must
  18288. match (case insensitive) the %@AI@%Filename%@AE@% element of the [io.device] section.  %@NL@%
  18289.  
  18290. %@AI@%Text_Description%@AE@% is displayed in the printers listbox (without the quotation
  18291. marks) once the driver is installed. It is placed on the lefthand side of
  18292. the equal sign-in the entries under the [devices] and [PrinterPorts]
  18293. sections of the WIN.INI file. It should also match the %@AI@%Text_Description%@AE@%
  18294. string in the .DEF file of the driver (see the following section for more
  18295. information on the .DEF file). If there is a portion within the text
  18296. description that is enclosed in square brackets, it will be used as the
  18297. lefthand side of the equal sign (=) in the WIN.INI entries. The text in the
  18298. brackets would normally be used to provide a "generic" name for a driver
  18299. that may support many printer models (see the following example for the XYZ
  18300. Ink Jet printer).  %@NL@%
  18301.  
  18302. %@AI@%Aspect_Ratio%@AE@% is information used to determine which raster (or screen) fonts
  18303. to install for use by the device. Any fonts found with matching aspect
  18304. values are installed in the [fonts] section of the WIN.INI file. Up to 5
  18305. different aspect ratio values may be listed. At least one must be listed. If
  18306. no raster font installation is desired, use "DEVICESPECIFIC" as the only
  18307. value.  %@NL@%
  18308.  
  18309. Aspect_Ratio includes the following three values:  %@NL@%
  18310.  
  18311.  
  18312.   ■   X and Y aspect ratio%@NL@%
  18313.  
  18314.   ■   X pixels-per-inch%@NL@%
  18315.  
  18316.   ■   Y pixels-per-inch%@NL@%
  18317.  
  18318.  
  18319. The three values are separated by commas and enclosed within quotation
  18320. marks. For example, for a VGA display, the values would be as follows:  %@NL@%
  18321.  
  18322. "100,96,96"  %@NL@%
  18323.  
  18324. Where:  %@NL@%
  18325.  
  18326. %@AI@%100%@AE@% is the X and Y aspect ratio (1-to-1).  %@NL@%
  18327.  
  18328. %@AI@%96%@AE@% is the X (horizontal) pixels-per-inch.  %@NL@%
  18329.  
  18330. %@AI@%96%@AE@% is the Y (vertical) pixels-per-inch.  %@NL@%
  18331.  
  18332. See the description of the GDIINFO data structure in Chapter 2, "Display
  18333. Drivers," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% for more
  18334. information on calculating these values.  %@NL@%
  18335.  
  18336. %@AI@%File1 %@AE@%is the MS-DOS filename of the dependent file. This might include a
  18337. help (.HLP) file or a font installer that is associated with File1. You can
  18338. have more than one dependent file listed, but each must have a unique name.
  18339. %@NL@%
  18340.  
  18341. See Section C.6.3, "Special Considerations," for information on how Control
  18342. Panel installs font files.  %@NL@%
  18343.  
  18344. The following is an example of what a .INF file for a specific printer
  18345. driver would look like.  %@NL@%
  18346.  
  18347. %@AS@%  [disk]
  18348. %@AS@%  1 = . ,"XYZ Printers Disk"%@AE@%
  18349.  
  18350. %@AS@%  [io.device]
  18351. %@AS@%  1:XYZLASER.DRV,"XYZ Laser Printer","DEVICESPECIFIC"
  18352. %@AS@%  1:XYZINK.DRV,"XYZ Ink Jet Printer [XYZ Series]", 
  18353. %@AS@%  "100,120,120","100,96,96"%@AE@%
  18354.  
  18355. %@AS@%  [io.dependent]
  18356. %@AS@%  XYZLASER.DRV= 1:XYZLASER.HLP,1:SFXYZ.DLL%@AE@%
  18357.  
  18358. If the driver is not found in the current drive, Control Panel will prompt
  18359. the user for that disk.  %@NL@%
  18360.  
  18361. The following is an example of a WIN.INI file after installation.  %@NL@%
  18362.  
  18363. %@AS@%  [windows]
  18364. %@AS@%   |
  18365. %@AS@%  device=XYZ Series,XYZINK,LPT1:  ; Default printer, only one allowed at 
  18366. %@AS@%  a time
  18367. %@AS@%   |%@AE@%
  18368.  
  18369. %@AS@%  [printerports]
  18370. %@AS@%  XYZ Series=XYZINK,LPT1:,15,45
  18371. %@AS@%  XYZ Laser Printer=XYZLASER,LPT2:,15,45%@AE@%
  18372.  
  18373. %@AS@%  [devices]
  18374. %@AS@%  XYZ Series=XYZINK,LPT1:
  18375. %@AS@%  XYZ Laser Printer=XYZLASER,LPT2:%@AE@%
  18376.  
  18377.  
  18378. %@3@%%@CR:C6A-C0014   @%%@AB@%C.6.2  Driver Description (.DEF) File%@AE@%%@EH@%%@NL@%
  18379.  
  18380. All drivers must provide a description string in the printer driver's .DEF
  18381. file. The following are a generalized example of the syntax used for printer
  18382. devices and a specific example along with definitions of each of the terms
  18383. presented.  %@NL@%
  18384.  
  18385. DESCRIPTION 'DDRV Text_Description:Aspect_Ratio  %@NL@%
  18386.  
  18387. DESCRIPTION 'DDRV PCL / HP LaserJet:100,300,300'  %@NL@%
  18388.  
  18389. Where:  %@NL@%
  18390.  
  18391. The character immediately following DDRV can be anything and is always
  18392. ignored.  %@NL@%
  18393.  
  18394. %@AI@%DDRV%@AE@% must be capitalized.  %@NL@%
  18395.  
  18396. %@AI@%Text_Description%@AE@%, up to but not including the colon, is placed on the
  18397. lefthand side of the equal sign for the entries in the [devices] and
  18398. [PrinterPorts] sections of the WIN.INI file. It is also the first element on
  18399. the righthand side of the "device=" line in the [windows] section. Because
  18400. the righthand side of the "device=" line is parsed using commas, if
  18401. %@AI@%Text_Description%@AE@% includes a comma, it will be terminated there. For example:
  18402. %@NL@%
  18403.  
  18404. DESCRIPTION 'Printer 1, Printer2:100,300,300'  %@NL@%
  18405.  
  18406. %@AI@%Printer 1%@AE@% will be used as the lefthand and righthand sides in the above
  18407. mentioned sections. This will cause problems when installing with the
  18408. Control Panel. If you need to list more than one printer, we suggest you use
  18409. a delimiter other than a comma. For example:  %@NL@%
  18410.  
  18411. DESCRIPTION 'Printer 1/Printer2:100,300,300'  %@NL@%
  18412.  
  18413. Aspect_Ratio includes the following three values:  %@NL@%
  18414.  
  18415.  
  18416.   ■   X and Y aspect ratio%@NL@%
  18417.  
  18418.   ■   X pixels-per-inch%@NL@%
  18419.  
  18420.   ■   Y pixels-per-inch%@NL@%
  18421.  
  18422.  
  18423. The three values are separated by commas and enclosed within quotation
  18424. marks. For example, for a VGA display, the values would be as follows:  %@NL@%
  18425.  
  18426. "100,96,96"  %@NL@%
  18427.  
  18428. Where:  %@NL@%
  18429.  
  18430. %@AI@%100%@AE@% is the X and Y aspect ratio (1-to-1).  %@NL@%
  18431.  
  18432. %@AI@%96%@AE@% is the X (horizontal) pixels-per-inch.  %@NL@%
  18433.  
  18434. %@AI@%96%@AE@% is the Y (vertical) pixels-per-inch.  %@NL@%
  18435.  
  18436. See the description of the GDIINFO data structure in Chapter 2, "Display
  18437. Drivers," in the %@AI@%Microsoft Windows Device Driver Adaptation Guide%@AE@% for more
  18438. information on calculating these values.  %@NL@%
  18439.  
  18440.  
  18441. %@3@%%@CR:C6A-C0015   @%%@AB@%C.6.3  Special Considerations%@AE@%%@EH@%%@NL@%
  18442.  
  18443. Control Panel references the SETUP.INF file in the Windows ..\SYSTEM
  18444. subdirectory for the raster font files. Control Panel will prompt the user
  18445. as necessary for the Microsoft Windows disk defined in the SETUP.INF file if
  18446. a font matching the %@AI@%Aspect_Ratio%@AE@% is available.  %@NL@%
  18447.  
  18448. If dependent files exist, the OEMSETUP.INF file needs to exist in the same
  18449. directory as the driver file.  %@NL@%
  18450.  
  18451.  
  18452. %@2@%%@CR:C6A-C0016   @%%@AB@%C.7  Testing the Installation of Your .INF File%@AE@%%@EH@%%@NL@%
  18453.  
  18454. Before testing, you need to create a .INF file according to the instructions
  18455. given in Section C.5, "Creating .INF File Entries," and Section C.6,
  18456. "Creating .INF File Entries for Printer Drivers." The .INF file and other
  18457. associated driver and virtual device files should then be copied to a disk
  18458. (or any other form on which you plan to distribute them).  %@NL@%
  18459.  
  18460. Depending on the type of device you support, you will need to run either
  18461. Setup or Control Panel to test your .INF file.  %@NL@%
  18462.  
  18463. Setup installs display, mouse or other pointing device, network, keyboard,
  18464. or machine-dependent drivers and virtual devices.  %@NL@%
  18465.  
  18466. Printer drivers are installed by Control Panel.  %@NL@%
  18467.  
  18468.  
  18469. %@3@%%@CR:C6A-C0017   @%%@AB@%C.7.1  Testing with Setup%@AE@%%@EH@%%@NL@%
  18470.  
  18471. You must run the Setup utility from MS-DOS when installing additional device
  18472. support (via an OEMSETUP.INF file). If you run Setup directly from Windows,
  18473. you can install only device drivers and virtual devices that are supplied
  18474. with Windows (i.e., defined in the SETUP.INF file).  %@NL@%
  18475.  
  18476. During debugging, we suggest you use the debugging version of the Setup
  18477. utility, which is provided on the DDK disks. For more information on the
  18478. error messages that might appear, see Section C.9, "Error Messages When
  18479. Running Debug Setup."  %@NL@%
  18480.  
  18481. Follow these steps to install additional drivers and virtual devices with
  18482. Setup:  %@NL@%
  18483.  
  18484.  
  18485.   1.  Exit Windows.%@NL@%
  18486.  
  18487. %@STUB@%      Do not use the DOS Prompt icon in the Main Group window. Using this
  18488.       icon will result in an incorrect setup.%@NL@%
  18489.  
  18490.   2.  Type %@AI@%setup%@AE@% and press ENTER.%@NL@%
  18491.  
  18492. %@STUB@%      Setup lists your current Windows configuration.%@NL@%
  18493.  
  18494.   3.  Press the UP or DOWN ARROW key to select the setting you want to
  18495.       change and press ENTER.%@NL@%
  18496.  
  18497. %@STUB@%      A list of choices is displayed.%@NL@%
  18498.  
  18499.   4.  Scroll to the bottom of the list using the DOWN ARROW key.%@NL@%
  18500.  
  18501.   5.  Select Other and press ENTER.%@NL@%
  18502.  
  18503. %@STUB@%      Setup prompts you for the disk containing the device driver or virtual
  18504.       device.%@NL@%
  18505.  
  18506.   6.  Insert your distribution disk into drive A. Setup displays a list of
  18507.       the device drivers or virtual devices defined in the OEMSETUP.INF file
  18508.       on that disk. Then select the appropriate driver or virtual device and
  18509.       press ENTER.%@NL@%
  18510.  
  18511. %@STUB@%      Or type the pathname of the device driver or virtual device and press
  18512.       ENTER.%@NL@%
  18513.  
  18514.   7.  Press ENTER to complete the process.%@NL@%
  18515.  
  18516.  
  18517. Be sure to install and test all the files described in your OEMSETUP.INF
  18518. file.  %@NL@%
  18519.  
  18520. Setup automatically expands your files if you choose to use the COMPRESS.EXE
  18521. utility supplied in the SDK to compress your files. Notice, however, that
  18522. OEMSETUP.INF should %@AI@%not%@AE@% be compressed.  %@NL@%
  18523.  
  18524.  
  18525. %@3@%%@CR:C6A-C0018   @%%@AB@%C.7.2  Testing with Control Panel%@AE@%%@EH@%%@NL@%
  18526.  
  18527. To test your OEMSETUP.INF file and the DESCRIPTION in your printer driver's
  18528. .DEF file, you need to run Control Panel.  %@NL@%
  18529.  
  18530. Additional printer drivers are installed the same way you would install a
  18531. driver supplied by Windows. Instead of selecting a printer from the list (of
  18532. those defined in the SETUP.INF file) to install, you would select Unlisted
  18533. Printer from the bottom of the list.  %@NL@%
  18534.  
  18535. Follow these steps to install an additional printer driver:  %@NL@%
  18536.  
  18537.  
  18538.   1.  Run Control Panel and select the Printers Icon.%@NL@%
  18539.  
  18540.   2.  Choose the Add Printer button.%@NL@%
  18541.  
  18542.   3.  Select Unlisted Printer from the bottom of the printers list.%@NL@%
  18543.  
  18544.   4.  Choose the Install button.%@NL@%
  18545.  
  18546.   5.  Insert your distribution disk, if necessary.%@NL@%
  18547.  
  18548.   6.  Select the appropriate drive and directory path.%@NL@%
  18549.  
  18550.   7.  Select OK.%@NL@%
  18551.  
  18552.   8.  Select the appropriate driver filename from the Driver Files list.%@NL@%
  18553.  
  18554.   9.  Select OK.%@NL@%
  18555.  
  18556.  
  18557. At this point, Control Panel looks for OEMSETUP.INF. If found, Control Panel
  18558. will install all the raster font and associated files defined in the
  18559. [io.dependent] section (if applicable to the driver file that you selected).
  18560. %@NL@%
  18561.  
  18562. If OEMSETUP.INF does not exist on this disk or in the specified directory,
  18563. Control Panel inspects the DESCRIPTION line within the driver and copies the
  18564. raster fonts that match exactly the values defined there.  %@NL@%
  18565.  
  18566. Control Panel expands your files automatically if you choose to use the
  18567. COMPRESS.EXE utility supplied in the SDK to compress your files. Notice,
  18568. however, that the OEMSETUP.INF file should %@AI@%not%@AE@% be compressed.  %@NL@%
  18569.  
  18570.  
  18571. %@2@%%@CR:C6A-C0019   @%%@AB@%C.8  Informing Microsoft About the Availability of Your Driver and/or%@EH@%
  18572. %@AB@%Virtual Device%@AE@%%@NL@%
  18573.  
  18574. Microsoft publishes the %@AI@%Microsoft Windows Software and Hardware Directory%@AE@%.
  18575. This publication is available to both developers and Windows users. The
  18576. directory contains information on the following:  %@NL@%
  18577.  
  18578.  
  18579.   ■   Windows-compatible applications%@NL@%
  18580.  
  18581.   ■   Windows device drivers%@NL@%
  18582.  
  18583.   ■   Windows virtual devices%@NL@%
  18584.  
  18585.   ■   Windows-based consultants%@NL@%
  18586.  
  18587.  
  18588. Included in this package is a %@AI@%Microsoft Windows Directory Survey%@AE@%. If you
  18589. want to publish information in the directory about your device drivers
  18590. and/or virtual devices, please complete this survey and return it to the
  18591. address listed on the survey form. There is no fee for taking advantage of
  18592. this opportunity to tell Microsoft Windows 3.0 users all about the support
  18593. for your product.  %@NL@%
  18594.  
  18595.  
  18596. %@2@%%@CR:C6A-C0020   @%%@AB@%C.9  Error Messages When Running Debug Setup%@AE@%%@EH@%%@NL@%
  18597.  
  18598. When using the debug version of Setup that is provided on the DDK disks, you
  18599. may see several error messages regarding possible Setup assertion failures.
  18600. The following list provides the error message numbers and a brief
  18601. description of each along with possible solutions:  %@NL@%
  18602.  
  18603. %@TH:  37  2307 02 34 44 @%Message                           Description%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%SUINF.C:68:                       Setup could not find a suitable (correct                                   aspect ratio) system font for the display                                   driver selected. Ensure that a matching                                   aspect ratio font is available in the                                   [sysfonts] section of the .INF file.SUINF.C:77:                       Setup could not find a suitable (correct                                   aspect ratio) OEM font for the display                                   driver selected. Ensure that a matching                                   aspect ratio font is available in the                                   [oemfonts] section of the .INF file.SUINF.C:80:                       Setup could not find a suitable (correct                                   aspect ratio) OEM font for the display                                   driver selected. Ensure that a matching                                   aspect ratio font is available in the                                   [oemfonts] section of the .INF file.SUINF.C:84:                       Setup could not find a suitable (correct                                   aspect ratio) fixed font for the display                                   driver selected. Ensure that a matching                                   aspect ratio font is available in the                                   [fixedfonts] section of the .INF file.SUINF.C:165:                      Setup detected a machine for which it                                   could not find a machine entry in the                                   [machine] section of the .INF file. SUUTIL.C:451:                     Setup cannot find a disk entry in the                                   [disks] section of SETUP.INF for a logical                                  disk ID given in the .INF file. Check to                                   see that all logical disk ID values have a                                  corresponding entry in the [disks] section                                  of the .INF file.%@TE:  37  2307 02 34 44 @%
  18604.  
  18605.  
  18606.  
  18607.  
  18608.  
  18609.  
  18610. %@CR:C6A-D0001   @%%@1@%%@AB@%Appendix D  Windows INT 2FH API%@AE@%%@EH@%%@NL@%
  18611. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18612.  
  18613. Enhanced Windows 3.0 supports an application program interface (API)
  18614. designed to enable MS-DOS device drivers, TSR programs, and application
  18615. programs to take full advantage of the multitasking abilities of the
  18616. enhanced Windows environment.  %@NL@%
  18617.  
  18618. Most application program writers will use the interface that releases the
  18619. current virtual machine's time-slice. This API allows enhanced Windows and
  18620. OS/2 to multitask non-Windows specific MS-DOS applications more efficiently.
  18621. The Release Time Slice API should be used by applications even if they are
  18622. not running under enhanced Windows. This allows OS/2 to detect idleness in
  18623. MS-DOS applications. OS/2 will recognize the enhanced Windows release
  18624. time-slice call but it does not support other enhanced Windows APIs.  %@NL@%
  18625.  
  18626. The Microsoft 80286 DOS extender will issue the initialization and exit INT
  18627. 2FH API calls so that real mode software can free extended memory through
  18628. XMS. The 286 DOS extender also supports the Int 31h service detection Int
  18629. 2FH API call.  %@NL@%
  18630.  
  18631. Other APIs are used by MS-DOS device drivers and TSRs that have enhanced
  18632. Windows specific requirements.  %@NL@%
  18633.  
  18634.  
  18635. %@2@%%@CR:C6A-D0002   @%%@AB@%D.1  Call-In Interfaces%@AE@%%@EH@%%@NL@%
  18636.  
  18637. Call-in interfaces are APIs that real mode MS-DOS device drivers, TSRs, and
  18638. applications use to communicate with enhanced Windows. These include:  %@NL@%
  18639.  
  18640.  
  18641.   ■   Get Windows version%@NL@%
  18642.  
  18643.   ■   Get virtual machine ID%@NL@%
  18644.  
  18645.   ■   Begin critical section%@NL@%
  18646.  
  18647.   ■   End critical section%@NL@%
  18648.  
  18649.   ■   Release time slice%@NL@%
  18650.  
  18651.   ■   Get device API entry point%@NL@%
  18652.  
  18653.   ■   Switch VMs and callback
  18654. %@NL@%
  18655.  
  18656.  
  18657.  
  18658. %@3@%%@CR:C6A-D0003   @%%@AB@%D.1.1  Enhanced Windows Installation Check (AX=1600H)%@AE@%%@EH@%%@NL@%
  18659.  
  18660. This API call is valid under all versions of enhanced Windows. If a program
  18661. intends to use a enhanced Windows API, it must first make sure that the
  18662. enhanced Windows environment is running. To do this, issue:  %@NL@%
  18663.  
  18664. %@AS@%  mov ax, 1600h
  18665. %@AS@%  int 2Fh
  18666. %@AS@%  test al, 7Fh
  18667. %@AS@%  jz Not_Running_Win386
  18668. %@AS@%  (Otherwise enhanced Windows is running)
  18669. %@AS@%  cmp al, 1
  18670. %@AS@%  je Running_Ver_2xx
  18671. %@AS@%  cmp al, -1
  18672. %@AS@%  je Running_Ver_2xx
  18673. %@AS@%  (Else al contains major version, AH contains minor)%@AE@%
  18674.  
  18675. If 0 or 80H is returned in AL, enhanced Windows is not running. Any other
  18676. value means that enhanced Windows is running. A value of 1 or -1 (0FFH)
  18677. indicates that the application is running under enhanced Windows version 2.0
  18678. or 3.0. Otherwise, %@AB@%AL%@AE@% will contain the major version number (3 or higher)
  18679. and %@AB@%AH%@AE@% will contain the minor version number. The table below summarizes the
  18680. possible return values:  %@NL@%
  18681.  
  18682. %@TH:  14   517 02 15 51 12 @%Value in AL    Meaning%@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%00H            Enhanced Windows 3.x or Windows/386 version 2.xx                is not running80H            Enhanced Windows 3.x or Windows/386 version 2.xx                is not running01H            Windows/386 version 2.xx runningFFH            Windows/386 version 2.xx runningAnything else  AL = Major version number                          AH = Minor%@TE:  14   517 02 15 51 12 @%
  18683.  
  18684.  
  18685. %@3@%%@CR:C6A-D0004   @%%@AB@%D.1.2  Releasing Current Virtual Machine's Time-Slice (AX=1680h)%@AE@%%@EH@%%@NL@%
  18686.  
  18687. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18688. %@AB@%NOTE %@AE@%%@AI@%
  18689. %@AI@%%@AI@%This API should be used only by non-Windows specific applications. Windows
  18690. %@AI@%programs should yield their time by calling the WaitMessage%@AI@% function.%@AE@%%@AE@%
  18691. %@AE@%────────────────────────────────────────────────────────────────────────────%@NL@%
  18692.  
  18693. This API is used by programs to indicate that the program is idle (usually
  18694. waiting for the user to type something). By issuing this interrupt,
  18695. applications prevent enhanced Windows from wasting time running a program
  18696. that is essentially doing nothing. This allows other programs to use the
  18697. time.  %@NL@%
  18698.  
  18699. Programs should always use this API even if they are not Windows-specific
  18700. applications and even if they are not currently running under Windows in 386
  18701. enhanced mode. This allows OS/2 to detect idleness even though it does not
  18702. support the complete enhanced Windows API. The only check you should make
  18703. before issuing the API call is to make sure that the INT 2FH interrupt
  18704. vector is not zero.  %@NL@%
  18705.  
  18706. Sample code:  %@NL@%
  18707.  
  18708. %@AS@%  mov ax, 352Fh
  18709. %@AS@%   int 21h  ; DOS get vector 2Fh
  18710. %@AS@%   mov ax, es  ; ES:BX = Vector
  18711. %@AS@%   or ax, bx  ; Q: Is it zero?
  18712. %@AS@%   jz Skip_Idle_Call ;    Y: Skip this
  18713. %@AS@%   mov ax, 1680h ;    N: Tell Win
  18714. %@AS@%   int 2Fh  ;       we're idle.
  18715. %@AS@%  Skip_Idle_Call:%@AE@%
  18716.  
  18717. If the API is supported, the INT 2FH will return with %@AB@%AL%@AE@%=0, otherwise it
  18718. will return with AL unchanged (80h). Usually application programs will not
  18719. be interested in the return value.  %@NL@%
  18720.  
  18721. Note that when an application uses this API it will continue to run
  18722. occasionally so your program should re-issue the interrupt in the program's
  18723. idle loop. In other words, this API does NOT block your application until a
  18724. key is pressed.  %@NL@%
  18725.  
  18726.  
  18727. %@3@%%@CR:C6A-D0005   @%%@AB@%D.1.3  Begin Critical Section (AX=1681h)%@AE@%%@EH@%%@NL@%
  18728.  
  18729. If an MS-DOS device driver or TSR needs to prevent a task-switch from
  18730. occurring, it should call this interface. When a virtual machine is in a
  18731. critical section, no other task will be allowed to run except to service
  18732. hardware interrupts. For this reason, the critical section should be freed
  18733. (using the end critical section API) as soon as possible.  %@NL@%
  18734.  
  18735.  
  18736. %@3@%%@CR:C6A-D0006   @%%@AB@%D.1.4  End Critical Section (AX=1682h)%@AE@%%@EH@%%@NL@%
  18737.  
  18738. This API must be called to release ownership of the critical section that
  18739. was claimed using the Begin Critical Section API. Every call to Begin
  18740. Critical Section must be followed by a matching call to End Critical
  18741. Section.  %@NL@%
  18742.  
  18743.  
  18744. %@3@%%@CR:C6A-D0007   @%%@AB@%D.1.5  Get Current Virtual Machine ID (AX=1683h)%@AE@%%@EH@%%@NL@%
  18745.  
  18746. This API returns with %@AB@%BX%@AE@% = Current virtual machine ID. The ID is unique for
  18747. each virtual machine. Although Windows currently runs in VM 1, your software
  18748. should not rely on this. Also, if a VM is destroyed, its ID may be reused by
  18749. another new virtual machine. Be sure to treat VM IDs as a word (not a byte).
  18750. An ID of 0 will %@AI@%never%@AE@% be returned.  %@NL@%
  18751.  
  18752.  
  18753. %@3@%%@CR:C6A-D0008   @%%@AB@%D.1.6  Get Device API Entry Point (AX=1684h)%@AE@%%@EH@%%@NL@%
  18754.  
  18755. Some VxDs (enhanced Windows device drivers) provide a set of services that
  18756. application programs can access. For example, the Virtual Display Device
  18757. provides services that the Windows old application program uses to display
  18758. MS-DOS programs in a window. Any VxD can support an API for MS-DOS
  18759. applications. Your program must issue an INT 2FH with %@AB@%AX%@AE@%=1684h and %@AB@%BX%@AE@% =
  18760. Virtual device ID. The entry point address will be returned in %@AB@%ES:DI%@AE@%. Your
  18761. application must execute a FAR CALL to this address to call the virtual
  18762. device. If the value returned is 0:0 then the device does not support an
  18763. API, otherwise %@AB@%ES:DI%@AE@% is the address of the procedure to call. You should
  18764. either make sure your application is running on version 3.0 or zero %@AB@%ES%@AE@% and
  18765. %@AB@%DI%@AE@% before using this API.  %@NL@%
  18766.  
  18767. %@AS@%  xor di, di ; * Only necessary if you have  *
  18768. %@AS@%  mov es, di ; * not checked for Win ver 3.0 *
  18769. %@AS@%  mov ax, 1684h
  18770. %@AS@%  mov bx, My_Device_ID
  18771. %@AS@%  int 2Fh
  18772. %@AS@%  mov ax, es
  18773. %@AS@%  or ax, di
  18774. %@AS@%  jz API_Is_Not_Supported
  18775. %@AS@%  (else API address in ES:DI)%@AE@%
  18776.  
  18777. The definition of a device API is specified by the virtual device driver.
  18778. Refer to individual virtual device documentation for details.  %@NL@%
  18779.  
  18780.  
  18781. %@3@%%@CR:C6A-D0009   @%%@AB@%D.1.7  Switch VMs and CallBack (AX=1685h)%@AE@%%@EH@%%@NL@%
  18782.  
  18783. Some MS-DOS devices, such as networks, need to perform functions in a
  18784. specific virtual machine. These devices can use this interface to force the
  18785. appropriate virtual machine to be installed so that they can modify the VM's
  18786. data. Refer to Chapter 24, "Primary Scheduler Services," for information on
  18787. appropriate priority boosts.  %@NL@%
  18788.  
  18789. Entry: %@AB@%AX%@AE@% = 1685h %@AB@% BX %@AE@%= VM ID of virtual machine to switch to %@AB@% CX%@AE@% = Flags
  18790. Bit 0 = 1 if wait until interrupts enabled  Bit 1 = 1 if wait until critical
  18791. section unowned  All other bits must be 0 %@AB@% DX:SI%@AE@% = Priority boost (%@AB@%DX%@AE@%=High
  18792. word, %@AB@%SI%@AE@%=Low word) %@AB@% ES:DI%@AE@% = %@AB@%CS:IP%@AE@% of procedure to call  %@NL@%
  18793.  
  18794. Exit:  %@NL@%
  18795.  
  18796. %@AS@%  If carry set then
  18797. %@AS@%     AX = Error code
  18798. %@AS@%  else
  18799. %@AS@%     Event will be called or has been called already.%@AE@%
  18800.  
  18801. Error codes: 1 = Invalid VM ID  2 = Invalid priority boost  3 = Invalid
  18802. flags  %@NL@%
  18803.  
  18804. Callback procedure: Must save all registers modified  Must IRET to caller
  18805. Priority will remain boosted until procedure irets  %@NL@%
  18806.  
  18807.  
  18808. %@3@%%@CR:C6A-D0010   @%%@AB@%D.1.8  Detect Presence of INT 31H Services (AX=1686h)%@AE@%%@EH@%%@NL@%
  18809.  
  18810. If a program needs to detect the presence of the INT 31H protected mode API,
  18811. it can use this INT 2FH. Note that this particular API is also supported by
  18812. the Microsoft 80286 DOS extender for protected mode Windows. INT 31H
  18813. services are only supported for protected mode programs.  %@NL@%
  18814.  
  18815.  
  18816. %@3@%%@AB@%Entry%@AE@%%@EH@%%@NL@%
  18817.  
  18818.  %@AB@%AX%@AE@% = 1686h  %@NL@%
  18819.  
  18820.  
  18821. %@3@%%@AB@%Exit%@AE@%%@EH@%%@NL@%
  18822.  
  18823. If AX = 0 then    INT 31H services are available and can be called else (AX
  18824. 0)    zINT 31H services are not available  %@NL@%
  18825.  
  18826.  
  18827. %@2@%%@CR:C6A-D0011   @%%@AB@%D.2  Call Out Interfaces%@AE@%%@EH@%%@NL@%
  18828. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18829.  
  18830. Enhanced Windows will broadcast INT 2FH to real mode device drivers and TSRs
  18831. to inform them of various activities. These can be used to load enhanced
  18832. Windows installable devices, free extended memory, instance per-VM data
  18833. structures, and turn on or off various device services or features. For
  18834. example, SmartDrv can free extended memory for enhanced Windows to use when
  18835. the initialization call is made and then reclaim it when it receives the
  18836. termination call. MS-DOS devices such as networks can inform the enhanced
  18837. Windows loader to load a special protected mode installable device that
  18838. cooperates with the real mode network device driver.  %@NL@%
  18839.  
  18840.  
  18841. %@3@%%@AB@%D.2.1  Enhanced Windows and 286 DOS Extender Initialization (AX=1605h)%@AE@%%@EH@%%@NL@%
  18842.  
  18843. The enhanced Windows loader and the Microsoft 286 DOS extender will
  18844. broadcast an INT 2FH with the following parameters:  %@NL@%
  18845.  
  18846. %@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
  18847. enhanced Windows initialization    1 if Microsoft 286 DOS extender
  18848. initialization    All other bits reserved and undefined. %@AB@%DI%@AE@% = Version #:
  18849. major version in upper byte, minor version in lower byte  %@NL@%
  18850.  
  18851. Any MS-DOS device driver or TSR can hook Int 2FH and watch for this
  18852. particular broadcast. When this broadcast is received, the real mode
  18853. software can inform enhanced Windows or the 286 DOS extender that it should
  18854. not load by returning with %@AB@%CX%@AE@%  0. The TSR or device that fails the
  18855. initialization should print an error message so the user can take
  18856. appropriate steps to reconfigure the machine. Enhanced Windows and the
  18857. Microsoft DOS extender will not print an error message─they will only issue
  18858. the termination API call and return to MS-DOS.  %@NL@%
  18859.  
  18860. If it is OK for enhanced Windows or the DOS extender to load, the real mode
  18861. software should not modify CX and may want to do one or more of the
  18862. following:  %@NL@%
  18863.  
  18864.  
  18865.   ■   Release extended memory through the XMS interface.%@NL@%
  18866.  
  18867.   ■   Switch back to real mode (if currently in virtual 8086 mode) or set
  18868.       %@AB@%DS:SI%@AE@% to the Virtual 8086 mode enable/disable routine address.%@NL@%
  18869.  
  18870.   ■   Load an installable device (enhanced Windows only).%@NL@%
  18871.  
  18872.   ■   Instance private data structures (enhanced Windows only).%@NL@%
  18873.  
  18874.  
  18875. The DOS extender only pays attention to the value returned in %@AB@%CX%@AE@%. It will
  18876. not instance any data or load enhanced Windows installable device drivers.
  18877. The DOS extender only issues this call so that extended memory can be
  18878. released and the machine can be placed in real mode if it is currently in
  18879. virtual 8086 mode.  %@NL@%
  18880.  
  18881. Instance data refers to data in a TSR or MS-DOS device driver that must have
  18882. a private copy in each VM. Normally, all TSRs and devices loaded before
  18883. enhanced Windows is run are considered global memory. That means that all of
  18884. the data is shared between virtual machines. However, there are some pieces
  18885. of data that actually should be maintained on a per-VM basis. For example,
  18886. the MS-DOS command line buffer needs to be instanced (this is done
  18887. automatically by enhanced Windows). However, TSRs such as the MS-DOS command
  18888. line editors will not function properly unless they identify the data that
  18889. needs to be instanced.  %@NL@%
  18890.  
  18891. The first two options (release extended memory, or switch from V86 to real
  18892. mode) are up to the device to handle on its own. The last options require
  18893. returning a pointer to a list of structures to load. Your INT 2FH hook must
  18894. first chain to the next INT 2FH handler with all registers unmodified. When
  18895. the handler returns you must take the %@AB@%ES:BX %@AE@%value returned and place it in
  18896. the following data structure in the %@AI@%Next_Dev_Ptr%@AE@% field:  %@NL@%
  18897.  
  18898. %@AS@%  Win386_Startup_Info_Struc STRUC
  18899. %@AS@%  SIS_Version   db 3, 0
  18900. %@AS@%  SIS_Next_Dev_Ptr   dd ?
  18901. %@AS@%  SIS_Virt_Dev_File_Ptr  dd 0
  18902. %@AS@%  SIS_Reference_Data  dd ?
  18903. %@AS@%  SIS_Instance_Data_Ptr  dd 0
  18904. %@AS@%  Win386_Startup_Info_Struc ENDS%@AE@%
  18905.  
  18906. Your software must point %@AB@%ES:BX%@AE@% at this structure and return. This allows
  18907. multiple enhanced Windows installable devices to be loaded through a single
  18908. INT 2FH call.  %@NL@%
  18909.  
  18910. The %@AB@%SIS_Version%@AE@% field is used by enhanced Windows to determine the size of
  18911. the structure. This field should always contain 3, 0 to indicate that it is
  18912. version 3.0.  %@NL@%
  18913.  
  18914. The %@AB@%SIS_Next_Dev_Ptr%@AE@% points to the next structure in the list. This field
  18915. must be filled in with the returned %@AB@%ES:BX%@AE@% after your software chains to the
  18916. next INT 2FH handler.  %@NL@%
  18917.  
  18918. %@AB@%SIS_Virt_Dev_File_Ptr%@AE@% is a pointer to an ASCIIZ string that contains the
  18919. name of a enhanced Windows virtual device file. MS-DOS devices such as
  18920. networks use this to force a special enhanced Windows protected mode virtual
  18921. device to be loaded. If this field is zero, then no device will be loaded.  %@NL@%
  18922.  
  18923. The %@AB@%SIS_Reference_Data%@AE@% is only used when the %@AB@%SIS_Virt_Dev_File_Ptr%@AE@% is
  18924. non-zero. This DWORD will be passed to the virtual device when it is
  18925. initialized. The DWORD can contain any value. Often it contains a pointer to
  18926. some device specific data structure.  %@NL@%
  18927.  
  18928. The %@AB@%SIS_Instance_Data_Ptr%@AE@% field points to a list of data to be instanced. If
  18929. the field is zero, then no data will be instanced. Each entry in the list
  18930. has the following structure:  %@NL@%
  18931.  
  18932. %@AS@%  Instance_Item_Struc STRUC
  18933. %@AS@%   IIS_Ptr   dd ?
  18934. %@AS@%   IIS_Size  dw ?
  18935. %@AS@%  Instance_Item_Struc ENDS%@AE@%
  18936.  
  18937. The list is terminated with a zero DWORD.  %@NL@%
  18938.  
  18939. Your handler must preserve all registers except the values returned in %@AB@%ES,
  18940. %@AB@%BX,%@AE@% and %@AB@%CX%@AE@%. It must also preserve %@AB@%DS%@AE@% and %@AB@%SI%@AE@% unless it explicitly changes
  18941. them to return the address of the virtual 8086 mode enable/disable routine.
  18942. Remember, any device that returns with %@AB@%CX%@AE@%  0 will force enhanced Windows or
  18943. the 286 DOS extender to abort. If the load is aborted, the termination INT
  18944. 2FH will be issued immediately.  %@NL@%
  18945.  
  18946. Enhanced Windows supports loading with a virtual mode program such as an EMM
  18947. "LIMulator" running provided that the program supports a virtual 8086 mode
  18948. enable/disable callback routine. The address of the routine must be returned
  18949. in %@AB@%DS:SI%@AE@%. If your TSR or device driver sets this return parameter, it should
  18950. first check to make sure that %@AB@%DS%@AE@% and%@AB@% SI%@AE@% are both zero. If they are non-zero,
  18951. then fail the initialization by setting CX=non-zero. Notice that the
  18952. Microsoft 286 DOS extender will not call this routine. Therefore, you must
  18953. either set the processor into real mode during the initialization INT 2FH or
  18954. set CX=non-zero to abort the load.  %@NL@%
  18955.  
  18956. The virtual mode enable/disable callback will be called with %@AB@%AX%@AE@%=0 to disable
  18957. V86 mode (return to real mode) and %@AB@%AX%@AE@%=1 to re-enable V86 mode. Just before
  18958. attempting to enter protected mode enhanced Windows will disable V86 mode
  18959. after every VxD has been loaded. It will call the enable/disable routine
  18960. with %@AB@%AX%@AE@%=0 and with interrupts disabled. Do not enable interrupts in your
  18961. routine unless the routine will return with Carry set to indicate failure.
  18962. After enhanced Windows exits, it will call the enable/disable routine in
  18963. real mode with %@AB@%AX%@AE@%=1 and with interrupts disabled to set the machine back
  18964. into V86 mode.  %@NL@%
  18965.  
  18966. The enable/disable routine will be called with a FAR return frame. It must
  18967. return with the carry flag clear to indicate success or Carry set to
  18968. indicate an error. If an error is returned from the disable call, then
  18969. enhanced Windows will abort. The error return from the enable V86 call will
  18970. be ignored and the machine will be left in real mode. It is the
  18971. responsibility of the enable/disable routine to print an error message.  %@NL@%
  18972.  
  18973.  
  18974. %@3@%%@AB@%D.2.2  Enhanced Windows and 286 DOS Extender Exit (AX=1606h)%@AE@%%@EH@%%@NL@%
  18975.  
  18976. When enhanced Windows or the 286 DOS extender terminates, it will broadcast
  18977. an INT 2FH with the following parameters:  %@NL@%
  18978.  
  18979. %@AB@%AX%@AE@% = 1606H. %@AB@%DX%@AE@% = Flags Bit 0 = 0 if enhanced Windows exit 1 if Microsoft 286
  18980. DOS extender exit All other bits reserved and undefined.  %@NL@%
  18981.  
  18982. This call will be issued in real mode. It allows devices and TSRs to undo
  18983. anything they did when enhanced Windows or the DOS extender initialized. For
  18984. example, a device like SmartDrv may re-allocate extended memory that it
  18985. released during initialization.  %@NL@%
  18986.  
  18987. If the initialization broadcast fails (returns with %@AB@%CX%@AE@%  0) then this
  18988. broadcast will be issued immediately.  %@NL@%
  18989.  
  18990.  
  18991. %@3@%%@AB@%D.2.3  Device Call Out API (AX=1607h)%@AE@%%@EH@%%@NL@%
  18992.  
  18993. This API is, in reality, more of a convention than an API. It specifies a
  18994. standard mechanism for enhanced Windows virtual devices to talk to MS-DOS
  18995. device drivers and TSRs.  %@NL@%
  18996.  
  18997. Some devices need to ask real-mode MS-DOS software for information. For
  18998. example, the Virtual NetBIOS mapper VxD will issue an INT 2FH to determine
  18999. if a network supports an extended NetBIOS API. The standard device call out
  19000. will have %@AB@%AX%@AE@%=1607H and %@AB@%BX%@AE@%=Device ID. As with the device API entry point
  19001. call-in interface, the details of the interface are specified by the device
  19002. that issues the interrupt.  %@NL@%
  19003.  
  19004. This interrupt may be issued at any time, either in real mode or after
  19005. enhanced Windows has begun execution.  %@NL@%
  19006.  
  19007.  
  19008. %@3@%%@AB@%D.2.4  Enhanced Windows Initialization Complete (AX=1608h)%@AE@%%@EH@%%@NL@%
  19009.  
  19010. This API call is made by enhanced Windows after all the installable devices
  19011. have initialized. At this point, it is still possible to identify instance
  19012. data and perform other functions that are restricted to enhanced Windows
  19013. initialization time. The enhanced Windows device initialization phase is
  19014. complete, so it is possible to call enhanced Windows device API entry
  19015. points.  %@NL@%
  19016.  
  19017. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19018. %@AU@%WARNING%@AE@%
  19019.  
  19020. Real mode software such as a TSR or DOS device driver may be called after
  19021. the enhanced Windows initialization call and before this API call is made.
  19022. It is the responsibility of the real mode software to detect and properly
  19023. handle this situation.
  19024. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19025.  
  19026.  
  19027. %@3@%%@AB@%D.2.5  Enhanced Windows Begin Exit (AX=1609H)%@AE@%%@EH@%%@NL@%
  19028.  
  19029. This API call is issued at the beginning of a normal Enhanced Windows exit
  19030. sequence. It is sent at the start of the %@AB@%Sys_VM_Terminate%@AE@% device control
  19031. call phase. All VxDs still exist so calls to device API entry points are
  19032. still valid.  %@NL@%
  19033.  
  19034. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19035. %@AU@%WARNING%@AE@%
  19036.  
  19037. This call will not be made in the event of a fatal system crash. Also, real
  19038. mode code may be executed after this API call has been made and before
  19039. enhanced Windows has returned to real mode. It is the responsibility of the
  19040. real mode software to detect and properly handle these situations.
  19041. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19042.  
  19043.  
  19044. %@2@%%@CR:C6A-D0012   @%%@AB@%D.3  Windows/386 Version 2.xx API Compatibility%@AE@%%@EH@%%@NL@%
  19045. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19046.  
  19047. The release of Windows/386 (version 2.xx) had a limited Application Program
  19048. Interface that was defined to help support real mode MS-DOS device drivers
  19049. such as networks. The 2.xx API allows MS-DOS programs to:  %@NL@%
  19050.  
  19051.  
  19052.   ■   Determine if Windows/386 or enhanced Windows (version 3.0) is running%@NL@%
  19053.  
  19054.   ■   Get the ID of the current Virtual Machine%@NL@%
  19055.  
  19056.   ■   Enter and leave a global critical section%@NL@%
  19057.  
  19058.  
  19059. The APIs used under version 2.xx are fairly complex and inflexible. We
  19060. suggest that, unless your application or device driver absolutely needs to
  19061. run under version 2.xx, you ignore all version 2.xx APIs and use the 3.0
  19062. APIs instead.  %@NL@%
  19063.  
  19064.  
  19065. %@3@%%@AB@%D.3.1  Installation Check%@AE@%%@EH@%%@NL@%
  19066.  
  19067. To test for Windows/386 version 2.xx, you should issue an Int 2fh with
  19068. %@AB@%AX%@AE@%=1600h. Refer to Windows Installation Check for complete documentation for
  19069. this API call.  %@NL@%
  19070.  
  19071.  
  19072. %@3@%%@AB@%D.3.2  Determining the Current Virtual Machine (Get VM ID)%@AE@%%@EH@%%@NL@%
  19073.  
  19074. Once the software has determined that it is running under Windows/386
  19075. version 2.xx, it must make another call to get the API procedure address. To
  19076. do this, issue:  %@NL@%
  19077.  
  19078. %@AS@%  mov ax, 1602h
  19079. %@AS@%   int 2fh
  19080. %@AS@%   (ES:DI -> Windows/386 API procedure)%@AE@%
  19081.  
  19082. The API procedure is the same address for every virtual machine, so you will
  19083. need to issue this call only once (although you can issue it as often as you
  19084. want).  %@NL@%
  19085.  
  19086. To get the ID of the current virtual machine %@AI@%jump%@AE@% to the Windows/386 API
  19087. procedure with %@AB@%AX%@AE@% = 0 and %@AB@%ES:DI%@AE@% - the address to return to.  %@NL@%
  19088.  
  19089. Sample code:  %@NL@%
  19090.  
  19091. %@AS@%  mov di, cs
  19092. %@AS@%   mov es, di
  19093. %@AS@%   mov di, OFFSET Win386_AIP_Return
  19094. %@AS@%   xor ax, ax   ; AX = 0
  19095. %@AS@%   jmp [Win386_API_Proc]
  19096. %@AS@%  Win386_API_Return:
  19097. %@AS@%   (Now BX contains the current VM ID)%@AE@%
  19098.  
  19099. Note that you must place the return address in %@AB@%ES:DI%@AE@% and JUMP to the API
  19100. procedure. When enhanced Windows returns control to your program it will
  19101. return to %@AB@%ES:DI%@AE@%.  %@NL@%
  19102.  
  19103. This interface is supported under version 3.0 only for compatibility
  19104. reasons. New MS-DOS devices or applications should use the version 3.0
  19105. interface.  %@NL@%
  19106.  
  19107.  
  19108. %@3@%%@AB@%D.3.3  Critical Section Handling%@AE@%%@EH@%%@NL@%
  19109.  
  19110. Windows/386 version 2.xx does not support API calls to enter and leave a
  19111. critical section. However, by incrementing and decrementing a special DOS
  19112. critical section counter called the InDOS flag, you can force the current
  19113. virtual machine into a critical section. Incrementing InDOS is not
  19114. sufficient to enter a critical section in version 3.0. You will need to make
  19115. an API call first and then, if it fails, increment the InDOS flag.  %@NL@%
  19116.  
  19117. To get the address of the InDOS flag, issue the following MS-DOS call
  19118. (documented in %@AI@%The MS-DOS Encyclopedia%@AE@% ):  %@NL@%
  19119.  
  19120. %@AS@%  mov ah, 34h
  19121. %@AS@%   int 21h
  19122. %@AS@%   (ES:BX -> InDOS flag)%@AE@%
  19123.  
  19124. The InDOS flag is a byte within the MS-DOS kernel. The value in InDOS is
  19125. incremented when MS-DOS begins execution of an Interrupt 21H and decremented
  19126. when MS-DOS's processing of that function has completed. When you increment
  19127. the byte, current versions of enhanced Windows will not switch to another
  19128. virtual machine. Therefore, to enter a critical section, you need to
  19129. increment the byte and to leave a critical section you should decrement the
  19130. InDOS flag.  %@NL@%
  19131.  
  19132. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19133. %@AU@%WARNING%@AE@%
  19134.  
  19135. You must make sure your code never decrements the InDOS flag through zero.
  19136. MS-DOS will set the InDOS flag to zero under some error conditions (for
  19137. example, the user types CTRL+C). Also, even if the InDOS flag is non-zero,
  19138. an Int 28H may cause the VM to be rescheduled.
  19139. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19140.  
  19141. For versions 3.xx and greater of Windows you will need to issue an INT 2FH
  19142. %@AB@%AX%@AE@% = 1681H to begin a critical section and %@AB@%AX%@AE@% = 1682H to end a critical
  19143. section. Note that if a program enters the critical section N times, it must
  19144. also issue the end critical section interrupt N times before the critical
  19145. section is actually released. Thus, nested begin/end critical section calls
  19146. are valid. Both of these APIs will zero the %@AB@%AL%@AE@% register to indicate that the
  19147. critical section API is supported. You should %@AI@%not%@AE@% increment and decrement
  19148. InDOS under versions of Windows that support these API calls.  %@NL@%
  19149.  
  19150. Unlike the InDOS critical section method, an INT 28H will%@AI@% not %@AE@%reschedule the
  19151. current virtual machine. The only way a task switch will occur is by
  19152. completely releasing the critical section.  %@NL@%
  19153.  
  19154. Since you need to call the Windows API or increment the InDOS flag you will
  19155. probably want to write two procedures similar to the following:  %@NL@%
  19156.  
  19157. %@AS@%  Begin_Win_Critical_Section:
  19158. %@AS@%   push ax
  19159. %@AS@%   mov ax, 1681h
  19160. %@AS@%   int 2Fh
  19161. %@AS@%   test al, al
  19162. %@AS@%   jz BCS_Quick_Exit
  19163. %@AS@%   push es
  19164. %@AS@%   les ax, [InDOS_Address]
  19165. %@AS@%   inc BYTE PTR es:[ax]
  19166. %@AS@%   pop es
  19167. %@AS@%  BCS_Quick_Exit:
  19168. %@AS@%   pop ax
  19169. %@AS@%   ret
  19170. %@AS@%  
  19171. %@AS@%  End_Win_Critical_Section:
  19172. %@AS@%   push ax
  19173. %@AS@%   mov ax, 1682h
  19174. %@AS@%   int 2Fh
  19175. %@AS@%   test al, al
  19176. %@AS@%   jz ECS_Quick_Exit
  19177. %@AS@%   push es
  19178. %@AS@%   les ax, [InDOS_Address]
  19179. %@AS@%   cmp BYTE PTR es:[ax], 0
  19180. %@AS@%   je (Error handler routine)
  19181. %@AS@%   dec BYTE PTR es:[ax]
  19182. %@AS@%   pop es
  19183. %@AS@%  ECS_Quick_Exit:
  19184. %@AS@%   pop ax
  19185. %@AS@%   ret %@AE@%
  19186.  
  19187. %@AS@%  %@AE@%
  19188.  
  19189.  
  19190.  
  19191. %@CR:GeneralIndex@%
  19192. %@1@%%@AB@%INDEX%@AE@%%@EH@%%@NL@%
  19193. %@AB@%──────────────────────────────────────────────────────────────────────────
  19194.  
  19195. %@2@%%@AB@%    A%@AE@%%@EH@%%@NL@%
  19196. ADDHDR, defined%@BO:       17bcf@%
  19197. AddInstanceItem service%@BO:       4bee4@%
  19198. AdjustInitEndPt function%@BO:       23530@%
  19199. Adjust_Execution_Time service%@BO:       6734f@%
  19200. Adjust_Exec_Priority service%@BO:       60bf8@%
  19201. Allocate_Device_CB_Area service%@BO:       28edf@%
  19202. Allocate_GDT_Selector service%@BO:       2fdf7@%
  19203. Allocate_Global_V86_Data_Area service%@BO:       29cc5@%
  19204. Allocate_LDT_Selector service%@BO:       30824@%
  19205. Allocate_PM_Call_Back service%@BO:       5d5cf@%
  19206. Allocate_Temp_V86_Data_Area service%@BO:       2bcb5@%
  19207. Allocate_V86_Call_Back service%@BO:       5d5cf@%
  19208. API translation%@BO:       964ee@%
  19209.  
  19210. %@2@%%@AB@%    B%@AE@%%@EH@%%@NL@%
  19211. BeginSelection function%@BO:       23919@%
  19212. Begin_Critical_Section service%@BO:       61895@%
  19213. Begin_Nest_Exec service%@BO:       57b24@%
  19214. Begin_Nest_V86_Exec service%@BO:       586ec@%
  19215. Begin_Reentrant_Execution service%@BO:       7f1a0@%
  19216. Begin_Use_Locked_PM_Stack service%@BO:       58b70@%
  19217. Break Point and Callback services
  19218.   Allocate_PM_Call_Back%@BO:       5d5cf@%
  19219.   Allocate_V86_Call_Back%@BO:       5d5cf@%
  19220.   Call_When_Idle%@BO:       5dd07@%
  19221.   Call_When_VM_Returns%@BO:       5e379@%
  19222.   Install_V86_Break_Point%@BO:       5ed0b@%
  19223.   Remove_V86_Break_Point%@BO:       5fa54@%
  19224. BuildDescDWORDs service%@BO:       319f1@%
  19225. Build_Int_Stack_Frame service%@BO:       528fa@%
  19226.  
  19227. %@2@%%@AB@%    C%@AE@%%@EH@%%@NL@%
  19228. Callback procedures%@BO:        fac1@%
  19229. Calling conventions, defined%@BO:       14100@%
  19230. Call_Global_Event service%@BO:       6aa5d@%
  19231. Call_Priority_VM_Event service%@BO:       6ae98@%
  19232. Call_VM_Event service%@BO:       6c204@%
  19233. Call_When_Idle service%@BO:       52df0@%%@BO:       5dd07@%%@BO:       67a21@%
  19234. Call_When_Not_Critical service%@BO:       624c1@%
  19235. Call_When_Task_Switched service%@BO:       62a34@%
  19236. Call_When_VM_Ints_Enabled service%@BO:       534c7@%
  19237. Call_When_VM_Returns service%@BO:       5e379@%
  19238. Cancel_Global_Event service%@BO:       6c66b@%
  19239. Cancel_Priority_VM_Event service%@BO:       6cc11@%
  19240. Cancel_Time_Out service%@BO:       6e834@%
  19241. Cancel_VM_Event service%@BO:       6d33b@%
  19242. CB_High_Linear service%@BO:       4e22c@%
  19243. CheckGRBVersion function%@BO:       255fd@%
  19244. Claim_Critical_Section service%@BO:       62f7e@%
  19245. ConsSelecRec function%@BO:       23b5c@%
  19246. Convert_Boolean_String service%@BO:       75bdc@%
  19247. Convert_Decimal_String service%@BO:       75fe0@%
  19248. Convert_Fixed_Point_String service%@BO:       76526@%
  19249. Convert_Hex_String service%@BO:       76ad5@%
  19250. CopyPageTable service%@BO:       363e2@%
  19251. Crash_Cur_VM service%@BO:       7e09d@%
  19252. Create_Semaphore service%@BO:       632a5@%
  19253. CursorOff function%@BO:       25824@%
  19254. CursorOn function%@BO:       259d5@%
  19255. CursorPosit function%@BO:       25b90@%
  19256.  
  19257. %@2@%%@AB@%    D%@AE@%%@EH@%%@NL@%
  19258. DCP. See Device control procedure%@BO:        bfc4@%
  19259. DDB. See Device descriptor block%@BO:        c377@%
  19260. DeAssign_Device_V86_Pages service%@BO:       2e286@%
  19261. Destroy_Semaphore service%@BO:       633ca@%
  19262. Device control procedure, defined%@BO:        bfc4@%
  19263. Device descriptor block, defined%@BO:        c377@%
  19264. Disable_Global_Trapping service%@BO:       503d0@%
  19265. Disable_Local_Trapping service%@BO:       506fa@%
  19266. Disable_VM_Ints service%@BO:       539be@%
  19267. DPMI. See DOS protected mode interface%@BO:        f1f1@%
  19268.  
  19269. %@2@%%@AB@%    E%@AE@%%@EH@%%@NL@%
  19270. Enable_Global_Trapping service%@BO:       503d0@%
  19271. Enable_Local_Trapping service%@BO:       506fa@%
  19272. Enable_VM_Ints service%@BO:       53beb@%
  19273. EndSelection function%@BO:       23d73@%
  19274. End_Critical_Section service%@BO:       63df2@%
  19275. End_Crit_And_Suspend service%@BO:       634f0@%
  19276. End_Nest_Exec service%@BO:       59092@%
  19277. End_Reentrant_Execution service%@BO:       7f662@%
  19278. End_Use_Locked_PM_Stack service%@BO:       59525@%
  19279. Error Condition services
  19280.   Crash_Cur_VM%@BO:       7e0b1@%
  19281.   Fatal_Error_Handler%@BO:       7e378@%
  19282.   Fatal_Memory_Error%@BO:       7e991@%
  19283. Event services
  19284.   Call_Global_Event%@BO:       6aa71@%
  19285.   Call_Priority_VM_Event%@BO:       6ae98@%
  19286.   Call_VM_Events%@BO:       6c218@%
  19287.   Cancel_Global_Event%@BO:       6c66b@%
  19288.   Cancel_Priority_VM_Event%@BO:       6cc11@%
  19289.   Cancel_VM_Event%@BO:       6d34f@%
  19290.   Hook_NMI_Event%@BO:       6d9b1@%
  19291.   Schedule_Global_Event%@BO:       6dc61@%
  19292.   Schedule_VM_Event%@BO:       6e001@%
  19293. Event
  19294.   defined%@BO:        ce2a@%%@BO:       6a244@%
  19295. Exec_Int service%@BO:       5986e@%
  19296. Exec_VxD_Int service%@BO:       59cb7@%
  19297.  
  19298. %@2@%%@AB@%    F%@AE@%%@EH@%%@NL@%
  19299. Fatal_Error_Handler service%@BO:       7e378@%
  19300. Fatal_Memory_Error service%@BO:       7e991@%
  19301. Free_GDT_Selector service%@BO:       32374@%
  19302. Free_LDT_Selector service%@BO:       32709@%
  19303. Free_Temp_V86_Data_Area service%@BO:       2c73b@%
  19304.  
  19305. %@2@%%@AB@%    G%@AE@%%@EH@%%@NL@%
  19306. GetAppFlatDSAlias service%@BO:       44bb2@%
  19307. GetDemandPageInfo service%@BO:       36fd0@%
  19308. GetDisplayUpd function%@BO:       25015@%
  19309. GetDOSVectors service%@BO:       77b5e@%
  19310. GetFirstV86Page service%@BO:       44869@%
  19311. GetFontList function%@BO:       25daa@%
  19312. GetFreePageCount service%@BO:       37896@%
  19313. GetNulPageHandle service%@BO:       44a7a@%
  19314. GetSetPageOutCount service%@BO:       38022@%
  19315. GetSet_HMA_Info service%@BO:       7479d@%
  19316. GetSysPageCount service%@BO:       3868b@%
  19317. GetVMPageCount service%@BO:       38983@%
  19318. Get_Config_Directory service%@BO:       76f31@%
  19319. Get_Crit_Section_Status service%@BO:       64124@%
  19320. Get_Cur_VM_Handle service%@BO:       7383b@%
  19321. Get_Device_V86_Pages_Array service%@BO:       2e960@%
  19322. Get_Environment_String service%@BO:       77237@%
  19323. Get_Execution_Focus service%@BO:       680fe@%
  19324. Get_Exec_Path service%@BO:       777c8@%
  19325. Get_Last_Updated_System_Time service%@BO:       6ed4a@%
  19326. Get_Last_Updated_VM_Exec_Time service%@BO:       6ef5f@%
  19327. Get_Machine_Info service%@BO:       77edf@%
  19328. Get_Next_Profile_String service%@BO:       783d3@%
  19329. Get_Next_VM_Handle service%@BO:       73a71@%
  19330. Get_PM_Int_Type service%@BO:       53f77@%
  19331. Get_PM_Int_Vector service%@BO:       5442b@%
  19332. Get_Profile_Boolean service%@BO:       7881a@%
  19333. Get_Profile_Decimal_Int service%@BO:       78e0f@%
  19334. Get_Profile_Fixed_Point service%@BO:       793bc@%
  19335. Get_Profile_Hex_Int service%@BO:       799e4@%
  19336. Get_Profile_String service%@BO:       7a020@%
  19337. Get_PSP_Segment service%@BO:       7a436@%
  19338. Get_System_Time service%@BO:       6f175@%
  19339. Get_Sys_VM_Handle service%@BO:       73f55@%
  19340. Get_Time_Slice_Granularity service%@BO:       68358@%
  19341. Get_Time_Slice_Info service%@BO:       685f7@%
  19342. Get_Time_Slice_Priority service%@BO:       688f2@%
  19343. Get_V86_Int_Vector service%@BO:       5442b@%
  19344. Get_VMM_Reenter_Count service%@BO:       74178@%
  19345. Get_VMM_Version service%@BO:       7456b@%
  19346. Get_VM_Exec_Time service%@BO:       6f49e@%
  19347. Global descriptor table, defined%@BO:       2fd83@%
  19348. Grabber DLL functions
  19349.   AdjustInitEndPt%@BO:       23544@%
  19350.   BeginSelection%@BO:       2392d@%
  19351.   CheckGRBVersion%@BO:       25611@%
  19352.   ConsSelecRec%@BO:       23b70@%
  19353.   CursorOff%@BO:       25824@%
  19354.   CursorOn%@BO:       259d5@%
  19355.   CursorPosit%@BO:       25b90@%
  19356.   EndSelection%@BO:       23d87@%
  19357.   GetDisplayUpd%@BO:       25029@%
  19358.   GetFontList%@BO:       25daa@%
  19359.   GrabComplete%@BO:       25f92@%
  19360.   GrabEvent%@BO:       262aa@%
  19361.   GrbUnLockApp%@BO:       265c0@%
  19362.   InitGrabber%@BO:       2676f@%
  19363.   InvertSelection%@BO:       23f1d@%
  19364.   KeySelection%@BO:       24105@%
  19365.   MakeSelctRect%@BO:       24740@%
  19366.   PaintScreen%@BO:       269be@%
  19367.   RenderSelection%@BO:       24c1f@%
  19368.   ScreenFree%@BO:       26d11@%
  19369.   SetPaintFnt%@BO:       26efa@%
  19370.   UpdateScreen%@BO:       2750d@%
  19371. Grabber%@BO:       227fa@%
  19372. GrabComplete function%@BO:       25f7e@%
  19373. GrabEvent function%@BO:       262aa@%
  19374. GrbUnLockApp function%@BO:       265ac@%
  19375.  
  19376. %@2@%%@AB@%    H%@AE@%%@EH@%%@NL@%
  19377. Hardware interrupt hooks%@BO:       10129@%
  19378. HeapAllocate service%@BO:       342b0@%
  19379. HeapFree service%@BO:       34995@%
  19380. HeapGetSize service%@BO:       34cac@%
  19381. HeapReAllocate service%@BO:       34fcc@%
  19382. Hook_Device_Service service%@BO:       7f8af@%
  19383. Hook_Device_V86_API service%@BO:       8034c@%
  19384. Hook_NMI_Event service%@BO:       6d99d@%
  19385. Hook_PM_Device_API service%@BO:       8034c@%
  19386. Hook_V86_Int_Chain service%@BO:       54b13@%
  19387. Hook_V86_Page service%@BO:       2f294@%
  19388.  
  19389. %@2@%%@AB@%    I%@AE@%%@EH@%%@NL@%
  19390. I/O port traps%@BO:        fdf0@%
  19391. I/O services and macros
  19392.   Disable_Global_Trapping%@BO:       503d0@%
  19393.   Disable_Local_Trapping%@BO:       506fa@%
  19394.   Enable_Global_Trapping%@BO:       503d0@%
  19395.   Enable_Local_Trapping%@BO:       506fa@%
  19396.   Install_IO_Handler%@BO:       509b8@%
  19397.   Install_Mult_IO_Handlers%@BO:       50f2e@%
  19398.   Simulate_IO%@BO:       51442@%
  19399. IDT. See Interrupt descriptor table%@BO:        de08@%
  19400. Information services
  19401.   GetSet_HMA_Info%@BO:       747b1@%
  19402.   Get_Cur_VM_Handle%@BO:       7383b@%
  19403.   Get_Next_VM_Handle%@BO:       73a71@%
  19404.   Get_Sys_VM_Handle%@BO:       73f55@%
  19405.   Get_VMM_Reenter_Count%@BO:       74178@%
  19406.   Get_VMM_Version%@BO:       7457f@%
  19407.   Test_Cur_VM_Handle%@BO:       74cb5@%
  19408.   Test_Debug_Installed%@BO:       74f3f@%
  19409.   Test_Sys_VM_Handle%@BO:       7518c@%
  19410.   Validate_VM_Handle%@BO:       7541b@%
  19411. InitGrabber function%@BO:       2676f@%
  19412. Initialization Information services
  19413.   Convert_Boolean_String%@BO:       75bdc@%
  19414.   Convert_Decimal_String%@BO:       75fe0@%
  19415.   Convert_Fixed_Point_String%@BO:       76526@%
  19416.   Convert_Hex_String%@BO:       76ad5@%
  19417.   GetDOSVectors%@BO:       77b4a@%
  19418.   Get_Config_Directory%@BO:       76f31@%
  19419.   Get_Environment_String%@BO:       77237@%
  19420.   Get_Exec_Path%@BO:       777c8@%
  19421.   Get_Machine_Info%@BO:       77edf@%
  19422.   Get_Next_Profile_String%@BO:       783d3@%
  19423.   Get_Profile_Boolean%@BO:       7881a@%
  19424.   Get_Profile_Decimal_Int%@BO:       78e0f@%
  19425.   Get_Profile_Fixed_Point%@BO:       793bc@%
  19426.   Get_Profile_Hex_Int%@BO:       799e4@%
  19427.   Get_Profile_String%@BO:       7a020@%
  19428.   Get_PSP_Segment%@BO:       7a436@%
  19429.   OpenFile%@BO:       7a7a1@%
  19430. Install_IO_Handler service%@BO:       509b8@%
  19431. Install_Mult_IO_Handlers service%@BO:       50f2e@%
  19432. Install_V86_Break_Point service%@BO:       5ed0b@%
  19433. INT 2FH%@BO:        cc14@%%@BO:       15c12@%
  19434. Interrupt descriptor table
  19435.   In protected mode%@BO:        de08@%
  19436. Interrupt request%@BO:       1029e@%
  19437. InvertSelection function%@BO:       23f09@%
  19438. IRQ. See Interrupt Request%@BO:       1029e@%
  19439.  
  19440. %@2@%%@AB@%    K%@AE@%%@EH@%%@NL@%
  19441. KeySelection function%@BO:       240f1@%
  19442.  
  19443. %@2@%%@AB@%    L%@AE@%%@EH@%%@NL@%
  19444. LDT. See Local descriptor table%@BO:       2fd83@%
  19445. Link386, defined%@BO:       16f12@%
  19446. Linked List services
  19447.   List_Allocate%@BO:       7aff8@%
  19448.   List_Attach%@BO:       7b3b8@%
  19449.   List_Attach_Tail%@BO:       7b6f3@%
  19450.   List_Create%@BO:       7ba66@%
  19451.   List_Deallocate%@BO:       7c58d@%
  19452.   List_Destroy%@BO:       7c854@%
  19453.   List_Get_First%@BO:       7cada@%
  19454.   List_Get_Next%@BO:       7cd85@%
  19455.   List_Insert%@BO:       7d24c@%
  19456.   List_Remove%@BO:       7d6dd@%
  19457.   List_Remove_First%@BO:       7d9fc@%
  19458. LinMapIntoV86 service%@BO:       45ff4@%
  19459. LinPageLock service%@BO:       4776c@%
  19460. LinPageUnLock service%@BO:       47ec0@%
  19461. List_Allocate service%@BO:       7afe4@%
  19462. List_Attach service%@BO:       7b3a4@%
  19463. List_Attach_Tail service%@BO:       7b6f3@%
  19464. List_Create service%@BO:       7ba52@%
  19465. List_Deallocate service%@BO:       7c579@%
  19466. List_Destroy service%@BO:       7c840@%
  19467. List_Get_First service%@BO:       7cac6@%
  19468. List_Get_Next service%@BO:       7cd71@%
  19469. List_Insert service%@BO:       7d238@%
  19470. List_Remove service%@BO:       7d6c9@%
  19471. List_Remove_First service%@BO:       7d9fc@%
  19472. Local descriptor table, defined%@BO:       2fd83@%
  19473.  
  19474. %@2@%%@AB@%    M%@AE@%%@EH@%%@NL@%
  19475. MakeSelctRect function%@BO:       2472c@%
  19476. MapIntoV86 service%@BO:       38e97@%
  19477. MapPhysToLinear service%@BO:       43f18@%
  19478. MAPSYM32, defined%@BO:       17d77@%
  19479. Map_Flat service%@BO:       80970@%
  19480. MASM5, defined%@BO:       16ba4@%
  19481. Memory Management services
  19482.   Data Access services
  19483.     GetAppFlatDSAlias%@BO:       44bb2@%
  19484.     GetFirstV86Page%@BO:       44869@%
  19485. Memory management services
  19486.   Data Access services
  19487.     GetNulPageHandle%@BO:       44a7a@%
  19488. Memory Management services
  19489.   Device V86 Page Management services
  19490.     Assign_Device_V86_Pages%@BO:       2dac4@%
  19491.     DeAssign_Device_V86_Pages%@BO:       2e286@%
  19492.     Get_Device_V86_Pages_Array%@BO:       2e960@%
  19493.     Hook_V86_Page%@BO:       2f294@%
  19494.   GDT/LDT Management services
  19495.     Allocate_GDT_Selector%@BO:       2fdf7@%
  19496.     Allocate_LDT_Selector%@BO:       30824@%
  19497.     BuildDescDWORDs%@BO:       319f1@%
  19498.     Free_GDT_Selector%@BO:       32374@%
  19499.     Free_LDT_Selector%@BO:       32709@%
  19500.   Instance Data Management services
  19501.     AddInstanceItem%@BO:       4bee4@%
  19502.     MMGR_Toggle_HMA%@BO:       4cff1@%
  19503.   Physical Device Memory in PM services
  19504.     MapPhysToLinear%@BO:       43f18@%
  19505.   Special services for PM APIs
  19506.     LinMapIntoV86%@BO:       45ff4@%
  19507.     LinPageLock%@BO:       4776c@%
  19508.     LinPageUnLock%@BO:       47ec0@%
  19509.     PageCheckLinRange%@BO:       487de@%
  19510.     SelectorMapFlat%@BO:       496d4@%
  19511.   System Data Object Management services
  19512.     Allocate_Device_CB_Area%@BO:       28edf@%
  19513.     Allocate_Global_V86_Data_Area%@BO:       29cc5@%
  19514.     Allocate_Temp_V86_Data_Area%@BO:       2bcb5@%
  19515.     Free_Temp_V86_Data_Area%@BO:       2c73b@%
  19516.   System Heap Allocator services
  19517.     HeapAllocate%@BO:       342b0@%
  19518.     HeapFree%@BO:       34995@%
  19519.     HeapGetSize%@BO:       34cac@%
  19520.     HeapReAllocate%@BO:       34fcc@%
  19521.   System Page Allocator services
  19522.     CopyPageTable%@BO:       363e2@%
  19523.     GetDemandPageInfo%@BO:       36fd0@%
  19524.     GetFreePageCount%@BO:       37896@%
  19525.     GetSetPageOutCount%@BO:       38022@%
  19526.     GetSysPageCount%@BO:       3868b@%
  19527.     GetVMPageCount%@BO:       38983@%
  19528.     MapIntoV86%@BO:       38e97@%
  19529.     ModifyPageBits%@BO:       3a7a5@%
  19530.     PageAllocate%@BO:       3b570@%
  19531.     PageFree%@BO:       3d91f@%
  19532.     PageGetAllocInfo%@BO:       3df18@%
  19533.     PageGetSizeAddr%@BO:       3e79e@%
  19534.     PageLock%@BO:       3ec7f@%
  19535.     PageOutDirtyPages%@BO:       3f883@%
  19536.     PageReAllocate%@BO:       4047b@%
  19537.     PageUnLock%@BO:       41741@%
  19538.     PhysIntoV86%@BO:       42347@%
  19539.     TestGlobalV86Mem%@BO:       42f20@%
  19540.   V86 Address Space services
  19541.     CB_High_Linear%@BO:       4e22c@%
  19542. Memory management, V86 mode
  19543.   API translation%@BO:       964ee@%
  19544. Memory management
  19545.    defined%@BO:       951b5@%
  19546. Message mode, defined%@BO:       1e6f8@%
  19547. Miscellaneous services
  19548.   Begin_Reentrant_Execution%@BO:       7f1a0@%
  19549.   End_Reentrant_Execution%@BO:       7f662@%
  19550.   Hook_Device_Service%@BO:       7f8af@%
  19551.   Hook_Device_V86_API%@BO:       8034c@%
  19552.   Hook_PM_Device_API%@BO:       8034c@%
  19553.   Map_Flat%@BO:       80984@%
  19554.   MMGR_SetNULPageAddr%@BO:       81604@%
  19555.   Set_System_Exit_code%@BO:       8190e@%
  19556.   Simulate_Pop%@BO:       81cc7@%
  19557.   Simulate_Push%@BO:       81f44@%
  19558.   System_Control%@BO:       821d7@%
  19559. MMGR_SetNULPageAddr service%@BO:       81604@%
  19560. MMGR_Toggle_HMA service%@BO:       4cff1@%
  19561. Mode
  19562.   Protected%@BO:        ade5@%%@BO:        f1f1@%
  19563.   Real%@BO:       18309@%%@BO:       aa1e3@%
  19564.   Virtual-86%@BO:        acd8@%%@BO:        f1f1@%
  19565. ModifyPageBits service%@BO:       3a7a5@%
  19566.  
  19567. %@2@%%@AB@%    N%@AE@%%@EH@%%@NL@%
  19568. Nested Execution services
  19569.   Begin_Nest_Exec%@BO:       57b24@%
  19570.   Begin_Nest_V86_Exec%@BO:       586ec@%
  19571.   Begin_Use_Locked_PM_Stack%@BO:       58b70@%
  19572.   End_Nest_Exec%@BO:       590a6@%
  19573.   End_Use_Locked_PM_Stack%@BO:       59525@%
  19574.   Exec_Int%@BO:       59882@%
  19575.   Exec_VxD_Int%@BO:       59ccb@%
  19576.   Restore_Client_State%@BO:       5ae0a@%
  19577.   Resume_Exec%@BO:       5b3f0@%
  19578.   Save_Client_State%@BO:       5bfed@%
  19579.   Set_PM_Exec_Mode%@BO:       5ca00@%
  19580.   Set_V86_Exec_Mode%@BO:       5ce5d@%
  19581. No_Fail_Resume_VM service%@BO:       6453b@%
  19582. Nuke_VM service%@BO:       648e9@%
  19583.  
  19584. %@2@%%@AB@%    O%@AE@%%@EH@%%@NL@%
  19585. OpenFile service%@BO:       7a7b5@%
  19586.  
  19587. %@2@%%@AB@%    P%@AE@%%@EH@%%@NL@%
  19588. PageAllocate service%@BO:       3b570@%
  19589. PageCheckLinRange service%@BO:       487de@%
  19590. PageFree service%@BO:       3d91f@%
  19591. PageGetAllocInfo service%@BO:       3df18@%
  19592. PageGetSizeAddr service%@BO:       3e79e@%
  19593. PageLock service%@BO:       3ec7f@%
  19594. PageOutDirtyPages service%@BO:       3f883@%
  19595. PageReAllocate service%@BO:       4047b@%
  19596. PageUnLock service%@BO:       41741@%
  19597. PaintScreen function%@BO:       269be@%
  19598. PhysIntoV86 service%@BO:       42347@%
  19599. PM. See Protected mode%@BO:        9ea7@%
  19600. Primary Scheduler services
  19601.   Adjust_Exec_Priority%@BO:       60bf8@%
  19602.   Begin_Critical_Section%@BO:       61895@%
  19603.   Call_When_Not_Critical%@BO:       624c1@%
  19604.   Call_When_Task_Switched%@BO:       62a34@%
  19605.   Claim_Critical_Section%@BO:       62f7e@%
  19606.   Create_Semaphore%@BO:       632a5@%
  19607.   Destroy_Semaphore%@BO:       633ca@%
  19608.   End_Critical_Section%@BO:       63df2@%
  19609.   End_Crit_And_Suspend%@BO:       634f0@%
  19610.   Get_Crit_Section_Status%@BO:       64124@%
  19611.   No_Fail_Resume_VM%@BO:       6454f@%
  19612.   Nuke_VM%@BO:       648fd@%
  19613.   Release_Critical_Section%@BO:       64c8e@%
  19614.   Resume_VM%@BO:       64f35@%
  19615.   Signal_Semaphore%@BO:       653ac@%
  19616.   Suspend_VM%@BO:       654e5@%
  19617.   Wait_Semaphore%@BO:       65c2c@%
  19618. Privilege rings%@BO:        f011@%
  19619. Processor Fault and Interrupt services
  19620.   Get_Fault_Hook_Addrs%@BO:       70d86@%
  19621.   Get_NMI_Handler_Addr%@BO:       71164@%
  19622.   Hook_NMI_Event%@BO:       71aba@%
  19623.   Hook_PM_Fault%@BO:       71dc6@%
  19624.   Hook_V86_Fault%@BO:       71dc6@%
  19625.   Hook_V86_Page%@BO:       72948@%
  19626.   Hook_VMM_Fault%@BO:       71dc6@%
  19627.   Set_NMI_Handler_Addr%@BO:       731b7@%
  19628. Protected mode
  19629.   defined%@BO:        e9d5@%%@BO:       aa9e7@%
  19630.   Initialization%@BO:       19c75@%
  19631.   Interrupt descriptor table%@BO:        de08@%
  19632.  
  19633. %@2@%%@AB@%    R%@AE@%%@EH@%%@NL@%
  19634. Real mode
  19635.   defined%@BO:       aa73f@%
  19636.   initialization%@BO:       18309@%
  19637. Release_Critical_Section service%@BO:       64c8e@%
  19638. Release_Time_Slice service%@BO:       68daf@%
  19639. Remove_V86_Break_Point service%@BO:       5fa54@%
  19640. RenderSelection function%@BO:       24c0b@%
  19641. Restore_Client_State service%@BO:       5ae0a@%
  19642. Resume_Exec service%@BO:       5b3dc@%
  19643. Resume_VM service%@BO:       64f21@%
  19644.  
  19645. %@2@%%@AB@%    S%@AE@%%@EH@%%@NL@%
  19646. Save_Client_State service%@BO:       5bfed@%
  19647. Schedule_Global_Event service%@BO:       6dc61@%
  19648. Schedule_VM_Event service%@BO:       6dfed@%
  19649. Scheduling
  19650.   defined%@BO:       600e0@%%@BO:       606ef@%
  19651.   Enhanced Windows execution%@BO:        cd21@%
  19652.   Primary scheduler%@BO:        d51a@%%@BO:        d708@%
  19653.   Time-slice scheduler%@BO:        d51a@%
  19654. ScreenFree function%@BO:       26d11@%
  19655. SelectorMapFlat service%@BO:       496d4@%
  19656. Services, defined%@BO:        f34f@%
  19657. SetPaintFnt function%@BO:       26efa@%
  19658. Set_Execution_Focus service%@BO:       691ff@%
  19659. Set_Global_Time_Out service%@BO:       6f829@%
  19660. Set_PM_Exec_Mode service%@BO:       5ca00@%
  19661. Set_PM_Int_Type service%@BO:       5578a@%
  19662. Set_PM_Int_Vector service%@BO:       55c52@%
  19663. Set_System_Exit_code service%@BO:       8190e@%
  19664. Set_Time_Slice_Granularity service%@BO:       695f3@%
  19665. Set_Time_Slice_Priority service%@BO:       69922@%
  19666. Set_V86_Exec_Mode service%@BO:       5ce5d@%
  19667. Set_V86_Int_Vector service%@BO:       55c52@%
  19668. Set_VM_Time_Out service%@BO:       6fe99@%
  19669. Shell services
  19670.   SHELL_Event%@BO:       82fac@%
  19671.   SHELL_Get_Version%@BO:       83589@%
  19672.   SHELL_Message%@BO:       8379b@%
  19673.   SHELL_Resolve_Contention%@BO:       83d4b@%
  19674. Shell, defined%@BO:        b971@%
  19675. Signal_Semaphore service%@BO:       653ac@%
  19676. Simulate_Far_Call service%@BO:       560e1@%
  19677. Simulate_Far_Jmp service%@BO:       5651a@%
  19678. Simulate_Far_Ret service%@BO:       567d9@%
  19679. Simulate_Far_Ret_N service%@BO:       56a68@%
  19680. Simulate_Int service%@BO:       56d67@%
  19681. Simulate_IO service%@BO:       51442@%
  19682. Simulate_Iret service%@BO:       57415@%
  19683. Simulate_Pop service%@BO:       81cb3@%
  19684. Simulate_Push service%@BO:       81f30@%
  19685. Software interrupt hooks%@BO:       1029e@%
  19686. Suspend_VM service%@BO:       654d1@%
  19687. System_Controls service%@BO:       821c3@%
  19688.  
  19689. %@2@%%@AB@%    T%@AE@%%@EH@%%@NL@%
  19690. TestGlobalV86Mem service%@BO:       42f20@%
  19691. Test_Cur_VM_Handle service%@BO:       74cb5@%
  19692. Test_Debug_Installed service%@BO:       74f3f@%
  19693. Test_Sys_VM_Handle service%@BO:       7518c@%
  19694. Time-Slice Scheduler services
  19695.   Adjust_Execution_Time%@BO:       6734f@%
  19696.   Call_When_Idle%@BO:       67a21@%
  19697.   Get_Execution_Focus%@BO:       680fe@%
  19698.   Get_Time_Slice_Granularity%@BO:       68358@%
  19699.   Get_Time_Slice_Info%@BO:       685f7@%
  19700.   Get_Time_Slice_Priority%@BO:       688f2@%
  19701.   Release_Time_Slice%@BO:       68daf@%
  19702.   Set_Execution_Focus%@BO:       691ff@%
  19703.   Set_Time_Slice_Granularity%@BO:       695f3@%
  19704.   Set_Time_Slice_Priority%@BO:       69922@%
  19705.   Wake_Up_VM%@BO:       69e3d@%
  19706. Timing services
  19707.   Cancel_Time_Out%@BO:       6e848@%
  19708.   Get_Last_Updated_System_Time%@BO:       6ed4a@%
  19709.   Get_Last_Updated_VM_Exec_Time%@BO:       6ef5f@%
  19710.   Get_System_Time%@BO:       6f189@%
  19711.   Get_VM_Exec_Time%@BO:       6f4b2@%
  19712.   Set_Global_Time_Out%@BO:       6f829@%
  19713.   Set_VM_Time_Out%@BO:       6fead@%
  19714.   Update_System_Clock%@BO:       7063b@%
  19715.  
  19716. %@2@%%@AB@%    U%@AE@%%@EH@%%@NL@%
  19717. UpdateScreen function%@BO:       274f9@%
  19718. Update_System_Clock service%@BO:       7063b@%
  19719.  
  19720. %@2@%%@AB@%    V%@AE@%%@EH@%%@NL@%
  19721. V86 Mode Memory Manager Device services
  19722.   V86MMGR_Allocate_Buffer%@BO:       9cf13@%
  19723.   V86MMGR_Allocate_V86_Pages%@BO:       95420@%
  19724.   V86MMGR_Free_Buffer%@BO:       9d56c@%
  19725.   V86MMGR_Free_Page_Map_Region%@BO:       9ebcd@%
  19726.   V86MMGR_Get_EMS_XMS_Limits%@BO:       95e83@%
  19727.   V86MMGR_Get_Mapping_Info%@BO:       9e61f@%
  19728.   V86MMGR_Get_Version%@BO:       9520b@%
  19729.   V86MMGR_Get_VM_Flat_Sel%@BO:       9e224@%
  19730.   V86MMGR_Get_Xlat_Buff_State%@BO:       9d990@%
  19731.   V86MMGR_Load_Client_Ptr%@BO:       9c965@%
  19732.   V86MMGR_Map_Pages%@BO:       9e84b@%
  19733.   V86MMGR_Set_EMS_XMS_Limits%@BO:       959ed@%
  19734.   V86MMGR_Set_Mapping_Info%@BO:       999a6@%
  19735.   V86MMGR_Set_Xlat_Buff_State%@BO:       9ddf6@%
  19736.   V86MMGR_Xlat_API%@BO:       9a016@%
  19737. V86. See Virtual-86 mode%@BO:        9ea7@%
  19738. V86MMGR services. See V86 Mode Memory Manager Device services%@BO:       94b08@%
  19739. Validate_VM_Handle service%@BO:       7541b@%
  19740. VDD services. See Virtual Display Device services%@BO:       84524@%
  19741. VDMAD services. See Virtual DMA Device services%@BO:       9f136@%
  19742. VDMAD_Request_Buffer service%@BO:       a26e3@%%@BO:       a2a0e@%
  19743. Virtual device
  19744.   API procedure%@BO:        c377@%%@BO:       1350f@%
  19745.   API%@BO:       15a2e@%
  19746.   Building%@BO:       163c5@%
  19747.   Declaration%@BO:       12781@%
  19748.   defined%@BO:        a188@%%@BO:        b971@%
  19749.   Device control procedure name%@BO:       1350f@%
  19750.   Device control procedure%@BO:        bfc4@%
  19751.   Device descriptor block%@BO:        c377@%
  19752.   ID%@BO:       1350f@%
  19753.   IDS%@BO:        c95b@%
  19754.   Initialization order%@BO:        c95b@%
  19755.   Initialization%@BO:       1350f@%%@BO:       18166@%
  19756.   Installing%@BO:       17fd6@%
  19757.   Memory model%@BO:       11b28@%
  19758.   Segmentation%@BO:       12054@%
  19759.   Service table%@BO:       1350f@%
  19760.   Services%@BO:       13fb4@%
  19761.   Version%@BO:       1350f@%
  19762.   Writing strategy%@BO:       1150e@%
  19763. Virtual Display Device services
  19764.   VDD_Get_GrabRtn%@BO:       85edb@%
  19765.   VDD_Get_ModTime%@BO:       861e6@%
  19766.   VDD_Get_Version%@BO:       86441@%
  19767.   VDD_Hide_Cursor%@BO:       8668d@%
  19768.   VDD_Msg_BakColor%@BO:       850e9@%
  19769.   VDD_Msg_ClrScrn%@BO:       85322@%
  19770.   VDD_Msg_ForColor%@BO:       8567e@%
  19771.   VDD_Msg_SetCursPos%@BO:       858b7@%
  19772.   VDD_Msg_TextOut%@BO:       85ad5@%
  19773.   VDD_PIF_State%@BO:       869d0@%
  19774.   VDD_Query_Access%@BO:       86bc4@%
  19775.   VDD_Set_HCurTrk%@BO:       86f1f@%
  19776.   VDD_Set_VMType%@BO:       871a5@%%@BO:       87599@%
  19777. Virtual DMA Device services
  19778.   VDMAD_Copy_From_Buffer%@BO:       9f794@%
  19779.   VDMAD_Copy_To_Buffer%@BO:       9fb89@%
  19780.   VDMAD_Default_Handler%@BO:       9ff5e@%
  19781.   VDMAD_Disable_Translation%@BO:       a02fd@%
  19782.   VDMAD_Enable_Translation%@BO:       a069f@%
  19783.   VDMAD_Get_EISA_Adr_Mode%@BO:       a09d1@%
  19784.   VDMAD_Get_Region_Info%@BO:       a0d86@%
  19785.   VDMAD_Get_Version%@BO:       a1128@%
  19786.   VDMAD_Get_Virt_State%@BO:       a13d7@%
  19787.   VDMAD_Lock_DMA_Region%@BO:       a1a16@%
  19788.   VDMAD_Mask_Channel%@BO:       a24e9@%
  19789.   VDMAD_Release_Buffer%@BO:       a26e3@%
  19790.   VDMAD_Request_Buffer%@BO:       a2a0e@%
  19791.   VDMAD_Reserve_Buffer_Space%@BO:       a2d49@%
  19792.   VDMAD_Scatter_Lock%@BO:       a321c@%
  19793.   VDMAD_Scatter_Unlock%@BO:       a3762@%
  19794.   VDMAD_Set_EISA_Adr_Mode%@BO:       a3c23@%
  19795.   VDMAD_Set_Phys_State%@BO:       a3ed2@%
  19796.   VDMAD_Set_Region_Info%@BO:       a41c8@%
  19797.   VDMAD_Set_Virt_State%@BO:       a44b6@%
  19798.   VDMAD_Unlock_DMA_Region%@BO:       a49eb@%
  19799.   VDMAD_UnMask_Channel%@BO:       a4ce8@%
  19800.   VDMAD_Virtualize_Channel%@BO:       a4eed@%
  19801. Virtual DOSNET device services
  19802.   DOSNET_Do_PSP_Adjust%@BO:       a5965@%
  19803.   DOSNET_Get_Version%@BO:       a574f@%
  19804.   DOSNET_Send_FILESYSCHANGE%@BO:       a6301@%
  19805. Virtual Keyboard Device services
  19806.   VKD_Cancel_Hot_Key_State%@BO:       87d2a@%
  19807.   VKD_Cancel_Paste%@BO:       87f19@%
  19808.   VKD_Define_Hot_Key%@BO:       8810e@%
  19809.   VKD_Define_Paste_Mode%@BO:       88f54@%
  19810.   VKD_Flush_Msg_Key_Queue%@BO:       89367@%
  19811.   VKD_Force_Keys%@BO:       89573@%
  19812.   VKD_Get_Kbd_Owner%@BO:       8987e@%
  19813.   VKD_Get_Msg_Key%@BO:       89a74@%
  19814.   VKD_Get_Version%@BO:       89dd3@%
  19815.   VKD_Local_Disable_Hot_Key%@BO:       89fc9@%
  19816.   VKD_Local_Enable_Hot_Key%@BO:       8a217@%
  19817.   VKD_Peek_Msg_Key%@BO:       8a463@%
  19818.   VKD_Reflect_Hot_Key%@BO:       8a7ab@%
  19819.   VKD_Remove_Hot_Key%@BO:       8abd8@%
  19820.   VKD_Start_Paste%@BO:       8adb9@%
  19821. Virtual machine manager, defined%@BO:        a009@%%@BO:        b408@%
  19822. Virtual machine
  19823.   Client Register structure%@BO:        a9b5@%%@BO:        b24c@%
  19824.   defined%@BO:        9ea7@%%@BO:        a7a9@%
  19825.   Events%@BO:        cf3b@%
  19826.   Initialization%@BO:       1a4b0@%
  19827.   Loading sequence%@BO:       103cb@%
  19828.   Privilege rings%@BO:        abfc@%
  19829.   Scheduling%@BO:        d319@%
  19830.   States%@BO:       1a3d8@%
  19831.   Termination%@BO:       1b691@%
  19832.   VM handle%@BO:        b0f0@%
  19833. Virtual PIC Device services
  19834.   VID_EOI_Proc%@BO:       8d140@%
  19835.   VID_Hw_Int_Proc%@BO:       8cb43@%
  19836.   VID_IRET_Proc%@BO:       8da51@%
  19837.   VID_Mask_Change_Proc%@BO:       8e485@%
  19838.   VID_Virt_Int_Proc%@BO:       8d62a@%
  19839.   VPICD_Call_When_Hw_Int%@BO:       8e81b@%
  19840.   VPICD_Clear_Int_Request%@BO:       8eee3@%
  19841.   VPICD_Convert_Handle_To_IRQ%@BO:       8f22e@%
  19842.   VPICD_Convert_Int_To_IRQ%@BO:       8f44d@%
  19843.   VPICD_Convert_IRQ_To_Int%@BO:       8f7b8@%
  19844.   VPICD_Get_Complete_Status%@BO:       8fb18@%
  19845.   VPICD_Get_IRQ_Complete_Status%@BO:       8fc16@%
  19846.   VPICD_Get_Status%@BO:       9006f@%
  19847.   VPICD_Get_Version%@BO:       9066f@%
  19848.   VPICD_Physically_Mask%@BO:       90ca9@%
  19849.   VPICD_Physically_Unmask%@BO:       90f1f@%
  19850.   VPICD_Phys_EOI%@BO:       90981@%
  19851.   VPICD_Set_Auto_Masking%@BO:       9119d@%
  19852.   VPICD_Set_Int_Request%@BO:       91506@%
  19853.   VPICD_Test_Phys_Request%@BO:       91c64@%
  19854.   VPICD_Virtualize_IRQ%@BO:       91ea4@%
  19855. Virtual PIC Device
  19856.   defined%@BO:       1029e@%
  19857. Virtual Sound Device services
  19858.   VSD_Bell%@BO:       92713@%
  19859.   VSD_Get_Version%@BO:       9299b@%
  19860. Virtual Timer Device services
  19861.   VTD_Begin_Min_Int_Period%@BO:       92eba@%
  19862.   VTD_Disable_Trapping%@BO:       9359e@%
  19863.   VTD_Enable_Trapping%@BO:       93bec@%
  19864.   VTD_End_Min_Int_Period%@BO:       93ebd@%
  19865.   VTD_Get_Interupt_Period%@BO:       94243@%
  19866.   VTD_Get_Version%@BO:       9443f@%
  19867.   VTD_Update_System_Clock%@BO:       94725@%
  19868. Virtual-86 mode, defined%@BO:        e9d5@%%@BO:       aac5e@%
  19869. VKD services. See Virtual Keyboard Device services%@BO:       87950@%
  19870. VM Interrupt and Call services
  19871.   Build_Int_Stack_Frame%@BO:       528fa@%
  19872.   Call_When_Idle%@BO:       52df0@%
  19873.   Call_When_VM_Ints_Enabled%@BO:       534c7@%
  19874.   Disable_VM_Ints%@BO:       539be@%
  19875.   Enable_VM_Ints%@BO:       53beb@%
  19876.   Get_PM_Int_Type%@BO:       53f8b@%
  19877.   Get_PM_Int_Vector%@BO:       5442b@%
  19878.   Get_V86_Int_Vector%@BO:       5442b@%
  19879.   Hook_V86_Int_Chain%@BO:       54a46@%
  19880.   Set_PM_Int_Type%@BO:       5578a@%
  19881.   Set_PM_Int_Vector%@BO:       55c52@%
  19882.   Set_V86_Int_Vector%@BO:       55c52@%
  19883.   Simulate_Far_Call%@BO:       560e1@%
  19884.   Simulate_Far_Jmp%@BO:       5651a@%
  19885.   Simulate_Far_Ret%@BO:       567d9@%
  19886.   Simulate_Far_Ret_N%@BO:       56a68@%
  19887.   Simulate_Int%@BO:       56d7b@%
  19888.   Simulate_Iret%@BO:       57415@%
  19889. VM. See Virtual machine%@BO:        9ea7@%
  19890. VMM. See Virtual machine manager%@BO:        a009@%
  19891. VPICD services. See Virtual PIC Device services%@BO:       8b941@%
  19892. VSD services. See Virtual Sound Device services%@BO:       925fc@%
  19893. VTD services. See Virtual Timer Device services%@BO:       92c76@%
  19894. VxD. See Virtual device%@BO:        a188@%
  19895.  
  19896. %@2@%%@AB@%    W%@AE@%%@EH@%%@NL@%
  19897. Wait_Semaphore service%@BO:       65c2c@%
  19898. Wake_Up_VM service%@BO:       69e3d@%
  19899. WINOLDAP%@BO:       15a2e@%%@BO:       227fa@%
  19900.  
  19901.