NTSTATUS SampRegQueryKeyInfo(IN HANDLE KeyHandle, OUT PULONG SubKeyCount, OUT PULONG ValueCount) { KEY_FULL_INFORMATION FullInfoBuffer; ULONG Length; NTSTATUS Status; FullInfoBuffer.ClassLength = 0; FullInfoBuffer.ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class); Status = NtQueryKey(KeyHandle, KeyFullInformation, &FullInfoBuffer, sizeof(KEY_FULL_INFORMATION), &Length); TRACE("NtQueryKey() returned status 0x%08lX\n", Status); if (!NT_SUCCESS(Status)) return Status; if (SubKeyCount != NULL) *SubKeyCount = FullInfoBuffer.SubKeys; if (ValueCount != NULL) *ValueCount = FullInfoBuffer.Values; return Status; }
void test1(void) { HANDLE hKey = NULL, hKey1; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software"); ULONG Index,Length,i; KEY_BASIC_INFORMATION KeyInformation[5]; #if 0 dprintf("NtOpenKey \\Registry : "); #endif dprintf("NtOpenKey \\Registry\\Machine\\Software : "); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status=NtOpenKey( &hKey1, MAXIMUM_ALLOWED, &ObjectAttributes); dprintf("\t\t\t\tStatus =%x\n",Status); if(Status==0) { dprintf("NtQueryKey : "); Status=NtQueryKey(hKey1,KeyBasicInformation ,&KeyInformation[0], sizeof(KeyInformation) ,&Length); dprintf("\t\t\t\t\tStatus =%x\n",Status); if (Status == STATUS_SUCCESS) { dprintf("\tKey Name = "); for (i=0;i<KeyInformation[0].NameLength/2;i++) dprintf("%C",KeyInformation[0].Name[i]); dprintf("\n"); } dprintf("NtEnumerateKey : \n"); Index=0; while(Status == STATUS_SUCCESS) { Status=NtEnumerateKey(hKey1,Index++,KeyBasicInformation ,&KeyInformation[0], sizeof(KeyInformation) ,&Length); if(Status== STATUS_SUCCESS) { dprintf("\tSubKey Name = "); for (i=0;i<KeyInformation[0].NameLength/2;i++) dprintf("%C",KeyInformation[0].Name[i]); dprintf("\n"); } } dprintf("NtClose : "); Status = NtClose( hKey1 ); dprintf("\t\t\t\t\tStatus =%x\n",Status); } NtClose(hKey); }
/* * propBasicQueryKey * * Purpose: * * Set information values for Key object type * * If ExtendedInfoAvailable is FALSE then it calls propSetDefaultInfo to set Basic page properties * */ VOID propBasicQueryKey( _In_ PROP_OBJECT_INFO *Context, _In_ HWND hwndDlg, _In_ BOOL ExtendedInfoAvailable ) { NTSTATUS status; ULONG bytesNeeded; HANDLE hObject; TIME_FIELDS SystemTime; WCHAR szBuffer[MAX_PATH]; KEY_FULL_INFORMATION kfi; SetDlgItemText(hwndDlg, ID_KEYSUBKEYS, T_CannotQuery); SetDlgItemText(hwndDlg, ID_KEYVALUES, T_CannotQuery); SetDlgItemText(hwndDlg, ID_KEYLASTWRITE, T_CannotQuery); if (Context == NULL) { return; } // // Open Key object. // hObject = NULL; if (!propOpenCurrentObject(Context, &hObject, KEY_QUERY_VALUE)) { return; } RtlSecureZeroMemory(&kfi, sizeof(KEY_FULL_INFORMATION)); status = NtQueryKey(hObject, KeyFullInformation, &kfi, sizeof(KEY_FULL_INFORMATION), &bytesNeeded); if (NT_SUCCESS(status)) { //Subkeys count RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); ultostr(kfi.SubKeys, _strend(szBuffer)); SetDlgItemText(hwndDlg, ID_KEYSUBKEYS, szBuffer); //Values count RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); ultostr(kfi.Values, _strend(szBuffer)); SetDlgItemText(hwndDlg, ID_KEYVALUES, szBuffer); //LastWrite time RtlSecureZeroMemory(&SystemTime, sizeof(SystemTime)); FileTimeToLocalFileTime((PFILETIME)&kfi.LastWriteTime, (PFILETIME)&kfi.LastWriteTime); RtlTimeToTimeFields((PLARGE_INTEGER)&kfi.LastWriteTime, (PTIME_FIELDS)&SystemTime); //Month starts from 0 index if (SystemTime.Month - 1 < 0) SystemTime.Month = 1; if (SystemTime.Month > 12) SystemTime.Month = 12; RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); wsprintf(szBuffer, FORMATTED_TIME_DATE_VALUE, SystemTime.Hour, SystemTime.Minute, SystemTime.Second, SystemTime.Day, Months[SystemTime.Month - 1], SystemTime.Year); SetDlgItemText(hwndDlg, ID_KEYLASTWRITE, szBuffer); } // // Query object basic and type info if needed. // if (ExtendedInfoAvailable == FALSE) { propSetDefaultInfo(Context, hwndDlg, hObject); } NtClose(hObject); }
static BOOLEAN GetComputerIdentifier(PWSTR Identifier, ULONG IdentifierLength) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; LPCWSTR ComputerIdentifier; HANDLE ProcessorsKey; PKEY_FULL_INFORMATION pFullInfo; ULONG Size, SizeNeeded; NTSTATUS Status; DPRINT("GetComputerIdentifier() called\n"); Size = sizeof(KEY_FULL_INFORMATION); pFullInfo = (PKEY_FULL_INFORMATION)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); if (!pFullInfo) { DPRINT("RtlAllocateHeap() failed\n"); return FALSE; } /* Open the processors key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&ProcessorsKey, KEY_QUERY_VALUE , &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status); RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); return FALSE; } /* Get number of subkeys */ Status = NtQueryKey( ProcessorsKey, KeyFullInformation, pFullInfo, Size, &Size); NtClose(ProcessorsKey); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status); RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); return FALSE; } /* Find computer identifier */ if (pFullInfo->SubKeys == 0) { /* Something strange happened. No processor detected */ RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); return FALSE; } if (IsAcpiComputer()) { if (pFullInfo->SubKeys == 1) { /* Computer is mono-CPU */ ComputerIdentifier = L"ACPI UP"; } else { /* Computer is multi-CPUs */ ComputerIdentifier = L"ACPI MP"; } } else { if (pFullInfo->SubKeys == 1) { /* Computer is mono-CPU */ ComputerIdentifier = L"PC UP"; } else { /* Computer is multi-CPUs */ ComputerIdentifier = L"PC MP"; } } RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo); /* Copy computer identifier to return buffer */ SizeNeeded = (wcslen(ComputerIdentifier) + 1) * sizeof(WCHAR); if (SizeNeeded > IdentifierLength) return FALSE; RtlCopyMemory(Identifier, ComputerIdentifier, SizeNeeded); return TRUE; }
void _CRTAPI1 main(int, char *) { NTSTATUS status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING KeyName2; UNICODE_STRING ClassName; UNICODE_STRING ClassName2; UNICODE_STRING ValueName; UNICODE_STRING ValueName2; HANDLE BaseHandle; HANDLE Testhand1; ULONG Disposition; LARGE_INTEGER CompTime; ULONG buffer[100]; ULONG bufsize = sizeof(ULONG) * 100; PKEY_NODE_INFORMATION NodeInformation; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; PKEY_VALUE_BASIC_INFORMATION KeyValueBasic; ULONG ResultLength; PUCHAR datastring = "Some simple ascii data for use as a value"; PUCHAR datastring2 = "Some more not so simple data $#"; ULONG expected; PVOID tp; printf("rtmisc1: starting\n"); NodeInformation = (PKEY_NODE_INFORMATION)&(buffer[0]); KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)&(buffer[0]); KeyValueBasic = (PKEY_VALUE_BASIC_INFORMATION)&(buffer[0]); // // t0: Perform all operations against a base node, open it here. // RtlInitUnicodeString( &KeyName, L"\\REGISTRY\\MACHINE\\TEST" ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, 0, (HANDLE)NULL, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtOpenKey( &BaseHandle, MAXIMUM_ALLOWED, &ObjectAttributes ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t0: %08lx\n", status); goto punt; } // // t1: Create a key with class and title index // RtlInitUnicodeString( &ClassName, L"t1 Class Name" ); RtlInitUnicodeString( &KeyName, L"first_test_node" ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, 0, BaseHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; NtQuerySystemTime(&CompTime); // printf("ClassName@%08lx KeyName@%08lx\n", // ClassName.Buffer, KeyName.Buffer); status = NtCreateKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes, TITLE_INDEX_1, &ClassName, 0, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t1: %08lx\n", status); goto punt; } if (Disposition != REG_CREATED_NEW_KEY) { printf("rtmisc1: t1a: got old key, expected to create new one\n"); failure++; } // // t2: See if we can get data back, and if it makes sense // RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t2a: %08lx\n", status); goto punt; } if (ResultLength != 80) { printf("rtmisc1: t2i: expect 80, ResultLength = %d\n", ResultLength); failure++; } NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, FALSE, // time must be >= CompTime "rtmisc1: t2b: " ); CompTime = NodeInformation->LastWriteTime; status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t2c: %08lx\n"); goto punt; } // // t3: Reopen the key with create, see if data still there. // status = NtCreateKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes, TITLE_INDEX_1, &ClassName, 0, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t3: %08lx\n", status); goto punt; } if (Disposition != REG_OPENED_EXISTING_KEY) { printf("rtmisc1: t3a failure\n"); failure++; } RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t3b: %08lx\n", status); goto punt; } NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, FALSE, // time must be >= CompTime "rtmisc1: t3c: " ); status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t3d: %08lx\n"); goto punt; } // // t4: Reopen the key with open, see if data still there. // status = NtOpenKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t4: %08lx\n", status); goto punt; } RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t4a: %08lx\n", status); goto punt; } NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, FALSE, // time must be >= CompTime "rtmisc1: t4b: " ); // status = NtClose(Testhand1); // if (!NT_SUCCESS(status)) { // printf("rtmisc1: t4c: %08lx\n"); // exit(1); // } // // t5: Create a value // RtlInitUnicodeString( &ValueName, L"the very first value stored in the registry" ); status = NtSetValueKey( Testhand1, &ValueName, TITLE_INDEX_2, TYPE_1, datastring, strlen(datastring)+1 ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t5: %08lx\n", status); failure++; } // // t6: Read the value back // RtlZeroMemory(KeyValueInformation, bufsize); status = NtQueryValueKey( Testhand1, &ValueName, KeyValueFullInformation, KeyValueInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t6: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) + ValueName.Length + strlen(datastring) + 1; if (ResultLength != expected) { printf("rtmisc1: t6a: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if ( (KeyValueInformation->TitleIndex != TITLE_INDEX_2) || (KeyValueInformation->Type != TYPE_1) || (KeyValueInformation->NameLength != ValueName.Length) || (KeyValueInformation->DataLength != strlen(datastring)+1)) { printf("rtmisc1: t6b: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueInformation->Name[0]); if (wcsncmp(ValueName.Buffer, tp, (ValueName.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t6c: wrong name\n"); expectstring( ValueName.Buffer, (ValueName.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueInformation->Name[0]), (KeyValueInformation->NameLength/sizeof(WCHAR)) ); failure++; } tp = (PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset; if (strcmp(tp, datastring) != 0) { printf("rtmisc1: t6d: wrong data\n"); printf("expected '%s', got '%s'\n", datastring, tp); failure++; } // // t7: Create a second value // RtlInitUnicodeString( &ValueName2, L"the second value stored in the registry" ); status = NtSetValueKey( Testhand1, &ValueName2, TITLE_INDEX_3, TYPE_2, datastring2, strlen(datastring2)+1 ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t7: %08lx\n", status); failure++; } // // t8: Read the second value back (short form) // RtlZeroMemory(KeyValueBasic, bufsize); status = NtQueryValueKey( Testhand1, &ValueName2, KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t8: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + ValueName2.Length; if (ResultLength != expected) { printf("rtmisc1: t8a: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if ( (KeyValueBasic->TitleIndex != TITLE_INDEX_3) || (KeyValueBasic->Type != TYPE_2) || (KeyValueBasic->NameLength != ValueName2.Length)) { printf("rtmisc1: t8b: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueBasic->Name[0]); if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t8c: wrong name\n"); expectstring( ValueName2.Buffer, (ValueName2.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueBasic->Name[0]), (KeyValueBasic->NameLength/sizeof(WCHAR)) ); failure++; } // // t9: Enumerate the values (short form) // RtlZeroMemory(KeyValueBasic, bufsize); status = NtEnumerateValueKey( Testhand1, 0, // Index KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t9: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + ValueName.Length; if (ResultLength != expected) { printf("rtmisc1: t9a: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if (KeyValueBasic->NameLength != ValueName.Length) { printf("rtmisc1: t9b: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueBasic->Name[0]); if (wcsncmp(ValueName.Buffer, tp, (ValueName.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t9c: wrong name\n"); expectstring( ValueName.Buffer, (ValueName.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueBasic->Name[0]), (KeyValueBasic->NameLength/sizeof(WCHAR)) ); failure++; } RtlZeroMemory(KeyValueBasic, bufsize); status = NtEnumerateValueKey( Testhand1, 1, // Index KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t9d: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + ValueName2.Length; if (ResultLength != expected) { printf("rtmisc1: t9e: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if (KeyValueBasic->NameLength != ValueName2.Length) { printf("rtmisc1: t9f: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueBasic->Name[0]); if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t9g: wrong name\n"); expectstring( ValueName2.Buffer, (ValueName2.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueBasic->Name[0]), (KeyValueBasic->NameLength/sizeof(WCHAR)) ); failure++; } status = NtEnumerateValueKey( Testhand1, 2, // Index KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (status != STATUS_NO_MORE_ENTRIES) { printf("rtmisc1: t9h: %08lx\n", status); goto punt; } // // t10: create a second subkey and ennumerate the subkeys // status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10a: %08lx\n", status); failure++; } RtlInitUnicodeString( &ClassName2, L"t2 Class Name" ); RtlInitUnicodeString( &KeyName2, L"second_test_node" ); InitializeObjectAttributes( &ObjectAttributes, &KeyName2, 0, BaseHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtCreateKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes, TITLE_INDEX_2, &ClassName2, 0, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10b: %08lx\n", status); goto punt; } if (Disposition != REG_CREATED_NEW_KEY) { printf("rtmisc1: t10c: got old key, expected to create new one\n"); failure++; } // // See if we can get data back, and if it makes sense // RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10d: %08lx\n", status); goto punt; } CompTime = NodeInformation->LastWriteTime; NameClassAndTitle( NodeInformation, ClassName2, TITLE_INDEX_2, KeyName2, CompTime, TRUE, "rtmisc1: t10e: " ); status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10f: %08lx\n"); goto punt; } RtlZeroMemory(NodeInformation, bufsize); status = NtEnumerateKey( BaseHandle, 0, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10g: %08lx\n", status); failure++; } CompTime = NodeInformation->LastWriteTime; NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, TRUE, "rtmisc1: t10h: " ); RtlZeroMemory(NodeInformation, bufsize); status = NtEnumerateKey( BaseHandle, 1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10i: %08lx\n", status); failure++; } CompTime = NodeInformation->LastWriteTime; NameClassAndTitle( NodeInformation, ClassName2, TITLE_INDEX_2, KeyName2, CompTime, TRUE, "rtmisc1: t10j: " ); status = NtEnumerateKey( BaseHandle, 2, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (status != STATUS_NO_MORE_ENTRIES) { printf("rtmisc1: t10k: %08lx\n", status); failure++; } // // Summary report // if (!failure) { printf("rtmisc1: success"); exit(0); } else { printf("rtmisc1: failed, %d failures\n", failure); exit(1); } punt: failure++; printf("rtmisc1: failed, %d failures\n", failure); exit(1); }
void test9(void) { HANDLE hKey = NULL, hKey1; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry"); ULONG Index,Length,i; KEY_BASIC_INFORMATION KeyInformation[5]; KEY_VALUE_FULL_INFORMATION KeyValueInformation[5]; dprintf("NtOpenKey \\Registry : "); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status=NtOpenKey( &hKey1, MAXIMUM_ALLOWED, &ObjectAttributes); dprintf("\t\t\t\tStatus =%x\n",Status); if (Status == 0) { dprintf("NtQueryKey : "); Status = NtQueryKey(hKey1, KeyBasicInformation, &KeyInformation[0], sizeof(KeyInformation), &Length); dprintf("\t\t\t\t\tStatus =%x\n",Status); if (Status == STATUS_SUCCESS) { dprintf("\tKey Name = "); for (i=0;i<KeyInformation[0].NameLength/2;i++) dprintf("%C",KeyInformation[0].Name[i]); dprintf("\n"); } dprintf("NtEnumerateKey : \n"); Index = 0; while (Status == STATUS_SUCCESS) { Status = NtEnumerateKey(hKey1,Index++,KeyBasicInformation,&KeyInformation[0], sizeof(KeyInformation),&Length); if (Status == STATUS_SUCCESS) { dprintf("\tSubKey Name = "); for (i = 0; i < KeyInformation[0].NameLength / 2; i++) dprintf("%C",KeyInformation[0].Name[i]); dprintf("\n"); } } dprintf("NtClose : "); Status = NtClose( hKey1 ); dprintf("\t\t\t\t\tStatus =%x\n",Status); } NtClose(hKey); // RobD - hKey unused so-far, should this have been hKey1 ??? dprintf("NtOpenKey \\Registry\\Machine : "); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hKey1, MAXIMUM_ALLOWED, &ObjectAttributes); dprintf("\t\t\tStatus =%x\n",Status); //Status of c0000001 opening \Registry\Machine\System\CurrentControlSet\Services\Tcpip\Linkage // dprintf("NtOpenKey System\\CurrentControlSet\\Services\\Tcpip : "); // RtlRosInitUnicodeStringFromLiteral(&KeyName, L"System\\CurrentControlSet\\Services\\Tcpip"); #if 1 dprintf("NtOpenKey System\\ControlSet001\\Services\\Tcpip\\Parameters : "); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"System\\ControlSet001\\Services\\Tcpip\\Parameters"); #else dprintf("NtOpenKey System\\CurrentControlSet\\Services\\Tcpip : "); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"System\\CurrentControlSet\\Services\\Tcpip"); #endif InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, hKey1 , NULL); Status = NtOpenKey(&hKey, KEY_READ , &ObjectAttributes); dprintf("\t\t\tStatus =%x\n",Status); if (Status == 0) { dprintf("NtQueryValueKey : "); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"NameServer"); Status = NtQueryValueKey(hKey, &KeyName, KeyValueFullInformation, &KeyValueInformation[0], sizeof(KeyValueInformation), &Length); dprintf("\t\t\t\tStatus =%x\n",Status); if (Status == STATUS_SUCCESS) { dprintf("\tValue:DO=%d, DL=%d, NL=%d, Name = " ,KeyValueInformation[0].DataOffset ,KeyValueInformation[0].DataLength ,KeyValueInformation[0].NameLength); for (i = 0; i < 10 && i < KeyValueInformation[0].NameLength / 2; i++) dprintf("%C", KeyValueInformation[0].Name[i]); dprintf("\n"); dprintf("\t\tType = %d\n", KeyValueInformation[0].Type); if (KeyValueInformation[0].Type == REG_SZ) //dprintf("\t\tValue = %S\n", KeyValueInformation[0].Name + 1 + KeyValueInformation[0].NameLength / 2); dprintf("\t\tValue = %S\n", KeyValueInformation[0].Name + KeyValueInformation[0].NameLength / 2); } dprintf("NtEnumerateValueKey : \n"); Index = 0; while (Status == STATUS_SUCCESS) { Status = NtEnumerateValueKey(hKey, Index++, KeyValueFullInformation, &KeyValueInformation[0], sizeof(KeyValueInformation), &Length); if (Status == STATUS_SUCCESS) { dprintf("\tValue:DO=%d, DL=%d, NL=%d, Name = " ,KeyValueInformation[0].DataOffset ,KeyValueInformation[0].DataLength ,KeyValueInformation[0].NameLength); for (i = 0; i < KeyValueInformation[0].NameLength / 2; i++) dprintf("%C", KeyValueInformation[0].Name[i]); dprintf(", Type = %d\n", KeyValueInformation[0].Type); if (KeyValueInformation[0].Type == REG_SZ) dprintf("\t\tValue = %S\n", ((char*)&KeyValueInformation[0]+KeyValueInformation[0].DataOffset)); if (KeyValueInformation[0].Type == REG_DWORD) dprintf("\t\tValue = %X\n", *((DWORD*)((char*)&KeyValueInformation[0]+KeyValueInformation[0].DataOffset))); } } dprintf("NtClose : "); Status = NtClose(hKey); dprintf("\t\t\t\t\tStatus =%x\n", Status); } NtClose(hKey1); }
void EnumerateKeyTest(void) { HANDLE hKey = NULL; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software"); ULONG Index; ULONG Length; ULONG i; KEY_BASIC_INFORMATION KeyInformation[5]; dprintf("Enumerate key '\\Registry\\Machine\\Software':\n"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); dprintf("NtOpenKey:\n"); Status = NtOpenKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes); dprintf(" Status = %lx\n", Status); if (!NT_SUCCESS(Status)) return; dprintf("NtQueryKey:\n"); Status = NtQueryKey(hKey, KeyBasicInformation, &KeyInformation[0], sizeof(KeyInformation), &Length); dprintf(" Status = %lx\n", Status); if (NT_SUCCESS(Status)) { dprintf("\tKey Name = "); for (i = 0; i < KeyInformation[0].NameLength / 2; i++) dprintf("%C", KeyInformation[0].Name[i]); dprintf("\n"); } dprintf("NtEnumerateKey:\n"); Index=0; while(NT_SUCCESS(Status)) { Status = NtEnumerateKey(hKey, Index, KeyBasicInformation, &KeyInformation[0], sizeof(KeyInformation), &Length); if (NT_SUCCESS(Status)) { dprintf("\tSubKey Name = "); for (i = 0; i < KeyInformation[0].NameLength / 2; i++) dprintf("%C", KeyInformation[0].Name[i]); dprintf("\n"); } Index++; } dprintf("NtClose:\n"); Status = NtClose(hKey); dprintf(" Status = %lx\n", Status); }
static VOID RemoveAppCompatEntry( _In_ HANDLE ParentKey ) { static PH_STRINGREF keyName = PH_STRINGREF_INIT(L"ProcessHacker.exe"); ULONG bufferLength; KEY_FULL_INFORMATION fullInfo; memset(&fullInfo, 0, sizeof(KEY_FULL_INFORMATION)); if (!NT_SUCCESS(NtQueryKey( ParentKey, KeyFullInformation, &fullInfo, sizeof(KEY_FULL_INFORMATION), &bufferLength ))) { return; } for (ULONG i = 0; i < fullInfo.Values; i++) { PPH_STRING value; PKEY_VALUE_FULL_INFORMATION buffer; bufferLength = sizeof(KEY_VALUE_FULL_INFORMATION); buffer = PhAllocate(bufferLength); memset(buffer, 0, bufferLength); if (NT_SUCCESS(NtEnumerateValueKey( ParentKey, i, KeyValueFullInformation, buffer, bufferLength, &bufferLength ))) { PhFree(buffer); break; } //bufferLength = bufferLength; buffer = PhReAllocate(buffer, bufferLength); memset(buffer, 0, bufferLength); if (!NT_SUCCESS(NtEnumerateValueKey( ParentKey, i, KeyValueFullInformation, buffer, bufferLength, &bufferLength ))) { PhFree(buffer); break; } if (value = PhCreateStringEx(buffer->Name, buffer->NameLength)) { UNICODE_STRING us; PhStringRefToUnicodeString(&value->sr, &us); if (PhEndsWithStringRef(&value->sr, &keyName, TRUE)) { NtDeleteValueKey(ParentKey, &us); } PhDereferenceObject(value); } PhFree(buffer); } }