ReactOS  0.4.15-dev-1068-g467feb9
IoCreateFile_drv.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS kernel-mode tests
3  * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE: Test driver for reparse point operations
5  * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 #include "IoCreateFile.h"
14 
15 typedef struct _TEST_FCB
16 {
21 
22 static KMT_IRP_HANDLER TestIrpHandler;
23 static KMT_MESSAGE_HANDLER TestMessageHandler;
24 
27 
33  _Inout_ INT *Flags)
34 {
36 
37  PAGED_CODE();
38 
40 
41  *DeviceName = L"IoCreateFile";
42  *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
43  TESTENTRY_BUFFERED_IO_DEVICE |
44  TESTENTRY_NO_READONLY_DEVICE;
45 
49 
50  return Status;
51 }
52 
53 VOID
56 {
57  PAGED_CODE();
58 }
59 
60 static volatile long gNoLinks = FALSE;
61 
62 static
66  _In_ PIRP Irp,
67  _In_ PIO_STACK_LOCATION IoStack)
68 {
70  PTEST_FCB Fcb;
71  CACHE_UNINITIALIZE_EVENT CacheUninitEvent;
72 
73  PAGED_CODE();
74 
75  DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
76  ASSERT(IoStack->MajorFunction == IRP_MJ_CREATE ||
77  IoStack->MajorFunction == IRP_MJ_CLEANUP);
78 
80  Irp->IoStatus.Information = 0;
81 
82  if (IoStack->MajorFunction == IRP_MJ_CREATE)
83  {
84  ok((IoStack->Parameters.Create.Options & FILE_OPEN_REPARSE_POINT) == 0, "FILE_OPEN_REPARSE_POINT set\n");
85  ok((IoStack->Flags == 0 && !gNoLinks) || (IoStack->Flags == SL_STOP_ON_SYMLINK && gNoLinks), "IoStack->Flags = %lx\n", IoStack->Flags);
86 
87  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
88  {
90  TestFileObject = IoStack->FileObject;
91  }
92  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
93  IoStack->FileObject->FileName.Buffer[1] == 'M')
94  {
95  PREPARSE_DATA_BUFFER Reparse;
96 
97  Irp->Tail.Overlay.AuxiliaryBuffer = ExAllocatePoolWithTag(NonPagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, 'FwrI');
98  Reparse = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
99 
102  Reparse->ReparseDataLength = 12 + sizeof(L"\\??\\C:\\Documents and Settings");
103  Reparse->MountPointReparseBuffer.SubstituteNameLength = sizeof(L"\\??\\C:\\Documents and Settings") - sizeof(UNICODE_NULL);
104  Reparse->MountPointReparseBuffer.PrintNameOffset = sizeof(L"\\??\\C:\\Documents and Settings");
105  RtlCopyMemory(Reparse->MountPointReparseBuffer.PathBuffer, L"\\??\\C:\\Documents and Settings", sizeof(L"\\??\\C:\\Documents and Settings"));
106  Irp->IoStatus.Information = IO_REPARSE_TAG_MOUNT_POINT;
108  }
109  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
110  IoStack->FileObject->FileName.Buffer[1] == 'S')
111  {
112  if (IoStack->Flags & SL_STOP_ON_SYMLINK)
113  {
115  }
116  else
117  {
118  PREPARSE_DATA_BUFFER Reparse;
119 
120  Irp->Tail.Overlay.AuxiliaryBuffer = ExAllocatePoolWithTag(NonPagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, 'FwrI');
121  Reparse = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
122 
125  Reparse->ReparseDataLength = 12 + sizeof(L"\\??\\C:\\Documents and Settings");
126  Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength = sizeof(L"\\??\\C:\\Documents and Settings") - sizeof(UNICODE_NULL);
127  Reparse->SymbolicLinkReparseBuffer.PrintNameOffset = sizeof(L"\\??\\C:\\Documents and Settings");
128  RtlCopyMemory(Reparse->SymbolicLinkReparseBuffer.PathBuffer, L"\\??\\C:\\Documents and Settings", sizeof(L"\\??\\C:\\Documents and Settings"));
129  Irp->IoStatus.Information = IO_REPARSE_TAG_SYMLINK;
131  }
132  }
133  else
134  {
135  Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
136  RtlZeroMemory(Fcb, sizeof(*Fcb));
137  ExInitializeFastMutex(&Fcb->HeaderMutex);
138  FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
139  Fcb->Header.AllocationSize.QuadPart = 0;
140  Fcb->Header.FileSize.QuadPart = 0;
141  Fcb->Header.ValidDataLength.QuadPart = 0;
142  IoStack->FileObject->FsContext = Fcb;
143  IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
144 
145  Irp->IoStatus.Information = FILE_OPENED;
147  }
148  }
149  else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
150  {
151  KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
152  CcUninitializeCacheMap(IoStack->FileObject, NULL, &CacheUninitEvent);
153  KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE, NULL);
154  Fcb = IoStack->FileObject->FsContext;
155  ExFreePoolWithTag(Fcb, 'FwrI');
156  IoStack->FileObject->FsContext = NULL;
158  }
159 
160  Irp->IoStatus.Status = Status;
162 
163  return Status;
164 }
165 
167 static UNICODE_STRING DocumentsAndSettings = RTL_CONSTANT_STRING(L"\\Documents and Settings");
168 
169 static
170 NTSTATUS
173 {
176  HANDLE Handle;
179 
181  Path,
183  NULL,
184  NULL);
186  GENERIC_READ,
188  &IoStatusBlock,
189  NULL,
192  FILE_OPEN,
194  NULL,
195  0,
197  NULL,
199  if (NT_SUCCESS(Status))
200  {
201  NTSTATUS IntStatus;
202 
203  IntStatus = ObReferenceObjectByHandle(Handle,
206  KernelMode,
207  (PVOID *)&FileObject,
208  NULL);
209  ok_eq_hex(IntStatus, STATUS_SUCCESS);
210  if (NT_SUCCESS(IntStatus))
211  {
214  "Expected: %wZ or %wZ. Opened: %wZ\n", &FileObjectFileName, &DocumentsAndSettings, &FileObject->FileName);
216  }
217 
218  IntStatus = ObCloseHandle(Handle, KernelMode);
219  ok_eq_hex(IntStatus, STATUS_SUCCESS);
220  }
221 
222  return Status;
223 }
224 
225 static
226 NTSTATUS
231  IN SIZE_T InLength,
232  IN OUT PSIZE_T OutLength)
233 {
235 
236  PAGED_CODE();
237 
238  switch (ControlCode)
239  {
241  {
243  {
245  }
246 
247  break;
248  }
249  case IOCTL_CALL_CREATE:
250  {
252  UNICODE_STRING PathW;
253 
254  ok(Buffer != NULL, "Buffer is NULL\n");
255  Path.Length = Path.MaximumLength = (USHORT)InLength;
256  Path.Buffer = Buffer;
257 
260 
261  Status = TestIoCreateFile(&PathW);
262 
263  RtlFreeUnicodeString(&PathW);
264 
265  break;
266  }
267  default:
268  return STATUS_NOT_SUPPORTED;
269  }
270 
271  return Status;
272 }
static UNICODE_STRING DocumentsAndSettings
struct _TEST_FCB * PTEST_FCB
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID TestUnload(_In_ PDRIVER_OBJECT DriverObject)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
PFILE_OBJECT FileObject
Definition: ntfs.h:516
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define IOCTL_DISABLE_SYMLINK
Definition: IoCreateFile.h:12
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_OPENED
Definition: nt_native.h:769
#define SL_STOP_ON_SYMLINK
Definition: iotypes.h:1799
static PFILE_OBJECT TestFileObject
#define IOCTL_CALL_CREATE
Definition: IoCreateFile.h:11
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
WCHAR DeviceName[]
Definition: adapter.cpp:21
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
int32_t INT
Definition: typedefs.h:58
#define STATUS_STOPPED_ON_SYMLINK
Definition: ntstatus.h:224
#define FILE_SHARE_READ
Definition: compat.h:136
#define IO_STOP_ON_SYMLINK
Definition: iotypes.h:7332
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7210
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:524
#define FILE_READ_DATA
Definition: nt_native.h:628
static KMT_MESSAGE_HANDLER TestMessageHandler
smooth NULL
Definition: ftsmooth.c:416
static UNICODE_STRING FileObjectFileName
#define _Out_
Definition: no_sal2.h:323
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
Definition: bufpool.h:45
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
FAST_MUTEX
Definition: extypes.h:17
_In_ HANDLE Handle
Definition: extypes.h:390
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
NTSTATUS KmtRegisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
SECTION_OBJECT_POINTERS SectionObjectPointers
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _Inout_
Definition: no_sal2.h:244
* PFILE_OBJECT
Definition: iotypes.h:1978
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
Status
Definition: gdiplustypes.h:24
USHORT ReparseDataLength
Definition: shellext.h:166
static const WCHAR L[]
Definition: oid.c:1250
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
FSRTL_ADVANCED_FCB_HEADER Header
#define GENERIC_READ
Definition: compat.h:135
static KMT_IRP_HANDLER TestIrpHandler
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define InterlockedExchange
Definition: armddk.h:54
#define FILE_OPEN
Definition: from_kernel.h:54
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:80
PRTL_UNICODE_STRING_BUFFER Path
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define ok(value,...)
Definition: atltest.h:57
#define STATUS_REPARSE
Definition: ntstatus.h:83
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3009
FAST_MUTEX HeaderMutex
#define IRP_MJ_CLEANUP
static PDEVICE_OBJECT TestDeviceObject
struct _REPARSE_DATA_BUFFER::@309::@311 SymbolicLinkReparseBuffer
#define OUT
Definition: typedefs.h:40
NTSTATUS TestEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PCUNICODE_STRING RegistryPath, _Out_ PCWSTR *DeviceName, _Inout_ INT *Flags)
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
struct _REPARSE_DATA_BUFFER::@309::@312 MountPointReparseBuffer
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static NTSTATUS TestIoCreateFile(IN PUNICODE_STRING Path)
#define ok_eq_hex(value, expected)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_In_ PFCB Fcb
Definition: cdprocs.h:159
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:7192
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7219
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:514
static volatile long gNoLinks
struct _REPARSE_DATA_BUFFER * PREPARSE_DATA_BUFFER
struct _TEST_FCB TEST_FCB
#define PAGED_CODE()
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68