예제 #1
0
BOOLEAN RemoveDirectoryPath(_In_ PWSTR DirPath)
{
    HANDLE findHandle;
    PPH_STRING findPath;
    WIN32_FIND_DATA data = { 0 };

    findPath = PhConcatStrings2(DirPath, L"\\*");

    if ((findHandle = FindFirstFile(findPath->Buffer, &data)) == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
        {
            PhDereferenceObject(findPath);
            return TRUE;
        }

        PhDereferenceObject(findPath);
        return FALSE;
    }

    do
    {
        if (PhEqualStringZ(data.cFileName, L".", TRUE) || PhEqualStringZ(data.cFileName, L"..", TRUE))
            continue;

        if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            PPH_STRING dirPath = PhConcatStrings(3, DirPath, L"\\", data.cFileName);

            RemoveDirectoryPath(dirPath->Buffer);
            PhDereferenceObject(dirPath);
        }
        else
        {
            PPH_STRING filePath = PhConcatStrings(3, DirPath, L"\\", data.cFileName);

            if (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
            {
                _wchmod(filePath->Buffer, _S_IWRITE);
            }

            SetupDeleteDirectoryFile(filePath->Buffer);
            PhDereferenceObject(filePath);
        }

    } while (FindNextFile(findHandle, &data));

    FindClose(findHandle);

    // Delete the parent directory
    RemoveDirectory(DirPath);

    PhDereferenceObject(findPath);
    return TRUE;
}
예제 #2
0
/**
 * Modifies the security descriptor of an object.
 *
 * \param SecurityDescriptor A security descriptor containing security information to set.
 * \param SecurityInformation The security information to retrieve.
 * \param Context A pointer to a PH_STD_OBJECT_SECURITY structure describing the object.
 *
 * \remarks This function may be used for the \a SetObjectSecurity callback in
 * PhCreateSecurityPage() or PhEditSecurity().
 */
_Callback_ NTSTATUS PhStdSetObjectSecurity(
    _In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
    _In_ SECURITY_INFORMATION SecurityInformation,
    _In_opt_ PVOID Context
)
{
    NTSTATUS status;
    PPH_STD_OBJECT_SECURITY stdObjectSecurity;
    HANDLE handle;

    stdObjectSecurity = (PPH_STD_OBJECT_SECURITY)Context;

    status = stdObjectSecurity->OpenObject(
                 &handle,
                 PhGetAccessForSetSecurity(SecurityInformation),
                 stdObjectSecurity->Context
             );

    if (!NT_SUCCESS(status))
        return status;

    if (PhEqualStringZ(stdObjectSecurity->ObjectType, L"Service", TRUE))
    {
        status = PhSetSeObjectSecurity(handle, SE_SERVICE, SecurityInformation, SecurityDescriptor);
        CloseServiceHandle(handle);
    }
    else
    {
        status = PhSetObjectSecurity(handle, SecurityInformation, SecurityDescriptor);
        NtClose(handle);
    }

    return status;
}
예제 #3
0
PWSTR XmlParseToken(
    _In_ PWSTR XmlString,
    _In_ PWSTR XmlTokenName
    )
{
    PWSTR xmlTokenNext = NULL;
    PWSTR xmlStringData;
    PWSTR xmlTokenString;

    xmlStringData = PhDuplicateStringZ(XmlString);

    xmlTokenString = wcstok_s(
        xmlStringData,
        L"<>",
        &xmlTokenNext
        );

    while (xmlTokenString)
    {
        if (PhEqualStringZ(xmlTokenString, XmlTokenName, TRUE))
        {
            // We found the value.
            xmlTokenString = wcstok_s(NULL, L"<>", &xmlTokenNext);
            break;
        }

        xmlTokenString = wcstok_s(NULL, L"<>", &xmlTokenNext);
    }

    if (xmlTokenString)
    {
        PWSTR xmlStringDup = PhDuplicateStringZ(xmlTokenString);

        PhFree(xmlStringData);

        return xmlStringDup;
    }

    PhFree(xmlStringData);
    return NULL;
}
예제 #4
0
/**
 * Gets access entries for an object type.
 *
 * \param Type The name of the object type.
 * \param AccessEntries A variable which receives an array of access entry structures. You must free
 * the buffer with PhFree() when you no longer need it.
 * \param NumberOfAccessEntries A variable which receives the number of access entry structures
 * returned in
 * \a AccessEntries.
 */
