ReactOS  0.4.15-dev-5131-g311fcc6
btrfslib.c
Go to the documentation of this file.
1 /* Copyright (c) Mark Harmstone 2016-17
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 <stdlib.h>
19 #include <stddef.h>
20 #include <time.h>
21 #include <ntstatus.h>
22 #define WIN32_NO_STATUS
23 #include <windef.h>
24 #include <winbase.h>
25 #ifndef __REACTOS__
26 #include <winternl.h>
27 #include <devioctl.h>
28 #include <ntdddisk.h>
29 #else
30 #include <ndk/iofuncs.h>
31 #include <ndk/obfuncs.h>
32 #include <ndk/rtlfuncs.h>
33 #endif
34 #include <ntddscsi.h>
35 #include <ntddstor.h>
36 #include <ata.h>
37 #include <mountmgr.h>
38 #ifdef __REACTOS__
39 #include <winnls.h>
40 #include <stdbool.h>
41 #include "btrfs.h"
42 #include "btrfsioctl.h"
43 #include "crc32c.h"
44 #include "xxhash.h"
45 #else
46 #include <stringapiset.h>
47 #include <stdbool.h>
48 #include "../btrfs.h"
49 #include "../btrfsioctl.h"
50 #include "../crc32c.h"
51 #include "../xxhash.h"
52 
53 #if defined(_X86_) || defined(_AMD64_)
54 #ifndef _MSC_VER
55 #include <cpuid.h>
56 #else
57 #include <intrin.h>
58 #endif
59 #endif
60 #endif // __REACTOS__
61 
62 #ifdef __REACTOS__
63 #define malloc(size) RtlAllocateHeap(RtlGetProcessHeap(), 0, (size))
64 #define free(ptr) RtlFreeHeap(RtlGetProcessHeap(), 0, (ptr))
65 #endif
66 
67 #define SHA256_HASH_SIZE 32
68 void calc_sha256(uint8_t* hash, const void* input, size_t len);
69 
70 #define BLAKE2_HASH_SIZE 32
71 void blake2b(void *out, size_t outlen, const void* in, size_t inlen);
72 
73 #ifndef __REACTOS__
74 #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
75 #define FSCTL_UNLOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
76 #define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
77 
78 #ifndef _MSC_VER // not in mingw yet
79 #define DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED 0x80000000
80 #endif
81 
82 #ifdef __cplusplus
83 extern "C" {
84 #endif
87 
90 #ifdef __cplusplus
91 }
92 #endif
93 #endif // __REACTOS__
94 
95 // These are undocumented, and what comes from format.exe
96 typedef struct {
97  void* table;
98  void* unk1;
100 } DSTRING;
101 
102 typedef struct {
103  void* table;
105 
106 #define FORMAT_FLAG_QUICK_FORMAT 0x00000001
107 #define FORMAT_FLAG_UNKNOWN1 0x00000002
108 #define FORMAT_FLAG_DISMOUNT_FIRST 0x00000004
109 #define FORMAT_FLAG_UNKNOWN2 0x00000040
110 #define FORMAT_FLAG_LARGE_RECORDS 0x00000100
111 #define FORMAT_FLAG_INTEGRITY_DISABLE 0x00000100
112 
113 typedef struct {
118 } options;
119 
120 #ifndef __REACTOS__
122  ListHead->Flink = ListHead->Blink = ListHead;
123 }
124 
126  PLIST_ENTRY Blink;
127 
128  Blink = ListHead->Blink;
129  Entry->Flink = ListHead;
130  Entry->Blink = Blink;
131  Blink->Flink = Entry;
132  ListHead->Blink = Entry;
133 }
134 #endif
135 
136 #ifdef __REACTOS__
138 #endif
139 
140 typedef struct {
143  void* data;
145 } btrfs_item;
146 
147 typedef struct {
153 } btrfs_chunk;
154 
155 typedef struct {
161 } btrfs_root;
162 
163 typedef struct {
166 } btrfs_dev;
167 
168 #define keycmp(key1, key2)\
169  ((key1.obj_id < key2.obj_id) ? -1 :\
170  ((key1.obj_id > key2.obj_id) ? 1 :\
171  ((key1.obj_type < key2.obj_type) ? -1 :\
172  ((key1.obj_type > key2.obj_type) ? 1 :\
173  ((key1.offset < key2.offset) ? -1 :\
174  ((key1.offset > key2.offset) ? 1 :\
175  0))))))
176 
181 
182 #ifndef __REACTOS__
183 // the following definitions come from fmifs.h in ReactOS
184 
185 typedef struct {
186  ULONG Lines;
187  PCHAR Output;
189 
190 typedef enum {
216 
217 typedef enum {
236 
237 typedef BOOLEAN (NTAPI* PFMIFSCALLBACK)(CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo);
238 
239 #else
240 
241 #include <fmifs/fmifs.h>
242 
243 #endif // __REACTOS__
244 
245 #ifndef __REACTOS__
247  BOOLEAN ScanDrive, PFMIFSCALLBACK Callback) {
248 #else
249 BOOLEAN
250 NTAPI
252  IN PUNICODE_STRING DriveRoot,
256  IN BOOLEAN CheckOnlyIfDirty,
257  IN BOOLEAN ScanDrive,
258  IN PVOID pUnknown1,
259  IN PVOID pUnknown2,
260  IN PVOID pUnknown3,
261  IN PVOID pUnknown4,
263 {
264 #endif
265  // STUB
266 
267  if (Callback) {
269 
270  TextOut.Lines = 1;
271  TextOut.Output = "stub, not implemented";
272 
273  Callback(OUTPUT, 0, &TextOut);
274  }
275 
276 #ifndef __REACTOS__
277  return STATUS_SUCCESS;
278 #else
280  return TRUE;
281 #endif
282 }
283 
284 static btrfs_root* add_root(LIST_ENTRY* roots, uint64_t id) {
285  btrfs_root* root;
286 
287  root = malloc(sizeof(btrfs_root));
288 
289  root->id = id;
290  RtlZeroMemory(&root->header, sizeof(tree_header));
291  InitializeListHead(&root->items);
292  InsertTailList(roots, &root->list_entry);
293 
294  return root;
295 }
296 
297 static void free_roots(LIST_ENTRY* roots) {
298  LIST_ENTRY* le;
299 
300  le = roots->Flink;
301  while (le != roots) {
302  LIST_ENTRY *le2 = le->Flink, *le3;
304 
305  le3 = r->items.Flink;
306  while (le3 != &r->items) {
307  LIST_ENTRY* le4 = le3->Flink;
309 
310  if (item->data)
311  free(item->data);
312 
313  free(item);
314 
315  le3 = le4;
316  }
317 
318  free(r);
319 
320  le = le2;
321  }
322 }
323 
324 static void free_chunks(LIST_ENTRY* chunks) {
325  LIST_ENTRY* le;
326 
327  le = chunks->Flink;
328  while (le != chunks) {
329  LIST_ENTRY *le2 = le->Flink;
331 
332  free(c->chunk_item);
333  free(c);
334 
335  le = le2;
336  }
337 }
338 
339 static void add_item(btrfs_root* r, uint64_t obj_id, uint8_t obj_type, uint64_t offset, void* data, uint16_t size) {
340  LIST_ENTRY* le;
341  btrfs_item* item;
342 
343  item = malloc(sizeof(btrfs_item));
344 
345  item->key.obj_id = obj_id;
346  item->key.obj_type = obj_type;
347  item->key.offset = offset;
348  item->size = size;
349 
350  if (size == 0)
351  item->data = NULL;
352  else {
353  item->data = malloc(size);
354  memcpy(item->data, data, size);
355  }
356 
357  le = r->items.Flink;
358  while (le != &r->items) {
360 
361  if (keycmp(item->key, i2->key) != 1) {
362  InsertTailList(le, &item->list_entry);
363  return;
364  }
365 
366  le = le->Flink;
367  }
368 
369  InsertTailList(&r->items, &item->list_entry);
370 }
371 
373  uint64_t off;
374  DEV_EXTENT de;
375 
376  off = dev->last_alloc;
377  dev->last_alloc += size;
378 
379  dev->dev_item.bytes_used += size;
380 
382  de.objid = 0x100;
383  de.address = offset;
384  de.length = size;
385  de.chunktree_uuid = *chunkuuid;
386 
387  add_item(dev_root, dev->dev_item.dev_id, TYPE_DEV_EXTENT, off, &de, sizeof(DEV_EXTENT));
388 
389  return off;
390 }
391 
392 static btrfs_chunk* add_chunk(LIST_ENTRY* chunks, uint64_t flags, btrfs_root* chunk_root, btrfs_dev* dev, btrfs_root* dev_root, BTRFS_UUID* chunkuuid, uint32_t sector_size) {
393  uint64_t off, size;
394  uint16_t stripes, i;
395  btrfs_chunk* c;
396  LIST_ENTRY* le;
397  CHUNK_ITEM_STRIPE* cis;
398 
399  off = 0xc00000;
400  le = chunks->Flink;
401  while (le != chunks) {
403 
404  if (c->offset + c->chunk_item->size > off)
405  off = c->offset + c->chunk_item->size;
406 
407  le = le->Flink;
408  }
409 
410  if (flags & BLOCK_FLAG_METADATA) {
411  if (dev->dev_item.num_bytes > 0xC80000000) // 50 GB
412  size = 0x40000000; // 1 GB
413  else
414  size = 0x10000000; // 256 MB
415  } else if (flags & BLOCK_FLAG_SYSTEM)
416  size = 0x800000;
417 
418  size = min(size, dev->dev_item.num_bytes / 10); // cap at 10%
419  size &= ~(sector_size - 1);
420 
421  stripes = flags & BLOCK_FLAG_DUPLICATE ? 2 : 1;
422 
423  if (dev->dev_item.num_bytes - dev->dev_item.bytes_used < stripes * size) // not enough space
424  return NULL;
425 
426  c = malloc(sizeof(btrfs_chunk));
427  c->offset = off;
428  c->lastoff = off;
429  c->used = 0;
430 
431  c->chunk_item = malloc(sizeof(CHUNK_ITEM) + (stripes * sizeof(CHUNK_ITEM_STRIPE)));
432 
433  c->chunk_item->size = size;
434  c->chunk_item->root_id = BTRFS_ROOT_EXTENT;
435  c->chunk_item->stripe_length = max(sector_size, 0x10000);
436  c->chunk_item->type = flags;
437  c->chunk_item->opt_io_alignment = max(sector_size, 0x10000);
438  c->chunk_item->opt_io_width = max(sector_size, 0x10000);
439  c->chunk_item->sector_size = sector_size;
440  c->chunk_item->num_stripes = stripes;
441  c->chunk_item->sub_stripes = 0;
442 
443  cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
444 
445  for (i = 0; i < stripes; i++) {
446  cis[i].dev_id = dev->dev_item.dev_id;
447  cis[i].offset = find_chunk_offset(size, c->offset, dev, dev_root, chunkuuid);
448  cis[i].dev_uuid = dev->dev_item.device_uuid;
449  }
450 
451  add_item(chunk_root, 0x100, TYPE_CHUNK_ITEM, c->offset, c->chunk_item, sizeof(CHUNK_ITEM) + (stripes * sizeof(CHUNK_ITEM_STRIPE)));
452 
453  InsertTailList(chunks, &c->list_entry);
454 
455  return c;
456 }
457 
459  CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
460  uint64_t stripe = (address - c->offset) / c->chunk_item->stripe_length;
461  uint16_t i, j;
462 
463  for (i = 0; i < c->chunk_item->num_stripes; i++) {
464  j = 0;
465  while (superblock_addrs[j] != 0) {
466  if (superblock_addrs[j] >= cis[i].offset) {
467  uint64_t stripe2 = (superblock_addrs[j] - cis[i].offset) / c->chunk_item->stripe_length;
468 
469  if (stripe2 == stripe)
470  return true;
471  }
472  j++;
473  }
474  }
475 
476  return false;
477 }
478 
480  uint64_t addr;
481 
482  addr = c->lastoff;
483 
484  while (superblock_collision(c, addr)) {
485  addr = addr - ((addr - c->offset) % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
486 
487  if (addr >= c->offset + c->chunk_item->size) // chunk has been exhausted
488  return 0;
489  }
490 
491  return addr;
492 }
493 
494 typedef struct {
499 
500 typedef struct {
506 
507 static void assign_addresses(LIST_ENTRY* roots, btrfs_chunk* sys_chunk, btrfs_chunk* metadata_chunk, uint32_t node_size,
508  btrfs_root* root_root, btrfs_root* extent_root, bool skinny) {
509  LIST_ENTRY* le;
510 
511  le = roots->Flink;
512  while (le != roots) {
514  btrfs_chunk* c = r->id == BTRFS_ROOT_CHUNK ? sys_chunk : metadata_chunk;
515 
516  r->header.address = get_next_address(c);
517  r->c = c;
518  c->lastoff = r->header.address + node_size;
519  c->used += node_size;
520 
521  if (skinny) {
523 
524  eim.ei.refcount = 1;
525  eim.ei.generation = 1;
528  eim.tbr.offset = r->id;
529 
530  add_item(extent_root, r->header.address, TYPE_METADATA_ITEM, 0, &eim, sizeof(EXTENT_ITEM_METADATA));
531  } else {
533  KEY firstitem;
534 
535  if (r->items.Flink == &r->items) {
536  firstitem.obj_id = 0;
537  firstitem.obj_type = 0;
538  firstitem.offset = 0;
539  } else {
540  btrfs_item* bi = CONTAINING_RECORD(r->items.Flink, btrfs_item, list_entry);
541 
542  firstitem = bi->key;
543  }
544 
545  eim2.ei.refcount = 1;
546  eim2.ei.generation = 1;
548  eim2.ei2.firstitem = firstitem;
549  eim2.ei2.level = 0;
550  eim2.type = TYPE_TREE_BLOCK_REF;
551  eim2.tbr.offset = r->id;
552 
553  add_item(extent_root, r->header.address, TYPE_EXTENT_ITEM, node_size, &eim2, sizeof(EXTENT_ITEM_METADATA2));
554  }
555 
556  if (r->id != BTRFS_ROOT_ROOT && r->id != BTRFS_ROOT_CHUNK) {
557  ROOT_ITEM ri;
558 
559  memset(&ri, 0, sizeof(ROOT_ITEM));
560 
561  ri.inode.generation = 1;
562  ri.inode.st_size = 3;
563  ri.inode.st_blocks = node_size;
564  ri.inode.st_nlink = 1;
565  ri.inode.st_mode = 040755;
566  ri.generation = 1;
567  ri.objid = r->id == 5 || r->id >= 0x100 ? SUBVOL_ROOT_INODE : 0;
568  ri.block_number = r->header.address;
569  ri.bytes_used = node_size;
570  ri.num_references = 1;
571  ri.generation2 = ri.generation;
572 
573  add_item(root_root, r->id, TYPE_ROOT_ITEM, 0, &ri, sizeof(ROOT_ITEM));
574  }
575 
576  le = le->Flink;
577  }
578 }
579 
582  uint16_t i;
584  LARGE_INTEGER off;
585  CHUNK_ITEM_STRIPE* cis;
586 
587  cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
588 
589  for (i = 0; i < c->chunk_item->num_stripes; i++) {
590  off.QuadPart = cis[i].offset + address - c->offset;
591 
592  Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, data, size, &off, NULL);
593  if (!NT_SUCCESS(Status))
594  return Status;
595  }
596 
597  return STATUS_SUCCESS;
598 }
599 
600 static void calc_tree_checksum(tree_header* th, uint32_t node_size) {
601  switch (def_csum_type) {
602  case CSUM_TYPE_CRC32C:
603  *(uint32_t*)th = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, node_size - sizeof(th->csum));
604  break;
605 
606  case CSUM_TYPE_XXHASH:
607  *(uint64_t*)th = XXH64((uint8_t*)&th->fs_uuid, node_size - sizeof(th->csum), 0);
608  break;
609 
610  case CSUM_TYPE_SHA256:
611  calc_sha256((uint8_t*)th, &th->fs_uuid, node_size - sizeof(th->csum));
612  break;
613 
614  case CSUM_TYPE_BLAKE2:
615  blake2b((uint8_t*)th, BLAKE2_HASH_SIZE, &th->fs_uuid, node_size - sizeof(th->csum));
616  break;
617  }
618 }
619 
620 static NTSTATUS write_roots(HANDLE h, LIST_ENTRY* roots, uint32_t node_size, BTRFS_UUID* fsuuid, BTRFS_UUID* chunkuuid) {
621  LIST_ENTRY *le, *le2;
623  uint8_t* tree;
624 
625  tree = malloc(node_size);
626 
627  le = roots->Flink;
628  while (le != roots) {
630  uint8_t* dp;
631  leaf_node* ln;
632 
633  memset(tree, 0, node_size);
634 
635  r->header.num_items = 0;
636  r->header.fs_uuid = *fsuuid;
638  r->header.chunk_tree_uuid = *chunkuuid;
639  r->header.generation = 1;
640  r->header.tree_id = r->id;
641 
642  ln = (leaf_node*)(tree + sizeof(tree_header));
643 
644  dp = tree + node_size;
645 
646  le2 = r->items.Flink;
647  while (le2 != &r->items) {
649 
650  ln->key = item->key;
651  ln->size = item->size;
652 
653  if (item->size > 0) {
654  dp -= item->size;
655  memcpy(dp, item->data, item->size);
656 
657  ln->offset = (uint32_t)(dp - tree - sizeof(tree_header));
658  } else
659  ln->offset = 0;
660 
661  ln = &ln[1];
662 
663  r->header.num_items++;
664 
665  le2 = le2->Flink;
666  }
667 
668  memcpy(tree, &r->header, sizeof(tree_header));
669 
670  calc_tree_checksum((tree_header*)tree, node_size);
671 
672  Status = write_data(h, r->header.address, r->c, tree, node_size);
673  if (!NT_SUCCESS(Status)) {
674  free(tree);
675  return Status;
676  }
677 
678  le = le->Flink;
679  }
680 
681  free(tree);
682 
683  return STATUS_SUCCESS;
684 }
685 
686 #ifndef __REACTOS__
687 static void get_uuid(BTRFS_UUID* uuid) {
688 #else
689 static void get_uuid(BTRFS_UUID* uuid, ULONG* seed) {
690 #endif
691  uint8_t i;
692 
693  for (i = 0; i < 16; i+=2) {
694 #ifndef __REACTOS__
695  ULONG r = rand();
696 #else
697  ULONG r = RtlRandom(seed);
698 #endif
699 
700  uuid->uuid[i] = (r & 0xff00) >> 8;
701  uuid->uuid[i+1] = r & 0xff;
702  }
703 }
704 
705 #ifndef __REACTOS__
707 #else
708 static void init_device(btrfs_dev* dev, uint64_t id, uint64_t size, BTRFS_UUID* fsuuid, uint32_t sector_size, ULONG* seed) {
709 #endif
710  dev->dev_item.dev_id = id;
711  dev->dev_item.num_bytes = size;
712  dev->dev_item.bytes_used = 0;
713  dev->dev_item.optimal_io_align = sector_size;
714  dev->dev_item.optimal_io_width = sector_size;
715  dev->dev_item.minimal_io_size = sector_size;
716  dev->dev_item.type = 0;
717  dev->dev_item.generation = 0;
718  dev->dev_item.start_offset = 0;
719  dev->dev_item.dev_group = 0;
720  dev->dev_item.seek_speed = 0;
721  dev->dev_item.bandwidth = 0;
722 #ifndef __REACTOS__
723  get_uuid(&dev->dev_item.device_uuid);
724 #else
725  get_uuid(&dev->dev_item.device_uuid, seed);
726 #endif
727  dev->dev_item.fs_uuid = *fsuuid;
728 
729  dev->last_alloc = 0x100000; // skip first megabyte
730 }
731 
733  switch (def_csum_type) {
734  case CSUM_TYPE_CRC32C:
735  *(uint32_t*)sb = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
736  break;
737 
738  case CSUM_TYPE_XXHASH:
739  *(uint64_t*)sb = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0);
740  break;
741 
742  case CSUM_TYPE_SHA256:
743  calc_sha256((uint8_t*)sb, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
744  break;
745 
746  case CSUM_TYPE_BLAKE2:
747  blake2b((uint8_t*)sb, BLAKE2_HASH_SIZE, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
748  break;
749  }
750 }
751 
752 static NTSTATUS write_superblocks(HANDLE h, btrfs_dev* dev, btrfs_root* chunk_root, btrfs_root* root_root, btrfs_root* extent_root,
753  btrfs_chunk* sys_chunk, uint32_t node_size, BTRFS_UUID* fsuuid, uint32_t sector_size, PUNICODE_STRING label, uint64_t incompat_flags) {
756  ULONG sblen;
757  int i;
758  superblock* sb;
759  KEY* key;
760  uint64_t bytes_used;
761  LIST_ENTRY* le;
762 
763  sblen = sizeof(*sb);
764  if (sblen & (sector_size - 1))
765  sblen = (sblen & sector_size) + sector_size;
766 
767  bytes_used = 0;
768 
769  le = extent_root->items.Flink;
770  while (le != &extent_root->items) {
772 
773  if (item->key.obj_type == TYPE_EXTENT_ITEM)
774  bytes_used += item->key.offset;
775  else if (item->key.obj_type == TYPE_METADATA_ITEM)
776  bytes_used += node_size;
777 
778  le = le->Flink;
779  }
780 
781  sb = malloc(sblen);
782  memset(sb, 0, sblen);
783 
784  sb->uuid = *fsuuid;
785  sb->flags = 1;
786  sb->magic = BTRFS_MAGIC;
787  sb->generation = 1;
788  sb->root_tree_addr = root_root->header.address;
789  sb->chunk_tree_addr = chunk_root->header.address;
790  sb->total_bytes = dev->dev_item.num_bytes;
791  sb->bytes_used = bytes_used;
793  sb->num_devices = 1;
795  sb->node_size = node_size;
796  sb->leaf_size = node_size;
798  sb->n = sizeof(KEY) + sizeof(CHUNK_ITEM) + (sys_chunk->chunk_item->num_stripes * sizeof(CHUNK_ITEM_STRIPE));
800  sb->incompat_flags = incompat_flags;
802  memcpy(&sb->dev_item, &dev->dev_item, sizeof(DEV_ITEM));
803 
804  if (label->Length > 0) {
805 #ifdef __REACTOS__
806  ANSI_STRING as;
807  unsigned int i;
808 
809  for (i = 0; i < label->Length / sizeof(WCHAR); i++) {
810 #else
811  ULONG utf8len;
812 
813  for (unsigned int i = 0; i < label->Length / sizeof(WCHAR); i++) {
814 #endif
815  if (label->Buffer[i] == '/' || label->Buffer[i] == '\\') {
816  free(sb);
818  }
819  }
820 
821 #ifndef __REACTOS__
822  utf8len = WideCharToMultiByte(CP_UTF8, 0, label->Buffer, label->Length / sizeof(WCHAR), NULL, 0, NULL, NULL);
823 
824  if (utf8len == 0 || utf8len > MAX_LABEL_SIZE) {
825  free(sb);
827  }
828 
829  if (WideCharToMultiByte(CP_UTF8, 0, label->Buffer, label->Length / sizeof(WCHAR), sb->label, utf8len, NULL, NULL) == 0) {
830 #else
831  as.Buffer = sb->label;
832  as.Length = 0;
834 
836  {
837 #endif
838  free(sb);
840  }
841  }
842  sb->cache_generation = 0xffffffffffffffff;
843 
844  key = (KEY*)sb->sys_chunk_array;
845  key->obj_id = 0x100;
846  key->obj_type = TYPE_CHUNK_ITEM;
847  key->offset = sys_chunk->offset;
848  memcpy(&key[1], sys_chunk->chunk_item, sizeof(CHUNK_ITEM) + (sys_chunk->chunk_item->num_stripes * sizeof(CHUNK_ITEM_STRIPE)));
849 
850  i = 0;
851  while (superblock_addrs[i] != 0) {
852  LARGE_INTEGER off;
853 
854  if (superblock_addrs[i] > dev->dev_item.num_bytes)
855  break;
856 
858 
860 
861  off.QuadPart = superblock_addrs[i];
862 
863  Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, sb, sblen, &off, NULL);
864  if (!NT_SUCCESS(Status)) {
865  free(sb);
866  return Status;
867  }
868 
869  i++;
870  }
871 
872  free(sb);
873 
874  return STATUS_SUCCESS;
875 }
876 
877 static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME* out) {
878  ULONGLONG l = t.QuadPart - 116444736000000000;
879 
880  out->seconds = l / 10000000;
881  out->nanoseconds = (l % 10000000) * 100;
882 }
883 
884 #ifdef __REACTOS__
885 VOID
886 WINAPI
888 {
889  LARGE_INTEGER SystemTime;
890 
891  do
892  {
893  SystemTime.HighPart = SharedUserData->SystemTime.High1Time;
894  SystemTime.LowPart = SharedUserData->SystemTime.LowPart;
895  }
896  while (SystemTime.HighPart != SharedUserData->SystemTime.High2Time);
897 
898  lpFileTime->dwLowDateTime = SystemTime.LowPart;
899  lpFileTime->dwHighDateTime = SystemTime.HighPart;
900 }
901 #endif
902 
904  uint16_t name_len = (uint16_t)strlen(name);
905  INODE_REF* ir = malloc(offsetof(INODE_REF, name[0]) + name_len);
906 
907  ir->index = 0;
908  ir->n = name_len;
909  memcpy(ir->name, name, name_len);
910 
912 
913  free(ir);
914 }
915 
916 static void init_fs_tree(btrfs_root* r, uint32_t node_size) {
917  INODE_ITEM ii;
920 
921  memset(&ii, 0, sizeof(INODE_ITEM));
922 
923  ii.generation = 1;
924  ii.st_blocks = node_size;
925  ii.st_nlink = 1;
926  ii.st_mode = 040755;
927 
929  time.LowPart = filetime.dwLowDateTime;
930  time.HighPart = filetime.dwHighDateTime;
931 
933  ii.st_ctime = ii.st_mtime = ii.st_atime;
934 
936 
938 }
939 
940 static void add_block_group_items(LIST_ENTRY* chunks, btrfs_root* extent_root) {
941  LIST_ENTRY* le;
942 
943  le = chunks->Flink;
944  while (le != chunks) {
946  BLOCK_GROUP_ITEM bgi;
947 
948  bgi.used = c->used;
949  bgi.chunk_tree = 0x100;
950  bgi.flags = c->chunk_item->type;
951  add_item(extent_root, c->offset, TYPE_BLOCK_GROUP_ITEM, c->chunk_item->size, &bgi, sizeof(BLOCK_GROUP_ITEM));
952 
953  le = le->Flink;
954  }
955 }
956 
961  uint8_t* mb;
962 
963  mb = malloc(0x100000);
964  memset(mb, 0, 0x100000);
965 
966  zero.QuadPart = 0;
967 
968  Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, mb, 0x100000, &zero, NULL);
969 
970  free(mb);
971 
972  return Status;
973 }
974 
975 static bool is_ssd(HANDLE h) {
976  ULONG aptelen;
977  ATA_PASS_THROUGH_EX* apte;
981 
982  aptelen = sizeof(ATA_PASS_THROUGH_EX) + 512;
983  apte = malloc(aptelen);
984 
985  RtlZeroMemory(apte, aptelen);
986 
987  apte->Length = sizeof(ATA_PASS_THROUGH_EX);
988  apte->AtaFlags = ATA_FLAGS_DATA_IN;
989  apte->DataTransferLength = aptelen - sizeof(ATA_PASS_THROUGH_EX);
990  apte->TimeOutValue = 3;
991  apte->DataBufferOffset = apte->Length;
993 
994  Status = NtDeviceIoControlFile(h, NULL, NULL, NULL, &iosb, IOCTL_ATA_PASS_THROUGH, apte, aptelen, apte, aptelen);
995 
996  if (NT_SUCCESS(Status)) {
997  idd = (IDENTIFY_DEVICE_DATA*)((uint8_t*)apte + sizeof(ATA_PASS_THROUGH_EX));
998 
999  if (idd->NominalMediaRotationRate == 1) {
1000  free(apte);
1001  return true;
1002  }
1003  }
1004 
1005  free(apte);
1006 
1007  return false;
1008 }
1009 
1011  uint64_t key_offset, uint64_t transid, uint8_t type, const char* name) {
1012  uint16_t name_len = (uint16_t)strlen(name);
1013  DIR_ITEM* di = malloc(offsetof(DIR_ITEM, name[0]) + name_len);
1014 
1015  di->key.obj_id = key_objid;
1016  di->key.obj_type = key_type;
1017  di->key.offset = key_offset;
1018  di->transid = transid;
1019  di->m = 0;
1020  di->n = name_len;
1021  di->type = type;
1022  memcpy(di->name, name, name_len);
1023 
1024  add_item(root, inode, TYPE_DIR_ITEM, hash, di, (uint16_t)(offsetof(DIR_ITEM, name[0]) + di->m + di->n));
1025 
1026  free(di);
1027 }
1028 
1029 static void set_default_subvol(btrfs_root* root_root, uint32_t node_size) {
1030  INODE_ITEM ii;
1033 
1034  static const char default_subvol[] = "default";
1035  static const uint32_t default_hash = 0x8dbfc2d2;
1036 
1037  add_inode_ref(root_root, BTRFS_ROOT_FSTREE, BTRFS_ROOT_TREEDIR, 0, default_subvol);
1038 
1039  memset(&ii, 0, sizeof(INODE_ITEM));
1040 
1041  ii.generation = 1;
1042  ii.st_blocks = node_size;
1043  ii.st_nlink = 1;
1044  ii.st_mode = 040755;
1045 
1047  time.LowPart = filetime.dwLowDateTime;
1048  time.HighPart = filetime.dwHighDateTime;
1049 
1051  ii.st_ctime = ii.st_mtime = ii.otime = ii.st_atime;
1052 
1053  add_item(root_root, BTRFS_ROOT_TREEDIR, TYPE_INODE_ITEM, 0, &ii, sizeof(INODE_ITEM));
1054 
1055  add_inode_ref(root_root, BTRFS_ROOT_TREEDIR, BTRFS_ROOT_TREEDIR, 0, "..");
1056 
1058  0xffffffffffffffff, 0, BTRFS_TYPE_DIRECTORY, default_subvol);
1059 }
1060 
1062  NTSTATUS Status;
1063  LIST_ENTRY roots, chunks;
1064  btrfs_root *root_root, *chunk_root, *extent_root, *dev_root, *fs_root, *reloc_root;
1065  btrfs_chunk *sys_chunk, *metadata_chunk;
1066  btrfs_dev dev;
1067  BTRFS_UUID fsuuid, chunkuuid;
1068  bool ssd;
1069  uint64_t metadata_flags;
1070 #ifdef __REACTOS__
1071  ULONG seed;
1072 #endif
1073 
1074 #ifndef __REACTOS__
1075  srand((unsigned int)time(0));
1076  get_uuid(&fsuuid);
1077  get_uuid(&chunkuuid);
1078 #else
1079  seed = NtGetTickCount();
1080  get_uuid(&fsuuid, &seed);
1081  get_uuid(&chunkuuid, &seed);
1082 #endif
1083 
1084  InitializeListHead(&roots);
1085  InitializeListHead(&chunks);
1086 
1087  root_root = add_root(&roots, BTRFS_ROOT_ROOT);
1088  chunk_root = add_root(&roots, BTRFS_ROOT_CHUNK);
1089  extent_root = add_root(&roots, BTRFS_ROOT_EXTENT);
1090  dev_root = add_root(&roots, BTRFS_ROOT_DEVTREE);
1091  add_root(&roots, BTRFS_ROOT_CHECKSUM);
1092  fs_root = add_root(&roots, BTRFS_ROOT_FSTREE);
1094 
1095 #ifndef __REACTOS__
1096  init_device(&dev, 1, size, &fsuuid, sector_size);
1097 #else
1098  init_device(&dev, 1, size, &fsuuid, sector_size, &seed);
1099 #endif
1100 
1101  ssd = is_ssd(h);
1102 
1103  sys_chunk = add_chunk(&chunks, BLOCK_FLAG_SYSTEM | (ssd ? 0 : BLOCK_FLAG_DUPLICATE), chunk_root, &dev, dev_root, &chunkuuid, sector_size);
1104  if (!sys_chunk)
1105  return STATUS_INTERNAL_ERROR;
1106 
1107  metadata_flags = BLOCK_FLAG_METADATA;
1108 
1109  if (!ssd && !(incompat_flags & BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS))
1110  metadata_flags |= BLOCK_FLAG_DUPLICATE;
1111 
1112  if (incompat_flags & BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS)
1113  metadata_flags |= BLOCK_FLAG_DATA;
1114 
1115  metadata_chunk = add_chunk(&chunks, metadata_flags, chunk_root, &dev, dev_root, &chunkuuid, sector_size);
1116  if (!metadata_chunk)
1117  return STATUS_INTERNAL_ERROR;
1118 
1119  add_item(chunk_root, 1, TYPE_DEV_ITEM, dev.dev_item.dev_id, &dev.dev_item, sizeof(DEV_ITEM));
1120 
1121  set_default_subvol(root_root, node_size);
1122 
1123  init_fs_tree(fs_root, node_size);
1124  init_fs_tree(reloc_root, node_size);
1125 
1126  assign_addresses(&roots, sys_chunk, metadata_chunk, node_size, root_root, extent_root, incompat_flags & BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA);
1127 
1128  add_block_group_items(&chunks, extent_root);
1129 
1130  Status = write_roots(h, &roots, node_size, &fsuuid, &chunkuuid);
1131  if (!NT_SUCCESS(Status))
1132  return Status;
1133 
1135  if (!NT_SUCCESS(Status))
1136  return Status;
1137 
1138  Status = write_superblocks(h, &dev, chunk_root, root_root, extent_root, sys_chunk, node_size, &fsuuid, sector_size, label, incompat_flags);
1139  if (!NT_SUCCESS(Status))
1140  return Status;
1141 
1142  free_roots(&roots);
1143  free_chunks(&chunks);
1144 
1145  return STATUS_SUCCESS;
1146 }
1147 
1148 static bool look_for_device(btrfs_filesystem* bfs, BTRFS_UUID* devuuid) {
1149  uint32_t i;
1151 
1152  for (i = 0; i < bfs->num_devices; i++) {
1153  if (i == 0)
1154  dev = &bfs->device;
1155  else
1157 
1158  if (RtlCompareMemory(&dev->uuid, devuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID))
1159  return true;
1160  }
1161 
1162  return false;
1163 }
1164 
1166  switch (sb->csum_type) {
1167  case CSUM_TYPE_CRC32C: {
1168  uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
1169 
1170  return crc32 == *(uint32_t*)sb;
1171  }
1172 
1173  case CSUM_TYPE_XXHASH: {
1174  uint64_t hash = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0);
1175 
1176  return hash == *(uint64_t*)sb;
1177  }
1178 
1179  case CSUM_TYPE_SHA256: {
1181 
1182  calc_sha256(hash, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
1183 
1184  return !memcmp(hash, sb, SHA256_HASH_SIZE);
1185  }
1186 
1187  case CSUM_TYPE_BLAKE2: {
1189 
1190  blake2b(hash, sizeof(hash), &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
1191 
1192  return !memcmp(hash, sb, BLAKE2_HASH_SIZE);
1193  }
1194 
1195  default:
1196  return false;
1197  }
1198 }
1199 
1201  NTSTATUS Status;
1202  superblock* sb;
1203  ULONG sblen;
1205  LARGE_INTEGER off;
1206  BTRFS_UUID fsuuid, devuuid;
1209  HANDLE h2;
1210  btrfs_filesystem *bfs = NULL, *bfs2;
1211  ULONG bfssize;
1212  bool ret = false;
1213 
1214  static WCHAR btrfs[] = L"\\Btrfs";
1215 
1216  sblen = sizeof(*sb);
1217  if (sblen & (sector_size - 1))
1218  sblen = (sblen & sector_size) + sector_size;
1219 
1220  sb = malloc(sblen);
1221 
1222  off.QuadPart = superblock_addrs[0];
1223 
1224  Status = NtReadFile(h, NULL, NULL, NULL, &iosb, sb, sblen, &off, NULL);
1225  if (!NT_SUCCESS(Status)) {
1226  free(sb);
1227  return false;
1228  }
1229 
1230  if (sb->magic != BTRFS_MAGIC) {
1231  free(sb);
1232  return false;
1233  }
1234 
1235  if (!check_superblock_checksum(sb)) {
1236  free(sb);
1237  return false;
1238  }
1239 
1240  fsuuid = sb->uuid;
1241  devuuid = sb->dev_item.device_uuid;
1242 
1243  free(sb);
1244 
1245  us.Length = us.MaximumLength = (USHORT)(wcslen(btrfs) * sizeof(WCHAR));
1246  us.Buffer = btrfs;
1247 
1249 
1252  if (!NT_SUCCESS(Status)) // not a problem, it usually just means the driver isn't loaded
1253  return false;
1254 
1255  bfssize = 0;
1256 
1257  do {
1258  bfssize += 1024;
1259 
1260  if (bfs) free(bfs);
1261  bfs = malloc(bfssize);
1262 
1264  } while (Status == STATUS_BUFFER_OVERFLOW);
1265 
1266  if (!NT_SUCCESS(Status))
1267  goto end;
1268 
1269  if (bfs->num_devices != 0) {
1270  bfs2 = bfs;
1271  while (true) {
1272  if (RtlCompareMemory(&bfs2->uuid, &fsuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1273  if (bfs2->num_devices == 1)
1274  ret = false;
1275  else
1276  ret = look_for_device(bfs2, &devuuid);
1277 
1278  goto end;
1279  }
1280 
1281  if (bfs2->next_entry == 0)
1282  break;
1283  else
1284  bfs2 = (btrfs_filesystem*)((uint8_t*)bfs2 + bfs2->next_entry);
1285  }
1286  }
1287 
1288 end:
1289  NtClose(h2);
1290 
1291  if (bfs)
1292  free(bfs);
1293 
1294  return ret;
1295 }
1296 
1297 static void do_full_trim(HANDLE h) {
1300 
1302 
1303  dmdsa.Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES);
1304  dmdsa.Action = DeviceDsmAction_Trim;
1306  dmdsa.ParameterBlockOffset = 0;
1307  dmdsa.ParameterBlockLength = 0;
1308  dmdsa.DataSetRangesOffset = 0;
1309  dmdsa.DataSetRangesLength = 0;
1310 
1312 }
1313 
1314 static bool is_power_of_two(ULONG i) {
1315  return ((i != 0) && !(i & (i - 1)));
1316 }
1317 
1318 #if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_))
1319 static void check_cpu() {
1320  unsigned int cpuInfo[4];
1321  bool have_sse42;
1322 
1323 #ifndef _MSC_VER
1324  __get_cpuid(1, &cpuInfo[0], &cpuInfo[1], &cpuInfo[2], &cpuInfo[3]);
1325  have_sse42 = cpuInfo[2] & bit_SSE4_2;
1326 #else
1327  __cpuid(cpuInfo, 1);
1328  have_sse42 = cpuInfo[2] & (1 << 20);
1329 #endif
1330 
1331  if (have_sse42)
1332  calc_crc32c = calc_crc32c_hw;
1333 }
1334 #endif
1335 
1338 {
1339  NTSTATUS Status;
1340  HANDLE h, btrfsh;
1344  DISK_GEOMETRY dg;
1345  uint32_t sector_size, node_size;
1346  UNICODE_STRING btrfsus;
1347 #ifndef __REACTOS__
1348  HANDLE token;
1350  LUID luid;
1351 #endif
1352  uint64_t incompat_flags;
1353  UNICODE_STRING empty_label;
1354 
1355  static WCHAR btrfs[] = L"\\Btrfs";
1356 
1357 #ifndef __REACTOS__
1360 
1361  if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &luid)) {
1362  CloseHandle(token);
1364  }
1365 
1366  tp.PrivilegeCount = 1;
1367  tp.Privileges[0].Luid = luid;
1368  tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1369 
1370  if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
1371  CloseHandle(token);
1373  }
1374 
1375  CloseHandle(token);
1376 
1377 #if defined(_X86_) || defined(_AMD64_)
1378  check_cpu();
1379 #endif
1380 #endif
1381 
1384  return STATUS_INVALID_PARAMETER;
1385 
1387 
1390 
1391  if (!NT_SUCCESS(Status))
1392  return Status;
1393 
1395  if (!NT_SUCCESS(Status)) {
1396  NtClose(h);
1397  return Status;
1398  }
1399 
1400  // MSDN tells us to use IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, but there are
1401  // some instances where it fails and IOCTL_DISK_GET_DRIVE_GEOMETRY succeeds -
1402  // such as with spanned volumes.
1404  if (!NT_SUCCESS(Status)) {
1405  NtClose(h);
1406  return Status;
1407  }
1408 
1409  if (def_sector_size == 0) {
1411 
1412  if (sector_size == 0x200 || sector_size == 0)
1413  sector_size = 0x1000;
1414  } else {
1416  NtClose(h);
1417  return STATUS_INVALID_PARAMETER;
1418  }
1419 
1421  }
1422 
1423  if (def_node_size == 0)
1424  node_size = 0x4000;
1425  else {
1427  NtClose(h);
1428  return STATUS_INVALID_PARAMETER;
1429  }
1430 
1431  node_size = def_node_size;
1432  }
1433 
1434  if (Callback) {
1435  ULONG pc = 0;
1436  Callback(PROGRESS, 0, (PVOID)&pc);
1437  }
1438 
1440 
1443  goto end;
1444  }
1445 
1446  do_full_trim(h);
1447 
1448  incompat_flags = def_incompat_flags;
1450 
1451  if (!Label) {
1452  empty_label.Buffer = NULL;
1453  empty_label.Length = empty_label.MaximumLength = 0;
1454  Label = &empty_label;
1455  }
1456 
1457  Status = write_btrfs(h, gli.Length.QuadPart, Label, sector_size, node_size, incompat_flags);
1458 
1460 
1461 end:
1463 
1464  NtClose(h);
1465 
1466  if (NT_SUCCESS(Status)) {
1467  btrfsus.Buffer = btrfs;
1468  btrfsus.Length = btrfsus.MaximumLength = (USHORT)(wcslen(btrfs) * sizeof(WCHAR));
1469 
1470  InitializeObjectAttributes(&attr, &btrfsus, 0, NULL, NULL);
1471 
1474 
1475  if (NT_SUCCESS(Status)) {
1476  MOUNTDEV_NAME* mdn;
1477  ULONG mdnsize;
1478 
1479  mdnsize = (ULONG)(offsetof(MOUNTDEV_NAME, Name[0]) + DriveRoot->Length);
1480  mdn = malloc(mdnsize);
1481 
1482  mdn->NameLength = DriveRoot->Length;
1483  memcpy(mdn->Name, DriveRoot->Buffer, DriveRoot->Length);
1484 
1485  NtDeviceIoControlFile(btrfsh, NULL, NULL, NULL, &iosb, IOCTL_BTRFS_PROBE_VOLUME, mdn, mdnsize, NULL, 0);
1486 
1487  free(mdn);
1488 
1489  NtClose(btrfsh);
1490  }
1491 
1493  }
1494 
1495 #ifndef __REACTOS__
1496  if (Callback) {
1497  bool success = NT_SUCCESS(Status);
1498  Callback(DONE, 0, (PVOID)&success);
1499  }
1500 #endif
1501 
1502  return Status;
1503 }
1504 
1505 #ifdef __REACTOS__
1506 
1507 BOOLEAN
1508 NTAPI
1509 BtrfsFormat(
1510  IN PUNICODE_STRING DriveRoot,
1513  IN BOOLEAN BackwardCompatible,
1514  IN MEDIA_TYPE MediaType,
1517 {
1518  NTSTATUS Status;
1519 
1520  if (BackwardCompatible)
1521  {
1522  // DPRINT1("BackwardCompatible == TRUE is unsupported!\n");
1523  return FALSE;
1524  }
1525 
1526  Status = FormatEx2(DriveRoot, (FMIFS_MEDIA_FLAG)MediaType, Label, QuickFormat, ClusterSize, Callback);
1527 
1528  return NT_SUCCESS(Status);
1529 }
1530 
1531 #else
1532 
1534  UNICODE_STRING DriveRoot, Label;
1535  NTSTATUS Status;
1536 
1537  if (!root || !root->string)
1538  return false;
1539 
1540  DriveRoot.Length = DriveRoot.MaximumLength = (USHORT)(wcslen(root->string) * sizeof(WCHAR));
1541  DriveRoot.Buffer = root->string;
1542 
1543  if (opts && opts->label && opts->label->string) {
1544  Label.Length = Label.MaximumLength = (USHORT)(wcslen(opts->label->string) * sizeof(WCHAR));
1545  Label.Buffer = opts->label->string;
1546  } else {
1547  Label.Length = Label.MaximumLength = 0;
1548  Label.Buffer = NULL;
1549  }
1550 
1551  Status = FormatEx2(&DriveRoot, FMIFS_HARDDISK, &Label, opts && opts->flags & FORMAT_FLAG_QUICK_FORMAT, 0, NULL);
1552 
1553  return NT_SUCCESS(Status);
1554 }
1555 
1556 #endif // __REACTOS__
1557 
1559  if (sector != 0)
1561 
1562  if (node != 0)
1563  def_node_size = node;
1564 }
1565 
1566 void __stdcall SetIncompatFlags(uint64_t incompat_flags) {
1567  def_incompat_flags = incompat_flags;
1568 }
1569 
1570 void __stdcall SetCsumType(uint16_t csum_type) {
1571  def_csum_type = csum_type;
1572 }
1573 
1575  // STUB - undocumented
1576 
1577  return true;
1578 }
1579 
1580 #ifndef __REACTOS__
1583  module = (HMODULE)hModule;
1584 
1585  return true;
1586 }
1587 #endif
void * table
Definition: btrfslib.c:97
signed char * PCHAR
Definition: retypes.h:7
uint8_t sys_chunk_array[SYS_CHUNK_ARRAY_SIZE]
Definition: btrfs.h:257
#define FILE_GENERIC_READ
Definition: nt_native.h:653
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
uint64_t obj_id
Definition: btrfs.h:144
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#define IN
Definition: typedefs.h:39
void __stdcall SetCsumType(uint16_t csum_type)
Definition: btrfslib.c:1570
#define TYPE_DEV_ITEM
Definition: btrfs.h:47
uint32_t sector
Definition: isohybrid.c:61
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:719
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
BOOLEAN NTAPI BtrfsFormat(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define max(a, b)
Definition: svc.c:63
Definition: tftpd.h:59
uint64_t lastoff
Definition: btrfslib.c:150
struct TEXTOUTPUT * PTEXTOUTPUT
static NTSTATUS write_superblocks(HANDLE h, btrfs_dev *dev, btrfs_root *chunk_root, btrfs_root *root_root, btrfs_root *extent_root, btrfs_chunk *sys_chunk, uint32_t node_size, BTRFS_UUID *fsuuid, uint32_t sector_size, PUNICODE_STRING label, uint64_t incompat_flags)
Definition: btrfslib.c:752
#define CloseHandle
Definition: compat.h:598
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
uint8_t obj_type
Definition: btrfs.h:145
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpPrivilegeName, PLUID lpLuid)
Definition: misc.c:782
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static NTSTATUS write_roots(HANDLE h, LIST_ENTRY *roots, uint32_t node_size, BTRFS_UUID *fsuuid, BTRFS_UUID *chunkuuid)
Definition: btrfslib.c:620
uint64_t bytes_used
Definition: btrfs.h:235
BTRFS_TIME otime
Definition: btrfs.h:304
#define WideCharToMultiByte
Definition: compat.h:111
EXTENT_ITEM2 ei2
Definition: btrfslib.c:502
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
struct _Entry Entry
Definition: kefuncs.h:629
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static uint64_t find_chunk_offset(uint64_t size, uint64_t offset, btrfs_dev *dev, btrfs_root *dev_root, BTRFS_UUID *chunkuuid)
Definition: btrfslib.c:372
static bool look_for_device(btrfs_filesystem *bfs, BTRFS_UUID *devuuid)
Definition: btrfslib.c:1148
USHORT MaximumLength
Definition: env_spec_w32.h:370
static void set_default_subvol(btrfs_root *root_root, uint32_t node_size)
Definition: btrfslib.c:1029
BOOL Verbose
Definition: chkdsk.c:72
DEV_ITEM dev_item
Definition: btrfslib.c:164
uint64_t last_alloc
Definition: btrfslib.c:165
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LIST_ENTRY list_entry
Definition: btrfs_drv.h:466
uint64_t root_tree_addr
Definition: btrfs.h:230
uint64_t bytes_used
Definition: btrfs.h:317
uint64_t dev_id
Definition: btrfs.h:352
static bool is_power_of_two(ULONG i)
Definition: btrfslib.c:1314
uint64_t magic
Definition: btrfs.h:228
char label[MAX_LABEL_SIZE]
Definition: btrfs.h:252
superblock * sb
Definition: btrfs.c:4261
#define TRUE
Definition: types.h:120
static bool is_mounted_multi_device(HANDLE h, uint32_t sector_size)
Definition: btrfslib.c:1200
static const BYTE us[]
Definition: encode.c:689
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOL __stdcall FormatEx(DSTRING *root, STREAM_MESSAGE *message, options *opts, uint32_t unk1)
Definition: btrfslib.c:1533
#define CSUM_TYPE_BLAKE2
Definition: btrfs.h:135
uint64_t flags
Definition: btrfs.h:426
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
#define IOCTL_BTRFS_QUERY_FILESYSTEMS
Definition: btrfsioctl.h:21
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
void * table
Definition: btrfslib.c:103
struct _tree tree
char * reloc_root
Definition: mkisofs.c:177
#define BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF
Definition: btrfs.h:121
#define free
Definition: debug_ros.c:5
struct _root root
static NTSTATUS write_btrfs(HANDLE h, uint64_t size, PUNICODE_STRING label, uint32_t sector_size, uint32_t node_size, uint64_t incompat_flags)
Definition: btrfslib.c:1061
#define TYPE_CHUNK_ITEM
Definition: btrfs.h:48
LONG NTSTATUS
Definition: precomp.h:26
static void add_inode_ref(btrfs_root *r, uint64_t inode, uint64_t parent, uint64_t index, const char *name)
Definition: btrfslib.c:903
#define FORMAT_FLAG_QUICK_FORMAT
Definition: btrfslib.c:106
NTSTATUS NTAPI NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
#define TYPE_TREE_BLOCK_REF
Definition: btrfs.h:37
void __cdecl srand(_In_ unsigned int _Seed)
uint64_t length
Definition: btrfs.h:472
ULONG_PTR DataBufferOffset
Definition: ntddscsi.h:201
struct _DEVICE_MANAGE_DATA_SET_ATTRIBUTES DEVICE_MANAGE_DATA_SET_ATTRIBUTES
GLdouble GLdouble t
Definition: gl.h:2047
#define ATA_FLAGS_DATA_IN
Definition: uata_ctl.h:222
Definition: write.c:113
void __stdcall SetIncompatFlags(uint64_t incompat_flags)
Definition: btrfslib.c:1566
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
uint64_t block_number
Definition: btrfs.h:315
enum _MEDIA_TYPE MEDIA_TYPE
#define BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA
Definition: btrfs.h:123
#define DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED
Definition: btrfslib.c:79
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
ULONG BytesPerSector
Definition: ntdddisk.h:409
uint8_t csum[32]
Definition: btrfs.h:154
#define CSUM_TYPE_CRC32C
Definition: btrfs.h:132
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
EXTENT_ITEM ei
Definition: btrfslib.c:501
__u16 time
Definition: mkdosfs.c:366
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
unsigned short int uint16_t
Definition: acefiex.h:54
#define uint16_t
Definition: nsiface.idl:60
TREE_BLOCK_REF tbr
Definition: btrfslib.c:504
#define TYPE_METADATA_ITEM
Definition: btrfs.h:36
LIST_ENTRY list_entry
Definition: btrfslib.c:144
if(dx==0 &&dy==0)
Definition: linetemp.h:174
CALLBACKCOMMAND
Definition: fmifs.h:66
uint16_t csum_type
Definition: btrfs.h:247
uint64_t used
Definition: btrfs.h:424
BTRFS_TIME st_ctime
Definition: btrfs.h:302
DSTRING * label
Definition: btrfslib.c:117
#define HEADER_FLAG_MIXED_BACKREF
Definition: btrfs.h:151
static void add_block_group_items(LIST_ENTRY *chunks, btrfs_root *extent_root)
Definition: btrfslib.c:940
uint64_t offset
Definition: btrfs.h:146
#define NtGetTickCount
Definition: rtlp.h:163
#define BTRFS_ROOT_DATA_RELOC
Definition: btrfs.h:63
static int dev
Definition: mkdosfs.c:536
#define FILE_SHARE_READ
Definition: compat.h:136
uint64_t chunk_tree_addr
Definition: btrfs.h:231
static btrfs_root * add_root(LIST_ENTRY *roots, uint64_t id)
Definition: btrfslib.c:284
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
DEVICE_DATA_MANAGEMENT_SET_ACTION Action
Definition: ntddstor.h:773
uint16_t unk1
Definition: btrfslib.c:114
uint64_t generation2
Definition: btrfs.h:324
Definition: fs.h:78
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
DWORD dwReason
Definition: misc.cpp:154
uint16_t size
Definition: btrfslib.c:142
struct node node
uint64_t offset
Definition: btrfs.h:353
static DWORD unk1
Definition: cursoricon.c:1638
static bool check_superblock_checksum(superblock *sb)
Definition: btrfslib.c:1165
#define FSCTL_UNLOCK_VOLUME
Definition: btrfslib.c:75
uint8_t checksum[32]
Definition: btrfs.h:224
btrfs_chunk * c
Definition: btrfslib.c:158
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
uint64_t address
Definition: btrfs.h:156
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define L(x)
Definition: ntvdm.h:50
uint16_t m
Definition: btrfs.h:275
uint32_t num_devices
Definition: btrfsioctl.h:191
static NTSTATUS NTAPI FormatEx2(PUNICODE_STRING DriveRoot, FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, BOOLEAN QuickFormat, ULONG ClusterSize, PFMIFSCALLBACK Callback)
Definition: btrfslib.c:1336
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
uint32_t stripe_size
Definition: btrfs.h:241
uint64_t refcount
Definition: btrfs.h:392
#define FALSE
Definition: types.h:117
#define CP_UTF8
Definition: nls.h:20
uint64_t id
Definition: btrfs_drv.h:451
unsigned int BOOL
Definition: ntddk_ex.h:94
USHORT NominalMediaRotationRate
Definition: ata.h:243
uint64_t generation
Definition: btrfs.h:313
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
uint16_t def_csum_type
Definition: btrfslib.c:180
uint64_t num_devices
Definition: btrfs.h:237
uint32_t st_nlink
Definition: btrfs.h:292
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 token
Definition: glfuncs.h:210
FORCEINLINE VOID InsertTailList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
Definition: btrfslib.c:125
#define BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS
Definition: btrfs.h:117
void blake2b(void *out, size_t outlen, const void *in, size_t inlen)
Definition: blake2b-ref.c:237
HMODULE module
Definition: btrfslib.c:177
WCHAR * string
Definition: btrfslib.c:99
#define TYPE_DEV_EXTENT
Definition: btrfs.h:46
#define DeviceDsmAction_Trim
Definition: ntddstor.h:276
char name[1]
Definition: btrfs.h:377
KEY key
Definition: btrfs.h:273
uint32_t num_references
Definition: btrfs.h:320
uint32_t offset
Definition: btrfs.h:167
char name[1]
Definition: btrfs.h:278
#define BLOCK_FLAG_SYSTEM
Definition: shellext.h:76
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
unsigned char BOOLEAN
int zero
Definition: sehframes.cpp:29
#define offsetof(TYPE, MEMBER)
#define TYPE_EXTENT_ITEM
Definition: btrfs.h:35
struct btrfs_disk_key key
Definition: btrfs.h:110
#define TYPE_INODE_REF
Definition: btrfs.h:24
DEV_ITEM dev_item
Definition: btrfs.h:251
uint8_t type
Definition: btrfs.h:277
uint32_t size
Definition: btrfs.h:168
Definition: bufpool.h:45
GLuint index
Definition: glext.h:6031
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
uint16_t n
Definition: btrfs.h:376
tree_header header
Definition: btrfslib.c:157
BOOL QuickFormat
Definition: format.c:66
BTRFS_TIME st_mtime
Definition: btrfs.h:303
uint64_t offset
Definition: btrfs.h:413
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
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
static uint64_t get_next_address(btrfs_chunk *c)
Definition: btrfslib.c:479
#define keycmp(key1, key2)
Definition: btrfslib.c:168
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 GLint GLint j
Definition: glfuncs.h:250
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
uint64_t sb_phys_addr
Definition: btrfs.h:226
r l[0]
Definition: byte_order.h:167
#define BTRFS_ROOT_ROOT
Definition: btrfs.h:54
BTRFS_UUID device_uuid
Definition: btrfs.h:190
void calc_sha256(uint8_t *hash, const void *input, size_t len)
Definition: sha256.c:126
#define BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF
Definition: btrfs.h:115
Status
Definition: gdiplustypes.h:24
BOOLEAN NTAPI BtrfsChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
uint64_t flags
Definition: btrfs.h:227
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
uint64_t st_size
Definition: btrfs.h:289
static void init_device(btrfs_dev *dev, uint64_t id, uint64_t size, BTRFS_UUID *fsuuid, uint32_t sector_size)
Definition: btrfslib.c:706
GLsizeiptr size
Definition: glext.h:5919
uint64_t objid
Definition: btrfs.h:314
static void calc_superblock_checksum(superblock *sb)
Definition: btrfslib.c:732
#define TOKEN_QUERY
Definition: setypes.h:924
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
r parent
Definition: btrfs.c:3010
#define BTRFS_ROOT_TREEDIR
Definition: btrfs.h:59
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR Name[1]
Definition: imports.h:144
FORCEINLINE VOID InitializeListHead(PLIST_ENTRY ListHead)
Definition: btrfslib.c:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void *lpReserved)
Definition: btrfslib.c:1581
#define IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
Definition: ntddstor.h:181
struct Command Command
GLintptr offset
Definition: glext.h:5920
uint64_t ULONGLONG
Definition: typedefs.h:67
uint64_t root_dir_objectid
Definition: btrfs.h:236
ULONG DataTransferLength
Definition: ntddscsi.h:198
DWORD ClusterSize
Definition: format.c:67
#define WINAPI
Definition: msvc.h:6
void * unk1
Definition: btrfslib.c:98
const GLubyte * c
Definition: glext.h:8905
static void do_full_trim(HANDLE h)
Definition: btrfslib.c:1297
KEY firstitem
Definition: btrfs.h:398
static FILE * out
Definition: regtests2xml.c:44
#define for
Definition: utility.h:88
uint64_t objid
Definition: btrfs.h:470
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint address
Definition: glext.h:9393
static bool is_ssd(HANDLE h)
Definition: btrfslib.c:975
#define success(from, fromstr, to, tostr)
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define __stdcall
Definition: typedefs.h:25
Definition: cookie.c:201
NTSTATUS WINAPI ChkdskEx(PUNICODE_STRING DriveRoot, BOOLEAN FixErrors, BOOLEAN Verbose, BOOLEAN CheckOnlyIfDirty, BOOLEAN ScanDrive, PFMIFSCALLBACK Callback)
Definition: btrfslib.c:246
#define CSUM_TYPE_XXHASH
Definition: btrfs.h:133
BTRFS_UUID dev_uuid
Definition: btrfs.h:354
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
TREE_BLOCK_REF tbr
Definition: btrfslib.c:497
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
GLbitfield flags
Definition: glext.h:7161
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
uint64_t used
Definition: btrfslib.c:151
uint64_t generation
Definition: btrfs.h:229
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
GLuint GLuint end
Definition: gl.h:1545
FMIFS_MEDIA_FLAG
Definition: btrfslib.c:190
ULONG def_node_size
Definition: btrfslib.c:178
BTRFS_TIME st_atime
Definition: btrfs.h:301
#define IOCTL_BTRFS_PROBE_VOLUME
Definition: btrfsioctl.h:28
#define SharedUserData
EXTENT_ITEM ei
Definition: btrfslib.c:495
int ret
GLenum const GLvoid * addr
Definition: glext.h:9621
tree_header header
Definition: btrfs_drv.h:426
__u8 attr
Definition: mkdosfs.c:359
#define BTRFS_INCOMPAT_FLAGS_BIG_METADATA
Definition: btrfs.h:120
#define BLOCK_FLAG_METADATA
Definition: shellext.h:77
#define BTRFS_ROOT_FSTREE
Definition: btrfs.h:58
Definition: arc.h:85
void * data
Definition: btrfslib.c:143
Definition: btrfslib.c:229
HKEY key
Definition: reg.c:28
uint64_t id
Definition: btrfslib.c:156
#define TYPE_INODE_ITEM
Definition: btrfs.h:23
uint8_t level
Definition: btrfs.h:399
ULONG LowPart
Definition: typedefs.h:106
#define TYPE_BLOCK_GROUP_ITEM
Definition: btrfs.h:42
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
crc_func calc_crc32c
Definition: crc32c.c:23
static bool superblock_collision(btrfs_chunk *c, uint64_t address)
Definition: btrfslib.c:458
#define BLAKE2_HASH_SIZE
Definition: btrfslib.c:70
#define GetCurrentProcess()
Definition: compat.h:618
uint64_t cache_generation
Definition: btrfs.h:253
static void add_item(btrfs_root *r, uint64_t obj_id, uint8_t obj_type, uint64_t offset, void *data, uint16_t size)
Definition: btrfslib.c:339
Definition: typedefs.h:119
uint32_t n
Definition: btrfs.h:242
static void init_fs_tree(btrfs_root *r, uint32_t node_size)
Definition: btrfslib.c:916
#define SYNCHRONIZE
Definition: nt_native.h:61
ULONG def_sector_size
Definition: btrfslib.c:178
uint64_t generation
Definition: btrfs.h:287
BYTE uint8_t
Definition: msvideo1.c:66
uint8_t label[11]
Definition: fsck.fat.h:65
LARGE_INTEGER Length
Definition: winioctl.h:560
uint64_t st_blocks
Definition: btrfs.h:290
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfslib.c:877
uint64_t generation
Definition: btrfs.h:393
__u8 sector_size[2]
Definition: mkdosfs.c:361
XXH_PUBLIC_API unsigned long long XXH64(const void *input, size_t len, unsigned long long seed)
Definition: xxhash.c:555
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:376
static void calc_tree_checksum(tree_header *th, uint32_t node_size)
Definition: btrfslib.c:600
static void add_dir_item(btrfs_root *root, uint64_t inode, uint32_t hash, uint64_t key_objid, uint8_t key_type, uint64_t key_offset, uint64_t transid, uint8_t type, const char *name)
Definition: btrfslib.c:1010
struct _ATA_PASS_THROUGH_EX ATA_PASS_THROUGH_EX
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
#define CSUM_TYPE_SHA256
Definition: btrfs.h:134
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
HANDLE HMODULE
Definition: typedefs.h:77
static void free_roots(LIST_ENTRY *roots)
Definition: btrfslib.c:297
Definition: btrfs.h:143
#define FSCTL_DISMOUNT_VOLUME
Definition: btrfslib.c:76
uint64_t offset
Definition: btrfslib.c:148
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1230
LIST_ENTRY list_entry
Definition: btrfslib.c:152
INODE_ITEM inode
Definition: btrfs.h:312
uint32_t flags
Definition: btrfslib.c:116
#define MAX_LABEL_SIZE
Definition: btrfs.h:19
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
UINT64 uint64_t
Definition: types.h:77
BTRFS_UUID fs_uuid
Definition: btrfs.h:155
static ATOM item
Definition: dde.c:856
GLenum GLenum GLenum input
Definition: glext.h:9031
#define BTRFS_ROOT_CHECKSUM
Definition: btrfs.h:60
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
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
GLuint in
Definition: glext.h:9616
#define EXTENT_ITEM_TREE_BLOCK
Definition: btrfs.h:388
unsigned short USHORT
Definition: pedump.c:61
uint64_t total_bytes
Definition: btrfs.h:234
KEY key
Definition: btrfs.h:166
uint64_t index
Definition: btrfs.h:375
UCHAR CurrentTaskFile[8]
Definition: ntddscsi.h:203
BTRFS_UUID uuid
Definition: btrfs.h:225
#define TYPE_ROOT_ITEM
Definition: btrfs.h:32
BOOLEAN(NTAPI * PFMIFSCALLBACK)(CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo)
Definition: btrfslib.c:237
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:859
uint32_t node_size
Definition: btrfs.h:239
#define FORCEINLINE
Definition: wdftypes.h:67
uint64_t chunk_tree
Definition: btrfs.h:425
#define TYPE_DIR_ITEM
Definition: btrfs.h:28
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
static btrfs_chunk * add_chunk(LIST_ENTRY *chunks, uint64_t flags, btrfs_root *chunk_root, btrfs_dev *dev, btrfs_root *dev_root, BTRFS_UUID *chunkuuid, uint32_t sector_size)
Definition: btrfslib.c:392
#define NULL
Definition: types.h:112
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
USHORT NameLength
Definition: imports.h:143
#define IOCTL_ATA_PASS_THROUGH
Definition: ntddscsi.h:40
uint64_t dev_id
#define DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE
Definition: ntddstor.h:306
static NTSTATUS write_data(HANDLE h, uint64_t address, btrfs_chunk *c, void *data, ULONG size)
Definition: btrfslib.c:580
UINT32 uint32_t
Definition: types.h:75
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
uint16_t unk2
Definition: btrfslib.c:115
LIST_ENTRY items
Definition: btrfslib.c:159
BOOL FixErrors
Definition: chkdsk.c:69
#define BLOCK_FLAG_DATA
Definition: shellext.h:75
#define crc32(crc, buf, len)
Definition: inflate.c:1081
uint64_t def_incompat_flags
Definition: btrfslib.c:179
#define BTRFS_ROOT_DEVTREE
Definition: btrfs.h:57
Definition: name.c:38
static const uint64_t superblock_addrs[]
Definition: btrfs.h:16
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:40
LIST_ENTRY list_entry
Definition: btrfslib.c:160
BOOL __stdcall GetFilesystemInformation(uint32_t unk1, uint32_t unk2, void *unk3)
Definition: btrfslib.c:1574
CHUNK_ITEM * chunk_item
Definition: btrfslib.c:149
#define FSCTL_LOCK_VOLUME
Definition: btrfslib.c:74
#define c
Definition: ke_i.h:80
static NTSTATUS clear_first_megabyte(HANDLE h)
Definition: btrfslib.c:957
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
#define TextOut
Definition: wingdi.h:4483
static void free_chunks(LIST_ENTRY *chunks)
Definition: btrfslib.c:324
PWCHAR Label
Definition: format.c:70
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define BTRFS_ROOT_CHUNK
Definition: btrfs.h:56
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _KEY KEY
#define HEADER_FLAG_WRITTEN
Definition: btrfs.h:149
#define malloc
Definition: debug_ros.c:4
#define BLOCK_FLAG_DUPLICATE
Definition: shellext.h:80
uint64_t transid
Definition: btrfs.h:274
#define STATUS_SUCCESS
Definition: shellext.h:65
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
uint64_t flags
Definition: btrfs.h:394
#define BTRFS_ROOT_EXTENT
Definition: btrfs.h:55
uint32_t sector_size
Definition: btrfs.h:238
uint64_t chunktree
Definition: btrfs.h:469
BTRFS_UUID chunktree_uuid
Definition: btrfs.h:473
uint32_t leaf_size
Definition: btrfs.h:240
#define uint32_t
Definition: nsiface.idl:61
uint64_t chunk_root_generation
Definition: btrfs.h:243
static void get_uuid(BTRFS_UUID *uuid)
Definition: btrfslib.c:687
uint16_t n
Definition: btrfs.h:276
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:926
static void assign_addresses(LIST_ENTRY *roots, btrfs_chunk *sys_chunk, btrfs_chunk *metadata_chunk, uint32_t node_size, btrfs_root *root_root, btrfs_root *extent_root, bool skinny)
Definition: btrfslib.c:507
void __stdcall SetSizes(ULONG sector, ULONG node)
Definition: btrfslib.c:1558
CALLBACKCOMMAND
Definition: btrfslib.c:217
base of all file and directory entries
Definition: entries.h:82
btrfs_filesystem_device device
Definition: btrfsioctl.h:192
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define APIENTRY
Definition: api.h:79
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint64_t address
Definition: btrfs.h:471
#define SHA256_HASH_SIZE
Definition: btrfslib.c:67
_In_ uint16_t _Out_ ULONG * atts
Definition: btrfs_drv.h:1107
LONGLONG QuadPart
Definition: typedefs.h:114
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:725
HMODULE hModule
Definition: animate.c:44
Definition: copy.c:22
FMIFS_MEDIA_FLAG
Definition: fmifs.h:37
#define BTRFS_MAGIC
Definition: btrfs.h:42
Definition: dlist.c:348
uint32_t st_mode
Definition: btrfs.h:295
uint64_t incompat_flags
Definition: btrfs.h:246