Tworzę aplikację CMD w trybie użytkownika przy użyciu VS 2013 w C++ i próbuję użyć w niej rodzimych funkcji edycji rejestru. Próbuję otworzyć określony klucz za pomocą "NtOpenKey", ale zawsze kończy się to niepowodzeniem z "STATUS_OBJECT_NAME_NOT_FOUND" i jestem pewien, że "obiekt" jest na swoim miejscu, więc powód musi być gdzie indziej. Chcę używać macierzystego rejestru API, ponieważ mogą obsługiwać "Ukryte klucze rejestru" - spójrz na here, aby uzyskać więcej informacji. Oto fragment mojego kodu:NtOpenKey kończy się niepowodzeniem z 0xC0000034 - jak to naprawić?
#include <Windows.h>
#include <tchar.h>
#include <wininet.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "Nt_Funcs_declr.h" //here I have manually included the native api declarations as normally I'm denied to use them but they're exported in ntdll.dll so basically it is possible
#include <zlib.h>
//Obitain Steam folder path
wchar_t *GetSteamPathBuffer()
{
//Open the Sofware Steam registry
OBJECT_ATTRIBUTES objAttrs;
objAttrs.Length = sizeof(OBJECT_ATTRIBUTES);
objAttrs.RootDirectory = NULL;
wchar_t strRegSteam [] = L"\\Registry\\Machine\\SOFTWARE\\Valve";
UNICODE_STRING uStrTmp = { sizeof(strRegSteam), sizeof(strRegSteam), strRegSteam };
objAttrs.ObjectName = &uStrTmp;
objAttrs.Attributes = OBJ_CASE_INSENSITIVE; //
objAttrs.SecurityDescriptor = NULL;
objAttrs.SecurityQualityOfService = NULL;
HANDLE pKey;
ULONG tmmp = NtOpenKey(&pKey, GENERIC_READ, &objAttrs); //here it fails with 'STATUS_OBJECT_NAME_NOT_FOUND'
if(tmmp)
{
cout << "Error: " << GetLastError();
return NULL;
}
//....
}
I Nt_Funcs_declr.h:
#pragma once
//NTDLL import declarations
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
//
// Unicode strings are counted 16-bit character strings. If they are
// NULL terminated, Length does not include trailing NULL.
//
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
#ifdef MIDL_PASS
[size_is(MaximumLength/2), length_is((Length)/2)] USHORT * Buffer;
#else // MIDL_PASS
_Field_size_bytes_part_(MaximumLength, Length) PWCH Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
//
// Valid values for the Attributes field
//
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
NtOpenKey(
_Out_ PHANDLE KeyHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes
);
typedef enum _KEY_INFORMATION_CLASS {
KeyBasicInformation,
KeyNodeInformation,
KeyFullInformation,
KeyNameInformation,
KeyCachedInformation,
KeyFlagsInformation,
KeyVirtualizationInformation,
KeyHandleTagsInformation,
KeyTrustInformation,
MaxKeyInfoClass // MaxKeyInfoClass should always be the last enum
} KEY_INFORMATION_CLASS;
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
NtQueryKey(
_In_ HANDLE KeyHandle,
_In_ KEY_INFORMATION_CLASS KeyInformationClass,
_Out_writes_bytes_opt_(Length) PVOID KeyInformation,
_In_ ULONG Length,
_Out_ PULONG ResultLength
);
typedef enum _KEY_VALUE_INFORMATION_CLASS {
KeyValueBasicInformation,
KeyValueFullInformation,
KeyValuePartialInformation,
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64,
MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum
} KEY_VALUE_INFORMATION_CLASS;
typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
_Field_size_bytes_(DataLength) UCHAR Data[1]; // Variable size
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
NtQueryValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
_Out_writes_bytes_opt_(Length) PVOID KeyValueInformation,
_In_ ULONG Length,
_Out_ PULONG ResultLength
);
UWAGA: To dla prupose edukacyjnego więc proszę nie pytaj mnie dlaczego nie używam API Win32.
"nie znaleziono nazwy obiektu", co oczywiście jest * bardzo * częstym problemem. Dlaczego, na Boga, robisz to, to nie dodaje niczego do RegOpenKeyEx(), tylko przenosi nędzę i samookaleczone zamieszanie. –
To jest na edukacyjną próbę - więc lepiej postaraj się mi pomóc. – AnArrayOfFunctions
To nikogo nie kształci, jest szkodliwe. To nie jest forum. –