BUTObtenir poignée à clé avec NtCreateKey/NtOpenKey
Je suis en train de faire une fonction qui permettra de créer une sous-clé donnée dans la ruche de Registre HKCU, ou ouvrir la sous-clé si elle existe déjà, retourne TRUE.
NOTES
Soit RegSidPath
représentent un chemin de registre HKCU complet avec un user SID
qui y est annexé tel que \\Registry\\User\\S-1-5-20-xxxxxx-xxxxxx-xxxxxxxx-1050
Soit KeyToCreate
représentent un chemin de registre spécifique tel que \\Software\\MyCompany\\MySoftware\\MySubKey
CODE
J'ai la fonction suivante:
BOOL CreateHKCUKey(PWCHAR RegSidPath, PWCHAR KeyToCreate) {
UNICODE_STRING uString;
RtlInitUnicodeString(&uString, RegSidPath);
OBJECT_ATTRIBUTES ObjAttributes;
InitializeObjectAttributes(&ObjAttributes, &uString, OBJ_CASE_INSENSITIVE, 0, 0);
HANDLE BaseKeyHandle = NULL;
NTSTATUS Status = NtOpenKey(&BaseKeyHandle, KEY_CREATE_SUB_KEY, &ObjAttributes);
if (NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) {
UNICODE_STRING KeyString = { 0 };
do {
PWCHAR NextSubKey = StrStrW((KeyString.Length == 0 ? KeyToCreate : KeyString.Buffer) + 1, L"\\");
DWORD CurrentKeyLength = lstrlenW(KeyToCreate) - lstrlenW(NextSubKey);
PWCHAR CurrentSubKey = PWCHAR(GlobalAlloc(GPTR, CurrentKeyLength + sizeof(WCHAR)));
if (CurrentSubKey != ERROR) {
memcpy(CurrentSubKey, KeyToCreate, CurrentKeyLength * sizeof(WCHAR));
CurrentSubKey[CurrentKeyLength] = UNICODE_NULL;
RtlInitUnicodeString(&KeyString, CurrentSubKey);
OBJECT_ATTRIBUTES KeyAttributes;
InitializeObjectAttributes(&KeyAttributes, &KeyString, OBJ_CASE_INSENSITIVE, &BaseKeyHandle, 0);
HANDLE CurrentHiveEntry = NULL;
Status = NtOpenKey(&CurrentHiveEntry, KEY_CREATE_SUB_KEY, &KeyAttributes);
if (RtlNtStatusToDosError(Status) == ERROR_BAD_PATHNAME) {
InitializeObjectAttributes(&KeyAttributes, &KeyString, OBJ_CASE_INSENSITIVE, &CurrentHiveEntry, 0);
DWORD DefaultDisposition;
Status = NtCreateKey(&CurrentHiveEntry, KEY_CREATE_SUB_KEY, &KeyAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &DefaultDisposition);
if (NT_SUCCESS(Status)) {
if (StrCmpNW(KeyString.Buffer + uString.Length, KeyString.Buffer, lstrlenW(KeyToCreate) == 0))
return TRUE;
else continue;
} else break;
} else break;
BaseKeyHandle = CurrentHiveEntry;
}
} while (TRUE);
}
NtClose(BaseKeyHandle);
return FALSE;
}
PROBLÈME
Chaque fois que le code arrive à cette partie de la fonction
Status = NtOpenKey(&CurrentHiveEntry, KEY_CREATE_SUB_KEY, &KeyAttributes);
if (RtlNtStatusToDosError(Status) == ERROR_BAD_PATHNAME) {
La valeur de retour est toujours ERROR_BAD_PATHNAME (161)
même si la sous-clé en cours existe déjà.
QUESTION
Quelle est la raison, et ce que je fais mal? Y a-t-il quelque chose que j'ai fait qui ne soit pas correct, et comment puis-je le réparer?
Au point d'échec, quelle est la valeur de 'CurrentSubKey'? En outre, la seule erreur que vous vérifiez est 'ERROR_BAD_PATHNAME', si la boucle précédente a échoué avec un autre code d'erreur, alors' BaseKeyHandle' ne pointera pas là où vous l'attendez. (Oh, et vous fuyez les poignées.) –
@HarryJohnston '\\ Software' - que puis-je faire pour déboguer l'erreur –
Pourquoi avez-vous besoin de l'API NT pour cela? – Anders