Гугление не помогло, подобной проблемы в интернете не обнаружил =\ У меня есть процедура, с помощью которой я получаю путь к файлу логов из реестра Код (Text): BOOLEAN GetLogDir(PUNICODE_STRING LogDir) { HANDLE KeyHandle; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS ntStatus; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\My software"); UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"DbgLogDir"); ULONG ValueLength; UCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256]; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; WCHAR ResBuffer[260] = L"\\??\\"; ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwOpenKey(&KeyHandle, KEY_QUERY_VALUE, &ObjectAttributes); if( NT_SUCCESS( ntStatus ) ) { RtlZeroMemory(ValueInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION)); ntStatus = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, ValueInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256, &ValueLength); if( (NT_SUCCESS(ntStatus)) && (ValueInfo->Type == REG_SZ) ) { ZwClose(KeyHandle); //wmemcpy(&ResBuffer[4], (PWCHAR)ValueInfo->Data, wcslen((PWCHAR)ValueInfo->Data)); wcscat(ResBuffer, (PWCHAR)ValueInfo->Data); RtlInitUnicodeString(LogDir, ResBuffer); return TRUE; } else DPRINT("'ZwQueryValueKey' failed 0x%.8x\n", ntStatus); ZwClose(KeyHandle); } else DPRINT("'ZwOpenKey' failed 0x%.8x\n", ntStatus); return FALSE; } //==================== // вызываю её так: UNICODE_STRING FileName; if( !GetLogDir(&FileName) ) return; После её вызова: DPRINT("FileName = '%ws'", FileName.Buffer);// (FileName = '\??\C:\Program Files\My soft\my_debug.txt') Вызываю ZwCreateFile, возвращает ошибку STATUS_OBJECT_PATH_SYNTAX_BAD(C000003B). Если не использовать GetLogDir, а просто вызвать Код (Text): RtlInitUnicodeString(&FileName, L"\\??\\C:\\Program Files\\My soft\\my_debug.txt"); Функция завершается успешно. Прошу помощи, буду очень благодарен. Спасибо за внимание
Код (Text): void LogToFile(char Msg[]) { IO_STATUS_BLOCK IoStatus; OBJECT_ATTRIBUTES objectAttributes; HANDLE FileHandle = NULL; UNICODE_STRING FileName; NTSTATUS ntStatus; IO_STATUS_BLOCK iosb; if( !GetLogDir(&FileName) ) return; DPRINT("FileName = '%ws'", FileName.Buffer); InitializeObjectAttributes( &objectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ntStatus = ZwCreateFile( &FileHandle, FILE_APPEND_DATA, &objectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if( NT_SUCCESS( ntStatus ) ) { ZwWriteFile( FileHandle, NULL, NULL, NULL, &IoStatus, Msg, strlen(Msg), NULL, NULL ); ZwWriteFile( FileHandle, NULL, NULL, NULL, &IoStatus, "\r\n", 2, NULL, NULL ); NtFlushBuffersFiles(FileHandle, &iosb); ZwClose(FileHandle); } else DPRINT("'ZwCreateFile' failed 0x%.8x\n", ntStatus); }
Нашёл в чем дело. Правильный участок кода для функции GetLogDir : Код (Text): if( (NT_SUCCESS(ntStatus)) && (ValueInfo->Type == REG_SZ) ) { ZwClose(KeyHandle); DPRINT("ValueLength = %d; DataLength = %d; wcslen = %d\n", ValueLength, ValueInfo->DataLength, wcslen((PWCHAR)ValueInfo->Data)); // ValueLength в данном случае - размер памяти, занимаемой буфером строки // Размер памяти занимаемый строкой = sizeof(WCHAR) * StrLen (StrLen - кол-во символов строки) // ValueLength = sizeof(WCHAR) * StrLen ResBuffer = ExAllocatePool( NonPagedPool, ValueLength + (4 * sizeof(WCHAR)) ); if( ResBuffer == NULL ) { DPRINT("'GetLogDir' Empty Non-Paged Pool\n"); return FALSE; } wmemcpy(&ResBuffer[0], (PWCHAR)&(L"\\??\\"), 4); // Прибавляем к строке длину прочтённой строки. //Внимание! wcslen возвращает длину без \0 конца строки! Поэтому копируем и его! + 1 wmemcpy(&ResBuffer[4], (PWCHAR)ValueInfo->Data, wcslen((PWCHAR)ValueInfo->Data) + 1); RtlInitUnicodeString(LogDir, ResBuffer); return TRUE; } else DPRINT("'ZwQueryValueKey' failed 0x%.8x\n", ntStatus); Благодарю за внимание