VirtualBox

Changeset 51786 in vbox for trunk/src


Ignore:
Timestamp:
Jul 1, 2014 8:11:03 PM (11 years ago)
Author:
vboxsync
Message:

Merge fix

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r51770 r51786  
    8282///** Win Symlink name for hardened stub access. */
    8383//# define DEVICE_NAME_DOS_STUB   L"\\DosDevices\\VBoxDrvStub"
    84 
    8584
    8685/** Macro for checking for deflecting calls to the stub device. */
     
    11181117
    11191118
    1120 #ifdef VBOXDRV_WITH_FAST_IO
    1121 /**
    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 be
    1127  *          called.
    1128  * @param   pFileObj            The file object.
    1129  * @param   fWait               Whether it's a blocking call
    1130  * @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 from
    1157      * the session and iCmd, and does not return anything.
    1158      */
    1159     if (   (   uCmd == SUP_IOCTL_FAST_DO_RAW_RUN
    1160             || uCmd == SUP_IOCTL_FAST_DO_HM_RUN
    1161             || 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_AMD64
    1180     /* Don't allow 32-bit processes to do any I/O controls. */
    1181     if (!IoIs32bitProcess(NULL))
    1182 #endif
    1183     {
    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 the
    1191                parameters before allocating any memory kernel for the reqest. */
    1192             SUPREQHDR Hdr;
    1193             if (cbInput >= sizeof(Hdr) && cbOutput >= sizeof(Hdr))
    1194             {
    1195                 __try
    1196                 {
    1197                     RtlCopyMemory(&Hdr, pvInput, sizeof(Hdr));
    1198                     rcNt = STATUS_SUCCESS;
    1199                 }
    1200                 __except(EXCEPTION_EXECUTE_HANDLER)
    1201                 {
    1202                     rcNt = GetExceptionCode();
    1203                 }
    1204             }
    1205             else
    1206                 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.cbIn
    1212                     && cbOutput == Hdr.cbOut
    1213                     && 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                         __try
    1220                         {
    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                     else
    1232                         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                                 __try
    1254                                 {
    1255                                     RtlCopyMemory(pvOutput, pHdr, cbOut);
    1256                                     rcNt = STATUS_SUCCESS;
    1257                                 }
    1258                                 __except(EXCEPTION_EXECUTE_HANDLER)
    1259                                 {
    1260                                     rcNt = GetExceptionCode();
    1261                                 }
    1262                             }
    1263                             else
    1264                                 rcNt = STATUS_SUCCESS;
    1265                         }
    1266                         else if (rc == VERR_INVALID_PARAMETER)
    1267                             rcNt = STATUS_INVALID_PARAMETER;
    1268                         else
    1269                             rcNt = STATUS_NOT_SUPPORTED;
    1270                         Log2(("VBoxDrvNtFastIoDeviceControl: returns %#x cbOut=%d rc=%#x\n", rcNt, cbOut, rc));
    1271                     }
    1272                     ExFreePoolWithTag(pHdr, 'VBox');
    1273                 }
    1274                 else
    1275                 {
    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         else
    1283         {
    1284             Log(("VBoxDrvNtFastIoDeviceControl: not buffered request (%#x) - not supported\n", uCmd));
    1285             rcNt = STATUS_NOT_SUPPORTED;
    1286         }
    1287     }
    1288 #ifdef RT_ARCH_AMD64
    1289     else
    1290     {
    1291         Log(("VBoxDrvNtFastIoDeviceControl: WOW64 req - not supported\n"));
    1292         rcNt = STATUS_NOT_SUPPORTED;
    1293     }
    1294 #endif
    1295 
    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 
    13041119/**
    13051120 * Device I/O Control entry point.
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette