Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

vdmint21.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 vdmint21.c 00008 00009 Abstract: 00010 00011 This module implements interfaces that support manipulation of i386 00012 int 21 entry of IDT. These entry points only exist on i386 machines. 00013 00014 Author: 00015 00016 Shie-Lin Tzong (shielint) 26-Dec-1993 00017 00018 Environment: 00019 00020 Kernel mode only. 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "ki.h" 00027 #pragma hdrstop 00028 #include "vdmntos.h" 00029 00030 #define IDT_ACCESS_DPL_USER 0x6000 00031 #define IDT_ACCESS_TYPE_386_TRAP 0xF00 00032 #define IDT_ACCESS_TYPE_286_TRAP 0x700 00033 #define IDT_ACCESS_PRESENT 0x8000 00034 #define LDT_MASK 4 00035 00036 // 00037 // External Reference 00038 // 00039 00040 BOOLEAN 00041 Ki386GetSelectorParameters( 00042 IN USHORT Selector, 00043 OUT PULONG Flags, 00044 OUT PULONG Base, 00045 OUT PULONG Limit 00046 ); 00047 00048 // 00049 // Define forward referenced function prototypes. 00050 // 00051 00052 VOID 00053 Ki386LoadTargetInt21Entry ( 00054 IN PKIPI_CONTEXT SignalDone, 00055 IN PVOID Parameter1, 00056 IN PVOID Parameter2, 00057 IN PVOID Parameter3 00058 ); 00059 00060 #define KiLoadInt21Entry() \ 00061 KeGetPcr()->IDT[0x21] = PsGetCurrentProcess()->Pcb.Int21Descriptor 00062 00063 NTSTATUS 00064 Ke386SetVdmInterruptHandler ( 00065 PKPROCESS Process, 00066 ULONG Interrupt, 00067 USHORT Selector, 00068 ULONG Offset, 00069 BOOLEAN Gate32 00070 ) 00071 00072 /*++ 00073 00074 Routine Description: 00075 00076 The specified (software) interrupt entry of IDT will be updated to 00077 point to the specified handler. For all threads which belong to the 00078 specified process, their execution processors will be notified to 00079 make the same change. 00080 00081 This function only exists on i386 and i386 compatible processors. 00082 00083 No checking is done on the validity of the interrupt handler. 00084 00085 Arguments: 00086 00087 Process - Pointer to KPROCESS object describing the process for 00088 which the int 21 entry is to be set. 00089 00090 Interrupt - The software interrupt vector which will be updated. 00091 00092 Selector, offset - Specified the address of the new handler. 00093 00094 Gate32 - True if the gate should be 32 bit, false otherwise 00095 00096 Return Value: 00097 00098 NTSTATUS. 00099 00100 --*/ 00101 00102 { 00103 00104 KIRQL OldIrql; 00105 BOOLEAN LocalProcessor; 00106 KAFFINITY TargetProcessors; 00107 PKPRCB Prcb; 00108 KIDTENTRY IdtDescriptor; 00109 ULONG Flags, Base, Limit; 00110 00111 // 00112 // Check the validity of the request 00113 // 1. Currently, we support int21 redirection only 00114 // 2. The specified interrupt handler must be in user space. 00115 // 00116 00117 if (Interrupt != 0x21 || Offset >= (ULONG)MM_HIGHEST_USER_ADDRESS || 00118 !Ki386GetSelectorParameters(Selector, &Flags, &Base, &Limit) ){ 00119 return(STATUS_INVALID_PARAMETER); 00120 } 00121 00122 // 00123 // Initialize the contents of the IDT entry 00124 // 00125 00126 IdtDescriptor.Offset = (USHORT)Offset; 00127 IdtDescriptor.Selector = Selector | RPL_MASK | LDT_MASK; 00128 IdtDescriptor.ExtendedOffset = (USHORT)(Offset >> 16); 00129 IdtDescriptor.Access = IDT_ACCESS_DPL_USER | IDT_ACCESS_PRESENT; 00130 if (Gate32) { 00131 IdtDescriptor.Access |= IDT_ACCESS_TYPE_386_TRAP; 00132 00133 } else { 00134 IdtDescriptor.Access |= IDT_ACCESS_TYPE_286_TRAP; 00135 } 00136 00137 // 00138 // Acquire the context swap lock so a context switch will not occur. 00139 // 00140 00141 KiLockContextSwap(&OldIrql); 00142 00143 // 00144 // Set the Ldt fields in the process object 00145 // 00146 00147 Process->Int21Descriptor = IdtDescriptor; 00148 00149 // 00150 // Tell all processors active for this process to reload their LDTs 00151 // 00152 00153 #if !defined(NT_UP) 00154 00155 Prcb = KeGetCurrentPrcb(); 00156 TargetProcessors = Process->ActiveProcessors & ~Prcb->SetMember; 00157 if (TargetProcessors != 0) { 00158 KiIpiSendPacket(TargetProcessors, 00159 Ki386LoadTargetInt21Entry, 00160 NULL, 00161 NULL, 00162 NULL); 00163 } 00164 00165 #endif 00166 00167 KiLoadInt21Entry(); 00168 00169 #if !defined(NT_UP) 00170 00171 // 00172 // Wait until all of the target processors have finished reloading 00173 // their LDT. 00174 // 00175 00176 if (TargetProcessors != 0) { 00177 KiIpiStallOnPacketTargets(TargetProcessors); 00178 } 00179 00180 #endif 00181 00182 // 00183 // Restore IRQL and unlock the context swap lock. 00184 // 00185 00186 KiUnlockContextSwap(OldIrql); 00187 return STATUS_SUCCESS; 00188 } 00189 00190 #if !defined(NT_UP) 00191 00192 00193 VOID 00194 Ki386LoadTargetInt21Entry ( 00195 IN PKIPI_CONTEXT PacketContext, 00196 IN PVOID Parameter1, 00197 IN PVOID Parameter2, 00198 IN PVOID Parameter3 00199 ) 00200 /*++ 00201 00202 Routine Description: 00203 00204 Reload local Ldt register and clear signal bit in TargetProcessor mask 00205 00206 Arguments: 00207 00208 Argument - pointer to a ipi packet structure. 00209 ReadyFlag - Pointer to flag to be set once LDTR has been reloaded 00210 00211 Return Value: 00212 00213 none. 00214 00215 --*/ 00216 00217 { 00218 00219 // 00220 // Set the int 21 entry of IDT from currently active process object 00221 // 00222 00223 KiLoadInt21Entry(); 00224 KiIpiSignalPacketDone(PacketContext); 00225 return; 00226 } 00227 00228 #endif

Generated on Sat May 15 19:42:21 2004 for test by doxygen 1.3.7