Я создал этот ужасный кусок кода, чтобы узнать путь воспроизведения песен в Windows.Предполагалось, что это обычный программный продукт, поэтому я хотел, чтобы он работал с несколькими программами.Сначала я использовал handle.exe для запроса дескрипторов, открытых, скажем, foobar2000 или vlc или itunes, что бы ни проигрывало аудиофайл на самом деле.Здорово, что это сработало бы, выглядело бы что-то вроде этого:
\Device\HarddiskVolume2\Music\Mamorukun Curse OST\Mamoru-kun has been Cursed Meikai Katsugeki Arrange\02 Blossom Shower [MEIKAI ARRANGE VERSION].flac
Но в тот момент, когда я проигрывал песню с Unicode, все это ломалось и не работало.Поэтому я создал этот фрагмент кода, откуда бы ни добавлялся код, написанный кем-то еще давным-давно.Он запустился, и я получил его, чтобы выплевывать тот же тип вывода, но теперь он делает то же самое с символами Юникода.
Не совсем уверен, как бы я поделился этим в маленьких фрагментах, поэтому я собираюсьсвалить весь проект.Пожалуйста, помните, что этот код действительно плох и смущает, не будучи экспертом в C ++ или Windows API и тому подобном.
#include "Main.h"
#include <Windows.h>
#include <fstream>
PVOID GetLibraryProcAddress(LPCWSTR LibraryName, LPCSTR ProcName)
{
return GetProcAddress(LoadLibrary(LibraryName), ProcName);
}
std::string getFileType(PWSTR buffer, USHORT length) {
char* temp = new char[length];
for (int i = 0; i < length; i++) {
temp[i] = (char)buffer[i];
}
return temp;
}
int main(int argc, WCHAR *argv[])
{
std::wofstream file("example.txt");
_NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)
GetLibraryProcAddress(L"ntdll.dll", "NtQuerySystemInformation");
_NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)
GetLibraryProcAddress(L"ntdll.dll", "NtDuplicateObject");
_NtQueryObject NtQueryObject = (_NtQueryObject)
GetLibraryProcAddress(L"ntdll.dll", "NtQueryObject");
NTSTATUS status;
PSYSTEM_HANDLE_INFORMATION handleInfo;
ULONG handleInfoSize = 0x10000;
ULONG pid;
HANDLE processHandle;
ULONG i;
// I'm entering the pid of foobar here.
pid = 17304;
if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)))
{
printf("Could not open PID %d! (Don't try to open a system process.)\n", pid);
return 1;
}
handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
while ((status = NtQuerySystemInformation(
SystemHandleInformation,
handleInfo,
handleInfoSize,
NULL
)) == STATUS_INFO_LENGTH_MISMATCH)
handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
if (!NT_SUCCESS(status))
return 1;
for (i = 0; i < handleInfo->HandleCount; i++)
{
SYSTEM_HANDLE handle = handleInfo->Handles[i];
HANDLE dupHandle = NULL;
POBJECT_TYPE_INFORMATION objectTypeInfo;
PVOID objectNameInfo;
UNICODE_STRING objectName;
ULONG returnLength;
if (handle.ProcessId != pid)
continue;
if (!NT_SUCCESS(NtDuplicateObject(
processHandle,
handle.Handle,
GetCurrentProcess(),
&dupHandle,
0,
0,
0
)))
{
continue;
}
objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
if (!NT_SUCCESS(NtQueryObject(
dupHandle,
ObjectTypeInformation,
objectTypeInfo,
0x1000,
NULL
)))
{
CloseHandle(dupHandle);
continue;
}
/* Query the object name (unless it has an access of
0x0012019f, on which NtQueryObject could hang.
if (handle.GrantedAccess == 0x0012019f)
{
free(objectTypeInfo);
CloseHandle(dupHandle);
continue;
}
*/
objectNameInfo = malloc(0x1000);
if (!NT_SUCCESS(NtQueryObject(
dupHandle,
ObjectNameInformation,
objectNameInfo,
0x1000,
&returnLength
)))
{
/* Reallocate the buffer and try again.
objectNameInfo = realloc(objectNameInfo, returnLength);
if (!NT_SUCCESS(NtQueryObject(
dupHandle,
ObjectNameInformation,
objectNameInfo,
returnLength,
NULL
)))
{
free(objectTypeInfo);
free(objectNameInfo);
CloseHandle(dupHandle);
continue;
}*/
}
Большая часть того, что я пытаюсь сделать, содержится здесь внизу и имеет делос objectname.Buffer, но я ожидаю, что проблема будет исходить из приведенного выше кода, который в значительной степени волшебен для меня.
/* Cast our buffer into an UNICODE_STRING. */
objectName = *(PUNICODE_STRING)objectNameInfo;
/* Print the information! */
// looking for audio files.
std::string format[4] = { ".flac",".mp3",".ogg",".wav"};
if (objectName.Length)
{
//get handle type. looking for 'File'
std::string type = getFileType(objectTypeInfo->Name.Buffer, objectTypeInfo->Name.Length / 2);
// Check to see if this Handle is a file type.
if (!type.find("File")) {
int count;
// loop through format array.
for (const std::string & word : format) {
// loop through format word one letter at a time.
count = 0;
for (int i = 0; i < word.length(); i++) {
char bChar = objectName.Buffer[(objectName.Length / 2)-word.length()+i];
// if format word char matches bChar count++ until count == word.length;
if (word.at(i) == bChar) {
count++;
}
else {
break;
}
}
// Write the matching word to file.
if (count == word.length()) {
printf("\nFile Pulled, %ls\n\n", objectName.Buffer);
file << objectName.Buffer;
break;
}
}
}
}
free(objectTypeInfo);
free(objectNameInfo);
CloseHandle(dupHandle);
}
free(handleInfo);
CloseHandle(processHandle);
file.close();
return 0;
}
Я заставил его выплюнуть
\Device\HarddiskVolume2\Music\Yonder Voice\Wonderful View Epilogue\04. ΓRⁿ[Γ∩ΓhΓXΓΦⁿ[Γpⁿ[.flac
, которыйЭто своего рода сюрприз, но в большинстве случаев он выплевывает что-то вроде
\Device\HarddiskVolume2\Music\Unsorted\Yonder Voice -
Как будто он мгновенно попадает в символ Unicode, он обрезает все перед ним.
Ожидаетсявывод будет выглядеть так:
\Device\HarddiskVolume2\Music\Unsorted\Yonder Voice - 秘封活動記録 -月- ORIGINAL SOUNDTRACK\01. 決別の旅(TV-Size).mp3
Сейчас ожидаемый вывод выглядит как
\Device\HarddiskVolume2\Music\Unsorted\Yonder Voice -
Хотя информация все еще должна быть в буфере, потому что она читает .mp3 для печатичтобы я смог увидеть.
Надеюсь, я достаточно хорошо объяснил свою проблему, она стала довольно нишевой в некоторых отношениях, никогда не ожидал, что что-то настолько простое, чтобы идти по этому пути головных болейи растерянность.