ReactOS 0.4.15-dev-7842-g558ab78
registry.c File Reference
#include "btrfs_drv.h"
#include "zstd/zstd.h"
Include dependency graph for registry.c:

Go to the source code of this file.

Classes

struct  key_name
 

Macros

#define is_hex(c)   ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
 

Functions

NTSTATUS registry_load_volume_options (device_extension *Vcb)
 
NTSTATUS registry_mark_volume_mounted (BTRFS_UUID *uuid)
 
static NTSTATUS registry_mark_volume_unmounted_path (PUNICODE_STRING path)
 
NTSTATUS registry_mark_volume_unmounted (BTRFS_UUID *uuid)
 
static bool is_uuid (ULONG namelen, WCHAR *name)
 
static void reset_subkeys (HANDLE h, PUNICODE_STRING reg_path)
 
static void read_mappings (PUNICODE_STRING regpath)
 
static void read_group_mappings (PUNICODE_STRING regpath)
 
static void get_registry_value (HANDLE h, WCHAR *string, ULONG type, void *val, ULONG size)
 
void read_registry (PUNICODE_STRING regpath, bool refresh)
 
 _Function_class_ (WORKER_THREAD_ROUTINE)
 
void watch_registry (HANDLE regh)
 

Variables

UNICODE_STRING log_device
 
UNICODE_STRING log_file
 
UNICODE_STRING registry_path
 
LIST_ENTRY uid_map_list
 
LIST_ENTRY gid_map_list
 
ERESOURCE mapping_lock
 
WORK_QUEUE_ITEM wqi
 
static const WCHAR option_mounted [] = L"Mounted"
 

Macro Definition Documentation

◆ is_hex

#define is_hex (   c)    ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))

Definition at line 430 of file registry.c.

Function Documentation

◆ _Function_class_()

_Function_class_ ( WORKER_THREAD_ROUTINE  )

Definition at line 1021 of file registry.c.

1022 {
1024 HANDLE regh = (HANDLE)Parameter;
1026
1027 TRACE("registry changed\n");
1028
1030
1031 Status = ZwNotifyChangeKey(regh, NULL, (PVOID)&wqi, (PVOID)DelayedWorkQueue, &iosb, REG_NOTIFY_CHANGE_LAST_SET, true, NULL, 0, true);
1032 if (!NT_SUCCESS(Status))
1033 ERR("ZwNotifyChangeKey returned %08lx\n", Status);
1034}
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UNICODE_STRING registry_path
Definition: registry.c:21
WORK_QUEUE_ITEM wqi
Definition: registry.c:32
void read_registry(PUNICODE_STRING regpath, bool refresh)
Definition: registry.c:777
Status
Definition: gdiplustypes.h:25
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#define TRACE(s)
Definition: solgame.cpp:4
PVOID HANDLE
Definition: typedefs.h:73
#define REG_NOTIFY_CHANGE_LAST_SET
Definition: winreg.h:40
@ DelayedWorkQueue
Definition: extypes.h:190
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

◆ get_registry_value()

static void get_registry_value ( HANDLE  h,
WCHAR string,
ULONG  type,
void val,
ULONG  size 
)
static

Definition at line 726 of file registry.c.

726 {
727 ULONG kvfilen;
731
732 RtlInitUnicodeString(&us, string);
733
734 kvfi = NULL;
735 kvfilen = 0;
736 Status = ZwQueryValueKey(h, &us, KeyValueFullInformation, kvfi, kvfilen, &kvfilen);
737
738 if ((Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW) && kvfilen > 0) {
739 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
740
741 if (!kvfi) {
742 ERR("out of memory\n");
743 ZwClose(h);
744 return;
745 }
746
747 Status = ZwQueryValueKey(h, &us, KeyValueFullInformation, kvfi, kvfilen, &kvfilen);
748
749 if (NT_SUCCESS(Status)) {
750 if (kvfi->Type == type && kvfi->DataLength >= size) {
751 RtlCopyMemory(val, ((uint8_t*)kvfi) + kvfi->DataOffset, size);
752 } else {
754 if (!NT_SUCCESS(Status)) {
755 ERR("ZwDeleteValueKey returned %08lx\n", Status);
756 }
757
758 Status = ZwSetValueKey(h, &us, 0, type, val, size);
759 if (!NT_SUCCESS(Status)) {
760 ERR("ZwSetValueKey returned %08lx\n", Status);
761 }
762 }
763 }
764
765 ExFreePool(kvfi);
766 } else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
767 Status = ZwSetValueKey(h, &us, 0, type, val, size);
768
769 if (!NT_SUCCESS(Status)) {
770 ERR("ZwSetValueKey returned %08lx\n", Status);
771 }
772 } else {
773 ERR("ZwQueryValueKey returned %08lx\n", Status);
774 }
775}
#define ALLOC_TAG
Definition: btrfs_drv.h:87
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
NTSYSAPI NTSTATUS NTAPI ZwDeleteValueKey(__in IN HANDLE Key, __in IN PUNICODE_STRING ValueName)
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
static const BYTE us[]
Definition: encode.c:689
BYTE uint8_t
Definition: msvideo1.c:66
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValueFullInformation
Definition: nt_native.h:1181
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by read_registry().

