- Timestamp:
- Jul 1, 2014 8:11:03 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r51770 r51786 82 82 ///** Win Symlink name for hardened stub access. */ 83 83 //# define DEVICE_NAME_DOS_STUB L"\\DosDevices\\VBoxDrvStub" 84 85 84 86 85 /** Macro for checking for deflecting calls to the stub device. */ … … 1118 1117 1119 1118 1120 #ifdef VBOXDRV_WITH_FAST_IO1121 /**1122 * Fast I/O device control callback.1123 *1124 * This performs no buffering, neither on the way in or out.1125 *1126 * @returns TRUE if handled, FALSE if the normal I/O control routine should be1127 * called.1128 * @param pFileObj The file object.1129 * @param fWait Whether it's a blocking call1130 * @param pvInput The input buffer as specified by the user.1131 * @param cbInput The size of the input buffer.1132 * @param pvOutput The output buffer as specfied by the user.1133 * @param cbOutput The size of the output buffer.1134 * @param uFunction The function.1135 * @param pIoStatus Where to return the status of the operation.1136 * @param pDevObj The device object..1137 */1138 static BOOLEAN _stdcall VBoxDrvNtFastIoDeviceControl(PFILE_OBJECT pFileObj, BOOLEAN fWait, PVOID pvInput, ULONG cbInput,1139 PVOID pvOutput, ULONG cbOutput, ULONG uCmd,1140 PIO_STATUS_BLOCK pIoStatus, PDEVICE_OBJECT pDevObj)1141 {1142 PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);1143 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFileObj->FsContext;1144 1145 /*1146 * Check the input a little bit.1147 */1148 if (!pSession)1149 {1150 pIoStatus->Status = STATUS_INVALID_PARAMETER;1151 pIoStatus->Information = 0;1152 return TRUE;1153 }1154 1155 /*1156 * Deal with the 2-3 high-speed IOCtl that takes their arguments from1157 * the session and iCmd, and does not return anything.1158 */1159 if ( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN1160 || uCmd == SUP_IOCTL_FAST_DO_HM_RUN1161 || uCmd == SUP_IOCTL_FAST_DO_NOP)1162 && pSession->fUnrestricted == true)1163 {1164 int rc = supdrvIOCtlFast(uCmd, (unsigned)(uintptr_t)pvOutput /* VMCPU id */, pDevExt, pSession);1165 pIoStatus->Status = RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER;1166 pIoStatus->Information = 0; /* Could be used to pass rc if we liked. */1167 return TRUE;1168 }1169 1170 /*1171 * The normal path.1172 */1173 NTSTATUS rcNt;1174 unsigned cbOut = 0;1175 int rc = 0;1176 Log2(("VBoxDrvNtFastIoDeviceControl(%p): ioctl=%#x pvIn=%p cbIn=%#x pvOut=%p cbOut=%#x pSession=%p\n",1177 pDevExt, uCmd, pvInput, cbInput, pvOutput, cbOutput, pSession));1178 1179 #ifdef RT_ARCH_AMD641180 /* Don't allow 32-bit processes to do any I/O controls. */1181 if (!IoIs32bitProcess(NULL))1182 #endif1183 {1184 /*1185 * In this fast I/O device control path we have to do our own buffering.1186 */1187 /* Verify that the I/O control function matches our pattern. */1188 if ((uCmd & 0x3) == METHOD_BUFFERED)1189 {1190 /* Get the header so we can validate it a little bit against the1191 parameters before allocating any memory kernel for the reqest. */1192 SUPREQHDR Hdr;1193 if (cbInput >= sizeof(Hdr) && cbOutput >= sizeof(Hdr))1194 {1195 __try1196 {1197 RtlCopyMemory(&Hdr, pvInput, sizeof(Hdr));1198 rcNt = STATUS_SUCCESS;1199 }1200 __except(EXCEPTION_EXECUTE_HANDLER)1201 {1202 rcNt = GetExceptionCode();1203 }1204 }1205 else1206 rcNt = STATUS_INVALID_PARAMETER;1207 if (NT_SUCCESS(rcNt))1208 {1209 /* Verify that the sizes in the request header are correct. */1210 ULONG cbBuf = RT_MAX(cbInput, cbOutput);1211 if ( cbInput == Hdr.cbIn1212 && cbOutput == Hdr.cbOut1213 && cbBuf < _1M*16)1214 {1215 /* Allocate a buffer and copy all the input into it. */1216 PSUPREQHDR pHdr = (PSUPREQHDR)ExAllocatePoolWithTag(NonPagedPool, cbBuf, 'VBox');1217 if (pHdr)1218 {1219 __try1220 {1221 RtlCopyMemory(pHdr, pvInput, cbInput);1222 if (cbInput < cbBuf)1223 RtlZeroMemory((uint8_t *)pHdr + cbInput, cbBuf - cbInput);1224 rcNt = STATUS_SUCCESS;1225 }1226 __except(EXCEPTION_EXECUTE_HANDLER)1227 {1228 rcNt = GetExceptionCode();1229 }1230 }1231 else1232 rcNt = STATUS_NO_MEMORY;1233 if (NT_SUCCESS(rcNt))1234 {1235 /*1236 * Now call the common code to do the real work.1237 */1238 rc = supdrvIOCtl(uCmd, pDevExt, pSession, pHdr);1239 if (RT_SUCCESS(rc))1240 {1241 /*1242 * Copy back the result.1243 */1244 cbOut = pHdr->cbOut;1245 if (cbOut > cbOutput)1246 {1247 cbOut = cbOutput;1248 OSDBGPRINT(("VBoxDrvNtFastIoDeviceControl: too much output! %#x > %#x; uCmd=%#x!\n",1249 pHdr->cbOut, cbOut, uCmd));1250 }1251 if (cbOut)1252 {1253 __try1254 {1255 RtlCopyMemory(pvOutput, pHdr, cbOut);1256 rcNt = STATUS_SUCCESS;1257 }1258 __except(EXCEPTION_EXECUTE_HANDLER)1259 {1260 rcNt = GetExceptionCode();1261 }1262 }1263 else1264 rcNt = STATUS_SUCCESS;1265 }1266 else if (rc == VERR_INVALID_PARAMETER)1267 rcNt = STATUS_INVALID_PARAMETER;1268 else1269 rcNt = STATUS_NOT_SUPPORTED;1270 Log2(("VBoxDrvNtFastIoDeviceControl: returns %#x cbOut=%d rc=%#x\n", rcNt, cbOut, rc));1271 }1272 ExFreePoolWithTag(pHdr, 'VBox');1273 }1274 else1275 {1276 Log(("VBoxDrvNtFastIoDeviceControl: Mismatching sizes (%#x) - Hdr=%#lx/%#lx Irp=%#lx/%#lx!\n",1277 uCmd, Hdr.cbIn, Hdr.cbOut, cbInput, cbOutput));1278 rcNt = STATUS_INVALID_PARAMETER;1279 }1280 }1281 }1282 else1283 {1284 Log(("VBoxDrvNtFastIoDeviceControl: not buffered request (%#x) - not supported\n", uCmd));1285 rcNt = STATUS_NOT_SUPPORTED;1286 }1287 }1288 #ifdef RT_ARCH_AMD641289 else1290 {1291 Log(("VBoxDrvNtFastIoDeviceControl: WOW64 req - not supported\n"));1292 rcNt = STATUS_NOT_SUPPORTED;1293 }1294 #endif1295 1296 /* complete the request. */1297 pIoStatus->Status = rcNt;1298 pIoStatus->Information = cbOut;1299 return TRUE; /* handled. */1300 }1301 #endif /* VBOXDRV_WITH_FAST_IO */1302 1303 1304 1119 /** 1305 1120 * Device I/O Control entry point.
Note:
See TracChangeset
for help on using the changeset viewer.