Changeset 70287 in vbox for trunk/src/VBox
- Timestamp:
- Dec 21, 2017 3:52:26 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
r70284 r70287 38 38 #include <iprt/asm.h> 39 39 #include <iprt/asm-amd64-x86.h> 40 #include <iprt/critsect.h> 40 41 #include <iprt/dbg.h> 41 42 #include <iprt/initterm.h> … … 135 136 * in a DPC callback and not the ISR. */ 136 137 KSPIN_LOCK MouseEventAccessSpinLock; 138 139 /** Read/write critical section for handling race between checking for idle 140 * driver (in IRP_MN_QUERY_REMOVE_DEVICE & IRP_MN_QUERY_STOP_DEVICE) and 141 * creating new sessions. The session creation code enteres the critical 142 * section in read (shared) access mode, whereas the idle checking code 143 * enteres is in write (exclusive) access mode. */ 144 RTCRITSECTRW SessionCreateCritSect; 137 145 } VBOXGUESTDEVEXTWIN; 138 146 typedef VBOXGUESTDEVEXTWIN *PVBOXGUESTDEVEXTWIN; … … 449 457 450 458 459 /** 460 * Does the fundamental device extension initialization. 461 * 462 * @returns NT status. 463 * @param pDevExt The device extension. 464 * @param pDevObj The device object. 465 */ 466 static NTSTATUS vgdrvNtInitDevExtFundament(PVBOXGUESTDEVEXTWIN pDevExt, PDEVICE_OBJECT pDevObj) 467 { 468 RT_ZERO(*pDevExt); 469 470 KeInitializeSpinLock(&pDevExt->MouseEventAccessSpinLock); 471 pDevExt->pDeviceObject = pDevObj; 472 pDevExt->enmPrevDevState = VGDRVNTDEVSTATE_STOPPED; 473 pDevExt->enmDevState = VGDRVNTDEVSTATE_STOPPED; 474 475 int rc = RTCritSectRwInit(&pDevExt->SessionCreateCritSect); 476 if (RT_SUCCESS(rc)) 477 { 478 rc = VGDrvCommonInitDevExtFundament(&pDevExt->Core); 479 if (RT_SUCCESS(rc)) 480 { 481 LogFlow(("vgdrvNtInitDevExtFundament: returning success\n")); 482 return STATUS_SUCCESS; 483 } 484 485 RTCritSectRwDelete(&pDevExt->SessionCreateCritSect); 486 } 487 Log(("vgdrvNtInitDevExtFundament: failed: rc=%Rrc\n", rc)); 488 return STATUS_UNSUCCESSFUL; 489 } 490 491 492 /** 493 * Counter part to vgdrvNtInitDevExtFundament. 494 * 495 * @param pDevExt The device extension. 496 */ 497 static void vgdrvNtDeleteDevExtFundament(PVBOXGUESTDEVEXTWIN pDevExt) 498 { 499 LogFlow(("vgdrvNtDeleteDevExtFundament:\n")); 500 VGDrvCommonDeleteDevExtFundament(&pDevExt->Core); 501 RTCritSectRwDelete(&pDevExt->SessionCreateCritSect); 502 } 503 504 451 505 #ifdef LOG_ENABLED 452 506 /** … … 986 1040 Log(("vgdrvNt4CreateDevice: Setting up device extension ...\n")); 987 1041 PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDeviceObject->DeviceExtension; 988 RT_ZERO(*pDevExt); 989 990 /* Store a reference to ourself. */ 991 pDevExt->pDeviceObject = pDeviceObject; 992 993 /* Store bus and slot number we've queried before. */ 994 pDevExt->uBus = uBus; 995 pDevExt->uSlot = uSlot.u.AsULONG; 996 997 /* Initialize common bits. */ 998 int vrc = VGDrvCommonInitDevExtFundament(&pDevExt->Core); 1042 int vrc = vgdrvNtInitDevExtFundament(pDevExt, pDeviceObject); 999 1043 if (RT_SUCCESS(vrc)) 1000 1044 { 1045 /* Store bus and slot number we've queried before. */ 1046 pDevExt->uBus = uBus; 1047 pDevExt->uSlot = uSlot.u.AsULONG; 1048 1001 1049 Log(("vgdrvNt4CreateDevice: Device extension created\n")); 1002 1050 … … 1010 1058 1011 1059 /* bail out */ 1012 VGDrvCommonDeleteDevExtFundament(&pDevExt->Core);1060 vgdrvNtDeleteDevExtFundament(pDevExt); 1013 1061 } 1014 1062 IoDeleteSymbolicLink(&DosName); … … 1060 1108 */ 1061 1109 PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDeviceObject->DeviceExtension; 1062 RT_ZERO(*pDevExt); 1063 1064 KeInitializeSpinLock(&pDevExt->MouseEventAccessSpinLock); 1065 pDevExt->pDeviceObject = pDeviceObject; 1066 pDevExt->enmPrevDevState = VGDRVNTDEVSTATE_STOPPED; 1067 pDevExt->enmDevState = VGDRVNTDEVSTATE_STOPPED; 1068 1069 int vrc = VGDrvCommonInitDevExtFundament(&pDevExt->Core); 1070 if (RT_SUCCESS(vrc)) 1110 rcNt = vgdrvNtInitDevExtFundament(pDevExt, pDeviceObject); 1111 if (NT_SUCCESS(rcNt)) 1071 1112 { 1072 1113 pDevExt->pNextLowerDriver = IoAttachDeviceToDeviceStack(pDeviceObject, pDevObj); … … 1081 1122 return rcNt; 1082 1123 } 1083 1084 1124 LogFunc(("IoAttachDeviceToDeviceStack did not give a nextLowerDriver!\n")); 1085 1125 rcNt = STATUS_DEVICE_NOT_CONNECTED; 1086 VGDrvCommonDeleteDevExtFundament(&pDevExt->Core);1126 vgdrvNtDeleteDevExtFundament(pDevExt); 1087 1127 } 1088 else 1089 rcNt = STATUS_UNSUCCESSFUL; 1090 1091 /* bail out */ 1128 1092 1129 IoDeleteSymbolicLink(&DosName); 1093 1130 } … … 1169 1206 pDevExt->pInterruptObject = NULL; 1170 1207 } 1208 pDevExt->pPowerStateRequest = NULL; /* Will be deleted by the following call. */ 1171 1209 if (pDevExt->Core.uInitState == VBOXGUESTDEVEXT_INIT_STATE_RESOURCES) 1172 1210 VGDrvCommonDeleteDevExtResources(&pDevExt->Core); … … 1189 1227 * Delete the remainder of the device extension. 1190 1228 */ 1191 pDevExt->pPowerStateRequest = NULL; /* Will be deleted by the following call. */ 1192 VGDrvCommonDeleteDevExtFundament(&pDevExt->Core); 1229 vgdrvNtDeleteDevExtFundament(pDevExt); 1193 1230 1194 1231 /* … … 1309 1346 Log(("vgdrvNtNt5PlusPnP: QUERY_REMOVE_DEVICE\n")); 1310 1347 1348 RTCritSectRwEnterExcl(&pDevExt->SessionCreateCritSect); 1311 1349 #ifdef VBOX_REBOOT_ON_UNINSTALL 1312 1350 Log(("vgdrvNtNt5PlusPnP: QUERY_REMOVE_DEVICE: Device cannot be removed without a reboot.\n")); … … 1318 1356 { 1319 1357 pDevExt->enmDevState = VGDRVNTDEVSTATE_PENDINGREMOVE; 1358 RTCritSectRwLeaveExcl(&pDevExt->SessionCreateCritSect); 1320 1359 1321 1360 /* This IRP passed down to lower driver. */ … … 1332 1371 else 1333 1372 { 1373 RTCritSectRwLeaveExcl(&pDevExt->SessionCreateCritSect); 1334 1374 pIrp->IoStatus.Status = rc; 1335 1375 IoCompleteRequest(pIrp, IO_NO_INCREMENT); … … 1429 1469 { 1430 1470 Log(("vgdrvNtNt5PlusPnP: QUERY_STOP_DEVICE\n")); 1471 RTCritSectRwEnterExcl(&pDevExt->SessionCreateCritSect); 1431 1472 rc = vgdrvNtCheckIdle(pDevExt, "QUERY_STOP_DEVICE"); 1432 1473 if (NT_SUCCESS(rc)) … … 1434 1475 pDevExt->enmPrevDevState = pDevExt->enmDevState; 1435 1476 pDevExt->enmDevState = VGDRVNTDEVSTATE_PENDINGSTOP; 1477 RTCritSectRwLeaveExcl(&pDevExt->SessionCreateCritSect); 1436 1478 1437 1479 /* This IRP passed down to lower driver. */ … … 1449 1491 else 1450 1492 { 1493 RTCritSectRwLeaveExcl(&pDevExt->SessionCreateCritSect); 1451 1494 pIrp->IoStatus.Status = rc; 1452 1495 IoCompleteRequest(pIrp, IO_NO_INCREMENT); … … 1836 1879 /* 1837 1880 * We are not remotely similar to a directory... 1838 * (But this is possible.)1839 1881 */ 1840 if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE) 1882 NTSTATUS rcNt; 1883 if (!(pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)) 1884 { 1885 /* 1886 * Check the device state. We enter the critsect in shared mode to 1887 * prevent race with PnP system requests checking whether we're idle. 1888 */ 1889 RTCritSectRwEnterShared(&pDevExt->SessionCreateCritSect); 1890 VGDRVNTDEVSTATE const enmDevState = pDevExt->enmDevState; 1891 if (enmDevState == VGDRVNTDEVSTATE_OPERATIONAL) 1892 { 1893 /* 1894 * Create a client session. 1895 */ 1896 int rc; 1897 PVBOXGUESTSESSION pSession; 1898 if (pIrp->RequestorMode == KernelMode) 1899 rc = VGDrvCommonCreateKernelSession(&pDevExt->Core, &pSession); 1900 else 1901 rc = VGDrvCommonCreateUserSession(&pDevExt->Core, &pSession); 1902 RTCritSectRwLeaveShared(&pDevExt->SessionCreateCritSect); 1903 if (RT_SUCCESS(rc)) 1904 { 1905 pFileObj->FsContext = pSession; 1906 Log(("vgdrvNtCreate: Successfully created %s session %p\n", 1907 pIrp->RequestorMode == KernelMode ? "kernel" : "user", pSession)); 1908 1909 return vgdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp); 1910 } 1911 1912 /* Note. the IoStatus is completely ignored on error. */ 1913 Log(("vgdrvNtCreate: Failed to create session: rc=%Rrc\n", rc)); 1914 if (rc == VERR_NO_MEMORY) 1915 rcNt = STATUS_NO_MEMORY; 1916 else 1917 rcNt = STATUS_UNSUCCESSFUL; 1918 } 1919 else 1920 { 1921 RTCritSectRwLeaveShared(&pDevExt->SessionCreateCritSect); 1922 LogFlow(("vgdrvNtCreate: Failed. Device is not in 'working' state: %d\n", enmDevState)); 1923 rcNt = STATUS_DEVICE_NOT_READY; 1924 } 1925 } 1926 else 1841 1927 { 1842 1928 LogFlow(("vgdrvNtCreate: Failed. FILE_DIRECTORY_FILE set\n")); 1843 return vgdrvNtCompleteRequest(STATUS_NOT_A_DIRECTORY, pIrp); 1844 } 1845 1846 /* 1847 * Check the device state. 1848 */ 1849 if (pDevExt->enmDevState != VGDRVNTDEVSTATE_OPERATIONAL) 1850 { 1851 LogFlow(("vgdrvNtCreate: Failed. Device is not in 'working' state: %d\n", pDevExt->enmDevState)); 1852 return vgdrvNtCompleteRequest(STATUS_DEVICE_NOT_READY, pIrp); 1853 } 1854 1855 /* 1856 * Create a client session. 1857 */ 1858 int rc; 1859 PVBOXGUESTSESSION pSession; 1860 if (pIrp->RequestorMode == KernelMode) 1861 rc = VGDrvCommonCreateKernelSession(&pDevExt->Core, &pSession); 1862 else 1863 rc = VGDrvCommonCreateUserSession(&pDevExt->Core, &pSession); 1864 if (RT_SUCCESS(rc)) 1865 { 1866 pFileObj->FsContext = pSession; 1867 Log(("vgdrvNtCreate: Successfully created %s session %p\n", 1868 pIrp->RequestorMode == KernelMode ? "kernel" : "user", pSession)); 1869 return vgdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp); 1870 } 1871 1872 Log(("vgdrvNtCreate: Failed to create session: rc=%Rrc\n", rc)); 1873 /* Note. the IoStatus is completely ignored on error. */ 1874 if (rc == VERR_NO_MEMORY) 1875 return vgdrvNtCompleteRequest(STATUS_NO_MEMORY, pIrp); 1876 return vgdrvNtCompleteRequest(STATUS_UNSUCCESSFUL, pIrp); 1929 rcNt = STATUS_NOT_A_DIRECTORY; 1930 } 1931 return vgdrvNtCompleteRequest(rcNt, pIrp); 1877 1932 } 1878 1933
Note:
See TracChangeset
for help on using the changeset viewer.