◆ is_uuid()

static bool is_uuid ( ULONG  namelen,
WCHAR name 
)
static

Definition at line 432 of file registry.c.

432 {
433 ULONG i;
434
435 if (namelen != 36 * sizeof(WCHAR))
436 return false;
437
438 for (i = 0; i < 36; i++) {
439 if (i == 8 || i == 13 || i == 18 || i == 23) {
440 if (name[i] != '-')
441 return false;
442 } else if (!is_hex(name[i]))
443 return false;
444 }
445
446 return true;
447}
#define is_hex(c)
Definition: registry.c:430
GLint namelen
Definition: glext.h:7232
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: name.c:39
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by reset_subkeys().

◆ read_group_mappings()

static void read_group_mappings ( PUNICODE_STRING  regpath)
static

Definition at line 622 of file registry.c.

622 {
623 WCHAR* path;
625 HANDLE h;
629
630 static const WCHAR mappings[] = L"\\GroupMappings";
631
632 while (!IsListEmpty(&gid_map_list)) {
634
635 if (gm->sid) ExFreePool(gm->sid);
636 ExFreePool(gm);
637 }
638
639 path = ExAllocatePoolWithTag(PagedPool, regpath->Length + sizeof(mappings) - sizeof(WCHAR), ALLOC_TAG);
640 if (!path) {
641 ERR("out of memory\n");
642 return;
643 }
644
645 RtlCopyMemory(path, regpath->Buffer, regpath->Length);
646 RtlCopyMemory((uint8_t*)path + regpath->Length, mappings, sizeof(mappings) - sizeof(WCHAR));
647
648 us.Buffer = path;
649 us.Length = us.MaximumLength = regpath->Length + sizeof(mappings) - sizeof(WCHAR);
650
652
653 Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
654
655 if (!NT_SUCCESS(Status)) {
656 ERR("ZwCreateKey returned %08lx\n", Status);
658 return;
659 }
660
662
665 ULONG kvfilen, retlen, i;
666
667 kvfilen = sizeof(KEY_VALUE_FULL_INFORMATION) + 256;
668 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
669
670 if (!kvfi) {
671 ERR("out of memory\n");
672 ZwClose(h);
673 return;
674 }
675
676 i = 0;
677 do {
678 Status = ZwEnumerateValueKey(h, i, KeyValueFullInformation, kvfi, kvfilen, &retlen);
679
680 if (NT_SUCCESS(Status) && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
681 uint32_t val = 0;
682
683 RtlCopyMemory(&val, (uint8_t*)kvfi + kvfi->DataOffset, min(kvfi->DataLength, sizeof(uint32_t)));
684
685 TRACE("entry %lu = %.*S = %u\n", i, (int)(kvfi->NameLength / sizeof(WCHAR)), kvfi->Name, val);
686
687 add_group_mapping(kvfi->Name, kvfi->NameLength / sizeof(WCHAR), val);
688 }
689
690 i = i + 1;
691 } while (Status != STATUS_NO_MORE_ENTRIES);
692
693 ExFreePool(kvfi);
694 } else if (dispos == REG_CREATED_NEW_KEY) {
695 static const WCHAR builtin_users[] = L"S-1-5-32-545";
696
697 UNICODE_STRING us2;
698 DWORD val;
699
700 // If we're creating the key for the first time, we add a default mapping of
701 // BUILTIN\Users to gid 100, which ought to correspond to the "users" group on Linux.
702
703 us2.Length = us2.MaximumLength = sizeof(builtin_users) - sizeof(WCHAR);
705
706 if (us2.Buffer) {
707 RtlCopyMemory(us2.Buffer, builtin_users, us2.Length);
708
709 val = 100;
710 Status = ZwSetValueKey(h, &us2, 0, REG_DWORD, &val, sizeof(DWORD));
711 if (!NT_SUCCESS(Status)) {
712 ERR("ZwSetValueKey returned %08lx\n", Status);
713 ZwClose(h);
714 return;
715 }
716
717 add_group_mapping(us2.Buffer, us2.Length / sizeof(WCHAR), val);
718
719 ExFreePool(us2.Buffer);
720 }
721 }
722
723 ZwClose(h);
724}
void add_group_mapping(WCHAR *sidstring, ULONG sidstringlength, uint32_t gid)
Definition: security.c:145
UINT32 uint32_t
Definition: types.h:75
LIST_ENTRY gid_map_list
Definition: registry.c:22
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
unsigned long DWORD
Definition: ntddk_ex.h:95
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
Definition: reg.c:132
#define min(a, b)
Definition: monoChain.cc:55
struct _KEY_VALUE_FULL_INFORMATION KEY_VALUE_FULL_INFORMATION
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define L(x)
Definition: ntvdm.h:50
#define REG_DWORD
Definition: sdbapi.c:596
USHORT MaximumLength
Definition: env_spec_w32.h:370
PSID sid
Definition: btrfs_drv.h:910
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by read_registry().

◆ read_mappings()

static void read_mappings ( PUNICODE_STRING  regpath)
static

Definition at line 544 of file registry.c.

