ReactOS  0.4.15-dev-506-ga3ec01c
boot.c
Go to the documentation of this file.
1 /* Copyright (c) Mark Harmstone 2019
2  *
3  * This file is part of WinBtrfs.
4  *
5  * WinBtrfs is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public Licence as published by
7  * the Free Software Foundation, either version 3 of the Licence, or
8  * (at your option) any later version.
9  *
10  * WinBtrfs is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public Licence for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public Licence
16  * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "btrfs_drv.h"
19 
20 #ifndef __REACTOS__
21 #ifdef _MSC_VER
22 #include <ntstrsafe.h>
23 #endif
24 #else
25 #include <ntstrsafe.h>
26 #endif
27 
29 extern LIST_ENTRY pdo_list;
30 extern ERESOURCE boot_lock;
31 extern PDRIVER_OBJECT drvobj;
32 
33 BTRFS_UUID boot_uuid; // initialized to 0
35 
36 #ifndef _MSC_VER
37 NTSTATUS RtlUnicodeStringPrintf(PUNICODE_STRING DestinationString, const WCHAR* pszFormat, ...); // not in mingw
38 #endif
39 
40 // Not in any headers? Windbg knows about it though.
41 #define DOE_START_PENDING 0x10
42 
43 // Just as much as we need - the version in mingw is truncated still further
44 typedef struct {
49  void* Dope;
52 
53 typedef enum {
58 
59 typedef struct {
64 } system_root;
65 
66 static void get_system_root(system_root* sr) {
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 }
246 
247 static void change_symlink(uint32_t disk_num, uint32_t partition_num, BTRFS_UUID* uuid) {
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 }
296 
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 }
355 
356 static void check_boot_options() {
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 }
441 
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 }
459 
460 /* If booting from Btrfs, Windows will pass the device object for the raw partition to
461  * mount_vol - which is no good to us, as we only use the \Device\Btrfs{} devices we
462  * create so that RAID works correctly.
463  * At the time check_system_root gets called, \SystemRoot is a symlink to the ARC device,
464  * e.g. \ArcName\multi(0)disk(0)rdisk(0)partition(1)\Windows. We can't change the symlink,
465  * as it gets clobbered by IopReassignSystemRoot shortly afterwards, and we can't touch
466  * the \ArcName symlinks as they haven't been created yet. Instead, we need to change the
467  * symlink \Device\HarddiskX\PartitionY, which is what the ArcName symlink will shortly
468  * point to.
469  */
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
#define hex_digit(c)
Definition: btrfs_drv.h:1794
WCHAR DeviceName[1]
Definition: imports.h:155
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)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
system_root_type type
Definition: boot.c:63
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ULONG PowerFlags
Definition: boot.c:48
USHORT MaximumLength
Definition: env_spec_w32.h:370
struct _KEY_VALUE_FULL_INFORMATION KEY_VALUE_FULL_INFORMATION
static const BYTE us[]
Definition: encode.c:689
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)
system_root_type
Definition: boot.c:53
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
PDEVICE_OBJECT device
Definition: btrfs_drv.h:883
LONG NTSTATUS
Definition: precomp.h:26
uint64_t boot_subvol
Definition: boot.c:34
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1173
CSHORT Type
Definition: boot.c:45
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
WCHAR DeviceName[]
Definition: adapter.cpp:21
ULONG part_num
Definition: btrfs_drv.h:873
ERESOURCE boot_lock
Definition: btrfs.c:115
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
Definition: imports.h:130
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
_SEH2_TRY
Definition: create.c:4226
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
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
#define DOE_START_PENDING
Definition: boot.c:41
LIST_ENTRY pdo_list
Definition: btrfs.c:109
BTRFS_UUID uuid
Definition: boot.c:62
USHORT Size
Definition: boot.c:46
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1868
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
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
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
int options
Definition: main.c:106
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
void __stdcall check_system_root(PDRIVER_OBJECT DriverObject, PVOID Context, ULONG Count)
Definition: boot.c:470
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
PDRIVER_OBJECT drvobj
Definition: btrfs.c:68
#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
NTSTATUS RtlUnicodeStringPrintf(PUNICODE_STRING DestinationString, const WCHAR *pszFormat,...)
GLint left
Definition: glext.h:7726
#define __stdcall
Definition: typedefs.h:25
ERESOURCE child_lock
Definition: btrfs_drv.h:904
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1957
static void get_system_root(system_root *sr)
Definition: boot.c:66
ULONG disk_num
Definition: btrfs_drv.h:872
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#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
GLdouble s
Definition: gl.h:2039
#define GENERIC_READ
Definition: compat.h:124
Definition: typedefs.h:118
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
uint8_t uuid[16]
Definition: btrfs.h:133
USHORT DeviceNameLength
Definition: imports.h:154
_SEH2_END
Definition: create.c:4400
UINT64 uint64_t
Definition: types.h:77
static void mountmgr_notification(BTRFS_UUID *uuid)
Definition: boot.c:297
unsigned short USHORT
Definition: pedump.c:61
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
Definition: list.h:27
PDEVICE_OBJECT DeviceObject
Definition: boot.c:47
UINT32 uint32_t
Definition: types.h:75
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
ULONG ERESOURCE
Definition: env_spec_w32.h:594
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
void * Dope
Definition: boot.c:49
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
static void check_boot_options()
Definition: boot.c:356
LIST_ENTRY children
Definition: btrfs_drv.h:905
short CSHORT
Definition: umtypes.h:127
ERESOURCE pdo_list_lock
Definition: btrfs.c:108
#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
ULONG ExtensionFlags
Definition: boot.c:50
GLuint const GLchar * name
Definition: glext.h:6031