1 /* Copyright (c) Mark Harmstone 2016-17
3 * This file is part of WinBtrfs.
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.
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.
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/>. */
18 #ifndef BTRFS_DRV_H_DEFINED
19 #define BTRFS_DRV_H_DEFINED
25 #define _WIN32_WINNT 0x0601
26 #define NTDDI_VERSION 0x06020000 // Win 8
27 #define _CRT_SECURE_NO_WARNINGS
28 #define _NO_CRT_STDIO_INLINE
29 #endif /* __REACTOS__ */
33 #pragma warning(disable:4163)
34 #pragma warning(disable:4311)
35 #pragma warning(disable:4312)
37 #pragma GCC diagnostic push
38 #pragma GCC diagnostic ignored "-Wsign-compare"
39 #pragma GCC diagnostic ignored "-Wsign-conversion"
46 #endif /* __REACTOS__ */
51 #include <pseh/pseh2.h>
52 #endif /* __REACTOS__ */
59 #pragma GCC diagnostic pop
67 #include <emmintrin.h>
68 #endif /* __REACTOS__ */
70 #include "btrfsioctl.h"
73 // #define DEBUG_FCB_REFCOUNTS
74 // #define DEBUG_LONG_MESSAGES
75 // #define DEBUG_FLUSH_TIMES
76 // #define DEBUG_STATS
77 #define DEBUG_PARANOID
80 #define UNUSED(x) (void)(x)
82 #define BTRFS_NODE_TYPE_CCB 0x2295
83 #define BTRFS_NODE_TYPE_FCB 0x2296
85 #define ALLOC_TAG 0x7442484D //'MHBt'
86 #define ALLOC_TAG_ZLIB 0x7A42484D //'MHBz'
88 #define UID_NOBODY 65534
89 #define GID_NOBODY 65534
91 #define EA_NTACL "security.NTACL"
92 #define EA_NTACL_HASH 0x45922146
94 #define EA_DOSATTRIB "user.DOSATTRIB"
95 #define EA_DOSATTRIB_HASH 0x914f9939
97 #define EA_REPARSE "user.reparse"
98 #define EA_REPARSE_HASH 0xfabad1fe
100 #define EA_EA "user.EA"
101 #define EA_EA_HASH 0x8270dd43
103 #define EA_PROP_COMPRESSION "btrfs.compression"
104 #define EA_PROP_COMPRESSION_HASH 0x20ccdf69
106 #define MAX_EXTENT_SIZE 0x8000000 // 128 MB
107 #define COMPRESSED_EXTENT_SIZE 0x20000 // 128 KB
109 #define READ_AHEAD_GRANULARITY COMPRESSED_EXTENT_SIZE // really ought to be a multiple of COMPRESSED_EXTENT_SIZE
111 #define IO_REPARSE_TAG_LXSS_SYMLINK 0xa000001d // undocumented?
113 #define BTRFS_VOLUME_PREFIX L"\\Device\\Btrfs{"
117 #define except __except
118 #define finally __finally
121 #define except(x) if (0 && (x))
122 #define finally if (1)
125 #ifndef FILE_SUPPORTS_BLOCK_REFCOUNTING
126 #define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000
129 #ifndef FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL
130 #define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000
133 typedef struct _DUPLICATE_EXTENTS_DATA
{
135 LARGE_INTEGER SourceFileOffset
;
136 LARGE_INTEGER TargetFileOffset
;
137 LARGE_INTEGER ByteCount
;
138 } DUPLICATE_EXTENTS_DATA
, *PDUPLICATE_EXTENTS_DATA
;
140 #define FSCTL_DUPLICATE_EXTENTS_TO_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 209, METHOD_BUFFERED, FILE_WRITE_ACCESS)
142 typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER
{
143 WORD ChecksumAlgorithm
;
146 DWORD ChecksumChunkSizeInBytes
;
147 DWORD ClusterSizeInBytes
;
148 } FSCTL_GET_INTEGRITY_INFORMATION_BUFFER
, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER
;
150 typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER
{
151 WORD ChecksumAlgorithm
;
154 } FSCTL_SET_INTEGRITY_INFORMATION_BUFFER
, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER
;
156 #define FSCTL_GET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS)
157 #define FSCTL_SET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
161 #define __drv_aliasesMem
162 #define _Requires_lock_held_(a)
163 #define _Requires_exclusive_lock_held_(a)
164 #define _Releases_lock_(a)
165 #define _Out_writes_bytes_opt_(a)
166 #define _Pre_satisfies_(a)
167 #define _Post_satisfies_(a)
168 #define _Releases_exclusive_lock_(a)
169 #define _Dispatch_type_(a)
170 #define _Create_lock_level_(a)
171 #define _Lock_level_order_(a,b)
172 #define _Has_lock_level_(a)
173 #define _Requires_lock_not_held_(a)
174 #define _Acquires_exclusive_lock_(a)
175 #define _Acquires_shared_lock_(a)
179 _Create_lock_level_(tree_lock
)
180 _Create_lock_level_(fcb_lock
)
181 _Lock_level_order_(tree_lock
, fcb_lock
)
183 struct _device_extension
;
185 typedef struct _fcb_nonpaged
{
186 FAST_MUTEX HeaderMutex
;
187 SECTION_OBJECT_POINTERS segment_object
;
189 ERESOURCE paging_resource
;
190 ERESOURCE dir_children_lock
;
203 LIST_ENTRY list_entry
;
205 EXTENT_DATA extent_data
;
213 LIST_ENTRY list_entry
;
226 UNICODE_STRING name_uc
;
228 struct _file_ref
* fileref
;
229 LIST_ENTRY list_entry_index
;
230 LIST_ENTRY list_entry_hash
;
231 LIST_ENTRY list_entry_hash_uc
;
234 enum prop_compression_type
{
235 PropCompression_None
,
236 PropCompression_Zlib
,
241 LIST_ENTRY list_entry
;
248 typedef struct _fcb
{
249 FSRTL_ADVANCED_FCB_HEADER Header
;
250 struct _fcb_nonpaged
* nonpaged
;
253 struct _device_extension
* Vcb
;
254 struct _root
* subvol
;
257 INODE_ITEM inode_item
;
258 SECURITY_DESCRIPTOR
* sd
;
261 PKTHREAD lazy_writer_thread
;
263 SHARE_ACCESS share_access
;
267 ANSI_STRING reparse_xattr
;
268 ANSI_STRING ea_xattr
;
270 LIST_ENTRY hardlinks
;
271 struct _file_ref
* fileref
;
272 BOOL inode_item_changed
;
273 enum prop_compression_type prop_compression
;
276 LIST_ENTRY dir_children_index
;
277 LIST_ENTRY dir_children_hash
;
278 LIST_ENTRY dir_children_hash_uc
;
279 LIST_ENTRY
** hash_ptrs
;
280 LIST_ENTRY
** hash_ptrs_uc
;
283 BOOL sd_dirty
, sd_deleted
;
284 BOOL atts_changed
, atts_deleted
;
285 BOOL extents_changed
;
286 BOOL reparse_xattr_changed
;
288 BOOL prop_compression_changed
;
295 ANSI_STRING adsxattr
;
298 LIST_ENTRY list_entry
;
299 LIST_ENTRY list_entry_all
;
300 LIST_ENTRY list_entry_dirty
;
304 ERESOURCE fileref_lock
;
305 ERESOURCE children_lock
;
308 typedef struct _file_ref
{
312 BOOL delete_on_close
;
315 file_ref_nonpaged
* nonpaged
;
319 struct _file_ref
* parent
;
325 LIST_ENTRY list_entry
;
326 LIST_ENTRY list_entry_dirty
;
333 KEVENT cleared_event
;
335 LIST_ENTRY list_entry
;
338 typedef struct _ccb
{
343 UINT64 query_dir_offset
;
344 UNICODE_STRING query_string
;
347 BOOL manage_volume_privilege
;
348 BOOL allow_extended_dasd_io
;
352 UNICODE_STRING filename
;
355 BOOL user_set_creation_time
;
356 BOOL user_set_access_time
;
357 BOOL user_set_write_time
;
358 BOOL user_set_change_time
;
361 NTSTATUS send_status
;
364 struct _device_extension
;
372 typedef struct _tree_data
{
374 LIST_ENTRY list_entry
;
379 tree_holder treeholder
;
388 typedef struct _tree
{
393 struct _device_extension
* Vcb
;
394 struct _tree
* parent
;
398 LIST_ENTRY list_entry
;
399 LIST_ENTRY list_entry_hash
;
401 BOOL has_new_address
;
402 BOOL updated_extents
;
405 BOOL uniqueness_determined
;
410 ERESOURCE load_tree_lock
;
413 typedef struct _root
{
415 LONGLONG lastinode
; // signed so we can use InterlockedIncrement64
416 tree_holder treeholder
;
417 root_nonpaged
* nonpaged
;
425 LIST_ENTRY list_entry
;
426 LIST_ENTRY list_entry_dirty
;
429 enum batch_operation
{
438 Batch_DeleteInodeRef
,
439 Batch_DeleteInodeExtRef
,
441 Batch_DeleteExtentData
,
442 Batch_DeleteFreeSpace
,
449 enum batch_operation operation
;
450 LIST_ENTRY list_entry
;
456 LIST_ENTRY list_entry
;
464 typedef struct _root_cache
{
466 struct _root_cache
* next
;
472 LIST_ENTRY list_entry
;
473 LIST_ENTRY list_entry_size
;
477 PDEVICE_OBJECT devobj
;
491 LIST_ENTRY list_entry
;
492 ULONG num_trim_entries
;
493 LIST_ENTRY trim_list
;
500 LIST_ENTRY list_entry
;
507 LIST_ENTRY list_entry
;
512 CHUNK_ITEM
* chunk_item
;
521 LIST_ENTRY space_size
;
523 LIST_ENTRY changed_extents
;
524 LIST_ENTRY range_locks
;
525 ERESOURCE range_locks_lock
;
526 KEVENT range_locks_event
;
528 ERESOURCE changed_extents_lock
;
538 LIST_ENTRY partial_stripes
;
539 ERESOURCE partial_stripes_lock
;
542 LIST_ENTRY list_entry
;
543 LIST_ENTRY list_entry_balance
;
556 LIST_ENTRY list_entry
;
567 LIST_ENTRY list_entry
;
568 } changed_extent_ref
;
574 LIST_ENTRY list_entry
;
584 LIST_ENTRY list_entry
;
588 PDEVICE_OBJECT DeviceObject
;
598 drv_calc_thread
* threads
;
609 UINT32 flush_interval
;
619 #define VCB_TYPE_FS 1
620 #define VCB_TYPE_CONTROL 2
621 #define VCB_TYPE_VOLUME 3
622 #define VCB_TYPE_PDO 4
628 UINT64 read_total_time
;
629 UINT64 read_csum_time
;
630 UINT64 read_disk_time
;
633 UINT64 open_total_time
;
634 UINT64 num_overwrites
;
635 UINT64 overwrite_total_time
;
637 UINT64 create_total_time
;
638 UINT64 open_fcb_calls
;
639 UINT64 open_fcb_time
;
640 UINT64 open_fileref_child_calls
;
641 UINT64 open_fileref_child_time
;
642 UINT64 fcb_lock_time
;
646 #define BALANCE_OPTS_DATA 0
647 #define BALANCE_OPTS_METADATA 1
648 #define BALANCE_OPTS_SYSTEM 2
654 btrfs_balance_opts opts
[3];
672 LIST_ENTRY list_entry
;
678 UINT16 filename_length
;
692 ERESOURCE stats_lock
;
697 LARGE_INTEGER start_time
;
698 LARGE_INTEGER finish_time
;
699 LARGE_INTEGER resume_time
;
700 LARGE_INTEGER duration
;
703 UINT64 data_scrubbed
;
709 struct _volume_device_extension
;
711 typedef struct _device_extension
{
713 mount_options options
;
715 struct _volume_device_extension
* vde
;
720 UINT64 devices_loaded
;
721 superblock superblock
;
725 BOOL lock_paused_balance
;
726 BOOL disallow_dismount
;
728 PFILE_OBJECT locked_fileobj
;
731 file_ref
* root_fileref
;
733 _Has_lock_level_(fcb_lock
) ERESOURCE fcb_lock
;
735 _Has_lock_level_(tree_lock
) ERESOURCE tree_lock
;
736 PNOTIFY_SYNC NotifySync
;
737 LIST_ENTRY DirNotifyList
;
741 UINT64 metadata_flags
;
744 LIST_ENTRY drop_roots
;
751 root
* data_reloc_root
;
753 BOOL log_to_phys_loaded
;
754 BOOL chunk_usage_found
;
755 LIST_ENTRY sys_chunks
;
758 LIST_ENTRY trees_hash
;
759 LIST_ENTRY
* trees_ptrs
[256];
761 LIST_ENTRY dirty_fcbs
;
762 ERESOURCE dirty_fcbs_lock
;
763 LIST_ENTRY dirty_filerefs
;
764 ERESOURCE dirty_filerefs_lock
;
765 LIST_ENTRY dirty_subvols
;
766 ERESOURCE dirty_subvols_lock
;
767 ERESOURCE chunk_lock
;
768 HANDLE flush_thread_handle
;
769 KTIMER flush_thread_timer
;
770 KEVENT flush_thread_finished
;
771 drv_calc_threads calcthreads
;
772 balance_info balance
;
774 ERESOURCE send_load_lock
;
777 PFILE_OBJECT root_file
;
778 PAGED_LOOKASIDE_LIST tree_data_lookaside
;
779 PAGED_LOOKASIDE_LIST traverse_ptr_lookaside
;
780 PAGED_LOOKASIDE_LIST batch_item_lookaside
;
781 PAGED_LOOKASIDE_LIST fileref_lookaside
;
782 PAGED_LOOKASIDE_LIST fcb_lookaside
;
783 PAGED_LOOKASIDE_LIST name_bit_lookaside
;
784 NPAGED_LOOKASIDE_LIST range_lock_lookaside
;
785 NPAGED_LOOKASIDE_LIST fileref_np_lookaside
;
786 NPAGED_LOOKASIDE_LIST fcb_np_lookaside
;
787 LIST_ENTRY list_entry
;
792 PDEVICE_OBJECT buspdo
;
793 PDEVICE_OBJECT attached_device
;
794 UNICODE_STRING bus_name
;
795 } control_device_extension
;
801 PDEVICE_OBJECT devobj
;
802 PFILE_OBJECT fileobj
;
803 UNICODE_STRING pnp_name
;
806 BOOL had_drive_letter
;
807 void* notification_entry
;
810 LIST_ENTRY list_entry
;
813 struct pdo_device_extension
;
815 typedef struct _volume_device_extension
{
818 PDEVICE_OBJECT device
;
819 PDEVICE_OBJECT mounted_device
;
821 struct pdo_device_extension
* pdode
;
822 UNICODE_STRING bus_name
;
823 PDEVICE_OBJECT attached_device
;
826 } volume_device_extension
;
828 typedef struct pdo_device_extension
{
831 volume_device_extension
* vde
;
836 UINT64 children_loaded
;
837 ERESOURCE child_lock
;
840 LIST_ENTRY list_entry
;
841 } pdo_device_extension
;
844 LIST_ENTRY listentry
;
850 LIST_ENTRY listentry
;
855 enum write_data_status
{
856 WriteDataStatus_Pending
,
857 WriteDataStatus_Success
,
858 WriteDataStatus_Error
,
859 WriteDataStatus_Cancelling
,
860 WriteDataStatus_Cancelled
,
861 WriteDataStatus_Ignore
864 struct _write_data_context
;
867 struct _write_data_context
* context
;
872 IO_STATUS_BLOCK iosb
;
873 enum write_data_status status
;
874 LIST_ENTRY list_entry
;
877 typedef struct _write_data_context
{
882 UINT8
*parity1
, *parity2
, *scratch
;
883 PMDL mdl
, parity1_mdl
, parity2_mdl
;
884 } write_data_context
;
891 LIST_ENTRY list_entry
;
896 LIST_ENTRY list_entry
;
899 _Requires_lock_not_held_(Vcb
->fcb_lock
)
900 _Acquires_shared_lock_(Vcb
->fcb_lock
)
901 static __inline
void acquire_fcb_lock_shared(device_extension
* Vcb
) {
903 LARGE_INTEGER time1
, time2
;
905 if (ExAcquireResourceSharedLite(&Vcb
->fcb_lock
, FALSE
))
908 time1
= KeQueryPerformanceCounter(NULL
);
911 ExAcquireResourceSharedLite(&Vcb
->fcb_lock
, TRUE
);
914 time2
= KeQueryPerformanceCounter(NULL
);
915 Vcb
->stats
.fcb_lock_time
+= time2
.QuadPart
- time1
.QuadPart
;
919 _Requires_lock_not_held_(Vcb
->fcb_lock
)
920 _Acquires_exclusive_lock_(Vcb
->fcb_lock
)
921 static __inline
void acquire_fcb_lock_exclusive(device_extension
* Vcb
) {
923 LARGE_INTEGER time1
, time2
;
925 if (ExAcquireResourceExclusiveLite(&Vcb
->fcb_lock
, FALSE
))
928 time1
= KeQueryPerformanceCounter(NULL
);
931 ExAcquireResourceExclusiveLite(&Vcb
->fcb_lock
, TRUE
);
934 time2
= KeQueryPerformanceCounter(NULL
);
935 Vcb
->stats
.fcb_lock_time
+= time2
.QuadPart
- time1
.QuadPart
;
939 _Requires_lock_held_(Vcb
->fcb_lock
)
940 _Releases_lock_(Vcb
->fcb_lock
)
941 static __inline
void release_fcb_lock(device_extension
* Vcb
) {
942 ExReleaseResourceLite(&Vcb
->fcb_lock
);
945 static __inline
void* map_user_buffer(PIRP Irp
, ULONG priority
) {
946 if (!Irp
->MdlAddress
) {
947 return Irp
->UserBuffer
;
949 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, priority
);
953 static __inline UINT64
unix_time_to_win(BTRFS_TIME
* t
) {
954 return (t
->seconds
* 10000000) + (t
->nanoseconds
/ 100) + 116444736000000000;
957 static __inline
void win_time_to_unix(LARGE_INTEGER t
, BTRFS_TIME
* out
) {
958 ULONGLONG l
= t
.QuadPart
- 116444736000000000;
960 out
->seconds
= l
/ 10000000;
961 out
->nanoseconds
= (l
% 10000000) * 100;
964 _Post_satisfies_(*stripe
>=0&&*stripe
<num_stripes
)
965 static __inline
void get_raid0_offset(_In_ UINT64 off
, _In_ UINT64 stripe_length
, _In_ UINT16 num_stripes
, _Out_ UINT64
* stripeoff
, _Out_ UINT16
* stripe
) {
966 UINT64 initoff
, startoff
;
968 startoff
= off
% (num_stripes
* stripe_length
);
969 initoff
= (off
/ (num_stripes
* stripe_length
)) * stripe_length
;
971 *stripe
= (UINT16
)(startoff
/ stripe_length
);
972 *stripeoff
= initoff
+ startoff
- (*stripe
* stripe_length
);
975 /* We only have 64 bits for a file ID, which isn't technically enough to be
976 * unique on Btrfs. We fudge it by having three bytes for the subvol and
977 * five for the inode, which should be good enough.
978 * Inodes are also 64 bits on Linux, but the Linux driver seems to get round
979 * this by tricking it into thinking subvols are separate volumes. */
980 static __inline UINT64
make_file_id(root
* r
, UINT64 inode
) {
981 return (r
->id
<< 40) | (inode
& 0xffffffffff);
984 #define keycmp(key1, key2)\
985 ((key1.obj_id < key2.obj_id) ? -1 :\
986 ((key1.obj_id > key2.obj_id) ? 1 :\
987 ((key1.obj_type < key2.obj_type) ? -1 :\
988 ((key1.obj_type > key2.obj_type) ? 1 :\
989 ((key1.offset < key2.offset) ? -1 :\
990 ((key1.offset > key2.offset) ? 1 :\
993 _Post_satisfies_(return>=n
)
994 __inline
static UINT64
sector_align(_In_ UINT64 n
, _In_ UINT64 a
) {
996 n
= (n
+ a
) & ~(a
- 1);
1001 __inline
static BOOL
is_subvol_readonly(root
* r
, PIRP Irp
) {
1002 if (!(r
->root_item
.flags
& BTRFS_SUBVOL_READONLY
))
1008 return (!Irp
|| Irp
->RequestorMode
== UserMode
) && PsGetCurrentProcess() != r
->reserved
? TRUE
: FALSE
;
1011 __inline
static UINT16
get_extent_data_len(UINT8 type
) {
1013 case TYPE_TREE_BLOCK_REF
:
1014 return sizeof(TREE_BLOCK_REF
);
1016 case TYPE_EXTENT_DATA_REF
:
1017 return sizeof(EXTENT_DATA_REF
);
1019 case TYPE_EXTENT_REF_V0
:
1020 return sizeof(EXTENT_REF_V0
);
1022 case TYPE_SHARED_BLOCK_REF
:
1023 return sizeof(SHARED_BLOCK_REF
);
1025 case TYPE_SHARED_DATA_REF
:
1026 return sizeof(SHARED_DATA_REF
);
1033 __inline
static UINT32
get_extent_data_refcount(UINT8 type
, void* data
) {
1035 case TYPE_TREE_BLOCK_REF
:
1038 case TYPE_EXTENT_DATA_REF
:
1040 EXTENT_DATA_REF
* edr
= (EXTENT_DATA_REF
*)data
;
1044 case TYPE_EXTENT_REF_V0
:
1046 EXTENT_REF_V0
* erv0
= (EXTENT_REF_V0
*)data
;
1050 case TYPE_SHARED_BLOCK_REF
:
1053 case TYPE_SHARED_DATA_REF
:
1055 SHARED_DATA_REF
* sdr
= (SHARED_DATA_REF
*)data
;
1066 device
* find_device_from_uuid(_In_ device_extension
* Vcb
, _In_ BTRFS_UUID
* uuid
);
1069 BOOL
get_file_attributes_from_xattr(_In_reads_bytes_(len
) char* val
, _In_ UINT16 len
, _Out_ ULONG
* atts
);
1071 ULONG
get_file_attributes(_In_
_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ root
* r
, _In_ UINT64 inode
,
1072 _In_ UINT8 type
, _In_ BOOL dotfile
, _In_ BOOL ignore_xa
, _In_opt_ PIRP Irp
);
1075 BOOL
get_xattr(_In_
_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ root
* subvol
, _In_ UINT64 inode
, _In_z_
char* name
, _In_ UINT32 crc32
,
1076 _Out_ UINT8
** data
, _Out_ UINT16
* datalen
, _In_opt_ PIRP Irp
);
1078 #ifndef DEBUG_FCB_REFCOUNTS
1079 void free_fcb(_Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) _In_ device_extension
* Vcb
, _Inout_ fcb
* fcb
);
1081 void free_fileref(_Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) _In_ device_extension
* Vcb
, _Inout_ file_ref
* fr
);
1082 void protect_superblocks(_Inout_ chunk
* c
);
1083 BOOL
is_top_level(_In_ PIRP Irp
);
1084 NTSTATUS
create_root(_In_
_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ UINT64 id
,
1085 _Out_ root
** rootptr
, _In_ BOOL no_tree
, _In_ UINT64 offset
, _In_opt_ PIRP Irp
);
1086 void uninit(_In_ device_extension
* Vcb
, _In_ BOOL flush
);
1087 NTSTATUS
dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject
, _In_ ULONG ControlCode
, _In_reads_bytes_opt_(InputBufferSize
) PVOID InputBuffer
, _In_ ULONG InputBufferSize
,
1088 _Out_writes_bytes_opt_(OutputBufferSize
) PVOID OutputBuffer
, _In_ ULONG OutputBufferSize
, _In_ BOOLEAN Override
, _Out_opt_ IO_STATUS_BLOCK
* iosb
);
1089 BOOL
is_file_name_valid(_In_ PUNICODE_STRING us
, _In_ BOOL posix
);
1090 void send_notification_fileref(_In_ file_ref
* fileref
, _In_ ULONG filter_match
, _In_ ULONG action
, _In_opt_ PUNICODE_STRING stream
);
1091 void send_notification_fcb(_In_ file_ref
* fileref
, _In_ ULONG filter_match
, _In_ ULONG action
, _In_opt_ PUNICODE_STRING stream
);
1094 WCHAR
* file_desc(_In_ PFILE_OBJECT FileObject
);
1095 WCHAR
* file_desc_fileref(_In_ file_ref
* fileref
);
1096 void mark_fcb_dirty(_In_ fcb
* fcb
);
1097 void mark_fileref_dirty(_In_ file_ref
* fileref
);
1098 NTSTATUS
delete_fileref(_In_ file_ref
* fileref
, _In_opt_ PFILE_OBJECT FileObject
, _In_opt_ PIRP Irp
, _In_ LIST_ENTRY
* rollback
);
1099 void chunk_lock_range(_In_ device_extension
* Vcb
, _In_ chunk
* c
, _In_ UINT64 start
, _In_ UINT64 length
);
1100 void chunk_unlock_range(_In_ device_extension
* Vcb
, _In_ chunk
* c
, _In_ UINT64 start
, _In_ UINT64 length
);
1101 void init_device(_In_ device_extension
* Vcb
, _Inout_ device
* dev
, _In_ BOOL get_nums
);
1102 void init_file_cache(_In_ PFILE_OBJECT FileObject
, _In_ CC_FILE_SIZES
* ccfs
);
1103 NTSTATUS
sync_read_phys(_In_ PDEVICE_OBJECT DeviceObject
, _In_ UINT64 StartingOffset
, _In_ ULONG Length
,
1104 _Out_writes_bytes_(Length
) PUCHAR Buffer
, _In_ BOOL override
);
1105 NTSTATUS
get_device_pnp_name(_In_ PDEVICE_OBJECT DeviceObject
, _Out_ PUNICODE_STRING pnp_name
, _Out_
const GUID
** guid
);
1106 void log_device_error(_In_ device_extension
* Vcb
, _Inout_ device
* dev
, _In_
int error
);
1107 NTSTATUS
find_chunk_usage(_In_
_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_opt_ PIRP Irp
);
1109 NTSTATUS NTAPI
AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT PhysicalDeviceObject
);
1111 NTSTATUS
AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT PhysicalDeviceObject
);
1115 #define funcname __FUNCTION__
1117 #define funcname __func__
1120 extern BOOL have_sse2
;
1122 extern UINT32 mount_compress
;
1123 extern UINT32 mount_compress_force
;
1124 extern UINT32 mount_compress_type
;
1125 extern UINT32 mount_zlib_level
;
1126 extern UINT32 mount_flush_interval
;
1127 extern UINT32 mount_max_inline
;
1128 extern UINT32 mount_skip_balance
;
1129 extern UINT32 mount_no_barrier
;
1130 extern UINT32 mount_no_trim
;
1131 extern UINT32 mount_clear_cache
;
1132 extern UINT32 mount_allow_degraded
;
1133 extern UINT32 mount_readonly
;
1134 extern UINT32 no_pnp
;
1138 extern BOOL log_started
;
1139 extern UINT32 debug_log_level
;
1141 #ifdef DEBUG_LONG_MESSAGES
1143 #define MSG(fn, file, line, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, file, line, s, ##__VA_ARGS__) : 0
1145 #define TRACE(s, ...) MSG(funcname, __FILE__, __LINE__, s, 3, ##__VA_ARGS__)
1146 #define WARN(s, ...) MSG(funcname, __FILE__, __LINE__, s, 2, ##__VA_ARGS__)
1147 #define FIXME(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__)
1148 #define ERR(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__)
1150 void _debug_message(_In_
const char* func
, _In_
const char* file
, _In_
unsigned int line
, _In_
char* s
, ...);
1154 #define MSG(fn, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, s, ##__VA_ARGS__) : 0
1156 #define TRACE(s, ...) MSG(funcname, s, 3, ##__VA_ARGS__)
1157 #define WARN(s, ...) MSG(funcname, s, 2, ##__VA_ARGS__)
1158 #define FIXME(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__)
1159 #define ERR(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__)
1161 void _debug_message(_In_
const char* func
, _In_
char* s
, ...);
1167 #define TRACE(s, ...)
1168 #define WARN(s, ...)
1169 #define FIXME(s, ...) DbgPrint("Btrfs FIXME : %s : " s, funcname, ##__VA_ARGS__)
1170 #define ERR(s, ...) DbgPrint("Btrfs ERR : %s : " s, funcname, ##__VA_ARGS__)
1174 #ifdef DEBUG_FCB_REFCOUNTS
1175 void _free_fcb(_Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) _In_ device_extension
* Vcb
, _Inout_ fcb
* fcb
, _In_
const char* func
);
1176 #define free_fcb(Vcb, fcb) _free_fcb(Vcb, fcb, funcname)
1180 void init_fast_io_dispatch(FAST_IO_DISPATCH
** fiod
);
1183 UINT32
calc_crc32c(_In_ UINT32 seed
, _In_reads_bytes_(msglen
) UINT8
* msg
, _In_ ULONG msglen
);
1187 LIST_ENTRY
* list_size
;
1198 enum rollback_type
{
1199 ROLLBACK_INSERT_EXTENT
,
1200 ROLLBACK_DELETE_EXTENT
,
1202 ROLLBACK_SUBTRACT_SPACE
1206 enum rollback_type type
;
1208 LIST_ENTRY list_entry
;
1212 NTSTATUS
find_item(_In_
_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ root
* r
, _Out_ traverse_ptr
* tp
,
1213 _In_
const KEY
* searchkey
, _In_ BOOL ignore
, _In_opt_ PIRP Irp
);
1214 NTSTATUS
find_item_to_level(device_extension
* Vcb
, root
* r
, traverse_ptr
* tp
, const KEY
* searchkey
, BOOL ignore
, UINT8 level
, PIRP Irp
);
1215 BOOL
find_next_item(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, const traverse_ptr
* tp
, traverse_ptr
* next_tp
, BOOL ignore
, PIRP Irp
);
1216 BOOL
find_prev_item(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, const traverse_ptr
* tp
, traverse_ptr
* prev_tp
, PIRP Irp
);
1217 void free_trees(device_extension
* Vcb
);
1218 NTSTATUS
insert_tree_item(_In_
_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ root
* r
, _In_ UINT64 obj_id
,
1219 _In_ UINT8 obj_type
, _In_ UINT64 offset
, _In_reads_bytes_opt_(size
) _When_(return >= 0, __drv_aliasesMem
) void* data
,
1220 _In_ UINT16 size
, _Out_opt_ traverse_ptr
* ptp
, _In_opt_ PIRP Irp
);
1221 NTSTATUS
delete_tree_item(_In_
_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _Inout_ traverse_ptr
* tp
);
1222 tree
* free_tree(tree
* t
);
1223 NTSTATUS
load_tree(device_extension
* Vcb
, UINT64 addr
, root
* r
, tree
** pt
, UINT64 generation
, PIRP Irp
);
1224 NTSTATUS
do_load_tree(device_extension
* Vcb
, tree_holder
* th
, root
* r
, tree
* t
, tree_data
* td
, BOOL
* loaded
, PIRP Irp
);
1225 void clear_rollback(LIST_ENTRY
* rollback
);
1226 void do_rollback(device_extension
* Vcb
, LIST_ENTRY
* rollback
);
1227 void free_trees_root(device_extension
* Vcb
, root
* r
);
1228 void add_rollback(_In_ LIST_ENTRY
* rollback
, _In_
enum rollback_type type
, _In_ __drv_aliasesMem
void* ptr
);
1229 NTSTATUS
commit_batch_list(_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, LIST_ENTRY
* batchlist
, PIRP Irp
);
1230 void clear_batch_list(device_extension
* Vcb
, LIST_ENTRY
* batchlist
);
1231 NTSTATUS
skip_to_difference(device_extension
* Vcb
, traverse_ptr
* tp
, traverse_ptr
* tp2
, BOOL
* ended1
, BOOL
* ended2
);
1234 NTSTATUS
remove_drive_letter(PDEVICE_OBJECT mountmgr
, PUNICODE_STRING devpath
);
1236 _Function_class_(KSTART_ROUTINE
)
1238 void NTAPI
mountmgr_thread(_In_
void* context
);
1240 void mountmgr_thread(_In_
void* context
);
1243 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE
)
1245 NTSTATUS NTAPI
pnp_notification(PVOID NotificationStructure
, PVOID Context
);
1247 NTSTATUS
pnp_notification(PVOID NotificationStructure
, PVOID Context
);
1250 void disk_arrival(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING devpath
);
1251 void volume_arrival(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING devpath
);
1252 void volume_removal(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING devpath
);
1254 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE
)
1256 NTSTATUS NTAPI
volume_notification(PVOID NotificationStructure
, PVOID Context
);
1258 NTSTATUS
volume_notification(PVOID NotificationStructure
, PVOID Context
);
1261 void remove_volume_child(_Inout_
_Requires_exclusive_lock_held_(_Curr_
->child_lock
) _Releases_exclusive_lock_(_Curr_
->child_lock
) _In_ volume_device_extension
* vde
,
1262 _In_ volume_child
* vc
, _In_ BOOL skip_dev
);
1265 NTSTATUS
init_cache();
1267 extern CACHE_MANAGER_CALLBACKS
* cache_callbacks
;
1270 NTSTATUS
write_file(device_extension
* Vcb
, PIRP Irp
, BOOLEAN wait
, BOOLEAN deferred_write
);
1271 NTSTATUS
write_file2(device_extension
* Vcb
, PIRP Irp
, LARGE_INTEGER offset
, void* buf
, ULONG
* length
, BOOLEAN paging_io
, BOOLEAN no_cache
,
1272 BOOLEAN wait
, BOOLEAN deferred_write
, BOOLEAN write_irp
, LIST_ENTRY
* rollback
);
1273 NTSTATUS
truncate_file(fcb
* fcb
, UINT64 end
, PIRP Irp
, LIST_ENTRY
* rollback
);
1274 NTSTATUS
extend_file(fcb
* fcb
, file_ref
* fileref
, UINT64 end
, BOOL prealloc
, PIRP Irp
, LIST_ENTRY
* rollback
);
1275 NTSTATUS
excise_extents(device_extension
* Vcb
, fcb
* fcb
, UINT64 start_data
, UINT64 end_data
, PIRP Irp
, LIST_ENTRY
* rollback
);
1276 chunk
* get_chunk_from_address(device_extension
* Vcb
, UINT64 address
);
1277 NTSTATUS
alloc_chunk(device_extension
* Vcb
, UINT64 flags
, chunk
** pc
, BOOL full_size
);
1278 NTSTATUS
write_data(_In_ device_extension
* Vcb
, _In_ UINT64 address
, _In_reads_bytes_(length
) void* data
, _In_ UINT32 length
, _In_ write_data_context
* wtc
,
1279 _In_opt_ PIRP Irp
, _In_opt_ chunk
* c
, _In_ BOOL file_write
, _In_ UINT64 irp_offset
, _In_ ULONG priority
);
1280 NTSTATUS
write_data_complete(device_extension
* Vcb
, UINT64 address
, void* data
, UINT32 length
, PIRP Irp
, chunk
* c
, BOOL file_write
, UINT64 irp_offset
, ULONG priority
);
1281 void free_write_data_stripes(write_data_context
* wtc
);
1283 _Dispatch_type_(IRP_MJ_WRITE
)
1284 _Function_class_(DRIVER_DISPATCH
)
1285 NTSTATUS
drv_write(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1287 _Requires_lock_held_(c
->lock
)
1288 _When_(return != 0, _Releases_lock_(c
->lock
))
1289 BOOL
insert_extent_chunk(_In_ device_extension
* Vcb
, _In_ fcb
* fcb
, _In_ chunk
* c
, _In_ UINT64 start_data
, _In_ UINT64 length
, _In_ BOOL prealloc
, _In_opt_
void* data
,
1290 _In_opt_ PIRP Irp
, _In_ LIST_ENTRY
* rollback
, _In_ UINT8 compression
, _In_ UINT64 decoded_size
, _In_ BOOL file_write
, _In_ UINT64 irp_offset
);
1292 NTSTATUS
do_write_file(fcb
* fcb
, UINT64 start_data
, UINT64 end_data
, void* data
, PIRP Irp
, BOOL file_write
, UINT32 irp_offset
, LIST_ENTRY
* rollback
);
1293 NTSTATUS
write_compressed(fcb
* fcb
, UINT64 start_data
, UINT64 end_data
, void* data
, PIRP Irp
, LIST_ENTRY
* rollback
);
1294 BOOL
find_data_address_in_chunk(device_extension
* Vcb
, chunk
* c
, UINT64 length
, UINT64
* address
);
1295 void get_raid56_lock_range(chunk
* c
, UINT64 address
, UINT64 length
, UINT64
* lockaddr
, UINT64
* locklen
);
1296 NTSTATUS
calc_csum(_In_ device_extension
* Vcb
, _In_reads_bytes_(sectors
*Vcb
->superblock
.sector_size
) UINT8
* data
,
1297 _In_ UINT32 sectors
, _Out_writes_bytes_(sectors
*sizeof(UINT32
)) UINT32
* csum
);
1298 void add_insert_extent_rollback(LIST_ENTRY
* rollback
, fcb
* fcb
, extent
* ext
);
1299 NTSTATUS
add_extent_to_fcb(_In_ fcb
* fcb
, _In_ UINT64 offset
, _In_reads_bytes_(edsize
) EXTENT_DATA
* ed
, _In_ UINT16 edsize
,
1300 _In_ BOOL unique
, _In_opt_
_When_(return >= 0, __drv_aliasesMem
) UINT32
* csum
, _In_ LIST_ENTRY
* rollback
);
1301 void add_extent(_In_ fcb
* fcb
, _In_ LIST_ENTRY
* prevextle
, _In_ __drv_aliasesMem extent
* newext
);
1305 _Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL
)
1306 _Function_class_(DRIVER_DISPATCH
)
1307 NTSTATUS
drv_directory_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1309 ULONG
get_reparse_tag(device_extension
* Vcb
, root
* subvol
, UINT64 inode
, UINT8 type
, ULONG atts
, BOOL lxss
, PIRP Irp
);
1313 _Dispatch_type_(IRP_MJ_QUERY_SECURITY
)
1314 _Function_class_(DRIVER_DISPATCH
)
1315 NTSTATUS
drv_query_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1317 _Dispatch_type_(IRP_MJ_SET_SECURITY
)
1318 _Function_class_(DRIVER_DISPATCH
)
1319 NTSTATUS
drv_set_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1321 void fcb_get_sd(fcb
* fcb
, struct _fcb
* parent
, BOOL look_for_xattr
, PIRP Irp
);
1322 void add_user_mapping(WCHAR
* sidstring
, ULONG sidstringlength
, UINT32 uid
);
1323 void add_group_mapping(WCHAR
* sidstring
, ULONG sidstringlength
, UINT32 gid
);
1324 UINT32
sid_to_uid(PSID sid
);
1325 NTSTATUS
uid_to_sid(UINT32 uid
, PSID
* sid
);
1326 NTSTATUS
fcb_get_new_sd(fcb
* fcb
, file_ref
* parfileref
, ACCESS_STATE
* as
);
1327 void find_gid(struct _fcb
* fcb
, struct _fcb
* parfcb
, PSECURITY_SUBJECT_CONTEXT subjcont
);
1331 _Dispatch_type_(IRP_MJ_SET_INFORMATION
)
1332 _Function_class_(DRIVER_DISPATCH
)
1333 NTSTATUS
drv_set_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1335 _Dispatch_type_(IRP_MJ_QUERY_INFORMATION
)
1336 _Function_class_(DRIVER_DISPATCH
)
1337 NTSTATUS
drv_query_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1339 _Dispatch_type_(IRP_MJ_QUERY_EA
)
1340 _Function_class_(DRIVER_DISPATCH
)
1341 NTSTATUS
drv_query_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1343 _Dispatch_type_(IRP_MJ_SET_EA
)
1344 _Function_class_(DRIVER_DISPATCH
)
1345 NTSTATUS
drv_set_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1347 BOOL
has_open_children(file_ref
* fileref
);
1348 NTSTATUS
stream_set_end_of_file_information(device_extension
* Vcb
, UINT16 end
, fcb
* fcb
, file_ref
* fileref
, BOOL advance_only
);
1349 NTSTATUS
fileref_get_filename(file_ref
* fileref
, PUNICODE_STRING fn
, USHORT
* name_offset
, ULONG
* preqlen
);
1350 NTSTATUS
open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) device_extension
* Vcb
, root
* subvol
, UINT64 inode
, file_ref
** pfr
, PIRP Irp
);
1351 void insert_dir_child_into_hash_lists(fcb
* fcb
, dir_child
* dc
);
1352 void remove_dir_child_from_hash_lists(fcb
* fcb
, dir_child
* dc
);
1355 NTSTATUS
get_reparse_point(PDEVICE_OBJECT DeviceObject
, PFILE_OBJECT FileObject
, void* buffer
, DWORD buflen
, ULONG_PTR
* retlen
);
1356 NTSTATUS
set_reparse_point(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1357 NTSTATUS
delete_reparse_point(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1361 _Dispatch_type_(IRP_MJ_CREATE
)
1362 _Function_class_(DRIVER_DISPATCH
)
1363 NTSTATUS
drv_create(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1365 NTSTATUS
open_fileref(_Requires_lock_held_(_Curr_
->tree_lock
) _Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) _In_ device_extension
* Vcb
, _Out_ file_ref
** pfr
,
1366 _In_ PUNICODE_STRING fnus
, _In_opt_ file_ref
* related
, _In_ BOOL parent
, _Out_opt_ USHORT
* parsed
, _Out_opt_ ULONG
* fn_offset
, _In_ POOL_TYPE pooltype
,
1367 _In_ BOOL case_sensitive
, _In_opt_ PIRP Irp
);
1368 NTSTATUS
open_fcb(_Requires_lock_held_(_Curr_
->tree_lock
) _Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) device_extension
* Vcb
,
1369 root
* subvol
, UINT64 inode
, UINT8 type
, PANSI_STRING utf8
, fcb
* parent
, fcb
** pfcb
, POOL_TYPE pooltype
, PIRP Irp
);
1370 NTSTATUS
load_csum(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, UINT32
* csum
, UINT64 start
, UINT64 length
, PIRP Irp
);
1371 NTSTATUS
load_dir_children(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, fcb
* fcb
, BOOL ignore_size
, PIRP Irp
);
1372 NTSTATUS
add_dir_child(fcb
* fcb
, UINT64 inode
, BOOL subvol
, PANSI_STRING utf8
, PUNICODE_STRING name
, UINT8 type
, dir_child
** pdc
);
1373 NTSTATUS
open_fileref_child(_Requires_lock_held_(_Curr_
->tree_lock
) _Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) _In_ device_extension
* Vcb
,
1374 _In_ file_ref
* sf
, _In_ PUNICODE_STRING name
, _In_ BOOL case_sensitive
, _In_ BOOL lastpart
, _In_ BOOL streampart
,
1375 _In_ POOL_TYPE pooltype
, _Out_ file_ref
** psf2
, _In_opt_ PIRP Irp
);
1376 fcb
* create_fcb(device_extension
* Vcb
, POOL_TYPE pool_type
);
1377 NTSTATUS
find_file_in_dir(PUNICODE_STRING filename
, fcb
* fcb
, root
** subvol
, UINT64
* inode
, dir_child
** pdc
, BOOL case_sensitive
);
1378 UINT32
inherit_mode(fcb
* parfcb
, BOOL is_dir
);
1379 file_ref
* create_fileref(device_extension
* Vcb
);
1382 NTSTATUS
fsctl_request(PDEVICE_OBJECT DeviceObject
, PIRP
* Pirp
, UINT32 type
);
1383 void do_unlock_volume(device_extension
* Vcb
);
1384 void trim_whole_device(device
* dev
);
1385 void flush_subvol_fcbs(root
* subvol
);
1386 BOOL
fcb_is_inline(fcb
* fcb
);
1390 _Function_class_(KSTART_ROUTINE
)
1392 void NTAPI
flush_thread(void* context
);
1394 void flush_thread(void* context
);
1397 NTSTATUS
do_write(device_extension
* Vcb
, PIRP Irp
);
1398 NTSTATUS
get_tree_new_address(device_extension
* Vcb
, tree
* t
, PIRP Irp
, LIST_ENTRY
* rollback
);
1399 NTSTATUS
flush_fcb(fcb
* fcb
, BOOL cache
, LIST_ENTRY
* batchlist
, PIRP Irp
);
1400 NTSTATUS
write_data_phys(_In_ PDEVICE_OBJECT device
, _In_ UINT64 address
, _In_reads_bytes_(length
) void* data
, _In_ UINT32 length
);
1401 BOOL
is_tree_unique(device_extension
* Vcb
, tree
* t
, PIRP Irp
);
1402 NTSTATUS
do_tree_writes(device_extension
* Vcb
, LIST_ENTRY
* tree_writes
, BOOL no_free
);
1403 void add_checksum_entry(device_extension
* Vcb
, UINT64 address
, ULONG length
, UINT32
* csum
, PIRP Irp
);
1404 BOOL
find_metadata_address_in_chunk(device_extension
* Vcb
, chunk
* c
, UINT64
* address
);
1405 void add_trim_entry_avoid_sb(device_extension
* Vcb
, device
* dev
, UINT64 address
, UINT64 size
);
1406 NTSTATUS
insert_tree_item_batch(LIST_ENTRY
* batchlist
, device_extension
* Vcb
, root
* r
, UINT64 objid
, UINT8 objtype
, UINT64 offset
,
1407 _In_opt_
_When_(return >= 0, __drv_aliasesMem
) void* data
, UINT16 datalen
, enum batch_operation operation
);
1408 NTSTATUS
flush_partial_stripe(device_extension
* Vcb
, chunk
* c
, partial_stripe
* ps
);
1409 NTSTATUS
update_dev_item(device_extension
* Vcb
, device
* device
, PIRP Irp
);
1413 _Dispatch_type_(IRP_MJ_READ
)
1414 _Function_class_(DRIVER_DISPATCH
)
1415 NTSTATUS
drv_read(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1417 NTSTATUS
read_data(_In_ device_extension
* Vcb
, _In_ UINT64 addr
, _In_ UINT32 length
, _In_reads_bytes_opt_(length
*sizeof(UINT32
)/Vcb
->superblock
.sector_size
) UINT32
* csum
,
1418 _In_ BOOL is_tree
, _Out_writes_bytes_(length
) UINT8
* buf
, _In_opt_ chunk
* c
, _Out_opt_ chunk
** pc
, _In_opt_ PIRP Irp
, _In_ UINT64 generation
, _In_ BOOL file_read
,
1419 _In_ ULONG priority
);
1420 NTSTATUS
read_file(fcb
* fcb
, UINT8
* data
, UINT64 start
, UINT64 length
, ULONG
* pbr
, PIRP Irp
);
1421 NTSTATUS
read_stream(fcb
* fcb
, UINT8
* data
, UINT64 start
, ULONG length
, ULONG
* pbr
);
1422 NTSTATUS
do_read(PIRP Irp
, BOOLEAN wait
, ULONG
* bytes_read
);
1423 NTSTATUS
check_csum(device_extension
* Vcb
, UINT8
* data
, UINT32 sectors
, UINT32
* csum
);
1424 void raid6_recover2(UINT8
* sectors
, UINT16 num_stripes
, ULONG sector_size
, UINT16 missing1
, UINT16 missing2
, UINT8
* out
);
1428 _Dispatch_type_(IRP_MJ_PNP
)
1429 _Function_class_(DRIVER_DISPATCH
)
1430 NTSTATUS
drv_pnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1432 NTSTATUS
pnp_surprise_removal(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1433 NTSTATUS
pnp_query_remove_device(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1436 NTSTATUS
load_cache_chunk(device_extension
* Vcb
, chunk
* c
, PIRP Irp
);
1437 NTSTATUS
clear_free_space_cache(device_extension
* Vcb
, LIST_ENTRY
* batchlist
, PIRP Irp
);
1438 NTSTATUS
allocate_cache(device_extension
* Vcb
, BOOL
* changed
, PIRP Irp
, LIST_ENTRY
* rollback
);
1439 NTSTATUS
update_chunk_caches(device_extension
* Vcb
, PIRP Irp
, LIST_ENTRY
* rollback
);
1440 NTSTATUS
update_chunk_caches_tree(device_extension
* Vcb
, PIRP Irp
);
1441 NTSTATUS
add_space_entry(LIST_ENTRY
* list
, LIST_ENTRY
* list_size
, UINT64 offset
, UINT64 size
);
1442 void space_list_add(chunk
* c
, UINT64 address
, UINT64 length
, LIST_ENTRY
* rollback
);
1443 void space_list_add2(LIST_ENTRY
* list
, LIST_ENTRY
* list_size
, UINT64 address
, UINT64 length
, chunk
* c
, LIST_ENTRY
* rollback
);
1444 void space_list_subtract(chunk
* c
, BOOL deleting
, UINT64 address
, UINT64 length
, LIST_ENTRY
* rollback
);
1445 void space_list_subtract2(LIST_ENTRY
* list
, LIST_ENTRY
* list_size
, UINT64 address
, UINT64 length
, chunk
* c
, LIST_ENTRY
* rollback
);
1446 NTSTATUS
load_stored_free_space_cache(device_extension
* Vcb
, chunk
* c
, BOOL load_only
, PIRP Irp
);
1449 NTSTATUS
increase_extent_refcount_data(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 inode
, UINT64 offset
, UINT32 refcount
, PIRP Irp
);
1450 NTSTATUS
decrease_extent_refcount_data(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 inode
, UINT64 offset
,
1451 UINT32 refcount
, BOOL superseded
, PIRP Irp
);
1452 NTSTATUS
decrease_extent_refcount_tree(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT64 root
, UINT8 level
, PIRP Irp
);
1453 UINT64
get_extent_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 size
, PIRP Irp
);
1454 BOOL
is_extent_unique(device_extension
* Vcb
, UINT64 address
, UINT64 size
, PIRP Irp
);
1455 NTSTATUS
increase_extent_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT8 type
, void* data
, KEY
* firstitem
, UINT8 level
, PIRP Irp
);
1456 UINT64
get_extent_flags(device_extension
* Vcb
, UINT64 address
, PIRP Irp
);
1457 void update_extent_flags(device_extension
* Vcb
, UINT64 address
, UINT64 flags
, PIRP Irp
);
1458 NTSTATUS
update_changed_extent_ref(device_extension
* Vcb
, chunk
* c
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 objid
, UINT64 offset
,
1459 INT32 count
, BOOL no_csum
, BOOL superseded
, PIRP Irp
);
1460 void add_changed_extent_ref(chunk
* c
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 objid
, UINT64 offset
, UINT32 count
, BOOL no_csum
);
1461 UINT64
find_extent_shared_tree_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 parent
, PIRP Irp
);
1462 UINT32
find_extent_shared_data_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 parent
, PIRP Irp
);
1463 NTSTATUS
decrease_extent_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT8 type
, void* data
, KEY
* firstitem
,
1464 UINT8 level
, UINT64 parent
, BOOL superseded
, PIRP Irp
);
1465 UINT64
get_extent_data_ref_hash2(UINT64 root
, UINT64 objid
, UINT64 offset
);
1467 // in worker-thread.c
1468 void do_read_job(PIRP Irp
);
1469 void do_write_job(device_extension
* Vcb
, PIRP Irp
);
1470 BOOL
add_thread_job(device_extension
* Vcb
, PIRP Irp
);
1473 void read_registry(PUNICODE_STRING regpath
, BOOL refresh
);
1474 NTSTATUS
registry_mark_volume_mounted(BTRFS_UUID
* uuid
);
1475 NTSTATUS
registry_mark_volume_unmounted(BTRFS_UUID
* uuid
);
1476 NTSTATUS
registry_load_volume_options(device_extension
* Vcb
);
1477 void watch_registry(HANDLE regh
);
1480 NTSTATUS
zlib_decompress(UINT8
* inbuf
, UINT32 inlen
, UINT8
* outbuf
, UINT32 outlen
);
1481 NTSTATUS
lzo_decompress(UINT8
* inbuf
, UINT32 inlen
, UINT8
* outbuf
, UINT32 outlen
, UINT32 inpageoff
);
1482 NTSTATUS
write_compressed_bit(fcb
* fcb
, UINT64 start_data
, UINT64 end_data
, void* data
, BOOL
* compressed
, PIRP Irp
, LIST_ENTRY
* rollback
);
1485 void galois_double(UINT8
* data
, UINT32 len
);
1486 void galois_divpower(UINT8
* data
, UINT8 div
, UINT32 readlen
);
1487 UINT8
gpow2(UINT8 e
);
1488 UINT8
gmul(UINT8 a
, UINT8 b
);
1489 UINT8
gdiv(UINT8 a
, UINT8 b
);
1493 _Dispatch_type_(IRP_MJ_DEVICE_CONTROL
)
1494 _Function_class_(DRIVER_DISPATCH
)
1495 NTSTATUS
drv_device_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1499 _Function_class_(KSTART_ROUTINE
)
1501 void NTAPI
calc_thread(void* context
);
1503 void calc_thread(void* context
);
1506 NTSTATUS
add_calc_job(device_extension
* Vcb
, UINT8
* data
, UINT32 sectors
, UINT32
* csum
, calc_job
** pcj
);
1507 void free_calc_job(calc_job
* cj
);
1510 NTSTATUS
start_balance(device_extension
* Vcb
, void* data
, ULONG length
, KPROCESSOR_MODE processor_mode
);
1511 NTSTATUS
query_balance(device_extension
* Vcb
, void* data
, ULONG length
);
1512 NTSTATUS
pause_balance(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1513 NTSTATUS
resume_balance(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1514 NTSTATUS
stop_balance(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1515 NTSTATUS
look_for_balance_item(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
);
1516 NTSTATUS
remove_device(device_extension
* Vcb
, void* data
, ULONG length
, KPROCESSOR_MODE processor_mode
);
1518 _Function_class_(KSTART_ROUTINE
)
1520 void NTAPI
balance_thread(void* context
);
1522 void balance_thread(void* context
);
1526 NTSTATUS
vol_create(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1527 NTSTATUS
vol_close(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1528 NTSTATUS
vol_read(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1529 NTSTATUS
vol_write(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1530 NTSTATUS
vol_query_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1531 NTSTATUS
vol_set_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1532 NTSTATUS
vol_query_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1533 NTSTATUS
vol_set_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1534 NTSTATUS
vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1535 NTSTATUS
vol_query_volume_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1536 NTSTATUS
vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1537 NTSTATUS
vol_cleanup(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1538 NTSTATUS
vol_directory_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1539 NTSTATUS
vol_file_system_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1540 NTSTATUS
vol_lock_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1541 NTSTATUS
vol_device_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1542 NTSTATUS
vol_shutdown(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1543 NTSTATUS
vol_query_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1544 NTSTATUS
vol_set_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1545 NTSTATUS
vol_power(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1546 void add_volume_device(superblock
* sb
, PDEVICE_OBJECT mountmgr
, PUNICODE_STRING devpath
, UINT64 length
, ULONG disk_num
, ULONG part_num
);
1547 NTSTATUS
mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr
, PUNICODE_STRING devpath
);
1549 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE
)
1551 NTSTATUS NTAPI
pnp_removal(PVOID NotificationStructure
, PVOID Context
);
1553 NTSTATUS
pnp_removal(PVOID NotificationStructure
, PVOID Context
);
1557 NTSTATUS
start_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1558 NTSTATUS
query_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
, void* data
, ULONG length
);
1559 NTSTATUS
pause_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1560 NTSTATUS
resume_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1561 NTSTATUS
stop_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1564 NTSTATUS
send_subvol(device_extension
* Vcb
, void* data
, ULONG datalen
, PFILE_OBJECT FileObject
, PIRP Irp
);
1565 NTSTATUS
read_send_buffer(device_extension
* Vcb
, PFILE_OBJECT FileObject
, void* data
, ULONG datalen
, ULONG_PTR
* retlen
, KPROCESSOR_MODE processor_mode
);
1567 // based on function in sys/sysmacros.h
1568 #define makedev(major, minor) (((minor) & 0xFF) | (((major) & 0xFFF) << 8) | (((UINT64)((minor) & ~0xFF)) << 12) | (((UINT64)((major) & ~0xFFF)) << 32))
1570 #define fast_io_possible(fcb) (!FsRtlAreThereCurrentFileLocks(&fcb->lock) && !fcb->Vcb->readonly ? FastIoIsPossible : FastIoIsQuestionable)
1572 static __inline
void print_open_trees(device_extension
* Vcb
) {
1573 LIST_ENTRY
* le
= Vcb
->trees
.Flink
;
1574 while (le
!= &Vcb
->trees
) {
1575 tree
* t
= CONTAINING_RECORD(le
, tree
, list_entry
);
1576 tree_data
* td
= CONTAINING_RECORD(t
->itemlist
.Flink
, tree_data
, list_entry
);
1577 ERR("tree %p: root %llx, level %u, first key (%llx,%x,%llx)\n",
1578 t
, t
->root
->id
, t
->header
.level
, td
->key
.obj_id
, td
->key
.obj_type
, td
->key
.offset
);
1584 static __inline BOOL
write_fcb_compressed(fcb
* fcb
) {
1585 // make sure we don't accidentally write the cache inodes or pagefile compressed
1586 if (fcb
->subvol
->id
== BTRFS_ROOT_ROOT
|| fcb
->Header
.Flags2
& FSRTL_FLAG2_IS_PAGING_FILE
)
1589 if (fcb
->Vcb
->options
.compress_force
)
1592 if (fcb
->inode_item
.flags
& BTRFS_INODE_NOCOMPRESS
)
1595 if (fcb
->inode_item
.flags
& BTRFS_INODE_COMPRESS
|| fcb
->Vcb
->options
.compress
)
1601 static __inline
void do_xor(UINT8
* buf1
, UINT8
* buf2
, UINT32 len
) {
1608 if (have_sse2
&& ((uintptr_t)buf1
& 0xf) == 0 && ((uintptr_t)buf2
& 0xf) == 0) {
1610 x1
= _mm_load_si128((__m128i
*)buf1
);
1611 x2
= _mm_load_si128((__m128i
*)buf2
);
1612 x1
= _mm_xor_si128(x1
, x2
);
1613 _mm_store_si128((__m128i
*)buf1
, x1
);
1622 for (j
= 0; j
< len
; j
++) {
1629 #ifdef DEBUG_FCB_REFCOUNTS
1630 #ifdef DEBUG_LONG_MESSAGES
1631 #define increase_fileref_refcount(fileref) {\
1632 LONG rc = InterlockedIncrement(&fileref->refcount);\
1633 MSG(funcname, __FILE__, __LINE__, "fileref %p: refcount now %i\n", 1, fileref, rc);\
1636 #define increase_fileref_refcount(fileref) {\
1637 LONG rc = InterlockedIncrement(&fileref->refcount);\
1638 MSG(funcname, "fileref %p: refcount now %i\n", 1, fileref, rc);\
1642 #define increase_fileref_refcount(fileref) InterlockedIncrement(&fileref->refcount)
1646 #define int3 __debugbreak()
1648 #define int3 asm("int3;")
1651 #define hex_digit(c) ((c) <= 9) ? ((c) + '0') : ((c) - 10 + 'a')
1653 // FIXME - find a way to catch unfreed trees again
1656 #define __S_IFMT 0170000 /* These bits determine file type. */
1657 #define __S_IFDIR 0040000 /* Directory. */
1658 #define __S_IFCHR 0020000 /* Character device. */
1659 #define __S_IFBLK 0060000 /* Block device. */
1660 #define __S_IFREG 0100000 /* Regular file. */
1661 #define __S_IFIFO 0010000 /* FIFO. */
1662 #define __S_IFLNK 0120000 /* Symbolic link. */
1663 #define __S_IFSOCK 0140000 /* Socket. */
1664 #define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask))
1667 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
1671 #define S_IRUSR 0000400
1675 #define S_IWUSR 0000200
1679 #define S_IXUSR 0000100
1683 #define S_IFDIR __S_IFDIR
1684 #define S_IFREG __S_IFREG
1685 #endif /* __REACTOS__ */
1688 #define S_IRGRP (S_IRUSR >> 3)
1692 #define S_IWGRP (S_IWUSR >> 3)
1696 #define S_IXGRP (S_IXUSR >> 3)
1700 #define S_IROTH (S_IRGRP >> 3)
1704 #define S_IWOTH (S_IWGRP >> 3)
1708 #define S_IXOTH (S_IXGRP >> 3)
1712 #define S_ISUID 0004000
1716 #define S_ISGID 0002000
1720 #define S_ISVTX 0001000
1723 static __inline UINT64
fcb_alloc_size(fcb
* fcb
) {
1724 if (S_ISDIR(fcb
->inode_item
.st_mode
))
1726 else if (fcb
->atts
& FILE_ATTRIBUTE_SPARSE_FILE
)
1727 return fcb
->inode_item
.st_blocks
;
1729 return sector_align(fcb
->inode_item
.st_size
, fcb
->Vcb
->superblock
.sector_size
);
1732 typedef BOOLEAN (*tPsIsDiskCountersEnabled
)();
1734 typedef VOID (*tPsUpdateDiskCounters
)(PEPROCESS Process
, ULONG64 BytesRead
, ULONG64 BytesWritten
,
1735 ULONG ReadOperationCount
, ULONG WriteOperationCount
, ULONG FlushOperationCount
);
1737 typedef BOOLEAN (*tCcCopyWriteEx
)(PFILE_OBJECT FileObject
, PLARGE_INTEGER FileOffset
, ULONG Length
, BOOLEAN Wait
,
1738 PVOID Buffer
, PETHREAD IoIssuerThread
);
1740 typedef BOOLEAN (*tCcCopyReadEx
)(PFILE_OBJECT FileObject
, PLARGE_INTEGER FileOffset
, ULONG Length
, BOOLEAN Wait
,
1741 PVOID Buffer
, PIO_STATUS_BLOCK IoStatus
, PETHREAD IoIssuerThread
);
1743 #ifndef CC_ENABLE_DISK_IO_ACCOUNTING
1744 #define CC_ENABLE_DISK_IO_ACCOUNTING 0x00000010
1747 typedef VOID (*tCcSetAdditionalCacheAttributesEx
)(PFILE_OBJECT FileObject
, ULONG Flags
);
1749 typedef VOID (*tFsRtlUpdateDiskCounters
)(ULONG64 BytesRead
, ULONG64 BytesWritten
);
1754 #undef RtlIsNtDdiVersionAvailable
1756 BOOLEAN
RtlIsNtDdiVersionAvailable(ULONG Version
);
1758 PEPROCESS
PsGetThreadProcess(_In_ PETHREAD Thread
); // not in mingw
1761 // not in DDK headers - taken from winternl.h
1762 typedef struct _LDR_DATA_TABLE_ENTRY
{
1764 LIST_ENTRY InMemoryOrderLinks
;
1768 UNICODE_STRING FullDllName
;
1775 ULONG TimeDateStamp
;
1776 } LDR_DATA_TABLE_ENTRY
,*PLDR_DATA_TABLE_ENTRY
;
1778 typedef struct _PEB_LDR_DATA
{
1781 LIST_ENTRY InMemoryOrderModuleList
;
1782 } PEB_LDR_DATA
,*PPEB_LDR_DATA
;
1784 typedef struct _RTL_USER_PROCESS_PARAMETERS
{
1786 PVOID Reserved2
[10];
1787 UNICODE_STRING ImagePathName
;
1788 UNICODE_STRING CommandLine
;
1789 } RTL_USER_PROCESS_PARAMETERS
,*PRTL_USER_PROCESS_PARAMETERS
;
1791 typedef VOID (NTAPI
*PPS_POST_PROCESS_INIT_ROUTINE
)(VOID
);
1793 typedef struct _PEB
{
1799 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
;
1800 BYTE Reserved4
[104];
1801 PVOID Reserved5
[52];
1802 PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine
;
1803 BYTE Reserved6
[128];
1810 NTSTATUS NTAPI
ZwQueryInformationProcess(
1811 IN HANDLE ProcessHandle
,
1812 IN PROCESSINFOCLASS ProcessInformationClass
,
1813 OUT PVOID ProcessInformation
,
1814 IN ULONG ProcessInformationLength
,
1815 OUT PULONG ReturnLength OPTIONAL
1820 #if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7)
1821 NTSTATUS WINAPI
RtlUnicodeToUTF8N(CHAR
*utf8_dest
, ULONG utf8_bytes_max
,
1822 ULONG
*utf8_bytes_written
,
1823 const WCHAR
*uni_src
, ULONG uni_bytes
);
1824 NTSTATUS WINAPI
RtlUTF8ToUnicodeN(WCHAR
*uni_dest
, ULONG uni_bytes_max
,
1825 ULONG
*uni_bytes_written
,
1826 const CHAR
*utf8_src
, ULONG utf8_bytes
);
1827 #endif /* defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7) */
1828 #if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_VISTA)
1829 NTSTATUS NTAPI
FsRtlRemoveDotsFromPath(PWSTR OriginalString
,
1830 USHORT PathLength
, USHORT
*NewLength
);
1831 NTSTATUS NTAPI
FsRtlValidateReparsePointBuffer(ULONG BufferLength
,
1832 PREPARSE_DATA_BUFFER ReparseBuffer
);
1833 ULONG NTAPI
KeQueryActiveProcessorCount(PKAFFINITY ActiveProcessors
);
1834 #endif /* defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_VISTA) */