ReactOS  0.4.14-dev-49-gfb4591c
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 "btrfs.h"
41 #include "btrfsioctl.h"
42 #else
43 #include <stringapiset.h>
44 #include "../btrfs.h"
45 #include "../btrfsioctl.h"
46 #endif
47 
48 #ifndef __REACTOS__
49 #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
50 #define FSCTL_UNLOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
51 #define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
52 
53 #ifndef _MSC_VER // not in mingw yet
54 #define DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED 0x80000000
55 #endif
56 
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
61 
64 
67 #ifdef __cplusplus
68 }
69 #endif
70 #endif
71 
72 // These are undocumented, and what comes from format.exe
73 typedef struct {
74  void* table;
75  void* unk1;
77 } DSTRING;
78 
79 typedef struct {
80  void* table;
82 
83 #define FORMAT_FLAG_QUICK_FORMAT 0x00000001
84 #define FORMAT_FLAG_UNKNOWN1 0x00000002
85 #define FORMAT_FLAG_DISMOUNT_FIRST 0x00000004
86 #define FORMAT_FLAG_UNKNOWN2 0x00000040
87 #define FORMAT_FLAG_LARGE_RECORDS 0x00000100
88 #define FORMAT_FLAG_INTEGRITY_DISABLE 0x00000100
89 
90 typedef struct {
95 } options;
96 
97 #ifndef __REACTOS__
99  ListHead->Flink = ListHead->Blink = ListHead;
100 }
101 
103  PLIST_ENTRY Blink;
104 
105  Blink = ListHead->Blink;
106  Entry->Flink = ListHead;
107  Entry->Blink = Blink;
108  Blink->Flink = Entry;
109  ListHead->Blink = Entry;
110 }
111 #endif
112 
113 #ifdef __REACTOS__
115 #endif
116 
117 typedef struct {
120  void* data;
122 } btrfs_item;
123 
124 typedef struct {
130 } btrfs_chunk;
131 
132 typedef struct {
138 } btrfs_root;
139 
140 typedef struct {
143 } btrfs_dev;
144 
145 #define keycmp(key1, key2)\
146  ((key1.obj_id < key2.obj_id) ? -1 :\
147  ((key1.obj_id > key2.obj_id) ? 1 :\
148  ((key1.obj_type < key2.obj_type) ? -1 :\
149  ((key1.obj_type > key2.obj_type) ? 1 :\
150  ((key1.offset < key2.offset) ? -1 :\
151  ((key1.offset > key2.offset) ? 1 :\
152  0))))))
153 
157 
158 // the following definitions come from fmifs.h in ReactOS
159 
160 typedef struct {
161  ULONG Lines;
162  PCHAR Output;
164 
165 typedef enum {
191 
192 typedef enum {
211 
212 typedef BOOLEAN (NTAPI* PFMIFSCALLBACK)(CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo);
213 
214 static const uint32_t crctable[] = {
215  0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
216  0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,
217  0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
218  0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,
219  0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,
220  0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
221  0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,
222  0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,
223  0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
224  0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,
225  0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,
226  0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
227  0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,
228  0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,
229  0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
230  0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,
231  0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,
232  0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
233  0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,
234  0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,
235  0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
236  0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,
237  0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,
238  0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
239  0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,
240  0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,
241  0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
242  0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,
243  0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,
244  0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
245  0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
246  0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351,
247 };
248 
249 static uint32_t calc_crc32c(uint32_t seed, uint8_t* msg, ULONG msglen) {
250  uint32_t rem;
251  ULONG i;
252 
253  rem = seed;
254 
255  for (i = 0; i < msglen; i++) {
256  rem = crctable[(rem ^ msg[i]) & 0xff] ^ (rem >> 8);
257  }
258 
259  return rem;
260 }
261 
262 #ifndef __REACTOS__
264 #else
266 #endif
267  BOOLEAN ScanDrive, PFMIFSCALLBACK Callback) {
268  // STUB
269 
270  if (Callback) {
272 
273  TextOut.Lines = 1;
274  TextOut.Output = "stub, not implemented";
275 
276  Callback(OUTPUT, 0, &TextOut);
277  }
278 
279  return STATUS_SUCCESS;
280 }
281 
282 static btrfs_root* add_root(LIST_ENTRY* roots, uint64_t id) {
283  btrfs_root* root;
284 
285 #ifdef __REACTOS__
286  root = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(btrfs_root));
287 #else
288  root = malloc(sizeof(btrfs_root));
289 #endif
290 
291  root->id = id;
292 #ifndef __REACTOS__
293  RtlZeroMemory(&root->header, sizeof(tree_header));
294 #endif
295  InitializeListHead(&root->items);
296  InsertTailList(roots, &root->list_entry);
297 
298  return root;
299 }
300 
301 static void free_roots(LIST_ENTRY* roots) {
302  LIST_ENTRY* le;
303 
304  le = roots->Flink;
305  while (le != roots) {
306  LIST_ENTRY *le2 = le->Flink, *le3;
308 
309  le3 = r->items.Flink;
310  while (le3 != &r->items) {
311  LIST_ENTRY* le4 = le3->Flink;
313 
314  if (item->data)
315 #ifdef __REACTOS__
316  RtlFreeHeap(RtlGetProcessHeap(), 0, item->data);
317 
318  RtlFreeHeap(RtlGetProcessHeap(), 0, item);
319 #else
320  free(item->data);
321 
322  free(item);
323 #endif
324 
325  le3 = le4;
326  }
327 
328 #ifdef __REACTOS__
329  RtlFreeHeap(RtlGetProcessHeap(), 0, r);
330 #else
331  free(r);
332 #endif
333 
334  le = le2;
335  }
336 }
337 
338 static void free_chunks(LIST_ENTRY* chunks) {
339  LIST_ENTRY* le;
340 
341  le = chunks->Flink;
342  while (le != chunks) {
343  LIST_ENTRY *le2 = le->Flink;
345 
346 #ifndef __REACTOS__
347  free(c->chunk_item);
348  free(c);
349 #else
350  RtlFreeHeap(RtlGetProcessHeap(), 0, c->chunk_item);
351  RtlFreeHeap(RtlGetProcessHeap(), 0, c);
352 #endif
353 
354  le = le2;
355  }
356 }
357 
358 static void add_item(btrfs_root* r, uint64_t obj_id, uint8_t obj_type, uint64_t offset, void* data, uint16_t size) {
359  LIST_ENTRY* le;
360  btrfs_item* item;
361 
362 #ifndef __REACTOS__
363  item = malloc(sizeof(btrfs_item));
364 #else
365  item = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(btrfs_item));
366 #endif
367 
368  item->key.obj_id = obj_id;
369  item->key.obj_type = obj_type;
370  item->key.offset = offset;
371  item->size = size;
372 
373  if (size == 0)
374  item->data = NULL;
375  else {
376 #ifndef __REACTOS__
377  item->data = malloc(size);
378 #else
379  item->data = RtlAllocateHeap(RtlGetProcessHeap(), 0, size);
380 #endif
381  memcpy(item->data, data, size);
382  }
383 
384  le = r->items.Flink;
385  while (le != &r->items) {
387 
388  if (keycmp(item->key, i2->key) != 1) {
389  InsertTailList(le, &item->list_entry);
390  return;
391  }
392 
393  le = le->Flink;
394  }
395 
396  InsertTailList(&r->items, &item->list_entry);
397 }
398 
400  uint64_t off;
401  DEV_EXTENT de;
402 
403  off = dev->last_alloc;
404  dev->last_alloc += size;
405 
406  dev->dev_item.bytes_used += size;
407 
409  de.objid = 0x100;
410  de.address = offset;
411  de.length = size;
412  de.chunktree_uuid = *chunkuuid;
413 
414  add_item(dev_root, dev->dev_item.dev_id, TYPE_DEV_EXTENT, off, &de, sizeof(DEV_EXTENT));
415 
416  return off;
417 }
418 
419 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) {
420  uint64_t off, size;
421  uint16_t stripes, i;
422  btrfs_chunk* c;
423  LIST_ENTRY* le;
424  CHUNK_ITEM_STRIPE* cis;
425 
426  off = 0xc00000;
427  le = chunks->Flink;
428  while (le != chunks) {
430 
431  if (c->offset + c->chunk_item->size > off)
432  off = c->offset + c->chunk_item->size;
433 
434  le = le->Flink;
435  }
436 
437  if (flags & BLOCK_FLAG_METADATA) {
438  if (dev->dev_item.num_bytes > 0xC80000000) // 50 GB
439  size = 0x40000000; // 1 GB
440  else
441  size = 0x10000000; // 256 MB
442  } else if (flags & BLOCK_FLAG_SYSTEM)
443  size = 0x800000;
444 
445  size = min(size, dev->dev_item.num_bytes / 10); // cap at 10%
446  size &= ~(sector_size - 1);
447 
448  stripes = flags & BLOCK_FLAG_DUPLICATE ? 2 : 1;
449 
450  if (dev->dev_item.num_bytes - dev->dev_item.bytes_used < stripes * size) // not enough space
451  return NULL;
452 
453 #ifndef __REACTOS__
454  c = malloc(sizeof(btrfs_chunk));
455 #else
456  c = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(btrfs_chunk));
457 #endif
458  c->offset = off;
459  c->lastoff = off;
460  c->used = 0;
461 
462 #ifndef __REACTOS__
463  c->chunk_item = malloc(sizeof(CHUNK_ITEM) + (stripes * sizeof(CHUNK_ITEM_STRIPE)));
464 #else
465  c->chunk_item = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(CHUNK_ITEM) + (stripes * sizeof(CHUNK_ITEM_STRIPE)));
466 #endif
467 
468  c->chunk_item->size = size;
469  c->chunk_item->root_id = BTRFS_ROOT_EXTENT;
470  c->chunk_item->stripe_length = max(sector_size, 0x10000);
471  c->chunk_item->type = flags;
472  c->chunk_item->opt_io_alignment = max(sector_size, 0x10000);
473  c->chunk_item->opt_io_width = max(sector_size, 0x10000);
474  c->chunk_item->sector_size = sector_size;
475  c->chunk_item->num_stripes = stripes;
476  c->chunk_item->sub_stripes = 0;
477 
478  cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
479 
480  for (i = 0; i < stripes; i++) {
481  cis[i].dev_id = dev->dev_item.dev_id;
482  cis[i].offset = find_chunk_offset(size, c->offset, dev, dev_root, chunkuuid);
483  cis[i].dev_uuid = dev->dev_item.device_uuid;
484  }
485 
486  add_item(chunk_root, 0x100, TYPE_CHUNK_ITEM, c->offset, c->chunk_item, sizeof(CHUNK_ITEM) + (stripes * sizeof(CHUNK_ITEM_STRIPE)));
487 
488  InsertTailList(chunks, &c->list_entry);
489 
490  return c;
491 }
492 
494  CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
495  uint64_t stripe = (address - c->offset) / c->chunk_item->stripe_length;
496  uint16_t i, j;
497 
498  for (i = 0; i < c->chunk_item->num_stripes; i++) {
499  j = 0;
500  while (superblock_addrs[j] != 0) {
501  if (superblock_addrs[j] >= cis[i].offset) {
502  uint64_t stripe2 = (superblock_addrs[j] - cis[i].offset) / c->chunk_item->stripe_length;
503 
504  if (stripe2 == stripe)
505  return TRUE;
506  }
507  j++;
508  }
509  }
510 
511  return FALSE;
512 }
513 
515  uint64_t addr;
516 
517  addr = c->lastoff;
518 
519  while (superblock_collision(c, addr)) {
520  addr = addr - ((addr - c->offset) % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
521 
522  if (addr >= c->offset + c->chunk_item->size) // chunk has been exhausted
523  return 0;
524  }
525 
526  return addr;
527 }
528 
529 typedef struct {
534 
535 typedef struct {
541 
542 static void assign_addresses(LIST_ENTRY* roots, btrfs_chunk* sys_chunk, btrfs_chunk* metadata_chunk, uint32_t node_size,
543  btrfs_root* root_root, btrfs_root* extent_root, BOOL skinny) {
544  LIST_ENTRY* le;
545 
546  le = roots->Flink;
547  while (le != roots) {
549  btrfs_chunk* c = r->id == BTRFS_ROOT_CHUNK ? sys_chunk : metadata_chunk;
550 
551  r->header.address = get_next_address(c);
552  r->c = c;
553  c->lastoff = r->header.address + node_size;
554  c->used += node_size;
555 
556  if (skinny) {
558 
559  eim.ei.refcount = 1;
560  eim.ei.generation = 1;
563  eim.tbr.offset = r->id;
564 
565  add_item(extent_root, r->header.address, TYPE_METADATA_ITEM, 0, &eim, sizeof(EXTENT_ITEM_METADATA));
566  } else {
568  KEY firstitem;
569 
570  if (r->items.Flink == &r->items) {
571  firstitem.obj_id = 0;
572  firstitem.obj_type = 0;
573  firstitem.offset = 0;
574  } else {
575  btrfs_item* bi = CONTAINING_RECORD(r->items.Flink, btrfs_item, list_entry);
576 
577  firstitem = bi->key;
578  }
579 
580  eim2.ei.refcount = 1;
581  eim2.ei.generation = 1;
583  eim2.ei2.firstitem = firstitem;
584  eim2.ei2.level = 0;
585  eim2.type = TYPE_TREE_BLOCK_REF;
586  eim2.tbr.offset = r->id;
587 
588  add_item(extent_root, r->header.address, TYPE_EXTENT_ITEM, node_size, &eim2, sizeof(EXTENT_ITEM_METADATA2));
589  }
590 
591  if (r->id != BTRFS_ROOT_ROOT && r->id != BTRFS_ROOT_CHUNK) {
592  ROOT_ITEM ri;
593 
594  memset(&ri, 0, sizeof(ROOT_ITEM));
595 
596  ri.inode.generation = 1;
597  ri.inode.st_size = 3;
598  ri.inode.st_blocks = node_size;
599  ri.inode.st_nlink = 1;
600  ri.inode.st_mode = 040755;
601  ri.generation = 1;
602  ri.objid = r->id == 5 || r->id >= 0x100 ? SUBVOL_ROOT_INODE : 0;
603  ri.block_number = r->header.address;
604  ri.bytes_used = node_size;
605  ri.num_references = 1;
606  ri.generation2 = ri.generation;
607 
608  add_item(root_root, r->id, TYPE_ROOT_ITEM, 0, &ri, sizeof(ROOT_ITEM));
609  }
610 
611  le = le->Flink;
612  }
613 }
614 
617  uint16_t i;
620  CHUNK_ITEM_STRIPE* cis;
621 
622  cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
623 
624  for (i = 0; i < c->chunk_item->num_stripes; i++) {
625  off.QuadPart = cis[i].offset + address - c->offset;
626 
628  if (!NT_SUCCESS(Status))
629  return Status;
630  }
631 
632  return STATUS_SUCCESS;
633 }
634 
635 static NTSTATUS write_roots(HANDLE h, LIST_ENTRY* roots, uint32_t node_size, BTRFS_UUID* fsuuid, BTRFS_UUID* chunkuuid) {
636  LIST_ENTRY *le, *le2;
638  uint8_t* tree;
639 
640 #ifndef __REACTOS__
641  tree = malloc(node_size);
642 #else
643  tree = RtlAllocateHeap(RtlGetProcessHeap(), 0, node_size);
644 #endif
645 
646  le = roots->Flink;
647  while (le != roots) {
649  uint8_t* dp;
650  leaf_node* ln;
651  uint32_t crc32;
652 
653  memset(tree, 0, node_size);
654 
655  r->header.num_items = 0;
656  r->header.fs_uuid = *fsuuid;
658  r->header.chunk_tree_uuid = *chunkuuid;
659  r->header.generation = 1;
660  r->header.tree_id = r->id;
661 
662  ln = (leaf_node*)(tree + sizeof(tree_header));
663 
664  dp = tree + node_size;
665 
666  le2 = r->items.Flink;
667  while (le2 != &r->items) {
669 
670  ln->key = item->key;
671  ln->size = item->size;
672 
673  if (item->size > 0) {
674  dp -= item->size;
675  memcpy(dp, item->data, item->size);
676 
677  ln->offset = dp - tree - sizeof(tree_header);
678  } else
679  ln->offset = 0;
680 
681  ln = &ln[1];
682 
683  r->header.num_items++;
684 
685  le2 = le2->Flink;
686  }
687 
688  memcpy(tree, &r->header, sizeof(tree_header));
689 
690  crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&((tree_header*)tree)->fs_uuid, node_size - sizeof(((tree_header*)tree)->csum));
691  memcpy(tree, &crc32, sizeof(uint32_t));
692 
693  Status = write_data(h, r->header.address, r->c, tree, node_size);
694  if (!NT_SUCCESS(Status)) {
695 #ifndef __REACTOS__
696  free(tree);
697 #else
698  RtlFreeHeap(RtlGetProcessHeap(), 0, tree);
699 #endif
700  return Status;
701  }
702 
703  le = le->Flink;
704  }
705 
706 #ifndef __REACTOS__
707  free(tree);
708 #else
709  RtlFreeHeap(RtlGetProcessHeap(), 0, tree);
710 #endif
711 
712  return STATUS_SUCCESS;
713 }
714 
715 #ifndef __REACTOS__
716 static void get_uuid(BTRFS_UUID* uuid) {
717 #else
718 static void get_uuid(BTRFS_UUID* uuid, ULONG* seed) {
719 #endif
720  uint8_t i;
721 
722  for (i = 0; i < 16; i+=2) {
723 #ifndef __REACTOS__
724  ULONG r = rand();
725 #else
726  ULONG r = RtlRandom(seed);
727 #endif
728 
729  uuid->uuid[i] = (r & 0xff00) >> 8;
730  uuid->uuid[i+1] = r & 0xff;
731  }
732 }
733 
734 #ifndef __REACTOS__
736 #else
737 static void init_device(btrfs_dev* dev, uint64_t id, uint64_t size, BTRFS_UUID* fsuuid, uint32_t sector_size, ULONG* seed) {
738 #endif
739  dev->dev_item.dev_id = id;
740  dev->dev_item.num_bytes = size;
741  dev->dev_item.bytes_used = 0;
742  dev->dev_item.optimal_io_align = sector_size;
743  dev->dev_item.optimal_io_width = sector_size;
744  dev->dev_item.minimal_io_size = sector_size;
745  dev->dev_item.type = 0;
746  dev->dev_item.generation = 0;
747  dev->dev_item.start_offset = 0;
748  dev->dev_item.dev_group = 0;
749  dev->dev_item.seek_speed = 0;
750  dev->dev_item.bandwidth = 0;
751 #ifndef __REACTOS__
752  get_uuid(&dev->dev_item.device_uuid);
753 #else
754  get_uuid(&dev->dev_item.device_uuid, seed);
755 #endif
756  dev->dev_item.fs_uuid = *fsuuid;
757 
758  dev->last_alloc = 0x100000; // skip first megabyte
759 }
760 
761 static NTSTATUS write_superblocks(HANDLE h, btrfs_dev* dev, btrfs_root* chunk_root, btrfs_root* root_root, btrfs_root* extent_root,
762  btrfs_chunk* sys_chunk, uint32_t node_size, BTRFS_UUID* fsuuid, uint32_t sector_size, PUNICODE_STRING label, uint64_t incompat_flags) {
765  ULONG sblen;
766  int i;
767  uint32_t crc32;
768  superblock* sb;
769  KEY* key;
770  uint64_t bytes_used;
771  LIST_ENTRY* le;
772 
773  sblen = sizeof(*sb);
774  if (sblen & (sector_size - 1))
775  sblen = (sblen & sector_size) + sector_size;
776 
777  bytes_used = 0;
778 
779  le = extent_root->items.Flink;
780  while (le != &extent_root->items) {
782 
783  if (item->key.obj_type == TYPE_EXTENT_ITEM)
784  bytes_used += item->key.offset;
785  else if (item->key.obj_type == TYPE_METADATA_ITEM)
786  bytes_used += node_size;
787 
788  le = le->Flink;
789  }
790 
791 #ifndef __REACTOS__
792  sb = malloc(sblen);
793  memset(sb, 0, sblen);
794 #else
795  sb = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sblen);
796 #endif
797 
798  sb->uuid = *fsuuid;
799  sb->flags = 1;
800  sb->magic = BTRFS_MAGIC;
801  sb->generation = 1;
802  sb->root_tree_addr = root_root->header.address;
803  sb->chunk_tree_addr = chunk_root->header.address;
804  sb->total_bytes = dev->dev_item.num_bytes;
805  sb->bytes_used = bytes_used;
806  sb->root_dir_objectid = 6;
807  sb->num_devices = 1;
809  sb->node_size = node_size;
810  sb->leaf_size = node_size;
812  sb->n = sizeof(KEY) + sizeof(CHUNK_ITEM) + (sys_chunk->chunk_item->num_stripes * sizeof(CHUNK_ITEM_STRIPE));
814  sb->incompat_flags = incompat_flags;
815  memcpy(&sb->dev_item, &dev->dev_item, sizeof(DEV_ITEM));
816 
817  if (label->Length > 0) {
818 #ifdef __REACTOS__
819  ANSI_STRING as;
820  unsigned int i;
821 
822  for (i = 0; i < label->Length / sizeof(WCHAR); i++) {
823 #else
824  ULONG utf8len;
825 
826  for (unsigned int i = 0; i < label->Length / sizeof(WCHAR); i++) {
827 #endif
828  if (label->Buffer[i] == '/' || label->Buffer[i] == '\\') {
829 #ifndef __REACTOS__
830  free(sb);
831 #else
832  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
833 #endif
835  }
836  }
837 
838 #ifndef __REACTOS__
839  utf8len = WideCharToMultiByte(CP_UTF8, 0, label->Buffer, label->Length, NULL, 0, NULL, NULL);
840 
841  if (utf8len == 0 || utf8len > MAX_LABEL_SIZE) {
842  free(sb);
844  }
845 
846  if (WideCharToMultiByte(CP_UTF8, 0, label->Buffer, label->Length, sb->label, utf8len, NULL, NULL) == 0) {
847  free(sb);
849  }
850 #else
851  as.Buffer = sb->label;
852  as.Length = 0;
854 
856  {
857  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
859  }
860 #endif
861  }
862  sb->cache_generation = 0xffffffffffffffff;
863 
864  key = (KEY*)sb->sys_chunk_array;
865  key->obj_id = 0x100;
866  key->obj_type = TYPE_CHUNK_ITEM;
867  key->offset = sys_chunk->offset;
868  memcpy(&key[1], sys_chunk->chunk_item, sizeof(CHUNK_ITEM) + (sys_chunk->chunk_item->num_stripes * sizeof(CHUNK_ITEM_STRIPE)));
869 
870  i = 0;
871  while (superblock_addrs[i] != 0) {
873 
874  if (superblock_addrs[i] > dev->dev_item.num_bytes)
875  break;
876 
878 
879  crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
880  memcpy(&sb->checksum, &crc32, sizeof(uint32_t));
881 
882  off.QuadPart = superblock_addrs[i];
883 
884  Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, sb, sblen, &off, NULL);
885  if (!NT_SUCCESS(Status)) {
886 #ifndef __REACTOS__
887  free(sb);
888 #else
889  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
890 #endif
891  return Status;
892  }
893 
894  i++;
895  }
896 
897 #ifndef __REACTOS__
898  free(sb);
899 #else
900  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
901 #endif
902 
903  return STATUS_SUCCESS;
904 }
905 
906 static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME* out) {
907  ULONGLONG l = t.QuadPart - 116444736000000000;
908 
909  out->seconds = l / 10000000;
910  out->nanoseconds = (l % 10000000) * 100;
911 }
912 
913 #ifdef __REACTOS__
914 VOID
915 WINAPI
917 {
918  LARGE_INTEGER SystemTime;
919 
920  do
921  {
922  SystemTime.HighPart = SharedUserData->SystemTime.High1Time;
923  SystemTime.LowPart = SharedUserData->SystemTime.LowPart;
924  }
925  while (SystemTime.HighPart != SharedUserData->SystemTime.High2Time);
926 
927  lpFileTime->dwLowDateTime = SystemTime.LowPart;
928  lpFileTime->dwHighDateTime = SystemTime.HighPart;
929 }
930 #endif
931 
932 static void init_fs_tree(btrfs_root* r, uint32_t node_size) {
933  INODE_ITEM ii;
934  INODE_REF* ir;
937 
938  memset(&ii, 0, sizeof(INODE_ITEM));
939 
940  ii.generation = 1;
941  ii.st_blocks = node_size;
942  ii.st_nlink = 1;
943  ii.st_mode = 040755;
944 
946  time.LowPart = filetime.dwLowDateTime;
947  time.HighPart = filetime.dwHighDateTime;
948 
950  ii.st_ctime = ii.st_mtime = ii.st_atime;
951 
953 
954 #ifndef __REACTOS__
955  ir = malloc(sizeof(INODE_REF) - 1 + 2);
956 #else
957  ir = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(INODE_REF) - 1 + 2);
958 #endif
959 
960  ir->index = 0;
961  ir->n = 2;
962  ir->name[0] = '.';
963  ir->name[1] = '.';
964 
966 
967 #ifndef __REACTOS__
968  free(ir);
969 #else
970  RtlFreeHeap(RtlGetProcessHeap(), 0, ir);
971 #endif
972 }
973 
974 static void add_block_group_items(LIST_ENTRY* chunks, btrfs_root* extent_root) {
975  LIST_ENTRY* le;
976 
977  le = chunks->Flink;
978  while (le != chunks) {
980  BLOCK_GROUP_ITEM bgi;
981 
982  bgi.used = c->used;
983  bgi.chunk_tree = 0x100;
984  bgi.flags = c->chunk_item->type;
985  add_item(extent_root, c->offset, TYPE_BLOCK_GROUP_ITEM, c->chunk_item->size, &bgi, sizeof(BLOCK_GROUP_ITEM));
986 
987  le = le->Flink;
988  }
989 }
990 
995  uint8_t* mb;
996 
997 #ifndef __REACTOS__
998  mb = malloc(0x100000);
999  memset(mb, 0, 0x100000);
1000 #else
1001  mb = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 0x100000);
1002 #endif
1003 
1004  zero.QuadPart = 0;
1005 
1006  Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, mb, 0x100000, &zero, NULL);
1007 
1008 #ifndef __REACTOS__
1009  free(mb);
1010 #else
1011  RtlFreeHeap(RtlGetProcessHeap(), 0, mb);
1012 #endif
1013 
1014  return Status;
1015 }
1016 
1017 static BOOL is_ssd(HANDLE h) {
1018  ULONG aptelen;
1019  ATA_PASS_THROUGH_EX* apte;
1021  NTSTATUS Status;
1022  IDENTIFY_DEVICE_DATA* idd;
1023 
1024  aptelen = sizeof(ATA_PASS_THROUGH_EX) + 512;
1025 #ifndef __REACTOS__
1026  apte = malloc(aptelen);
1027 
1028  RtlZeroMemory(apte, aptelen);
1029 #else
1030  apte = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, aptelen);
1031 #endif
1032 
1033  apte->Length = sizeof(ATA_PASS_THROUGH_EX);
1034  apte->AtaFlags = ATA_FLAGS_DATA_IN;
1035  apte->DataTransferLength = aptelen - sizeof(ATA_PASS_THROUGH_EX);
1036  apte->TimeOutValue = 3;
1037  apte->DataBufferOffset = apte->Length;
1039 
1040  Status = NtDeviceIoControlFile(h, NULL, NULL, NULL, &iosb, IOCTL_ATA_PASS_THROUGH, apte, aptelen, apte, aptelen);
1041 
1042  if (NT_SUCCESS(Status)) {
1043  idd = (IDENTIFY_DEVICE_DATA*)((uint8_t*)apte + sizeof(ATA_PASS_THROUGH_EX));
1044 
1045  if (idd->NominalMediaRotationRate == 1) {
1046 #ifndef __REACTOS__
1047  free(apte);
1048 #else
1049  RtlFreeHeap(RtlGetProcessHeap(), 0, apte);
1050 #endif
1051  return TRUE;
1052  }
1053  }
1054 
1055 #ifndef __REACTOS__
1056  free(apte);
1057 #else
1058  RtlFreeHeap(RtlGetProcessHeap(), 0, apte);
1059 #endif
1060 
1061  return FALSE;
1062 }
1063 
1065  NTSTATUS Status;
1066  LIST_ENTRY roots, chunks;
1067  btrfs_root *root_root, *chunk_root, *extent_root, *dev_root, *fs_root, *reloc_root;
1068  btrfs_chunk *sys_chunk, *metadata_chunk;
1069  btrfs_dev dev;
1070  BTRFS_UUID fsuuid, chunkuuid;
1071  BOOL ssd;
1072  uint64_t metadata_flags;
1073 #ifdef __REACTOS__
1074  ULONG seed;
1075 #endif
1076 
1077 #ifndef __REACTOS__
1078  srand((unsigned int)time(0));
1079  get_uuid(&fsuuid);
1080  get_uuid(&chunkuuid);
1081 #else
1082  seed = NtGetTickCount();
1083  get_uuid(&fsuuid, &seed);
1084  get_uuid(&chunkuuid, &seed);
1085 #endif
1086 
1087  InitializeListHead(&roots);
1088  InitializeListHead(&chunks);
1089 
1090  root_root = add_root(&roots, BTRFS_ROOT_ROOT);
1091  chunk_root = add_root(&roots, BTRFS_ROOT_CHUNK);
1092  extent_root = add_root(&roots, BTRFS_ROOT_EXTENT);
1093  dev_root = add_root(&roots, BTRFS_ROOT_DEVTREE);
1094  add_root(&roots, BTRFS_ROOT_CHECKSUM);
1095  fs_root = add_root(&roots, BTRFS_ROOT_FSTREE);
1097 
1098 #ifndef __REACTOS__
1099  init_device(&dev, 1, size, &fsuuid, sector_size);
1100 #else
1101  init_device(&dev, 1, size, &fsuuid, sector_size, &seed);
1102 #endif
1103 
1104  ssd = is_ssd(h);
1105 
1106  sys_chunk = add_chunk(&chunks, BLOCK_FLAG_SYSTEM | (ssd ? 0 : BLOCK_FLAG_DUPLICATE), chunk_root, &dev, dev_root, &chunkuuid, sector_size);
1107  if (!sys_chunk)
1108  return STATUS_INTERNAL_ERROR;
1109 
1110  metadata_flags = BLOCK_FLAG_METADATA;
1111 
1112  if (!ssd && !(incompat_flags & BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS))
1113  metadata_flags |= BLOCK_FLAG_DUPLICATE;
1114 
1115  if (incompat_flags & BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS)
1116  metadata_flags |= BLOCK_FLAG_DATA;
1117 
1118  metadata_chunk = add_chunk(&chunks, metadata_flags, chunk_root, &dev, dev_root, &chunkuuid, sector_size);
1119  if (!metadata_chunk)
1120  return STATUS_INTERNAL_ERROR;
1121 
1122  add_item(chunk_root, 1, TYPE_DEV_ITEM, dev.dev_item.dev_id, &dev.dev_item, sizeof(DEV_ITEM));
1123 
1124  init_fs_tree(fs_root, node_size);
1125  init_fs_tree(reloc_root, node_size);
1126 
1127  assign_addresses(&roots, sys_chunk, metadata_chunk, node_size, root_root, extent_root, incompat_flags & BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA);
1128 
1129  add_block_group_items(&chunks, extent_root);
1130 
1131  Status = write_roots(h, &roots, node_size, &fsuuid, &chunkuuid);
1132  if (!NT_SUCCESS(Status))
1133  return Status;
1134 
1136  if (!NT_SUCCESS(Status))
1137  return Status;
1138 
1139  Status = write_superblocks(h, &dev, chunk_root, root_root, extent_root, sys_chunk, node_size, &fsuuid, sector_size, label, incompat_flags);
1140  if (!NT_SUCCESS(Status))
1141  return Status;
1142 
1143  free_roots(&roots);
1144  free_chunks(&chunks);
1145 
1146  return STATUS_SUCCESS;
1147 }
1148 
1150  uint32_t i;
1152 
1153  for (i = 0; i < bfs->num_devices; i++) {
1154  if (i == 0)
1155  dev = &bfs->device;
1156  else
1158 
1159  if (RtlCompareMemory(&dev->uuid, devuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID))
1160  return TRUE;
1161  }
1162 
1163  return FALSE;
1164 }
1165 
1167  NTSTATUS Status;
1168  superblock* sb;
1169  ULONG sblen;
1172  BTRFS_UUID fsuuid, devuuid;
1173  uint32_t crc32;
1176  HANDLE h2;
1177  btrfs_filesystem *bfs = NULL, *bfs2;
1178  ULONG bfssize;
1179  BOOL ret = FALSE;
1180 
1181  static WCHAR btrfs[] = L"\\Btrfs";
1182 
1183  sblen = sizeof(*sb);
1184  if (sblen & (sector_size - 1))
1185  sblen = (sblen & sector_size) + sector_size;
1186 
1187 #ifndef __REACTOS__
1188  sb = malloc(sblen);
1189 #else
1190  sb = RtlAllocateHeap(RtlGetProcessHeap(), 0, sblen);
1191 #endif
1192 
1193  off.QuadPart = superblock_addrs[0];
1194 
1195  Status = NtReadFile(h, NULL, NULL, NULL, &iosb, sb, sblen, &off, NULL);
1196  if (!NT_SUCCESS(Status)) {
1197 #ifndef __REACTOS__
1198  free(sb);
1199 #else
1200  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
1201 #endif
1202  return FALSE;
1203  }
1204 
1205  if (sb->magic != BTRFS_MAGIC) {
1206 #ifndef __REACTOS__
1207  free(sb);
1208 #else
1209  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
1210 #endif
1211  return FALSE;
1212  }
1213 
1214  crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
1215  if (crc32 != *((uint32_t*)sb)) {
1216 #ifndef __REACTOS__
1217  free(sb);
1218 #else
1219  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
1220 #endif
1221  return FALSE;
1222  }
1223 
1224  fsuuid = sb->uuid;
1225  devuuid = sb->dev_item.device_uuid;
1226 
1227 #ifndef __REACTOS__
1228  free(sb);
1229 #else
1230  RtlFreeHeap(RtlGetProcessHeap(), 0, sb);
1231 #endif
1232 
1233  us.Length = us.MaximumLength = (USHORT)(wcslen(btrfs) * sizeof(WCHAR));
1234  us.Buffer = btrfs;
1235 
1237 
1240  if (!NT_SUCCESS(Status)) // not a problem, it usually just means the driver isn't loaded
1241  return FALSE;
1242 
1243  bfssize = 0;
1244 
1245  do {
1246  bfssize += 1024;
1247 
1248 #ifndef __REACTOS__
1249  if (bfs) free(bfs);
1250  bfs = malloc(bfssize);
1251 #else
1252  if (bfs) RtlFreeHeap(RtlGetProcessHeap(), 0, bfs);
1253  bfs = RtlAllocateHeap(RtlGetProcessHeap(), 0, bfssize);
1254 #endif
1255 
1258  NtClose(h2);
1259  return FALSE;
1260  }
1261  } while (Status == STATUS_BUFFER_OVERFLOW);
1262 
1263  if (!NT_SUCCESS(Status))
1264  goto end;
1265 
1266  if (bfs->num_devices != 0) {
1267  bfs2 = bfs;
1268  while (TRUE) {
1269  if (RtlCompareMemory(&bfs2->uuid, &fsuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1270  if (bfs2->num_devices == 1)
1271  ret = FALSE;
1272  else
1273  ret = look_for_device(bfs2, &devuuid);
1274 
1275  goto end;
1276  }
1277 
1278  if (bfs2->next_entry == 0)
1279  break;
1280  else
1281  bfs2 = (btrfs_filesystem*)((uint8_t*)bfs2 + bfs2->next_entry);
1282  }
1283  }
1284 
1285 end:
1286  NtClose(h2);
1287 
1288  if (bfs)
1289 #ifndef __REACTOS__
1290  free(bfs);
1291 #else
1292  RtlFreeHeap(RtlGetProcessHeap(), 0, bfs);
1293 #endif
1294 
1295  return ret;
1296 }
1297 
1298 static void do_full_trim(HANDLE h) {
1301 
1303 
1304  dmdsa.Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES);
1305  dmdsa.Action = DeviceDsmAction_Trim;
1307  dmdsa.ParameterBlockOffset = 0;
1308  dmdsa.ParameterBlockLength = 0;
1309  dmdsa.DataSetRangesOffset = 0;
1310  dmdsa.DataSetRangesLength = 0;
1311 
1313 }
1314 
1316  return ((i != 0) && !(i & (i - 1)));
1317 }
1318 
1319 #ifndef __REACTOS__
1321 #else
1323 #endif
1325 {
1326  NTSTATUS Status;
1327  HANDLE h, btrfsh;
1331  DISK_GEOMETRY dg;
1332  uint32_t sector_size, node_size;
1333  UNICODE_STRING btrfsus;
1334 #ifndef __REACTOS__
1335  HANDLE token;
1337  LUID luid;
1338 #endif
1339  uint64_t incompat_flags;
1340  UNICODE_STRING empty_label;
1341 
1342  static WCHAR btrfs[] = L"\\Btrfs";
1343 
1344 #ifndef __REACTOS__
1347 
1348  if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &luid)) {
1349  CloseHandle(token);
1351  }
1352 
1353  tp.PrivilegeCount = 1;
1354  tp.Privileges[0].Luid = luid;
1355  tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1356 
1358  CloseHandle(token);
1360  }
1361 
1362  CloseHandle(token);
1363 #endif
1364 
1366 
1369 
1370  if (!NT_SUCCESS(Status))
1371  return Status;
1372 
1374  if (!NT_SUCCESS(Status)) {
1375  NtClose(h);
1376  return Status;
1377  }
1378 
1379  // MSDN tells us to use IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, but there are
1380  // some instances where it fails and IOCTL_DISK_GET_DRIVE_GEOMETRY succeeds -
1381  // such as with spanned volumes.
1383  if (!NT_SUCCESS(Status)) {
1384  NtClose(h);
1385  return Status;
1386  }
1387 
1388  if (def_sector_size == 0) {
1390 
1391  if (sector_size == 0x200 || sector_size == 0)
1392  sector_size = 0x1000;
1393  } else {
1395  NtClose(h);
1396  return STATUS_INVALID_PARAMETER;
1397  }
1398 
1400  }
1401 
1402  if (def_node_size == 0)
1403  node_size = 0x4000;
1404  else {
1406  NtClose(h);
1407  return STATUS_INVALID_PARAMETER;
1408  }
1409 
1410  node_size = def_node_size;
1411  }
1412 
1413  if (Callback) {
1414  ULONG pc = 0;
1415  Callback(PROGRESS, 0, (PVOID)&pc);
1416  }
1417 
1419 
1422  goto end;
1423  }
1424 
1425  do_full_trim(h);
1426 
1427  incompat_flags = def_incompat_flags;
1429 
1430  if (!Label) {
1431  empty_label.Buffer = NULL;
1432  empty_label.Length = empty_label.MaximumLength = 0;
1433  Label = &empty_label;
1434  }
1435 
1436  Status = write_btrfs(h, gli.Length.QuadPart, Label, sector_size, node_size, incompat_flags);
1437 
1439 
1440 end:
1442 
1443  NtClose(h);
1444 
1445  if (NT_SUCCESS(Status)) {
1446  btrfsus.Buffer = btrfs;
1447  btrfsus.Length = btrfsus.MaximumLength = (USHORT)(wcslen(btrfs) * sizeof(WCHAR));
1448 
1449  InitializeObjectAttributes(&attr, &btrfsus, 0, NULL, NULL);
1450 
1453 
1454  if (NT_SUCCESS(Status)) {
1455  MOUNTDEV_NAME* mdn;
1456  ULONG mdnsize;
1457 
1458  mdnsize = offsetof(MOUNTDEV_NAME, Name[0]) + DriveRoot->Length;
1459 #ifndef __REACTOS__
1460  mdn = malloc(mdnsize);
1461 #else
1462  mdn = RtlAllocateHeap(RtlGetProcessHeap(), 0, mdnsize);
1463 #endif
1464 
1465  mdn->NameLength = DriveRoot->Length;
1466  memcpy(mdn->Name, DriveRoot->Buffer, DriveRoot->Length);
1467 
1468  NtDeviceIoControlFile(btrfsh, NULL, NULL, NULL, &iosb, IOCTL_BTRFS_PROBE_VOLUME, mdn, mdnsize, NULL, 0);
1469 
1470 #ifndef __REACTOS__
1471  free(mdn);
1472 #else
1473  RtlFreeHeap(RtlGetProcessHeap(), 0, mdn);
1474 #endif
1475 
1476  NtClose(btrfsh);
1477  }
1478 
1480  }
1481 
1482  if (Callback) {
1484  Callback(DONE, 0, (PVOID)&success);
1485  }
1486 
1487  return Status;
1488 }
1489 
1491  UNICODE_STRING DriveRoot, Label;
1492  NTSTATUS Status;
1493 
1494  if (!root || !root->string)
1495  return FALSE;
1496 
1497  DriveRoot.Length = DriveRoot.MaximumLength = (USHORT)(wcslen(root->string) * sizeof(WCHAR));
1498  DriveRoot.Buffer = root->string;
1499 
1500  if (opts && opts->label && opts->label->string) {
1501  Label.Length = Label.MaximumLength = (USHORT)(wcslen(opts->label->string) * sizeof(WCHAR));
1502  Label.Buffer = opts->label->string;
1503  } else {
1504  Label.Length = Label.MaximumLength = 0;
1505  Label.Buffer = NULL;
1506  }
1507 
1508 #ifndef __REACTOS__
1509  Status = FormatEx2(&DriveRoot, FMIFS_HARDDISK, &Label, opts && opts->flags & FORMAT_FLAG_QUICK_FORMAT, 0, NULL);
1510 #else
1511  Status = BtrfsFormatEx(&DriveRoot, FMIFS_HARDDISK, &Label, opts && opts->flags & FORMAT_FLAG_QUICK_FORMAT, 0, NULL);
1512 #endif
1513 
1514  return NT_SUCCESS(Status);
1515 }
1516 
1518  if (sector != 0)
1520 
1521  if (node != 0)
1522  def_node_size = node;
1523 }
1524 
1525 void __stdcall SetIncompatFlags(uint64_t incompat_flags) {
1526  def_incompat_flags = incompat_flags;
1527 }
1528 
1530  // STUB - undocumented
1531 
1532  return TRUE;
1533 }
1534 
1535 #ifndef __REACTOS__
1538  module = (HMODULE)hModule;
1539 
1540  return TRUE;
1541 }
1542 #endif
void * table
Definition: btrfslib.c:74
signed char * PCHAR
Definition: retypes.h:7
uint8_t sys_chunk_array[SYS_CHUNK_ARRAY_SIZE]
Definition: btrfs.h:239
#define FILE_GENERIC_READ
Definition: nt_native.h:653
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
uint64_t obj_id
Definition: btrfs.h:127
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#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
#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:127
struct TEXTOUTPUT * PTEXTOUTPUT
#define TRUE
Definition: types.h:120
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:761
#define CloseHandle
Definition: compat.h:398
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:128
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpPrivilegeName, PLUID lpLuid)
Definition: misc.c:782
static BOOL look_for_device(btrfs_filesystem *bfs, BTRFS_UUID *devuuid)
Definition: btrfslib.c:1149
static BOOL is_power_of_two(ULONG i)
Definition: btrfslib.c:1315
static NTSTATUS write_roots(HANDLE h, LIST_ENTRY *roots, uint32_t node_size, BTRFS_UUID *fsuuid, BTRFS_UUID *chunkuuid)
Definition: btrfslib.c:635
uint64_t bytes_used
Definition: btrfs.h:218
#define WideCharToMultiByte
Definition: compat.h:101
EXTENT_ITEM2 ei2
Definition: btrfslib.c:537
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:640
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:399
USHORT MaximumLength
Definition: env_spec_w32.h:370
BOOL Verbose
Definition: chkdsk.c:72
DEV_ITEM dev_item
Definition: btrfslib.c:141
uint64_t last_alloc
Definition: btrfslib.c:142
LIST_ENTRY list_entry
Definition: btrfs_drv.h:460
uint64_t root_tree_addr
Definition: btrfs.h:213
uint64_t bytes_used
Definition: btrfs.h:294
uint64_t dev_id
Definition: btrfs.h:329
uint64_t magic
Definition: btrfs.h:211
char label[MAX_LABEL_SIZE]
Definition: btrfs.h:235
superblock * sb
Definition: btrfs.c:4162
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:1490
uint64_t flags
Definition: btrfs.h:403
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
#define IOCTL_BTRFS_QUERY_FILESYSTEMS
Definition: btrfsioctl.h:21
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
void * table
Definition: btrfslib.c:80
struct _tree tree
char * reloc_root
Definition: mkisofs.c:177
#define BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF
Definition: btrfs.h:111
#define free
Definition: debug_ros.c:5
struct _root root
static BOOL is_ssd(HANDLE h)
Definition: btrfslib.c:1017
static uint32_t calc_crc32c(uint32_t seed, uint8_t *msg, ULONG msglen)
Definition: btrfslib.c:249
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:1064
#define TYPE_CHUNK_ITEM
Definition: btrfs.h:44
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define FORMAT_FLAG_QUICK_FORMAT
Definition: btrfslib.c:83
GLintptr offset
Definition: glext.h:5920
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:449
ULONG_PTR DataBufferOffset
Definition: ntddscsi.h:139
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
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
Definition: write.c:111
void __stdcall SetIncompatFlags(uint64_t incompat_flags)
Definition: btrfslib.c:1525
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
uint64_t block_number
Definition: btrfs.h:292
#define BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA
Definition: btrfs.h:113
#define NTSYSCALLAPI
Definition: ntbasedef.h:204
#define DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED
Definition: btrfslib.c:54
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
uint32_t crc32
Definition: btrfs.c:4163
ULONG BytesPerSector
Definition: ntdddisk.h:376
GLuint GLuint end
Definition: gl.h:1545
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:536
__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
TREE_BLOCK_REF tbr
Definition: btrfslib.c:539
#define TYPE_METADATA_ITEM
Definition: btrfs.h:32
LIST_ENTRY list_entry
Definition: btrfslib.c:121
CALLBACKCOMMAND
Definition: fmifs.h:66
uint64_t used
Definition: btrfs.h:401
BTRFS_TIME st_ctime
Definition: btrfs.h:283
DSTRING * label
Definition: btrfslib.c:94
#define HEADER_FLAG_MIXED_BACKREF
Definition: btrfs.h:134
static void add_block_group_items(LIST_ENTRY *chunks, btrfs_root *extent_root)
Definition: btrfslib.c:974
uint64_t offset
Definition: btrfs.h:129
#define NtGetTickCount
Definition: rtlp.h:146
#define BTRFS_ROOT_DATA_RELOC
Definition: btrfs.h:58
static int dev
Definition: mkdosfs.c:536
CHAR InputBuffer[80]
Definition: conmgr.c:33
#define FILE_SHARE_READ
Definition: compat.h:125
uint64_t chunk_tree_addr
Definition: btrfs.h:214
static btrfs_root * add_root(LIST_ENTRY *roots, uint64_t id)
Definition: btrfslib.c:282
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
DEVICE_DATA_MANAGEMENT_SET_ACTION Action
Definition: ntddstor.h:578
uint16_t unk1
Definition: btrfslib.c:91
uint64_t generation2
Definition: btrfs.h:301
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
DWORD dwReason
Definition: misc.cpp:154
uint16_t size
Definition: btrfslib.c:119
struct node node
uint64_t offset
Definition: btrfs.h:330
static DWORD unk1
Definition: cursoricon.c:1521
HANDLE FileHandle
Definition: stats.c:38
#define FSCTL_UNLOCK_VOLUME
Definition: btrfslib.c:50
uint8_t checksum[32]
Definition: btrfs.h:207
NTSTATUS NTAPI BtrfsFormatEx(IN PUNICODE_STRING DriveRoot, IN FMIFS_MEDIA_FLAG MediaFlag, IN PUNICODE_STRING Label, IN BOOLEAN QuickFormat, IN ULONG ClusterSize, IN PFMIFSCALLBACK Callback)
btrfs_chunk * c
Definition: btrfslib.c:135
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
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
uint64_t address
Definition: btrfs.h:139
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
uint32_t num_devices
Definition: btrfsioctl.h:189
static NTSTATUS NTAPI FormatEx2(PUNICODE_STRING DriveRoot, FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, BOOLEAN QuickFormat, ULONG ClusterSize, PFMIFSCALLBACK Callback)
Definition: btrfslib.c:1320
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:224
uint64_t refcount
Definition: btrfs.h:369
#define CP_UTF8
Definition: nls.h:20
uint64_t id
Definition: btrfs_drv.h:446
unsigned int BOOL
Definition: ntddk_ex.h:94
USHORT NominalMediaRotationRate
Definition: ata.h:243
uint64_t generation
Definition: btrfs.h:290
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
uint64_t num_devices
Definition: btrfs.h:220
uint32_t st_nlink
Definition: btrfs.h:274
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:102
#define BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS
Definition: btrfs.h:107
HMODULE module
Definition: btrfslib.c:154
WCHAR * string
Definition: btrfslib.c:76
#define TYPE_DEV_EXTENT
Definition: btrfs.h:42
#define DeviceDsmAction_Trim
Definition: ntddstor.h:211
char name[1]
Definition: btrfs.h:354
uint32_t num_references
Definition: btrfs.h:297
uint32_t offset
Definition: btrfs.h:150
#define BLOCK_FLAG_SYSTEM
Definition: shellext.h:71
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#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
#define FORCEINLINE
Definition: ntbasedef.h:221
DEV_ITEM dev_item
Definition: btrfs.h:234
uint32_t size
Definition: btrfs.h:151
Definition: bufpool.h:45
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
uint16_t n
Definition: btrfs.h:353
tree_header header
Definition: btrfslib.c:134
BOOL QuickFormat
Definition: format.c:66
BTRFS_TIME st_mtime
Definition: btrfs.h:284
uint64_t offset
Definition: btrfs.h:390
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
NTSTATUS NTAPI BtrfsChkdskEx(IN PUNICODE_STRING DriveRoot, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PFMIFSCALLBACK Callback)
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
static uint64_t get_next_address(btrfs_chunk *c)
Definition: btrfslib.c:514
#define keycmp(key1, key2)
Definition: btrfslib.c:145
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:2883
uint64_t sb_phys_addr
Definition: btrfs.h:209
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
r l[0]
Definition: byte_order.h:167
#define BTRFS_ROOT_ROOT
Definition: btrfs.h:50
BTRFS_UUID device_uuid
Definition: btrfs.h:173
#define BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF
Definition: btrfs.h:105
uint64_t flags
Definition: btrfs.h:210
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
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:271
static void init_device(btrfs_dev *dev, uint64_t id, uint64_t size, BTRFS_UUID *fsuuid, uint32_t sector_size)
Definition: btrfslib.c:735
GLsizeiptr size
Definition: glext.h:5919
uint64_t objid
Definition: btrfs.h:291
#define TOKEN_QUERY
Definition: setypes.h:874
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR Name[1]
Definition: imports.h:144
FORCEINLINE VOID InitializeListHead(PLIST_ENTRY ListHead)
Definition: btrfslib.c:98
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void *lpReserved)
Definition: btrfslib.c:1536
#define IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
Definition: ntddstor.h:170
struct Command Command
uint64_t ULONGLONG
Definition: typedefs.h:65
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1138
uint64_t root_dir_objectid
Definition: btrfs.h:219
ULONG DataTransferLength
Definition: ntddscsi.h:136
static BOOL is_mounted_multi_device(HANDLE h, uint32_t sector_size)
Definition: btrfslib.c:1166
DWORD ClusterSize
Definition: format.c:67
#define WINAPI
Definition: msvc.h:8
void * unk1
Definition: btrfslib.c:75
const GLubyte * c
Definition: glext.h:8905
static void do_full_trim(HANDLE h)
Definition: btrfslib.c:1298
KEY firstitem
Definition: btrfs.h:375
static FILE * out
Definition: regtests2xml.c:44
#define for
Definition: utility.h:88
uint64_t objid
Definition: btrfs.h:447
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint address
Definition: glext.h:9393
#define success(from, fromstr, to, tostr)
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
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:542
#define __stdcall
Definition: typedefs.h:25
Definition: cookie.c:170
NTSTATUS WINAPI ChkdskEx(PUNICODE_STRING DriveRoot, BOOLEAN FixErrors, BOOLEAN Verbose, BOOLEAN CheckOnlyIfDirty, BOOLEAN ScanDrive, PFMIFSCALLBACK Callback)
Definition: btrfslib.c:263
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
BTRFS_UUID dev_uuid
Definition: btrfs.h:331
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
TREE_BLOCK_REF tbr
Definition: btrfslib.c:532
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
GLbitfield flags
Definition: glext.h:7161
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
uint64_t used
Definition: btrfslib.c:128
uint64_t generation
Definition: btrfs.h:212
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
FMIFS_MEDIA_FLAG
Definition: btrfslib.c:165
ULONG def_node_size
Definition: btrfslib.c:155
BTRFS_TIME st_atime
Definition: btrfs.h:282
#define IOCTL_BTRFS_PROBE_VOLUME
Definition: btrfsioctl.h:28
#define SharedUserData
EXTENT_ITEM ei
Definition: btrfslib.c:530
int ret
static double zero
Definition: j0_y0.c:96
GLenum const GLvoid * addr
Definition: glext.h:9621
tree_header header
Definition: btrfs_drv.h:421
__u8 attr
Definition: mkdosfs.c:359
static const WCHAR L[]
Definition: oid.c:1250
#define BTRFS_INCOMPAT_FLAGS_BIG_METADATA
Definition: btrfs.h:110
#define BLOCK_FLAG_METADATA
Definition: shellext.h:72
#define BTRFS_ROOT_FSTREE
Definition: btrfs.h:54
Definition: arc.h:85
void * data
Definition: btrfslib.c:120
Definition: btrfslib.c:204
HKEY key
Definition: reg.c:42
uint64_t id
Definition: btrfslib.c:133
#define TYPE_INODE_ITEM
Definition: btrfs.h:19
uint8_t level
Definition: btrfs.h:376
ULONG LowPart
Definition: typedefs.h:104
#define TYPE_BLOCK_GROUP_ITEM
Definition: btrfs.h:38
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
uint64_t cache_generation
Definition: btrfs.h:236
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:358
Definition: typedefs.h:117
uint32_t n
Definition: btrfs.h:225
static void init_fs_tree(btrfs_root *r, uint32_t node_size)
Definition: btrfslib.c:932
#define SYNCHRONIZE
Definition: nt_native.h:61
ULONG def_sector_size
Definition: btrfslib.c:155
uint64_t generation
Definition: btrfs.h:269
BYTE uint8_t
Definition: msvideo1.c:66
uint8_t label[11]
Definition: fsck.fat.h:65
LARGE_INTEGER Length
Definition: winioctl.h:423
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG InputBufferLength
Definition: fltkernel.h:1372
uint64_t st_blocks
Definition: btrfs.h:272
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfslib.c:906
uint64_t generation
Definition: btrfs.h:370
__u8 sector_size[2]
Definition: mkdosfs.c:361
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:376
struct _ATA_PASS_THROUGH_EX ATA_PASS_THROUGH_EX
Status
Definition: gdiplustypes.h:24
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
HANDLE HMODULE
Definition: typedefs.h:75
static void free_roots(LIST_ENTRY *roots)
Definition: btrfslib.c:301
Definition: btrfs.h:126
#define FSCTL_DISMOUNT_VOLUME
Definition: btrfslib.c:51
uint64_t offset
Definition: btrfslib.c:125
LIST_ENTRY list_entry
Definition: btrfslib.c:129
INODE_ITEM inode
Definition: btrfs.h:289
uint32_t flags
Definition: btrfslib.c:93
#define MAX_LABEL_SIZE
Definition: btrfs.h:16
UINT64 uint64_t
Definition: types.h:77
static ATOM item
Definition: dde.c:856
#define BTRFS_ROOT_CHECKSUM
Definition: btrfs.h:55
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define KEY
Definition: profile.c:30
#define EXTENT_ITEM_TREE_BLOCK
Definition: btrfs.h:365
unsigned short USHORT
Definition: pedump.c:61
uint64_t total_bytes
Definition: btrfs.h:217
KEY key
Definition: btrfs.h:149
uint64_t index
Definition: btrfs.h:352
UCHAR CurrentTaskFile[8]
Definition: ntddscsi.h:141
BTRFS_UUID uuid
Definition: btrfs.h:208
#define TYPE_ROOT_ITEM
Definition: btrfs.h:28
BOOLEAN(NTAPI * PFMIFSCALLBACK)(CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo)
Definition: btrfslib.c:212
uint32_t node_size
Definition: btrfs.h:222
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:402
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:419
static const uint32_t crctable[]
Definition: btrfslib.c:214
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:214
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
static NTSTATUS write_data(HANDLE h, uint64_t address, btrfs_chunk *c, void *data, ULONG size)
Definition: btrfslib.c:615
UINT32 uint32_t
Definition: types.h:75
uint16_t unk2
Definition: btrfslib.c:92
LIST_ENTRY items
Definition: btrfslib.c:136
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:70
Definition: fs.h:216
uint64_t def_incompat_flags
Definition: btrfslib.c:156
#define msg(x)
Definition: auth_time.c:54
#define BTRFS_ROOT_DEVTREE
Definition: btrfs.h:53
Definition: name.c:36
static const uint64_t superblock_addrs[]
Definition: btrfs.h:13
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
LIST_ENTRY list_entry
Definition: btrfslib.c:137
BOOL __stdcall GetFilesystemInformation(uint32_t unk1, uint32_t unk2, void *unk3)
Definition: btrfslib.c:1529
CHUNK_ITEM * chunk_item
Definition: btrfslib.c:126
#define FSCTL_LOCK_VOLUME
Definition: btrfslib.c:49
#define c
Definition: ke_i.h:80
static NTSTATUS clear_first_megabyte(HANDLE h)
Definition: btrfslib.c:991
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
#define TextOut
Definition: wingdi.h:4478
static void free_chunks(LIST_ENTRY *chunks)
Definition: btrfslib.c:338
PWCHAR Label
Definition: format.c:70
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#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:132
#define malloc
Definition: debug_ros.c:4
static BOOL superblock_collision(btrfs_chunk *c, uint64_t address)
Definition: btrfslib.c:493
#define BLOCK_FLAG_DUPLICATE
Definition: shellext.h:75
uint64_t flags
Definition: btrfs.h:371
#define BTRFS_ROOT_EXTENT
Definition: btrfs.h:51
uint32_t sector_size
Definition: btrfs.h:221
uint64_t chunktree
Definition: btrfs.h:446
BTRFS_UUID chunktree_uuid
Definition: btrfs.h:450
uint32_t leaf_size
Definition: btrfs.h:223
uint64_t chunk_root_generation
Definition: btrfs.h:226
static void get_uuid(BTRFS_UUID *uuid)
Definition: btrfslib.c:716
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define memset(x, y, z)
Definition: compat.h:39
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:876
LPFNPSPCALLBACK Callback
Definition: desk.c:111
void __stdcall SetSizes(ULONG sector, ULONG node)
Definition: btrfslib.c:1517
CALLBACKCOMMAND
Definition: btrfslib.c:192
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:190
#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:448
_In_ uint16_t _Out_ ULONG * atts
Definition: btrfs_drv.h:1065
LONGLONG QuadPart
Definition: typedefs.h:112
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
HMODULE hModule
Definition: animate.c:44
Definition: path.c:42
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:277
off
Definition: i386-dis.c:3909
uint64_t incompat_flags
Definition: btrfs.h:229