Changeset 70040 in vbox
- Timestamp:
- Dec 8, 2017 6:07:32 PM (7 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxGuest
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
r69999 r70040 61 61 static NTSTATUS vgdrvNtDeviceControlSlow(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, PIRP pIrp, PIO_STACK_LOCATION pStack); 62 62 static NTSTATUS vgdrvNtInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp); 63 static NTSTATUS vgdrvNtRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName, PULONG puValue);63 static void vgdrvNtReadConfiguration(PVBOXGUESTDEVEXTWIN pDevExt); 64 64 static NTSTATUS vgdrvNtSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp); 65 65 static NTSTATUS vgdrvNtShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp); … … 535 535 if (NT_SUCCESS(rcNt)) 536 536 { 537 ULONG uValue = 0x123; 538 NTSTATUS rcNt2 = vgdrvNtRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled", &uValue); 539 if (NT_SUCCESS(rcNt2)) 540 { 541 pDevExt->Core.fLoggingEnabled = uValue >= 0xFF; 542 if (pDevExt->Core.fLoggingEnabled) 543 LogRelFunc(("Logging to host log enabled (%#x)", uValue)); 544 } 537 /* 538 * Once we've read configuration from register and host, we're finally read. 539 */ 540 pDevExt->Core.fLoggingEnabled = true; /** @todo clean up guest ring-3 logging, keeping it separate from the kernel to avoid sharing limits with it. */ 541 vgdrvNtReadConfiguration(pDevExt); 545 542 546 543 /* Ready to rumble! */ … … 1098 1095 * registry value if found. 1099 1096 */ 1100 static NTSTATUS vgdrvNtRegistryReadDWORD(ULONG u lRoot, PCWSTR pwszPath, PWSTR pwszName, PULONG puValue)1097 static NTSTATUS vgdrvNtRegistryReadDWORD(ULONG uRoot, PCWSTR pwszPath, PWSTR pwszName, PULONG puValue) 1101 1098 { 1102 1099 if (!pwszPath || !pwszName || !puValue) 1103 1100 return STATUS_INVALID_PARAMETER; 1104 1101 1105 ULONG ulDefault = *puValue; 1106 1107 RTL_QUERY_REGISTRY_TABLE tblQuery[2]; 1108 RtlZeroMemory(tblQuery, sizeof(tblQuery)); 1102 ULONG uDefault = *puValue; 1103 RTL_QUERY_REGISTRY_TABLE aQuery[2]; 1104 RT_ZERO(aQuery); 1109 1105 /** @todo Add RTL_QUERY_REGISTRY_TYPECHECK! */ 1110 tblQuery[0].Flags = RTL_QUERY_REGISTRY_DIRECT; 1111 tblQuery[0].Name = pwszName; 1112 tblQuery[0].EntryContext = puValue; 1113 tblQuery[0].DefaultType = REG_DWORD; 1114 tblQuery[0].DefaultData = &ulDefault; 1115 tblQuery[0].DefaultLength = sizeof(ULONG); 1116 1117 return RtlQueryRegistryValues(ulRoot, 1118 pwszPath, 1119 &tblQuery[0], 1120 NULL /* Context */, 1121 NULL /* Environment */); 1106 aQuery[0].Flags = RTL_QUERY_REGISTRY_DIRECT; 1107 aQuery[0].Name = pwszName; 1108 aQuery[0].EntryContext = puValue; 1109 aQuery[0].DefaultType = REG_DWORD; 1110 aQuery[0].DefaultData = &uDefault; 1111 aQuery[0].DefaultLength = sizeof(uDefault); 1112 1113 return RtlQueryRegistryValues(uRoot, pwszPath, &aQuery[0], NULL /* Context */, NULL /* Environment */); 1114 } 1115 1116 1117 /** 1118 * Reads configuration from the registry and guest properties. 1119 * 1120 * We ignore failures and instead preserve existing configuration values. 1121 * 1122 * Thie routine will block. 1123 * 1124 * @param pDevExt The device extension. 1125 */ 1126 static void vgdrvNtReadConfiguration(PVBOXGUESTDEVEXTWIN pDevExt) 1127 { 1128 /* 1129 * First the registry. 1130 */ 1131 ULONG uValue = 0; 1132 NTSTATUS rcNt = vgdrvNtRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled", &uValue); 1133 if (NT_SUCCESS(rcNt)) 1134 { 1135 pDevExt->Core.fLoggingEnabled = uValue >= 0xFF; 1136 if (pDevExt->Core.fLoggingEnabled) 1137 LogRelFunc(("Logging to host log enabled (%#x)", uValue)); 1138 } 1139 1140 #if 0 /* test me */ 1141 /* 1142 * Read configuration from the host. 1143 */ 1144 VGDrvCommonProcessOptionsFromHost(&pDevExt->Core); 1145 #endif 1122 1146 } 1123 1147 -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r69500 r70040 55 55 #include <VBox/VMMDev.h> /* for VMMDEV_RAM_SIZE */ 56 56 #include <VBox/log.h> 57 #include <iprt/ctype.h> 57 58 #include <iprt/mem.h> 58 59 #include <iprt/time.h> … … 1135 1136 } 1136 1137 1138 #if 0 /* needs testing */ 1139 1140 #include <VBox/HostServices/GuestPropertySvc.h> 1141 1142 /** 1143 * Checks if the given option can be taken to no mean 'false'. 1144 * 1145 * @returns true or false accordingly. 1146 * @param pszValue The value to consider. 1147 */ 1148 bool VBDrvCommonIsOptionValueTrue(const char *pszValue) 1149 { 1150 if (pszValue) 1151 { 1152 char ch; 1153 while ( (ch = *pszValue) != '\0' 1154 && RT_C_IS_SPACE(ch)) 1155 pszValue++; 1156 1157 return ch != '\0' 1158 && ch != 'n' /* no */ 1159 && ch != 'N' /* NO */ 1160 && ch != 'd' /* disabled */ 1161 && ch != 'D' /* DISABLED */ 1162 && ( (ch != 'o' && ch != 'O') /* off, OFF, Off */ 1163 || (pszValue[1] != 'f' && pszValue[1] != 'F') ) 1164 && (ch != '0' || pszValue[1] != '\0') /* '0' */ 1165 ; 1166 } 1167 return false; 1168 } 1169 1170 1171 /** 1172 * Hook for handling OS specfic options from the host. 1173 * 1174 * @returns true if handled, false if not. 1175 * @param pDevExt The device extension. 1176 * @param pszName The option name. 1177 * @param pszValue The option value. 1178 */ 1179 bool VGDrvNativeProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue) 1180 { 1181 RT_NOREF(pDevExt); RT_NOREF(pszName); RT_NOREF(pszValue); 1182 return false; 1183 } 1184 1185 /** 1186 * Processes a option. 1187 * 1188 * This will let the OS specific code have a go at it too. 1189 * 1190 * @param pDevExt The device extension. 1191 * @param pszName The option name, sans prefix. 1192 * @param pszValue The option value. 1193 */ 1194 void VGDrvCommonProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue) 1195 { 1196 if (strcmp(pszName, "r3_log_to_host") == 0) 1197 pDevExt->fLoggingEnabled = VBDrvCommonIsOptionValueTrue(pszValue); 1198 else if (VGDrvNativeProcessOption(pDevExt, pszName, pszValue)) 1199 LogRel(("VBoxGuest: Ignoring unknown option '%s' (value '%s')\n", pszName, pszValue)); 1200 } 1201 1202 1203 /** 1204 * Read driver configuration from the host. 1205 * 1206 * This involves connecting to the guest properties service, which means that 1207 * interrupts needs to work and that the calling thread must be able to block. 1208 * 1209 * @param pDevExt The device extension. 1210 */ 1211 void VGDrvCommonProcessOptionsFromHost(PVBOXGUESTDEVEXT pDevExt) 1212 { 1213 /* 1214 * Create a kernel session without our selves, then connect to the HGCM service. 1215 */ 1216 PVBOXGUESTSESSION pSession; 1217 int rc = VGDrvCommonCreateKernelSession(pDevExt, &pSession); 1218 if (RT_SUCCESS(rc)) 1219 { 1220 union 1221 { 1222 VBGLIOCHGCMCONNECT Connect; 1223 VBGLIOCHGCMDISCONNECT Disconnect; 1224 guestProp::EnumProperties EnumMsg; 1225 } uBuf; 1226 1227 RT_ZERO(uBuf.Connect); 1228 VBGLREQHDR_INIT(&uBuf.Connect.Hdr, HGCM_CONNECT); 1229 uBuf.Connect.u.In.Loc.type = VMMDevHGCMLoc_LocalHost_Existing; 1230 RTStrCopy(uBuf.Connect.u.In.Loc.u.host.achName, sizeof(uBuf.Connect.u.In.Loc.u.host.achName), 1231 "VBoxGuestPropSvc"); /** @todo Add a define to the header for the name. */ 1232 rc = VGDrvCommonIoCtl(VBGL_IOCTL_HGCM_CONNECT, pDevExt, pSession, &uBuf.Connect.Hdr, sizeof(uBuf.Connect)); 1233 if (RT_SUCCESS(rc)) 1234 { 1235 static const char g_szzPattern[] = "/VirtualBox/GuestAdd/VBoxGuest/*\0"; 1236 uint32_t const idClient = uBuf.Connect.u.Out.idClient; 1237 char *pszzStrings = NULL; 1238 uint32_t cbStrings; 1239 1240 /* 1241 * Enumerate all the relevant properties. We try with a 2KB buffer, but 1242 * will double it until we get what we want or go beyond 64KB. 1243 */ 1244 for (cbStrings = _2K; cbStrings <= _64K; cbStrings *= 2) 1245 { 1246 pszzStrings = (char *)RTMemAllocZ(cbStrings); 1247 if (pszzStrings) 1248 { 1249 VBGL_HGCM_HDR_INIT(&uBuf.EnumMsg.hdr, idClient, guestProp::ENUM_PROPS, 3); 1250 1251 uBuf.EnumMsg.patterns.type = VMMDevHGCMParmType_LinAddr; 1252 uBuf.EnumMsg.patterns.u.Pointer.size = sizeof(g_szzPattern); 1253 uBuf.EnumMsg.patterns.u.Pointer.u.linearAddr = (uintptr_t)g_szzPattern; 1254 1255 uBuf.EnumMsg.strings.type = VMMDevHGCMParmType_LinAddr; 1256 uBuf.EnumMsg.strings.u.Pointer.size = cbStrings; 1257 uBuf.EnumMsg.strings.u.Pointer.u.linearAddr = (uintptr_t)pszzStrings; 1258 1259 uBuf.EnumMsg.size.type = VMMDevHGCMParmType_32bit; 1260 uBuf.EnumMsg.size.u.value32 = 0; 1261 1262 rc = VGDrvCommonIoCtl(VBGL_IOCTL_HGCM_CALL(sizeof(uBuf.EnumMsg)), pDevExt, pSession, 1263 &uBuf.EnumMsg.hdr.Hdr, sizeof(uBuf.EnumMsg)); 1264 if (RT_SUCCESS(rc)) 1265 break; 1266 1267 RTMemFree(pszzStrings); 1268 pszzStrings = NULL; 1269 } 1270 else 1271 { 1272 LogRel(("VGDrvCommonReadConfigurationFromHost: failed to allocate %#x bytes\n", cbStrings)); 1273 break; 1274 } 1275 } 1276 1277 /* 1278 * Disconnect and destroy the session. 1279 */ 1280 VBGLREQHDR_INIT(&uBuf.Disconnect.Hdr, HGCM_DISCONNECT); 1281 uBuf.Disconnect.u.In.idClient = idClient; 1282 VGDrvCommonIoCtl(VBGL_IOCTL_HGCM_DISCONNECT, pDevExt, pSession, &uBuf.Disconnect.Hdr, sizeof(uBuf.Disconnect)); 1283 1284 VGDrvCommonCloseSession(pDevExt, pSession); 1285 1286 /* 1287 * Process the properties if we got any. 1288 * 1289 * The string buffer contains packed strings in groups of four - name, value, 1290 * timestamp (as a decimal string) and flags. It is terminated by four empty 1291 * strings. Layout: 1292 * Name\0Value\0Timestamp\0Flags\0 1293 */ 1294 if (pszzStrings) 1295 { 1296 uint32_t off; 1297 for (off = 0; off < cbStrings; off++) 1298 { 1299 /* 1300 * Parse the four fields, checking that it's all plain ASCII w/o any control characters. 1301 */ 1302 const char *apszFields[4] = { NULL, NULL, NULL, NULL }; 1303 bool fValidFields = true; 1304 unsigned iField; 1305 for (iField = 0; iField < RT_ELEMENTS(apszFields); iField++) 1306 { 1307 apszFields[0] = &pszzStrings[off]; 1308 while (off < cbStrings) 1309 { 1310 char ch = pszzStrings[off++]; 1311 if ((unsigned)ch < 0x20U || (unsigned)ch > 0x7fU) 1312 { 1313 if (!ch) 1314 break; 1315 fValidFields = false; 1316 } 1317 } 1318 } 1319 if ( off < cbStrings 1320 && fValidFields 1321 && *apszFields[0] != '\0') 1322 { 1323 /* 1324 * Validate and convert the flags to integer, then process the option. 1325 */ 1326 uint32_t fFlags = 0; 1327 rc = guestProp::validateFlags(apszFields[3], &fFlags); 1328 if (RT_SUCCESS(rc)) 1329 { 1330 if (fFlags & guestProp::RDONLYGUEST) 1331 { 1332 apszFields[0] += sizeof(g_szzPattern) - 2; 1333 VGDrvCommonProcessOption(pDevExt, apszFields[0], apszFields[1]); 1334 } 1335 else 1336 LogRel(("VBoxGuest: Ignoring '%s' as it does not have RDONLYGUEST set\n", apszFields[0])); 1337 } 1338 else 1339 LogRel(("VBoxGuest: Invalid flags '%s' for '%s': %Rrc\n", apszFields[2], apszFields[0], rc)); 1340 } 1341 else if (off < cbStrings) 1342 { 1343 LogRel(("VBoxGuest: Malformed guest properties enum result!\n")); 1344 break; 1345 } 1346 else if (fValidFields) 1347 LogRel(("VBoxGuest: Ignoring %.*Rhxs as it has invalid characters in one or more fields\n", 1348 (int)strlen(apszFields[0]), apszFields[0])); 1349 else 1350 break; 1351 } 1352 1353 RTMemFree(pszzStrings); 1354 } 1355 else 1356 LogRel(("VGDrvCommonReadConfigurationFromHost: failed to enumerate '%s': %Rrc\n", g_szzPattern, rc)); 1357 1358 } 1359 else 1360 LogRel(("VGDrvCommonReadConfigurationFromHost: failed to connect: %Rrc\n", rc)); 1361 } 1362 else 1363 LogRel(("VGDrvCommonReadConfigurationFromHost: failed to connect: %Rrc\n", rc)); 1364 } 1365 1366 #endif /* needs testing */ 1137 1367 1138 1368 /** -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
r69500 r70040 325 325 int VGDrvCommonInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase, void *pvMMIOBase, uint32_t cbMMIO, 326 326 VBOXOSTYPE enmOSType, uint32_t fEvents); 327 void VGDrvCommonProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue); 328 void VGDrvCommonProcessOptionsFromHost(PVBOXGUESTDEVEXT pDevExt); 327 329 bool VGDrvCommonIsOurIRQ(PVBOXGUESTDEVEXT pDevExt); 328 330 bool VGDrvCommonISR(PVBOXGUESTDEVEXT pDevExt); … … 351 353 void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt); 352 354 355 /** 356 * Hook for handling OS specfic options from the host. 357 * 358 * @returns true if handled, false if not. 359 * @param pDevExt The device extension. 360 * @param pszName The option name. 361 * @param pszValue The option value. 362 */ 363 bool VGDrvNativeProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue); 364 353 365 354 366 #ifdef VBOX_WITH_DPC_LATENCY_CHECKER
Note:
See TracChangeset
for help on using the changeset viewer.