ReactOS  0.4.15-dev-509-g96a357b
fsrtl.c File Reference
#include <ntifs.h>
#include <ntdef.h>
Include dependency graph for fsrtl.c:

Go to the source code of this file.

Macros

#define FIELDS_SIZE   (FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) - FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset))
 

Functions

FORCEINLINE BOOLEAN IsNullGuid (IN PGUID Guid)
 
FORCEINLINE BOOLEAN IsEven (IN USHORT Digit)
 
NTSTATUS __stdcall compat_FsRtlValidateReparsePointBuffer (IN ULONG BufferLength, IN PREPARSE_DATA_BUFFER ReparseBuffer)
 

Macro Definition Documentation

◆ FIELDS_SIZE

#define FIELDS_SIZE   (FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) - FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset))

Function Documentation

◆ compat_FsRtlValidateReparsePointBuffer()

NTSTATUS __stdcall compat_FsRtlValidateReparsePointBuffer ( IN ULONG  BufferLength,
IN PREPARSE_DATA_BUFFER  ReparseBuffer 
)

Definition at line 32 of file fsrtl.c.

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 IsReparseTagMicrosoft(_tag)
Definition: iotypes.h:6866
#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
Definition: iotypes.h:6857
#define IO_REPARSE_TAG_RESERVED_ZERO
Definition: iotypes.h:6862
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6877
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
FORCEINLINE BOOLEAN IsEven(IN USHORT Digit)
Definition: fsrtl.c:27
struct _REPARSE_GUID_DATA_BUFFER * PREPARSE_GUID_DATA_BUFFER
#define REPARSE_DATA_BUFFER_HEADER_SIZE
Definition: iotypes.h:6845
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:6863
#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:3014
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:6859
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6886

Referenced by _Function_class_().

◆ IsEven()

FORCEINLINE BOOLEAN IsEven ( IN USHORT  Digit)

Definition at line 27 of file fsrtl.c.

28 {
29  return ((Digit & 1) != 1);
30 }

Referenced by compat_FsRtlValidateReparsePointBuffer(), and FsRtlValidateReparsePointBuffer().

◆ IsNullGuid()

FORCEINLINE BOOLEAN IsNullGuid ( IN PGUID  Guid)

Definition at line 14 of file fsrtl.c.

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 }
#define TRUE
Definition: types.h:120
static GUID * Guid
Definition: apphelp.c:93
unsigned int ULONG
Definition: retypes.h:1

Referenced by compat_FsRtlValidateReparsePointBuffer(), and FsRtlValidateReparsePointBuffer().