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

psvdm.c File Reference

#include "psp.h"

Go to the source code of this file.

Defines

#define ASSERTEQUAL(value1, value2, string)
#define ASSERTEQUALBREAK(value1, value2, string)

Functions

NTSTATUS Psp386InstallIoHandler (IN PEPROCESS Process, IN PEMULATOR_ACCESS_ENTRY EmulatorAccessEntry, IN ULONG PortNumber, IN ULONG Context)
NTSTATUS Psp386RemoveIoHandler (IN PEPROCESS Process, IN PEMULATOR_ACCESS_ENTRY EmulatorAccessEntry, IN ULONG PortNumber)
NTSTATUS Psp386InsertVdmIoHandlerBlock (IN PEPROCESS Process, IN PVDM_IO_HANDLER VdmIoHandler)
PVDM_IO_HANDLER Psp386GetVdmIoHandler (IN PEPROCESS Process, IN ULONG PortNumber)
NTSTATUS Psp386CreateVdmIoListHead (IN PEPROCESS Process)
NTSTATUS PspSetProcessIoHandlers (IN PEPROCESS Process, IN PVOID IoHandlerInformation, IN ULONG IoHandlerLength)
VOID PspDeleteVdmObjects (IN PEPROCESS Process)
BOOLEAN Ps386GetVdmIoHandler (IN PEPROCESS Process, IN ULONG PortNumber, OUT PVDM_IO_HANDLER VdmIoHandler, OUT PULONG Context)
NTSTATUS PspVdmInitialize ()

Variables

ERESOURCE VdmIoListCreationResource


Define Documentation

#define ASSERTEQUAL value1,
value2,
string   ) 
 

Definition at line 37 of file i386/psvdm.c.

Referenced by Psp386RemoveIoHandler().

#define ASSERTEQUALBREAK value1,
value2,
string   ) 
 

Definition at line 38 of file i386/psvdm.c.

Referenced by Psp386InstallIoHandler(), and Psp386RemoveIoHandler().


Function Documentation

BOOLEAN Ps386GetVdmIoHandler IN PEPROCESS  Process,
IN ULONG  PortNumber,
OUT PVDM_IO_HANDLER  VdmIoHandler,
OUT PULONG  Context
 

Definition at line 869 of file i386/psvdm.c.

References APC_LEVEL, ASSERT, DbgPrint, ExAcquireResourceExclusive, ExReleaseResource, FALSE, KeLowerIrql(), KeRaiseIrql(), NULL, PAGED_CODE, Psp386GetVdmIoHandler(), and TRUE.

Referenced by Ki386VdmDispatchIo(), and Ki386VdmDispatchStringIo().

