OSDN Git Service

[Release] 2.0.26
[dokopop/dokopop.git] / VxD / hk95c.c
1 //// HK95c.c
2 // --------------------------------------------
3 // Dynamically loadable VxD for DCHOOK
4 // --------------------------------------------
5 #define WIN32_LEAN_AND_MEAN // Excludes un-needed parts of windows.h
6 #include <windows.h>
7 #include <vmm.h>
8 #include <vwin32.h>
9 #include <debug.h>
10 #include "hk95d.h"
11
12 // -------------------------------------
13 // Externs defined in assembly module 
14 // -------------------------------------
15 // These defined in assembly for the VMM.INC or VPICD.INC file inclusion
16 // ------------------------
17 // PRAGMA for this DATA 
18 // ------------------------
19 // Establish segment
20 #pragma data_seg ( "_LDATA","_LCODE")
21
22 // ------------------------------------
23 // Data structures MUST be INITIALIZED
24 // ------------------------------------
25 // ------------------------
26 // PRAGMAS for this CODE 
27 // ------------------------
28 // Establish segment
29 #pragma code_seg ( "_LTEXT", "_LCODE" )
30 //No stack checking for routines in this module
31 #pragma check_stack(off)
32
33 // ---------------------------------------
34 // Set Good Return code for DIOC requests
35 // ---------------------------------------
36 void _declspec(naked)GoodReturnDIOC(void)
37 {
38         // Clear eax and carry flag for GOOD return
39         _asm xor eax,eax
40         _asm clc
41         _asm ret;
42 }
43
44 // ---------------------------------------
45 // Set Bad Return code for DIOC requests
46 // ---------------------------------------
47 void _declspec(naked) BadReturnDIOC(void)
48 {
49         // NOTE: 50 is a FCN NOT SUPPORTED code -- ok to use
50         // SET carry flag for BAD return
51         _asm mov eax,50
52         _asm stc
53         _asm ret;
54 }
55
56
57 // ------------------------------
58 // Routine for DCHOOK Device UNINIT  
59 // ------------------------------
60 void CHK95_Device_UNInit()
61 {
62         // Set GOOD return code
63         GoodReturnDIOC();
64         return;
65 }
66 // ------------------------------
67 // Routine for DCHOOK Device INIT  
68 // ------------------------------
69
70 void CHK95_Device_Init()
71 {
72     GoodReturnDIOC();
73 }
74 DWORD VXDINLINE
75 PageModPerm( DWORD Page, DWORD nPages, DWORD Flags1, DWORD Flags2 )
76 {
77     DWORD    dw;
78
79         _asm push [Flags2]
80         _asm push [Flags1]
81         _asm push [nPages]
82         _asm push [Page]
83     VMMCall( _PageModifyPermissions );
84         _asm add esp, 10h
85     _asm mov [dw], eax
86
87     return(dw);
88 }
89
90 // --------------------------------
91 // Routine for DCHOOK Device IO ctrl  
92 // --------------------------------
93 void CHK95_Device_IOctrl(PDIOCPARAMETERS ptr)
94 {
95         int i;
96         unsigned int addr;
97         unsigned int page;
98         int npage;
99         unsigned char *p;
100         unsigned char *q;
101         DWORD oldpermission;
102         // Field the DEV IO requests from VMM
103         switch(ptr->dwIoControlCode)
104                 {
105                 case DIOC_WRITEABLE_MEMORY:     // The address to be changed must be already committed.
106                         if ( ptr->lpvInBuffer ){
107                                 // Does it need a PC_STATIC?
108
109                                 long r = 0;
110
111                                 // I don't know exact parameters. But it works well, so I don't care about it....
112
113                                 r = PageModPerm( *((DWORD*)ptr->lpvInBuffer), 1, 0xFFFFFFFF, PC_WRITEABLE | PC_USER | PC_STATIC );
114                                 if ( ptr->lpvOutBuffer ){
115                                         *((DWORD*)ptr->lpvOutBuffer) = r;
116                                 }
117                         }
118                 break;
119                 case DIOC_NONWRITEABLE_MEMORY:  // The address to be changed must be already committed.
120                         {
121                         long r = 0;
122
123                         r = PageModPerm( *((DWORD*)ptr->lpvInBuffer), 1, ~PC_WRITEABLE, PC_USER | PC_STATIC );
124                         if ( ptr->lpvOutBuffer ){
125                                 *((DWORD*)ptr->lpvOutBuffer) = r;
126                         }
127                         }
128                 break;
129                 case DIOC_CHANGE_MEMORY:
130                         addr = (DWORD)ptr->lpvOutBuffer;
131                         page = addr >> 12;      // 4KB
132                         npage = ((addr + ptr->cbInBuffer) >> 12) - page + 1;
133                         oldpermission = PageModPerm( page, npage, 0xFFFFFFFF, PC_WRITEABLE | PC_USER | PC_STATIC );
134                         _asm pushfd
135                         _asm cli
136                         if ( oldpermission == (DWORD)-1 ){
137                                 _asm popfd
138                                 BadReturnDIOC();
139                                 return;
140                         }
141                         p = (unsigned char*)addr;
142                         q = (unsigned char*)ptr->lpvInBuffer;
143                         for ( i=0;i<ptr->cbInBuffer;i++ ){
144                                 *p++ = *q++;
145                         }
146                         PageModPerm( page, npage, oldpermission, oldpermission );
147                         _asm popfd
148                 break;
149 #if 0
150                 case DIOC_DEBUG:
151                         *(DWORD*)ptr->lpvOutBuffer = (DWORD)CHK95_Device_IOctrl;
152                 break;
153 #endif
154                 //The below DIOC_GETVERSION is a part of the dynamic load protocol
155                 //It MUST return a GOOD code (all codes here use GoodReturnDIOC()
156 //              case(DIOC_GETVERSION):
157 //              case(DIOC_CLOSEHANDLE):
158 //              default:
159 //              break;
160         }
161         GoodReturnDIOC();
162         return;
163 }
164