ReactOS  0.4.15-dev-507-g90aff8d
boot.c File Reference
#include "btrfs_drv.h"
Include dependency graph for boot.c:

Go to the source code of this file.

Classes

struct  DEVOBJ_EXTENSION2
 
struct  system_root
 

Macros

#define DOE_START_PENDING   0x10
 

Enumerations

enum  system_root_type { system_root_unknown, system_root_partition, system_root_btrfs }
 

Functions

NTSTATUS RtlUnicodeStringPrintf (PUNICODE_STRING DestinationString, const WCHAR *pszFormat,...)
 
static void get_system_root (system_root *sr)
 
static void change_symlink (uint32_t disk_num, uint32_t partition_num, BTRFS_UUID *uuid)
 
static void mountmgr_notification (BTRFS_UUID *uuid)
 
static void check_boot_options ()
 
void boot_add_device (DEVICE_OBJECT *pdo)
 
void __stdcall check_system_root (PDRIVER_OBJECT DriverObject, PVOID Context, ULONG Count)
 

Variables

ERESOURCE pdo_list_lock
 
LIST_ENTRY pdo_list
 
ERESOURCE boot_lock
 
PDRIVER_OBJECT drvobj
 
BTRFS_UUID boot_uuid
 
uint64_t boot_subvol = 0
 

Macro Definition Documentation

◆ DOE_START_PENDING

#define DOE_START_PENDING   0x10

Definition at line 41 of file boot.c.

Enumeration Type Documentation

◆ system_root_type

Enumerator
system_root_unknown 
system_root_partition 
system_root_btrfs 

Definition at line 53 of file boot.c.

Function Documentation

◆ boot_add_device()

void boot_add_device ( DEVICE_OBJECT pdo)

Definition at line 442 of file boot.c.

442  {
444 
445  AddDevice(drvobj, pdo);
446 
447  // To stop Windows sneakily setting DOE_START_PENDING
448  pdode->dont_report = true;
449 
450  if (pdo->DeviceObjectExtension) {
451  ((DEVOBJ_EXTENSION2*)pdo->DeviceObjectExtension)->ExtensionFlags &= ~DOE_START_PENDING;
452 
453  if (pdode && pdode->vde && pdode->vde->device)
454  ((DEVOBJ_EXTENSION2*)pdode->vde->device->DeviceObjectExtension)->ExtensionFlags &= ~DOE_START_PENDING;
455  }
456 
457  mountmgr_notification(&pdode->uuid);
458 }
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
PDEVICE_OBJECT device
Definition: btrfs_drv.h:883
#define DOE_START_PENDING
Definition: boot.c:41
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDRIVER_OBJECT drvobj
Definition: btrfs.c:68
static void mountmgr_notification(BTRFS_UUID *uuid)
Definition: boot.c:297
volume_device_extension * vde
Definition: btrfs_drv.h:897

Referenced by add_volume_device(), and check_system_root().

◆ change_symlink()

static void change_symlink ( uint32_t  disk_num,
uint32_t  partition_num,
BTRFS_UUID uuid 
)
static

Definition at line 247 of file boot.c.

