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