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; }
/** * 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; }
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; }
/** * 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; }
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; }
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; }
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; }
_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; }
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); } }