|
3 | 3 | * handle information
|
4 | 4 | *
|
5 | 5 | * Copyright (C) 2010-2015 wj32
|
6 |
| - * Copyright (C) 2017-2020 dmex |
| 6 | + * Copyright (C) 2017-2021 dmex |
7 | 7 | *
|
8 | 8 | * This file is part of Process Hacker.
|
9 | 9 | *
|
|
26 | 26 | #include <json.h>
|
27 | 27 | #include <kphuser.h>
|
28 | 28 | #include <lsasup.h>
|
| 29 | +#include <devquery.h> |
| 30 | +#include <devpkey.h> |
29 | 31 |
|
30 | 32 | #define PH_QUERY_HACK_MAX_THREADS 20
|
31 | 33 |
|
@@ -575,6 +577,141 @@ PPH_STRING PhGetEtwPublisherName(
|
575 | 577 | }
|
576 | 578 | }
|
577 | 579 |
|
| 580 | +PPH_STRING PhGetPnPDeviceName( |
| 581 | + _In_ PPH_STRING ObjectName |
| 582 | + ) |
| 583 | +{ |
| 584 | + static PH_INITONCE initOnce = PH_INITONCE_INIT; |
| 585 | + static HRESULT (WINAPI* DevGetObjects_I)( |
| 586 | + _In_ DEV_OBJECT_TYPE ObjectType, |
| 587 | + _In_ ULONG QueryFlags, |
| 588 | + _In_ ULONG cRequestedProperties, |
| 589 | + _In_reads_opt_(cRequestedProperties) const DEVPROPCOMPKEY *pRequestedProperties, |
| 590 | + _In_ ULONG cFilterExpressionCount, |
| 591 | + _In_reads_opt_(cFilterExpressionCount) const DEVPROP_FILTER_EXPRESSION *pFilter, |
| 592 | + _Out_ PULONG pcObjectCount, |
| 593 | + _Outptr_result_buffer_maybenull_(*pcObjectCount) const DEV_OBJECT **ppObjects) = NULL; |
| 594 | + static HRESULT (WINAPI* DevFreeObjects_I)( |
| 595 | + _In_ ULONG cObjectCount, |
| 596 | + _In_reads_(cObjectCount) const DEV_OBJECT *pObjects) = NULL; |
| 597 | + |
| 598 | + PPH_STRING objectPnPDeviceName = NULL; |
| 599 | + ULONG deviceCount = 0; |
| 600 | + PDEV_OBJECT deviceObjects = NULL; |
| 601 | + DEVPROPCOMPKEY deviceProperties[2]; |
| 602 | + DEVPROP_FILTER_EXPRESSION deviceFilter[1]; |
| 603 | + DEVPROPERTY deviceFilterProperty; |
| 604 | + DEVPROPCOMPKEY deviceFilterCompoundProp; |
| 605 | + |
| 606 | + if (PhBeginInitOnce(&initOnce)) |
| 607 | + { |
| 608 | + PVOID cfgmgr32; |
| 609 | + |
| 610 | + if (cfgmgr32 = LoadLibrary(L"cfgmgr32.dll")) |
| 611 | + { |
| 612 | + DevGetObjects_I = PhGetDllBaseProcedureAddress(cfgmgr32, "DevGetObjects", 0); |
| 613 | + DevFreeObjects_I = PhGetDllBaseProcedureAddress(cfgmgr32, "DevFreeObjects", 0); |
| 614 | + } |
| 615 | + |
| 616 | + PhEndInitOnce(&initOnce); |
| 617 | + } |
| 618 | + |
| 619 | + if (!(DevGetObjects_I && DevFreeObjects_I)) |
| 620 | + return NULL; |
| 621 | + |
| 622 | + memset(deviceProperties, 0, sizeof(deviceProperties)); |
| 623 | + deviceProperties[0].Key = DEVPKEY_NAME; |
| 624 | + deviceProperties[0].Store = DEVPROP_STORE_SYSTEM; |
| 625 | + deviceProperties[1].Key = DEVPKEY_Device_BusReportedDeviceDesc; |
| 626 | + deviceProperties[1].Store = DEVPROP_STORE_SYSTEM; |
| 627 | + |
| 628 | + memset(&deviceFilterCompoundProp, 0, sizeof(deviceFilterCompoundProp)); |
| 629 | + deviceFilterCompoundProp.Key = DEVPKEY_Device_PDOName; |
| 630 | + deviceFilterCompoundProp.Store = DEVPROP_STORE_SYSTEM; |
| 631 | + deviceFilterCompoundProp.LocaleName = NULL; |
| 632 | + |
| 633 | + memset(&deviceFilterProperty, 0, sizeof(deviceFilterProperty)); |
| 634 | + deviceFilterProperty.CompKey = deviceFilterCompoundProp; |
| 635 | + deviceFilterProperty.Type = DEVPROP_TYPE_STRING; |
| 636 | + deviceFilterProperty.BufferSize = (ULONG)ObjectName->Length + sizeof(UNICODE_NULL); |
| 637 | + deviceFilterProperty.Buffer = ObjectName->Buffer; |
| 638 | + |
| 639 | + memset(deviceFilter, 0, sizeof(deviceFilter)); |
| 640 | + deviceFilter[0].Operator = DEVPROP_OPERATOR_EQUALS_IGNORE_CASE; |
| 641 | + deviceFilter[0].Property = deviceFilterProperty; |
| 642 | + |
| 643 | + if (SUCCEEDED(DevGetObjects_I( |
| 644 | + DevObjectTypeDevice, |
| 645 | + DevQueryFlagNone, |
| 646 | + RTL_NUMBER_OF(deviceProperties), |
| 647 | + deviceProperties, |
| 648 | + RTL_NUMBER_OF(deviceFilter), |
| 649 | + deviceFilter, |
| 650 | + &deviceCount, |
| 651 | + &deviceObjects |
| 652 | + ))) |
| 653 | + { |
| 654 | + // Note: We can get a success with 0 results. |
| 655 | + if (deviceCount > 0) |
| 656 | + { |
| 657 | + DEV_OBJECT device = deviceObjects[0]; |
| 658 | + PPH_STRING deviceName; |
| 659 | + PPH_STRING deviceDesc; |
| 660 | + PH_STRINGREF displayName; |
| 661 | + PH_STRINGREF displayDesc; |
| 662 | + PH_STRINGREF firstPart; |
| 663 | + PH_STRINGREF secondPart; |
| 664 | + |
| 665 | + displayName.Length = device.pProperties[0].BufferSize; |
| 666 | + displayName.Buffer = device.pProperties[0].Buffer; |
| 667 | + displayDesc.Length = device.pProperties[1].BufferSize; |
| 668 | + displayDesc.Buffer = device.pProperties[1].Buffer; |
| 669 | + |
| 670 | + if (PhSplitStringRefAtLastChar(&displayName, L';', &firstPart, &secondPart)) |
| 671 | + deviceName = PhCreateString2(&secondPart); |
| 672 | + else |
| 673 | + deviceName = PhCreateString2(&displayName); |
| 674 | + |
| 675 | + if (PhSplitStringRefAtLastChar(&displayDesc, L';', &firstPart, &secondPart)) |
| 676 | + deviceDesc = PhCreateString2(&secondPart); |
| 677 | + else |
| 678 | + deviceDesc = PhCreateString2(&displayDesc); |
| 679 | + |
| 680 | + if (!PhIsNullOrEmptyString(deviceDesc)) |
| 681 | + { |
| 682 | + PH_FORMAT format[4]; |
| 683 | + |
| 684 | + PhInitFormatSR(&format[0], deviceDesc->sr); |
| 685 | + PhInitFormatS(&format[1], L"(PDO: "); |
| 686 | + PhInitFormatSR(&format[2], ObjectName->sr); |
| 687 | + PhInitFormatC(&format[3], ')'); |
| 688 | + |
| 689 | + PhSetReference(&objectPnPDeviceName, PhFormat(format, 4, 0x50)); |
| 690 | + } |
| 691 | + else if (!PhIsNullOrEmptyString(deviceName)) |
| 692 | + { |
| 693 | + PH_FORMAT format[4]; |
| 694 | + |
| 695 | + PhInitFormatSR(&format[0], deviceName->sr); |
| 696 | + PhInitFormatS(&format[1], L"(PDO: "); |
| 697 | + PhInitFormatSR(&format[2], ObjectName->sr); |
| 698 | + PhInitFormatC(&format[3], ')'); |
| 699 | + |
| 700 | + PhSetReference(&objectPnPDeviceName, PhFormat(format, 4, 0x50)); |
| 701 | + } |
| 702 | + |
| 703 | + if (deviceDesc) |
| 704 | + PhDereferenceObject(deviceDesc); |
| 705 | + if (deviceName) |
| 706 | + PhDereferenceObject(deviceName); |
| 707 | + } |
| 708 | + |
| 709 | + DevFreeObjects_I(deviceCount, deviceObjects); |
| 710 | + } |
| 711 | + |
| 712 | + return objectPnPDeviceName; |
| 713 | +} |
| 714 | + |
578 | 715 | PPH_STRING PhFormatNativeKeyName(
|
579 | 716 | _In_ PPH_STRING Name
|
580 | 717 | )
|
@@ -830,8 +967,17 @@ NTSTATUS PhpGetBestObjectName(
|
830 | 967 |
|
831 | 968 | if (!bestObjectName)
|
832 | 969 | {
|
833 |
| - // The file doesn't have a DOS name. |
834 |
| - PhSetReference(&bestObjectName, ObjectName); |
| 970 | + if (PhStartsWithString2(ObjectName, L"\\Device\\", TRUE)) |
| 971 | + { |
| 972 | + // The device might be a PDO... Query the PnP manager for the friendy name of the device. |
| 973 | + bestObjectName = PhGetPnPDeviceName(ObjectName); |
| 974 | + } |
| 975 | + |
| 976 | + if (!bestObjectName) |
| 977 | + { |
| 978 | + // The file doesn't have a DOS filename and doesn't have a PnP friendy name. |
| 979 | + PhSetReference(&bestObjectName, ObjectName); |
| 980 | + } |
835 | 981 | }
|
836 | 982 |
|
837 | 983 | if (PhIsNullOrEmptyString(bestObjectName) && KphIsConnected())
|
|
0 commit comments