registry.c

来自「一个类似windows」· C语言 代码 · 共 714 行 · 第 1/2 页

C
714
字号
	}

      NtSetValueKey (KeyHandle,
		     ValueName,
		     0,
		     Type,
		     (PVOID)Data,
		     Size);

      RtlFreeHeap (ProcessHeap, 0, Data);
    }

  return TRUE;
}


NTSTATUS
CreateNestedKey (PHANDLE KeyHandle,
		 ACCESS_MASK DesiredAccess,
		 POBJECT_ATTRIBUTES ObjectAttributes)
{
  OBJECT_ATTRIBUTES LocalObjectAttributes;
  UNICODE_STRING LocalKeyName;
  ULONG Disposition;
  NTSTATUS Status;
  ULONG FullNameLength;
  ULONG Length;
  PWCHAR Ptr;
  HANDLE LocalKeyHandle;

  Status = NtCreateKey (KeyHandle,
			KEY_ALL_ACCESS,
			ObjectAttributes,
			0,
			NULL,
			0,
			&Disposition);
  DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status);
  if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
    return Status;

  /* Copy object attributes */
  RtlCopyMemory (&LocalObjectAttributes,
		 ObjectAttributes,
		 sizeof(OBJECT_ATTRIBUTES));
  RtlCreateUnicodeString (&LocalKeyName,
			  ObjectAttributes->ObjectName->Buffer);
  LocalObjectAttributes.ObjectName = &LocalKeyName;
  FullNameLength = LocalKeyName.Length / sizeof(WCHAR);

  /* Remove the last part of the key name and try to create the key again. */
  while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
    {
      Ptr = wcsrchr (LocalKeyName.Buffer, '\\');
      if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
	{
	  Status = STATUS_UNSUCCESSFUL;
	  break;
	}
      *Ptr = (WCHAR)0;
      LocalKeyName.Length = wcslen (LocalKeyName.Buffer) * sizeof(WCHAR);

      Status = NtCreateKey (&LocalKeyHandle,
			    KEY_ALL_ACCESS,
			    &LocalObjectAttributes,
			    0,
			    NULL,
			    0,
			    &Disposition);
      DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
    }

  if (!NT_SUCCESS(Status))
    {
      RtlFreeUnicodeString (&LocalKeyName);
      return Status;
    }

  /* Add removed parts of the key name and create them too. */
  Length = wcslen (LocalKeyName.Buffer);
  while (TRUE)
    {
      if (Length == FullNameLength)
	{
	  Status = STATUS_SUCCESS;
	  *KeyHandle = LocalKeyHandle;
	  break;
	}
      NtClose (LocalKeyHandle);

      LocalKeyName.Buffer[Length] = L'\\';
      Length = wcslen (LocalKeyName.Buffer);
      LocalKeyName.Length = Length * sizeof(WCHAR);

      Status = NtCreateKey (&LocalKeyHandle,
			    KEY_ALL_ACCESS,
			    &LocalObjectAttributes,
			    0,
			    NULL,
			    0,
			    &Disposition);
      DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
      if (!NT_SUCCESS(Status))
	break;
    }

  RtlFreeUnicodeString (&LocalKeyName);

  return Status;
}


/***********************************************************************
 *            registry_callback
 *
 * Called once for each AddReg and DelReg entry in a given section.
 */
static BOOLEAN
registry_callback (HINF hInf, PCWSTR Section, BOOLEAN Delete)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  WCHAR Buffer[MAX_INF_STRING_LENGTH];
  UNICODE_STRING Name;
  UNICODE_STRING Value;
  PUNICODE_STRING ValuePtr;
  NTSTATUS Status;
  ULONG Flags;
  ULONG Length;

  PINFCONTEXT Context;
  HANDLE KeyHandle;
  BOOLEAN Ok;


  Ok = InfFindFirstLine (hInf, Section, NULL, &Context);

  if (Ok)
    {
      for (;Ok; Ok = InfFindNextLine (Context, Context))
        {
          /* get root */
          if (!InfGetStringField (Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL))
              continue;
          if (!GetRootKey (Buffer))
            continue;

          /* get key */
          Length = wcslen (Buffer);
          if (!InfGetStringField (Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - Length, NULL))
            *Buffer = 0;

          DPRINT("KeyName: <%S>\n", Buffer);

          /* get flags */
          if (!InfGetIntField (Context, 4, (PLONG)&Flags))
            Flags = 0;

          DPRINT("Flags: %lx\n", Flags);

          RtlInitUnicodeString (&Name,
                                Buffer);

          InitializeObjectAttributes (&ObjectAttributes,
                                      &Name,
                                      OBJ_CASE_INSENSITIVE,
                                      NULL,
                                      NULL);

          if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
            {
              Status = NtOpenKey (&KeyHandle,
                                  KEY_ALL_ACCESS,
                                  &ObjectAttributes);
              if (!NT_SUCCESS(Status))
                {
                  DPRINT("NtOpenKey(%wZ) failed (Status %lx)\n", &Name, Status);
                  continue;  /* ignore if it doesn't exist */
                }
            }
          else
            {
              Status = CreateNestedKey (&KeyHandle,
                                        KEY_ALL_ACCESS,
                                        &ObjectAttributes);
              if (!NT_SUCCESS(Status))
                {
                  DPRINT("CreateNestedKey(%wZ) failed (Status %lx)\n", &Name, Status);
                  continue;
                }
            }

          /* get value name */
          if (InfGetStringField (Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL))
            {
              RtlInitUnicodeString (&Value,
                                    Buffer);
              ValuePtr = &Value;
            }
          else
            {
              ValuePtr = NULL;
            }

          /* and now do it */
          if (!do_reg_operation (KeyHandle, ValuePtr, Context, Flags))
            {
              NtClose (KeyHandle);
              return FALSE;
            }

          NtClose (KeyHandle);
        }
      InfFreeContext(Context);
    }

  return TRUE;
}