544 {
545 WCHAR* path;
547 HANDLE h;
551
552 static const WCHAR mappings[] = L"\\Mappings";
553
554 while (!IsListEmpty(&uid_map_list)) {
556
557 if (um->sid) ExFreePool(um->sid);
558 ExFreePool(um);
559 }
560
561 path = ExAllocatePoolWithTag(PagedPool, regpath->Length + sizeof(mappings) - sizeof(WCHAR), ALLOC_TAG);
562 if (!path) {
563 ERR("out of memory\n");
564 return;
565 }
566
567 RtlCopyMemory(path, regpath->Buffer, regpath->Length);
568 RtlCopyMemory((uint8_t*)path + regpath->Length, mappings, sizeof(mappings) - sizeof(WCHAR));
569
570 us.Buffer = path;
571 us.Length = us.MaximumLength = regpath->Length + sizeof(mappings) - sizeof(WCHAR);
572
574
575 Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
576
577 if (!NT_SUCCESS(Status)) {
578 ERR("ZwCreateKey returned %08lx\n", Status);
580 return;
581 }
582
585 ULONG kvfilen, retlen, i;
586
587 kvfilen = sizeof(KEY_VALUE_FULL_INFORMATION) + 256;
588 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
589
590 if (!kvfi) {
591 ERR("out of memory\n");
593 ZwClose(h);
594 return;
595 }
596
597 i = 0;
598 do {
599 Status = ZwEnumerateValueKey(h, i, KeyValueFullInformation, kvfi, kvfilen, &retlen);
600
601 if (NT_SUCCESS(Status) && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
602 uint32_t val = 0;
603
604 RtlCopyMemory(&val, (uint8_t*)kvfi + kvfi->DataOffset, min(kvfi->DataLength, sizeof(uint32_t)));
605
606 TRACE("entry %lu = %.*S = %u\n", i, (int)(kvfi->NameLength / sizeof(WCHAR)), kvfi->Name, val);
607
608 add_user_mapping(kvfi->Name, kvfi->NameLength / sizeof(WCHAR), val);
609 }
610
611 i = i + 1;
612 } while (Status != STATUS_NO_MORE_ENTRIES);
613
614 ExFreePool(kvfi);
615 }
616
617 ZwClose(h);
618
620}
void add_user_mapping(WCHAR *sidstring, ULONG sidstringlength, uint32_t uid)
Definition: security.c:56
LIST_ENTRY uid_map_list
Definition: btrfs.c:68
PSID sid
Definition: btrfs_drv.h:904

Referenced by read_registry().

◆ read_registry()

void read_registry ( PUNICODE_STRING  regpath,
bool  refresh 
)

Definition at line 777 of file registry.c.