247  {
249  UNICODE_STRING us, us2;
250  WCHAR symlink[60], target[(sizeof(BTRFS_VOLUME_PREFIX) / sizeof(WCHAR)) + 36], *w;
251 #ifdef __REACTOS__
252  unsigned int i;
253 #endif
254 
255  us.Buffer = symlink;
256  us.Length = 0;
257  us.MaximumLength = sizeof(symlink);
258 
259  Status = RtlUnicodeStringPrintf(&us, L"\\Device\\Harddisk%u\\Partition%u", disk_num, partition_num);
260  if (!NT_SUCCESS(Status)) {
261  ERR("RtlUnicodeStringPrintf returned %08lx\n", Status);
262  return;
263  }
264 
266  if (!NT_SUCCESS(Status))
267  ERR("IoDeleteSymbolicLink returned %08lx\n", Status);
268 
270 
271  w = &target[(sizeof(BTRFS_VOLUME_PREFIX) / sizeof(WCHAR)) - 1];
272 
273 #ifndef __REACTOS__
274  for (unsigned int i = 0; i < 16; i++) {
275 #else
276  for (i = 0; i < 16; i++) {
277 #endif
278  *w = hex_digit(uuid->uuid[i] >> 4); w++;
279  *w = hex_digit(uuid->uuid[i] & 0xf); w++;
280 
281  if (i == 3 || i == 5 || i == 7 || i == 9) {
282  *w = L'-';
283  w++;
284  }
285  }
286 
287  *w = L'}';
288 
289  us2.Buffer = target;
290  us2.Length = us2.MaximumLength = sizeof(target);
291 
292  Status = IoCreateSymbolicLink(&us, &us2);
293  if (!NT_SUCCESS(Status))
294  ERR("IoCreateSymbolicLink returned %08lx\n", Status);
295 }
#define hex_digit(c)
Definition: btrfs_drv.h:1794
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
USHORT MaximumLength
Definition: env_spec_w32.h:370
static const BYTE us[]
Definition: encode.c:689
LONG NTSTATUS
Definition: precomp.h:26
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define BTRFS_VOLUME_PREFIX
Definition: btrfs_drv.h:131
NTSTATUS RtlUnicodeStringPrintf(PUNICODE_STRING DestinationString, const WCHAR *pszFormat,...)
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
Definition: msctf.idl:510
GLenum target
Definition: glext.h:7315

Referenced by check_system_root().

◆ check_boot_options()

static void check_boot_options ( )
static

Definition at line 356 of file boot.c.

356  {
358  WCHAR* s;
359 
360  static const WCHAR pathw[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control";
361  static const WCHAR namew[] = L"SystemStartOptions";
362  static const WCHAR subvol[] = L"SUBVOL=";
363 
364  _SEH2_TRY {
365  HANDLE control;
368  ULONG kvfilen = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR) + (255 * sizeof(WCHAR));
371  WCHAR* options;
372 
373  path.Buffer = (WCHAR*)pathw;
374  path.Length = path.MaximumLength = sizeof(pathw) - sizeof(WCHAR);
375 
377 
378  Status = ZwOpenKey(&control, KEY_QUERY_VALUE, &oa);
379  if (!NT_SUCCESS(Status)) {
380  ERR("ZwOpenKey returned %08lx\n", Status);
381  return;
382  }
383 
384  // FIXME - don't fail if value too long (can we query for the length?)
385 
386  kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
387  if (!kvfi) {
388  ERR("out of memory\n");
389  NtClose(control);
390  return;
391  }
392 
393  name.Buffer = (WCHAR*)namew;
394  name.Length = name.MaximumLength = sizeof(namew) - sizeof(WCHAR);
395 
396  Status = ZwQueryValueKey(control, &name, KeyValueFullInformation, kvfi,
397  kvfilen, &kvfilen);
398  if (!NT_SUCCESS(Status)) {
399  ERR("ZwQueryValueKey returned %08lx\n", Status);
400  NtClose(control);
401  return;
402  }
403 
404  NtClose(control);
405 
406  options = (WCHAR*)((uint8_t*)kvfi + kvfi->DataOffset);
407  options[kvfi->DataLength / sizeof(WCHAR)] = 0; // FIXME - make sure buffer long enough to allow this
408 
409  s = wcsstr(options, subvol);
410 
411  if (!s)
412  return;
413 
414  s += (sizeof(subvol) / sizeof(WCHAR)) - 1;
415 
416  boot_subvol = 0;
417 
418  while (true) {
419  if (*s >= '0' && *s <= '9') {
420  boot_subvol <<= 4;
421  boot_subvol |= *s - '0';
422  } else if (*s >= 'a' && *s <= 'f') {
423  boot_subvol <<= 4;
424  boot_subvol |= *s - 'a' + 0xa;
425  } else if (*s >= 'A' && *s <= 'F') {
426  boot_subvol <<= 4;
427  boot_subvol |= *s - 'A' + 0xa;
428  } else
429  break;
430 
431  s++;
432  }
434  return;
435  } _SEH2_END;
436 
437  if (boot_subvol != 0) {
438  TRACE("passed subvol %I64x in boot options\n", boot_subvol);
439  }
440 }
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
struct _KEY_VALUE_FULL_INFORMATION KEY_VALUE_FULL_INFORMATION
GLsizei const GLchar ** path
Definition: glext.h:7234
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
LONG NTSTATUS
Definition: precomp.h:26
uint64_t boot_subvol
Definition: boot.c:34
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_SEH2_TRY
Definition: create.c:4226
#define ALLOC_TAG
Definition: btrfs_drv.h:91
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
int options
Definition: main.c:106
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
GLdouble s
Definition: gl.h:2039
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
_SEH2_END
Definition: create.c:4400
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
struct _root * subvol
Definition: btrfs_drv.h:299
Definition: name.c:38
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by check_system_root().

◆ check_system_root()

void __stdcall check_system_root ( PDRIVER_OBJECT  DriverObject,
PVOID  Context,
ULONG  Count 
)

Definition at line 470 of file boot.c.

470  {
471  system_root sr;
472  LIST_ENTRY* le;
473  bool done = false;
474  PDEVICE_OBJECT pdo_to_add = NULL;
475  volume_child* boot_vc = NULL;
476 
477  TRACE("(%p, %p, %lu)\n", DriverObject, Context, Count);
478 
479  // wait for any PNP notifications in progress to finish
482 
483  get_system_root(&sr);
484 
485  if (sr.type == system_root_partition) {
486  TRACE("system boot partition is disk %u, partition %u\n", sr.disk_num, sr.partition_num);
487 
489 
490  le = pdo_list.Flink;
491  while (le != &pdo_list) {
492  LIST_ENTRY* le2;
494 
496 
497  le2 = pdode->children.Flink;
498 
499  while (le2 != &pdode->children) {
501 
502  if (vc->disk_num == sr.disk_num && vc->part_num == sr.partition_num) {
503  change_symlink(sr.disk_num, sr.partition_num, &pdode->uuid);
504  done = true;
505 
506  vc->boot_volume = true;
507  boot_uuid = pdode->uuid;
508 
509  if (!pdode->vde)
510  pdo_to_add = pdode->pdo;
511 
512  boot_vc = vc;
513 
514  break;
515  }
516 
517  le2 = le2->Flink;
518  }
519 
520  if (done) {
521  le2 = pdode->children.Flink;
522 
523  while (le2 != &pdode->children) {
525 
526  /* On Windows 7 we need to clear the DO_SYSTEM_BOOT_PARTITION flag of
527  * all of our underlying partition objects - otherwise IopMountVolume
528  * will bugcheck with UNMOUNTABLE_BOOT_VOLUME when it tries and fails
529  * to mount one. */
530  if (vc->devobj) {
531  PDEVICE_OBJECT dev = vc->devobj;
532 
534 
535  while (dev) {
537 
538  dev->Flags &= ~DO_SYSTEM_BOOT_PARTITION;
539 
541 
542  dev = dev2;
543  }
544  }
545 
546  le2 = le2->Flink;
547  }
548 
550 
551  break;
552  }
553 
555 
556  le = le->Flink;
557  }
558 
560  } else if (sr.type == system_root_btrfs) {
561  boot_uuid = sr.uuid;
562 
564 
565  le = pdo_list.Flink;
566  while (le != &pdo_list) {
568 
569  if (RtlCompareMemory(&pdode->uuid, &sr.uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
570  if (!pdode->vde)
571  pdo_to_add = pdode->pdo;
572 
573  break;
574  }
575 
576  le = le->Flink;
577  }
578 
580  }
581 
582  if (boot_vc) {
585 
586  /* On Windows 8, mountmgr!MountMgrFindBootVolume returns the first volume in its database
587  * with the DO_SYSTEM_BOOT_PARTITION flag set. We've cleared the bit on the underlying devices,
588  * but as it caches it we need to disable and re-enable the volume so mountmgr receives a PNP
589  * notification to refresh its list. */
590 
591  static const WCHAR prefix[] = L"\\??";
592 
593  name.Length = name.MaximumLength = boot_vc->pnp_name.Length + sizeof(prefix) - sizeof(WCHAR);
594 
595  name.Buffer = ExAllocatePoolWithTag(PagedPool, name.MaximumLength, ALLOC_TAG);
596  if (!name.Buffer)
597  ERR("out of memory\n");
598  else {
599  RtlCopyMemory(name.Buffer, prefix, sizeof(prefix) - sizeof(WCHAR));
600  RtlCopyMemory(&name.Buffer[(sizeof(prefix) / sizeof(WCHAR)) - 1], boot_vc->pnp_name.Buffer, boot_vc->pnp_name.Length);
601 
603  if (!NT_SUCCESS(Status))
604  ERR("IoSetDeviceInterfaceState returned %08lx\n", Status);
605 
607  if (!NT_SUCCESS(Status))
608  ERR("IoSetDeviceInterfaceState returned %08lx\n", Status);
609 
610  ExFreePool(name.Buffer);
611  }
612  }
613 
614  if (sr.type == system_root_btrfs || boot_vc)
616 
617  // If our FS depends on volumes that aren't there when we do our IoRegisterPlugPlayNotification calls
618  // in DriverEntry, bus_query_device_relations won't get called until it's too late. We need to do our
619  // own call to AddDevice here as a result. We need to clear the DOE_START_PENDING bits, or NtOpenFile
620  // will return STATUS_NO_SUCH_DEVICE.
621  if (pdo_to_add)
622  boot_add_device(pdo_to_add);
623 }
bool boot_volume
Definition: btrfs_drv.h:874
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:867
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
system_root_type type
Definition: boot.c:63
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1173
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
ULONG part_num
Definition: btrfs_drv.h:873
ERESOURCE boot_lock
Definition: btrfs.c:115
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:898
void boot_add_device(DEVICE_OBJECT *pdo)
Definition: boot.c:442
#define ALLOC_TAG
Definition: btrfs_drv.h:91
BTRFS_UUID boot_uuid
Definition: boot.c:33
LIST_ENTRY pdo_list
Definition: btrfs.c:109
BTRFS_UUID uuid
Definition: boot.c:62
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
smooth NULL
Definition: ftsmooth.c:416
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:865
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
static void change_symlink(uint32_t disk_num, uint32_t partition_num, BTRFS_UUID *uuid)
Definition: boot.c:247
PDEVICE_OBJECT NTAPI IoGetLowerDeviceObject(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1507
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ERESOURCE child_lock
Definition: btrfs_drv.h:904
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
static void get_system_root(system_root *sr)
Definition: boot.c:66
ULONG disk_num
Definition: btrfs_drv.h:872
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:118
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:27
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
uint32_t partition_num
Definition: boot.c:61
volume_device_extension * vde
Definition: btrfs_drv.h:897
Definition: name.c:38
#define ObReferenceObject
Definition: obfuncs.h:204
static void check_boot_options()
Definition: boot.c:356
LIST_ENTRY children
Definition: btrfs_drv.h:905
ERESOURCE pdo_list_lock
Definition: btrfs.c:108
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint32_t disk_num
Definition: boot.c:60
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by _Function_class_().

◆ get_system_root()

static void get_system_root ( system_root sr)
static

Definition at line 66 of file boot.c.

66  {
68  HANDLE h;
70  OBJECT_ATTRIBUTES objatt;
71  ULONG retlen = 0;
72  bool second_time = false;
73 
74  static const WCHAR system_root[] = L"\\SystemRoot";
75  static const WCHAR boot_device[] = L"\\Device\\BootDevice";
76  static const WCHAR arc_prefix[] = L"\\ArcName\\multi(0)disk(0)rdisk(";
77  static const WCHAR arc_middle[] = L")partition(";
78  static const WCHAR arc_btrfs_prefix[] = L"\\ArcName\\btrfs(";
79 
80  us.Buffer = (WCHAR*)system_root;
81  us.Length = us.MaximumLength = sizeof(system_root) - sizeof(WCHAR);
82 
84 
85  while (true) {
87  if (!NT_SUCCESS(Status)) {
88  ERR("ZwOpenSymbolicLinkObject returned %08lx\n", Status);
89  return;
90  }
91 
92  target.Length = target.MaximumLength = 0;
93 
94  Status = ZwQuerySymbolicLinkObject(h, &target, &retlen);
96  ERR("ZwQuerySymbolicLinkObject returned %08lx\n", Status);
97  NtClose(h);
98  return;
99  }
100 
101  if (retlen == 0) {
102  NtClose(h);
103  return;
104  }
105 
107  if (!target.Buffer) {
108  ERR("out of memory\n");
109  NtClose(h);
110  return;
111  }
112 
113  target.Length = target.MaximumLength = (USHORT)retlen;
114 
115  Status = ZwQuerySymbolicLinkObject(h, &target, NULL);
116  if (!NT_SUCCESS(Status)) {
117  ERR("ZwQuerySymbolicLinkObject returned %08lx\n", Status);
118  NtClose(h);
119  ExFreePool(target.Buffer);
120  return;
121  }
122 
123  NtClose(h);
124 
125  if (second_time) {
126  TRACE("boot device is %.*S\n", (int)(target.Length / sizeof(WCHAR)), target.Buffer);
127  } else {
128  TRACE("system root is %.*S\n", (int)(target.Length / sizeof(WCHAR)), target.Buffer);
129  }
130 
131  if (!second_time && target.Length >= sizeof(boot_device) - sizeof(WCHAR) &&
132  RtlCompareMemory(target.Buffer, boot_device, sizeof(boot_device) - sizeof(WCHAR)) == sizeof(boot_device) - sizeof(WCHAR)) {
133  ExFreePool(target.Buffer);
134 
135  us.Buffer = (WCHAR*)boot_device;
136  us.Length = us.MaximumLength = sizeof(boot_device) - sizeof(WCHAR);
137 
138  second_time = true;
139  } else
140  break;
141  }
142 
144 
145  if (target.Length >= sizeof(arc_prefix) - sizeof(WCHAR) &&
146  RtlCompareMemory(target.Buffer, arc_prefix, sizeof(arc_prefix) - sizeof(WCHAR)) == sizeof(arc_prefix) - sizeof(WCHAR)) {
147  WCHAR* s = &target.Buffer[(sizeof(arc_prefix) / sizeof(WCHAR)) - 1];
148  ULONG left = ((target.Length - sizeof(arc_prefix)) / sizeof(WCHAR)) + 1;
149 
150  if (left == 0 || s[0] < '0' || s[0] > '9') {
151  ExFreePool(target.Buffer);
152  return;
153  }
154 
155  sr->disk_num = 0;
156 
157  while (left > 0 && s[0] >= '0' && s[0] <= '9') {
158  sr->disk_num *= 10;
159  sr->disk_num += s[0] - '0';
160  s++;
161  left--;
162  }
163 
164  if (left <= (sizeof(arc_middle) / sizeof(WCHAR)) - 1 ||
165  RtlCompareMemory(s, arc_middle, sizeof(arc_middle) - sizeof(WCHAR)) != sizeof(arc_middle) - sizeof(WCHAR)) {
166  ExFreePool(target.Buffer);
167  return;
168  }
169 
170  s = &s[(sizeof(arc_middle) / sizeof(WCHAR)) - 1];
171  left -= (sizeof(arc_middle) / sizeof(WCHAR)) - 1;
172 
173  if (left == 0 || s[0] < '0' || s[0] > '9') {
174  ExFreePool(target.Buffer);
175  return;
176  }
177 
178  sr->partition_num = 0;
179 
180  while (left > 0 && s[0] >= '0' && s[0] <= '9') {
181  sr->partition_num *= 10;
182  sr->partition_num += s[0] - '0';
183  s++;
184  left--;
185  }
186 
188  } else if (target.Length >= sizeof(arc_btrfs_prefix) - sizeof(WCHAR) &&
189  RtlCompareMemory(target.Buffer, arc_btrfs_prefix, sizeof(arc_btrfs_prefix) - sizeof(WCHAR)) == sizeof(arc_btrfs_prefix) - sizeof(WCHAR)) {
190  WCHAR* s = &target.Buffer[(sizeof(arc_btrfs_prefix) / sizeof(WCHAR)) - 1];
191 #ifdef __REACTOS__
192  unsigned int i;
193 #endif // __REACTOS__
194 
195 #ifndef __REACTOS__
196  for (unsigned int i = 0; i < 16; i++) {
197 #else
198  for (i = 0; i < 16; i++) {
199 #endif // __REACTOS__
200  if (*s >= '0' && *s <= '9')
201  sr->uuid.uuid[i] = (*s - '0') << 4;
202  else if (*s >= 'a' && *s <= 'f')
203  sr->uuid.uuid[i] = (*s - 'a' + 0xa) << 4;
204  else if (*s >= 'A' && *s <= 'F')
205  sr->uuid.uuid[i] = (*s - 'A' + 0xa) << 4;
206  else {
207  ExFreePool(target.Buffer);
208  return;
209  }
210 
211  s++;
212 
213  if (*s >= '0' && *s <= '9')
214  sr->uuid.uuid[i] |= *s - '0';
215  else if (*s >= 'a' && *s <= 'f')
216  sr->uuid.uuid[i] |= *s - 'a' + 0xa;
217  else if (*s >= 'A' && *s <= 'F')
218  sr->uuid.uuid[i] |= *s - 'A' + 0xa;
219  else {
220  ExFreePool(target.Buffer);
221  return;
222  }
223 
224  s++;
225 
226  if (i == 3 || i == 5 || i == 7 || i == 9) {
227  if (*s != '-') {
228  ExFreePool(target.Buffer);
229  return;
230  }
231 
232  s++;
233  }
234  }
235 
236  if (*s != ')') {
237  ExFreePool(target.Buffer);
238  return;
239  }
240 
241  sr->type = system_root_btrfs;
242  }
243 
244  ExFreePool(target.Buffer);
245 }
system_root_type type
Definition: boot.c:63
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const BYTE us[]
Definition: encode.c:689
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define ALLOC_TAG
Definition: btrfs_drv.h:91
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BTRFS_UUID uuid
Definition: boot.c:62
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLint left
Definition: glext.h:7726
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
GLdouble s
Definition: gl.h:2039
#define GENERIC_READ
Definition: compat.h:124
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
uint8_t uuid[16]
Definition: btrfs.h:133
unsigned short USHORT
Definition: pedump.c:61
uint32_t partition_num
Definition: boot.c:61
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint32_t disk_num
Definition: boot.c:60

Referenced by check_system_root().

◆ mountmgr_notification()

static void mountmgr_notification ( BTRFS_UUID uuid)
static

Definition at line 297 of file boot.c.

297  {
298  UNICODE_STRING mmdevpath;
302  ULONG mmtnlen;
303  MOUNTMGR_TARGET_NAME* mmtn;
304  WCHAR* w;
305 #ifdef __REACTOS__
306  unsigned int i;
307 #endif
308 
311  if (!NT_SUCCESS(Status)) {
312  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
313  return;
314  }
315 
316  mmtnlen = offsetof(MOUNTMGR_TARGET_NAME, DeviceName[0]) + sizeof(BTRFS_VOLUME_PREFIX) + (36 * sizeof(WCHAR));
317 
318  mmtn = ExAllocatePoolWithTag(NonPagedPool, mmtnlen, ALLOC_TAG);
319  if (!mmtn) {
320  ERR("out of memory\n");
321  return;
322  }
323 
324  mmtn->DeviceNameLength = sizeof(BTRFS_VOLUME_PREFIX) + (36 * sizeof(WCHAR));
325 
327 
328  w = &mmtn->DeviceName[(sizeof(BTRFS_VOLUME_PREFIX) / sizeof(WCHAR)) - 1];
329 
330 #ifndef __REACTOS__
331  for (unsigned int i = 0; i < 16; i++) {
332 #else
333  for (i = 0; i < 16; i++) {
334 #endif
335  *w = hex_digit(uuid->uuid[i] >> 4); w++;
336  *w = hex_digit(uuid->uuid[i] & 0xf); w++;
337 
338  if (i == 3 || i == 5 || i == 7 || i == 9) {
339  *w = L'-';
340  w++;
341  }
342  }
343 
344  *w = L'}';
345 
347  if (!NT_SUCCESS(Status)) {
348  ERR("IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION returned %08lx\n", Status);
349  ExFreePool(mmtn);
350  return;
351  }
352 
353  ExFreePool(mmtn);
354 }
#define hex_digit(c)
Definition: btrfs_drv.h:1794
WCHAR DeviceName[1]
Definition: imports.h:155
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
Definition: imports.h:130
#define ALLOC_TAG
Definition: btrfs_drv.h:91
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define BTRFS_VOLUME_PREFIX
Definition: btrfs_drv.h:131
NTSTATUS dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG ControlCode, _In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer, _In_ ULONG InputBufferSize, _Out_writes_bytes_opt_(OutputBufferSize) PVOID OutputBuffer, _In_ ULONG OutputBufferSize, _In_ bool Override, _Out_opt_ IO_STATUS_BLOCK *iosb)
Definition: btrfs.c:2888
* PFILE_OBJECT
Definition: iotypes.h:1957
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
USHORT DeviceNameLength
Definition: imports.h:154
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by boot_add_device().

◆ RtlUnicodeStringPrintf()

NTSTATUS RtlUnicodeStringPrintf ( PUNICODE_STRING  DestinationString,
const WCHAR pszFormat,
  ... 
)

Variable Documentation

◆ boot_lock

ERESOURCE boot_lock

Definition at line 115 of file btrfs.c.

Referenced by check_system_root().

◆ boot_subvol

uint64_t boot_subvol = 0

Definition at line 34 of file boot.c.

Referenced by check_boot_options(), and mount_vol().

◆ boot_uuid

BTRFS_UUID boot_uuid

Definition at line 33 of file boot.c.

Referenced by _Function_class_(), add_volume_device(), check_system_root(), and mount_vol().

◆ drvobj

Definition at line 68 of file btrfs.c.

Referenced by boot_add_device().

◆ pdo_list

LIST_ENTRY pdo_list

Definition at line 109 of file btrfs.c.

Referenced by check_system_root().

◆ pdo_list_lock

ERESOURCE pdo_list_lock

Definition at line 108 of file btrfs.c.

Referenced by check_system_root().