commands-win32.c (cb4e0f9ddf7d45de7e4716cbab661ea568bd0b6c) | commands-win32.c (c6bd8c706a799eb0fece99f468aaa22b818036f3) |
---|---|
1/* 2 * QEMU Guest Agent win32-specific command implementations 3 * 4 * Copyright IBM Corp. 2012 5 * 6 * Authors: 7 * Michael Roth <mdroth@linux.vnet.ibm.com> 8 * Gal Hammer <ghammer@redhat.com> --- 168 unchanged lines hidden (view full) --- 177 HANDLE token = NULL; 178 TOKEN_PRIVILEGES priv; 179 Error *local_err = NULL; 180 181 if (OpenProcessToken(GetCurrentProcess(), 182 TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token)) 183 { 184 if (!LookupPrivilegeValue(NULL, name, &priv.Privileges[0].Luid)) { | 1/* 2 * QEMU Guest Agent win32-specific command implementations 3 * 4 * Copyright IBM Corp. 2012 5 * 6 * Authors: 7 * Michael Roth <mdroth@linux.vnet.ibm.com> 8 * Gal Hammer <ghammer@redhat.com> --- 168 unchanged lines hidden (view full) --- 177 HANDLE token = NULL; 178 TOKEN_PRIVILEGES priv; 179 Error *local_err = NULL; 180 181 if (OpenProcessToken(GetCurrentProcess(), 182 TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token)) 183 { 184 if (!LookupPrivilegeValue(NULL, name, &priv.Privileges[0].Luid)) { |
185 error_set(&local_err, QERR_QGA_COMMAND_FAILED, 186 "no luid for requested privilege"); | 185 error_setg(&local_err, QERR_QGA_COMMAND_FAILED, 186 "no luid for requested privilege"); |
187 goto out; 188 } 189 190 priv.PrivilegeCount = 1; 191 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 192 193 if (!AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, 0)) { | 187 goto out; 188 } 189 190 priv.PrivilegeCount = 1; 191 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 192 193 if (!AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, 0)) { |
194 error_set(&local_err, QERR_QGA_COMMAND_FAILED, 195 "unable to acquire requested privilege"); | 194 error_setg(&local_err, QERR_QGA_COMMAND_FAILED, 195 "unable to acquire requested privilege"); |
196 goto out; 197 } 198 199 } else { | 196 goto out; 197 } 198 199 } else { |
200 error_set(&local_err, QERR_QGA_COMMAND_FAILED, 201 "failed to open privilege token"); | 200 error_setg(&local_err, QERR_QGA_COMMAND_FAILED, 201 "failed to open privilege token"); |
202 } 203 204out: 205 if (token) { 206 CloseHandle(token); 207 } 208 if (local_err) { 209 error_propagate(errp, local_err); 210 } 211} 212 213static void execute_async(DWORD WINAPI (*func)(LPVOID), LPVOID opaque, 214 Error **errp) 215{ 216 Error *local_err = NULL; 217 218 HANDLE thread = CreateThread(NULL, 0, func, opaque, 0, NULL); 219 if (!thread) { | 202 } 203 204out: 205 if (token) { 206 CloseHandle(token); 207 } 208 if (local_err) { 209 error_propagate(errp, local_err); 210 } 211} 212 213static void execute_async(DWORD WINAPI (*func)(LPVOID), LPVOID opaque, 214 Error **errp) 215{ 216 Error *local_err = NULL; 217 218 HANDLE thread = CreateThread(NULL, 0, func, opaque, 0, NULL); 219 if (!thread) { |
220 error_set(&local_err, QERR_QGA_COMMAND_FAILED, 221 "failed to dispatch asynchronous command"); | 220 error_setg(&local_err, QERR_QGA_COMMAND_FAILED, 221 "failed to dispatch asynchronous command"); |
222 error_propagate(errp, local_err); 223 } 224} 225 226void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) 227{ 228 Error *local_err = NULL; 229 UINT shutdown_flag = EWX_FORCE; 230 231 slog("guest-shutdown called, mode: %s", mode); 232 233 if (!has_mode || strcmp(mode, "powerdown") == 0) { 234 shutdown_flag |= EWX_POWEROFF; 235 } else if (strcmp(mode, "halt") == 0) { 236 shutdown_flag |= EWX_SHUTDOWN; 237 } else if (strcmp(mode, "reboot") == 0) { 238 shutdown_flag |= EWX_REBOOT; 239 } else { | 222 error_propagate(errp, local_err); 223 } 224} 225 226void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) 227{ 228 Error *local_err = NULL; 229 UINT shutdown_flag = EWX_FORCE; 230 231 slog("guest-shutdown called, mode: %s", mode); 232 233 if (!has_mode || strcmp(mode, "powerdown") == 0) { 234 shutdown_flag |= EWX_POWEROFF; 235 } else if (strcmp(mode, "halt") == 0) { 236 shutdown_flag |= EWX_SHUTDOWN; 237 } else if (strcmp(mode, "reboot") == 0) { 238 shutdown_flag |= EWX_REBOOT; 239 } else { |
240 error_set(errp, QERR_INVALID_PARAMETER_VALUE, "mode", 241 "halt|powerdown|reboot"); | 240 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "mode", 241 "halt|powerdown|reboot"); |
242 return; 243 } 244 245 /* Request a shutdown privilege, but try to shut down the system 246 anyway. */ 247 acquire_privilege(SE_SHUTDOWN_NAME, &local_err); 248 if (local_err) { 249 error_propagate(errp, local_err); 250 return; 251 } 252 253 if (!ExitWindowsEx(shutdown_flag, SHTDN_REASON_FLAG_PLANNED)) { 254 slog("guest-shutdown failed: %lu", GetLastError()); | 242 return; 243 } 244 245 /* Request a shutdown privilege, but try to shut down the system 246 anyway. */ 247 acquire_privilege(SE_SHUTDOWN_NAME, &local_err); 248 if (local_err) { 249 error_propagate(errp, local_err); 250 return; 251 } 252 253 if (!ExitWindowsEx(shutdown_flag, SHTDN_REASON_FLAG_PLANNED)) { 254 slog("guest-shutdown failed: %lu", GetLastError()); |
255 error_set(errp, QERR_UNDEFINED_ERROR); | 255 error_setg(errp, QERR_UNDEFINED_ERROR); |
256 } 257} 258 259GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count, 260 int64_t count, Error **errp) 261{ 262 GuestFileRead *read_data = NULL; 263 guchar *buf; --- 115 unchanged lines hidden (view full) --- 379 380static void guest_file_init(void) 381{ 382 QTAILQ_INIT(&guest_file_state.filehandles); 383} 384 385GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) 386{ | 256 } 257} 258 259GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count, 260 int64_t count, Error **errp) 261{ 262 GuestFileRead *read_data = NULL; 263 guchar *buf; --- 115 unchanged lines hidden (view full) --- 379 380static void guest_file_init(void) 381{ 382 QTAILQ_INIT(&guest_file_state.filehandles); 383} 384 385GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) 386{ |
387 error_set(errp, QERR_UNSUPPORTED); | 387 error_setg(errp, QERR_UNSUPPORTED); |
388 return NULL; 389} 390 391/* 392 * Return status of freeze/thaw 393 */ 394GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) 395{ 396 if (!vss_initialized()) { | 388 return NULL; 389} 390 391/* 392 * Return status of freeze/thaw 393 */ 394GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) 395{ 396 if (!vss_initialized()) { |
397 error_set(errp, QERR_UNSUPPORTED); | 397 error_setg(errp, QERR_UNSUPPORTED); |
398 return 0; 399 } 400 401 if (ga_is_frozen(ga_state)) { 402 return GUEST_FSFREEZE_STATUS_FROZEN; 403 } 404 405 return GUEST_FSFREEZE_STATUS_THAWED; --- 4 unchanged lines hidden (view full) --- 410 * The frozen state is limited for up to 10 seconds by VSS. 411 */ 412int64_t qmp_guest_fsfreeze_freeze(Error **errp) 413{ 414 int i; 415 Error *local_err = NULL; 416 417 if (!vss_initialized()) { | 398 return 0; 399 } 400 401 if (ga_is_frozen(ga_state)) { 402 return GUEST_FSFREEZE_STATUS_FROZEN; 403 } 404 405 return GUEST_FSFREEZE_STATUS_THAWED; --- 4 unchanged lines hidden (view full) --- 410 * The frozen state is limited for up to 10 seconds by VSS. 411 */ 412int64_t qmp_guest_fsfreeze_freeze(Error **errp) 413{ 414 int i; 415 Error *local_err = NULL; 416 417 if (!vss_initialized()) { |
418 error_set(errp, QERR_UNSUPPORTED); | 418 error_setg(errp, QERR_UNSUPPORTED); |
419 return 0; 420 } 421 422 slog("guest-fsfreeze called"); 423 424 /* cannot risk guest agent blocking itself on a write in this state */ 425 ga_set_frozen(ga_state); 426 --- 14 unchanged lines hidden (view full) --- 441 } 442 return 0; 443} 444 445int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, 446 strList *mountpoints, 447 Error **errp) 448{ | 419 return 0; 420 } 421 422 slog("guest-fsfreeze called"); 423 424 /* cannot risk guest agent blocking itself on a write in this state */ 425 ga_set_frozen(ga_state); 426 --- 14 unchanged lines hidden (view full) --- 441 } 442 return 0; 443} 444 445int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, 446 strList *mountpoints, 447 Error **errp) 448{ |
449 error_set(errp, QERR_UNSUPPORTED); | 449 error_setg(errp, QERR_UNSUPPORTED); |
450 451 return 0; 452} 453 454/* 455 * Thaw local file systems using Volume Shadow-copy Service. 456 */ 457int64_t qmp_guest_fsfreeze_thaw(Error **errp) 458{ 459 int i; 460 461 if (!vss_initialized()) { | 450 451 return 0; 452} 453 454/* 455 * Thaw local file systems using Volume Shadow-copy Service. 456 */ 457int64_t qmp_guest_fsfreeze_thaw(Error **errp) 458{ 459 int i; 460 461 if (!vss_initialized()) { |
462 error_set(errp, QERR_UNSUPPORTED); | 462 error_setg(errp, QERR_UNSUPPORTED); |
463 return 0; 464 } 465 466 qga_vss_fsfreeze(&i, errp, false); 467 468 ga_unset_frozen(ga_state); 469 return i; 470} --- 19 unchanged lines hidden (view full) --- 490} 491 492/* 493 * Walk list of mounted file systems in the guest, and discard unused 494 * areas. 495 */ 496void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) 497{ | 463 return 0; 464 } 465 466 qga_vss_fsfreeze(&i, errp, false); 467 468 ga_unset_frozen(ga_state); 469 return i; 470} --- 19 unchanged lines hidden (view full) --- 490} 491 492/* 493 * Walk list of mounted file systems in the guest, and discard unused 494 * areas. 495 */ 496void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) 497{ |
498 error_set(errp, QERR_UNSUPPORTED); | 498 error_setg(errp, QERR_UNSUPPORTED); |
499} 500 501typedef enum { 502 GUEST_SUSPEND_MODE_DISK, 503 GUEST_SUSPEND_MODE_RAM 504} GuestSuspendMode; 505 506static void check_suspend_mode(GuestSuspendMode mode, Error **errp) 507{ 508 SYSTEM_POWER_CAPABILITIES sys_pwr_caps; 509 Error *local_err = NULL; 510 511 ZeroMemory(&sys_pwr_caps, sizeof(sys_pwr_caps)); 512 if (!GetPwrCapabilities(&sys_pwr_caps)) { | 499} 500 501typedef enum { 502 GUEST_SUSPEND_MODE_DISK, 503 GUEST_SUSPEND_MODE_RAM 504} GuestSuspendMode; 505 506static void check_suspend_mode(GuestSuspendMode mode, Error **errp) 507{ 508 SYSTEM_POWER_CAPABILITIES sys_pwr_caps; 509 Error *local_err = NULL; 510 511 ZeroMemory(&sys_pwr_caps, sizeof(sys_pwr_caps)); 512 if (!GetPwrCapabilities(&sys_pwr_caps)) { |
513 error_set(&local_err, QERR_QGA_COMMAND_FAILED, 514 "failed to determine guest suspend capabilities"); | 513 error_setg(&local_err, QERR_QGA_COMMAND_FAILED, 514 "failed to determine guest suspend capabilities"); |
515 goto out; 516 } 517 518 switch (mode) { 519 case GUEST_SUSPEND_MODE_DISK: 520 if (!sys_pwr_caps.SystemS4) { | 515 goto out; 516 } 517 518 switch (mode) { 519 case GUEST_SUSPEND_MODE_DISK: 520 if (!sys_pwr_caps.SystemS4) { |
521 error_set(&local_err, QERR_QGA_COMMAND_FAILED, 522 "suspend-to-disk not supported by OS"); | 521 error_setg(&local_err, QERR_QGA_COMMAND_FAILED, 522 "suspend-to-disk not supported by OS"); |
523 } 524 break; 525 case GUEST_SUSPEND_MODE_RAM: 526 if (!sys_pwr_caps.SystemS3) { | 523 } 524 break; 525 case GUEST_SUSPEND_MODE_RAM: 526 if (!sys_pwr_caps.SystemS3) { |
527 error_set(&local_err, QERR_QGA_COMMAND_FAILED, 528 "suspend-to-ram not supported by OS"); | 527 error_setg(&local_err, QERR_QGA_COMMAND_FAILED, 528 "suspend-to-ram not supported by OS"); |
529 } 530 break; 531 default: | 529 } 530 break; 531 default: |
532 error_set(&local_err, QERR_INVALID_PARAMETER_VALUE, "mode", 533 "GuestSuspendMode"); | 532 error_setg(&local_err, QERR_INVALID_PARAMETER_VALUE, "mode", 533 "GuestSuspendMode"); |
534 } 535 536out: 537 if (local_err) { 538 error_propagate(errp, local_err); 539 } 540} 541 --- 39 unchanged lines hidden (view full) --- 581 if (local_err) { 582 error_propagate(errp, local_err); 583 g_free(mode); 584 } 585} 586 587void qmp_guest_suspend_hybrid(Error **errp) 588{ | 534 } 535 536out: 537 if (local_err) { 538 error_propagate(errp, local_err); 539 } 540} 541 --- 39 unchanged lines hidden (view full) --- 581 if (local_err) { 582 error_propagate(errp, local_err); 583 g_free(mode); 584 } 585} 586 587void qmp_guest_suspend_hybrid(Error **errp) 588{ |
589 error_set(errp, QERR_UNSUPPORTED); | 589 error_setg(errp, QERR_UNSUPPORTED); |
590} 591 592GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 593{ | 590} 591 592GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 593{ |
594 error_set(errp, QERR_UNSUPPORTED); | 594 error_setg(errp, QERR_UNSUPPORTED); |
595 return NULL; 596} 597 598int64_t qmp_guest_get_time(Error **errp) 599{ 600 SYSTEMTIME ts = {0}; 601 int64_t time_ns; 602 FILETIME tf; --- 58 unchanged lines hidden (view full) --- 661 if (!SetSystemTime(&ts)) { 662 error_setg(errp, "Failed to set time to guest: %d", (int)GetLastError()); 663 return; 664 } 665} 666 667GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 668{ | 595 return NULL; 596} 597 598int64_t qmp_guest_get_time(Error **errp) 599{ 600 SYSTEMTIME ts = {0}; 601 int64_t time_ns; 602 FILETIME tf; --- 58 unchanged lines hidden (view full) --- 661 if (!SetSystemTime(&ts)) { 662 error_setg(errp, "Failed to set time to guest: %d", (int)GetLastError()); 663 return; 664 } 665} 666 667GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 668{ |
669 error_set(errp, QERR_UNSUPPORTED); | 669 error_setg(errp, QERR_UNSUPPORTED); |
670 return NULL; 671} 672 673int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 674{ | 670 return NULL; 671} 672 673int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 674{ |
675 error_set(errp, QERR_UNSUPPORTED); | 675 error_setg(errp, QERR_UNSUPPORTED); |
676 return -1; 677} 678 679void qmp_guest_set_user_password(const char *username, 680 const char *password, 681 bool crypted, 682 Error **errp) 683{ | 676 return -1; 677} 678 679void qmp_guest_set_user_password(const char *username, 680 const char *password, 681 bool crypted, 682 Error **errp) 683{ |
684 error_set(errp, QERR_UNSUPPORTED); | 684 error_setg(errp, QERR_UNSUPPORTED); |
685} 686 687GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) 688{ | 685} 686 687GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) 688{ |
689 error_set(errp, QERR_UNSUPPORTED); | 689 error_setg(errp, QERR_UNSUPPORTED); |
690 return NULL; 691} 692 693GuestMemoryBlockResponseList * 694qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp) 695{ | 690 return NULL; 691} 692 693GuestMemoryBlockResponseList * 694qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp) 695{ |
696 error_set(errp, QERR_UNSUPPORTED); | 696 error_setg(errp, QERR_UNSUPPORTED); |
697 return NULL; 698} 699 700GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) 701{ | 697 return NULL; 698} 699 700GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) 701{ |
702 error_set(errp, QERR_UNSUPPORTED); | 702 error_setg(errp, QERR_UNSUPPORTED); |
703 return NULL; 704} 705 706/* add unsupported commands to the blacklist */ 707GList *ga_command_blacklist_init(GList *blacklist) 708{ 709 const char *list_unsupported[] = { 710 "guest-suspend-hybrid", "guest-network-get-interfaces", --- 35 unchanged lines hidden --- | 703 return NULL; 704} 705 706/* add unsupported commands to the blacklist */ 707GList *ga_command_blacklist_init(GList *blacklist) 708{ 709 const char *list_unsupported[] = { 710 "guest-suspend-hybrid", "guest-network-get-interfaces", --- 35 unchanged lines hidden --- |