777 {
780 HANDLE h;
782#ifdef _DEBUG
784 ULONG kvfilen, old_debug_log_level = debug_log_level;
785 UNICODE_STRING us, old_log_file, old_log_device;
786
787 static const WCHAR def_log_file[] = L"\\??\\C:\\btrfs.log";
788#endif
789
791
792 read_mappings(regpath);
793 read_group_mappings(regpath);
794
796
798
800
801 if (!NT_SUCCESS(Status)) {
802 ERR("ZwCreateKey returned %08lx\n", Status);
803 return;
804 }
805
806 if (!refresh)
807 reset_subkeys(h, regpath);
808
824
825 if (!refresh)
826 get_registry_value(h, L"NoPNP", REG_DWORD, &no_pnp, sizeof(no_pnp));
827
828 if (mount_flush_interval == 0)
830
831#ifdef _DEBUG
832 get_registry_value(h, L"DebugLogLevel", REG_DWORD, &debug_log_level, sizeof(debug_log_level));
833
834 RtlInitUnicodeString(&us, L"LogDevice");
835
836 kvfi = NULL;
837 kvfilen = 0;
838 Status = ZwQueryValueKey(h, &us, KeyValueFullInformation, kvfi, kvfilen, &kvfilen);
839
840 old_log_device = log_device;
841
844
845 if ((Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW) && kvfilen > 0) {
846 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
847
848 if (!kvfi) {
849 ERR("out of memory\n");
850 ZwClose(h);
851 return;
852 }
853
854 Status = ZwQueryValueKey(h, &us, KeyValueFullInformation, kvfi, kvfilen, &kvfilen);
855
856 if (NT_SUCCESS(Status)) {
857 if ((kvfi->Type == REG_SZ || kvfi->Type == REG_EXPAND_SZ) && kvfi->DataLength >= sizeof(WCHAR)) {
860
861 if (!log_device.Buffer) {
862 ERR("out of memory\n");
863 ExFreePool(kvfi);
864 ZwClose(h);
865 return;
866 }
867
868 RtlCopyMemory(log_device.Buffer, ((uint8_t*)kvfi) + kvfi->DataOffset, log_device.Length);
869
870 if (log_device.Buffer[(log_device.Length / sizeof(WCHAR)) - 1] == 0)
871 log_device.Length -= sizeof(WCHAR);
872 } else {
873 ERR("LogDevice was type %lu, length %lu\n", kvfi->Type, kvfi->DataLength);
874
876 if (!NT_SUCCESS(Status)) {
877 ERR("ZwDeleteValueKey returned %08lx\n", Status);
878 }
879 }
880 }
881
882 ExFreePool(kvfi);
883 } else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
884 ERR("ZwQueryValueKey returned %08lx\n", Status);
885 }
886
887 ExAcquireResourceExclusiveLite(&log_lock, true);
888
889 if (refresh && (log_device.Length != old_log_device.Length || RtlCompareMemory(log_device.Buffer, old_log_device.Buffer, log_device.Length) != log_device.Length ||
890 (!comfo && log_device.Length > 0) || (old_debug_log_level == 0 && debug_log_level > 0) || (old_debug_log_level > 0 && debug_log_level == 0))) {
891 if (comfo)
892 ObDereferenceObject(comfo);
893
894 if (log_handle) {
895 ZwClose(log_handle);
896 log_handle = NULL;
897 }
898
899 comfo = NULL;
900 comdo = NULL;
901
902 if (log_device.Length > 0 && debug_log_level > 0) {
904 if (!NT_SUCCESS(Status))
905 DbgPrint("IoGetDeviceObjectPointer returned %08lx\n", Status);
906 }
907 }
908
909 ExReleaseResourceLite(&log_lock);
910
911 if (old_log_device.Buffer)
912 ExFreePool(old_log_device.Buffer);
913
914 RtlInitUnicodeString(&us, L"LogFile");
915
916 kvfi = NULL;
917 kvfilen = 0;
918 Status = ZwQueryValueKey(h, &us, KeyValueFullInformation, kvfi, kvfilen, &kvfilen);
919
920 old_log_file = log_file;
921
922 if ((Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW) && kvfilen > 0) {
923 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
924
925 if (!kvfi) {
926 ERR("out of memory\n");
927 ZwClose(h);
928 return;
929 }
930
931 Status = ZwQueryValueKey(h, &us, KeyValueFullInformation, kvfi, kvfilen, &kvfilen);
932
933 if (NT_SUCCESS(Status)) {
934 if ((kvfi->Type == REG_SZ || kvfi->Type == REG_EXPAND_SZ) && kvfi->DataLength >= sizeof(WCHAR)) {
937
938 if (!log_file.Buffer) {
939 ERR("out of memory\n");
940 ExFreePool(kvfi);
941 ZwClose(h);
942 return;
943 }
944
945 RtlCopyMemory(log_file.Buffer, ((uint8_t*)kvfi) + kvfi->DataOffset, log_file.Length);
946
947 if (log_file.Buffer[(log_file.Length / sizeof(WCHAR)) - 1] == 0)
948 log_file.Length -= sizeof(WCHAR);
949 } else {
950 ERR("LogFile was type %lu, length %lu\n", kvfi->Type, kvfi->DataLength);
951
953 if (!NT_SUCCESS(Status))
954 ERR("ZwDeleteValueKey returned %08lx\n", Status);
955
956 log_file.Length = 0;
957 }
958 } else {
959 ERR("ZwQueryValueKey returned %08lx\n", Status);
960 log_file.Length = 0;
961 }
962
963 ExFreePool(kvfi);
964 } else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
965 Status = ZwSetValueKey(h, &us, 0, REG_SZ, (void*)def_log_file, sizeof(def_log_file));
966
967 if (!NT_SUCCESS(Status))
968 ERR("ZwSetValueKey returned %08lx\n", Status);
969
970 log_file.Length = 0;
971 } else {
972 ERR("ZwQueryValueKey returned %08lx\n", Status);
973 log_file.Length = 0;
974 }
975
976 if (log_file.Length == 0) {
977 log_file.Length = log_file.MaximumLength = sizeof(def_log_file) - sizeof(WCHAR);
979
980 if (!log_file.Buffer) {
981 ERR("out of memory\n");
982 ZwClose(h);
983 return;
984 }
985
987 }
988
989 ExAcquireResourceExclusiveLite(&log_lock, true);
990
991 if (refresh && (log_file.Length != old_log_file.Length || RtlCompareMemory(log_file.Buffer, old_log_file.Buffer, log_file.Length) != log_file.Length ||
992 (!log_handle && log_file.Length > 0) || (old_debug_log_level == 0 && debug_log_level > 0) || (old_debug_log_level > 0 && debug_log_level == 0))) {
993 if (log_handle) {
994 ZwClose(log_handle);
995 log_handle = NULL;
996 }
997
998 if (!comfo && log_file.Length > 0 && refresh && debug_log_level > 0) {
1000
1002
1003 Status = ZwCreateFile(&log_handle, FILE_WRITE_DATA, &oa, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
1005 if (!NT_SUCCESS(Status)) {
1006 DbgPrint("ZwCreateFile returned %08lx\n", Status);
1007 log_handle = NULL;
1008 }
1009 }
1010 }
1011
1012 ExReleaseResourceLite(&log_lock);
1013
1014 if (old_log_file.Buffer)
1015 ExFreePool(old_log_file.Buffer);
1016#endif
1017
1018 ZwClose(h);
1019}
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
uint32_t mount_readonly
Definition: btrfs.c:84
uint32_t mount_max_inline
Definition: btrfs.c:78
uint32_t mount_no_trim
Definition: btrfs.c:81
uint32_t mount_compress
Definition: btrfs.c:72
uint32_t mount_allow_degraded
Definition: btrfs.c:83
uint32_t mount_skip_balance
Definition: btrfs.c:79
uint32_t mount_zlib_level
Definition: btrfs.c:75
uint32_t mount_zstd_level
Definition: btrfs.c:76
uint32_t mount_nodatacow
Definition: btrfs.c:86
uint32_t mount_compress_type
Definition: btrfs.c:74
uint32_t mount_no_root_dir
Definition: btrfs.c:85
uint32_t mount_flush_interval
Definition: btrfs.c:77
uint32_t no_pnp
Definition: btrfs.c:87
uint32_t mount_no_barrier
Definition: btrfs.c:80
uint32_t mount_compress_force
Definition: btrfs.c:73
uint32_t mount_clear_cache
Definition: btrfs.c:82
uint32_t debug_log_level
Definition: btrfs.c:71
UNICODE_STRING log_file
Definition: registry.c:21
static void get_registry_value(HANDLE h, WCHAR *string, ULONG type, void *val, ULONG size)
Definition: registry.c:726
static void read_mappings(PUNICODE_STRING regpath)
Definition: registry.c:544
UNICODE_STRING log_device
Definition: btrfs.c:89
static void reset_subkeys(HANDLE h, PUNICODE_STRING reg_path)
Definition: registry.c:454
ERESOURCE mapping_lock
Definition: btrfs.c:103
static void read_group_mappings(PUNICODE_STRING regpath)
Definition: registry.c:622
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define DbgPrint
Definition: hal.h:12
#define REG_SZ
Definition: layer.c:22
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
unsigned short USHORT
Definition: pedump.c:61
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by _Function_class_().

