Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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;
    }
}
Ejemplo n.º 10
0
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);

}
Ejemplo n.º 11
0
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;
}