ReactOS  0.4.14-dev-317-g96040ec
fsrtl.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel - Vista+ APIs
3  * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4  * FILE: lib/drivers/ntoskrnl_vista/fsrtl.c
5  * PURPOSE: FsRtl functions of Vista+
6  * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7  */
8 
9 #include <ntifs.h>
10 #include <ntdef.h>
11 
13 BOOLEAN
15 {
16  if (Guid->Data1 == 0 && Guid->Data2 == 0 && Guid->Data3 == 0 &&
17  ((ULONG *)Guid->Data4)[0] == 0 && ((ULONG *)Guid->Data4)[1] == 0)
18  {
19  return TRUE;
20  }
21 
22  return FALSE;
23 }
24 
26 BOOLEAN
28 {
29  return ((Digit & 1) != 1);
30 }
31 
33 {
35  ULONG ReparseTag;
36  PREPARSE_GUID_DATA_BUFFER GuidBuffer;
37 
38  /* Validate data size range */
39  if (BufferLength < REPARSE_DATA_BUFFER_HEADER_SIZE || BufferLength > MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
40  {
42  }
43 
44  GuidBuffer = (PREPARSE_GUID_DATA_BUFFER)ReparseBuffer;
45  DataLength = ReparseBuffer->ReparseDataLength;
46  ReparseTag = ReparseBuffer->ReparseTag;
47 
48  /* Validate size consistency */
50  {
52  }
53 
54  /* REPARSE_DATA_BUFFER is reserved for MS tags */
56  {
58  }
59 
60  /* If that a GUID data buffer, its GUID cannot be null, and it cannot contain a MS tag */
62  && IsNullGuid(&GuidBuffer->ReparseGuid)) || (ReparseTag == IO_REPARSE_TAG_MOUNT_POINT || ReparseTag == IO_REPARSE_TAG_SYMLINK)))
63  {
65  }
66 
67  /* Check the data for MS non reserved tags */
68  if (!(ReparseTag & 0xFFF0000) && ReparseTag != IO_REPARSE_TAG_RESERVED_ZERO && ReparseTag != IO_REPARSE_TAG_RESERVED_ONE)
69  {
70  /* If that's a mount point, validate the MountPointReparseBuffer branch */
71  if (ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
72  {
73  /* We need information */
75  {
76  /* Substitue must be the first in row */
77  if (!ReparseBuffer->MountPointReparseBuffer.SubstituteNameOffset)
78  {
79  /* Substitude must be null-terminated */
80  if (ReparseBuffer->MountPointReparseBuffer.PrintNameOffset == ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength + sizeof(UNICODE_NULL))
81  {
82  /* There must just be the Offset/Length fields + buffer + 2 null chars */
83  if (DataLength == ReparseBuffer->MountPointReparseBuffer.PrintNameLength + ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength + (FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.SubstituteNameOffset)) + 2 * sizeof(UNICODE_NULL))
84  {
85  return STATUS_SUCCESS;
86  }
87  }
88  }
89  }
90  }
91  else
92  {
93 #define FIELDS_SIZE (FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) - FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset))
94 
95  /* If that's not a symlink, accept the MS tag as it */
96  if (ReparseTag != IO_REPARSE_TAG_SYMLINK)
97  {
98  return STATUS_SUCCESS;
99  }
100 
101  /* We need information */
102  if (DataLength >= FIELDS_SIZE)
103  {
104  /* Validate lengths */
105  if (ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength && ReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength)
106  {
107  /* Validate unicode strings */
108  if (IsEven(ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength) && IsEven(ReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength) &&
109  IsEven(ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset) && IsEven(ReparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset))
110  {
111  if ((DataLength + REPARSE_DATA_BUFFER_HEADER_SIZE >= ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset + ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength + FIELDS_SIZE + REPARSE_DATA_BUFFER_HEADER_SIZE)
112  && (DataLength + REPARSE_DATA_BUFFER_HEADER_SIZE >= ReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength + ReparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset + FIELDS_SIZE + REPARSE_DATA_BUFFER_HEADER_SIZE))
113  {
114  return STATUS_SUCCESS;
115  }
116  }
117  }
118  }
119 #undef FIELDS_SIZE
120  }
121 
123  }
124 
126 }
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define IsReparseTagMicrosoft(_tag)
Definition: iotypes.h:6864
#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
Definition: iotypes.h:6855
#define IO_REPARSE_TAG_RESERVED_ZERO
Definition: iotypes.h:6860
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6875
WCHAR PathBuffer[1]
Definition: shellext.h:176
FORCEINLINE BOOLEAN IsNullGuid(IN PGUID Guid)
Definition: fsrtl.c:14
#define UNICODE_NULL
#define FIELDS_SIZE
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define STATUS_IO_REPARSE_DATA_INVALID
Definition: ntstatus.h:742
unsigned char BOOLEAN
static GUID * Guid
Definition: apphelp.c:93
#define FORCEINLINE
Definition: ntbasedef.h:221
FORCEINLINE BOOLEAN IsEven(IN USHORT Digit)
Definition: fsrtl.c:27
#define __stdcall
Definition: typedefs.h:25
struct _REPARSE_GUID_DATA_BUFFER * PREPARSE_GUID_DATA_BUFFER
#define REPARSE_DATA_BUFFER_HEADER_SIZE
Definition: iotypes.h:6843
unsigned short USHORT
Definition: pedump.c:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define IO_REPARSE_TAG_RESERVED_ONE
Definition: iotypes.h:6861
#define STATUS_IO_REPARSE_TAG_INVALID
Definition: ntstatus.h:740
USHORT SubstituteNameOffset
Definition: shellext.h:171
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:6857
NTSTATUS __stdcall compat_FsRtlValidateReparsePointBuffer(IN ULONG BufferLength, IN PREPARSE_DATA_BUFFER ReparseBuffer)
Definition: fsrtl.c:32
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6884