Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1 | /* |
| 2 | * VxD emulation |
| 3 | * |
| 4 | * Copyright 1995 Anand Kumria |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Lesser General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2.1 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library; if not, write to the Free Software |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 19 | */ |
| 20 | |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 21 | #include "config.h" |
Patrik Stridvall | 51e6c0c | 2002-08-31 19:04:14 +0000 | [diff] [blame] | 22 | #include "wine/port.h" |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 23 | |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 24 | #include <fcntl.h> |
| 25 | #include <memory.h> |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 26 | #include <stdarg.h> |
Patrik Stridvall | 51e6c0c | 2002-08-31 19:04:14 +0000 | [diff] [blame] | 27 | #include <stdio.h> |
Jeremy White | d3e22d9 | 2000-02-10 19:03:02 +0000 | [diff] [blame] | 28 | #include <sys/types.h> |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 29 | #ifdef HAVE_UNISTD_H |
| 30 | # include <unistd.h> |
| 31 | #endif |
Dimitrie O. Paun | 297f3d8 | 2003-01-07 20:36:20 +0000 | [diff] [blame] | 32 | |
| 33 | #define NONAMELESSUNION |
| 34 | #define NONAMELESSSTRUCT |
Jeremy White | d3e22d9 | 2000-02-10 19:03:02 +0000 | [diff] [blame] | 35 | #include "windef.h" |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 36 | #include "winbase.h" |
| 37 | #include "winreg.h" |
Patrik Stridvall | 9c1de6d | 2002-09-12 22:07:02 +0000 | [diff] [blame] | 38 | #include "winternl.h" |
Jeremy White | d3e22d9 | 2000-02-10 19:03:02 +0000 | [diff] [blame] | 39 | #include "wingdi.h" |
Marcus Meissner | 219cfd8 | 1999-02-24 13:05:13 +0000 | [diff] [blame] | 40 | #include "winuser.h" |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 41 | #include "ntstatus.h" |
Marcus Meissner | 219cfd8 | 1999-02-24 13:05:13 +0000 | [diff] [blame] | 42 | #include "wine/winbase16.h" |
| 43 | #include "wine/winuser16.h" |
Alexandre Julliard | e983652 | 2003-11-15 00:13:20 +0000 | [diff] [blame] | 44 | #include "dosexe.h" |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 45 | #include "wine/debug.h" |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 46 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 47 | WINE_DEFAULT_DEBUG_CHANNEL(vxd); |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 48 | |
Jukka Heinonen | 56dff0d | 2002-11-20 19:40:12 +0000 | [diff] [blame] | 49 | #define W32S_APP2WINE(addr) ((addr)? (DWORD)(addr) + W32S_offset : 0) |
| 50 | #define W32S_WINE2APP(addr) ((addr)? (DWORD)(addr) - W32S_offset : 0) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 51 | |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 52 | #define VXD_BARF(context,name) \ |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 53 | DPRINTF( "vxd %s: unknown/not implemented parameters:\n" \ |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 54 | "vxd %s: AX %04x, BX %04x, CX %04x, DX %04x, " \ |
| 55 | "SI %04x, DI %04x, DS %04x, ES %04x\n", \ |
| 56 | (name), (name), AX_reg(context), BX_reg(context), \ |
| 57 | CX_reg(context), DX_reg(context), SI_reg(context), \ |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 58 | DI_reg(context), (WORD)context->SegDs, (WORD)context->SegEs ) |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 59 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 60 | UINT W32S_offset = 0; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 61 | |
| 62 | static WORD VXD_WinVersion(void) |
| 63 | { |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 64 | WORD version = LOWORD(GetVersion16()); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 65 | return (version >> 8) | (version << 8); |
| 66 | } |
| 67 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 68 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 69 | * VXD_VMM (WPROCS.401) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 70 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 71 | void WINAPI VXD_VMM ( CONTEXT86 *context ) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 72 | { |
| 73 | unsigned service = AX_reg(context); |
| 74 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 75 | TRACE("[%04x] VMM\n", (UINT16)service); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 76 | |
| 77 | switch(service) |
| 78 | { |
| 79 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 80 | SET_AX( context, VXD_WinVersion() ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 81 | RESET_CFLAG(context); |
| 82 | break; |
| 83 | |
Ulrich Weigand | ff1c569 | 1998-10-14 18:01:08 +0000 | [diff] [blame] | 84 | case 0x026d: /* Get_Debug_Flag '/m' */ |
| 85 | case 0x026e: /* Get_Debug_Flag '/n' */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 86 | SET_AL( context, 0 ); |
Ulrich Weigand | ff1c569 | 1998-10-14 18:01:08 +0000 | [diff] [blame] | 87 | RESET_CFLAG(context); |
| 88 | break; |
| 89 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 90 | default: |
| 91 | VXD_BARF( context, "VMM" ); |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 96 | * VXD_PageFile (WPROCS.433) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 97 | */ |
Alexandre Julliard | 617955d | 1999-06-26 18:40:24 +0000 | [diff] [blame] | 98 | void WINAPI VXD_PageFile( CONTEXT86 *context ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 99 | { |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 100 | unsigned service = AX_reg(context); |
| 101 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 102 | /* taken from Ralf Brown's Interrupt List */ |
| 103 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 104 | TRACE("[%04x] PageFile\n", (UINT16)service ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 105 | |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 106 | switch(service) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 107 | { |
| 108 | case 0x00: /* get version, is this windows version? */ |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 109 | TRACE("returning version\n"); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 110 | SET_AX( context, VXD_WinVersion() ); |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 111 | RESET_CFLAG(context); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 112 | break; |
| 113 | |
| 114 | case 0x01: /* get swap file info */ |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 115 | TRACE("VxD PageFile: returning swap file info\n"); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 116 | SET_AX( context, 0x00 ); /* paging disabled */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 117 | context->Ecx = 0; /* maximum size of paging file */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 118 | /* FIXME: do I touch DS:SI or DS:DI? */ |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 119 | RESET_CFLAG(context); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 120 | break; |
| 121 | |
| 122 | case 0x02: /* delete permanent swap on exit */ |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 123 | TRACE("VxD PageFile: supposed to delete swap\n"); |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 124 | RESET_CFLAG(context); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 125 | break; |
| 126 | |
| 127 | case 0x03: /* current temporary swap file size */ |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 128 | TRACE("VxD PageFile: what is current temp. swap size\n"); |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 129 | RESET_CFLAG(context); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 130 | break; |
| 131 | |
| 132 | case 0x04: /* read or write?? INTERRUP.D */ |
| 133 | case 0x05: /* cancel?? INTERRUP.D */ |
| 134 | case 0x06: /* test I/O valid INTERRUP.D */ |
| 135 | default: |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 136 | VXD_BARF( context, "pagefile" ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 137 | break; |
| 138 | } |
| 139 | } |
| 140 | |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 141 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 142 | * VXD_Reboot (WPROCS.409) |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 143 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 144 | void WINAPI VXD_Reboot ( CONTEXT86 *context ) |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 145 | { |
| 146 | unsigned service = AX_reg(context); |
| 147 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 148 | TRACE("[%04x] Reboot\n", (UINT16)service); |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 149 | |
| 150 | switch(service) |
| 151 | { |
| 152 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 153 | SET_AX( context, VXD_WinVersion() ); |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 154 | RESET_CFLAG(context); |
| 155 | break; |
| 156 | |
| 157 | default: |
| 158 | VXD_BARF( context, "REBOOT" ); |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 163 | * VXD_VDD (WPROCS.410) |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 164 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 165 | void WINAPI VXD_VDD ( CONTEXT86 *context ) |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 166 | { |
| 167 | unsigned service = AX_reg(context); |
| 168 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 169 | TRACE("[%04x] VDD\n", (UINT16)service); |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 170 | |
| 171 | switch(service) |
| 172 | { |
| 173 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 174 | SET_AX( context, VXD_WinVersion() ); |
Ulrich Weigand | 0b597bc | 1998-10-11 19:01:33 +0000 | [diff] [blame] | 175 | RESET_CFLAG(context); |
| 176 | break; |
| 177 | |
| 178 | default: |
| 179 | VXD_BARF( context, "VDD" ); |
| 180 | } |
| 181 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 182 | |
| 183 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 184 | * VXD_VMD (WPROCS.412) |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 185 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 186 | void WINAPI VXD_VMD ( CONTEXT86 *context ) |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 187 | { |
| 188 | unsigned service = AX_reg(context); |
| 189 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 190 | TRACE("[%04x] VMD\n", (UINT16)service); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 191 | |
| 192 | switch(service) |
| 193 | { |
| 194 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 195 | SET_AX( context, VXD_WinVersion() ); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 196 | RESET_CFLAG(context); |
| 197 | break; |
| 198 | |
| 199 | default: |
| 200 | VXD_BARF( context, "VMD" ); |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 205 | * VXD_VXDLoader (WPROCS.439) |
James Abbatiello | 5f150ba | 2000-08-28 19:29:26 +0000 | [diff] [blame] | 206 | */ |
| 207 | void WINAPI VXD_VXDLoader( CONTEXT86 *context ) |
| 208 | { |
| 209 | unsigned service = AX_reg(context); |
| 210 | |
| 211 | TRACE("[%04x] VXDLoader\n", (UINT16)service); |
| 212 | |
| 213 | switch (service) |
| 214 | { |
| 215 | case 0x0000: /* get version */ |
| 216 | TRACE("returning version\n"); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 217 | SET_AX( context, 0x0000 ); |
| 218 | SET_DX( context, VXD_WinVersion() ); |
James Abbatiello | 5f150ba | 2000-08-28 19:29:26 +0000 | [diff] [blame] | 219 | RESET_CFLAG(context); |
| 220 | break; |
| 221 | |
| 222 | case 0x0001: /* load device */ |
| 223 | FIXME("load device %04lx:%04x (%s)\n", |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 224 | context->SegDs, DX_reg(context), |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 225 | debugstr_a(MapSL(MAKESEGPTR(context->SegDs, DX_reg(context))))); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 226 | SET_AX( context, 0x0000 ); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 227 | context->SegEs = 0x0000; |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 228 | SET_DI( context, 0x0000 ); |
James Abbatiello | 5f150ba | 2000-08-28 19:29:26 +0000 | [diff] [blame] | 229 | RESET_CFLAG(context); |
| 230 | break; |
| 231 | |
| 232 | case 0x0002: /* unload device */ |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 233 | FIXME("unload device (%08lx)\n", context->Ebx); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 234 | SET_AX( context, 0x0000 ); |
James Abbatiello | 5f150ba | 2000-08-28 19:29:26 +0000 | [diff] [blame] | 235 | RESET_CFLAG(context); |
| 236 | break; |
| 237 | |
| 238 | default: |
| 239 | VXD_BARF( context, "VXDLDR" ); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 240 | SET_AX( context, 0x000B ); /* invalid function number */ |
James Abbatiello | 5f150ba | 2000-08-28 19:29:26 +0000 | [diff] [blame] | 241 | SET_CFLAG(context); |
| 242 | break; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 243 | } |
James Abbatiello | 5f150ba | 2000-08-28 19:29:26 +0000 | [diff] [blame] | 244 | } |
| 245 | |
| 246 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 247 | * VXD_Shell (WPROCS.423) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 248 | */ |
Alexandre Julliard | 617955d | 1999-06-26 18:40:24 +0000 | [diff] [blame] | 249 | void WINAPI VXD_Shell( CONTEXT86 *context ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 250 | { |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 251 | unsigned service = DX_reg(context); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 252 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 253 | TRACE("[%04x] Shell\n", (UINT16)service); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 254 | |
| 255 | switch (service) /* Ralf Brown says EDX, but I use DX instead */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 256 | { |
| 257 | case 0x0000: |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 258 | TRACE("returning version\n"); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 259 | SET_AX( context, VXD_WinVersion() ); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 260 | context->Ebx = 1; /* system VM Handle */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 261 | break; |
| 262 | |
| 263 | case 0x0001: |
| 264 | case 0x0002: |
| 265 | case 0x0003: |
Juergen Schmied | f08b819 | 1999-05-22 10:33:50 +0000 | [diff] [blame] | 266 | /* SHELL_SYSMODAL_Message |
| 267 | ebx virtual maschine handle |
| 268 | eax message box flags |
| 269 | ecx address of message |
| 270 | edi address of caption |
| 271 | return response in eax |
| 272 | */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 273 | case 0x0004: |
Juergen Schmied | f08b819 | 1999-05-22 10:33:50 +0000 | [diff] [blame] | 274 | /* SHELL_Message |
| 275 | ebx virtual maschine handle |
| 276 | eax message box flags |
| 277 | ecx address of message |
| 278 | edi address of caption |
| 279 | esi address callback |
| 280 | edx reference data for callback |
| 281 | return response in eax |
| 282 | */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 283 | case 0x0005: |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 284 | VXD_BARF( context, "shell" ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 285 | break; |
| 286 | |
| 287 | case 0x0006: /* SHELL_Get_VM_State */ |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 288 | TRACE("VxD Shell: returning VM state\n"); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 289 | /* Actually we don't, not yet. We have to return a structure |
| 290 | * and I am not to sure how to set it up and return it yet, |
| 291 | * so for now let's do nothing. I can (hopefully) get this |
| 292 | * by the next release |
| 293 | */ |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 294 | /* RESET_CFLAG(context); */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 295 | break; |
| 296 | |
| 297 | case 0x0007: |
| 298 | case 0x0008: |
| 299 | case 0x0009: |
| 300 | case 0x000A: |
| 301 | case 0x000B: |
| 302 | case 0x000C: |
| 303 | case 0x000D: |
| 304 | case 0x000E: |
| 305 | case 0x000F: |
| 306 | case 0x0010: |
| 307 | case 0x0011: |
| 308 | case 0x0012: |
| 309 | case 0x0013: |
| 310 | case 0x0014: |
| 311 | case 0x0015: |
| 312 | case 0x0016: |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 313 | VXD_BARF( context, "SHELL" ); |
| 314 | break; |
| 315 | |
| 316 | /* the new Win95 shell API */ |
| 317 | case 0x0100: /* get version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 318 | SET_AX( context, VXD_WinVersion() ); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 319 | break; |
| 320 | |
| 321 | case 0x0104: /* retrieve Hook_Properties list */ |
| 322 | case 0x0105: /* call Hook_Properties callbacks */ |
| 323 | VXD_BARF( context, "SHELL" ); |
| 324 | break; |
| 325 | |
| 326 | case 0x0106: /* install timeout callback */ |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 327 | TRACE("VxD Shell: ignoring shell callback (%ld sec.)\n", context->Ebx); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 328 | SET_CFLAG(context); |
| 329 | break; |
| 330 | |
| 331 | case 0x0107: /* get version of any VxD */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 332 | default: |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 333 | VXD_BARF( context, "SHELL" ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 334 | break; |
| 335 | } |
| 336 | } |
| 337 | |
| 338 | |
| 339 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 340 | * VXD_Comm (WPROCS.414) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 341 | */ |
Alexandre Julliard | 617955d | 1999-06-26 18:40:24 +0000 | [diff] [blame] | 342 | void WINAPI VXD_Comm( CONTEXT86 *context ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 343 | { |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 344 | unsigned service = AX_reg(context); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 345 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 346 | TRACE("[%04x] Comm\n", (UINT16)service); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 347 | |
| 348 | switch (service) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 349 | { |
| 350 | case 0x0000: /* get version */ |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 351 | TRACE("returning version\n"); |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 352 | SET_AX( context, VXD_WinVersion() ); |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 353 | RESET_CFLAG(context); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 354 | break; |
| 355 | |
| 356 | case 0x0001: /* set port global */ |
| 357 | case 0x0002: /* get focus */ |
| 358 | case 0x0003: /* virtualise port */ |
| 359 | default: |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 360 | VXD_BARF( context, "comm" ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 361 | } |
| 362 | } |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 363 | |
| 364 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 365 | * VXD_Timer (WPROCS.405) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 366 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 367 | void WINAPI VXD_Timer( CONTEXT86 *context ) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 368 | { |
| 369 | unsigned service = AX_reg(context); |
| 370 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 371 | TRACE("[%04x] Virtual Timer\n", (UINT16)service); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 372 | |
| 373 | switch(service) |
| 374 | { |
| 375 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 376 | SET_AX( context, VXD_WinVersion() ); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 377 | RESET_CFLAG(context); |
| 378 | break; |
| 379 | |
| 380 | case 0x0100: /* clock tick time, in 840nsecs */ |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 381 | context->Eax = GetTickCount(); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 382 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 383 | context->Edx = context->Eax >> 22; |
| 384 | context->Eax <<= 10; /* not very precise */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 385 | break; |
| 386 | |
| 387 | case 0x0101: /* current Windows time, msecs */ |
| 388 | case 0x0102: /* current VM time, msecs */ |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 389 | context->Eax = GetTickCount(); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 390 | break; |
| 391 | |
| 392 | default: |
| 393 | VXD_BARF( context, "VTD" ); |
| 394 | } |
| 395 | } |
| 396 | |
Alexandre Julliard | a098c82 | 2003-05-15 23:25:49 +0000 | [diff] [blame] | 397 | |
| 398 | /*********************************************************************** |
| 399 | * timer_thread |
| 400 | */ |
| 401 | static DWORD CALLBACK timer_thread( void *arg ) |
| 402 | { |
| 403 | DWORD *system_time = arg; |
| 404 | |
| 405 | for (;;) |
| 406 | { |
| 407 | *system_time = GetTickCount(); |
| 408 | Sleep( 55 ); |
| 409 | } |
| 410 | } |
| 411 | |
| 412 | |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 413 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 414 | * VXD_TimerAPI (WPROCS.1490) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 415 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 416 | void WINAPI VXD_TimerAPI ( CONTEXT86 *context ) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 417 | { |
Alexandre Julliard | a098c82 | 2003-05-15 23:25:49 +0000 | [diff] [blame] | 418 | static WORD System_Time_Selector; |
| 419 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 420 | unsigned service = AX_reg(context); |
| 421 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 422 | TRACE("[%04x] TimerAPI\n", (UINT16)service); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 423 | |
| 424 | switch(service) |
| 425 | { |
| 426 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 427 | SET_AX( context, VXD_WinVersion() ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 428 | RESET_CFLAG(context); |
| 429 | break; |
| 430 | |
| 431 | case 0x0009: /* get system time selector */ |
Ulrich Weigand | 1cd0794 | 1998-12-10 11:01:09 +0000 | [diff] [blame] | 432 | if ( !System_Time_Selector ) |
| 433 | { |
Alexandre Julliard | a098c82 | 2003-05-15 23:25:49 +0000 | [diff] [blame] | 434 | HANDLE16 handle = GlobalAlloc16( GMEM_FIXED, sizeof(DWORD) ); |
| 435 | System_Time_Selector = handle | 7; |
| 436 | CloseHandle( CreateThread( NULL, 0, timer_thread, GlobalLock16(handle), 0, NULL ) ); |
Ulrich Weigand | 1cd0794 | 1998-12-10 11:01:09 +0000 | [diff] [blame] | 437 | } |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 438 | SET_AX( context, System_Time_Selector ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 439 | RESET_CFLAG(context); |
| 440 | break; |
| 441 | |
| 442 | default: |
| 443 | VXD_BARF( context, "VTDAPI" ); |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 448 | * VXD_ConfigMG (WPROCS.451) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 449 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 450 | void WINAPI VXD_ConfigMG ( CONTEXT86 *context ) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 451 | { |
| 452 | unsigned service = AX_reg(context); |
| 453 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 454 | TRACE("[%04x] ConfigMG\n", (UINT16)service); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 455 | |
| 456 | switch(service) |
| 457 | { |
| 458 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 459 | SET_AX( context, VXD_WinVersion() ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 460 | RESET_CFLAG(context); |
| 461 | break; |
| 462 | |
| 463 | default: |
| 464 | VXD_BARF( context, "CONFIGMG" ); |
| 465 | } |
| 466 | } |
| 467 | |
| 468 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 469 | * VXD_Enable (WPROCS.455) |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 470 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 471 | void WINAPI VXD_Enable ( CONTEXT86 *context ) |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 472 | { |
| 473 | unsigned service = AX_reg(context); |
| 474 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 475 | TRACE("[%04x] Enable\n", (UINT16)service); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 476 | |
| 477 | switch(service) |
| 478 | { |
| 479 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 480 | SET_AX( context, VXD_WinVersion() ); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 481 | RESET_CFLAG(context); |
| 482 | break; |
| 483 | |
| 484 | default: |
| 485 | VXD_BARF( context, "ENABLE" ); |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 490 | * VXD_APM (WPROCS.438) |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 491 | */ |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 492 | void WINAPI VXD_APM ( CONTEXT86 *context ) |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 493 | { |
| 494 | unsigned service = AX_reg(context); |
| 495 | |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 496 | TRACE("[%04x] APM\n", (UINT16)service); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 497 | |
| 498 | switch(service) |
| 499 | { |
| 500 | case 0x0000: /* version */ |
Alexandre Julliard | 3fa613c | 2002-08-31 18:47:00 +0000 | [diff] [blame] | 501 | SET_AX( context, VXD_WinVersion() ); |
Ulrich Weigand | ab635b2 | 1998-11-14 18:33:34 +0000 | [diff] [blame] | 502 | RESET_CFLAG(context); |
| 503 | break; |
| 504 | |
| 505 | default: |
| 506 | VXD_BARF( context, "APM" ); |
| 507 | } |
| 508 | } |
| 509 | |
| 510 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 511 | * VXD_Win32s (WPROCS.445) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 512 | * |
| 513 | * This is an implementation of the services of the Win32s VxD. |
| 514 | * Since official documentation of these does not seem to be available, |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 515 | * certain arguments of some of the services remain unclear. |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 516 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 517 | * FIXME: The following services are currently unimplemented: |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 518 | * Exception handling (0x01, 0x1C) |
| 519 | * Debugger support (0x0C, 0x14, 0x17) |
| 520 | * Low-level memory access (0x02, 0x03, 0x0A, 0x0B) |
| 521 | * Memory Statistics (0x1B) |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 522 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 523 | * |
| 524 | * We have a specific problem running Win32s on Linux (and probably also |
| 525 | * the other x86 unixes), since Win32s tries to allocate its main 'flat |
| 526 | * code/data segment' selectors with a base of 0xffff0000 (and limit 4GB). |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 527 | * The rationale for this seems to be that they want one the one hand to |
| 528 | * be able to leave the Win 3.1 memory (starting with the main DOS memory) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 529 | * at linear address 0, but want at other hand to have offset 0 of the |
| 530 | * flat data/code segment point to an unmapped page (to catch NULL pointer |
| 531 | * accesses). Hence they allocate the flat segments with a base of 0xffff0000 |
| 532 | * so that the Win 3.1 memory area at linear address zero shows up in the |
| 533 | * flat segments at offset 0x10000 (since linear addresses wrap around at |
| 534 | * 4GB). To compensate for that discrepancy between flat segment offsets |
| 535 | * and plain linear addresses, all flat pointers passed between the 32-bit |
| 536 | * and the 16-bit parts of Win32s are shifted by 0x10000 in the appropriate |
| 537 | * direction by the glue code (mainly) in W32SKRNL and WIN32S16. |
| 538 | * |
| 539 | * The problem for us is now that Linux does not allow a LDT selector with |
| 540 | * base 0xffff0000 to be created, since it would 'see' a part of the kernel |
| 541 | * address space. To address this problem we introduce *another* offset: |
| 542 | * We add 0x10000 to every linear address we get as an argument from Win32s. |
| 543 | * This means especially that the flat code/data selectors get actually |
| 544 | * allocated with base 0x0, so that flat offsets and (real) linear addresses |
| 545 | * do again agree! In fact, every call e.g. of a Win32s VxD service now |
| 546 | * has all pointer arguments (which are offsets in the flat data segement) |
| 547 | * first reduced by 0x10000 by the W32SKRNL glue code, and then again |
| 548 | * increased by 0x10000 by *our* code. |
| 549 | * |
| 550 | * Note that to keep everything consistent, this offset has to be applied by |
| 551 | * every Wine function that operates on 'linear addresses' passed to it by |
| 552 | * Win32s. Fortunately, since Win32s does not directly call any Wine 32-bit |
| 553 | * API routines, this affects only two locations: this VxD and the DPMI |
| 554 | * handler. (NOTE: Should any Win32s application pass a linear address to |
| 555 | * any routine apart from those, e.g. some other VxD handler, that code |
| 556 | * would have to take the offset into account as well!) |
| 557 | * |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 558 | * The offset is set the first time any application calls the GetVersion() |
| 559 | * service of the Win32s VxD. (Note that the offset is never reset.) |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 560 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 561 | */ |
| 562 | |
Ulrich Weigand | ff9c44f | 1999-06-27 15:28:51 +0000 | [diff] [blame] | 563 | void WINAPI VXD_Win32s( CONTEXT86 *context ) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 564 | { |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 565 | switch (AX_reg(context)) |
| 566 | { |
| 567 | case 0x0000: /* Get Version */ |
| 568 | /* |
| 569 | * Input: None |
| 570 | * |
| 571 | * Output: EAX: LoWord: Win32s Version (1.30) |
| 572 | * HiWord: VxD Version (200) |
| 573 | * |
| 574 | * EBX: Build (172) |
| 575 | * |
| 576 | * ECX: ??? (1) |
| 577 | * |
| 578 | * EDX: Debugging Flags |
| 579 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 580 | * EDI: Error Flag |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 581 | * 0 if OK, |
| 582 | * 1 if VMCPD VxD not found |
| 583 | */ |
| 584 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 585 | TRACE("GetVersion()\n"); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 586 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 587 | context->Eax = VXD_WinVersion() | (200 << 16); |
| 588 | context->Ebx = 0; |
| 589 | context->Ecx = 0; |
| 590 | context->Edx = 0; |
| 591 | context->Edi = 0; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 592 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 593 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 594 | * If this is the first time we are called for this process, |
| 595 | * hack the memory image of WIN32S16 so that it doesn't try |
| 596 | * to access the GDT directly ... |
| 597 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 598 | * The first code segment of WIN32S16 (version 1.30) contains |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 599 | * an unexported function somewhere between the exported functions |
| 600 | * SetFS and StackLinearToSegmented that tries to find a selector |
| 601 | * in the LDT that maps to the memory image of the LDT itself. |
| 602 | * If it succeeds, it stores this selector into a global variable |
| 603 | * which will be used to speed up execution by using this selector |
| 604 | * to modify the LDT directly instead of using the DPMI calls. |
| 605 | * |
| 606 | * To perform this search of the LDT, this function uses the |
| 607 | * sgdt and sldt instructions to find the linear address of |
| 608 | * the (GDT and then) LDT. While those instructions themselves |
| 609 | * execute without problem, the linear address that sgdt returns |
| 610 | * points (at least under Linux) to the kernel address space, so |
| 611 | * that any subsequent access leads to a segfault. |
| 612 | * |
| 613 | * Fortunately, WIN32S16 still contains as a fallback option the |
| 614 | * mechanism of using DPMI calls to modify LDT selectors instead |
| 615 | * of direct writes to the LDT. Thus we can circumvent the problem |
| 616 | * by simply replacing the first byte of the offending function |
| 617 | * with an 'retf' instruction. This means that the global variable |
| 618 | * supposed to contain the LDT alias selector will remain zero, |
| 619 | * and hence WIN32S16 will fall back to using DPMI calls. |
| 620 | * |
| 621 | * The heuristic we employ to _find_ that function is as follows: |
| 622 | * We search between the addresses of the exported symbols SetFS |
| 623 | * and StackLinearToSegmented for the byte sequence '0F 01 04' |
| 624 | * (this is the opcode of 'sgdt [si]'). We then search backwards |
Andreas Mohr | 8bc7f16 | 2002-02-27 01:34:08 +0000 | [diff] [blame] | 625 | * from this address for the last occurrence of 'CB' (retf) that marks |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 626 | * the end of the preceeding function. The following byte (which |
| 627 | * should now be the first byte of the function we are looking for) |
| 628 | * will be replaced by 'CB' (retf). |
| 629 | * |
| 630 | * This heuristic works for the retail as well as the debug version |
| 631 | * of Win32s version 1.30. For versions earlier than that this |
| 632 | * hack should not be necessary at all, since the whole mechanism |
| 633 | * ('PERF130') was introduced only in 1.30 to improve the overall |
| 634 | * performance of Win32s. |
| 635 | */ |
| 636 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 637 | if (!W32S_offset) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 638 | { |
| 639 | HMODULE16 hModule = GetModuleHandle16("win32s16"); |
Alexandre Julliard | 5ce902b | 2000-11-27 21:59:08 +0000 | [diff] [blame] | 640 | SEGPTR func1 = (SEGPTR)GetProcAddress16(hModule, "SetFS"); |
| 641 | SEGPTR func2 = (SEGPTR)GetProcAddress16(hModule, "StackLinearToSegmented"); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 642 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 643 | if ( hModule && func1 && func2 |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 644 | && SELECTOROF(func1) == SELECTOROF(func2)) |
| 645 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 646 | BYTE *start = MapSL(func1); |
| 647 | BYTE *end = MapSL(func2); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 648 | BYTE *p, *retv = NULL; |
| 649 | int found = 0; |
| 650 | |
| 651 | for (p = start; p < end; p++) |
| 652 | if (*p == 0xCB) found = 0, retv = p; |
| 653 | else if (*p == 0x0F) found = 1; |
| 654 | else if (*p == 0x01 && found == 1) found = 2; |
| 655 | else if (*p == 0x04 && found == 2) { found = 3; break; } |
| 656 | else found = 0; |
| 657 | |
| 658 | if (found == 3 && retv) |
| 659 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 660 | TRACE("PERF130 hack: " |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 661 | "Replacing byte %02X at offset %04X:%04X\n", |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 662 | *(retv+1), SELECTOROF(func1), |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 663 | OFFSETOF(func1) + retv+1-start); |
| 664 | |
| 665 | *(retv+1) = (BYTE)0xCB; |
| 666 | } |
| 667 | } |
| 668 | } |
| 669 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 670 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 671 | * Mark process as Win32s, so that subsequent DPMI calls |
Andreas Mohr | a00b49f | 1998-12-07 10:48:09 +0000 | [diff] [blame] | 672 | * will perform the W32S_APP2WINE/W32S_WINE2APP address shift. |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 673 | */ |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 674 | W32S_offset = 0x10000; |
| 675 | break; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 676 | |
| 677 | |
| 678 | case 0x0001: /* Install Exception Handling */ |
| 679 | /* |
| 680 | * Input: EBX: Flat address of W32SKRNL Exception Data |
| 681 | * |
| 682 | * ECX: LoWord: Flat Code Selector |
| 683 | * HiWord: Flat Data Selector |
| 684 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 685 | * EDX: Flat address of W32SKRNL Exception Handler |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 686 | * (this is equal to W32S_BackTo32 + 0x40) |
| 687 | * |
| 688 | * ESI: SEGPTR KERNEL.HASGPHANDLER |
| 689 | * |
| 690 | * EDI: SEGPTR phCurrentTask (KERNEL.THHOOK + 0x10) |
| 691 | * |
| 692 | * Output: EAX: 0 if OK |
| 693 | */ |
| 694 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 695 | TRACE("[0001] EBX=%lx ECX=%lx EDX=%lx ESI=%lx EDI=%lx\n", |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 696 | context->Ebx, context->Ecx, context->Edx, |
| 697 | context->Esi, context->Edi); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 698 | |
| 699 | /* FIXME */ |
| 700 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 701 | context->Eax = 0; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 702 | break; |
| 703 | |
| 704 | |
| 705 | case 0x0002: /* Set Page Access Flags */ |
| 706 | /* |
| 707 | * Input: EBX: New access flags |
| 708 | * Bit 2: User Page if set, Supervisor Page if clear |
| 709 | * Bit 1: Read-Write if set, Read-Only if clear |
| 710 | * |
| 711 | * ECX: Size of memory area to change |
| 712 | * |
| 713 | * EDX: Flat start address of memory area |
| 714 | * |
| 715 | * Output: EAX: Size of area changed |
| 716 | */ |
| 717 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 718 | TRACE("[0002] EBX=%lx ECX=%lx EDX=%lx\n", |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 719 | context->Ebx, context->Ecx, context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 720 | |
| 721 | /* FIXME */ |
| 722 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 723 | context->Eax = context->Ecx; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 724 | break; |
| 725 | |
| 726 | |
| 727 | case 0x0003: /* Get Page Access Flags */ |
| 728 | /* |
| 729 | * Input: EDX: Flat address of page to query |
| 730 | * |
| 731 | * Output: EAX: Page access flags |
| 732 | * Bit 2: User Page if set, Supervisor Page if clear |
| 733 | * Bit 1: Read-Write if set, Read-Only if clear |
| 734 | */ |
| 735 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 736 | TRACE("[0003] EDX=%lx\n", context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 737 | |
| 738 | /* FIXME */ |
| 739 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 740 | context->Eax = 6; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 741 | break; |
| 742 | |
| 743 | |
| 744 | case 0x0004: /* Map Module */ |
| 745 | /* |
| 746 | * Input: ECX: IMTE (offset in Module Table) of new module |
| 747 | * |
| 748 | * EDX: Flat address of Win32s Module Table |
| 749 | * |
| 750 | * Output: EAX: 0 if OK |
| 751 | */ |
| 752 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 753 | if (!context->Edx || CX_reg(context) == 0xFFFF) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 754 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 755 | TRACE("MapModule: Initialization call\n"); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 756 | context->Eax = 0; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 757 | } |
| 758 | else |
| 759 | { |
| 760 | /* |
| 761 | * Structure of a Win32s Module Table Entry: |
| 762 | */ |
| 763 | struct Win32sModule |
| 764 | { |
| 765 | DWORD flags; |
| 766 | DWORD flatBaseAddr; |
| 767 | LPCSTR moduleName; |
| 768 | LPCSTR pathName; |
| 769 | LPCSTR unknown; |
| 770 | LPBYTE baseAddr; |
| 771 | DWORD hModule; |
| 772 | DWORD relocDelta; |
| 773 | }; |
| 774 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 775 | /* |
| 776 | * Note: This function should set up a demand-paged memory image |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 777 | * of the given module. Since mmap does not allow file offsets |
| 778 | * not aligned at 1024 bytes, we simply load the image fully |
| 779 | * into memory. |
| 780 | */ |
| 781 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 782 | struct Win32sModule *moduleTable = |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 783 | (struct Win32sModule *)W32S_APP2WINE(context->Edx); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 784 | struct Win32sModule *module = moduleTable + context->Ecx; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 785 | |
Alexandre Julliard | a5dea21 | 2002-08-09 19:57:38 +0000 | [diff] [blame] | 786 | IMAGE_NT_HEADERS *nt_header = RtlImageNtHeader( (HMODULE)module->baseAddr ); |
| 787 | IMAGE_SECTION_HEADER *pe_seg = (IMAGE_SECTION_HEADER*)((char *)&nt_header->OptionalHeader + |
| 788 | nt_header->FileHeader.SizeOfOptionalHeader); |
| 789 | |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 790 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 791 | HFILE image = _lopen(module->pathName, OF_READ); |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 792 | BOOL error = (image == HFILE_ERROR); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 793 | UINT i; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 794 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 795 | TRACE("MapModule: Loading %s\n", module->pathName); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 796 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 797 | for (i = 0; |
| 798 | !error && i < nt_header->FileHeader.NumberOfSections; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 799 | i++, pe_seg++) |
| 800 | if(!(pe_seg->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)) |
| 801 | { |
| 802 | DWORD off = pe_seg->PointerToRawData; |
| 803 | DWORD len = pe_seg->SizeOfRawData; |
| 804 | LPBYTE addr = module->baseAddr + pe_seg->VirtualAddress; |
| 805 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 806 | TRACE("MapModule: " |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 807 | "Section %d at %08lx from %08lx len %08lx\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 808 | i, (DWORD)addr, off, len); |
| 809 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 810 | if ( _llseek(image, off, SEEK_SET) != off |
| 811 | || _lread(image, addr, len) != len) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 812 | error = TRUE; |
| 813 | } |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 814 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 815 | _lclose(image); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 816 | |
| 817 | if (error) |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 818 | ERR("MapModule: Unable to load %s\n", module->pathName); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 819 | |
| 820 | else if (module->relocDelta != 0) |
| 821 | { |
| 822 | IMAGE_DATA_DIRECTORY *dir = nt_header->OptionalHeader.DataDirectory |
| 823 | + IMAGE_DIRECTORY_ENTRY_BASERELOC; |
| 824 | IMAGE_BASE_RELOCATION *r = (IMAGE_BASE_RELOCATION *) |
| 825 | (dir->Size? module->baseAddr + dir->VirtualAddress : 0); |
| 826 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 827 | TRACE("MapModule: Reloc delta %08lx\n", module->relocDelta); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 828 | |
| 829 | while (r && r->VirtualAddress) |
| 830 | { |
| 831 | LPBYTE page = module->baseAddr + r->VirtualAddress; |
Dmitry Timoshkov | 6b6596a | 2001-11-23 18:44:43 +0000 | [diff] [blame] | 832 | WORD *TypeOffset = (WORD *)(r + 1); |
| 833 | int count = (r->SizeOfBlock - sizeof(*r)) / sizeof(*TypeOffset); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 834 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 835 | TRACE("MapModule: %d relocations for page %08lx\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 836 | count, (DWORD)page); |
| 837 | |
| 838 | for(i = 0; i < count; i++) |
| 839 | { |
Dmitry Timoshkov | 6b6596a | 2001-11-23 18:44:43 +0000 | [diff] [blame] | 840 | int offset = TypeOffset[i] & 0xFFF; |
| 841 | int type = TypeOffset[i] >> 12; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 842 | switch(type) |
| 843 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 844 | case IMAGE_REL_BASED_ABSOLUTE: |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 845 | break; |
| 846 | case IMAGE_REL_BASED_HIGH: |
| 847 | *(WORD *)(page+offset) += HIWORD(module->relocDelta); |
| 848 | break; |
| 849 | case IMAGE_REL_BASED_LOW: |
| 850 | *(WORD *)(page+offset) += LOWORD(module->relocDelta); |
| 851 | break; |
| 852 | case IMAGE_REL_BASED_HIGHLOW: |
| 853 | *(DWORD*)(page+offset) += module->relocDelta; |
| 854 | break; |
| 855 | default: |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 856 | WARN("MapModule: Unsupported fixup type\n"); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 857 | break; |
| 858 | } |
| 859 | } |
| 860 | |
| 861 | r = (IMAGE_BASE_RELOCATION *)((LPBYTE)r + r->SizeOfBlock); |
| 862 | } |
| 863 | } |
| 864 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 865 | context->Eax = 0; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 866 | RESET_CFLAG(context); |
| 867 | } |
| 868 | break; |
| 869 | |
| 870 | |
| 871 | case 0x0005: /* UnMap Module */ |
| 872 | /* |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 873 | * Input: EDX: Flat address of module image |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 874 | * |
| 875 | * Output: EAX: 1 if OK |
| 876 | */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 877 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 878 | TRACE("UnMapModule: %lx\n", (DWORD)W32S_APP2WINE(context->Edx)); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 879 | |
| 880 | /* As we didn't map anything, there's nothing to unmap ... */ |
| 881 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 882 | context->Eax = 1; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 883 | break; |
| 884 | |
| 885 | |
| 886 | case 0x0006: /* VirtualAlloc */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 887 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 888 | * Input: ECX: Current Process |
| 889 | * |
| 890 | * EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 891 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 892 | * DWORD *retv [out] Flat base address of allocated region |
| 893 | * LPVOID base [in] Flat address of region to reserve/commit |
| 894 | * DWORD size [in] Size of region |
| 895 | * DWORD type [in] Type of allocation |
| 896 | * DWORD prot [in] Type of access protection |
| 897 | * |
| 898 | * Output: EAX: NtStatus |
| 899 | */ |
| 900 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 901 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
| 902 | DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); |
| 903 | LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 904 | DWORD size = stack[2]; |
| 905 | DWORD type = stack[3]; |
| 906 | DWORD prot = stack[4]; |
| 907 | DWORD result; |
| 908 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 909 | TRACE("VirtualAlloc(%lx, %lx, %lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 910 | (DWORD)retv, (DWORD)base, size, type, prot); |
| 911 | |
| 912 | if (type & 0x80000000) |
| 913 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 914 | WARN("VirtualAlloc: strange type %lx\n", type); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 915 | type &= 0x7fffffff; |
| 916 | } |
| 917 | |
| 918 | if (!base && (type & MEM_COMMIT) && prot == PAGE_READONLY) |
| 919 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 920 | WARN("VirtualAlloc: NLS hack, allowing write access!\n"); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 921 | prot = PAGE_READWRITE; |
| 922 | } |
| 923 | |
| 924 | result = (DWORD)VirtualAlloc(base, size, type, prot); |
| 925 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 926 | if (W32S_WINE2APP(result)) |
| 927 | *retv = W32S_WINE2APP(result), |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 928 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 929 | else |
| 930 | *retv = 0, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 931 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 932 | } |
| 933 | break; |
| 934 | |
| 935 | |
| 936 | case 0x0007: /* VirtualFree */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 937 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 938 | * Input: ECX: Current Process |
| 939 | * |
| 940 | * EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 941 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 942 | * DWORD *retv [out] TRUE if success, FALSE if failure |
| 943 | * LPVOID base [in] Flat address of region |
| 944 | * DWORD size [in] Size of region |
| 945 | * DWORD type [in] Type of operation |
| 946 | * |
| 947 | * Output: EAX: NtStatus |
| 948 | */ |
| 949 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 950 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
| 951 | DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); |
| 952 | LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 953 | DWORD size = stack[2]; |
| 954 | DWORD type = stack[3]; |
| 955 | DWORD result; |
| 956 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 957 | TRACE("VirtualFree(%lx, %lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 958 | (DWORD)retv, (DWORD)base, size, type); |
| 959 | |
| 960 | result = VirtualFree(base, size, type); |
| 961 | |
| 962 | if (result) |
| 963 | *retv = TRUE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 964 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 965 | else |
| 966 | *retv = FALSE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 967 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 968 | } |
| 969 | break; |
| 970 | |
| 971 | |
| 972 | case 0x0008: /* VirtualProtect */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 973 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 974 | * Input: ECX: Current Process |
| 975 | * |
| 976 | * EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 977 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 978 | * DWORD *retv [out] TRUE if success, FALSE if failure |
| 979 | * LPVOID base [in] Flat address of region |
| 980 | * DWORD size [in] Size of region |
| 981 | * DWORD new_prot [in] Desired access protection |
| 982 | * DWORD *old_prot [out] Previous access protection |
| 983 | * |
| 984 | * Output: EAX: NtStatus |
| 985 | */ |
| 986 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 987 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
| 988 | DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); |
| 989 | LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 990 | DWORD size = stack[2]; |
| 991 | DWORD new_prot = stack[3]; |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 992 | DWORD *old_prot = (DWORD *)W32S_APP2WINE(stack[4]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 993 | DWORD result; |
| 994 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 995 | TRACE("VirtualProtect(%lx, %lx, %lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 996 | (DWORD)retv, (DWORD)base, size, new_prot, (DWORD)old_prot); |
| 997 | |
| 998 | result = VirtualProtect(base, size, new_prot, old_prot); |
| 999 | |
| 1000 | if (result) |
| 1001 | *retv = TRUE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1002 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1003 | else |
| 1004 | *retv = FALSE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1005 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1006 | } |
| 1007 | break; |
| 1008 | |
| 1009 | |
| 1010 | case 0x0009: /* VirtualQuery */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1011 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1012 | * Input: ECX: Current Process |
| 1013 | * |
| 1014 | * EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1015 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1016 | * DWORD *retv [out] Nr. bytes returned |
| 1017 | * LPVOID base [in] Flat address of region |
| 1018 | * LPMEMORY_BASIC_INFORMATION info [out] Info buffer |
| 1019 | * DWORD len [in] Size of buffer |
| 1020 | * |
| 1021 | * Output: EAX: NtStatus |
| 1022 | */ |
| 1023 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1024 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
| 1025 | DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); |
| 1026 | LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); |
Patrik Stridvall | ba9dc78 | 2002-11-04 22:43:24 +0000 | [diff] [blame] | 1027 | PMEMORY_BASIC_INFORMATION info = |
| 1028 | (PMEMORY_BASIC_INFORMATION)W32S_APP2WINE(stack[2]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1029 | DWORD len = stack[3]; |
| 1030 | DWORD result; |
| 1031 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1032 | TRACE("VirtualQuery(%lx, %lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1033 | (DWORD)retv, (DWORD)base, (DWORD)info, len); |
| 1034 | |
| 1035 | result = VirtualQuery(base, info, len); |
| 1036 | |
| 1037 | *retv = result; |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1038 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1039 | } |
| 1040 | break; |
| 1041 | |
| 1042 | |
| 1043 | case 0x000A: /* SetVirtMemProcess */ |
| 1044 | /* |
| 1045 | * Input: ECX: Process Handle |
| 1046 | * |
| 1047 | * EDX: Flat address of region |
| 1048 | * |
| 1049 | * Output: EAX: NtStatus |
| 1050 | */ |
| 1051 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1052 | TRACE("[000a] ECX=%lx EDX=%lx\n", |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1053 | context->Ecx, context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1054 | |
| 1055 | /* FIXME */ |
| 1056 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1057 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1058 | break; |
| 1059 | |
| 1060 | |
| 1061 | case 0x000B: /* ??? some kind of cleanup */ |
| 1062 | /* |
| 1063 | * Input: ECX: Process Handle |
| 1064 | * |
| 1065 | * Output: EAX: NtStatus |
| 1066 | */ |
| 1067 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1068 | TRACE("[000b] ECX=%lx\n", context->Ecx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1069 | |
| 1070 | /* FIXME */ |
| 1071 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1072 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1073 | break; |
| 1074 | |
| 1075 | |
| 1076 | case 0x000C: /* Set Debug Flags */ |
| 1077 | /* |
| 1078 | * Input: EDX: Debug Flags |
| 1079 | * |
| 1080 | * Output: EDX: Previous Debug Flags |
| 1081 | */ |
| 1082 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1083 | FIXME("[000c] EDX=%lx\n", context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1084 | |
| 1085 | /* FIXME */ |
| 1086 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1087 | context->Edx = 0; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1088 | break; |
| 1089 | |
| 1090 | |
| 1091 | case 0x000D: /* NtCreateSection */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1092 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1093 | * Input: EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1094 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1095 | * HANDLE32 *retv [out] Handle of Section created |
| 1096 | * DWORD flags1 [in] (?? unknown ??) |
| 1097 | * DWORD atom [in] Name of Section to create |
| 1098 | * LARGE_INTEGER *size [in] Size of Section |
| 1099 | * DWORD protect [in] Access protection |
| 1100 | * DWORD flags2 [in] (?? unknown ??) |
| 1101 | * HFILE32 hFile [in] Handle of file to map |
| 1102 | * DWORD psp [in] (Win32s: PSP that hFile belongs to) |
| 1103 | * |
| 1104 | * Output: EAX: NtStatus |
| 1105 | */ |
| 1106 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1107 | DWORD *stack = (DWORD *) W32S_APP2WINE(context->Edx); |
| 1108 | HANDLE *retv = (HANDLE *)W32S_APP2WINE(stack[0]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1109 | DWORD flags1 = stack[1]; |
| 1110 | DWORD atom = stack[2]; |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1111 | LARGE_INTEGER *size = (LARGE_INTEGER *)W32S_APP2WINE(stack[3]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1112 | DWORD protect = stack[4]; |
| 1113 | DWORD flags2 = stack[5]; |
Alexandre Julliard | 5ce902b | 2000-11-27 21:59:08 +0000 | [diff] [blame] | 1114 | HANDLE hFile = DosFileHandleToWin32Handle(stack[6]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1115 | DWORD psp = stack[7]; |
| 1116 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1117 | HANDLE result = INVALID_HANDLE_VALUE; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1118 | char name[128]; |
| 1119 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1120 | TRACE("NtCreateSection(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1121 | (DWORD)retv, flags1, atom, (DWORD)size, protect, flags2, |
| 1122 | (DWORD)hFile, psp); |
| 1123 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1124 | if (!atom || GlobalGetAtomNameA(atom, name, sizeof(name))) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1125 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1126 | TRACE("NtCreateSection: name=%s\n", atom? name : NULL); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1127 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1128 | result = CreateFileMappingA(hFile, NULL, protect, |
Ge van Geldorp | 399901e | 2004-01-23 01:51:33 +0000 | [diff] [blame] | 1129 | size? size->u.HighPart : 0, |
| 1130 | size? size->u.LowPart : 0, |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1131 | atom? name : NULL); |
| 1132 | } |
| 1133 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1134 | if (result == INVALID_HANDLE_VALUE) |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1135 | WARN("NtCreateSection: failed!\n"); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1136 | else |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1137 | TRACE("NtCreateSection: returned %lx\n", (DWORD)result); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1138 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1139 | if (result != INVALID_HANDLE_VALUE) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1140 | *retv = result, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1141 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1142 | else |
| 1143 | *retv = result, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1144 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1145 | } |
| 1146 | break; |
| 1147 | |
| 1148 | |
| 1149 | case 0x000E: /* NtOpenSection */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1150 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1151 | * Input: EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1152 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1153 | * HANDLE32 *retv [out] Handle of Section opened |
| 1154 | * DWORD protect [in] Access protection |
| 1155 | * DWORD atom [in] Name of Section to create |
| 1156 | * |
| 1157 | * Output: EAX: NtStatus |
| 1158 | */ |
| 1159 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1160 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
| 1161 | HANDLE *retv = (HANDLE *)W32S_APP2WINE(stack[0]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1162 | DWORD protect = stack[1]; |
| 1163 | DWORD atom = stack[2]; |
| 1164 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1165 | HANDLE result = INVALID_HANDLE_VALUE; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1166 | char name[128]; |
| 1167 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1168 | TRACE("NtOpenSection(%lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1169 | (DWORD)retv, protect, atom); |
| 1170 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1171 | if (atom && GlobalGetAtomNameA(atom, name, sizeof(name))) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1172 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1173 | TRACE("NtOpenSection: name=%s\n", name); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1174 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1175 | result = OpenFileMappingA(protect, FALSE, name); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1176 | } |
| 1177 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1178 | if (result == INVALID_HANDLE_VALUE) |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1179 | WARN("NtOpenSection: failed!\n"); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1180 | else |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1181 | TRACE("NtOpenSection: returned %lx\n", (DWORD)result); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1182 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1183 | if (result != INVALID_HANDLE_VALUE) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1184 | *retv = result, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1185 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1186 | else |
| 1187 | *retv = result, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1188 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1189 | } |
| 1190 | break; |
| 1191 | |
| 1192 | |
| 1193 | case 0x000F: /* NtCloseSection */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1194 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1195 | * Input: EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1196 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1197 | * HANDLE32 handle [in] Handle of Section to close |
| 1198 | * DWORD *id [out] Unique ID (?? unclear ??) |
| 1199 | * |
| 1200 | * Output: EAX: NtStatus |
| 1201 | */ |
| 1202 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1203 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
Alexandre Julliard | 7375597 | 2002-07-31 19:26:03 +0000 | [diff] [blame] | 1204 | HANDLE handle = (HANDLE)stack[0]; |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1205 | DWORD *id = (DWORD *)W32S_APP2WINE(stack[1]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1206 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1207 | TRACE("NtCloseSection(%lx, %lx)\n", (DWORD)handle, (DWORD)id); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1208 | |
| 1209 | CloseHandle(handle); |
| 1210 | if (id) *id = 0; /* FIXME */ |
| 1211 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1212 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1213 | } |
| 1214 | break; |
| 1215 | |
| 1216 | |
| 1217 | case 0x0010: /* NtDupSection */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1218 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1219 | * Input: EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1220 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1221 | * HANDLE32 handle [in] Handle of Section to duplicate |
| 1222 | * |
| 1223 | * Output: EAX: NtStatus |
| 1224 | */ |
| 1225 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1226 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
Alexandre Julliard | 7375597 | 2002-07-31 19:26:03 +0000 | [diff] [blame] | 1227 | HANDLE handle = (HANDLE)stack[0]; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1228 | HANDLE new_handle; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1229 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1230 | TRACE("NtDupSection(%lx)\n", (DWORD)handle); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1231 | |
Alexandre Julliard | 62a8b43 | 1999-01-19 17:48:23 +0000 | [diff] [blame] | 1232 | DuplicateHandle( GetCurrentProcess(), handle, |
| 1233 | GetCurrentProcess(), &new_handle, |
| 1234 | 0, FALSE, DUPLICATE_SAME_ACCESS ); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1235 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1236 | } |
| 1237 | break; |
| 1238 | |
| 1239 | |
| 1240 | case 0x0011: /* NtMapViewOfSection */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1241 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1242 | * Input: EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1243 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1244 | * HANDLE32 SectionHandle [in] Section to be mapped |
| 1245 | * DWORD ProcessHandle [in] Process to be mapped into |
| 1246 | * DWORD * BaseAddress [in/out] Address to be mapped at |
| 1247 | * DWORD ZeroBits [in] (?? unclear ??) |
| 1248 | * DWORD CommitSize [in] (?? unclear ??) |
| 1249 | * LARGE_INTEGER *SectionOffset [in] Offset within section |
| 1250 | * DWORD * ViewSize [in] Size of view |
| 1251 | * DWORD InheritDisposition [in] (?? unclear ??) |
| 1252 | * DWORD AllocationType [in] (?? unclear ??) |
| 1253 | * DWORD Protect [in] Access protection |
| 1254 | * |
| 1255 | * Output: EAX: NtStatus |
| 1256 | */ |
| 1257 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1258 | DWORD * stack = (DWORD *)W32S_APP2WINE(context->Edx); |
Alexandre Julliard | 7375597 | 2002-07-31 19:26:03 +0000 | [diff] [blame] | 1259 | HANDLE SectionHandle = (HANDLE)stack[0]; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1260 | DWORD ProcessHandle = stack[1]; /* ignored */ |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1261 | DWORD * BaseAddress = (DWORD *)W32S_APP2WINE(stack[2]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1262 | DWORD ZeroBits = stack[3]; |
| 1263 | DWORD CommitSize = stack[4]; |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1264 | LARGE_INTEGER *SectionOffset = (LARGE_INTEGER *)W32S_APP2WINE(stack[5]); |
| 1265 | DWORD * ViewSize = (DWORD *)W32S_APP2WINE(stack[6]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1266 | DWORD InheritDisposition = stack[7]; |
| 1267 | DWORD AllocationType = stack[8]; |
| 1268 | DWORD Protect = stack[9]; |
| 1269 | |
Andreas Mohr | a00b49f | 1998-12-07 10:48:09 +0000 | [diff] [blame] | 1270 | LPBYTE address = (LPBYTE)(BaseAddress? |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1271 | W32S_APP2WINE(*BaseAddress) : 0); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1272 | DWORD access = 0, result; |
| 1273 | |
| 1274 | switch (Protect & ~(PAGE_GUARD|PAGE_NOCACHE)) |
| 1275 | { |
| 1276 | case PAGE_READONLY: access = FILE_MAP_READ; break; |
| 1277 | case PAGE_READWRITE: access = FILE_MAP_WRITE; break; |
| 1278 | case PAGE_WRITECOPY: access = FILE_MAP_COPY; break; |
| 1279 | |
| 1280 | case PAGE_EXECUTE_READ: access = FILE_MAP_READ; break; |
| 1281 | case PAGE_EXECUTE_READWRITE: access = FILE_MAP_WRITE; break; |
| 1282 | case PAGE_EXECUTE_WRITECOPY: access = FILE_MAP_COPY; break; |
| 1283 | } |
| 1284 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1285 | TRACE("NtMapViewOfSection" |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1286 | "(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx)\n", |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1287 | (DWORD)SectionHandle, ProcessHandle, (DWORD)BaseAddress, |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1288 | ZeroBits, CommitSize, (DWORD)SectionOffset, (DWORD)ViewSize, |
| 1289 | InheritDisposition, AllocationType, Protect); |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1290 | TRACE("NtMapViewOfSection: " |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1291 | "base=%lx, offset=%lx, size=%lx, access=%lx\n", |
Ge van Geldorp | 399901e | 2004-01-23 01:51:33 +0000 | [diff] [blame] | 1292 | (DWORD)address, SectionOffset? SectionOffset->u.LowPart : 0, |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1293 | ViewSize? *ViewSize : 0, access); |
| 1294 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1295 | result = (DWORD)MapViewOfFileEx(SectionHandle, access, |
Ge van Geldorp | 399901e | 2004-01-23 01:51:33 +0000 | [diff] [blame] | 1296 | SectionOffset? SectionOffset->u.HighPart : 0, |
| 1297 | SectionOffset? SectionOffset->u.LowPart : 0, |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1298 | ViewSize? *ViewSize : 0, address); |
| 1299 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1300 | TRACE("NtMapViewOfSection: result=%lx\n", result); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1301 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1302 | if (W32S_WINE2APP(result)) |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1303 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1304 | if (BaseAddress) *BaseAddress = W32S_WINE2APP(result); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1305 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1306 | } |
| 1307 | else |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1308 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1309 | } |
| 1310 | break; |
| 1311 | |
| 1312 | |
| 1313 | case 0x0012: /* NtUnmapViewOfSection */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1314 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1315 | * Input: EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1316 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1317 | * DWORD ProcessHandle [in] Process (defining address space) |
| 1318 | * LPBYTE BaseAddress [in] Base address of view to be unmapped |
| 1319 | * |
| 1320 | * Output: EAX: NtStatus |
| 1321 | */ |
| 1322 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1323 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1324 | DWORD ProcessHandle = stack[0]; /* ignored */ |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1325 | LPBYTE BaseAddress = (LPBYTE)W32S_APP2WINE(stack[1]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1326 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1327 | TRACE("NtUnmapViewOfSection(%lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1328 | ProcessHandle, (DWORD)BaseAddress); |
| 1329 | |
| 1330 | UnmapViewOfFile(BaseAddress); |
| 1331 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1332 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1333 | } |
| 1334 | break; |
| 1335 | |
| 1336 | |
| 1337 | case 0x0013: /* NtFlushVirtualMemory */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1338 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1339 | * Input: EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1340 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1341 | * DWORD ProcessHandle [in] Process (defining address space) |
| 1342 | * LPBYTE *BaseAddress [in?] Base address of range to be flushed |
| 1343 | * DWORD *ViewSize [in?] Number of bytes to be flushed |
| 1344 | * DWORD *unknown [???] (?? unknown ??) |
| 1345 | * |
| 1346 | * Output: EAX: NtStatus |
| 1347 | */ |
| 1348 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1349 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1350 | DWORD ProcessHandle = stack[0]; /* ignored */ |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1351 | DWORD *BaseAddress = (DWORD *)W32S_APP2WINE(stack[1]); |
| 1352 | DWORD *ViewSize = (DWORD *)W32S_APP2WINE(stack[2]); |
| 1353 | DWORD *unknown = (DWORD *)W32S_APP2WINE(stack[3]); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1354 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1355 | LPBYTE address = (LPBYTE)(BaseAddress? W32S_APP2WINE(*BaseAddress) : 0); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1356 | DWORD size = ViewSize? *ViewSize : 0; |
| 1357 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1358 | TRACE("NtFlushVirtualMemory(%lx, %lx, %lx, %lx)\n", |
| 1359 | ProcessHandle, (DWORD)BaseAddress, (DWORD)ViewSize, |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1360 | (DWORD)unknown); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1361 | TRACE("NtFlushVirtualMemory: base=%lx, size=%lx\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1362 | (DWORD)address, size); |
| 1363 | |
| 1364 | FlushViewOfFile(address, size); |
| 1365 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1366 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1367 | } |
| 1368 | break; |
| 1369 | |
| 1370 | |
| 1371 | case 0x0014: /* Get/Set Debug Registers */ |
| 1372 | /* |
| 1373 | * Input: ECX: 0 if Get, 1 if Set |
| 1374 | * |
| 1375 | * EDX: Get: Flat address of buffer to receive values of |
| 1376 | * debug registers DR0 .. DR7 |
| 1377 | * Set: Flat address of buffer containing values of |
| 1378 | * debug registers DR0 .. DR7 to be set |
| 1379 | * Output: None |
| 1380 | */ |
| 1381 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1382 | FIXME("[0014] ECX=%lx EDX=%lx\n", |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1383 | context->Ecx, context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1384 | |
| 1385 | /* FIXME */ |
| 1386 | break; |
| 1387 | |
| 1388 | |
| 1389 | case 0x0015: /* Set Coprocessor Emulation Flag */ |
| 1390 | /* |
| 1391 | * Input: EDX: 0 to deactivate, 1 to activate coprocessor emulation |
| 1392 | * |
| 1393 | * Output: None |
| 1394 | */ |
| 1395 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1396 | TRACE("[0015] EDX=%lx\n", context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1397 | |
| 1398 | /* We don't care, as we always have a coprocessor anyway */ |
| 1399 | break; |
| 1400 | |
| 1401 | |
| 1402 | case 0x0016: /* Init Win32S VxD PSP */ |
| 1403 | /* |
| 1404 | * If called to query required PSP size: |
| 1405 | * |
| 1406 | * Input: EBX: 0 |
| 1407 | * Output: EDX: Required size of Win32s VxD PSP |
| 1408 | * |
| 1409 | * If called to initialize allocated PSP: |
| 1410 | * |
| 1411 | * Input: EBX: LoWord: Selector of Win32s VxD PSP |
| 1412 | * HiWord: Paragraph of Win32s VxD PSP (DOSMEM) |
| 1413 | * Output: None |
| 1414 | */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1415 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1416 | if (context->Ebx == 0) |
| 1417 | context->Edx = 0x80; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1418 | else |
| 1419 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 1420 | PDB16 *psp = MapSL( MAKESEGPTR( BX_reg(context), 0 )); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1421 | psp->nbFiles = 32; |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1422 | psp->fileHandlesPtr = MAKELONG(HIWORD(context->Ebx), 0x5c); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1423 | memset((LPBYTE)psp + 0x5c, '\xFF', 32); |
| 1424 | } |
| 1425 | break; |
| 1426 | |
| 1427 | |
| 1428 | case 0x0017: /* Set Break Point */ |
| 1429 | /* |
| 1430 | * Input: EBX: Offset of Break Point |
| 1431 | * CX: Selector of Break Point |
| 1432 | * |
| 1433 | * Output: None |
| 1434 | */ |
| 1435 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1436 | FIXME("[0017] EBX=%lx CX=%x\n", |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1437 | context->Ebx, CX_reg(context)); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1438 | |
| 1439 | /* FIXME */ |
| 1440 | break; |
| 1441 | |
| 1442 | |
| 1443 | case 0x0018: /* VirtualLock */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1444 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1445 | * Input: ECX: Current Process |
| 1446 | * |
| 1447 | * EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1448 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1449 | * DWORD *retv [out] TRUE if success, FALSE if failure |
| 1450 | * LPVOID base [in] Flat address of range to lock |
| 1451 | * DWORD size [in] Size of range |
| 1452 | * |
| 1453 | * Output: EAX: NtStatus |
| 1454 | */ |
| 1455 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1456 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
| 1457 | DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); |
| 1458 | LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1459 | DWORD size = stack[2]; |
| 1460 | DWORD result; |
| 1461 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1462 | TRACE("VirtualLock(%lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1463 | (DWORD)retv, (DWORD)base, size); |
| 1464 | |
| 1465 | result = VirtualLock(base, size); |
| 1466 | |
| 1467 | if (result) |
| 1468 | *retv = TRUE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1469 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1470 | else |
| 1471 | *retv = FALSE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1472 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1473 | } |
| 1474 | break; |
| 1475 | |
| 1476 | |
| 1477 | case 0x0019: /* VirtualUnlock */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1478 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1479 | * Input: ECX: Current Process |
| 1480 | * |
| 1481 | * EDX: Flat address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1482 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1483 | * DWORD *retv [out] TRUE if success, FALSE if failure |
| 1484 | * LPVOID base [in] Flat address of range to unlock |
| 1485 | * DWORD size [in] Size of range |
| 1486 | * |
| 1487 | * Output: EAX: NtStatus |
| 1488 | */ |
| 1489 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1490 | DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); |
| 1491 | DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); |
| 1492 | LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1493 | DWORD size = stack[2]; |
| 1494 | DWORD result; |
| 1495 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1496 | TRACE("VirtualUnlock(%lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1497 | (DWORD)retv, (DWORD)base, size); |
| 1498 | |
| 1499 | result = VirtualUnlock(base, size); |
| 1500 | |
| 1501 | if (result) |
| 1502 | *retv = TRUE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1503 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1504 | else |
| 1505 | *retv = FALSE, |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1506 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1507 | } |
| 1508 | break; |
| 1509 | |
| 1510 | |
| 1511 | case 0x001A: /* KGetSystemInfo */ |
| 1512 | /* |
| 1513 | * Input: None |
| 1514 | * |
| 1515 | * Output: ECX: Start of sparse memory arena |
| 1516 | * EDX: End of sparse memory arena |
| 1517 | */ |
| 1518 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1519 | TRACE("KGetSystemInfo()\n"); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1520 | |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1521 | /* |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1522 | * Note: Win32s reserves 0GB - 2GB for Win 3.1 and uses 2GB - 4GB as |
| 1523 | * sparse memory arena. We do it the other way around, since |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1524 | * we have to reserve 3GB - 4GB for Linux, and thus use |
| 1525 | * 0GB - 3GB as sparse memory arena. |
| 1526 | * |
| 1527 | * FIXME: What about other OSes ? |
| 1528 | */ |
| 1529 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1530 | context->Ecx = W32S_WINE2APP(0x00000000); |
| 1531 | context->Edx = W32S_WINE2APP(0xbfffffff); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1532 | break; |
| 1533 | |
| 1534 | |
| 1535 | case 0x001B: /* KGlobalMemStat */ |
| 1536 | /* |
| 1537 | * Input: ESI: Flat address of buffer to receive memory info |
| 1538 | * |
| 1539 | * Output: None |
| 1540 | */ |
| 1541 | { |
| 1542 | struct Win32sMemoryInfo |
| 1543 | { |
| 1544 | DWORD DIPhys_Count; /* Total physical pages */ |
| 1545 | DWORD DIFree_Count; /* Free physical pages */ |
| 1546 | DWORD DILin_Total_Count; /* Total virtual pages (private arena) */ |
| 1547 | DWORD DILin_Total_Free; /* Free virtual pages (private arena) */ |
| 1548 | |
| 1549 | DWORD SparseTotal; /* Total size of sparse arena (bytes ?) */ |
| 1550 | DWORD SparseFree; /* Free size of sparse arena (bytes ?) */ |
| 1551 | }; |
| 1552 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1553 | struct Win32sMemoryInfo *info = |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1554 | (struct Win32sMemoryInfo *)W32S_APP2WINE(context->Esi); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1555 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1556 | FIXME("KGlobalMemStat(%lx)\n", (DWORD)info); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1557 | |
| 1558 | /* FIXME */ |
| 1559 | } |
| 1560 | break; |
| 1561 | |
| 1562 | |
| 1563 | case 0x001C: /* Enable/Disable Exceptions */ |
| 1564 | /* |
| 1565 | * Input: ECX: 0 to disable, 1 to enable exception handling |
| 1566 | * |
| 1567 | * Output: None |
| 1568 | */ |
| 1569 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1570 | TRACE("[001c] ECX=%lx\n", context->Ecx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1571 | |
| 1572 | /* FIXME */ |
| 1573 | break; |
| 1574 | |
| 1575 | |
| 1576 | case 0x001D: /* VirtualAlloc called from 16-bit code */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1577 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1578 | * Input: EDX: Segmented address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1579 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1580 | * LPVOID base [in] Flat address of region to reserve/commit |
| 1581 | * DWORD size [in] Size of region |
| 1582 | * DWORD type [in] Type of allocation |
| 1583 | * DWORD prot [in] Type of access protection |
| 1584 | * |
| 1585 | * Output: EAX: NtStatus |
| 1586 | * EDX: Flat base address of allocated region |
| 1587 | */ |
| 1588 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 1589 | DWORD *stack = MapSL( MAKESEGPTR( LOWORD(context->Edx), HIWORD(context->Edx) )); |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1590 | LPVOID base = (LPVOID)W32S_APP2WINE(stack[0]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1591 | DWORD size = stack[1]; |
| 1592 | DWORD type = stack[2]; |
| 1593 | DWORD prot = stack[3]; |
| 1594 | DWORD result; |
| 1595 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1596 | TRACE("VirtualAlloc16(%lx, %lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1597 | (DWORD)base, size, type, prot); |
| 1598 | |
| 1599 | if (type & 0x80000000) |
| 1600 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1601 | WARN("VirtualAlloc16: strange type %lx\n", type); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1602 | type &= 0x7fffffff; |
| 1603 | } |
| 1604 | |
| 1605 | result = (DWORD)VirtualAlloc(base, size, type, prot); |
| 1606 | |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1607 | if (W32S_WINE2APP(result)) |
| 1608 | context->Edx = W32S_WINE2APP(result), |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1609 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1610 | else |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1611 | context->Edx = 0, |
| 1612 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
| 1613 | TRACE("VirtualAlloc16: returning base %lx\n", context->Edx); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1614 | } |
| 1615 | break; |
| 1616 | |
| 1617 | |
| 1618 | case 0x001E: /* VirtualFree called from 16-bit code */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1619 | /* |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1620 | * Input: EDX: Segmented address of arguments on stack |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1621 | * |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1622 | * LPVOID base [in] Flat address of region |
| 1623 | * DWORD size [in] Size of region |
| 1624 | * DWORD type [in] Type of operation |
| 1625 | * |
| 1626 | * Output: EAX: NtStatus |
| 1627 | * EDX: TRUE if success, FALSE if failure |
| 1628 | */ |
| 1629 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 1630 | DWORD *stack = MapSL( MAKESEGPTR( LOWORD(context->Edx), HIWORD(context->Edx) )); |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1631 | LPVOID base = (LPVOID)W32S_APP2WINE(stack[0]); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1632 | DWORD size = stack[1]; |
| 1633 | DWORD type = stack[2]; |
| 1634 | DWORD result; |
| 1635 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1636 | TRACE("VirtualFree16(%lx, %lx, %lx)\n", |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1637 | (DWORD)base, size, type); |
| 1638 | |
| 1639 | result = VirtualFree(base, size, type); |
| 1640 | |
| 1641 | if (result) |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1642 | context->Edx = TRUE, |
| 1643 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1644 | else |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1645 | context->Edx = FALSE, |
| 1646 | context->Eax = STATUS_NO_MEMORY; /* FIXME */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1647 | } |
| 1648 | break; |
| 1649 | |
| 1650 | |
| 1651 | case 0x001F: /* FWorkingSetSize */ |
| 1652 | /* |
| 1653 | * Input: EDX: 0 if Get, 1 if Set |
| 1654 | * |
| 1655 | * ECX: Get: Buffer to receive Working Set Size |
| 1656 | * Set: Buffer containing Working Set Size |
| 1657 | * |
| 1658 | * Output: NtStatus |
| 1659 | */ |
| 1660 | { |
Alexandre Julliard | becb9a3 | 2000-12-11 03:48:15 +0000 | [diff] [blame] | 1661 | DWORD *ptr = (DWORD *)W32S_APP2WINE(context->Ecx); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1662 | BOOL set = context->Edx; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1663 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 1664 | TRACE("FWorkingSetSize(%lx, %lx)\n", (DWORD)ptr, (DWORD)set); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1665 | |
| 1666 | if (set) |
| 1667 | /* We do it differently ... */; |
| 1668 | else |
| 1669 | *ptr = 0x100; |
| 1670 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 1671 | context->Eax = STATUS_SUCCESS; |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1672 | } |
| 1673 | break; |
| 1674 | |
| 1675 | |
| 1676 | default: |
| 1677 | VXD_BARF( context, "W32S" ); |
| 1678 | } |
| 1679 | |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 1680 | } |