◆ registry_load_volume_options()

NTSTATUS registry_load_volume_options ( device_extension Vcb)

Definition at line 36 of file registry.c.

36 {
37 BTRFS_UUID* uuid = &Vcb->superblock.uuid;
38 mount_options* options = &Vcb->options;
39 UNICODE_STRING path, ignoreus, compressus, compressforceus, compresstypeus, readonlyus, zliblevelus, flushintervalus,
40 maxinlineus, subvolidus, skipbalanceus, nobarrierus, notrimus, clearcacheus, allowdegradedus, zstdlevelus,
41 norootdirus, nodatacowus;
44 ULONG i, j, kvfilen, index, retlen;
46 HANDLE h;
47
48 options->compress = mount_compress;
49 options->compress_force = mount_compress_force;
51 options->readonly = mount_readonly;
52 options->zlib_level = mount_zlib_level;
53 options->zstd_level = mount_zstd_level;
54 options->flush_interval = mount_flush_interval;
55 options->max_inline = min(mount_max_inline, Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - sizeof(EXTENT_DATA) + 1);
56 options->skip_balance = mount_skip_balance;
57 options->no_barrier = mount_no_barrier;
58 options->no_trim = mount_no_trim;
59 options->clear_cache = mount_clear_cache;
60 options->allow_degraded = mount_allow_degraded;
61 options->subvol_id = 0;
62 options->no_root_dir = mount_no_root_dir;
63 options->nodatacow = mount_nodatacow;
64
65 path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
67
68 if (!path.Buffer) {
69 ERR("out of memory\n");
71 }
72
74 i = registry_path.Length / sizeof(WCHAR);
75
76 path.Buffer[i] = '\\';
77 i++;
78
79 for (j = 0; j < 16; j++) {
80 path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
81 path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
82
83 i += 2;
84
85 if (j == 3 || j == 5 || j == 7 || j == 9) {
86 path.Buffer[i] = '-';
87 i++;
88 }
89 }
90
91 kvfilen = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR) + (255 * sizeof(WCHAR));
93 if (!kvfi) {
94 ERR("out of memory\n");
96 goto end;
97 }
98
100
101 Status = ZwOpenKey(&h, KEY_QUERY_VALUE, &oa);
104 goto end;
105 } else if (!NT_SUCCESS(Status)) {
106 ERR("ZwOpenKey returned %08lx\n", Status);
107 goto end;
108 }
109
110 index = 0;
111
112 RtlInitUnicodeString(&ignoreus, L"Ignore");
113 RtlInitUnicodeString(&compressus, L"Compress");
114 RtlInitUnicodeString(&compressforceus, L"CompressForce");
115 RtlInitUnicodeString(&compresstypeus, L"CompressType");
116 RtlInitUnicodeString(&readonlyus, L"Readonly");
117 RtlInitUnicodeString(&zliblevelus, L"ZlibLevel");
118 RtlInitUnicodeString(&flushintervalus, L"FlushInterval");
119 RtlInitUnicodeString(&maxinlineus, L"MaxInline");
120 RtlInitUnicodeString(&subvolidus, L"SubvolId");
121 RtlInitUnicodeString(&skipbalanceus, L"SkipBalance");
122 RtlInitUnicodeString(&nobarrierus, L"NoBarrier");
123 RtlInitUnicodeString(&notrimus, L"NoTrim");
124 RtlInitUnicodeString(&clearcacheus, L"ClearCache");
125 RtlInitUnicodeString(&allowdegradedus, L"AllowDegraded");
126 RtlInitUnicodeString(&zstdlevelus, L"ZstdLevel");
127 RtlInitUnicodeString(&norootdirus, L"NoRootDir");
128 RtlInitUnicodeString(&nodatacowus, L"NoDataCOW");
129
130 do {
131 Status = ZwEnumerateValueKey(h, index, KeyValueFullInformation, kvfi, kvfilen, &retlen);
132
133 index++;
134
135 if (NT_SUCCESS(Status)) {
137
138 us.Length = us.MaximumLength = (USHORT)kvfi->NameLength;
139 us.Buffer = kvfi->Name;
140
141 if (FsRtlAreNamesEqual(&ignoreus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
142 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
143
144 options->ignore = *val != 0 ? true : false;
145 } else if (FsRtlAreNamesEqual(&compressus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
146 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
147
148 options->compress = *val != 0 ? true : false;
149 } else if (FsRtlAreNamesEqual(&compressforceus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
150 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
151
152 options->compress_force = *val != 0 ? true : false;
153 } else if (FsRtlAreNamesEqual(&compresstypeus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
154 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
155
156 options->compress_type = (uint8_t)(*val > BTRFS_COMPRESSION_ZSTD ? 0 : *val);
157 } else if (FsRtlAreNamesEqual(&readonlyus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
158 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
159
160 options->readonly = *val != 0 ? true : false;
161 } else if (FsRtlAreNamesEqual(&zliblevelus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
162 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
163
164 options->zlib_level = *val;
165 } else if (FsRtlAreNamesEqual(&flushintervalus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
166 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
167
168 options->flush_interval = *val;
169 } else if (FsRtlAreNamesEqual(&maxinlineus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
170 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
171
172 options->max_inline = min(*val, Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - sizeof(EXTENT_DATA) + 1);
173 } else if (FsRtlAreNamesEqual(&subvolidus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_QWORD) {
174 uint64_t* val = (uint64_t*)((uint8_t*)kvfi + kvfi->DataOffset);
175
176 options->subvol_id = *val;
177 } else if (FsRtlAreNamesEqual(&skipbalanceus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
178 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
179
180 options->skip_balance = *val;
181 } else if (FsRtlAreNamesEqual(&nobarrierus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
182 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
183
184 options->no_barrier = *val;
185 } else if (FsRtlAreNamesEqual(&notrimus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
186 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
187
188 options->no_trim = *val;
189 } else if (FsRtlAreNamesEqual(&clearcacheus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
190 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
191
192 options->clear_cache = *val;
193 } else if (FsRtlAreNamesEqual(&allowdegradedus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
194 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
195
196 options->allow_degraded = *val;
197 } else if (FsRtlAreNamesEqual(&zstdlevelus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
198 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
199
200 options->zstd_level = *val;
201 } else if (FsRtlAreNamesEqual(&norootdirus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
202 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
203
204 options->no_root_dir = *val;
205 } else if (FsRtlAreNamesEqual(&nodatacowus, &us, true, NULL) && kvfi->DataOffset > 0 && kvfi->DataLength > 0 && kvfi->Type == REG_DWORD) {
206 DWORD* val = (DWORD*)((uint8_t*)kvfi + kvfi->DataOffset);
207
208 options->nodatacow = *val;
209 }
210 } else if (Status != STATUS_NO_MORE_ENTRIES) {
211 ERR("ZwEnumerateValueKey returned %08lx\n", Status);
212 goto end2;
213 }
214 } while (NT_SUCCESS(Status));
215
216 if (!options->compress && options->compress_force)
217 options->compress = true;
218
219 if (options->zlib_level > 9)
220 options->zlib_level = 9;
221
222 if (options->zstd_level > (uint32_t)ZSTD_maxCLevel())
223 options->zstd_level = ZSTD_maxCLevel();
224
225 if (options->flush_interval == 0)
226 options->flush_interval = mount_flush_interval;
227
229
230end2:
231 ZwClose(h);
232
233end:
234 ExFreePool(path.Buffer);
235
236 if (kvfi)
237 ExFreePool(kvfi);
238
239 return Status;
240}
#define index(s, c)
Definition: various.h:29
#define hex_digit(c)
Definition: btrfs_drv.h:1748
UINT64 uint64_t
Definition: types.h:77
#define BTRFS_COMPRESSION_ZSTD
Definition: btrfs.h:68
GLuint GLuint end
Definition: gl.h:1545
GLuint index
Definition: glext.h:6031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
Definition: msctf.idl:550
if(dx< 0)
Definition: linetemp.h:194
#define uint8_t
Definition: nsiface.idl:59
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
#define Vcb
Definition: cdprocs.h:1415
#define REG_QWORD
Definition: sdbapi.c:597
#define STATUS_SUCCESS
Definition: shellext.h:65
#define true
Definition: stdbool.h:36
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ZSTDLIB_API int ZSTD_maxCLevel(void)

Referenced by mount_vol().

◆ registry_mark_volume_mounted()

NTSTATUS registry_mark_volume_mounted ( BTRFS_UUID uuid)

Definition at line 242 of file registry.c.

242 {
243 UNICODE_STRING path, mountedus;
244 ULONG i, j;
247 HANDLE h;
248 DWORD data;
249
250 path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
252
253 if (!path.Buffer) {
254 ERR("out of memory\n");
256 }
257
259 i = registry_path.Length / sizeof(WCHAR);
260
261 path.Buffer[i] = '\\';
262 i++;
263
264 for (j = 0; j < 16; j++) {
265 path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
266 path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
267
268 i += 2;
269
270 if (j == 3 || j == 5 || j == 7 || j == 9) {
271 path.Buffer[i] = '-';
272 i++;
273 }
274 }
275
277
278 Status = ZwCreateKey(&h, KEY_SET_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
279 if (!NT_SUCCESS(Status)) {
280 ERR("ZwCreateKey returned %08lx\n", Status);
281 goto end;
282 }
283
284 mountedus.Buffer = (WCHAR*)option_mounted;
285 mountedus.Length = mountedus.MaximumLength = sizeof(option_mounted) - sizeof(WCHAR);
286
287 data = 1;
288
289 Status = ZwSetValueKey(h, &mountedus, 0, REG_DWORD, &data, sizeof(DWORD));
290 if (!NT_SUCCESS(Status)) {
291 ERR("ZwSetValueKey returned %08lx\n", Status);
292 goto end2;
293 }
294
296
297end2:
298 ZwClose(h);
299
300end:
301 ExFreePool(path.Buffer);
302
303 return Status;
304}
static const WCHAR option_mounted[]
Definition: registry.c:34
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define KEY_SET_VALUE
Definition: nt_native.h:1017

Referenced by mount_vol().

◆ registry_mark_volume_unmounted()

NTSTATUS registry_mark_volume_unmounted ( BTRFS_UUID uuid)

Definition at line 385 of file registry.c.

385 {
388 ULONG i, j;
389
390 path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
392
393 if (!path.Buffer) {
394 ERR("out of memory\n");
396 }
397
399 i = registry_path.Length / sizeof(WCHAR);
400
401 path.Buffer[i] = '\\';
402 i++;
403
404 for (j = 0; j < 16; j++) {
405 path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
406 path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
407
408 i += 2;
409
410 if (j == 3 || j == 5 || j == 7 || j == 9) {
411 path.Buffer[i] = '-';
412 i++;
413 }
414 }
415
417 if (!NT_SUCCESS(Status)) {
418 ERR("registry_mark_volume_unmounted_path returned %08lx\n", Status);
419 goto end;
420 }
421
423
424end:
425 ExFreePool(path.Buffer);
426
427 return Status;
428}
static NTSTATUS registry_mark_volume_unmounted_path(PUNICODE_STRING path)
Definition: registry.c:306

Referenced by uninit().

◆ registry_mark_volume_unmounted_path()

static NTSTATUS registry_mark_volume_unmounted_path ( PUNICODE_STRING  path)
static

Definition at line 306 of file registry.c.

306 {
307 HANDLE h;
310 ULONG index, kvbilen = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR) + (255 * sizeof(WCHAR)), retlen;
312 bool has_options = false;
313 UNICODE_STRING mountedus;
314
315 // If a volume key has any options in it, we set Mounted to 0 and return. Otherwise,
316 // we delete the whole thing.
317
318 kvbi = ExAllocatePoolWithTag(PagedPool, kvbilen, ALLOC_TAG);
319 if (!kvbi) {
320 ERR("out of memory\n");
322 }
323
325
326 Status = ZwOpenKey(&h, KEY_QUERY_VALUE | KEY_SET_VALUE | DELETE, &oa);
327 if (!NT_SUCCESS(Status)) {
328 ERR("ZwOpenKey returned %08lx\n", Status);
329 goto end;
330 }
331
332 index = 0;
333
334 mountedus.Buffer = (WCHAR*)option_mounted;
335 mountedus.Length = mountedus.MaximumLength = sizeof(option_mounted) - sizeof(WCHAR);
336
337 do {
338 Status = ZwEnumerateValueKey(h, index, KeyValueBasicInformation, kvbi, kvbilen, &retlen);
339
340 index++;
341
342 if (NT_SUCCESS(Status)) {
344
345 us.Length = us.MaximumLength = (USHORT)kvbi->NameLength;
346 us.Buffer = kvbi->Name;
347
348 if (!FsRtlAreNamesEqual(&mountedus, &us, true, NULL)) {
349 has_options = true;
350 break;
351 }
352 } else if (Status != STATUS_NO_MORE_ENTRIES) {
353 ERR("ZwEnumerateValueKey returned %08lx\n", Status);
354 goto end2;
355 }
356 } while (NT_SUCCESS(Status));
357
358 if (has_options) {
359 DWORD data = 0;
360
361 Status = ZwSetValueKey(h, &mountedus, 0, REG_DWORD, &data, sizeof(DWORD));
362 if (!NT_SUCCESS(Status)) {
363 ERR("ZwSetValueKey returned %08lx\n", Status);
364 goto end2;
365 }
366 } else {
367 Status = ZwDeleteKey(h);
368 if (!NT_SUCCESS(Status)) {
369 ERR("ZwDeleteKey returned %08lx\n", Status);
370 goto end2;
371 }
372 }
373
375
376end2:
377 ZwClose(h);
378
379end:
380 ExFreePool(kvbi);
381
382 return Status;
383}
struct _KEY_VALUE_BASIC_INFORMATION KEY_VALUE_BASIC_INFORMATION
@ KeyValueBasicInformation
Definition: nt_native.h:1180
#define DELETE
Definition: nt_native.h:57

Referenced by registry_mark_volume_unmounted(), and reset_subkeys().

◆ reset_subkeys()

static void reset_subkeys ( HANDLE  h,
PUNICODE_STRING  reg_path 
)
static

Definition at line 454 of file registry.c.

454 {
457 ULONG kbilen = sizeof(KEY_BASIC_INFORMATION) - sizeof(WCHAR) + (255 * sizeof(WCHAR)), retlen, index = 0;
459
461
463 if (!kbi) {
464 ERR("out of memory\n");
465 return;
466 }
467
468 do {
469 Status = ZwEnumerateKey(h, index, KeyBasicInformation, kbi, kbilen, &retlen);
470
471 index++;
472
473 if (NT_SUCCESS(Status)) {
474 key_name* kn;
475
476 TRACE("key: %.*S\n", (int)(kbi->NameLength / sizeof(WCHAR)), kbi->Name);
477
478 if (is_uuid(kbi->NameLength, kbi->Name)) {
480 if (!kn) {
481 ERR("out of memory\n");
482 goto end;
483 }
484
485 kn->name.Length = kn->name.MaximumLength = (USHORT)min(0xffff, kbi->NameLength);
487
488 if (!kn->name.Buffer) {
489 ERR("out of memory\n");
490 ExFreePool(kn);
491 goto end;
492 }
493
494 RtlCopyMemory(kn->name.Buffer, kbi->Name, kn->name.Length);
495
497 }
498 } else if (Status != STATUS_NO_MORE_ENTRIES)
499 ERR("ZwEnumerateKey returned %08lx\n", Status);
500 } while (NT_SUCCESS(Status));
501
502 le = key_names.Flink;
503 while (le != &key_names) {
506
507 path.Length = path.MaximumLength = reg_path->Length + sizeof(WCHAR) + kn->name.Length;
509
510 if (!path.Buffer) {
511 ERR("out of memory\n");
512 goto end;
513 }
514
515 RtlCopyMemory(path.Buffer, reg_path->Buffer, reg_path->Length);
516 path.Buffer[reg_path->Length / sizeof(WCHAR)] = '\\';
517 RtlCopyMemory(&path.Buffer[(reg_path->Length / sizeof(WCHAR)) + 1], kn->name.Buffer, kn->name.Length);
518
520 if (!NT_SUCCESS(Status))
521 WARN("registry_mark_volume_unmounted_path returned %08lx\n", Status);
522
523 ExFreePool(path.Buffer);
524
525 le = le->Flink;
526 }
527
528end:
529 while (!IsListEmpty(&key_names)) {
530 key_name* kn;
531
534
535 if (kn->name.Buffer)
537
538 ExFreePool(kn);
539 }
540
541 ExFreePool(kbi);
542}
#define WARN(fmt,...)
Definition: debug.h:112
static bool is_uuid(ULONG namelen, WCHAR *name)
Definition: registry.c:432
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ROSDATA VSC_LPWSTR key_names[]
Definition: kbda1.c:260
@ KeyBasicInformation
Definition: nt_native.h:1131
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY list_entry
Definition: registry.c:451
UNICODE_STRING name
Definition: registry.c:450
Definition: list.h:27

Referenced by read_registry().

◆ watch_registry()

void watch_registry ( HANDLE  regh)

Definition at line 1036 of file registry.c.

1036 {
1039
1040 ExInitializeWorkItem(&wqi, registry_work_item, regh);
1041
1042 Status = ZwNotifyChangeKey(regh, NULL, (PVOID)&wqi, (PVOID)DelayedWorkQueue, &iosb, REG_NOTIFY_CHANGE_LAST_SET, true, NULL, 0, true);
1043 if (!NT_SUCCESS(Status))
1044 ERR("ZwNotifyChangeKey returned %08lx\n", Status);
1045}
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265

Referenced by _Function_class_().

Variable Documentation

◆ gid_map_list

LIST_ENTRY gid_map_list

Definition at line 22 of file registry.c.

Referenced by read_group_mappings().

◆ log_device

UNICODE_STRING log_device
extern

Definition at line 89 of file btrfs.c.

Referenced by _Function_class_(), and read_registry().

◆ log_file

UNICODE_STRING log_file

Definition at line 21 of file registry.c.

Referenced by read_registry().

◆ mapping_lock

ERESOURCE mapping_lock
extern

Definition at line 103 of file btrfs.c.

Referenced by read_registry().

◆ option_mounted

const WCHAR option_mounted[] = L"Mounted"
static

Definition at line 34 of file registry.c.

Referenced by registry_mark_volume_mounted(), and registry_mark_volume_unmounted_path().

◆ registry_path

◆ uid_map_list

LIST_ENTRY uid_map_list
extern

Definition at line 68 of file btrfs.c.

Referenced by read_mappings().

◆ wqi

Definition at line 32 of file registry.c.

Referenced by _Function_class_(), and watch_registry().