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_CHUNK_LOCKS
78 #define DEBUG_PARANOID
81 #define UNUSED(x) (void)(x)
83 #define BTRFS_NODE_TYPE_CCB 0x2295
84 #define BTRFS_NODE_TYPE_FCB 0x2296
86 #define ALLOC_TAG 0x7442484D //'MHBt'
87 #define ALLOC_TAG_ZLIB 0x7A42484D //'MHBz'
89 #define UID_NOBODY 65534
90 #define GID_NOBODY 65534
92 #define EA_NTACL "security.NTACL"
93 #define EA_NTACL_HASH 0x45922146
95 #define EA_DOSATTRIB "user.DOSATTRIB"
96 #define EA_DOSATTRIB_HASH 0x914f9939
98 #define EA_REPARSE "user.reparse"
99 #define EA_REPARSE_HASH 0xfabad1fe
101 #define EA_EA "user.EA"
102 #define EA_EA_HASH 0x8270dd43
104 #define EA_CASE_SENSITIVE "user.casesensitive"
105 #define EA_CASE_SENSITIVE_HASH 0x1a9d97d4
107 #define EA_PROP_COMPRESSION "btrfs.compression"
108 #define EA_PROP_COMPRESSION_HASH 0x20ccdf69
110 #define MAX_EXTENT_SIZE 0x8000000 // 128 MB
111 #define COMPRESSED_EXTENT_SIZE 0x20000 // 128 KB
113 #define READ_AHEAD_GRANULARITY COMPRESSED_EXTENT_SIZE // really ought to be a multiple of COMPRESSED_EXTENT_SIZE
115 #define IO_REPARSE_TAG_LXSS_SYMLINK 0xa000001d // undocumented?
117 #define IO_REPARSE_TAG_LXSS_SOCKET 0x80000023
118 #define IO_REPARSE_TAG_LXSS_FIFO 0x80000024
119 #define IO_REPARSE_TAG_LXSS_CHARDEV 0x80000025
120 #define IO_REPARSE_TAG_LXSS_BLOCKDEV 0x80000026
122 #define BTRFS_VOLUME_PREFIX L"\\Device\\Btrfs{"
126 #define except __except
127 #define finally __finally
130 #define except(x) if (0 && (x))
131 #define finally if (1)
134 #ifndef FILE_SUPPORTS_BLOCK_REFCOUNTING
135 #define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000
138 #ifndef FILE_SUPPORTS_POSIX_UNLINK_RENAME
139 #define FILE_SUPPORTS_POSIX_UNLINK_RENAME 0x00000400
142 #ifndef FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL
143 #define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000
147 typedef struct _FILE_ID_128
{
148 UCHAR Identifier
[16];
149 } FILE_ID_128
, *PFILE_ID_128
;
152 typedef struct _DUPLICATE_EXTENTS_DATA
{
154 LARGE_INTEGER SourceFileOffset
;
155 LARGE_INTEGER TargetFileOffset
;
156 LARGE_INTEGER ByteCount
;
157 } DUPLICATE_EXTENTS_DATA
, *PDUPLICATE_EXTENTS_DATA
;
159 #define FSCTL_DUPLICATE_EXTENTS_TO_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 209, METHOD_BUFFERED, FILE_WRITE_ACCESS)
161 typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER
{
162 WORD ChecksumAlgorithm
;
165 DWORD ChecksumChunkSizeInBytes
;
166 DWORD ClusterSizeInBytes
;
167 } FSCTL_GET_INTEGRITY_INFORMATION_BUFFER
, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER
;
169 typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER
{
170 WORD ChecksumAlgorithm
;
173 } FSCTL_SET_INTEGRITY_INFORMATION_BUFFER
, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER
;
175 #define FSCTL_GET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS)
176 #define FSCTL_SET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
180 #define __drv_aliasesMem
181 #define _Requires_lock_held_(a)
182 #define _Requires_exclusive_lock_held_(a)
183 #define _Releases_lock_(a)
184 #define _Out_writes_bytes_opt_(a)
185 #define _Pre_satisfies_(a)
186 #define _Post_satisfies_(a)
187 #define _Releases_exclusive_lock_(a)
188 #define _Dispatch_type_(a)
189 #define _Create_lock_level_(a)
190 #define _Lock_level_order_(a,b)
191 #define _Has_lock_level_(a)
192 #define _Requires_lock_not_held_(a)
193 #define _Acquires_exclusive_lock_(a)
194 #define _Acquires_shared_lock_(a)
198 _Create_lock_level_(tree_lock
)
199 _Create_lock_level_(fcb_lock
)
200 _Lock_level_order_(tree_lock
, fcb_lock
)
202 struct _device_extension
;
204 typedef struct _fcb_nonpaged
{
205 FAST_MUTEX HeaderMutex
;
206 SECTION_OBJECT_POINTERS segment_object
;
208 ERESOURCE paging_resource
;
209 ERESOURCE dir_children_lock
;
222 LIST_ENTRY list_entry
;
224 EXTENT_DATA extent_data
;
232 LIST_ENTRY list_entry
;
245 UNICODE_STRING name_uc
;
247 struct _file_ref
* fileref
;
248 LIST_ENTRY list_entry_index
;
249 LIST_ENTRY list_entry_hash
;
250 LIST_ENTRY list_entry_hash_uc
;
253 enum prop_compression_type
{
254 PropCompression_None
,
255 PropCompression_Zlib
,
261 LIST_ENTRY list_entry
;
268 typedef struct _fcb
{
269 FSRTL_ADVANCED_FCB_HEADER Header
;
270 struct _fcb_nonpaged
* nonpaged
;
273 struct _device_extension
* Vcb
;
274 struct _root
* subvol
;
278 INODE_ITEM inode_item
;
279 SECURITY_DESCRIPTOR
* sd
;
282 PKTHREAD lazy_writer_thread
;
284 SHARE_ACCESS share_access
;
288 ANSI_STRING reparse_xattr
;
289 ANSI_STRING ea_xattr
;
291 LIST_ENTRY hardlinks
;
292 struct _file_ref
* fileref
;
293 BOOL inode_item_changed
;
294 enum prop_compression_type prop_compression
;
296 BOOL marked_as_orphan
;
298 BOOL case_sensitive_set
;
300 LIST_ENTRY dir_children_index
;
301 LIST_ENTRY dir_children_hash
;
302 LIST_ENTRY dir_children_hash_uc
;
303 LIST_ENTRY
** hash_ptrs
;
304 LIST_ENTRY
** hash_ptrs_uc
;
307 BOOL sd_dirty
, sd_deleted
;
308 BOOL atts_changed
, atts_deleted
;
309 BOOL extents_changed
;
310 BOOL reparse_xattr_changed
;
312 BOOL prop_compression_changed
;
319 ANSI_STRING adsxattr
;
322 LIST_ENTRY list_entry
;
323 LIST_ENTRY list_entry_all
;
324 LIST_ENTRY list_entry_dirty
;
328 ERESOURCE fileref_lock
;
331 typedef struct _file_ref
{
335 BOOL delete_on_close
;
339 file_ref_nonpaged
* nonpaged
;
343 struct _file_ref
* parent
;
349 LIST_ENTRY list_entry
;
350 LIST_ENTRY list_entry_dirty
;
357 KEVENT cleared_event
;
359 LIST_ENTRY list_entry
;
362 typedef struct _ccb
{
367 UINT64 query_dir_offset
;
368 UNICODE_STRING query_string
;
371 BOOL manage_volume_privilege
;
372 BOOL allow_extended_dasd_io
;
376 UNICODE_STRING filename
;
379 BOOL user_set_creation_time
;
380 BOOL user_set_access_time
;
381 BOOL user_set_write_time
;
382 BOOL user_set_change_time
;
385 NTSTATUS send_status
;
388 struct _device_extension
;
396 typedef struct _tree_data
{
398 LIST_ENTRY list_entry
;
403 tree_holder treeholder
;
416 typedef struct _tree
{
417 tree_nonpaged
* nonpaged
;
422 struct _device_extension
* Vcb
;
423 struct _tree
* parent
;
427 LIST_ENTRY list_entry
;
428 LIST_ENTRY list_entry_hash
;
430 BOOL has_new_address
;
431 BOOL updated_extents
;
434 BOOL uniqueness_determined
;
439 ERESOURCE load_tree_lock
;
442 typedef struct _root
{
444 LONGLONG lastinode
; // signed so we can use InterlockedIncrement64
445 tree_holder treeholder
;
446 root_nonpaged
* nonpaged
;
454 BOOL checked_for_orphans
;
456 LIST_ENTRY
* fcbs_ptrs
[256];
457 LIST_ENTRY list_entry
;
458 LIST_ENTRY list_entry_dirty
;
461 enum batch_operation
{
465 Batch_DeleteInodeRef
,
466 Batch_DeleteInodeExtRef
,
468 Batch_DeleteExtentData
,
469 Batch_DeleteFreeSpace
,
481 enum batch_operation operation
;
482 LIST_ENTRY list_entry
;
488 LIST_ENTRY list_entry
;
496 typedef struct _root_cache
{
498 struct _root_cache
* next
;
504 LIST_ENTRY list_entry
;
505 LIST_ENTRY list_entry_size
;
509 PDEVICE_OBJECT devobj
;
523 LIST_ENTRY list_entry
;
524 ULONG num_trim_entries
;
525 LIST_ENTRY trim_list
;
532 LIST_ENTRY list_entry
;
539 LIST_ENTRY list_entry
;
544 CHUNK_ITEM
* chunk_item
;
553 LIST_ENTRY space_size
;
555 LIST_ENTRY changed_extents
;
556 LIST_ENTRY range_locks
;
557 ERESOURCE range_locks_lock
;
558 KEVENT range_locks_event
;
560 ERESOURCE changed_extents_lock
;
570 LIST_ENTRY partial_stripes
;
571 ERESOURCE partial_stripes_lock
;
574 LIST_ENTRY list_entry
;
575 LIST_ENTRY list_entry_balance
;
588 LIST_ENTRY list_entry
;
599 LIST_ENTRY list_entry
;
600 } changed_extent_ref
;
606 LIST_ENTRY list_entry
;
616 LIST_ENTRY list_entry
;
620 PDEVICE_OBJECT DeviceObject
;
630 drv_calc_thread
* threads
;
642 UINT32 flush_interval
;
652 #define VCB_TYPE_FS 1
653 #define VCB_TYPE_CONTROL 2
654 #define VCB_TYPE_VOLUME 3
655 #define VCB_TYPE_PDO 4
661 UINT64 read_total_time
;
662 UINT64 read_csum_time
;
663 UINT64 read_disk_time
;
666 UINT64 open_total_time
;
667 UINT64 num_overwrites
;
668 UINT64 overwrite_total_time
;
670 UINT64 create_total_time
;
671 UINT64 open_fcb_calls
;
672 UINT64 open_fcb_time
;
673 UINT64 open_fileref_child_calls
;
674 UINT64 open_fileref_child_time
;
675 UINT64 fcb_lock_time
;
679 #define BALANCE_OPTS_DATA 0
680 #define BALANCE_OPTS_METADATA 1
681 #define BALANCE_OPTS_SYSTEM 2
687 btrfs_balance_opts opts
[3];
705 LIST_ENTRY list_entry
;
711 UINT16 filename_length
;
725 ERESOURCE stats_lock
;
730 LARGE_INTEGER start_time
;
731 LARGE_INTEGER finish_time
;
732 LARGE_INTEGER resume_time
;
733 LARGE_INTEGER duration
;
736 UINT64 data_scrubbed
;
742 struct _volume_device_extension
;
744 typedef struct _device_extension
{
746 mount_options options
;
748 struct _volume_device_extension
* vde
;
753 #ifdef DEBUG_CHUNK_LOCKS
754 LONG chunk_locks_held
;
756 UINT64 devices_loaded
;
757 superblock superblock
;
761 BOOL lock_paused_balance
;
762 BOOL disallow_dismount
;
764 PFILE_OBJECT locked_fileobj
;
767 file_ref
* root_fileref
;
769 _Has_lock_level_(fcb_lock
) ERESOURCE fcb_lock
;
770 ERESOURCE fileref_lock
;
772 _Has_lock_level_(tree_lock
) ERESOURCE tree_lock
;
773 PNOTIFY_SYNC NotifySync
;
774 LIST_ENTRY DirNotifyList
;
778 UINT64 metadata_flags
;
781 LIST_ENTRY drop_roots
;
788 root
* data_reloc_root
;
790 BOOL log_to_phys_loaded
;
791 BOOL chunk_usage_found
;
792 LIST_ENTRY sys_chunks
;
795 LIST_ENTRY trees_hash
;
796 LIST_ENTRY
* trees_ptrs
[256];
797 FAST_MUTEX trees_list_mutex
;
799 LIST_ENTRY dirty_fcbs
;
800 ERESOURCE dirty_fcbs_lock
;
801 LIST_ENTRY dirty_filerefs
;
802 ERESOURCE dirty_filerefs_lock
;
803 LIST_ENTRY dirty_subvols
;
804 ERESOURCE dirty_subvols_lock
;
805 ERESOURCE chunk_lock
;
806 HANDLE flush_thread_handle
;
807 KTIMER flush_thread_timer
;
808 KEVENT flush_thread_finished
;
809 drv_calc_threads calcthreads
;
810 balance_info balance
;
812 ERESOURCE send_load_lock
;
815 PFILE_OBJECT root_file
;
816 PAGED_LOOKASIDE_LIST tree_data_lookaside
;
817 PAGED_LOOKASIDE_LIST traverse_ptr_lookaside
;
818 PAGED_LOOKASIDE_LIST batch_item_lookaside
;
819 PAGED_LOOKASIDE_LIST fileref_lookaside
;
820 PAGED_LOOKASIDE_LIST fcb_lookaside
;
821 PAGED_LOOKASIDE_LIST name_bit_lookaside
;
822 NPAGED_LOOKASIDE_LIST range_lock_lookaside
;
823 NPAGED_LOOKASIDE_LIST fileref_np_lookaside
;
824 NPAGED_LOOKASIDE_LIST fcb_np_lookaside
;
825 LIST_ENTRY list_entry
;
830 PDEVICE_OBJECT buspdo
;
831 PDEVICE_OBJECT attached_device
;
832 UNICODE_STRING bus_name
;
833 } control_device_extension
;
839 PDEVICE_OBJECT devobj
;
840 PFILE_OBJECT fileobj
;
841 UNICODE_STRING pnp_name
;
844 BOOL had_drive_letter
;
845 void* notification_entry
;
848 LIST_ENTRY list_entry
;
851 struct pdo_device_extension
;
853 typedef struct _volume_device_extension
{
856 PDEVICE_OBJECT device
;
857 PDEVICE_OBJECT mounted_device
;
859 struct pdo_device_extension
* pdode
;
860 UNICODE_STRING bus_name
;
861 PDEVICE_OBJECT attached_device
;
864 } volume_device_extension
;
866 typedef struct pdo_device_extension
{
869 volume_device_extension
* vde
;
874 UINT64 children_loaded
;
875 ERESOURCE child_lock
;
878 LIST_ENTRY list_entry
;
879 } pdo_device_extension
;
882 LIST_ENTRY listentry
;
888 LIST_ENTRY listentry
;
893 enum write_data_status
{
894 WriteDataStatus_Pending
,
895 WriteDataStatus_Success
,
896 WriteDataStatus_Error
,
897 WriteDataStatus_Cancelling
,
898 WriteDataStatus_Cancelled
,
899 WriteDataStatus_Ignore
902 struct _write_data_context
;
905 struct _write_data_context
* context
;
910 IO_STATUS_BLOCK iosb
;
911 enum write_data_status status
;
912 LIST_ENTRY list_entry
;
915 typedef struct _write_data_context
{
920 UINT8
*parity1
, *parity2
, *scratch
;
921 PMDL mdl
, parity1_mdl
, parity2_mdl
;
922 } write_data_context
;
929 LIST_ENTRY list_entry
;
934 LIST_ENTRY list_entry
;
937 _Requires_lock_not_held_(Vcb
->fcb_lock
)
938 _Acquires_shared_lock_(Vcb
->fcb_lock
)
939 static __inline
void acquire_fcb_lock_shared(device_extension
* Vcb
) {
941 LARGE_INTEGER time1
, time2
;
943 if (ExAcquireResourceSharedLite(&Vcb
->fcb_lock
, FALSE
))
946 time1
= KeQueryPerformanceCounter(NULL
);
949 ExAcquireResourceSharedLite(&Vcb
->fcb_lock
, TRUE
);
952 time2
= KeQueryPerformanceCounter(NULL
);
953 Vcb
->stats
.fcb_lock_time
+= time2
.QuadPart
- time1
.QuadPart
;
957 _Requires_lock_not_held_(Vcb
->fcb_lock
)
958 _Acquires_exclusive_lock_(Vcb
->fcb_lock
)
959 static __inline
void acquire_fcb_lock_exclusive(device_extension
* Vcb
) {
961 LARGE_INTEGER time1
, time2
;
963 if (ExAcquireResourceExclusiveLite(&Vcb
->fcb_lock
, FALSE
))
966 time1
= KeQueryPerformanceCounter(NULL
);
969 ExAcquireResourceExclusiveLite(&Vcb
->fcb_lock
, TRUE
);
972 time2
= KeQueryPerformanceCounter(NULL
);
973 Vcb
->stats
.fcb_lock_time
+= time2
.QuadPart
- time1
.QuadPart
;
977 _Requires_lock_held_(Vcb
->fcb_lock
)
978 _Releases_lock_(Vcb
->fcb_lock
)
979 static __inline
void release_fcb_lock(device_extension
* Vcb
) {
980 ExReleaseResourceLite(&Vcb
->fcb_lock
);
983 static __inline
void* map_user_buffer(PIRP Irp
, ULONG priority
) {
984 if (!Irp
->MdlAddress
) {
985 return Irp
->UserBuffer
;
987 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, priority
);
991 static __inline UINT64
unix_time_to_win(BTRFS_TIME
* t
) {
992 return (t
->seconds
* 10000000) + (t
->nanoseconds
/ 100) + 116444736000000000;
995 static __inline
void win_time_to_unix(LARGE_INTEGER t
, BTRFS_TIME
* out
) {
996 ULONGLONG l
= (ULONGLONG
)t
.QuadPart
- 116444736000000000;
998 out
->seconds
= l
/ 10000000;
999 out
->nanoseconds
= (UINT32
)((l
% 10000000) * 100);
1002 _Post_satisfies_(*stripe
>=0&&*stripe
<num_stripes
)
1003 static __inline
void get_raid0_offset(_In_ UINT64 off
, _In_ UINT64 stripe_length
, _In_ UINT16 num_stripes
, _Out_ UINT64
* stripeoff
, _Out_ UINT16
* stripe
) {
1004 UINT64 initoff
, startoff
;
1006 startoff
= off
% (num_stripes
* stripe_length
);
1007 initoff
= (off
/ (num_stripes
* stripe_length
)) * stripe_length
;
1009 *stripe
= (UINT16
)(startoff
/ stripe_length
);
1010 *stripeoff
= initoff
+ startoff
- (*stripe
* stripe_length
);
1013 /* We only have 64 bits for a file ID, which isn't technically enough to be
1014 * unique on Btrfs. We fudge it by having three bytes for the subvol and
1015 * five for the inode, which should be good enough.
1016 * Inodes are also 64 bits on Linux, but the Linux driver seems to get round
1017 * this by tricking it into thinking subvols are separate volumes. */
1018 static __inline UINT64
make_file_id(root
* r
, UINT64 inode
) {
1019 return (r
->id
<< 40) | (inode
& 0xffffffffff);
1022 #define keycmp(key1, key2)\
1023 ((key1.obj_id < key2.obj_id) ? -1 :\
1024 ((key1.obj_id > key2.obj_id) ? 1 :\
1025 ((key1.obj_type < key2.obj_type) ? -1 :\
1026 ((key1.obj_type > key2.obj_type) ? 1 :\
1027 ((key1.offset < key2.offset) ? -1 :\
1028 ((key1.offset > key2.offset) ? 1 :\
1031 _Post_satisfies_(return>=n
)
1032 __inline
static UINT64
sector_align(_In_ UINT64 n
, _In_ UINT64 a
) {
1034 n
= (n
+ a
) & ~(a
- 1);
1039 __inline
static BOOL
is_subvol_readonly(root
* r
, PIRP Irp
) {
1040 if (!(r
->root_item
.flags
& BTRFS_SUBVOL_READONLY
))
1046 return (!Irp
|| Irp
->RequestorMode
== UserMode
) && PsGetCurrentProcess() != r
->reserved
? TRUE
: FALSE
;
1049 __inline
static UINT16
get_extent_data_len(UINT8 type
) {
1051 case TYPE_TREE_BLOCK_REF
:
1052 return sizeof(TREE_BLOCK_REF
);
1054 case TYPE_EXTENT_DATA_REF
:
1055 return sizeof(EXTENT_DATA_REF
);
1057 case TYPE_EXTENT_REF_V0
:
1058 return sizeof(EXTENT_REF_V0
);
1060 case TYPE_SHARED_BLOCK_REF
:
1061 return sizeof(SHARED_BLOCK_REF
);
1063 case TYPE_SHARED_DATA_REF
:
1064 return sizeof(SHARED_DATA_REF
);
1071 __inline
static UINT32
get_extent_data_refcount(UINT8 type
, void* data
) {
1073 case TYPE_TREE_BLOCK_REF
:
1076 case TYPE_EXTENT_DATA_REF
:
1078 EXTENT_DATA_REF
* edr
= (EXTENT_DATA_REF
*)data
;
1082 case TYPE_EXTENT_REF_V0
:
1084 EXTENT_REF_V0
* erv0
= (EXTENT_REF_V0
*)data
;
1088 case TYPE_SHARED_BLOCK_REF
:
1091 case TYPE_SHARED_DATA_REF
:
1093 SHARED_DATA_REF
* sdr
= (SHARED_DATA_REF
*)data
;
1104 device
* find_device_from_uuid(_In_ device_extension
* Vcb
, _In_ BTRFS_UUID
* uuid
);
1107 BOOL
get_file_attributes_from_xattr(_In_reads_bytes_(len
) char* val
, _In_ UINT16 len
, _Out_ ULONG
* atts
);
1109 ULONG
get_file_attributes(_In_
_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ root
* r
, _In_ UINT64 inode
,
1110 _In_ UINT8 type
, _In_ BOOL dotfile
, _In_ BOOL ignore_xa
, _In_opt_ PIRP Irp
);
1113 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
,
1114 _Out_ UINT8
** data
, _Out_ UINT16
* datalen
, _In_opt_ PIRP Irp
);
1116 #ifndef DEBUG_FCB_REFCOUNTS
1117 void free_fcb(_Inout_ fcb
* fcb
);
1119 void free_fileref(_Inout_ file_ref
* fr
);
1120 void protect_superblocks(_Inout_ chunk
* c
);
1121 BOOL
is_top_level(_In_ PIRP Irp
);
1122 NTSTATUS
create_root(_In_
_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ UINT64 id
,
1123 _Out_ root
** rootptr
, _In_ BOOL no_tree
, _In_ UINT64 offset
, _In_opt_ PIRP Irp
);
1124 void uninit(_In_ device_extension
* Vcb
);
1125 NTSTATUS
dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject
, _In_ ULONG ControlCode
, _In_reads_bytes_opt_(InputBufferSize
) PVOID InputBuffer
, _In_ ULONG InputBufferSize
,
1126 _Out_writes_bytes_opt_(OutputBufferSize
) PVOID OutputBuffer
, _In_ ULONG OutputBufferSize
, _In_ BOOLEAN Override
, _Out_opt_ IO_STATUS_BLOCK
* iosb
);
1127 BOOL
is_file_name_valid(_In_ PUNICODE_STRING us
, _In_ BOOL posix
);
1128 void send_notification_fileref(_In_ file_ref
* fileref
, _In_ ULONG filter_match
, _In_ ULONG action
, _In_opt_ PUNICODE_STRING stream
);
1129 void send_notification_fcb(_In_ file_ref
* fileref
, _In_ ULONG filter_match
, _In_ ULONG action
, _In_opt_ PUNICODE_STRING stream
);
1131 #ifdef DEBUG_CHUNK_LOCKS
1132 #define acquire_chunk_lock(c, Vcb) { ExAcquireResourceExclusiveLite(&c->lock, TRUE); InterlockedIncrement(&Vcb->chunk_locks_held); }
1133 #define release_chunk_lock(c, Vcb) { InterlockedDecrement(&Vcb->chunk_locks_held); ExReleaseResourceLite(&c->lock); }
1135 #define acquire_chunk_lock(c, Vcb) ExAcquireResourceExclusiveLite(&(c)->lock, TRUE)
1136 #define release_chunk_lock(c, Vcb) ExReleaseResourceLite(&(c)->lock)
1140 WCHAR
* file_desc(_In_ PFILE_OBJECT FileObject
);
1141 WCHAR
* file_desc_fileref(_In_ file_ref
* fileref
);
1142 void mark_fcb_dirty(_In_ fcb
* fcb
);
1143 void mark_fileref_dirty(_In_ file_ref
* fileref
);
1144 NTSTATUS
delete_fileref(_In_ file_ref
* fileref
, _In_opt_ PFILE_OBJECT FileObject
, _In_ BOOL make_orphan
, _In_opt_ PIRP Irp
, _In_ LIST_ENTRY
* rollback
);
1145 void chunk_lock_range(_In_ device_extension
* Vcb
, _In_ chunk
* c
, _In_ UINT64 start
, _In_ UINT64 length
);
1146 void chunk_unlock_range(_In_ device_extension
* Vcb
, _In_ chunk
* c
, _In_ UINT64 start
, _In_ UINT64 length
);
1147 void init_device(_In_ device_extension
* Vcb
, _Inout_ device
* dev
, _In_ BOOL get_nums
);
1148 void init_file_cache(_In_ PFILE_OBJECT FileObject
, _In_ CC_FILE_SIZES
* ccfs
);
1149 NTSTATUS
sync_read_phys(_In_ PDEVICE_OBJECT DeviceObject
, _In_ UINT64 StartingOffset
, _In_ ULONG Length
,
1150 _Out_writes_bytes_(Length
) PUCHAR Buffer
, _In_ BOOL override
);
1151 NTSTATUS
get_device_pnp_name(_In_ PDEVICE_OBJECT DeviceObject
, _Out_ PUNICODE_STRING pnp_name
, _Out_
const GUID
** guid
);
1152 void log_device_error(_In_ device_extension
* Vcb
, _Inout_ device
* dev
, _In_
int error
);
1153 NTSTATUS
find_chunk_usage(_In_
_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_opt_ PIRP Irp
);
1155 NTSTATUS NTAPI
AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT PhysicalDeviceObject
);
1157 NTSTATUS
AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT PhysicalDeviceObject
);
1159 void reap_fcb(fcb
* fcb
);
1160 void reap_fcbs(device_extension
* Vcb
);
1161 void reap_fileref(device_extension
* Vcb
, file_ref
* fr
);
1162 void reap_filerefs(device_extension
* Vcb
, file_ref
* fr
);
1163 UINT64
chunk_estimate_phys_size(device_extension
* Vcb
, chunk
* c
, UINT64 u
);
1166 #define funcname __FUNCTION__
1168 #define funcname __func__
1171 extern BOOL have_sse2
;
1173 extern UINT32 mount_compress
;
1174 extern UINT32 mount_compress_force
;
1175 extern UINT32 mount_compress_type
;
1176 extern UINT32 mount_zlib_level
;
1177 extern UINT32 mount_zstd_level
;
1178 extern UINT32 mount_flush_interval
;
1179 extern UINT32 mount_max_inline
;
1180 extern UINT32 mount_skip_balance
;
1181 extern UINT32 mount_no_barrier
;
1182 extern UINT32 mount_no_trim
;
1183 extern UINT32 mount_clear_cache
;
1184 extern UINT32 mount_allow_degraded
;
1185 extern UINT32 mount_readonly
;
1186 extern UINT32 no_pnp
;
1190 extern BOOL log_started
;
1191 extern UINT32 debug_log_level
;
1193 #ifdef DEBUG_LONG_MESSAGES
1195 #define MSG(fn, file, line, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, file, line, s, ##__VA_ARGS__) : 0
1197 #define TRACE(s, ...) MSG(funcname, __FILE__, __LINE__, s, 3, ##__VA_ARGS__)
1198 #define WARN(s, ...) MSG(funcname, __FILE__, __LINE__, s, 2, ##__VA_ARGS__)
1199 #define FIXME(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__)
1200 #define ERR(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__)
1202 void _debug_message(_In_
const char* func
, _In_
const char* file
, _In_
unsigned int line
, _In_
char* s
, ...);
1206 #define MSG(fn, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, s, ##__VA_ARGS__) : 0
1208 #define TRACE(s, ...) MSG(funcname, s, 3, ##__VA_ARGS__)
1209 #define WARN(s, ...) MSG(funcname, s, 2, ##__VA_ARGS__)
1210 #define FIXME(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__)
1211 #define ERR(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__)
1213 void _debug_message(_In_
const char* func
, _In_
char* s
, ...);
1219 #define TRACE(s, ...)
1220 #define WARN(s, ...)
1221 #define FIXME(s, ...) DbgPrint("Btrfs FIXME : %s : " s, funcname, ##__VA_ARGS__)
1222 #define ERR(s, ...) DbgPrint("Btrfs ERR : %s : " s, funcname, ##__VA_ARGS__)
1226 #ifdef DEBUG_FCB_REFCOUNTS
1227 void _free_fcb(_Inout_ fcb
* fcb
, _In_
const char* func
);
1228 #define free_fcb(fcb) _free_fcb(fcb, funcname)
1232 void init_fast_io_dispatch(FAST_IO_DISPATCH
** fiod
);
1235 UINT32
calc_crc32c(_In_ UINT32 seed
, _In_reads_bytes_(msglen
) UINT8
* msg
, _In_ ULONG msglen
);
1239 LIST_ENTRY
* list_size
;
1250 enum rollback_type
{
1251 ROLLBACK_INSERT_EXTENT
,
1252 ROLLBACK_DELETE_EXTENT
,
1254 ROLLBACK_SUBTRACT_SPACE
1258 enum rollback_type type
;
1260 LIST_ENTRY list_entry
;
1267 LIST_ENTRY list_entry
;
1270 static const char lxuid
[] = "$LXUID";
1271 static const char lxgid
[] = "$LXGID";
1272 static const char lxmod
[] = "$LXMOD";
1273 static const char lxdev
[] = "$LXDEV";
1276 NTSTATUS
find_item(_In_
_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ root
* r
, _Out_ traverse_ptr
* tp
,
1277 _In_
const KEY
* searchkey
, _In_ BOOL ignore
, _In_opt_ PIRP Irp
);
1278 NTSTATUS
find_item_to_level(device_extension
* Vcb
, root
* r
, traverse_ptr
* tp
, const KEY
* searchkey
, BOOL ignore
, UINT8 level
, PIRP Irp
);
1279 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
);
1280 BOOL
find_prev_item(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, const traverse_ptr
* tp
, traverse_ptr
* prev_tp
, PIRP Irp
);
1281 void free_trees(device_extension
* Vcb
);
1282 NTSTATUS
insert_tree_item(_In_
_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _In_ root
* r
, _In_ UINT64 obj_id
,
1283 _In_ UINT8 obj_type
, _In_ UINT64 offset
, _In_reads_bytes_opt_(size
) _When_(return >= 0, __drv_aliasesMem
) void* data
,
1284 _In_ UINT16 size
, _Out_opt_ traverse_ptr
* ptp
, _In_opt_ PIRP Irp
);
1285 NTSTATUS
delete_tree_item(_In_
_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, _Inout_ traverse_ptr
* tp
);
1286 void free_tree(tree
* t
);
1287 NTSTATUS
load_tree(device_extension
* Vcb
, UINT64 addr
, UINT8
* buf
, root
* r
, tree
** pt
);
1288 NTSTATUS
do_load_tree(device_extension
* Vcb
, tree_holder
* th
, root
* r
, tree
* t
, tree_data
* td
, PIRP Irp
);
1289 void clear_rollback(LIST_ENTRY
* rollback
);
1290 void do_rollback(device_extension
* Vcb
, LIST_ENTRY
* rollback
);
1291 void free_trees_root(device_extension
* Vcb
, root
* r
);
1292 void add_rollback(_In_ LIST_ENTRY
* rollback
, _In_
enum rollback_type type
, _In_ __drv_aliasesMem
void* ptr
);
1293 NTSTATUS
commit_batch_list(_Requires_exclusive_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, LIST_ENTRY
* batchlist
, PIRP Irp
);
1294 void clear_batch_list(device_extension
* Vcb
, LIST_ENTRY
* batchlist
);
1295 NTSTATUS
skip_to_difference(device_extension
* Vcb
, traverse_ptr
* tp
, traverse_ptr
* tp2
, BOOL
* ended1
, BOOL
* ended2
);
1298 NTSTATUS
remove_drive_letter(PDEVICE_OBJECT mountmgr
, PUNICODE_STRING devpath
);
1300 _Function_class_(KSTART_ROUTINE
)
1302 void NTAPI
mountmgr_thread(_In_
void* context
);
1304 void mountmgr_thread(_In_
void* context
);
1307 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE
)
1309 NTSTATUS NTAPI
pnp_notification(PVOID NotificationStructure
, PVOID Context
);
1311 NTSTATUS
pnp_notification(PVOID NotificationStructure
, PVOID Context
);
1314 void disk_arrival(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING devpath
);
1315 void volume_arrival(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING devpath
);
1316 void volume_removal(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING devpath
);
1318 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE
)
1320 NTSTATUS NTAPI
volume_notification(PVOID NotificationStructure
, PVOID Context
);
1322 NTSTATUS
volume_notification(PVOID NotificationStructure
, PVOID Context
);
1325 void remove_volume_child(_Inout_
_Requires_exclusive_lock_held_(_Curr_
->child_lock
) _Releases_exclusive_lock_(_Curr_
->child_lock
) _In_ volume_device_extension
* vde
,
1326 _In_ volume_child
* vc
, _In_ BOOL skip_dev
);
1329 NTSTATUS
init_cache();
1331 extern CACHE_MANAGER_CALLBACKS
* cache_callbacks
;
1334 NTSTATUS
write_file(device_extension
* Vcb
, PIRP Irp
, BOOLEAN wait
, BOOLEAN deferred_write
);
1335 NTSTATUS
write_file2(device_extension
* Vcb
, PIRP Irp
, LARGE_INTEGER offset
, void* buf
, ULONG
* length
, BOOLEAN paging_io
, BOOLEAN no_cache
,
1336 BOOLEAN wait
, BOOLEAN deferred_write
, BOOLEAN write_irp
, LIST_ENTRY
* rollback
);
1337 NTSTATUS
truncate_file(fcb
* fcb
, UINT64 end
, PIRP Irp
, LIST_ENTRY
* rollback
);
1338 NTSTATUS
extend_file(fcb
* fcb
, file_ref
* fileref
, UINT64 end
, BOOL prealloc
, PIRP Irp
, LIST_ENTRY
* rollback
);
1339 NTSTATUS
excise_extents(device_extension
* Vcb
, fcb
* fcb
, UINT64 start_data
, UINT64 end_data
, PIRP Irp
, LIST_ENTRY
* rollback
);
1340 chunk
* get_chunk_from_address(device_extension
* Vcb
, UINT64 address
);
1341 NTSTATUS
alloc_chunk(device_extension
* Vcb
, UINT64 flags
, chunk
** pc
, BOOL full_size
);
1342 NTSTATUS
write_data(_In_ device_extension
* Vcb
, _In_ UINT64 address
, _In_reads_bytes_(length
) void* data
, _In_ UINT32 length
, _In_ write_data_context
* wtc
,
1343 _In_opt_ PIRP Irp
, _In_opt_ chunk
* c
, _In_ BOOL file_write
, _In_ UINT64 irp_offset
, _In_ ULONG priority
);
1344 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
);
1345 void free_write_data_stripes(write_data_context
* wtc
);
1347 _Dispatch_type_(IRP_MJ_WRITE
)
1348 _Function_class_(DRIVER_DISPATCH
)
1349 NTSTATUS NTAPI
drv_write(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1351 _Requires_lock_held_(c
->lock
)
1352 _When_(return != 0, _Releases_lock_(c
->lock
))
1353 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
,
1354 _In_opt_ PIRP Irp
, _In_ LIST_ENTRY
* rollback
, _In_ UINT8 compression
, _In_ UINT64 decoded_size
, _In_ BOOL file_write
, _In_ UINT64 irp_offset
);
1356 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
);
1357 NTSTATUS
write_compressed(fcb
* fcb
, UINT64 start_data
, UINT64 end_data
, void* data
, PIRP Irp
, LIST_ENTRY
* rollback
);
1358 BOOL
find_data_address_in_chunk(device_extension
* Vcb
, chunk
* c
, UINT64 length
, UINT64
* address
);
1359 void get_raid56_lock_range(chunk
* c
, UINT64 address
, UINT64 length
, UINT64
* lockaddr
, UINT64
* locklen
);
1360 NTSTATUS
calc_csum(_In_ device_extension
* Vcb
, _In_reads_bytes_(sectors
*Vcb
->superblock
.sector_size
) UINT8
* data
,
1361 _In_ UINT32 sectors
, _Out_writes_bytes_(sectors
*sizeof(UINT32
)) UINT32
* csum
);
1362 void add_insert_extent_rollback(LIST_ENTRY
* rollback
, fcb
* fcb
, extent
* ext
);
1363 NTSTATUS
add_extent_to_fcb(_In_ fcb
* fcb
, _In_ UINT64 offset
, _In_reads_bytes_(edsize
) EXTENT_DATA
* ed
, _In_ UINT16 edsize
,
1364 _In_ BOOL unique
, _In_opt_
_When_(return >= 0, __drv_aliasesMem
) UINT32
* csum
, _In_ LIST_ENTRY
* rollback
);
1365 void add_extent(_In_ fcb
* fcb
, _In_ LIST_ENTRY
* prevextle
, _In_ __drv_aliasesMem extent
* newext
);
1369 _Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL
)
1370 _Function_class_(DRIVER_DISPATCH
)
1371 NTSTATUS NTAPI
drv_directory_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1373 ULONG
get_reparse_tag(device_extension
* Vcb
, root
* subvol
, UINT64 inode
, UINT8 type
, ULONG atts
, BOOL lxss
, PIRP Irp
);
1374 ULONG
get_reparse_tag_fcb(fcb
* fcb
);
1378 _Dispatch_type_(IRP_MJ_QUERY_SECURITY
)
1379 _Function_class_(DRIVER_DISPATCH
)
1380 NTSTATUS NTAPI
drv_query_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1382 _Dispatch_type_(IRP_MJ_SET_SECURITY
)
1383 _Function_class_(DRIVER_DISPATCH
)
1384 NTSTATUS NTAPI
drv_set_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1386 void fcb_get_sd(fcb
* fcb
, struct _fcb
* parent
, BOOL look_for_xattr
, PIRP Irp
);
1387 void add_user_mapping(WCHAR
* sidstring
, ULONG sidstringlength
, UINT32 uid
);
1388 void add_group_mapping(WCHAR
* sidstring
, ULONG sidstringlength
, UINT32 gid
);
1389 UINT32
sid_to_uid(PSID sid
);
1390 NTSTATUS
uid_to_sid(UINT32 uid
, PSID
* sid
);
1391 NTSTATUS
fcb_get_new_sd(fcb
* fcb
, file_ref
* parfileref
, ACCESS_STATE
* as
);
1392 void find_gid(struct _fcb
* fcb
, struct _fcb
* parfcb
, PSECURITY_SUBJECT_CONTEXT subjcont
);
1396 _Dispatch_type_(IRP_MJ_SET_INFORMATION
)
1397 _Function_class_(DRIVER_DISPATCH
)
1398 NTSTATUS NTAPI
drv_set_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1400 _Dispatch_type_(IRP_MJ_QUERY_INFORMATION
)
1401 _Function_class_(DRIVER_DISPATCH
)
1402 NTSTATUS NTAPI
drv_query_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1404 _Dispatch_type_(IRP_MJ_QUERY_EA
)
1405 _Function_class_(DRIVER_DISPATCH
)
1406 NTSTATUS NTAPI
drv_query_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1408 _Dispatch_type_(IRP_MJ_SET_EA
)
1409 _Function_class_(DRIVER_DISPATCH
)
1410 NTSTATUS NTAPI
drv_set_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1412 BOOL
has_open_children(file_ref
* fileref
);
1413 NTSTATUS
stream_set_end_of_file_information(device_extension
* Vcb
, UINT16 end
, fcb
* fcb
, file_ref
* fileref
, BOOL advance_only
);
1414 NTSTATUS
fileref_get_filename(file_ref
* fileref
, PUNICODE_STRING fn
, USHORT
* name_offset
, ULONG
* preqlen
);
1415 void insert_dir_child_into_hash_lists(fcb
* fcb
, dir_child
* dc
);
1416 void remove_dir_child_from_hash_lists(fcb
* fcb
, dir_child
* dc
);
1419 NTSTATUS
get_reparse_point(PDEVICE_OBJECT DeviceObject
, PFILE_OBJECT FileObject
, void* buffer
, DWORD buflen
, ULONG_PTR
* retlen
);
1420 NTSTATUS
set_reparse_point2(fcb
* fcb
, REPARSE_DATA_BUFFER
* rdb
, ULONG buflen
, ccb
* ccb
, file_ref
* fileref
, PIRP Irp
, LIST_ENTRY
* rollback
);
1421 NTSTATUS
set_reparse_point(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1422 NTSTATUS
delete_reparse_point(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1426 _Dispatch_type_(IRP_MJ_CREATE
)
1427 _Function_class_(DRIVER_DISPATCH
)
1428 NTSTATUS NTAPI
drv_create(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1430 NTSTATUS
open_fileref(_Requires_lock_held_(_Curr_
->tree_lock
) _Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) _In_ device_extension
* Vcb
, _Out_ file_ref
** pfr
,
1431 _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
,
1432 _In_ BOOL case_sensitive
, _In_opt_ PIRP Irp
);
1433 NTSTATUS
open_fcb(_Requires_lock_held_(_Curr_
->tree_lock
) _Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) device_extension
* Vcb
,
1434 root
* subvol
, UINT64 inode
, UINT8 type
, PANSI_STRING utf8
, BOOL always_add_hl
, fcb
* parent
, fcb
** pfcb
, POOL_TYPE pooltype
, PIRP Irp
);
1435 NTSTATUS
load_csum(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, UINT32
* csum
, UINT64 start
, UINT64 length
, PIRP Irp
);
1436 NTSTATUS
load_dir_children(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
, fcb
* fcb
, BOOL ignore_size
, PIRP Irp
);
1437 NTSTATUS
add_dir_child(fcb
* fcb
, UINT64 inode
, BOOL subvol
, PANSI_STRING utf8
, PUNICODE_STRING name
, UINT8 type
, dir_child
** pdc
);
1438 NTSTATUS
open_fileref_child(_Requires_lock_held_(_Curr_
->tree_lock
) _Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) _In_ device_extension
* Vcb
,
1439 _In_ file_ref
* sf
, _In_ PUNICODE_STRING name
, _In_ BOOL case_sensitive
, _In_ BOOL lastpart
, _In_ BOOL streampart
,
1440 _In_ POOL_TYPE pooltype
, _Out_ file_ref
** psf2
, _In_opt_ PIRP Irp
);
1441 fcb
* create_fcb(device_extension
* Vcb
, POOL_TYPE pool_type
);
1442 NTSTATUS
find_file_in_dir(PUNICODE_STRING filename
, fcb
* fcb
, root
** subvol
, UINT64
* inode
, dir_child
** pdc
, BOOL case_sensitive
);
1443 UINT32
inherit_mode(fcb
* parfcb
, BOOL is_dir
);
1444 file_ref
* create_fileref(device_extension
* Vcb
);
1445 NTSTATUS
open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_
->fcb_lock
) device_extension
* Vcb
, root
* subvol
, UINT64 inode
, file_ref
** pfr
, PIRP Irp
);
1448 NTSTATUS
fsctl_request(PDEVICE_OBJECT DeviceObject
, PIRP
* Pirp
, UINT32 type
);
1449 void do_unlock_volume(device_extension
* Vcb
);
1450 void trim_whole_device(device
* dev
);
1451 void flush_subvol_fcbs(root
* subvol
);
1452 BOOL
fcb_is_inline(fcb
* fcb
);
1456 _Function_class_(KSTART_ROUTINE
)
1458 void NTAPI
flush_thread(void* context
);
1460 void flush_thread(void* context
);
1463 NTSTATUS
do_write(device_extension
* Vcb
, PIRP Irp
);
1464 NTSTATUS
get_tree_new_address(device_extension
* Vcb
, tree
* t
, PIRP Irp
, LIST_ENTRY
* rollback
);
1465 NTSTATUS
flush_fcb(fcb
* fcb
, BOOL cache
, LIST_ENTRY
* batchlist
, PIRP Irp
);
1466 NTSTATUS
write_data_phys(_In_ PDEVICE_OBJECT device
, _In_ UINT64 address
, _In_reads_bytes_(length
) void* data
, _In_ UINT32 length
);
1467 BOOL
is_tree_unique(device_extension
* Vcb
, tree
* t
, PIRP Irp
);
1468 NTSTATUS
do_tree_writes(device_extension
* Vcb
, LIST_ENTRY
* tree_writes
, BOOL no_free
);
1469 void add_checksum_entry(device_extension
* Vcb
, UINT64 address
, ULONG length
, UINT32
* csum
, PIRP Irp
);
1470 BOOL
find_metadata_address_in_chunk(device_extension
* Vcb
, chunk
* c
, UINT64
* address
);
1471 void add_trim_entry_avoid_sb(device_extension
* Vcb
, device
* dev
, UINT64 address
, UINT64 size
);
1472 NTSTATUS
insert_tree_item_batch(LIST_ENTRY
* batchlist
, device_extension
* Vcb
, root
* r
, UINT64 objid
, UINT8 objtype
, UINT64 offset
,
1473 _In_opt_
_When_(return >= 0, __drv_aliasesMem
) void* data
, UINT16 datalen
, enum batch_operation operation
);
1474 NTSTATUS
flush_partial_stripe(device_extension
* Vcb
, chunk
* c
, partial_stripe
* ps
);
1475 NTSTATUS
update_dev_item(device_extension
* Vcb
, device
* device
, PIRP Irp
);
1479 _Dispatch_type_(IRP_MJ_READ
)
1480 _Function_class_(DRIVER_DISPATCH
)
1481 NTSTATUS NTAPI
drv_read(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1483 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
,
1484 _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
,
1485 _In_ ULONG priority
);
1486 NTSTATUS
read_file(fcb
* fcb
, UINT8
* data
, UINT64 start
, UINT64 length
, ULONG
* pbr
, PIRP Irp
);
1487 NTSTATUS
read_stream(fcb
* fcb
, UINT8
* data
, UINT64 start
, ULONG length
, ULONG
* pbr
);
1488 NTSTATUS
do_read(PIRP Irp
, BOOLEAN wait
, ULONG
* bytes_read
);
1489 NTSTATUS
check_csum(device_extension
* Vcb
, UINT8
* data
, UINT32 sectors
, UINT32
* csum
);
1490 void raid6_recover2(UINT8
* sectors
, UINT16 num_stripes
, ULONG sector_size
, UINT16 missing1
, UINT16 missing2
, UINT8
* out
);
1494 _Dispatch_type_(IRP_MJ_PNP
)
1495 _Function_class_(DRIVER_DISPATCH
)
1496 NTSTATUS NTAPI
drv_pnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1498 NTSTATUS
pnp_surprise_removal(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1499 NTSTATUS
pnp_query_remove_device(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
1502 NTSTATUS
load_cache_chunk(device_extension
* Vcb
, chunk
* c
, PIRP Irp
);
1503 NTSTATUS
clear_free_space_cache(device_extension
* Vcb
, LIST_ENTRY
* batchlist
, PIRP Irp
);
1504 NTSTATUS
allocate_cache(device_extension
* Vcb
, BOOL
* changed
, PIRP Irp
, LIST_ENTRY
* rollback
);
1505 NTSTATUS
update_chunk_caches(device_extension
* Vcb
, PIRP Irp
, LIST_ENTRY
* rollback
);
1506 NTSTATUS
update_chunk_caches_tree(device_extension
* Vcb
, PIRP Irp
);
1507 NTSTATUS
add_space_entry(LIST_ENTRY
* list
, LIST_ENTRY
* list_size
, UINT64 offset
, UINT64 size
);
1508 void space_list_add(chunk
* c
, UINT64 address
, UINT64 length
, LIST_ENTRY
* rollback
);
1509 void space_list_add2(LIST_ENTRY
* list
, LIST_ENTRY
* list_size
, UINT64 address
, UINT64 length
, chunk
* c
, LIST_ENTRY
* rollback
);
1510 void space_list_subtract(chunk
* c
, BOOL deleting
, UINT64 address
, UINT64 length
, LIST_ENTRY
* rollback
);
1511 void space_list_subtract2(LIST_ENTRY
* list
, LIST_ENTRY
* list_size
, UINT64 address
, UINT64 length
, chunk
* c
, LIST_ENTRY
* rollback
);
1512 NTSTATUS
load_stored_free_space_cache(device_extension
* Vcb
, chunk
* c
, BOOL load_only
, PIRP Irp
);
1515 NTSTATUS
increase_extent_refcount_data(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 inode
, UINT64 offset
, UINT32 refcount
, PIRP Irp
);
1516 NTSTATUS
decrease_extent_refcount_data(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 inode
, UINT64 offset
,
1517 UINT32 refcount
, BOOL superseded
, PIRP Irp
);
1518 NTSTATUS
decrease_extent_refcount_tree(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT64 root
, UINT8 level
, PIRP Irp
);
1519 UINT64
get_extent_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 size
, PIRP Irp
);
1520 BOOL
is_extent_unique(device_extension
* Vcb
, UINT64 address
, UINT64 size
, PIRP Irp
);
1521 NTSTATUS
increase_extent_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT8 type
, void* data
, KEY
* firstitem
, UINT8 level
, PIRP Irp
);
1522 UINT64
get_extent_flags(device_extension
* Vcb
, UINT64 address
, PIRP Irp
);
1523 void update_extent_flags(device_extension
* Vcb
, UINT64 address
, UINT64 flags
, PIRP Irp
);
1524 NTSTATUS
update_changed_extent_ref(device_extension
* Vcb
, chunk
* c
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 objid
, UINT64 offset
,
1525 INT32 count
, BOOL no_csum
, BOOL superseded
, PIRP Irp
);
1526 void add_changed_extent_ref(chunk
* c
, UINT64 address
, UINT64 size
, UINT64 root
, UINT64 objid
, UINT64 offset
, UINT32 count
, BOOL no_csum
);
1527 UINT64
find_extent_shared_tree_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 parent
, PIRP Irp
);
1528 UINT32
find_extent_shared_data_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 parent
, PIRP Irp
);
1529 NTSTATUS
decrease_extent_refcount(device_extension
* Vcb
, UINT64 address
, UINT64 size
, UINT8 type
, void* data
, KEY
* firstitem
,
1530 UINT8 level
, UINT64 parent
, BOOL superseded
, PIRP Irp
);
1531 UINT64
get_extent_data_ref_hash2(UINT64 root
, UINT64 objid
, UINT64 offset
);
1533 // in worker-thread.c
1534 void do_read_job(PIRP Irp
);
1535 void do_write_job(device_extension
* Vcb
, PIRP Irp
);
1536 BOOL
add_thread_job(device_extension
* Vcb
, PIRP Irp
);
1539 void read_registry(PUNICODE_STRING regpath
, BOOL refresh
);
1540 NTSTATUS
registry_mark_volume_mounted(BTRFS_UUID
* uuid
);
1541 NTSTATUS
registry_mark_volume_unmounted(BTRFS_UUID
* uuid
);
1542 NTSTATUS
registry_load_volume_options(device_extension
* Vcb
);
1543 void watch_registry(HANDLE regh
);
1546 NTSTATUS
zlib_decompress(UINT8
* inbuf
, UINT32 inlen
, UINT8
* outbuf
, UINT32 outlen
);
1547 NTSTATUS
lzo_decompress(UINT8
* inbuf
, UINT32 inlen
, UINT8
* outbuf
, UINT32 outlen
, UINT32 inpageoff
);
1548 NTSTATUS
zstd_decompress(UINT8
* inbuf
, UINT32 inlen
, UINT8
* outbuf
, UINT32 outlen
);
1549 NTSTATUS
write_compressed_bit(fcb
* fcb
, UINT64 start_data
, UINT64 end_data
, void* data
, BOOL
* compressed
, PIRP Irp
, LIST_ENTRY
* rollback
);
1552 void galois_double(UINT8
* data
, UINT32 len
);
1553 void galois_divpower(UINT8
* data
, UINT8 div
, UINT32 readlen
);
1554 UINT8
gpow2(UINT8 e
);
1555 UINT8
gmul(UINT8 a
, UINT8 b
);
1556 UINT8
gdiv(UINT8 a
, UINT8 b
);
1560 _Dispatch_type_(IRP_MJ_DEVICE_CONTROL
)
1561 _Function_class_(DRIVER_DISPATCH
)
1562 NTSTATUS NTAPI
drv_device_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1566 _Function_class_(KSTART_ROUTINE
)
1568 void NTAPI
calc_thread(void* context
);
1570 void calc_thread(void* context
);
1573 NTSTATUS
add_calc_job(device_extension
* Vcb
, UINT8
* data
, UINT32 sectors
, UINT32
* csum
, calc_job
** pcj
);
1574 void free_calc_job(calc_job
* cj
);
1577 NTSTATUS
start_balance(device_extension
* Vcb
, void* data
, ULONG length
, KPROCESSOR_MODE processor_mode
);
1578 NTSTATUS
query_balance(device_extension
* Vcb
, void* data
, ULONG length
);
1579 NTSTATUS
pause_balance(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1580 NTSTATUS
resume_balance(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1581 NTSTATUS
stop_balance(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1582 NTSTATUS
look_for_balance_item(_Requires_lock_held_(_Curr_
->tree_lock
) device_extension
* Vcb
);
1583 NTSTATUS
remove_device(device_extension
* Vcb
, void* data
, ULONG length
, KPROCESSOR_MODE processor_mode
);
1585 _Function_class_(KSTART_ROUTINE
)
1587 void NTAPI
balance_thread(void* context
);
1589 void balance_thread(void* context
);
1593 NTSTATUS
vol_create(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1594 NTSTATUS
vol_close(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1595 NTSTATUS
vol_read(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1596 NTSTATUS
vol_write(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1597 NTSTATUS
vol_query_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1598 NTSTATUS
vol_set_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1599 NTSTATUS
vol_query_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1600 NTSTATUS
vol_set_ea(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1601 NTSTATUS
vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1602 NTSTATUS
vol_query_volume_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1603 NTSTATUS
vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1604 NTSTATUS
vol_cleanup(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1605 NTSTATUS
vol_directory_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1606 NTSTATUS
vol_file_system_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1607 NTSTATUS
vol_lock_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1608 NTSTATUS
vol_device_control(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1609 NTSTATUS
vol_shutdown(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1610 NTSTATUS
vol_query_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1611 NTSTATUS
vol_set_security(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1612 NTSTATUS
vol_power(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
1613 void add_volume_device(superblock
* sb
, PDEVICE_OBJECT mountmgr
, PUNICODE_STRING devpath
, UINT64 length
, ULONG disk_num
, ULONG part_num
);
1614 NTSTATUS
mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr
, PUNICODE_STRING devpath
);
1616 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE
)
1618 NTSTATUS NTAPI
pnp_removal(PVOID NotificationStructure
, PVOID Context
);
1620 NTSTATUS
pnp_removal(PVOID NotificationStructure
, PVOID Context
);
1624 NTSTATUS
start_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1625 NTSTATUS
query_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
, void* data
, ULONG length
);
1626 NTSTATUS
pause_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1627 NTSTATUS
resume_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1628 NTSTATUS
stop_scrub(device_extension
* Vcb
, KPROCESSOR_MODE processor_mode
);
1631 NTSTATUS
send_subvol(device_extension
* Vcb
, void* data
, ULONG datalen
, PFILE_OBJECT FileObject
, PIRP Irp
);
1632 NTSTATUS
read_send_buffer(device_extension
* Vcb
, PFILE_OBJECT FileObject
, void* data
, ULONG datalen
, ULONG_PTR
* retlen
, KPROCESSOR_MODE processor_mode
);
1634 // based on function in sys/sysmacros.h
1635 #define makedev(major, minor) (((minor) & 0xFF) | (((major) & 0xFFF) << 8) | (((UINT64)((minor) & ~0xFF)) << 12) | (((UINT64)((major) & ~0xFFF)) << 32))
1637 #define fast_io_possible(fcb) (!FsRtlAreThereCurrentFileLocks(&fcb->lock) && !fcb->Vcb->readonly ? FastIoIsPossible : FastIoIsQuestionable)
1639 static __inline
void print_open_trees(device_extension
* Vcb
) {
1640 LIST_ENTRY
* le
= Vcb
->trees
.Flink
;
1641 while (le
!= &Vcb
->trees
) {
1642 tree
* t
= CONTAINING_RECORD(le
, tree
, list_entry
);
1643 tree_data
* td
= CONTAINING_RECORD(t
->itemlist
.Flink
, tree_data
, list_entry
);
1644 ERR("tree %p: root %llx, level %u, first key (%llx,%x,%llx)\n",
1645 t
, t
->root
->id
, t
->header
.level
, td
->key
.obj_id
, td
->key
.obj_type
, td
->key
.offset
);
1651 static __inline BOOL
write_fcb_compressed(fcb
* fcb
) {
1652 // make sure we don't accidentally write the cache inodes or pagefile compressed
1653 if (fcb
->subvol
->id
== BTRFS_ROOT_ROOT
|| fcb
->Header
.Flags2
& FSRTL_FLAG2_IS_PAGING_FILE
)
1656 if (fcb
->Vcb
->options
.compress_force
)
1659 if (fcb
->inode_item
.flags
& BTRFS_INODE_NOCOMPRESS
)
1662 if (fcb
->inode_item
.flags
& BTRFS_INODE_COMPRESS
|| fcb
->Vcb
->options
.compress
)
1668 static __inline
void do_xor(UINT8
* buf1
, UINT8
* buf2
, UINT32 len
) {
1675 if (have_sse2
&& ((uintptr_t)buf1
& 0xf) == 0 && ((uintptr_t)buf2
& 0xf) == 0) {
1677 x1
= _mm_load_si128((__m128i
*)buf1
);
1678 x2
= _mm_load_si128((__m128i
*)buf2
);
1679 x1
= _mm_xor_si128(x1
, x2
);
1680 _mm_store_si128((__m128i
*)buf1
, x1
);
1689 for (j
= 0; j
< len
; j
++) {
1696 #ifdef DEBUG_FCB_REFCOUNTS
1697 #ifdef DEBUG_LONG_MESSAGES
1698 #define increase_fileref_refcount(fileref) {\
1699 LONG rc = InterlockedIncrement(&fileref->refcount);\
1700 MSG(funcname, __FILE__, __LINE__, "fileref %p: refcount now %i\n", 1, fileref, rc);\
1703 #define increase_fileref_refcount(fileref) {\
1704 LONG rc = InterlockedIncrement(&fileref->refcount);\
1705 MSG(funcname, "fileref %p: refcount now %i\n", 1, fileref, rc);\
1709 #define increase_fileref_refcount(fileref) InterlockedIncrement(&fileref->refcount)
1713 #define int3 __debugbreak()
1715 #define int3 asm("int3;")
1718 #define hex_digit(c) ((c) <= 9) ? ((c) + '0') : ((c) - 10 + 'a')
1720 // FIXME - find a way to catch unfreed trees again
1723 #define __S_IFMT 0170000 /* These bits determine file type. */
1724 #define __S_IFDIR 0040000 /* Directory. */
1725 #define __S_IFCHR 0020000 /* Character device. */
1726 #define __S_IFBLK 0060000 /* Block device. */
1727 #define __S_IFREG 0100000 /* Regular file. */
1728 #define __S_IFIFO 0010000 /* FIFO. */
1729 #define __S_IFLNK 0120000 /* Symbolic link. */
1730 #define __S_IFSOCK 0140000 /* Socket. */
1731 #define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask))
1734 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
1738 #define S_IRUSR 0000400
1742 #define S_IWUSR 0000200
1746 #define S_IXUSR 0000100
1750 #define S_IFDIR __S_IFDIR
1751 #define S_IFREG __S_IFREG
1752 #endif /* __REACTOS__ */
1755 #define S_IRGRP (S_IRUSR >> 3)
1759 #define S_IWGRP (S_IWUSR >> 3)
1763 #define S_IXGRP (S_IXUSR >> 3)
1767 #define S_IROTH (S_IRGRP >> 3)
1771 #define S_IWOTH (S_IWGRP >> 3)
1775 #define S_IXOTH (S_IXGRP >> 3)
1779 #define S_ISUID 0004000
1783 #define S_ISGID 0002000
1787 #define S_ISVTX 0001000
1790 // based on functions in sys/sysmacros.h
1791 #define major(rdev) ((((rdev) >> 8) & 0xFFF) | ((UINT32)((rdev) >> 32) & ~0xFFF))
1792 #define minor(rdev) (((rdev) & 0xFF) | ((UINT32)((rdev) >> 12) & ~0xFF))
1794 static __inline UINT64
fcb_alloc_size(fcb
* fcb
) {
1795 if (S_ISDIR(fcb
->inode_item
.st_mode
))
1797 else if (fcb
->atts
& FILE_ATTRIBUTE_SPARSE_FILE
)
1798 return fcb
->inode_item
.st_blocks
;
1800 return sector_align(fcb
->inode_item
.st_size
, fcb
->Vcb
->superblock
.sector_size
);
1803 typedef BOOLEAN (*tPsIsDiskCountersEnabled
)();
1805 typedef VOID (*tPsUpdateDiskCounters
)(PEPROCESS Process
, ULONG64 BytesRead
, ULONG64 BytesWritten
,
1806 ULONG ReadOperationCount
, ULONG WriteOperationCount
, ULONG FlushOperationCount
);
1808 typedef BOOLEAN (*tCcCopyWriteEx
)(PFILE_OBJECT FileObject
, PLARGE_INTEGER FileOffset
, ULONG Length
, BOOLEAN Wait
,
1809 PVOID Buffer
, PETHREAD IoIssuerThread
);
1811 typedef BOOLEAN (*tCcCopyReadEx
)(PFILE_OBJECT FileObject
, PLARGE_INTEGER FileOffset
, ULONG Length
, BOOLEAN Wait
,
1812 PVOID Buffer
, PIO_STATUS_BLOCK IoStatus
, PETHREAD IoIssuerThread
);
1814 #ifndef CC_ENABLE_DISK_IO_ACCOUNTING
1815 #define CC_ENABLE_DISK_IO_ACCOUNTING 0x00000010
1818 typedef VOID (*tCcSetAdditionalCacheAttributesEx
)(PFILE_OBJECT FileObject
, ULONG Flags
);
1820 typedef VOID (*tFsRtlUpdateDiskCounters
)(ULONG64 BytesRead
, ULONG64 BytesWritten
);
1825 #undef RtlIsNtDdiVersionAvailable
1827 BOOLEAN
RtlIsNtDdiVersionAvailable(ULONG Version
);
1829 PEPROCESS
PsGetThreadProcess(_In_ PETHREAD Thread
); // not in mingw
1832 // not in DDK headers - taken from winternl.h
1833 typedef struct _LDR_DATA_TABLE_ENTRY
{
1835 LIST_ENTRY InMemoryOrderLinks
;
1839 UNICODE_STRING FullDllName
;
1846 ULONG TimeDateStamp
;
1847 } LDR_DATA_TABLE_ENTRY
,*PLDR_DATA_TABLE_ENTRY
;
1849 typedef struct _PEB_LDR_DATA
{
1852 LIST_ENTRY InMemoryOrderModuleList
;
1853 } PEB_LDR_DATA
,*PPEB_LDR_DATA
;
1855 typedef struct _RTL_USER_PROCESS_PARAMETERS
{
1857 PVOID Reserved2
[10];
1858 UNICODE_STRING ImagePathName
;
1859 UNICODE_STRING CommandLine
;
1860 } RTL_USER_PROCESS_PARAMETERS
,*PRTL_USER_PROCESS_PARAMETERS
;
1862 typedef VOID (NTAPI
*PPS_POST_PROCESS_INIT_ROUTINE
)(VOID
);
1864 typedef struct _PEB
{
1870 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
;
1871 BYTE Reserved4
[104];
1872 PVOID Reserved5
[52];
1873 PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine
;
1874 BYTE Reserved6
[128];
1881 NTSTATUS NTAPI
ZwQueryInformationProcess(
1882 IN HANDLE ProcessHandle
,
1883 IN PROCESSINFOCLASS ProcessInformationClass
,
1884 OUT PVOID ProcessInformation
,
1885 IN ULONG ProcessInformationLength
,
1886 OUT PULONG ReturnLength OPTIONAL
1891 #if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_VISTA)
1892 typedef struct _ECP_LIST ECP_LIST
;
1893 typedef struct _ECP_LIST
*PECP_LIST
;
1896 #if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7)
1897 NTSTATUS WINAPI
RtlUnicodeToUTF8N(CHAR
*utf8_dest
, ULONG utf8_bytes_max
,
1898 ULONG
*utf8_bytes_written
,
1899 const WCHAR
*uni_src
, ULONG uni_bytes
);
1900 NTSTATUS WINAPI
RtlUTF8ToUnicodeN(WCHAR
*uni_dest
, ULONG uni_bytes_max
,
1901 ULONG
*uni_bytes_written
,
1902 const CHAR
*utf8_src
, ULONG utf8_bytes
);
1903 #endif /* defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7) */
1904 #if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_VISTA)
1905 NTSTATUS NTAPI
FsRtlRemoveDotsFromPath(PWSTR OriginalString
,
1906 USHORT PathLength
, USHORT
*NewLength
);
1907 NTSTATUS NTAPI
FsRtlValidateReparsePointBuffer(ULONG BufferLength
,
1908 PREPARSE_DATA_BUFFER ReparseBuffer
);
1909 ULONG NTAPI
KeQueryActiveProcessorCount(PKAFFINITY ActiveProcessors
);
1910 NTSTATUS NTAPI
FsRtlGetEcpListFromIrp(IN PIRP Irp
,
1911 OUT PECP_LIST
*EcpList
);
1912 NTSTATUS NTAPI
FsRtlGetNextExtraCreateParameter(IN PECP_LIST EcpList
,
1913 IN PVOID CurrentEcpContext
,
1914 OUT LPGUID NextEcpType OPTIONAL
,
1915 OUT PVOID
*NextEcpContext
,
1916 OUT PULONG NextEcpContextSize OPTIONAL
);
1917 #endif /* defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_VISTA) */