PPH_LIST PhInitializeColumnSetList(
    _In_ PWSTR SettingName
    )
{
    PPH_LIST columnSetList;
    PPH_STRING settingsString;
    ULONG64 count;
    ULONG64 index;
    PH_STRINGREF remaining;
    PH_STRINGREF part;

    columnSetList = PhCreateList(10);
    settingsString = PhaGetStringSetting(SettingName);
    remaining = settingsString->sr;

    if (remaining.Length == 0)
        goto CleanupExit;
    if (!PhSplitStringRefAtChar(&remaining, '-', &part, &remaining))
        goto CleanupExit;
    if (!PhStringToInteger64(&part, 10, &count))
        goto CleanupExit;

    for (index = 0; index < count; index++)
    {
        PH_STRINGREF columnSetNamePart;
        PH_STRINGREF columnSetSettingPart;
        PH_STRINGREF columnSetSortPart;

        if (remaining.Length == 0)
            break;

        PhSplitStringRefAtChar(&remaining, '-', &columnSetNamePart, &remaining);
        PhSplitStringRefAtChar(&remaining, '-', &columnSetSettingPart, &remaining);
        PhSplitStringRefAtChar(&remaining, '-', &columnSetSortPart, &remaining);

        {
            PPH_COLUMN_SET_ENTRY entry;

            entry = PhAllocate(sizeof(PH_COLUMN_SET_ENTRY));
            entry->Name = PhCreateString2(&columnSetNamePart);
            entry->Setting = PhCreateString2(&columnSetSettingPart);
            entry->Sorting = PhCreateString2(&columnSetSortPart);

            PhAddItemList(columnSetList, entry);
        }
    }

CleanupExit:
    return columnSetList;
}
Beispiel #2
0
_May_raise_ VOID PhSetStringSetting2(
    _In_ PWSTR Name,
    _In_ PPH_STRINGREF Value
    )
{
    PPH_SETTING setting;
    PH_STRINGREF name;

    PhInitializeStringRef(&name, Name);

    PhAcquireQueuedLockExclusive(&PhSettingsLock);

    setting = PhpLookupSetting(&name);

    if (setting && setting->Type == StringSettingType)
    {
        PhpFreeSettingValue(StringSettingType, setting);
        setting->u.Pointer = PhCreateString2(Value);
    }

    PhReleaseQueuedLockExclusive(&PhSettingsLock);

    if (!setting)
        PhRaiseStatus(STATUS_NOT_FOUND);
}
VOID DiskDrivesLoadList(
    VOID
    )
{
    PPH_STRING settingsString;
    PH_STRINGREF remaining;

    settingsString = PhaGetStringSetting(SETTING_NAME_DISK_LIST);
    remaining = settingsString->sr;

    while (remaining.Length != 0)
    {
        PH_STRINGREF part;
        DV_DISK_ID id;
        PDV_DISK_ENTRY entry;

        if (remaining.Length == 0)
            break;

        PhSplitStringRefAtChar(&remaining, ',', &part, &remaining);

        InitializeDiskId(&id, PhCreateString2(&part));
        entry = CreateDiskEntry(&id);
        DeleteDiskId(&id);

        entry->UserReference = TRUE;
    }
}
VOID PhpAddDisabledPlugins(
    VOID
    )
{
    PPH_STRING disabled;
    PH_STRINGREF remainingPart;
    PH_STRINGREF part;
    PPH_PLUGIN disabledPlugin;
    PPH_STRING displayText;
    INT lvItemIndex;

    disabled = PhGetStringSetting(L"DisabledPlugins");
    remainingPart = disabled->sr;

    while (remainingPart.Length != 0)
    {
        PhSplitStringRefAtChar(&remainingPart, '|', &part, &remainingPart);

        if (part.Length != 0)
        {
            if (!PhpIsPluginLoadedByBaseName(&part))
            {
                disabledPlugin = PhpCreateDisabledPlugin(&part);
                PhAddItemList(DisabledPluginInstances, disabledPlugin);
                PhAddItemSimpleHashtable(DisabledPluginLookup, disabledPlugin, NULL);

                displayText = PhCreateString2(&part);
                lvItemIndex = PhAddListViewItem(PluginsLv, MAXINT, displayText->Buffer, disabledPlugin);
                PhDereferenceObject(displayText);
            }
        }
    }

    PhDereferenceObject(disabled);
}
Beispiel #5
0
PPH_STRING TrimString(
    _In_ PPH_STRING String
    )
{
    static PH_STRINGREF whitespace = PH_STRINGREF_INIT(L" \t\r\n");
    PH_STRINGREF sr = String->sr;
    PhTrimStringRef(&sr, &whitespace, 0);
    return PhCreateString2(&sr);
}
Beispiel #6
0
PPH_STRING PhpGetX500Value(
    _In_ PPH_STRINGREF String,
    _In_ PPH_STRINGREF KeyName
    )
{
    WCHAR keyNamePlusEqualsBuffer[10];
    PH_STRINGREF keyNamePlusEquals;
    SIZE_T keyNameLength;
    PH_STRINGREF firstPart;
    PH_STRINGREF remainingPart;

    keyNameLength = KeyName->Length / sizeof(WCHAR);
    assert(!(keyNameLength > sizeof(keyNamePlusEquals) / sizeof(WCHAR) - 1));
    keyNamePlusEquals.Buffer = keyNamePlusEqualsBuffer;
    keyNamePlusEquals.Length = (keyNameLength + 1) * sizeof(WCHAR);

    memcpy(keyNamePlusEquals.Buffer, KeyName->Buffer, KeyName->Length);
    keyNamePlusEquals.Buffer[keyNameLength] = '=';

    // Find "Key=".

    if (!PhSplitStringRefAtString(String, &keyNamePlusEquals, FALSE, &firstPart, &remainingPart))
        return NULL;
    if (remainingPart.Length == 0)
        return NULL;

    // Is the value quoted? If so, return the part inside the quotes.
    if (remainingPart.Buffer[0] == '"')
    {
        PhSkipStringRef(&remainingPart, sizeof(WCHAR));

        if (!PhSplitStringRefAtChar(&remainingPart, '"', &firstPart, &remainingPart))
            return NULL;

        return PhCreateString2(&firstPart);
    }
    else
    {
        PhSplitStringRefAtChar(&remainingPart, ',', &firstPart, &remainingPart);

        return PhCreateString2(&firstPart);
    }
}
Beispiel #7
0
PPH_STRING PhGetUrlBaseName(
    _In_ PPH_STRING FileName
    )
{
    PH_STRINGREF pathPart;
    PH_STRINGREF baseNamePart;

    if (!PhSplitStringRefAtLastChar(&FileName->sr, '/', &pathPart, &baseNamePart))
        return NULL;

    return PhCreateString2(&baseNamePart);
}
Beispiel #8
0
VOID PhpExecuteCallbackForAllPlugins(
    _In_ PH_PLUGIN_CALLBACK Callback,
    _In_ BOOLEAN StartupParameters
    )
{
    PPH_AVL_LINKS links;

    links = PhMinimumElementAvlTree(&PhPluginsByName);

    while (links)
    {
        PPH_PLUGIN plugin = CONTAINING_RECORD(links, PH_PLUGIN, Links);
        PPH_LIST parameters = NULL;

        // Find relevant startup parameters for this plugin.
        if (StartupParameters && PhStartupParameters.PluginParameters)
        {
            ULONG i;

            for (i = 0; i < PhStartupParameters.PluginParameters->Count; i++)
            {
                PPH_STRING string = PhStartupParameters.PluginParameters->Items[i];
                PH_STRINGREF pluginName;
                PH_STRINGREF parameter;

                if (PhSplitStringRefAtChar(&string->sr, ':', &pluginName, &parameter) &&
                    PhEqualStringRef(&pluginName, &plugin->Name, FALSE) &&
                    parameter.Length != 0)
                {
                    if (!parameters)
                        parameters = PhCreateList(3);

                    PhAddItemList(parameters, PhCreateString2(&parameter));
                }
            }
        }

        PhInvokeCallback(PhGetPluginCallback(plugin, Callback), parameters);

        if (parameters)
        {
            ULONG i;

            for (i = 0; i < parameters->Count; i++)
                PhDereferenceObject(parameters->Items[i]);

            PhDereferenceObject(parameters);
        }

        links = PhSuccessorElementAvlTree(links);
    }
}
Beispiel #9
0
static VOID PhpSplitUserName(
    _In_ PWSTR UserName,
    _Out_ PPH_STRING *DomainPart,
    _Out_ PPH_STRING *UserPart
    )
{
    PH_STRINGREF userName;
    PH_STRINGREF domainPart;
    PH_STRINGREF userPart;

    PhInitializeStringRefLongHint(&userName, UserName);

    if (PhSplitStringRefAtChar(&userName, '\\', &domainPart, &userPart))
    {
        *DomainPart = PhCreateString2(&domainPart);
        *UserPart = PhCreateString2(&userPart);
    }
    else
    {
        *DomainPart = NULL;
        *UserPart = PhCreateString2(&userName);
    }
}
Beispiel #10
0
BOOLEAN NTAPI EnumDirectoryObjectsCallback(
    __in PPH_STRINGREF Name,
    __in PPH_STRINGREF TypeName,
    __in_opt PVOID Context
    )
{
    INT result;
    PPH_STRING name;
    PPH_STRING typeName;

    name = PhCreateString2(Name);
    typeName = PhCreateString2(TypeName);
    result = PhShowMessage(
        PhMainWndHandle,
        MB_ICONINFORMATION | MB_OKCANCEL,
        L"%s: %s",
        name->Buffer,
        typeName->Buffer
        );
    PhDereferenceObject(name);
    PhDereferenceObject(typeName);

    return result == IDOK;
}
static PPH_STRING UpdaterParseDownloadFileName(
    _In_ PPH_STRING DownloadUrlPath
    )
{
    PH_STRINGREF pathPart;
    PH_STRINGREF baseNamePart;
    PPH_STRING filePath;
    PPH_STRING downloadFileName;

    if (!PhSplitStringRefAtLastChar(&DownloadUrlPath->sr, '/', &pathPart, &baseNamePart))
        return NULL;

    downloadFileName = PhCreateString2(&baseNamePart);
    filePath = PhCreateCacheFile(downloadFileName);
    PhDereferenceObject(downloadFileName);

    return filePath;
}
Beispiel #12
0
VOID NetAdaptersLoadList(
    VOID
    )
{
    PPH_STRING settingsString;
    PH_STRINGREF remaining;

    settingsString = PhaGetStringSetting(SETTING_NAME_INTERFACE_LIST);
    remaining = settingsString->sr;

    while (remaining.Length != 0)
    {
        ULONG64 ifindex;
        ULONG64 luid64;
        PH_STRINGREF part1;
        PH_STRINGREF part2;
        PH_STRINGREF part3;
        IF_LUID ifLuid;
        DV_NETADAPTER_ID id;
        PDV_NETADAPTER_ENTRY entry;

        if (remaining.Length == 0)
            break;

        PhSplitStringRefAtChar(&remaining, ',', &part1, &remaining);
        PhSplitStringRefAtChar(&remaining, ',', &part2, &remaining);
        PhSplitStringRefAtChar(&remaining, ',', &part3, &remaining);

        PhStringToInteger64(&part1, 10, &ifindex);
        PhStringToInteger64(&part2, 10, &luid64);

        ifLuid.Value = luid64;
        InitializeNetAdapterId(&id, (IF_INDEX)ifindex, ifLuid, PhCreateString2(&part3));
        entry = CreateNetAdapterEntry(&id);
        DeleteNetAdapterId(&id);

        entry->UserReference = TRUE;
    }
}
VOID EtDiskProcessFileEvent(
    _In_ PET_ETW_FILE_EVENT Event
    )
{
    PH_KEY_VALUE_PAIR pair;
    PPH_KEY_VALUE_PAIR realPair;

    if (!EtDiskEnabled)
        return;

    if (Event->Type == EtEtwFileCreateType || Event->Type == EtEtwFileRundownType)
    {
        pair.Key = Event->FileObject;
        pair.Value = NULL;

        PhAcquireQueuedLockExclusive(&EtFileNameHashtableLock);

        realPair = PhAddEntryHashtableEx(EtFileNameHashtable, &pair, NULL);
        PhMoveReference(&realPair->Value, PhCreateString2(&Event->FileName));

        PhReleaseQueuedLockExclusive(&EtFileNameHashtableLock);
    }
    else if (Event->Type == EtEtwFileDeleteType)
    {
        pair.Key = Event->FileObject;

        PhAcquireQueuedLockExclusive(&EtFileNameHashtableLock);

        realPair = PhFindEntryHashtable(EtFileNameHashtable, &pair);

        if (realPair)
        {
            PhDereferenceObject(realPair->Value);
            PhRemoveEntryHashtable(EtFileNameHashtable, &pair);
        }

        PhReleaseQueuedLockExclusive(&EtFileNameHashtableLock);
    }
}
Beispiel #14
0
static BOOLEAN PhpSettingFromString(
    _In_ PH_SETTING_TYPE Type,
    _In_ PPH_STRINGREF StringRef,
    _In_opt_ PPH_STRING String,
    _Inout_ PPH_SETTING Setting
    )
{
    switch (Type)
    {
    case StringSettingType:
        {
            if (String)
            {
                PhSetReference(&Setting->u.Pointer, String);
            }
            else
            {
                Setting->u.Pointer = PhCreateString2(StringRef);
            }

            return TRUE;
        }
    case IntegerSettingType:
        {
            ULONG64 integer;

            if (PhStringToInteger64(StringRef, 16, &integer))
            {
                Setting->u.Integer = (ULONG)integer;
                return TRUE;
            }
            else
            {
                return FALSE;
            }
        }
    case IntegerPairSettingType:
        {
            LONG64 x;
            LONG64 y;
            PH_STRINGREF xString;
            PH_STRINGREF yString;

            if (!PhSplitStringRefAtChar(StringRef, ',', &xString, &yString))
                return FALSE;

            if (PhStringToInteger64(&xString, 10, &x) && PhStringToInteger64(&yString, 10, &y))
            {
                Setting->u.IntegerPair.X = (LONG)x;
                Setting->u.IntegerPair.Y = (LONG)y;
                return TRUE;
            }
            else
            {
                return FALSE;
            }
        }
    case ScalableIntegerPairSettingType:
        {
            ULONG64 scale;
            LONG64 x;
            LONG64 y;
            PH_STRINGREF stringRef;
            PH_STRINGREF firstPart;
            PH_STRINGREF secondPart;
            PPH_SCALABLE_INTEGER_PAIR scalableIntegerPair;

            stringRef = *StringRef;

            if (stringRef.Length != 0 && stringRef.Buffer[0] == '@')
            {
                PhSkipStringRef(&stringRef, sizeof(WCHAR));

                if (!PhSplitStringRefAtChar(&stringRef, '|', &firstPart, &stringRef))
                    return FALSE;
                if (!PhStringToInteger64(&firstPart, 10, &scale))
                    return FALSE;
            }
            else
            {
                scale = PhpGetCurrentScale();
            }

            if (!PhSplitStringRefAtChar(&stringRef, ',', &firstPart, &secondPart))
                return FALSE;

            if (PhStringToInteger64(&firstPart, 10, &x) && PhStringToInteger64(&secondPart, 10, &y))
            {
                scalableIntegerPair = PhAllocate(sizeof(PH_SCALABLE_INTEGER_PAIR));
                scalableIntegerPair->X = (LONG)x;
                scalableIntegerPair->Y = (LONG)y;
                scalableIntegerPair->Scale = (ULONG)scale;
                Setting->u.Pointer = scalableIntegerPair;
                return TRUE;
            }
            else
            {
                return FALSE;
            }
        }
    }

    return FALSE;
}
BOOLEAN PhLoadSettingsColumnSet(
    _In_ PWSTR SettingName,
    _In_ PPH_STRING ColumnSetName,
    _Out_ PPH_STRING *TreeListSettings,
    _Out_ PPH_STRING *TreeSortSettings
    )
{
    PPH_STRING treeSettings = NULL;
    PPH_STRING sortSettings = NULL;
    PPH_STRING settingsString;
    ULONG64 count;
    ULONG64 index;
    PH_STRINGREF remaining;
    PH_STRINGREF part;

    settingsString = PhaGetStringSetting(SettingName);
    remaining = settingsString->sr;

    if (remaining.Length == 0)
        return FALSE;

    if (!PhSplitStringRefAtChar(&remaining, '-', &part, &remaining))
        return FALSE;
    if (!PhStringToInteger64(&part, 10, &count))
        return FALSE;

    for (index = 0; index < count; index++)
    {
        PH_STRINGREF columnSetNamePart;
        PH_STRINGREF columnSetSettingPart;
        PH_STRINGREF columnSetSortPart;

        if (remaining.Length == 0)
            break;

        PhSplitStringRefAtChar(&remaining, '-', &columnSetNamePart, &remaining);
        PhSplitStringRefAtChar(&remaining, '-', &columnSetSettingPart, &remaining);
        PhSplitStringRefAtChar(&remaining, '-', &columnSetSortPart, &remaining);

        if (PhEqualStringRef(&columnSetNamePart, &ColumnSetName->sr, FALSE))
        {
            treeSettings = PhCreateString2(&columnSetSettingPart);
            sortSettings = PhCreateString2(&columnSetSortPart);
            break;
        }
    }

    if (!PhIsNullOrEmptyString(treeSettings) && !PhIsNullOrEmptyString(sortSettings))
    {
        *TreeListSettings = treeSettings;
        *TreeSortSettings = sortSettings;
        return TRUE;
    }
    else
    {
        if (treeSettings)
            PhDereferenceObject(treeSettings);
        if (sortSettings)
            PhDereferenceObject(sortSettings);
        return FALSE;
    }
}
Beispiel #16
0
VOID FindNetworkAdapters(
    _In_ PDV_NETADAPTER_CONTEXT Context
    )
{
    if (Context->UseAlternateMethod)
    {
        ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_INTERFACES;
        ULONG bufferLength = 0;
        PVOID buffer;

        if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &bufferLength) != ERROR_BUFFER_OVERFLOW)
            return;

        buffer = PhAllocate(bufferLength);
        memset(buffer, 0, bufferLength);

        if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, buffer, &bufferLength) == ERROR_SUCCESS)
        {
            PhAcquireQueuedLockShared(&NetworkAdaptersListLock);

            for (PIP_ADAPTER_ADDRESSES i = buffer; i; i = i->Next)
            {
                PPH_STRING description;

                if (description = PhCreateString(i->Description))
                {
                    AddNetworkAdapterToListView(
                        Context,
                        TRUE,
                        i->IfIndex,
                        i->Luid,
                        PhConvertMultiByteToUtf16(i->AdapterName),
                        description
                        );

                    PhDereferenceObject(description);
                }
            }

            PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
        }

        PhFree(buffer);
    }
    else
    {
        static PH_STRINGREF devicePathSr = PH_STRINGREF_INIT(L"\\\\.\\");
        PPH_LIST deviceList;
        PWSTR deviceInterfaceList;
        ULONG deviceInterfaceListLength = 0;
        PWSTR deviceInterface;

        if (CM_Get_Device_Interface_List_Size(
            &deviceInterfaceListLength,
            (PGUID)&GUID_DEVINTERFACE_NET,
            NULL,
            CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES
            ) != CR_SUCCESS)
        {
            return;
        }

        deviceInterfaceList = PhAllocate(deviceInterfaceListLength * sizeof(WCHAR));
        memset(deviceInterfaceList, 0, deviceInterfaceListLength * sizeof(WCHAR));

        if (CM_Get_Device_Interface_List(
            (PGUID)&GUID_DEVINTERFACE_NET,
            NULL,
            deviceInterfaceList,
            deviceInterfaceListLength,
            CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES
            ) != CR_SUCCESS)
        {
            PhFree(deviceInterfaceList);
            return;
        }

        deviceList = PH_AUTO(PhCreateList(1));

        for (deviceInterface = deviceInterfaceList; *deviceInterface; deviceInterface += PhCountStringZ(deviceInterface) + 1)
        {
            HKEY keyHandle;
            DEVINST deviceInstanceHandle;
            PPH_STRING deviceDescription = NULL;

            if (!QueryNetworkDeviceInterfaceDescription(deviceInterface, &deviceInstanceHandle, &deviceDescription))
                continue;

            if (CM_Open_DevInst_Key(
                deviceInstanceHandle,
                KEY_QUERY_VALUE,
                0,
                RegDisposition_OpenExisting,
                &keyHandle,
                CM_REGISTRY_SOFTWARE
                ) == CR_SUCCESS)
            {
                PNET_ENUM_ENTRY adapterEntry;
                HANDLE deviceHandle;

                adapterEntry = PhAllocate(sizeof(NET_ENUM_ENTRY));
                memset(adapterEntry, 0, sizeof(NET_ENUM_ENTRY));

                adapterEntry->DeviceGuid = PhQueryRegistryString(keyHandle, L"NetCfgInstanceId");
                adapterEntry->DeviceInterface = PhConcatStringRef2(&devicePathSr, &adapterEntry->DeviceGuid->sr);
                adapterEntry->DeviceLuid.Info.IfType = PhQueryRegistryUlong64(keyHandle, L"*IfType");
                adapterEntry->DeviceLuid.Info.NetLuidIndex = PhQueryRegistryUlong64(keyHandle, L"NetLuidIndex");

                if (NT_SUCCESS(PhCreateFileWin32(
                    &deviceHandle,
                    PhGetString(adapterEntry->DeviceInterface),
                    FILE_GENERIC_READ,
                    FILE_ATTRIBUTE_NORMAL,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    FILE_OPEN,
                    FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
                    )))
                {
                    PPH_STRING adapterName;

                    // Try query the full adapter name
                    adapterName = NetworkAdapterQueryName(deviceHandle, adapterEntry->DeviceGuid);

                    if (adapterName)
                        adapterEntry->DeviceName = adapterName;

                    adapterEntry->DevicePresent = TRUE;

                    NtClose(deviceHandle);
                }

                if (!adapterEntry->DeviceName)
                    adapterEntry->DeviceName = PhCreateString2(&deviceDescription->sr);

                PhAddItemList(deviceList, adapterEntry);

                NtClose(keyHandle);
            }

            PhClearReference(&deviceDescription);
        }

        // Cleanup.
        PhFree(deviceInterfaceList);

        // Sort the entries
        qsort(deviceList->Items, deviceList->Count, sizeof(PVOID), AdapterEntryCompareFunction);

        PhAcquireQueuedLockShared(&NetworkAdaptersListLock);

        for (ULONG i = 0; i < deviceList->Count; i++)
        {
            PNET_ENUM_ENTRY entry = deviceList->Items[i];

            AddNetworkAdapterToListView(
                Context,
                entry->DevicePresent,
                0,
                entry->DeviceLuid,
                entry->DeviceGuid,
                entry->DeviceName
                );

            if (entry->DeviceName)
                PhDereferenceObject(entry->DeviceName);
            if (entry->DeviceInterface)
                PhDereferenceObject(entry->DeviceInterface);
            // Note: DeviceGuid is disposed by WM_DESTROY.

            PhFree(entry);
        }

        PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
    }

    // HACK: Show all unknown devices.
    PhAcquireQueuedLockShared(&NetworkAdaptersListLock);

    for (ULONG i = 0; i < NetworkAdaptersList->Count; i++)
    {
        ULONG index = ULONG_MAX;
        BOOLEAN found = FALSE;
        PDV_NETADAPTER_ENTRY entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]);

        if (!entry)
            continue;

        while ((index = PhFindListViewItemByFlags(
            Context->ListViewHandle,
            index,
            LVNI_ALL
            )) != ULONG_MAX)
        {
            PDV_NETADAPTER_ID param;

            if (PhGetListViewItemParam(Context->ListViewHandle, index, &param))
            {
                if (EquivalentNetAdapterId(param, &entry->AdapterId))
                {
                    found = TRUE;
                }
            }
        }

        if (!found)
        {
            PPH_STRING description;
            MIB_IF_ROW2 interfaceRow;

            memset(&interfaceRow, 0, sizeof(MIB_IF_ROW2));
            interfaceRow.InterfaceLuid = entry->AdapterId.InterfaceLuid;
            interfaceRow.InterfaceIndex = entry->AdapterId.InterfaceIndex;

            // HACK: Try query the description from the interface entry (if it exists).
            if (GetIfEntry2(&interfaceRow) == NO_ERROR)
                description = PhCreateString(interfaceRow.Description);
            else
                description = PhCreateString(L"Unknown network adapter");

            if (description)
            {
                AddNetworkAdapterToListView(
                    Context,
                    FALSE,
                    entry->AdapterId.InterfaceIndex,
                    entry->AdapterId.InterfaceLuid,
                    entry->AdapterId.InterfaceGuid,
                    description
                    );

                PhDereferenceObject(description);
            }
        }

        PhDereferenceObjectDeferDelete(entry);
    }

    PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
}