Changeset 10797 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Jul 22, 2008 8:12:42 AM (17 years ago)
- Location:
- trunk/src/VBox/Additions/common
- Files:
-
- 1 added
- 6 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/Makefile.kmk
r10130 r10797 30 30 # Include sub-makefile. 31 31 include $(PATH_SUB_CURRENT)/VBoxGuestLib/Makefile.kmk 32 if1of ($(KBUILD_TARGET), freebsd linux os2 solaris)33 32 include $(PATH_SUB_CURRENT)/VBoxControl/Makefile.kmk 34 endif35 33 if1of ($(KBUILD_TARGET), freebsd os2 solaris) 36 34 include $(PATH_SUB_CURRENT)/VBoxGuest/Makefile.kmk -
trunk/src/VBox/Additions/common/VBoxControl/Makefile.kmk
r10127 r10797 33 33 PROGRAMS += VBoxControl 34 34 VBoxControl_TEMPLATE = VBOXGUESTR3EXE 35 ifdef VBOX_WITH_INFO_SVC 36 VBoxControl_DEFS += VBOX_HGCM VBOX_WITH_INFO_SVC 35 ifeq ($(KBUILD_TARGET),win) 36 ifdef VBOX_SIGN_ADDITIONS # (See the main Windows Additions makefile.) 37 VBoxControl_NOINST = true 38 endif 37 39 endif 40 VBoxControl_DEFS += \ 41 $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS VBOX_HGCM,) 38 42 VBoxControl_SOURCES = \ 39 43 VBoxControl.cpp \ 40 44 VBoxControlSVN.cpp 45 VBoxControl_SOURCES.win = \ 46 VBoxControl.rc 41 47 VBoxControl_LIBS = \ 42 48 $(VBOX_LIB_IPRT_GUEST_R3) \ -
trunk/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp
r10236 r10797 25 25 * Header Files * 26 26 *******************************************************************************/ 27 #include <iprt/ thread.h>27 #include <iprt/mem.h> 28 28 #include <iprt/string.h> 29 29 #include <iprt/stream.h> 30 30 #include <iprt/path.h> 31 31 #include <iprt/initterm.h> 32 #include <VBox/log.h> 32 33 #include <VBox/VBoxGuest.h> 33 34 #include <VBox/version.h> 34 #ifdef VBOX_WITH_INFO_SVC 35 # include <VBox/HostServices/VBoxInfoSvc.h> 35 #ifdef RT_OS_WINDOWS 36 # include <windows.h> 37 # include <malloc.h> /* for alloca */ 38 #endif 39 #ifdef VBOX_WITH_GUEST_PROPS 40 # include <VBox/HostServices/GuestPropertySvc.h> 36 41 #endif 37 42 #include "VBoxControl.h" … … 57 62 static void doUsage(char const *line, char const *name = "", char const *command = "") 58 63 { 59 RTPrintf("%s %-*s%s", name, 3 0- strlen(name), command, line);64 RTPrintf("%s %-*s%s", name, 32 - strlen(name), command, line); 60 65 } 61 66 … … 63 68 enum g_eUsage 64 69 { 65 #ifdef VBOX_WITH_INFO_SVC 70 #ifdef RT_OS_WINDOWS 71 GET_VIDEO_ACCEL, 72 SET_VIDEO_ACCEL, 73 LIST_CUST_MODES, 74 ADD_CUST_MODE, 75 REMOVE_CUST_MODE, 76 SET_VIDEO_MODE, 77 #endif 78 #ifdef VBOX_WITH_GUEST_PROPS 66 79 GET_GUEST_PROP, 67 80 SET_GUEST_PROP, … … 73 86 { 74 87 RTPrintf("Usage:\n\n"); 75 RTPrintf("%s [-v|--version] print version number and exit\n", g_pszProgName); 76 RTPrintf("%s --nologo ... suppress the logo\n\n", g_pszProgName); 77 78 #ifdef VBOX_WITH_INFO_SVC 88 RTPrintf("%s [-v|--version] print version number and exit\n", g_pszProgName); 89 RTPrintf("%s --nologo ... suppress the logo\n\n", g_pszProgName); 90 91 #ifdef RT_OS_WINDOWS 92 if ((GET_VIDEO_ACCEL == eWhich) || (USAGE_ALL == eWhich)) 93 doUsage("\n", g_pszProgName, "getvideoacceleration"); 94 if ((SET_VIDEO_ACCEL == eWhich) || (USAGE_ALL == eWhich)) 95 doUsage("<on|off>\n", g_pszProgName, "setvideoacceleration"); 96 if ((LIST_CUST_MODES == eWhich) || (USAGE_ALL == eWhich)) 97 doUsage("\n", g_pszProgName, "listcustommodes"); 98 if ((ADD_CUST_MODE == eWhich) || (USAGE_ALL == eWhich)) 99 doUsage("<width> <height> <bpp>\n", g_pszProgName, "addcustommode"); 100 if ((REMOVE_CUST_MODE == eWhich) || (USAGE_ALL == eWhich)) 101 doUsage("<width> <height> <bpp>\n", g_pszProgName, "removecustommode"); 102 if ((SET_VIDEO_MODE == eWhich) || (USAGE_ALL == eWhich)) 103 doUsage("<width> <height> <bpp> <screen>\n", g_pszProgName, "setvideomode"); 104 #endif 105 #ifdef VBOX_WITH_GUEST_PROPS 79 106 if ((GET_GUEST_PROP == eWhich) || (USAGE_ALL == eWhich)) 80 doUsage("< key>\n", g_pszProgName, "getguestproperty");107 doUsage("<name>\n", g_pszProgName, "getguestproperty"); 81 108 if ((SET_GUEST_PROP == eWhich) || (USAGE_ALL == eWhich)) 82 doUsage("< key> [<value>] (no value deletes key)\n", g_pszProgName, "setguestproperty");109 doUsage("<name> [<value>] (no value deletes property)\n", g_pszProgName, "setguestproperty"); 83 110 #endif 84 111 } … … 101 128 } 102 129 103 #ifdef VBOX_WITH_INFO_SVC 130 #ifdef RT_OS_WINDOWS 131 132 LONG (WINAPI * gpfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam); 133 134 static unsigned nextAdjacentRectXP (RECTL *paRects, unsigned nRects, unsigned iRect) 135 { 136 unsigned i; 137 for (i = 0; i < nRects; i++) 138 { 139 if (paRects[iRect].right == paRects[i].left) 140 { 141 return i; 142 } 143 } 144 return ~0; 145 } 146 147 static unsigned nextAdjacentRectXN (RECTL *paRects, unsigned nRects, unsigned iRect) 148 { 149 unsigned i; 150 for (i = 0; i < nRects; i++) 151 { 152 if (paRects[iRect].left == paRects[i].right) 153 { 154 return i; 155 } 156 } 157 return ~0; 158 } 159 160 static unsigned nextAdjacentRectYP (RECTL *paRects, unsigned nRects, unsigned iRect) 161 { 162 unsigned i; 163 for (i = 0; i < nRects; i++) 164 { 165 if (paRects[iRect].bottom == paRects[i].top) 166 { 167 return i; 168 } 169 } 170 return ~0; 171 } 172 173 unsigned nextAdjacentRectYN (RECTL *paRects, unsigned nRects, unsigned iRect) 174 { 175 unsigned i; 176 for (i = 0; i < nRects; i++) 177 { 178 if (paRects[iRect].top == paRects[i].bottom) 179 { 180 return i; 181 } 182 } 183 return ~0; 184 } 185 186 void resizeRect(RECTL *paRects, unsigned nRects, unsigned iPrimary, unsigned iResized, int NewWidth, int NewHeight) 187 { 188 RECTL *paNewRects = (RECTL *)alloca (sizeof (RECTL) * nRects); 189 memcpy (paNewRects, paRects, sizeof (RECTL) * nRects); 190 paNewRects[iResized].right += NewWidth - (paNewRects[iResized].right - paNewRects[iResized].left); 191 paNewRects[iResized].bottom += NewHeight - (paNewRects[iResized].bottom - paNewRects[iResized].top); 192 193 /* Verify all pairs of originally adjacent rectangles for all 4 directions. 194 * If the pair has a "good" delta (that is the first rectangle intersects the second) 195 * at a direction and the second rectangle is not primary one (which can not be moved), 196 * move the second rectangle to make it adjacent to the first one. 197 */ 198 199 /* X positive. */ 200 unsigned iRect; 201 for (iRect = 0; iRect < nRects; iRect++) 202 { 203 /* Find the next adjacent original rect in x positive direction. */ 204 unsigned iNextRect = nextAdjacentRectXP (paRects, nRects, iRect); 205 Log(("next %d -> %d\n", iRect, iNextRect)); 206 207 if (iNextRect == ~0 || iNextRect == iPrimary) 208 { 209 continue; 210 } 211 212 /* Check whether there is an X intesection between these adjacent rects in the new rectangles 213 * and fix the intersection if delta is "good". 214 */ 215 int delta = paNewRects[iRect].right - paNewRects[iNextRect].left; 216 217 if (delta > 0) 218 { 219 Log(("XP intersection right %d left %d, diff %d\n", 220 paNewRects[iRect].right, paNewRects[iNextRect].left, 221 delta)); 222 223 paNewRects[iNextRect].left += delta; 224 paNewRects[iNextRect].right += delta; 225 } 226 } 227 228 /* X negative. */ 229 for (iRect = 0; iRect < nRects; iRect++) 230 { 231 /* Find the next adjacent original rect in x negative direction. */ 232 unsigned iNextRect = nextAdjacentRectXN (paRects, nRects, iRect); 233 Log(("next %d -> %d\n", iRect, iNextRect)); 234 235 if (iNextRect == ~0 || iNextRect == iPrimary) 236 { 237 continue; 238 } 239 240 /* Check whether there is an X intesection between these adjacent rects in the new rectangles 241 * and fix the intersection if delta is "good". 242 */ 243 int delta = paNewRects[iRect].left - paNewRects[iNextRect].right; 244 245 if (delta < 0) 246 { 247 Log(("XN intersection left %d right %d, diff %d\n", 248 paNewRects[iRect].left, paNewRects[iNextRect].right, 249 delta)); 250 251 paNewRects[iNextRect].left += delta; 252 paNewRects[iNextRect].right += delta; 253 } 254 } 255 256 /* Y positive (in the computer sence, top->down). */ 257 for (iRect = 0; iRect < nRects; iRect++) 258 { 259 /* Find the next adjacent original rect in y positive direction. */ 260 unsigned iNextRect = nextAdjacentRectYP (paRects, nRects, iRect); 261 Log(("next %d -> %d\n", iRect, iNextRect)); 262 263 if (iNextRect == ~0 || iNextRect == iPrimary) 264 { 265 continue; 266 } 267 268 /* Check whether there is an Y intesection between these adjacent rects in the new rectangles 269 * and fix the intersection if delta is "good". 270 */ 271 int delta = paNewRects[iRect].bottom - paNewRects[iNextRect].top; 272 273 if (delta > 0) 274 { 275 Log(("YP intersection bottom %d top %d, diff %d\n", 276 paNewRects[iRect].bottom, paNewRects[iNextRect].top, 277 delta)); 278 279 paNewRects[iNextRect].top += delta; 280 paNewRects[iNextRect].bottom += delta; 281 } 282 } 283 284 /* Y negative (in the computer sence, down->top). */ 285 for (iRect = 0; iRect < nRects; iRect++) 286 { 287 /* Find the next adjacent original rect in x negative direction. */ 288 unsigned iNextRect = nextAdjacentRectYN (paRects, nRects, iRect); 289 Log(("next %d -> %d\n", iRect, iNextRect)); 290 291 if (iNextRect == ~0 || iNextRect == iPrimary) 292 { 293 continue; 294 } 295 296 /* Check whether there is an Y intesection between these adjacent rects in the new rectangles 297 * and fix the intersection if delta is "good". 298 */ 299 int delta = paNewRects[iRect].top - paNewRects[iNextRect].bottom; 300 301 if (delta < 0) 302 { 303 Log(("YN intersection top %d bottom %d, diff %d\n", 304 paNewRects[iRect].top, paNewRects[iNextRect].bottom, 305 delta)); 306 307 paNewRects[iNextRect].top += delta; 308 paNewRects[iNextRect].bottom += delta; 309 } 310 } 311 312 memcpy (paRects, paNewRects, sizeof (RECTL) * nRects); 313 return; 314 } 315 316 /* Returns TRUE to try again. */ 317 static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel) 318 { 319 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0); 320 321 DISPLAY_DEVICE DisplayDevice; 322 323 ZeroMemory(&DisplayDevice, sizeof(DisplayDevice)); 324 DisplayDevice.cb = sizeof(DisplayDevice); 325 326 /* Find out how many display devices the system has */ 327 DWORD NumDevices = 0; 328 DWORD i = 0; 329 while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0)) 330 { 331 Log(("[%d] %s\n", i, DisplayDevice.DeviceName)); 332 333 if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) 334 { 335 Log(("Found primary device. err %d\n", GetLastError ())); 336 NumDevices++; 337 } 338 else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) 339 { 340 341 Log(("Found secondary device. err %d\n", GetLastError ())); 342 NumDevices++; 343 } 344 345 ZeroMemory(&DisplayDevice, sizeof(DisplayDevice)); 346 DisplayDevice.cb = sizeof(DisplayDevice); 347 i++; 348 } 349 350 Log(("Found total %d devices. err %d\n", NumDevices, GetLastError ())); 351 352 if (NumDevices == 0 || Id >= NumDevices) 353 { 354 Log(("Requested identifier %d is invalid. err %d\n", Id, GetLastError ())); 355 return FALSE; 356 } 357 358 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 359 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 360 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices); 361 362 /* Fetch information about current devices and modes. */ 363 DWORD DevNum = 0; 364 DWORD DevPrimaryNum = 0; 365 366 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 367 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 368 369 i = 0; 370 while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0)) 371 { 372 Log(("[%d(%d)] %s\n", i, DevNum, DisplayDevice.DeviceName)); 373 374 BOOL bFetchDevice = FALSE; 375 376 if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) 377 { 378 Log(("Found primary device. err %d\n", GetLastError ())); 379 DevPrimaryNum = DevNum; 380 bFetchDevice = TRUE; 381 } 382 else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) 383 { 384 385 Log(("Found secondary device. err %d\n", GetLastError ())); 386 bFetchDevice = TRUE; 387 } 388 389 if (bFetchDevice) 390 { 391 if (DevNum >= NumDevices) 392 { 393 Log(("%d >= %d\n", NumDevices, DevNum)); 394 return FALSE; 395 } 396 397 paDisplayDevices[DevNum] = DisplayDevice; 398 399 ZeroMemory(&paDeviceModes[DevNum], sizeof(DEVMODE)); 400 paDeviceModes[DevNum].dmSize = sizeof(DEVMODE); 401 if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName, 402 ENUM_REGISTRY_SETTINGS, &paDeviceModes[DevNum])) 403 { 404 Log(("EnumDisplaySettings err %d\n", GetLastError ())); 405 return FALSE; 406 } 407 408 Log(("%dx%d at %d,%d\n", 409 paDeviceModes[DevNum].dmPelsWidth, 410 paDeviceModes[DevNum].dmPelsHeight, 411 paDeviceModes[DevNum].dmPosition.x, 412 paDeviceModes[DevNum].dmPosition.y)); 413 414 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 415 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 416 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 417 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 418 DevNum++; 419 } 420 421 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 422 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 423 i++; 424 } 425 426 if (Width == 0) 427 { 428 Width = paRects[Id].right - paRects[Id].left; 429 } 430 431 if (Height == 0) 432 { 433 Height = paRects[Id].bottom - paRects[Id].top; 434 } 435 436 /* Check whether a mode reset or a change is requested. */ 437 if ( !fModeReset 438 && paRects[Id].right - paRects[Id].left == Width 439 && paRects[Id].bottom - paRects[Id].top == Height 440 && paDeviceModes[Id].dmBitsPerPel == BitsPerPixel) 441 { 442 Log(("VBoxDisplayThread : already at desired resolution.\n")); 443 return FALSE; 444 } 445 446 resizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height); 447 #ifdef Log 448 for (i = 0; i < NumDevices; i++) 449 { 450 Log(("[%d]: %d,%d %dx%d\n", 451 i, paRects[i].left, paRects[i].top, 452 paRects[i].right - paRects[i].left, 453 paRects[i].bottom - paRects[i].top)); 454 } 455 #endif /* Log */ 456 457 /* Without this, Windows will not ask the miniport for its 458 * mode table but uses an internal cache instead. 459 */ 460 DEVMODE tempDevMode; 461 ZeroMemory (&tempDevMode, sizeof (tempDevMode)); 462 tempDevMode.dmSize = sizeof(DEVMODE); 463 EnumDisplaySettings(NULL, 0xffffff, &tempDevMode); 464 465 /* Assign the new rectangles to displays. */ 466 for (i = 0; i < NumDevices; i++) 467 { 468 paDeviceModes[i].dmPosition.x = paRects[i].left; 469 paDeviceModes[i].dmPosition.y = paRects[i].top; 470 paDeviceModes[i].dmPelsWidth = paRects[i].right - paRects[i].left; 471 paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top; 472 473 paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH; 474 475 if ( i == Id 476 && BitsPerPixel != 0) 477 { 478 paDeviceModes[i].dmFields |= DM_BITSPERPEL; 479 paDeviceModes[i].dmBitsPerPel = BitsPerPixel; 480 } 481 Log(("calling pfnChangeDisplaySettingsEx %x\n", gpfnChangeDisplaySettingsEx)); 482 gpfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName, 483 &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL); 484 Log(("ChangeDisplaySettings position err %d\n", GetLastError ())); 485 } 486 487 /* A second call to ChangeDisplaySettings updates the monitor. */ 488 LONG status = ChangeDisplaySettings(NULL, 0); 489 Log(("ChangeDisplaySettings update status %d\n", status)); 490 if (status == DISP_CHANGE_SUCCESSFUL || status == DISP_CHANGE_BADMODE) 491 { 492 /* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */ 493 return FALSE; 494 } 495 496 /* Retry the request. */ 497 return TRUE; 498 } 499 500 int handleSetVideoMode(int argc, char *argv[]) 501 { 502 if (argc != 3 && argc != 4) 503 { 504 usage(SET_VIDEO_MODE); 505 return 1; 506 } 507 508 DWORD xres = atoi(argv[0]); 509 DWORD yres = atoi(argv[1]); 510 DWORD bpp = atoi(argv[2]); 511 DWORD scr = 0; 512 513 if (argc == 4) 514 { 515 scr = atoi(argv[3]); 516 } 517 518 HMODULE hUser = GetModuleHandle("USER32"); 519 520 if (hUser) 521 { 522 *(uintptr_t *)&gpfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA"); 523 Log(("VBoxService: pChangeDisplaySettingsEx = %p\n", gpfnChangeDisplaySettingsEx)); 524 525 if (gpfnChangeDisplaySettingsEx) 526 { 527 /* The screen index is 0 based in the ResizeDisplayDevice call. */ 528 scr = scr > 0? scr - 1: 0; 529 530 /* Horizontal resolution must be a multiple of 8, round down. */ 531 xres &= ~0x7; 532 533 ResizeDisplayDevice(scr, xres, yres, bpp); 534 } 535 } 536 return 0; 537 } 538 539 HKEY getVideoKey(bool writable) 540 { 541 HKEY hkeyDeviceMap = 0; 542 HKEY hkeyVideo = 0; 543 LONG status; 544 545 status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkeyDeviceMap); 546 if ((status != ERROR_SUCCESS) || !hkeyDeviceMap) 547 { 548 VBoxControlError("Error opening video device map registry key!\n"); 549 return 0; 550 } 551 char szVideoLocation[256]; 552 DWORD dwKeyType; 553 szVideoLocation[0] = 0; 554 DWORD len = sizeof(szVideoLocation); 555 status = RegQueryValueExA(hkeyDeviceMap, "\\Device\\Video0", NULL, &dwKeyType, (LPBYTE)szVideoLocation, &len); 556 /* 557 * This value will start with a weird value: \REGISTRY\Machine 558 * Make sure this is true. 559 */ 560 if ( (status == ERROR_SUCCESS) 561 && (dwKeyType == REG_SZ) 562 && (_strnicmp(szVideoLocation, "\\REGISTRY\\Machine", 17) == 0)) 563 { 564 /* open that branch */ 565 status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, &szVideoLocation[18], 0, KEY_READ | (writable ? KEY_WRITE : 0), &hkeyVideo); 566 } 567 else 568 { 569 VBoxControlError("Error opening registry key '%s'\n", &szVideoLocation[18]); 570 } 571 RegCloseKey(hkeyDeviceMap); 572 return hkeyVideo; 573 } 574 575 int handleGetVideoAcceleration(int argc, char *argv[]) 576 { 577 ULONG status; 578 HKEY hkeyVideo = getVideoKey(false); 579 580 if (hkeyVideo) 581 { 582 /* query the actual value */ 583 DWORD fAcceleration = 1; 584 DWORD len = sizeof(fAcceleration); 585 DWORD dwKeyType; 586 status = RegQueryValueExA(hkeyVideo, "EnableVideoAccel", NULL, &dwKeyType, (LPBYTE)&fAcceleration, &len); 587 if (status != ERROR_SUCCESS) 588 RTPrintf("Video acceleration: default\n"); 589 else 590 RTPrintf("Video acceleration: %s\n", fAcceleration ? "on" : "off"); 591 RegCloseKey(hkeyVideo); 592 } 593 return 0; 594 } 595 596 int handleSetVideoAcceleration(int argc, char *argv[]) 597 { 598 ULONG status; 599 HKEY hkeyVideo; 600 601 /* must have exactly one argument: the new offset */ 602 if ( (argc != 1) 603 || ( strcmp(argv[0], "on") 604 && strcmp(argv[0], "off"))) 605 { 606 usage(SET_VIDEO_ACCEL); 607 return 1; 608 } 609 610 hkeyVideo = getVideoKey(true); 611 612 if (hkeyVideo) 613 { 614 int fAccel = 0; 615 if (!strcmp(argv[0], "on")) 616 fAccel = 1; 617 /* set a new value */ 618 status = RegSetValueExA(hkeyVideo, "EnableVideoAccel", 0, REG_DWORD, (LPBYTE)&fAccel, sizeof(fAccel)); 619 if (status != ERROR_SUCCESS) 620 { 621 VBoxControlError("Error %d writing video acceleration status!\n", status); 622 } 623 RegCloseKey(hkeyVideo); 624 } 625 return 0; 626 } 627 628 #define MAX_CUSTOM_MODES 128 629 630 /* the table of custom modes */ 631 struct 632 { 633 DWORD xres; 634 DWORD yres; 635 DWORD bpp; 636 } customModes[MAX_CUSTOM_MODES] = {0}; 637 638 void getCustomModes(HKEY hkeyVideo) 639 { 640 ULONG status; 641 int curMode = 0; 642 643 /* null out the table */ 644 memset(customModes, 0, sizeof(customModes)); 645 646 do 647 { 648 char valueName[20]; 649 DWORD xres, yres, bpp = 0; 650 DWORD dwType; 651 DWORD dwLen = sizeof(DWORD); 652 653 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", curMode); 654 status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&xres, &dwLen); 655 if (status != ERROR_SUCCESS) 656 break; 657 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", curMode); 658 status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&yres, &dwLen); 659 if (status != ERROR_SUCCESS) 660 break; 661 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", curMode); 662 status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&bpp, &dwLen); 663 if (status != ERROR_SUCCESS) 664 break; 665 666 /* check if the mode is OK */ 667 if ( (xres > (1 << 16)) 668 && (yres > (1 << 16)) 669 && ( (bpp != 16) 670 || (bpp != 24) 671 || (bpp != 32))) 672 break; 673 674 /* add mode to table */ 675 customModes[curMode].xres = xres; 676 customModes[curMode].yres = yres; 677 customModes[curMode].bpp = bpp; 678 679 ++curMode; 680 681 if (curMode >= MAX_CUSTOM_MODES) 682 break; 683 } while(1); 684 } 685 686 void writeCustomModes(HKEY hkeyVideo) 687 { 688 ULONG status; 689 int tableIndex = 0; 690 int modeIndex = 0; 691 692 /* first remove all values */ 693 for (int i = 0; i < MAX_CUSTOM_MODES; i++) 694 { 695 char valueName[20]; 696 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", i); 697 RegDeleteValueA(hkeyVideo, valueName); 698 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", i); 699 RegDeleteValueA(hkeyVideo, valueName); 700 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", i); 701 RegDeleteValueA(hkeyVideo, valueName); 702 } 703 704 do 705 { 706 if (tableIndex >= MAX_CUSTOM_MODES) 707 break; 708 709 /* is the table entry present? */ 710 if ( (!customModes[tableIndex].xres) 711 || (!customModes[tableIndex].yres) 712 || (!customModes[tableIndex].bpp)) 713 { 714 tableIndex++; 715 continue; 716 } 717 718 RTPrintf("writing mode %d (%dx%dx%d)\n", modeIndex, customModes[tableIndex].xres, customModes[tableIndex].yres, customModes[tableIndex].bpp); 719 char valueName[20]; 720 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", modeIndex); 721 status = RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].xres, 722 sizeof(customModes[tableIndex].xres)); 723 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", modeIndex); 724 RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].yres, 725 sizeof(customModes[tableIndex].yres)); 726 RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", modeIndex); 727 RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].bpp, 728 sizeof(customModes[tableIndex].bpp)); 729 730 modeIndex++; 731 tableIndex++; 732 733 } while(1); 734 735 } 736 737 int handleListCustomModes(int argc, char *argv[]) 738 { 739 if (argc != 0) 740 { 741 usage(LIST_CUST_MODES); 742 return 1; 743 } 744 745 HKEY hkeyVideo = getVideoKey(false); 746 747 if (hkeyVideo) 748 { 749 getCustomModes(hkeyVideo); 750 for (int i = 0; i < (sizeof(customModes) / sizeof(customModes[0])); i++) 751 { 752 if ( !customModes[i].xres 753 || !customModes[i].yres 754 || !customModes[i].bpp) 755 continue; 756 757 RTPrintf("Mode: %d x %d x %d\n", 758 customModes[i].xres, customModes[i].yres, customModes[i].bpp); 759 } 760 RegCloseKey(hkeyVideo); 761 } 762 return 0; 763 } 764 765 int handleAddCustomMode(int argc, char *argv[]) 766 { 767 if (argc != 3) 768 { 769 usage(ADD_CUST_MODE); 770 return 1; 771 } 772 773 DWORD xres = atoi(argv[0]); 774 DWORD yres = atoi(argv[1]); 775 DWORD bpp = atoi(argv[2]); 776 777 /** @todo better check including xres mod 8 = 0! */ 778 if ( (xres > (1 << 16)) 779 && (yres > (1 << 16)) 780 && ( (bpp != 16) 781 || (bpp != 24) 782 || (bpp != 32))) 783 { 784 VBoxControlError("Error: invalid mode specified!\n"); 785 return 1; 786 } 787 788 HKEY hkeyVideo = getVideoKey(true); 789 790 if (hkeyVideo) 791 { 792 int i; 793 int fModeExists = 0; 794 getCustomModes(hkeyVideo); 795 for (i = 0; i < MAX_CUSTOM_MODES; i++) 796 { 797 /* mode exists? */ 798 if ( customModes[i].xres == xres 799 && customModes[i].yres == yres 800 && customModes[i].bpp == bpp 801 ) 802 { 803 fModeExists = 1; 804 } 805 } 806 if (!fModeExists) 807 { 808 for (i = 0; i < MAX_CUSTOM_MODES; i++) 809 { 810 /* item free? */ 811 if (!customModes[i].xres) 812 { 813 customModes[i].xres = xres; 814 customModes[i].yres = yres; 815 customModes[i].bpp = bpp; 816 break; 817 } 818 } 819 writeCustomModes(hkeyVideo); 820 } 821 RegCloseKey(hkeyVideo); 822 } 823 return 0; 824 } 825 826 int handleRemoveCustomMode(int argc, char *argv[]) 827 { 828 if (argc != 3) 829 { 830 usage(REMOVE_CUST_MODE); 831 return 1; 832 } 833 834 DWORD xres = atoi(argv[0]); 835 DWORD yres = atoi(argv[1]); 836 DWORD bpp = atoi(argv[2]); 837 838 HKEY hkeyVideo = getVideoKey(true); 839 840 if (hkeyVideo) 841 { 842 getCustomModes(hkeyVideo); 843 for (int i = 0; i < MAX_CUSTOM_MODES; i++) 844 { 845 /* correct item? */ 846 if ( (customModes[i].xres == xres) 847 && (customModes[i].yres == yres) 848 && (customModes[i].bpp == bpp)) 849 { 850 RTPrintf("found mode at index %d\n", i); 851 memset(&customModes[i], 0, sizeof(customModes[i])); 852 break; 853 } 854 } 855 writeCustomModes(hkeyVideo); 856 RegCloseKey(hkeyVideo); 857 } 858 } 859 860 #endif /* RT_OS_WINDOWS */ 861 862 #ifdef VBOX_WITH_GUEST_PROPS 104 863 /** 105 * Retrieves a value from the host/guest configuration registry.106 * This is accessed through the "VBox SharedInfoSvc" HGCM service.864 * Retrieves a value from the guest property store. 865 * This is accessed through the "VBoxGuestPropSvc" HGCM service. 107 866 * 108 867 * @returns 0 on success, 1 on failure 109 * @param key (string) the key which the value is stored under.868 * @param name (string) the name of the property. 110 869 */ 111 870 int getGuestProperty(int argc, char **argv) 112 871 { 113 using namespace svcInfo; 872 using namespace guestProp; 873 874 if (argc != 1) 875 { 876 usage(GET_GUEST_PROP); 877 return 1; 878 } 114 879 115 880 uint32_t u32ClientID = 0; 116 881 int rc = VINF_SUCCESS; 117 char *pszKey = NULL; 118 char szValue[KEY_MAX_VALUE_LEN]; 119 120 if (argc != 1) 121 { 122 usage(GET_GUEST_PROP); 123 return 1; 124 } 125 rc = RTStrCurrentCPToUtf8(&pszKey, argv[0]); 882 char *pszName = argv[0]; 883 char *pszValue = NULL; 884 885 rc = VbglR3GuestPropConnect(&u32ClientID); 126 886 if (!RT_SUCCESS(rc)) 127 VBoxControlError("Failed to con vert the key name to Utf8, error %Rrc\n", rc);887 VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc); 128 888 if (RT_SUCCESS(rc)) 129 889 { 130 rc = VbglR3InfoSvcConnect(&u32ClientID); 131 if (!RT_SUCCESS(rc)) 132 VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc); 133 } 134 if (RT_SUCCESS(rc)) 135 { 136 rc = VbglR3InfoSvcReadKey(u32ClientID, argv[0], szValue, sizeof(szValue), NULL); 890 rc = VbglR3GuestPropReadValueAlloc(u32ClientID, pszName, &pszValue); 137 891 if (!RT_SUCCESS(rc) && (rc != VERR_NOT_FOUND)) 138 892 VBoxControlError("Failed to retrieve the property value, error %Rrc\n", rc); … … 141 895 RTPrintf("No value set!\n"); 142 896 if (RT_SUCCESS(rc)) 143 RTPrintf("Value: %S\n", szValue);897 RTPrintf("Value: %S\n", pszValue); 144 898 if (u32ClientID != 0) 145 VbglR3 InfoSvcDisconnect(u32ClientID);146 RTStrFree(pszKey);899 VbglR3GuestPropDisconnect(u32ClientID); 900 VbglR3GuestPropReadValueFree(pszValue); 147 901 return RT_SUCCESS(rc) ? 0 : 1; 148 902 } … … 150 904 151 905 /** 152 * Writes a value to the host/guest configuration registry.153 * This is accessed through the "VBox SharedInfoSvc" HGCM service.906 * Writes a value to the guest property store. 907 * This is accessed through the "VBoxGuestPropSvc" HGCM service. 154 908 * 155 909 * @returns 0 on success, 1 on failure 156 * @param key (string) the key which the value is stored under.157 * @param value (string) the value to write. If empty, the key will be910 * @param name (string) the name of the property. 911 * @param value (string) the value to write. If empty, the property will be 158 912 * removed. 159 913 */ 160 914 static int setGuestProperty(int argc, char *argv[]) 161 915 { 916 if (argc != 1 && argc != 2) 917 { 918 usage(SET_GUEST_PROP); 919 return 1; 920 } 921 162 922 uint32_t u32ClientID = 0; 163 923 int rc = VINF_SUCCESS; 164 char *psz Key = NULL;924 char *pszName = argv[0]; 165 925 char *pszValue = NULL; 166 167 if (argc != 1 && argc != 2) 168 { 169 usage(); 170 return 1; 171 } 172 rc = RTStrCurrentCPToUtf8(&pszKey, argv[0]); 926 if (2 == argc) 927 pszValue = argv[1]; 928 929 rc = VbglR3GuestPropConnect(&u32ClientID); 173 930 if (!RT_SUCCESS(rc)) 174 VBoxControlError("Failed to convert the key name to Utf8, error %Rrc\n", rc); 175 if (RT_SUCCESS(rc) && (2 == argc)) 176 { 177 rc = RTStrCurrentCPToUtf8(&pszValue, argv[1]); 178 if (!RT_SUCCESS(rc)) 179 VBoxControlError("Failed to convert the key value to Utf8, error %Rrc\n", rc); 180 } 931 VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc); 181 932 if (RT_SUCCESS(rc)) 182 933 { 183 rc = VbglR3InfoSvcConnect(&u32ClientID); 184 if (!RT_SUCCESS(rc)) 185 VBoxControlError("Failed to connect to the host/guest registry service, error %Rrc\n", rc); 186 } 187 if (RT_SUCCESS(rc)) 188 { 189 rc = VbglR3InfoSvcWriteKey(u32ClientID, argv[0], pszValue); 934 rc = VbglR3GuestPropWriteValue(u32ClientID, pszName, pszValue); 190 935 if (!RT_SUCCESS(rc)) 191 936 VBoxControlError("Failed to store the property value, error %Rrc\n", rc); 192 937 } 193 938 if (u32ClientID != 0) 194 VbglR3InfoSvcDisconnect(u32ClientID); 195 RTStrFree(pszKey); 196 RTStrFree(pszValue); 939 VbglR3GuestPropDisconnect(u32ClientID); 197 940 return RT_SUCCESS(rc) ? 0 : 1; 198 941 } … … 210 953 } g_commandHandlers[] = 211 954 { 212 #ifdef VBOX_WITH_INFO_SVC 955 #ifdef RT_OS_WINDOWS 956 { "getvideoacceleration", handleGetVideoAcceleration }, 957 { "setvideoacceleration", handleSetVideoAcceleration }, 958 { "listcustommodes", handleListCustomModes }, 959 { "addcustommode", handleAddCustomMode }, 960 { "removecustommode", handleRemoveCustomMode }, 961 { "setvideomode", handleSetVideoMode }, 962 #endif 963 #ifdef VBOX_WITH_GUEST_PROPS 213 964 { "getguestproperty", getGuestProperty }, 214 965 { "setguestproperty", setGuestProperty }, … … 243 994 if ( (0 == strcmp(argv[iArg], "-v")) 244 995 || (0 == strcmp(argv[iArg], "--version")) 996 || (0 == strcmp(argv[iArg], "-version")) 997 || (0 == strcmp(argv[iArg], "getversion")) 245 998 ) 246 999 { … … 311 1064 if (!onlyinfo && (0 == rc)) 312 1065 { 1066 /* 1067 * The input is in the guest OS'es codepage (NT guarantees ACP). 1068 * For VBox we use UTF-8. For simplicity, just convert the argv[] array 1069 * here. 1070 */ 1071 for (int i = iArg; i < argc; i++) 1072 { 1073 char *converted; 1074 RTStrCurrentCPToUtf8(&converted, argv[i]); 1075 argv[i] = converted; 1076 } 1077 313 1078 if (argc > iArg) 314 1079 { … … 340 1105 usage(); 341 1106 } 1107 1108 /* 1109 * Free converted argument vector 1110 */ 1111 for (int i = iArg; i < argc; i++) 1112 RTStrFree(argv[i]); 1113 342 1114 } 343 1115 -
trunk/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
r10719 r10797 86 86 VBoxGuestR3Lib_DEFS = \ 87 87 VBOX_HGCM \ 88 $(if $(VBOX_WITH_ INFO_SVC),VBOX_WITH_INFO_SVC,)88 $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) 89 89 VBoxGuestR3Lib_SOURCES = \ 90 90 VBoxGuestR3Lib.cpp \ … … 92 92 VBoxGuestR3LibDaemonize.cpp \ 93 93 VBoxGuestR3LibGR.cpp \ 94 $(if $(VBOX_WITH_ INFO_SVC),VBoxGuestR3LibInfoSvc.cpp,) \94 $(if $(VBOX_WITH_GUEST_PROPS),VBoxGuestR3LibGuestProp.cpp,) \ 95 95 VBoxGuestR3LibMouse.cpp \ 96 96 VBoxGuestR3LibMisc.cpp \ … … 102 102 VBoxGuestR3Lib.cpp \ 103 103 VBoxGuestR3LibGR.cpp \ 104 $(if $(VBOX_WITH_ INFO_SVC),VBoxGuestR3LibInfoSvc.cpp,) \104 $(if $(VBOX_WITH_GUEST_PROPS),VBoxGuestR3LibGuestProp.cpp,) \ 105 105 VBoxGuestR3LibMisc.cpp 106 106 endif … … 124 124 VBoxGuestR3LibXFree86_DEFS = \ 125 125 VBOX_HGCM VBOX_VBGLR3_XFREE86 \ 126 $(if $(VBOX_WITH_ INFO_SVC),VBOX_WITH_INFO_SVC,)126 $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) 127 127 VBoxGuestR3LibXFree86_SOURCES = \ 128 128 VBoxGuestR3Lib.cpp \ 129 129 VBoxGuestR3LibGR.cpp \ 130 $(if $(VBOX_WITH_ INFO_SVC),VBoxGuestR3LibInfoSvc.cpp,) \130 $(if $(VBOX_WITH_GUEST_PROPS),VBoxGuestR3LibGuestProp.cpp,) \ 131 131 VBoxGuestR3LibMouse.cpp \ 132 132 VBoxGuestR3LibMisc.cpp \ -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
r9536 r10797 56 56 57 57 58 DECLINLINE(void) VbglHGCMParmUInt64Set(HGCMFunctionParameter *pParm, uint64_t u64) 59 { 60 pParm->type = VMMDevHGCMParmType_64bit; 61 pParm->u.value64 = u64; 62 } 63 64 65 DECLINLINE(int) VbglHGCMParmUInt64Get(HGCMFunctionParameter *pParm, uint64_t *pu64) 66 { 67 if (pParm->type == VMMDevHGCMParmType_64bit) 68 { 69 *pu64 = pParm->u.value64; 70 return VINF_SUCCESS; 71 } 72 return VERR_INVALID_PARAMETER; 73 } 74 75 58 76 DECLINLINE(void) VbglHGCMParmPtrSet(HGCMFunctionParameter *pParm, void *pv, uint32_t cb) 59 77 { -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
r10683 r10797 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, information service. 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, 4 * guest properties. 4 5 */ 5 6 … … 28 29 #include <iprt/assert.h> 29 30 #include <VBox/log.h> 30 #include <VBox/HostServices/ VBoxInfoSvc.h> /* For Save and RetrieveVideoMode */31 #include <VBox/HostServices/GuestPropertySvc.h> 31 32 32 33 #include "VBGLR3Internal.h" 33 34 34 using namespace svcInfo;35 36 /** 37 * Connects to the informationservice.35 using namespace guestProp; 36 37 /** 38 * Connects to the guest property service. 38 39 * 39 40 * @returns VBox status code … … 41 42 * must be passed to all the other calls to the service. 42 43 */ 43 VBGLR3DECL(int) VbglR3 InfoSvcConnect(uint32_t *pu32ClientId)44 VBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId) 44 45 { 45 46 VBoxGuestHGCMConnectInfo Info; … … 47 48 Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing; 48 49 memset(&Info.Loc.u, 0, sizeof(Info.Loc.u)); 49 strcpy(Info.Loc.u.host.achName, "VBox SharedInfoSvc");50 strcpy(Info.Loc.u.host.achName, "VBoxGuestPropSvc"); 50 51 Info.u32ClientID = UINT32_MAX; /* try make valgrid shut up. */ 51 52 … … 62 63 63 64 /** 64 * Disconnect from the informationservice.65 * Disconnect from the guest property service. 65 66 * 66 67 * @returns VBox status code. 67 68 * @param u32ClientId The client id returned by VbglR3InfoSvcConnect(). 68 69 */ 69 VBGLR3DECL(int) VbglR3 InfoSvcDisconnect(uint32_t u32ClientId)70 VBGLR3DECL(int) VbglR3GuestPropDisconnect(uint32_t u32ClientId) 70 71 { 71 72 VBoxGuestHGCMDisconnectInfo Info; … … 81 82 82 83 /** 83 * Write a key value.84 * Write a property value. 84 85 * 85 86 * @returns VBox status code. 86 87 * @param u32ClientId The client id returned by VbglR3InvsSvcConnect(). 87 * @param psz Key The key to save to. Utf888 * @param pszName The property to save to. Utf8 88 89 * @param pszValue The value to store. Utf8. If this is NULL then 89 * the key will be removed. 90 */ 91 VBGLR3DECL(int) VbglR3InfoSvcWriteKey(uint32_t u32ClientId, char *pszKey, char *pszValue) 90 * the property will be removed. 91 * @param pszFlags The flags for the property 92 */ 93 VBGLR3DECL(int) VbglR3GuestPropWrite(uint32_t u32ClientId, char *pszName, char *pszValue, char *pszFlags) 92 94 { 93 95 int rc; … … 95 97 if (pszValue != NULL) 96 98 { 97 Set ConfigKey Msg;99 SetProperty Msg; 98 100 99 101 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 100 102 Msg.hdr.u32ClientID = u32ClientId; 101 Msg.hdr.u32Function = SET_ CONFIG_KEY;103 Msg.hdr.u32Function = SET_PROP_VALUE; 102 104 Msg.hdr.cParms = 2; 103 VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1); 105 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 106 VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1); 107 VbglHGCMParmPtrSet(&Msg.flags, pszFlags, strlen(pszFlags) + 1); 108 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 109 if (RT_SUCCESS(rc)) 110 rc = Msg.hdr.result; 111 } 112 else 113 { 114 DelProperty Msg; 115 116 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 117 Msg.hdr.u32ClientID = u32ClientId; 118 Msg.hdr.u32Function = DEL_PROP; 119 Msg.hdr.cParms = 1; 120 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 121 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 122 if (RT_SUCCESS(rc)) 123 rc = Msg.hdr.result; 124 } 125 return rc; 126 } 127 128 129 /** 130 * Write a property value. 131 * 132 * @returns VBox status code. 133 * @param u32ClientId The client id returned by VbglR3InvsSvcConnect(). 134 * @param pszName The property to save to. Utf8 135 * @param pszValue The value to store. Utf8. If this is NULL then 136 * the property will be removed. 137 * @note if the property already exists and pszValue is not NULL then the 138 * property's flags field will be left unchanged 139 */ 140 VBGLR3DECL(int) VbglR3GuestPropWriteValue(uint32_t u32ClientId, char *pszName, char *pszValue) 141 { 142 int rc; 143 144 if (pszValue != NULL) 145 { 146 SetPropertyValue Msg; 147 148 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 149 Msg.hdr.u32ClientID = u32ClientId; 150 Msg.hdr.u32Function = SET_PROP_VALUE; 151 Msg.hdr.cParms = 2; 152 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 104 153 VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1); 105 154 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); … … 109 158 else 110 159 { 111 Del ConfigKey Msg;160 DelProperty Msg; 112 161 113 162 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 114 163 Msg.hdr.u32ClientID = u32ClientId; 115 Msg.hdr.u32Function = DEL_ CONFIG_KEY;164 Msg.hdr.u32Function = DEL_PROP; 116 165 Msg.hdr.cParms = 1; 117 VbglHGCMParmPtrSet(&Msg. key, pszKey, strlen(pszKey) + 1);166 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 118 167 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 119 168 if (RT_SUCCESS(rc)) … … 125 174 126 175 /** 127 * Retrieve a key value. 128 * 129 * @returns VBox status code. 130 * @retval VINF_SUCCESS on success, pszValue and pcbActual containing valid data. 131 * @retval VERR_BUFFER_OVERFLOW if the buffer is too small, pcbActual will contain 132 * the require buffer size. Note race condition here when retrying wrt 133 * someone updating it. 176 * Retrieve a property. 177 * 178 * @returns VBox status code. 179 * @retval VINF_SUCCESS on success, pszValue, pu64Timestamp and pszFlags 180 * containing valid data. 181 * @retval VERR_BUFFER_OVERFLOW if the scratch buffer @a pcBuf is not large 182 * enough. In this case the size needed will be placed in 183 * @a pcbBufActual if it is not NULL. 134 184 * @retval VERR_NOT_FOUND if the key wasn't found. 135 185 * 136 186 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). 137 * @param pszKey The key to read. Utf8 138 * @param pszValue Where to store the value retrieved. Utf8. 139 * @param cbValue The size of the buffer pszValue points to. 140 * @param pcbActual Where to store the required buffer size if cbValue 141 * is too small. On success this contains the 142 * actual size of the value retrieved. Optional. 143 */ 144 VBGLR3DECL(int) VbglR3InfoSvcReadKey(uint32_t u32ClientId, char *pszKey, 145 char *pszValue, uint32_t cbValue, uint32_t *pcbActual) 146 { 147 GetConfigKey Msg; 187 * @param pszName The value to read. Utf8 188 * @param pcBuf A scratch buffer to store the data retrieved into. 189 * The returned data is only valid for it's lifetime. 190 * @param cbBuf The size of @a pcBuf 191 * @param pszValue Where to store the pointer to the value retrieved. 192 * @param pu64Timestamp Where to store the timestamp. Optional. 193 * @param pszFlags Where to store the pointer to the flags. Optional. 194 * @param pcbBufActual If @a pcBuf is not large enough, the size needed. 195 * Optional. 196 */ 197 VBGLR3DECL(int) VbglR3GuestPropRead(uint32_t u32ClientId, const char *pszName, 198 void *pvBuf, uint32_t cbBuf, 199 char **ppszValue, uint64_t *pu64Timestamp, 200 char **ppszFlags, 201 uint32_t *pcbBufActual) 202 { 203 GetProperty Msg; 148 204 149 205 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 150 206 Msg.hdr.u32ClientID = u32ClientId; 151 Msg.hdr.u32Function = GET_CONFIG_KEY; 152 Msg.hdr.cParms = 3; 153 VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1); 154 VbglHGCMParmPtrSet(&Msg.value, pszValue, cbValue); 207 Msg.hdr.u32Function = GET_PROP; 208 Msg.hdr.cParms = 4; 209 VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName), 210 strlen(pszName) + 1); 211 VbglHGCMParmPtrSet(&Msg.buffer, pvBuf, cbBuf); 212 VbglHGCMParmUInt64Set(&Msg.timestamp, 0); 155 213 VbglHGCMParmUInt32Set(&Msg.size, 0); 156 214 … … 158 216 if (RT_SUCCESS(rc)) 159 217 rc = Msg.hdr.result; 160 uint32_t cbActual; 161 if (RT_SUCCESS(rc) || (VERR_BUFFER_OVERFLOW == rc)) 162 { 163 int rc2 = VbglHGCMParmUInt32Get(&Msg.size, &cbActual); 164 if (RT_SUCCESS(rc2)) 218 if ((VERR_BUFFER_OVERFLOW == rc) && (pcbBufActual != NULL)) 219 { 220 int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual); 221 if (!RT_SUCCESS(rc2)) 222 rc = rc2; 223 } 224 if (RT_SUCCESS(rc) && (pu64Timestamp != NULL)) 225 rc = VbglHGCMParmUInt64Get(&Msg.timestamp, pu64Timestamp); 226 if (RT_SUCCESS(rc)) 227 *ppszValue = reinterpret_cast<char *>(pvBuf); 228 if (RT_SUCCESS(rc) && (ppszFlags != NULL)) 229 { 230 bool found = false; 231 size_t i = 0; 232 char *pcBuf = reinterpret_cast<char *>(pvBuf); 233 for (; i < cbBuf && !found; ++i) 234 if (0 == pcBuf[i]) 235 found = true; 236 if (!found) 237 /* To my mind this is an internal error, but whatever */ 238 rc = VERR_TOO_MUCH_DATA; 239 else 240 *ppszFlags = pcBuf + i; 241 } 242 return rc; 243 } 244 245 246 /** 247 * Retrieve a property value, allocating space for it. 248 * 249 * @returns VBox status code. 250 * @retval VINF_SUCCESS on success, pszValue containing valid data. 251 * @retval VERR_NOT_FOUND if the key wasn't found. 252 * 253 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). 254 * @param pszName The value to read. Utf8 255 * @param ppszValue Where to store the pointer to the value returned. 256 */ 257 VBGLR3DECL(int) VbglR3GuestPropReadValueAlloc(uint32_t u32ClientId, 258 const char *pszName, 259 char **ppszValue) 260 { 261 int rc = VINF_SUCCESS; 262 uint32_t cchBuf = 1024; 263 void *pvBuf = RTMemAlloc(cchBuf); 264 char *pszValue = NULL; 265 if (NULL == pvBuf) 266 rc = VERR_NO_MEMORY; 267 if (RT_SUCCESS(rc)) 268 { 269 rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf, 270 &pszValue, NULL, NULL, &cchBuf); 271 if (VERR_BUFFER_OVERFLOW == rc) 165 272 { 166 if (pcbActual != NULL) 167 *pcbActual = cbActual; 273 /** @todo how should we handle the race condition here? */ 274 pvBuf = RTMemRealloc(pvBuf, cchBuf); 275 if (pvBuf != NULL) 276 rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf, 277 &pszValue, NULL, NULL, NULL); 278 else 279 rc = VERR_NO_MEMORY; 280 if (VERR_BUFFER_OVERFLOW == rc) 281 /* VERR_BUFFER_OVERFLOW has a different meaning here as a 282 * return code */ 283 rc = VERR_TOO_MUCH_DATA; 168 284 } 169 else 170 rc = rc2; 171 } 172 return rc; 173 } 285 } 286 if (RT_SUCCESS(rc)) 287 *ppszValue = pszValue; 288 return rc; 289 } 290 291 /** 292 * Free the memory used by VbglR3GuestPropReadValueAlloc for returning a 293 * value. 294 * 295 * @param pszValue the memory to be freed. NULL pointers will be ignored. 296 */ 297 VBGLR3DECL(void) VbglR3GuestPropReadValueFree(char *pszValue) 298 { 299 RTMemFree(pszValue); 300 } 301 302 303 /** 304 * Retrieve a property value, using a user-provided buffer to store it. 305 * 306 * @returns VBox status code. 307 * @retval VINF_SUCCESS on success, pszValue containing valid data. 308 * @retval VERR_BUFFER_OVERFLOW and the size needed in pcchValueActual if the 309 * buffer provided was too small 310 * @retval VERR_NOT_FOUND if the key wasn't found. 311 * 312 * @note There is a race here between obtaining the size of the buffer 313 * needed to hold the value and the value being updated. 314 * 315 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). 316 * @param pszName The value to read. Utf8 317 * @param pszValue Where to store the value retrieved. 318 * @param cchValue The size of the buffer pointed to by @a pszValue 319 * @param pcchValueActual Where to store the size of the buffer needed if 320 * the buffer supplied is too small. Optional. 321 */ 322 VBGLR3DECL(int) VbglR3GuestPropReadValue(uint32_t u32ClientId, const char *pszName, 323 char *pszValue, uint32_t cchValue, 324 uint32_t *pcchValueActual) 325 { 326 char *pcBuf = NULL; 327 int rc = VbglR3GuestPropReadValueAlloc(u32ClientId, pszName, &pcBuf); 328 if (RT_SUCCESS(rc)) 329 { 330 uint32_t cchValueActual = strlen(pcBuf) + 1; 331 if (cchValueActual > cchValue) 332 { 333 if (pcchValueActual != NULL) 334 *pcchValueActual = cchValueActual; 335 rc = VERR_BUFFER_OVERFLOW; 336 } 337 if (RT_SUCCESS(rc)) 338 strcpy(pszValue, pcBuf); 339 } 340 VbglR3GuestPropReadValueFree(pcBuf); 341 return rc; 342 } -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp
r10236 r10797 28 28 #include <iprt/assert.h> 29 29 #include <VBox/log.h> 30 #include <VBox/HostServices/ VBoxInfoSvc.h> /* For Save and RetrieveVideoMode */30 #include <VBox/HostServices/GuestPropertySvc.h> /* For Save and RetrieveVideoMode */ 31 31 32 32 #include "VBGLR3Internal.h" 33 33 34 #define VIDEO_PROP_PREFIX "/VirtualBox/GuestAdd/Vbgl/Video/" 34 35 35 36 /** … … 228 229 if (RT_SUCCESS(rc) && RT_SUCCESS(req.header.rc)) 229 230 fRc = req.fSupported; 230 else231 LogRelFunc(("error querying video mode supported status from VMMDev."232 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req.header.rc));233 231 return fRc; 234 232 } … … 245 243 VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t cy, uint32_t cBits) 246 244 { 247 #ifdef VBOX_WITH_ INFO_SVC248 using namespace svcInfo;249 250 char szModeName[ KEY_MAX_LEN];251 char szModeParms[ KEY_MAX_VALUE_LEN];245 #ifdef VBOX_WITH_GUEST_PROPS 246 using namespace guestProp; 247 248 char szModeName[MAX_NAME_LEN]; 249 char szModeParms[MAX_VALUE_LEN]; 252 250 uint32_t u32ClientId = 0; 253 RTStrPrintf(szModeName, sizeof(szModeName), "VideoMode/%s", pszName);251 RTStrPrintf(szModeName, sizeof(szModeName), VIDEO_PROP_PREFIX"%s", pszName); 254 252 RTStrPrintf(szModeParms, sizeof(szModeParms), "%dx%dx%d", cx, cy, cBits); 255 int rc = VbglR3 InfoSvcConnect(&u32ClientId);256 if (RT_SUCCESS(rc)) 257 rc = VbglR3 InfoSvcWriteKey(u32ClientId, szModeName, szModeParms);253 int rc = VbglR3GuestPropConnect(&u32ClientId); 254 if (RT_SUCCESS(rc)) 255 rc = VbglR3GuestPropWriteValue(u32ClientId, szModeName, szModeParms); 258 256 if (u32ClientId != 0) 259 VbglR3 InfoSvcDisconnect(u32ClientId); /* Return value ignored, because what can we do anyway? */260 return rc; 261 #else /* VBOX_WITH_ INFO_SVCnot defined */257 VbglR3GuestPropDisconnect(u32ClientId); /* Return value ignored, because what can we do anyway? */ 258 return rc; 259 #else /* VBOX_WITH_GUEST_PROPS not defined */ 262 260 return VERR_NOT_IMPLEMENTED; 263 #endif /* VBOX_WITH_ INFO_SVCnot defined */264 } 265 266 267 /** 268 * Retrieve video mode parameters from the registry.261 #endif /* VBOX_WITH_GUEST_PROPS not defined */ 262 } 263 264 265 /** 266 * Retrieve video mode parameters from the guest property store. 269 267 * 270 268 * @returns iprt status value … … 276 274 VBGLR3DECL(int) VbglR3RetrieveVideoMode(const char *pszName, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits) 277 275 { 278 #ifdef VBOX_WITH_INFO_SVC 279 using namespace svcInfo; 280 281 char szModeParms[KEY_MAX_VALUE_LEN]; 282 char *pszNext; 276 #ifdef VBOX_WITH_GUEST_PROPS 277 using namespace guestProp; 278 279 /* 280 * First we retreive the video mode which is saved as a string in the 281 * guest property store. 282 */ 283 /* The buffer for VbglR3GuestPropReadValue. If this is too small then 284 * something is wrong with the data stored in the property. */ 285 char szModeParms[1024]; 283 286 uint32_t u32ClientId = 0; 284 287 uint32_t cx, cy, cBits; 285 288 286 int rc = VbglR3InfoSvcConnect(&u32ClientId); 287 if (RT_SUCCESS(rc)) 288 { 289 char szModeName[KEY_MAX_LEN]; 290 RTStrPrintf(szModeName, sizeof(szModeName), "VideoMode/%s", pszName); 291 rc = VbglR3InfoSvcReadKey(u32ClientId, szModeName, szModeParms, 292 sizeof(szModeParms), NULL); /** @todo add a VbglR3InfoSvcReadKeyF/FV that does the RTStrPrintf for you. */ 293 } 289 int rc = VbglR3GuestPropConnect(&u32ClientId); 290 if (RT_SUCCESS(rc)) 291 { 292 char szModeName[MAX_NAME_LEN]; 293 RTStrPrintf(szModeName, sizeof(szModeName), VIDEO_PROP_PREFIX"%s", pszName); 294 /** @todo add a VbglR3GuestPropReadValueF/FV that does the RTStrPrintf for you. */ 295 rc = VbglR3GuestPropReadValue(u32ClientId, szModeName, szModeParms, 296 sizeof(szModeParms), NULL); 297 } 298 299 /* 300 * Now we convert the string returned to numeric values. 301 */ 302 char *pszNext; 294 303 if (RT_SUCCESS(rc)) 295 304 /* Extract the width from the string */ … … 299 308 if (RT_SUCCESS(rc)) 300 309 { 310 /* Extract the height from the string */ 301 311 ++pszNext; 302 312 rc = RTStrToUInt32Ex(pszNext, &pszNext, 10, &cy); … … 306 316 if (RT_SUCCESS(rc)) 307 317 { 318 /* Extract the bpp from the string */ 308 319 ++pszNext; 309 320 rc = RTStrToUInt32Full(pszNext, 10, &cBits); … … 311 322 if (rc != VINF_SUCCESS) 312 323 rc = VERR_PARSE_ERROR; 324 325 /* 326 * And clean up and return the values if we successfully obtained them. 327 */ 313 328 if (u32ClientId != 0) 314 VbglR3 InfoSvcDisconnect(u32ClientId); /* Return value ignored, because what can we do anyway? */329 VbglR3GuestPropDisconnect(u32ClientId); /* Return value ignored, because what can we do anyway? */ 315 330 if (RT_SUCCESS(rc)) 316 331 { … … 320 335 } 321 336 return rc; 322 #else /* VBOX_WITH_ INFO_SVCnot defined */337 #else /* VBOX_WITH_GUEST_PROPS not defined */ 323 338 return VERR_NOT_IMPLEMENTED; 324 #endif /* VBOX_WITH_ INFO_SVCnot defined */325 } 339 #endif /* VBOX_WITH_GUEST_PROPS not defined */ 340 }
Note:
See TracChangeset
for help on using the changeset viewer.