BOOLEAN
ImportRegistryFile(PWSTR Filename,
		   PWSTR Section,
		   BOOLEAN Delete)
{
  WCHAR FileNameBuffer[MAX_PATH];
  UNICODE_STRING FileName;
  HINF hInf;
  NTSTATUS Status;
  ULONG ErrorLine;

  /* Load inf file from install media. */
  wcscpy(FileNameBuffer, SourceRootPath.Buffer);
  wcscat(FileNameBuffer, L"\\reactos\\");
  wcscat(FileNameBuffer, Filename);

  RtlInitUnicodeString(&FileName,
		       FileNameBuffer);

  Status = InfOpenFile(&hInf,
		       &FileName,
		       &ErrorLine);
  if (!NT_SUCCESS(Status))
    {
      DPRINT1("InfOpenFile() failed (Status %lx)\n", Status);
      return FALSE;
    }

  if (!registry_callback (hInf, L"AddReg", FALSE))
    {
      DPRINT1("registry_callback() failed\n");
    }

  InfCloseFile (hInf);

  return TRUE;
}


BOOLEAN
SetInstallPathValue(PUNICODE_STRING InstallPath)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE");
  UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"InstallPath");
  HANDLE KeyHandle;
  NTSTATUS Status;

  /* Create the 'secret' InstallPath key */			   
  InitializeObjectAttributes (&ObjectAttributes,
			      &KeyName,
			      OBJ_CASE_INSENSITIVE,
			      NULL,
			      NULL);
  Status =  NtOpenKey (&KeyHandle,
		       KEY_ALL_ACCESS,
		       &ObjectAttributes);
  if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
      return FALSE;
    }

  Status = NtSetValueKey (KeyHandle,
			  &ValueName,
			  0,
			  REG_SZ,
			  (PVOID)InstallPath->Buffer,
			  InstallPath->Length);
  NtClose(KeyHandle);
  if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
      return FALSE;
    }

  return TRUE;
}

BOOLEAN
SetMountedDeviceValue(CHAR Letter, ULONG Signature, LARGE_INTEGER StartingOffset)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  WCHAR ValueNameBuffer[16];
  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices");
  UNICODE_STRING ValueName;
  REG_DISK_MOUNT_INFO MountInfo;
  NTSTATUS Status;
  HANDLE KeyHandle;

  swprintf(ValueNameBuffer, L"\\DosDevices\\%C:", Letter);
  RtlInitUnicodeString(&ValueName, ValueNameBuffer);
  
  InitializeObjectAttributes (&ObjectAttributes,
			      &KeyName,
			      OBJ_CASE_INSENSITIVE,
			      NULL,
			      NULL);
  Status =  NtOpenKey (&KeyHandle,
		       KEY_ALL_ACCESS,
		       &ObjectAttributes);
  if (!NT_SUCCESS(Status))
    {
      Status = NtCreateKey(&KeyHandle, 
                           KEY_ALL_ACCESS,
                           &ObjectAttributes,
                           0,
                           NULL,
                           REG_OPTION_NON_VOLATILE,
                           NULL);
    }

  if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
      return FALSE;
    }

  MountInfo.Signature = Signature;
  MountInfo.StartingOffset = StartingOffset;
  Status = NtSetValueKey (KeyHandle,
			  &ValueName,
			  0,
			  REG_BINARY,
			  (PVOID)&MountInfo,
			  sizeof(MountInfo));
  NtClose(KeyHandle);
  if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
      return FALSE;
    }

  return TRUE;
}

/* EOF */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?