⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootsup.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
  Status = NtOpenFile(&FileHandle,
		      GENERIC_READ,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(Status);
  }

  Status = NtReadFile(FileHandle,
		      NULL,
		      NULL,
		      NULL,
		      &IoStatusBlock,
		      OrigBootSector,
		      SECTORSIZE,
		      NULL,
		      NULL);
  NtClose(FileHandle);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(Status);
  }


  /* Allocate buffer for new bootsector */
  NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
					             0,
                                                     sizeof(PARTITION_SECTOR));
  if (NewBootSector == NULL)
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(STATUS_INSUFFICIENT_RESOURCES);
  }

  /* Read new bootsector from SrcPath */
  RtlInitUnicodeString(&Name,
		       SrcPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_READ,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  Status = NtReadFile(FileHandle,
		      NULL,
		      NULL,
		      NULL,
		      &IoStatusBlock,
		      NewBootSector,
		      sizeof(PARTITION_SECTOR),
		      NULL,
		      NULL);
  NtClose(FileHandle);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  /* Copy partition table from old MBR to new */
  RtlCopyMemory (&NewBootSector->Signature,
		 &OrigBootSector->Signature,
		 sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */);

  /* Free the original boot sector */
  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);

  /* Write new bootsector to RootPath */
  RtlInitUnicodeString(&Name,
		       RootPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_WRITE,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
  if (!NT_SUCCESS(Status))
  {
    DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  Status = NtWriteFile(FileHandle,
		       NULL,
		       NULL,
		       NULL,
		       &IoStatusBlock,
		       NewBootSector,
		       SECTORSIZE,
		       NULL,
		       NULL);
  NtClose(FileHandle);

  /* Free the new boot sector */
  RtlFreeHeap(ProcessHeap, 0, NewBootSector);

  return(Status);
}


NTSTATUS
InstallFat16BootCodeToDisk(PWSTR SrcPath,
			   PWSTR RootPath)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  IO_STATUS_BLOCK IoStatusBlock;
  UNICODE_STRING Name;
  HANDLE FileHandle;
  NTSTATUS Status;
  PUCHAR OrigBootSector;
  PUCHAR NewBootSector;

  /* Allocate buffer for original bootsector */
  OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
					   0,
					   SECTORSIZE);
  if (OrigBootSector == NULL)
    return(STATUS_INSUFFICIENT_RESOURCES);

  /* Read current boot sector into buffer */
  RtlInitUnicodeString(&Name,
		       RootPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_READ,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(Status);
  }

  Status = NtReadFile(FileHandle,
		      NULL,
		      NULL,
		      NULL,
		      &IoStatusBlock,
		      OrigBootSector,
		      SECTORSIZE,
		      NULL,
		      NULL);
  NtClose(FileHandle);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(Status);
  }


  /* Allocate buffer for new bootsector */
  NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
					  0,
					  SECTORSIZE);
  if (NewBootSector == NULL)
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(STATUS_INSUFFICIENT_RESOURCES);
  }

  /* Read new bootsector from SrcPath */
  RtlInitUnicodeString(&Name,
		       SrcPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_READ,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  Status = NtReadFile(FileHandle,
		      NULL,
		      NULL,
		      NULL,
		      &IoStatusBlock,
		      NewBootSector,
		      SECTORSIZE,
		      NULL,
		      NULL);
  NtClose(FileHandle);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  /* Adjust bootsector (copy a part of the FAT16 BPB) */
  memcpy((NewBootSector + 3),
	 (OrigBootSector + 3),
	 59);  /* FAT16 BPB length*/

  /* Free the original boot sector */
  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);

  /* Write new bootsector to RootPath */
  RtlInitUnicodeString(&Name,
		       RootPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_WRITE,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
  if (!NT_SUCCESS(Status))
  {
    DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

#if 0
  FilePosition.QuadPart = 0;
#endif
  Status = NtWriteFile(FileHandle,
		       NULL,
		       NULL,
		       NULL,
		       &IoStatusBlock,
		       NewBootSector,
		       SECTORSIZE,
		       NULL,
		       NULL);
  NtClose(FileHandle);

  /* Free the new boot sector */
  RtlFreeHeap(ProcessHeap, 0, NewBootSector);

  return(Status);
}


NTSTATUS
InstallFat32BootCodeToDisk(PWSTR SrcPath,
			   PWSTR RootPath)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  IO_STATUS_BLOCK IoStatusBlock;
  UNICODE_STRING Name;
  HANDLE FileHandle;
  NTSTATUS Status;
  PUCHAR OrigBootSector;
  PUCHAR NewBootSector;
  LARGE_INTEGER FileOffset;
  USHORT BackupBootSector;

  /* Allocate buffer for original bootsector */
  OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
					   0,
					   SECTORSIZE);
  if (OrigBootSector == NULL)
    return(STATUS_INSUFFICIENT_RESOURCES);

  /* Read current boot sector into buffer */
  RtlInitUnicodeString(&Name,
		       RootPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_READ,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(Status);
  }

  Status = NtReadFile(FileHandle,
		      NULL,
		      NULL,
		      NULL,
		      &IoStatusBlock,
		      OrigBootSector,
		      SECTORSIZE,
		      NULL,
		      NULL);
  NtClose(FileHandle);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(Status);
  }


  /* Allocate buffer for new bootsector (2 sectors) */
  NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
					  0,
					  2 * SECTORSIZE);
  if (NewBootSector == NULL)
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    return(STATUS_INSUFFICIENT_RESOURCES);
  }

  /* Read new bootsector from SrcPath */
  RtlInitUnicodeString(&Name,
		       SrcPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_READ,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  Status = NtReadFile(FileHandle,
		      NULL,
		      NULL,
		      NULL,
		      &IoStatusBlock,
		      NewBootSector,
		      2 * SECTORSIZE,
		      NULL,
		      NULL);
  NtClose(FileHandle);
  if (!NT_SUCCESS(Status))
  {
    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  /* Adjust bootsector (copy a part of the FAT32 BPB) */
  memcpy((NewBootSector + 3),
	 (OrigBootSector + 3),
	 87); /* FAT32 BPB length */

  /* Get the location of the backup boot sector */
  BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x32];

  /* Free the original boot sector */
  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);

  /* Write the first sector of the new bootcode to DstPath */
  RtlInitUnicodeString(&Name,
		       RootPath);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_WRITE,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
  if (!NT_SUCCESS(Status))
  {
    DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  /* Write sector 0 */
  FileOffset.QuadPart = 0ULL;
  Status = NtWriteFile(FileHandle,
		       NULL,
		       NULL,
		       NULL,
		       &IoStatusBlock,
		       NewBootSector,
		       SECTORSIZE,
		       &FileOffset,
		       NULL);
  if (!NT_SUCCESS(Status))
  {
    DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
    NtClose(FileHandle);
    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
    return(Status);
  }

  /* Write backup boot sector */
  if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
  {
    FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE);
    Status = NtWriteFile(FileHandle,
			 NULL,
			 NULL,
			 NULL,
			 &IoStatusBlock,
			 NewBootSector,
			 SECTORSIZE,
			 &FileOffset,
			 NULL);
    if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
      NtClose(FileHandle);
      RtlFreeHeap(ProcessHeap, 0, NewBootSector);
      return(Status);
    }
  }

  /* Write sector 14 */
  FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
  Status = NtWriteFile(FileHandle,
		       NULL,
		       NULL,
		       NULL,
		       &IoStatusBlock,
		       (NewBootSector + SECTORSIZE),
		       SECTORSIZE,
		       &FileOffset,
		       NULL);
  if (!NT_SUCCESS(Status))
  {
    DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
  }
  NtClose(FileHandle);

  /* Free the new boot sector */
  RtlFreeHeap(ProcessHeap, 0, NewBootSector);

  return(Status);
}