00877 : 00878 00879 This routine finds the VdmIoHandler block for the specified port. 00880 00881 Arguments: 00882 00883 Process -- Supplies a pointer to the process 00884 PortNumber -- Supplies the port number 00885 VdmIoHandler -- Supplies a pointer to the destination for the lookup 00886 00887 Returns: 00888 00889 True -- A handler structure was found and copied 00890 False -- A handler structure was not found 00891 00892 00893 --*/ 00894 { 00895 PVDM_PROCESS_OBJECTS pVdmObjects = Process->VdmObjects; 00896 PVDM_IO_HANDLER p; 00897 BOOLEAN Success; 00898 KIRQL OldIrql; 00899 PAGED_CODE(); 00900 00901 ASSERT (pVdmObjects != NULL); 00902 00903 if (PortNumber % 4) { 00904 #if DBG 00905 DbgPrint( 00906 "Ps386GetVdmIoHandler : Invalid Port Number %lx\n", 00907 PortNumber 00908 ); 00909 #endif 00910 return FALSE; 00911 } 00912 00913 if (!pVdmObjects->VdmIoListHead) { 00914 return FALSE; 00915 } 00916 00917 00918 KeRaiseIrql(APC_LEVEL, &OldIrql); 00919 ExAcquireResourceExclusive(&pVdmObjects->VdmIoListHead->VdmIoResource,TRUE); 00920 00921 p = Psp386GetVdmIoHandler( 00922 Process, 00923 PortNumber 00924 ); 00925 00926 if (p) { 00927 *VdmIoHandler = *p; 00928 *Context = pVdmObjects->VdmIoListHead->Context; 00929 Success = TRUE; 00930 } else { 00931 Success = FALSE; 00932 } 00933 ExReleaseResource(&pVdmObjects->VdmIoListHead->VdmIoResource); 00934 KeLowerIrql(OldIrql); 00935 00936 return Success; 00937 }

NTSTATUS Psp386CreateVdmIoListHead IN PEPROCESS  Process  ) 
 

Definition at line 730 of file i386/psvdm.c.

References APC_LEVEL, ExAcquireResourceExclusive, ExAllocatePoolWithQuota, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExInitializeResource, ExReleaseResource, KeLowerIrql(), KeRaiseIrql(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, Status, TRUE, and VdmIoListCreationResource.

Referenced by Psp386InstallIoHandler().

00735 : 00736 00737 This routine creates the head node of the Io handler list. This node 00738 contains the spin lock that protects the list. This routine also 00739 initializes the spin lock. 00740 00741 Arguments: 00742 00743 Process -- Supplies a pointer to the process 00744 00745 Return Value: 00746 00747 Notes: 00748 00749 --*/ 00750 { 00751 PVDM_PROCESS_OBJECTS pVdmObjects = Process->VdmObjects; 00752 NTSTATUS Status; 00753 PVDM_IO_LISTHEAD HandlerListHead; 00754 KIRQL OldIrql; 00755 PAGED_CODE(); 00756 00757 Status = STATUS_SUCCESS; 00758 00759 // if there isn't yet a head, grab the resource lock and create one 00760 if (pVdmObjects->VdmIoListHead == NULL) { 00761 KeRaiseIrql(APC_LEVEL, &OldIrql); 00762 ExAcquireResourceExclusive(&VdmIoListCreationResource, TRUE); 00763 00764 // if no head was created while we grabbed the spin lock 00765 if (pVdmObjects->VdmIoListHead == NULL) { 00766 00767 try { 00768 // allocate space for the list head 00769 // and charge the quota for it 00770 00771 HandlerListHead = ExAllocatePoolWithQuota( 00772 NonPagedPool, 00773 sizeof(VDM_IO_LISTHEAD) 00774 ); 00775 00776 } except(EXCEPTION_EXECUTE_HANDLER) { 00777 Status = GetExceptionCode(); 00778 if (HandlerListHead) { 00779 ExFreePool(HandlerListHead); 00780 } 00781 } 00782 00783 if ((!NT_SUCCESS(Status) || !HandlerListHead)) { 00784 ExReleaseResource(&VdmIoListCreationResource); 00785 KeLowerIrql(OldIrql); 00786 00787 return (Status == STATUS_SUCCESS ? 00788 STATUS_INSUFFICIENT_RESOURCES : 00789 Status); 00790 00791 } 00792 00793 ExInitializeResource(&HandlerListHead->VdmIoResource); 00794 00795 HandlerListHead->VdmIoHandlerList = NULL; 00796 00797 // 00798 // Attach the list head to the process 00799 // and attach the handler to the list. 00800 // Since this was a new list 00801 00802 pVdmObjects->VdmIoListHead = HandlerListHead; 00803 00804 ExReleaseResource(&VdmIoListCreationResource); 00805 KeLowerIrql(OldIrql); 00806 00807 00808 } 00809 } 00810 return STATUS_SUCCESS; 00811 }

PVDM_IO_HANDLER Psp386GetVdmIoHandler IN PEPROCESS  Process,
IN ULONG  PortNumber
 

Definition at line 941 of file i386/psvdm.c.

References DbgPrint, NULL, and PAGED_CODE.

Referenced by Ps386GetVdmIoHandler(), Psp386InstallIoHandler(), and Psp386RemoveIoHandler().

00947 : 00948 00949 This routine finds the VdmIoHandler block for the specified port. 00950 00951 Arguments: 00952 00953 Process -- Supplies a pointer to the process 00954 PortNumber -- Supplies the port number 00955 00956 Returns: 00957 00958 NULL if no handler found 00959 non-NULL if handler found 00960 00961 --*/ 00962 { 00963 PVDM_PROCESS_OBJECTS pVdmObjects = Process->VdmObjects; 00964 PVDM_IO_HANDLER p; 00965 PAGED_CODE(); 00966 00967 if (PortNumber % 4) { 00968 #if DBG 00969 DbgPrint( 00970 "Ps386GetVdmIoHandler : Invalid Port Number %lx\n", 00971 PortNumber 00972 ); 00973 #endif 00974 return NULL; 00975 } 00976 00977 p = pVdmObjects->VdmIoListHead->VdmIoHandlerList; 00978 while ((p) && (p->PortNumber != PortNumber)) { 00979 p = p->Next; 00980 } 00981 00982 return p; 00983 00984 }

NTSTATUS Psp386InsertVdmIoHandlerBlock IN PEPROCESS  Process,
IN PVDM_IO_HANDLER  VdmIoHandler
 

Definition at line 814 of file i386/psvdm.c.

References DbgPrint, HandlerList, NULL, and PAGED_CODE.

Referenced by Psp386InstallIoHandler().

00820 : 00821 00822 This routine inserts a new VdmIoHandler block into the process's io 00823 handler list. 00824 00825 Arguments: 00826 00827 Process -- Supplies a pointer to the process 00828 VdmIoHandler -- Supplies a pointer to the block to insert. 00829 00830 Return Value: 00831 00832 --*/ 00833 { 00834 PVDM_PROCESS_OBJECTS pVdmObjects = Process->VdmObjects; 00835 PVDM_IO_HANDLER HandlerList, p; 00836 PVDM_IO_LISTHEAD HandlerListHead; 00837 PAGED_CODE(); 00838 00839 00840 HandlerListHead = pVdmObjects->VdmIoListHead; 00841 HandlerList = HandlerListHead->VdmIoHandlerList; 00842 p = NULL; 00843 while ((HandlerList != NULL) && 00844 (HandlerList->PortNumber < VdmIoHandler->PortNumber)) { 00845 #if DBG 00846 if (HandlerList->PortNumber == VdmIoHandler->PortNumber) { 00847 DbgPrint("Ps386InsertVdmIoHandlerBlock : handler list corrupt\n"); 00848 } 00849 #endif 00850 p = HandlerList; 00851 HandlerList = HandlerList->Next; 00852 } 00853 00854 if (p == NULL) { // Beginning of list 00855 VdmIoHandler->Next = HandlerListHead->VdmIoHandlerList; 00856 HandlerListHead->VdmIoHandlerList = VdmIoHandler; 00857 } else if (HandlerList == NULL) { // End of list 00858 p->Next = VdmIoHandler; 00859 VdmIoHandler->Next = NULL; 00860 } else { // Middle of list 00861 VdmIoHandler->Next = HandlerList; 00862 p->Next = VdmIoHandler; 00863 } 00864 00865 return STATUS_SUCCESS; 00866 }

NTSTATUS Psp386InstallIoHandler IN PEPROCESS  Process,
IN PEMULATOR_ACCESS_ENTRY  EmulatorAccessEntry,
IN ULONG  PortNumber,
IN ULONG  Context
 

Definition at line 477 of file i386/psvdm.c.

References APC_LEVEL, ASSERTEQUALBREAK, DbgPrint, EMULATOR_READ_ACCESS, EMULATOR_WRITE_ACCESS, ExAcquireResourceExclusive, ExAllocatePoolWithQuota, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExReleaseResource, KeLowerIrql(), KeRaiseIrql(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, PDRIVER_IO_PORT_UCHAR, PDRIVER_IO_PORT_UCHAR_STRING, PDRIVER_IO_PORT_ULONG, PDRIVER_IO_PORT_ULONG_STRING, PDRIVER_IO_PORT_USHORT, PDRIVER_IO_PORT_USHORT_STRING, Psp386CreateVdmIoListHead(), Psp386GetVdmIoHandler(), Psp386InsertVdmIoHandlerBlock(), Status, TRUE, Uchar, Ulong, and Ushort.

Referenced by PspSetProcessIoHandlers().

00485 : 00486 00487 This routine install a handler for a port. On debug version, it will 00488 print a message if there is already a handler. 00489 00490 Arguments: 00491 00492 Process -- Supplies a pointer to the process 00493 EmulatorAccess -- Supplies a pointer to the information about the 00494 io port handler 00495 PortNumber -- Supplies the port number to install the handler for. 00496 00497 Return Value: 00498 00499 --*/ 00500 { 00501 PVDM_PROCESS_OBJECTS pVdmObjects = Process->VdmObjects; 00502 PVDM_IO_HANDLER VdmIoHandler; 00503 NTSTATUS Status; 00504 KIRQL OldIrql; 00505 PAGED_CODE(); 00506 00507 00508 // 00509 // Ensure we have a vdm process which is initialized 00510 // correctly for VdmIoHandlers 00511 // 00512 if (!pVdmObjects) { 00513 #if DBG 00514 DbgPrint("Psp386InstallIoHandler: uninitialized VdmObjects\n"); 00515 #endif 00516 return STATUS_UNSUCCESSFUL; 00517 } 00518 00519 00520 Status = STATUS_SUCCESS; 00521 00522 // 00523 // If this is the first handler to be installed, create the list head, 00524 // and initialize the resource lock. 00525 // 00526 if (!pVdmObjects->VdmIoListHead) { 00527 Status = Psp386CreateVdmIoListHead( 00528 Process 00529 ); 00530 00531 if (!NT_SUCCESS(Status)) { 00532 return Status; 00533 } 00534 } 00535 00536 // 00537 // Lock the list to insure correct update. 00538 // 00539 KeRaiseIrql(APC_LEVEL, &OldIrql); 00540 ExAcquireResourceExclusive(&pVdmObjects->VdmIoListHead->VdmIoResource,TRUE); 00541 00542 // 00543 // Update Context 00544 // 00545 00546 pVdmObjects->VdmIoListHead->Context = Context; 00547 00548 VdmIoHandler = Psp386GetVdmIoHandler( 00549 Process, 00550 PortNumber & ~0x3 00551 ); 00552 00553 // If there isn't already a node for this block of ports, 00554 // attempt to allocate a new one. 00555 // 00556 if (!VdmIoHandler) { 00557 try { 00558 00559 VdmIoHandler = ExAllocatePoolWithQuota( 00560 PagedPool, 00561 sizeof(VDM_IO_HANDLER) 00562 ); 00563 00564 } except(EXCEPTION_EXECUTE_HANDLER) { 00565 Status = GetExceptionCode(); 00566 if (VdmIoHandler) { 00567 ExFreePool(VdmIoHandler); 00568 } 00569 } 00570 00571 if (!NT_SUCCESS(Status)) { 00572 ExReleaseResource(&pVdmObjects->VdmIoListHead->VdmIoResource); 00573 KeLowerIrql(OldIrql); 00574 return Status; 00575 } 00576 00577 RtlZeroMemory(VdmIoHandler, sizeof(VDM_IO_HANDLER)); 00578 VdmIoHandler->PortNumber = PortNumber & ~0x3; 00579 00580 Status = Psp386InsertVdmIoHandlerBlock( 00581 Process, 00582 VdmIoHandler 00583 ); 00584 00585 if (!NT_SUCCESS(Status)) { 00586 ExReleaseResource(&pVdmObjects->VdmIoListHead->VdmIoResource); 00587 KeLowerIrql(OldIrql); 00588 return Status; 00589 } 00590 } 00591 00592 ASSERTEQUALBREAK( 00593 VdmIoHandler->PortNumber, 00594 PortNumber & ~0x3, 00595 ("Psp386InstallIoHandler : Bad pointer returned from GetVdmIoHandler\n") 00596 ); 00597 00598 if (EmulatorAccessEntry->AccessMode & EMULATOR_READ_ACCESS) { 00599 switch (EmulatorAccessEntry->AccessType) { 00600 case Uchar: 00601 if (EmulatorAccessEntry->StringSupport) { 00602 ASSERTEQUALBREAK( 00603 NULL, 00604 VdmIoHandler->IoFunctions[0].UcharStringIo[PortNumber % 4], 00605 ("Psp386InstallIoHandler : UcharString fns don't match\n") 00606 ); 00607 VdmIoHandler->IoFunctions[0].UcharStringIo[PortNumber % 4] = 00608 (PDRIVER_IO_PORT_UCHAR_STRING)EmulatorAccessEntry->Routine; 00609 } else { 00610 ASSERTEQUALBREAK( 00611 NULL, 00612 VdmIoHandler->IoFunctions[0].UcharIo[PortNumber % 4], 00613 ("Psp386InstallIoHandler : Uchar fns don't match\n") 00614 ); 00615 VdmIoHandler->IoFunctions[0].UcharIo[PortNumber % 4] = 00616 (PDRIVER_IO_PORT_UCHAR)EmulatorAccessEntry->Routine; 00617 } 00618 break; 00619 case Ushort: 00620 if (EmulatorAccessEntry->StringSupport) { 00621 ASSERTEQUALBREAK( 00622 NULL, 00623 VdmIoHandler->IoFunctions[0].UshortStringIo[(PortNumber & 2) >> 1], 00624 ("Psp386InstallIoHandler : UshortString fns don't match\n") 00625 ); 00626 VdmIoHandler->IoFunctions[0].UshortStringIo[(PortNumber & 2) >> 1] = 00627 (PDRIVER_IO_PORT_USHORT_STRING)EmulatorAccessEntry->Routine; 00628 } else { 00629 ASSERTEQUALBREAK( 00630 NULL, 00631 VdmIoHandler->IoFunctions[0].UshortIo[(PortNumber & 2) >> 1], 00632 ("Psp386InstallIoHandler : Ushort fns don't match\n") 00633 ); 00634 VdmIoHandler->IoFunctions[0].UshortIo[(PortNumber & 2) >> 1] = 00635 (PDRIVER_IO_PORT_USHORT)EmulatorAccessEntry->Routine; 00636 } 00637 break; 00638 case Ulong: 00639 if (EmulatorAccessEntry->StringSupport) { 00640 ASSERTEQUALBREAK( 00641 NULL, 00642 VdmIoHandler->IoFunctions[0].UlongStringIo, 00643 ("Psp386InstallIoHandler : UlongString fns don't match\n") 00644 ); 00645 VdmIoHandler->IoFunctions[0].UlongStringIo = 00646 (PDRIVER_IO_PORT_ULONG_STRING)EmulatorAccessEntry->Routine; 00647 } else { 00648 ASSERTEQUALBREAK( 00649 NULL, 00650 VdmIoHandler->IoFunctions[0].UlongIo, 00651 ("Psp386InstallIoHandler : Ulong fns don't match\n") 00652 ); 00653 VdmIoHandler->IoFunctions[0].UlongIo = 00654 (PDRIVER_IO_PORT_ULONG)EmulatorAccessEntry->Routine; 00655 } 00656 break; 00657 } 00658 } 00659 00660 if (EmulatorAccessEntry->AccessMode & EMULATOR_WRITE_ACCESS) { 00661 switch (EmulatorAccessEntry->AccessType) { 00662 case Uchar: 00663 if (EmulatorAccessEntry->StringSupport) { 00664 ASSERTEQUALBREAK( 00665 NULL, 00666 VdmIoHandler->IoFunctions[1].UcharStringIo[PortNumber % 4], 00667 ("Psp386InstallIoHandler : UcharString fns don't match\n") 00668 ); 00669 VdmIoHandler->IoFunctions[1].UcharStringIo[PortNumber % 4] = 00670 (PDRIVER_IO_PORT_UCHAR_STRING)EmulatorAccessEntry->Routine; 00671 } else { 00672 ASSERTEQUALBREAK( 00673 NULL, 00674 VdmIoHandler->IoFunctions[1].UcharIo[PortNumber % 4], 00675 ("Psp386InstallIoHandler : Uchar fns don't match\n") 00676 ); 00677 VdmIoHandler->IoFunctions[1].UcharIo[PortNumber % 4] = 00678 (PDRIVER_IO_PORT_UCHAR)EmulatorAccessEntry->Routine; 00679 } 00680 break; 00681 case Ushort: 00682 if (EmulatorAccessEntry->StringSupport) { 00683 ASSERTEQUALBREAK( 00684 NULL, 00685 VdmIoHandler->IoFunctions[1].UshortStringIo[(PortNumber & 2) >> 1], 00686 ("Psp386InstallIoHandler : UshortString fns don't match\n") 00687 ); 00688 VdmIoHandler->IoFunctions[1].UshortStringIo[(PortNumber & 2) >> 1] = 00689 (PDRIVER_IO_PORT_USHORT_STRING)EmulatorAccessEntry->Routine; 00690 } else { 00691 ASSERTEQUALBREAK( 00692 NULL, 00693 VdmIoHandler->IoFunctions[1].UshortIo[(PortNumber & 2) >> 1], 00694 ("Psp386InstallIoHandler : Ushort fns don't match\n") 00695 ); 00696 VdmIoHandler->IoFunctions[1].UshortIo[(PortNumber & 2) >> 1] = 00697 (PDRIVER_IO_PORT_USHORT)EmulatorAccessEntry->Routine; 00698 } 00699 break; 00700 case Ulong: 00701 if (EmulatorAccessEntry->StringSupport) { 00702 ASSERTEQUALBREAK( 00703 NULL, 00704 VdmIoHandler->IoFunctions[1].UlongStringIo, 00705 ("Psp386InstallIoHandler : UlongString fns don't match\n") 00706 ); 00707 VdmIoHandler->IoFunctions[1].UlongStringIo = 00708 (PDRIVER_IO_PORT_ULONG_STRING)EmulatorAccessEntry->Routine; 00709 } else { 00710 ASSERTEQUALBREAK( 00711 NULL, 00712 VdmIoHandler->IoFunctions[1].UlongIo, 00713 ("Psp386InstallIoHandler : Ulong fns don't match\n") 00714 ); 00715 VdmIoHandler->IoFunctions[1].UlongIo = 00716 (PDRIVER_IO_PORT_ULONG)EmulatorAccessEntry->Routine; 00717 } 00718 } 00719 } 00720 00721 ExReleaseResource(&pVdmObjects->VdmIoListHead->VdmIoResource); 00722 KeLowerIrql(OldIrql); 00723 return STATUS_SUCCESS; 00724 00725 }

NTSTATUS Psp386RemoveIoHandler IN PEPROCESS  Process,
IN PEMULATOR_ACCESS_ENTRY  EmulatorAccessEntry,
IN ULONG  PortNumber
 

Definition at line 280 of file i386/psvdm.c.

References APC_LEVEL, ASSERTEQUAL, ASSERTEQUALBREAK, DbgPrint, EMULATOR_READ_ACCESS, EMULATOR_WRITE_ACCESS, ExAcquireResourceExclusive, ExReleaseResource, KeLowerIrql(), KeRaiseIrql(), NULL, PAGED_CODE, Psp386GetVdmIoHandler(), TRUE, Uchar, Ulong, and Ushort.

Referenced by PspSetProcessIoHandlers().

00287 : 00288 00289 This routine remove a handler for a port. On debug version, it will 00290 print a message if there is no handler. 00291 00292 Arguments: 00293 00294 Process -- Supplies a pointer to the process 00295 EmulatorAccess -- Supplies a pointer to the information about the 00296 io port handler 00297 PortNumber -- Supplies the port number to remove the handler from. 00298 00299 Return Value: 00300 00301 --*/ 00302 { 00303 PVDM_PROCESS_OBJECTS pVdmObjects = Process->VdmObjects; 00304 PVDM_IO_HANDLER VdmIoHandler; 00305 KIRQL OldIrql; 00306 PAGED_CODE(); 00307 00308 // 00309 // Ensure we have a vdm process which is initialized 00310 // correctly for VdmIoHandlers 00311 // 00312 if (!pVdmObjects) { 00313 #if DBG 00314 DbgPrint("Psp386RemoveIoHandler: uninitialized VdmObjects\n"); 00315 #endif 00316 return STATUS_UNSUCCESSFUL; 00317 } 00318 00319 00320 // 00321 // If the list does not have a head, then there are no handlers to 00322 // remove. 00323 // 00324 if (!pVdmObjects->VdmIoListHead) { 00325 #if DBG 00326 DbgPrint("Psp386RemoveIoHandler : attempt to remove non-existent hdlr\n"); 00327 #endif 00328 return STATUS_SUCCESS; 00329 } 00330 00331 // 00332 // Lock the list, so we can insure a correct update. 00333 // 00334 KeRaiseIrql(APC_LEVEL, &OldIrql); 00335 ExAcquireResourceExclusive(&pVdmObjects->VdmIoListHead->VdmIoResource,TRUE); 00336 00337 VdmIoHandler = Psp386GetVdmIoHandler( 00338 Process, 00339 PortNumber & ~0x3 00340 ); 00341 00342 if (!VdmIoHandler) { 00343 #if DBG 00344 DbgPrint("Psp386RemoveIoHandler : attempt to remove non-existent hdlr\n"); 00345 #endif 00346 ExReleaseResource(&pVdmObjects->VdmIoListHead->VdmIoResource); 00347 KeLowerIrql(OldIrql); 00348 return STATUS_SUCCESS; 00349 } 00350 00351 ASSERTEQUALBREAK( 00352 VdmIoHandler->PortNumber, 00353 PortNumber & ~0x3, 00354 ("Psp386RemoveIoHandler : Bad pointer returned from GetVdmIoHandler\n") 00355 ); 00356 00357 if (EmulatorAccessEntry->AccessMode & EMULATOR_READ_ACCESS) { 00358 switch (EmulatorAccessEntry->AccessType) { 00359 case Uchar: 00360 if (EmulatorAccessEntry->StringSupport) { 00361 ASSERTEQUAL( 00362 EmulatorAccessEntry->Routine, 00363 VdmIoHandler->IoFunctions[0].UcharStringIo[PortNumber % 4], 00364 ("Psp386RemoveIoHandler : UcharString fns don't match\n") 00365 ); 00366 VdmIoHandler->IoFunctions[0].UcharStringIo[PortNumber % 4] = NULL; 00367 } else { 00368 ASSERTEQUAL( 00369 EmulatorAccessEntry->Routine, 00370 VdmIoHandler->IoFunctions[0].UcharIo[PortNumber % 4], 00371 ("Psp386RemoveIoHandler : Uchar fns don't match\n") 00372 ); 00373 VdmIoHandler->IoFunctions[0].UcharIo[PortNumber % 4] = NULL; 00374 } 00375 break; 00376 case Ushort: 00377 if (EmulatorAccessEntry->StringSupport) { 00378 ASSERTEQUAL( 00379 EmulatorAccessEntry->Routine, 00380 VdmIoHandler->IoFunctions[0].UshortStringIo[(PortNumber & 2) >> 1], 00381 ("Psp386RemoveIoHandler : UshortString fns don't match\n") 00382 ); 00383 VdmIoHandler->IoFunctions[0].UshortStringIo[(PortNumber & 2) >> 1] = NULL; 00384 } else { 00385 ASSERTEQUAL( 00386 EmulatorAccessEntry->Routine, 00387 VdmIoHandler->IoFunctions[0].UshortIo[(PortNumber & 2) >> 1], 00388 ("Psp386RemoveIoHandler : Ushort fns don't match\n") 00389 ); 00390 VdmIoHandler->IoFunctions[0].UshortIo[(PortNumber & 2) >> 1] = NULL; 00391 } 00392 break; 00393 case Ulong: 00394 if (EmulatorAccessEntry->StringSupport) { 00395 ASSERTEQUAL( 00396 EmulatorAccessEntry->Routine, 00397 VdmIoHandler->IoFunctions[0].UlongStringIo, 00398 ("Psp386RemoveIoHandler : UlongString fns don't match\n") 00399 ); 00400 VdmIoHandler->IoFunctions[0].UlongStringIo = NULL; 00401 } else { 00402 ASSERTEQUAL( 00403 EmulatorAccessEntry->Routine, 00404 VdmIoHandler->IoFunctions[0].UlongIo, 00405 ("Psp386RemoveIoHandler : Ulong fns don't match\n") 00406 ); 00407 VdmIoHandler->IoFunctions[0].UlongIo = NULL; 00408 } 00409 break; 00410 } 00411 } 00412 00413 if (EmulatorAccessEntry->AccessMode & EMULATOR_WRITE_ACCESS) { 00414 switch (EmulatorAccessEntry->AccessType) { 00415 case Uchar: 00416 if (EmulatorAccessEntry->StringSupport) { 00417 ASSERTEQUAL( 00418 EmulatorAccessEntry->Routine, 00419 VdmIoHandler->IoFunctions[1].UcharStringIo[PortNumber % 4], 00420 ("Psp386RemoveIoHandler : UcharString fns don't match\n") 00421 ); 00422 VdmIoHandler->IoFunctions[1].UcharStringIo[PortNumber % 4] = NULL; 00423 } else { 00424 ASSERTEQUAL( 00425 EmulatorAccessEntry->Routine, 00426 VdmIoHandler->IoFunctions[1].UcharIo[PortNumber % 4], 00427 ("Psp386RemoveIoHandler : Uchar fns don't match\n") 00428 ); 00429 VdmIoHandler->IoFunctions[1].UcharIo[PortNumber % 4] = NULL; 00430 } 00431 break; 00432 case Ushort: 00433 if (EmulatorAccessEntry->StringSupport) { 00434 ASSERTEQUAL( 00435 EmulatorAccessEntry->Routine, 00436 VdmIoHandler->IoFunctions[1].UshortStringIo[(PortNumber & 2) >> 1], 00437 ("Psp386RemoveIoHandler : UshortString fns don't match\n") 00438 ); 00439 VdmIoHandler->IoFunctions[1].UshortStringIo[(PortNumber & 2) >> 1] = NULL; 00440 } else { 00441 ASSERTEQUAL( 00442 EmulatorAccessEntry->Routine, 00443 VdmIoHandler->IoFunctions[1].UshortIo[(PortNumber & 2) >> 1], 00444 ("Psp386RemoveIoHandler : Ushort fns don't match\n") 00445 ); 00446 VdmIoHandler->IoFunctions[1].UshortIo[(PortNumber & 2) >> 1] = NULL; 00447 } 00448 break; 00449 case Ulong: 00450 if (EmulatorAccessEntry->StringSupport) { 00451 ASSERTEQUAL( 00452 EmulatorAccessEntry->Routine, 00453 VdmIoHandler->IoFunctions[1].UlongStringIo, 00454 ("Psp386RemoveIoHandler : UlongString fns don't match\n") 00455 ); 00456 VdmIoHandler->IoFunctions[1].UlongStringIo = NULL; 00457 } else { 00458 ASSERTEQUAL( 00459 EmulatorAccessEntry->Routine, 00460 VdmIoHandler->IoFunctions[1].UlongIo, 00461 ("Psp386RemoveIoHandler : Ulong fns don't match\n") 00462 ); 00463 VdmIoHandler->IoFunctions[1].UlongIo = NULL; 00464 } 00465 break; 00466 } 00467 } 00468 00469 ExReleaseResource(&pVdmObjects->VdmIoListHead->VdmIoResource); 00470 KeLowerIrql(OldIrql); 00471 00472 return STATUS_SUCCESS; 00473 00474 }

VOID PspDeleteVdmObjects IN PEPROCESS  Process  ) 
 

Definition at line 203 of file i386/psvdm.c.

References ExDeleteResource, ExFreePool(), KeAcquireSpinLock, KeReleaseSpinLock(), and NULL.

00208 : 00209 00210 Frees the VdmObjects structure and the Frees the IoHandler list 00211 00212 Arguments: 00213 00214 Process -- Supplies a pointer to the process 00215 00216 Return Value: 00217 00218 None 00219 --*/ 00220 { 00221 00222 PVDM_PROCESS_OBJECTS pVdmObjects = Process->VdmObjects; 00223 PVDM_IO_HANDLER p1, p2; 00224 PVDM_IO_LISTHEAD p3; 00225 PLIST_ENTRY Next; 00226 PDELAYINTIRQ pDelayIntIrq; 00227 KIRQL OldIrql; 00228 00229 if (pVdmObjects == NULL) { 00230 return; 00231 } 00232 00233 // 00234 // First Free any port handler entries for this process, 00235 // 00236 p1 = NULL; 00237 p3 = pVdmObjects->VdmIoListHead; 00238 00239 if (p3) { 00240 p2 = p3->VdmIoHandlerList; 00241 00242 while (p2) { 00243 p1 = p2; 00244 p2 = p1->Next; 00245 ExFreePool( p1 ); 00246 } 00247 00248 ExDeleteResource(&p3->VdmIoResource); 00249 00250 ExFreePool( p3 ); 00251 pVdmObjects->VdmIoListHead = NULL; 00252 } 00253 00254 if (pVdmObjects->pIcaUserData) { 00255 ExFreePool(pVdmObjects->pIcaUserData); 00256 } 00257 00258 // 00259 // Free up the DelayedIntList, canceling pending timers. 00260 // 00261 KeAcquireSpinLock(&pVdmObjects->DelayIntSpinLock, &OldIrql); 00262 00263 Next = pVdmObjects->DelayIntListHead.Flink; 00264 while (Next != &pVdmObjects->DelayIntListHead) { 00265 pDelayIntIrq = CONTAINING_RECORD(Next, DELAYINTIRQ, DelayIntListEntry); 00266 Next = Next->Flink; 00267 RemoveEntryList(&pDelayIntIrq->DelayIntListEntry); 00268 ExFreePool(pDelayIntIrq); 00269 } 00270 00271 KeReleaseSpinLock(&pVdmObjects->DelayIntSpinLock, OldIrql); 00272 00273 ExFreePool(Process->VdmObjects); 00274 Process->VdmObjects = NULL; 00275 }

NTSTATUS PspSetProcessIoHandlers IN PEPROCESS  Process,
IN PVOID  IoHandlerInformation,
IN ULONG  IoHandlerLength
 

Definition at line 101 of file i386/psvdm.c.

References KernelMode, NT_SUCCESS, NTSTATUS(), PAGED_CODE, Psp386InstallIoHandler(), Psp386RemoveIoHandler(), Status, Uchar, Ulong, and Ushort.

00108 : 00109 00110 This routine installs a device driver IO handling routine for the 00111 specified process. If an io operation is detected in a vdm on a port 00112 that has a device driver IO handling routine, that routine will be called. 00113 00114 Arguments: 00115 00116 Process -- Supplies a pointer to the process for which Io port handlers 00117 are to be installed 00118 IoHandlerInformation -- Supplies a pointer to the information about the 00119 io port handlers 00120 IoHandlerLength -- Supplies the length of the IoHandlerInformation 00121 structure. 00122 00123 Return Value: 00124 00125 00126 00127 --*/ 00128 { 00129 PPROCESS_IO_PORT_HANDLER_INFORMATION IoHandlerInfo; 00130 NTSTATUS Status; 00131 PEMULATOR_ACCESS_ENTRY EmulatorAccess; 00132 ULONG EmulatorEntryNumber, NumberPorts; 00133 ULONG PortSize; 00134 PAGED_CODE(); 00135 00136 // 00137 // Insure that this call was made from KernelMode 00138 // 00139 if (KeGetPreviousMode() != KernelMode) { 00140 return STATUS_INVALID_PARAMETER; // this info type invalid in usermode 00141 } 00142 // 00143 // Insure that the data passed is long enough 00144 // 00145 if (IoHandlerLength < (ULONG)sizeof( PROCESS_IO_PORT_HANDLER_INFORMATION)) { 00146 return STATUS_INFO_LENGTH_MISMATCH; 00147 } 00148 IoHandlerInfo = IoHandlerInformation; 00149 00150 // 00151 // For each of the entries in the array that describes the handlers, 00152 // determine what size of port the specified handler is being installed 00153 // for, and then iterate over each individual port. 00154 // 00155 for (EmulatorEntryNumber = 0, EmulatorAccess = 00156 IoHandlerInfo->EmulatorAccessEntries; 00157 EmulatorEntryNumber < IoHandlerInfo->NumEntries; 00158 EmulatorEntryNumber++, EmulatorAccess++) { 00159 00160 switch (EmulatorAccess->AccessType) { 00161 case Uchar: 00162 PortSize = 1; 00163 break; 00164 case Ushort: 00165 PortSize = 2; 00166 break; 00167 case Ulong: 00168 PortSize = 4; 00169 } 00170 00171 for (NumberPorts = 0; 00172 NumberPorts < EmulatorAccess->NumConsecutivePorts; 00173 NumberPorts++) { 00174 if (IoHandlerInfo->Install) { 00175 Status = Psp386InstallIoHandler( 00176 Process, 00177 EmulatorAccess, 00178 EmulatorAccess->BasePort + NumberPorts * PortSize, 00179 IoHandlerInfo->Context 00180 ); 00181 if (NT_SUCCESS(Status)) { 00182 } 00183 } else { 00184 Status = Psp386RemoveIoHandler( 00185 Process, 00186 EmulatorAccess, 00187 EmulatorAccess->BasePort + NumberPorts * PortSize 00188 ); 00189 } 00190 if (!NT_SUCCESS(Status)) { 00191 goto exitloop; 00192 } 00193 } 00194 } 00195 Status = STATUS_SUCCESS; 00196 exitloop: 00197 return Status; 00198 00199 }

NTSTATUS PspVdmInitialize  ) 
 

Definition at line 987 of file i386/psvdm.c.

References ExInitializeResource, and VdmIoListCreationResource.

Referenced by PspInitPhase0().

00992 : 00993 00994 This routine initializes the process based Vdm support for x86. 00995 00996 Arguments: 00997 00998 None 00999 01000 Return Value: 01001 01002 TBS 01003 --*/ 01004 { 01005 return ExInitializeResource(&VdmIoListCreationResource); 01006 } }


Variable Documentation

ERESOURCE VdmIoListCreationResource
 

Definition at line 95 of file i386/psvdm.c.

Referenced by Psp386CreateVdmIoListHead(), and PspVdmInitialize().


Generated on Sat May 15 19:45:24 2004 for test by doxygen 1.3.7