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