static NTSTATUS
UnprotectBootIni(PWSTR FileName,
		 PULONG Attributes)
{
  UNICODE_STRING Name;
  OBJECT_ATTRIBUTES ObjectAttributes;
  IO_STATUS_BLOCK IoStatusBlock;
  FILE_BASIC_INFORMATION FileInfo;
  HANDLE FileHandle;
  NTSTATUS Status;

  RtlInitUnicodeString(&Name,
		       FileName);

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

  Status = NtOpenFile(&FileHandle,
		      GENERIC_READ|GENERIC_WRITE,
		      &ObjectAttributes,
		      &IoStatusBlock,
		      0,
		      FILE_SYNCHRONOUS_IO_NONALERT);
  if (Status == STATUS_NO_SUCH_FILE)
  {
    DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
    *Attributes = 0;
    return(STATUS_SUCCESS);
  }
  if (!NT_SUCCESS(Status))
  {
    DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
    return(Status);
  }

  Status = NtQueryInformationFile(FileHandle,
				  &IoStatusBlock,
				  &FileInfo,
				  sizeof(FILE_BASIC_INFORMATION),
				  FileBasicInformation);
  if (!NT_SUCCESS(Status))
  {
    DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
    NtClose(FileHandle);
    return(Status);
  }

  *Attributes = FileInfo.FileAttributes;

⌨️ 快捷键说明

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