BOOLEAN PhGetAccessEntries(
    _In_ PWSTR Type,
    _Out_ PPH_ACCESS_ENTRY *AccessEntries,
    _Out_ PULONG NumberOfAccessEntries
    )
{
    ULONG i;
    PPH_SPECIFIC_TYPE specificType = NULL;
    PPH_ACCESS_ENTRY accessEntries;

    if (PhEqualStringZ(Type, L"ALPC Port", TRUE))
    {
        Type = L"AlpcPort";
    }
    else if (PhEqualStringZ(Type, L"Port", TRUE))
    {
        Type = L"AlpcPort";
    }
    else if (PhEqualStringZ(Type, L"WaitablePort", TRUE))
    {
        Type = L"AlpcPort";
    }
    else if (PhEqualStringZ(Type, L"Process", TRUE))
    {
        if (WindowsVersion >= WINDOWS_VISTA)
            Type = L"Process60";
    }
    else if (PhEqualStringZ(Type, L"Thread", TRUE))
    {
        if (WindowsVersion >= WINDOWS_VISTA)
            Type = L"Thread60";
    }

    // Find the specific type.
    for (i = 0; i < sizeof(PhSpecificTypes) / sizeof(PH_SPECIFIC_TYPE); i++)
    {
        if (PhEqualStringZ(PhSpecificTypes[i].Type, Type, TRUE))
        {
            specificType = &PhSpecificTypes[i];
            break;
        }
    }

    if (specificType)
    {
        ULONG sizeOfEntries;

        // Copy the specific access entries and append the standard access entries.

        if (specificType->HasSynchronize)
            sizeOfEntries = specificType->SizeOfAccessEntries + sizeof(PhStandardAccessEntries);
        else
            sizeOfEntries = specificType->SizeOfAccessEntries + sizeof(PhStandardAccessEntries) - sizeof(PH_ACCESS_ENTRY);

        accessEntries = PhAllocate(sizeOfEntries);
        memcpy(accessEntries, specificType->AccessEntries, specificType->SizeOfAccessEntries);

        if (specificType->HasSynchronize)
        {
            memcpy(
                PTR_ADD_OFFSET(accessEntries, specificType->SizeOfAccessEntries),
                PhStandardAccessEntries,
                sizeof(PhStandardAccessEntries)
                );
        }
        else
        {
            memcpy(
                PTR_ADD_OFFSET(accessEntries, specificType->SizeOfAccessEntries),
                &PhStandardAccessEntries[1],
                sizeof(PhStandardAccessEntries) - sizeof(PH_ACCESS_ENTRY)
                );
        }

        *AccessEntries = accessEntries;
        *NumberOfAccessEntries = sizeOfEntries / sizeof(PH_ACCESS_ENTRY);
    }
    else
    {
        accessEntries = PhAllocate(sizeof(PhStandardAccessEntries));
        memcpy(accessEntries, PhStandardAccessEntries, sizeof(PhStandardAccessEntries));

        *AccessEntries = accessEntries;
        *NumberOfAccessEntries = sizeof(PhStandardAccessEntries) / sizeof(PH_ACCESS_ENTRY);
    }

    return TRUE;
}
예제 #5
0
PPH_STRING FindDiskDeviceInstance(
    _In_ PPH_STRING DevicePath
    )
{
    PPH_STRING deviceIdString = NULL;
    HDEVINFO deviceInfoHandle;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
    SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail;
    ULONG deviceInfoLength = 0;

    if ((deviceInfoHandle = SetupDiGetClassDevs(
        &GUID_DEVINTERFACE_DISK,
        NULL,
        NULL,
        DIGCF_DEVICEINTERFACE
        )) == INVALID_HANDLE_VALUE)
    {
        return NULL;
    }

    for (ULONG i = 0; SetupDiEnumDeviceInterfaces(deviceInfoHandle, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++)
    {
        if (SetupDiGetDeviceInterfaceDetail(
            deviceInfoHandle,
            &deviceInterfaceData,
            0,
            0,
            &deviceInfoLength,
            &deviceInfoData
            ) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        {
            continue;
        }

        deviceInterfaceDetail = PhAllocate(deviceInfoLength);
        deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        if (SetupDiGetDeviceInterfaceDetail(
            deviceInfoHandle,
            &deviceInterfaceData,
            deviceInterfaceDetail,
            deviceInfoLength,
            &deviceInfoLength,
            &deviceInfoData
            ))
        {
            if (PhEqualStringZ(deviceInterfaceDetail->DevicePath, DevicePath->Buffer, TRUE))
            {
                deviceIdString = PhCreateStringEx(NULL, 0x100);

                SetupDiGetDeviceInstanceId(
                    deviceInfoHandle,
                    &deviceInfoData,
                    deviceIdString->Buffer,
                    (ULONG)deviceIdString->Length,
                    NULL
                    );

                PhTrimToNullTerminatorString(deviceIdString);
            }
        }

        PhFree(deviceInterfaceDetail);
    }

    SetupDiDestroyDeviceInfoList(deviceInfoHandle);

    return deviceIdString;
}
예제 #6
0
static PDNS_RECORD _SearchRootQuery(
    _In_ PWCHAR RemoteAddressString, 
    _In_ PDNS_RECORD DnsCacheList
    )
{
    PDNS_RECORD p = DnsCacheList;
    PWCHAR orig = RemoteAddressString;
    PDNS_RECORD result = NULL;
    WCHAR ipAddrString[INET6_ADDRSTRLEN] = L"";

    while (p)
    {
        BOOLEAN found = FALSE;

        if (p->wType == DNS_TYPE_A)
        {
            RtlIpv4AddressToString((IN_ADDR*)&p->Data.A.IpAddress, ipAddrString);

            if (PhEqualStringZ(ipAddrString, orig, TRUE))
            {
                found = TRUE;
            }
        }

        if (p->wType == DNS_TYPE_AAAA)
        {
            RtlIpv6AddressToString((IN6_ADDR*)&p->Data.AAAA.Ip6Address, ipAddrString);

            if (PhEqualStringZ(ipAddrString, orig, TRUE))
            {
                found = TRUE;
            }
        }

        if (p->wType == DNS_TYPE_MX && PhEqualStringZ(orig, p->Data.MX.pNameExchange, TRUE))
        {
            found = TRUE;
        }

        if (p->wType == DNS_TYPE_SRV && PhEqualStringZ(orig, p->Data.SRV.pNameTarget, TRUE))
        {
            found = TRUE;
        }
        else if (p->wType == DNS_TYPE_CNAME && PhEqualStringZ(p->Data.CNAME.pNameHost, orig, TRUE))
        {
            found = TRUE;
        }

        if (found)
        {
            PDNS_RECORD tmp = DnsRecordCopy(p);
            tmp->pNext = result;
            result = tmp;
        }

        p = p->pNext;
    }

    if (result)
    {
        PDNS_RECORD p = result;
        PDNS_RECORD finalResult = NULL;

        while (p)
        {
            PDNS_RECORD r = _SearchRootQuery(p->pName, DnsCacheList);
            if (r)
            {
                PDNS_RECORD t = r;

                while (t->pNext)
                    t = t->pNext;

                t->pNext = finalResult;
                finalResult = r;
            }

            p = p->pNext;
        }

        if (finalResult)
        {
            DnsRecordListFree(result, DnsFreeRecordList);
            return finalResult;
        }

        return result;
    }

    return NULL;
}
예제 #7
0
HICON PhGetFileShellIcon(
    _In_opt_ PWSTR FileName,
    _In_opt_ PWSTR DefaultExtension,
    _In_ BOOLEAN LargeIcon
    )
{
    SHFILEINFO fileInfo;
    ULONG iconFlag;
    HICON icon;

    if (DefaultExtension && PhEqualStringZ(DefaultExtension, L".exe", TRUE))
    {
        // Special case for executable files (see above for reasoning).

        icon = NULL;

        if (FileName)
        {
            ExtractIconEx(
                FileName,
                0,
                LargeIcon ? &icon : NULL,
                !LargeIcon ? &icon : NULL,
                1
                );
        }

        if (!icon)
        {
            PhGetStockApplicationIcon(
                !LargeIcon ? &icon : NULL,
                LargeIcon ? &icon : NULL
                );

            if (icon)
                icon = DuplicateIcon(NULL, icon);
        }

        return icon;
    }

    iconFlag = LargeIcon ? SHGFI_LARGEICON : SHGFI_SMALLICON;
    icon = NULL;

    if (FileName && SHGetFileInfo(
        FileName,
        0,
        &fileInfo,
        sizeof(SHFILEINFO),
        SHGFI_ICON | iconFlag
        ))
    {
        icon = fileInfo.hIcon;
    }

    if (!icon && DefaultExtension)
    {
        if (SHGetFileInfo(
            DefaultExtension,
            FILE_ATTRIBUTE_NORMAL,
            &fileInfo,
            sizeof(SHFILEINFO),
            SHGFI_ICON | iconFlag | SHGFI_USEFILEATTRIBUTES
            ))
            icon = fileInfo.hIcon;
    }

    return icon;
}
예제 #8
0
_Callback_ NTSTATUS SxStdSetObjectSecurity(
    _In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
    _In_ SECURITY_INFORMATION SecurityInformation,
    _In_opt_ PVOID Context
    )
{
    NTSTATUS status;
    PPH_STD_OBJECT_SECURITY stdObjectSecurity;
    HANDLE handle;

    stdObjectSecurity = (PPH_STD_OBJECT_SECURITY)Context;

    if (
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaAccount", TRUE) ||
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaPolicy", TRUE) ||
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaSecret", TRUE) ||
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaTrusted", TRUE)
        )
    {
        status = stdObjectSecurity->OpenObject(
            &handle,
            PhGetAccessForSetSecurity(SecurityInformation),
            stdObjectSecurity->Context
            );

        if (!NT_SUCCESS(status))
            return status;

        status = LsaSetSecurityObject(
            handle,
            SecurityInformation,
            SecurityDescriptor
            );

        LsaClose(handle);
    }
    else if (
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamAlias", TRUE) ||
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamDomain", TRUE) ||
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamGroup", TRUE) ||
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamServer", TRUE) ||
        PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamUser", TRUE)
        )
    {
        status = stdObjectSecurity->OpenObject(
            &handle,
            PhGetAccessForSetSecurity(SecurityInformation),
            stdObjectSecurity->Context
            );

        if (!NT_SUCCESS(status))
            return status;

        status = SamSetSecurityObject(
            handle,
            SecurityInformation,
            SecurityDescriptor
            );

        SamCloseHandle(handle);
    }
    else
    {
        status = PhStdSetObjectSecurity(SecurityDescriptor, SecurityInformation, Context);
    }

    return status;
}
예제 #9
0
static VOID ShowStatusMenu(
    _In_ HWND hwndDlg
    )
{
    PPH_STRING cacheEntryName;
        
    cacheEntryName = PhGetSelectedListViewItemText(ListViewWndHandle);

    if (cacheEntryName)
    {
        POINT cursorPos;
        PPH_EMENU menu;
        PPH_EMENU_ITEM selectedItem;

        GetCursorPos(&cursorPos);

        menu = PhCreateEMenu();
        PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Remove", NULL, NULL), -1);

        selectedItem = PhShowEMenu(
            menu,
            ListViewWndHandle,
            PH_EMENU_SHOW_LEFTRIGHT,
            PH_ALIGN_LEFT | PH_ALIGN_TOP,
            cursorPos.x,
            cursorPos.y
            );

        if (selectedItem && selectedItem->Id != -1)
        {
            switch (selectedItem->Id)
            {
            case 1:
                {
                    INT lvItemIndex = PhFindListViewItemByFlags(
                        ListViewWndHandle,
                        -1,
                        LVNI_SELECTED
                        );

                    if (lvItemIndex != -1)
                    {
                        if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage(
                            hwndDlg,
                            L"remove",
                            cacheEntryName->Buffer,
                            NULL,
                            FALSE
                            ))
                        {
                            PATOM_TABLE_INFORMATION atomTable = NULL;

                            if (!NT_SUCCESS(PhEnumAtomTable(&atomTable)))
                                return;

                            for (ULONG i = 0; i < atomTable->NumberOfAtoms; i++)
                            {
                                PATOM_BASIC_INFORMATION atomInfo = NULL;

                                if (!NT_SUCCESS(PhQueryAtomTableEntry(atomTable->Atoms[i], &atomInfo)))
                                    continue;

                                if (!PhEqualStringZ(atomInfo->Name, cacheEntryName->Buffer, TRUE))
                                    continue;

                                do
                                {
                                    if (!NT_SUCCESS(NtDeleteAtom(atomTable->Atoms[i])))
                                    {
                                        break;
                                    }

                                    PhFree(atomInfo);
                                    atomInfo = NULL;

                                    if (!NT_SUCCESS(PhQueryAtomTableEntry(atomTable->Atoms[i], &atomInfo)))
                                        break;

                                } while (atomInfo->UsageCount >= 1);

                                ListView_DeleteItem(ListViewWndHandle, lvItemIndex);

                                if (atomInfo)
                                {
                                    PhFree(atomInfo);
                                }
                            }

                            PhFree(atomTable);
                        }
                    }
                }
                break;
            }
        }

        PhDestroyEMenu(menu);
        PhDereferenceObject(cacheEntryName);
    }
}