void do_enumeratekey(PWSTR Name) { ULONG Index,Length,i; KEY_BASIC_INFORMATION KeyInformation[5]; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hKey1; UNICODE_STRING KeyName; RtlInitUnicodeString(&KeyName, Name); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE , NULL, NULL); Status=NtOpenKey( &hKey1, MAXIMUM_ALLOWED, &ObjectAttributes); 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"); } } NtClose(hKey1); }
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); }
NTSTATUS WINAPI SafeNtEnumerateKey( HANDLE KeyHandle, ULONG Index, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength ) { NTSTATUS rc; if (CheckOldFunction(&OldNtEnumerateKey)) rc=OldNtEnumerateKey(KeyHandle,Index,KeyInformationClass,KeyInformation,Length,ResultLength); else rc=NtEnumerateKey(KeyHandle,Index,KeyInformationClass,KeyInformation,Length,ResultLength); return rc; }
NTSTATUS PiInitializeSystemEnumSubKeys( IN HANDLE CurrentKeyHandle, IN PUNICODE_STRING ValueName ) /*++ Routine Description: This routine checks to see if the key whose handle was passed in contains a value whose name was specified by the ValueName argument. If so, it resets this value to a REG_DWORD 0. It then enumerates all subkeys under the current key, and recursively calls itself for each one. Arguments: CurrentKeyHandle - Supplies a handle to the key which will be enumerated. ValueName - Supplies a pointer to the value entry name to be initialized. Return Value: None. --*/ { NTSTATUS Status; PKEY_BASIC_INFORMATION KeyInformation; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; USHORT i; ULONG TempValue, ResultLength; UNICODE_STRING UnicodeName; HANDLE WorkHandle; // // Set "FoundAtEnum=" entry of current key to FALSE, if exists. // Status = IopGetRegistryValue(CurrentKeyHandle, ValueName->Buffer, &KeyValueInformation ); if(NT_SUCCESS(Status)) { ExFreePool(KeyValueInformation); TempValue = 0; Status = NtSetValueKey(CurrentKeyHandle, ValueName, TITLE_INDEX_VALUE, REG_DWORD, &TempValue, sizeof(TempValue) ); if(!NT_SUCCESS(Status)) { return Status; } } // // Enumerate current node's children and apply ourselves to each one // KeyInformation = (PKEY_BASIC_INFORMATION)PiScratchBuffer; for(i = 0; TRUE; i++) { Status = NtEnumerateKey(CurrentKeyHandle, i, KeyBasicInformation, KeyInformation, PNP_LARGE_SCRATCH_BUFFER_SIZE, &ResultLength ); if(Status == STATUS_NO_MORE_ENTRIES) { break; } else if(!NT_SUCCESS(Status)) { continue; } UnicodeName.Length = (USHORT)KeyInformation->NameLength; UnicodeName.MaximumLength = (USHORT)KeyInformation->NameLength; UnicodeName.Buffer = KeyInformation->Name; Status = IopOpenRegistryKey(&WorkHandle, CurrentKeyHandle, &UnicodeName, KEY_ALL_ACCESS, FALSE ); if(!NT_SUCCESS(Status)) { continue; } Status = PiInitializeSystemEnumSubKeys(WorkHandle, ValueName); NtClose(WorkHandle); if(!NT_SUCCESS(Status)) { return Status; } } return STATUS_SUCCESS; }
static BOOLEAN IsAcpiComputer(VOID) { UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS"); OBJECT_ATTRIBUTES ObjectAttributes; PKEY_BASIC_INFORMATION pDeviceInformation = NULL; ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR); PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL; ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); ULONG RequiredSize; ULONG IndexDevice = 0; UNICODE_STRING DeviceName, ValueName; HANDLE hDevicesKey = NULL; HANDLE hDeviceKey = NULL; NTSTATUS Status; BOOLEAN ret = FALSE; InitializeObjectAttributes(&ObjectAttributes, &MultiKeyPathU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); goto cleanup; } pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } while (TRUE) { Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); if (Status == STATUS_NO_MORE_ENTRIES) break; else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); DeviceInfoLength = RequiredSize; pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); } if (!NT_SUCCESS(Status)) { DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status); goto cleanup; } IndexDevice++; /* Open device key */ DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; DeviceName.Buffer = pDeviceInformation->Name; InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, hDevicesKey, NULL); Status = NtOpenKey( &hDeviceKey, KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); goto cleanup; } /* Read identifier */ Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); ValueInfoLength = RequiredSize; pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); if (!pValueInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); } if (!NT_SUCCESS(Status)) { DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status); goto nextdevice; } else if (pValueInformation->Type != REG_SZ) { DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); goto nextdevice; } ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; ValueName.Buffer = (PWCHAR)pValueInformation->Data; if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) ValueName.Length -= sizeof(WCHAR); if (RtlCompareUnicodeString(&ValueName, &AcpiBiosIdentifier, FALSE) == 0) { DPRINT("Found ACPI BIOS\n"); ret = TRUE; goto cleanup; } nextdevice: NtClose(hDeviceKey); hDeviceKey = NULL; } cleanup: if (pDeviceInformation) RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); if (pValueInformation) RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); if (hDevicesKey) NtClose(hDevicesKey); if (hDeviceKey) NtClose(hDeviceKey); return ret; }
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); }
void Dump( HANDLE Handle ) { NTSTATUS status; PKEY_BASIC_INFORMATION KeyInformation; OBJECT_ATTRIBUTES ObjectAttributes; ULONG NamePos; ULONG index; STRING enumname; HANDLE WorkHandle; ULONG ResultLength; static char buffer[WORK_SIZE]; PUCHAR p; KeyInformation = (PKEY_BASIC_INFORMATION)buffer; NamePos = WorkName.Length; // // Print name of node we are about to dump out // print(&WorkName); printf("::\n\n"); // // Print out node's values // DumpValues(Handle); // // Enumerate node's children and apply ourselves to each one // for (index = 0; TRUE; index++) { RtlZeroMemory(KeyInformation, WORK_SIZE); status = NtEnumerateKey( Handle, index, KeyBasicInformation, KeyInformation, WORK_SIZE, &ResultLength ); if (status == STATUS_NO_MORE_ENTRIES) { WorkName.Length = NamePos; return; } else if (!NT_SUCCESS(status)) { printf("rtdmp: dump1: status = %08lx\n", status); exit(1); } enumname.Buffer = &(KeyInformation->Name[0]); enumname.Length = KeyInformation->NameLength; enumname.MaximumLength = KeyInformation->NameLength; p = WorkName.Buffer; p += WorkName.Length; *p = '\\'; p++; *p = '\0'; WorkName.Length += 2; RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&enumname); InitializeObjectAttributes( &ObjectAttributes, &enumname, 0, Handle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtOpenKey( &WorkHandle, MAXIMUM_ALLOWED, &ObjectAttributes ); if (!NT_SUCCESS(status)) { printf("rtdmp: dump2: %08lx\n", status); exit(1); } Dump(WorkHandle); NtClose(WorkHandle); WorkName.Length = NamePos; } }
NTSTATUS SampCleanup18471( ) /*++ Routine Description: Cleans up the transaction log left by fixing bug 18471. This routine builds a transaction with all the keys in the log and then commits the transaction Arguments: None. Return Value: Status codes from the NT registry APIs and NT RXact APIs --*/ { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE RootKey = NULL; HANDLE AliasKey = NULL; UCHAR Buffer[sizeof(KEY_BASIC_INFORMATION) + 15 * sizeof(WCHAR)]; UCHAR Buffer2[sizeof(KEY_BASIC_INFORMATION) + 15 * sizeof(WCHAR)]; UNICODE_STRING KeyName; WCHAR KeyBuffer[100]; PKEY_BASIC_INFORMATION BasicInfo = (PKEY_BASIC_INFORMATION) Buffer; PKEY_BASIC_INFORMATION BasicInfo2 = (PKEY_BASIC_INFORMATION) Buffer2; ULONG BasicInfoLength; ULONG Index, Index2; // // Open the 18471 key in the registry // RtlInitUnicodeString( &KeyName, SAMP_FIX_18471_KEY_NAME ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL ); Status = NtOpenKey( &RootKey, KEY_READ | DELETE, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { // // If the error was that the key did not exist, then there // is nothing to cleanup, so return success. // if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { return(STATUS_SUCCESS); } return(Status); } // // Create a transaction to add all the keys to delete to // Status = SampAcquireWriteLock(); if (!NT_SUCCESS(Status)) { goto Cleanup; } SampSetTransactionDomain(0); SampTransactionWithinDomain = FALSE; // // Now enumerate all the subkeys of the root 18471 key // Index = 0; do { Status = NtEnumerateKey( RootKey, Index, KeyBasicInformation, BasicInfo, sizeof(Buffer), &BasicInfoLength ); // // // Check if this is the RXACT key. If it is, we don't want // to add it to the delete log. // // Otherwise open this key and enumerate all the subkeys of it. // if (NT_SUCCESS(Status) && ((BasicInfo->NameLength != RTLP_RXACT_KEY_NAME_SIZE) || memcmp( BasicInfo->Name, RTLP_RXACT_KEY_NAME, RTLP_RXACT_KEY_NAME_SIZE ) ) ) { KeyName.Buffer = BasicInfo->Name; KeyName.Length = (USHORT) BasicInfo->NameLength; KeyName.MaximumLength = KeyName.Length; InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, RootKey, NULL ); // // Open the key for the alias rid. This really should // succeed // Status = NtOpenKey( &AliasKey, KEY_READ, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { break; } // // Enumerate all the subkeys (the alias members) and add them // to the transaction // Index2 = 0; do { Status = NtEnumerateKey( AliasKey, Index2, KeyBasicInformation, BasicInfo2, sizeof(Buffer2), &BasicInfoLength ); if (NT_SUCCESS(Status)) { // // Build the name of this key from the alias rid and the // member rid // KeyName.Buffer = KeyBuffer; KeyName.MaximumLength = sizeof(KeyBuffer); SampBuild18471CleanupKey( &KeyName, BasicInfo->Name, BasicInfo->NameLength, BasicInfo2->Name, BasicInfo2->NameLength ); Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationDelete, &KeyName, 0, NULL, 0 ); } Index2++; } while (NT_SUCCESS(Status)); NtClose(AliasKey); AliasKey = NULL; // // If we suffered a serious error, get out of here now // if (!NT_SUCCESS(Status)) { if (Status != STATUS_NO_MORE_ENTRIES) { break; } else { Status = STATUS_SUCCESS; } } // // Add the alias RID key to the RXact now - we need to add it // after deleting all the children // KeyName.Buffer = KeyBuffer; KeyName.MaximumLength = sizeof(KeyBuffer); SampBuild18471CleanupKey( &KeyName, BasicInfo->Name, BasicInfo->NameLength, NULL, 0 ); Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationDelete, &KeyName, 0, NULL, 0 ); } Index++; } while (NT_SUCCESS(Status)); if (Status == STATUS_NO_MORE_ENTRIES) { Status = STATUS_SUCCESS; } if (!NT_SUCCESS(Status)) { goto Cleanup; } RtlInitUnicodeString( &KeyName, SAMP_FIX_18471_SHORT_KEY_NAME ); Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationDelete, &KeyName, 0, NULL, 0 ); if (NT_SUCCESS(Status)) { // // Write the new server revision to indicate that this // upgrade has been performed // ULONG Revision = SAMP_SERVER_REVISION; PSAMP_OBJECT ServerContext; // // We need to read the fixed attributes of the server objects. // Create a context to do that. // ServerContext = SampCreateContext( SampServerObjectType, TRUE ); if ( ServerContext != NULL ) { ServerContext->RootKey = SampKey; Status = SampSetFixedAttributes( ServerContext, &Revision ); if (NT_SUCCESS(Status)) { Status = SampStoreObjectAttributes( ServerContext, TRUE ); } SampDeleteContext( ServerContext ); } else { Status = STATUS_INSUFFICIENT_RESOURCES; } } // // Apply the RXACT and delete the remaining keys. // Cleanup: // // Cleanup any floating bits from above. // if (NT_SUCCESS(Status)) { Status = SampReleaseWriteLock( TRUE ); } else { (VOID) SampReleaseWriteLock( FALSE ); } if (RootKey != NULL) { NtClose(RootKey); } ASSERT(AliasKey == NULL); return(Status); }
BOOL CliGetImeHotKeysFromRegistry() { BOOL fFoundAny = FALSE; HANDLE hCurrentUserKey; HANDLE hKeyHotKeys; OBJECT_ATTRIBUTES Obja; UNICODE_STRING SubKeyName; NTSTATUS Status; ULONG uIndex; // // Open the current user registry key // Status = RtlOpenCurrentUser(MAXIMUM_ALLOWED, &hCurrentUserKey); if (!NT_SUCCESS(Status)) { return fFoundAny; } RtlInitUnicodeString( &SubKeyName, szRegImeHotKey ); InitializeObjectAttributes( &Obja, &SubKeyName, OBJ_CASE_INSENSITIVE, hCurrentUserKey, NULL); Status = NtOpenKey( &hKeyHotKeys, KEY_READ, &Obja ); if (!NT_SUCCESS(Status)) { NtClose( hCurrentUserKey ); return fFoundAny; } for (uIndex = 0; TRUE; uIndex++) { BYTE KeyBuffer[sizeof(KEY_BASIC_INFORMATION) + 16 * sizeof(WCHAR)]; PKEY_BASIC_INFORMATION pKeyInfo; ULONG ResultLength; pKeyInfo = (PKEY_BASIC_INFORMATION)KeyBuffer; Status = NtEnumerateKey(hKeyHotKeys, uIndex, KeyBasicInformation, pKeyInfo, sizeof( KeyBuffer ), &ResultLength ); if (NT_SUCCESS(Status)) { if (CliSetSingleHotKey(pKeyInfo, hKeyHotKeys)) { fFoundAny = TRUE; } } else if (Status == STATUS_NO_MORE_ENTRIES) { break; } } NtClose(hKeyHotKeys); NtClose(hCurrentUserKey); return fFoundAny; }