- Update to r53061
[reactos.git] / drivers / filesystems / ext2 / src / devcntrl.c
1 /*************************************************************************
2 *
3 * File: devcntrl.c
4 *
5 * Module: Ext2 File System Driver (Kernel mode execution only)
6 *
7 * Description:
8 * Contains code to handle the "Device IOCTL" dispatch entry point.
9 *
10 * Author: Manoj Paul Joseph
11 *
12 *
13 *************************************************************************/
14
15 #include "ext2fsd.h"
16
17 // define the file specific bug-check id
18 #define EXT2_BUG_CHECK_ID EXT2_FILE_DEVICE_CONTROL
19 #define DEBUG_LEVEL DEBUG_TRACE_DEVCTRL
20
21
22 #if(_WIN32_WINNT < 0x0400)
23 #define IOCTL_REDIR_QUERY_PATH CTL_CODE(FILE_DEVICE_NETWORK_FILE_SYSTEM, 99, METHOD_NEITHER, FILE_ANY_ACCESS)
24
25 typedef struct _QUERY_PATH_REQUEST
26 {
27 ULONG PathNameLength;
28 PIO_SECURITY_CONTEXT SecurityContext;
29 WCHAR FilePathName[1];
30 } QUERY_PATH_REQUEST, *PQUERY_PATH_REQUEST;
31
32 typedef struct _QUERY_PATH_RESPONSE
33 {
34 ULONG LengthAccepted;
35 } QUERY_PATH_RESPONSE, *PQUERY_PATH_RESPONSE;
36 #endif
37
38
39 /*************************************************************************
40 *
41 * Function: Ext2DeviceControl()
42 *
43 * Description:
44 * The I/O Manager will invoke this routine to handle a Device IOCTL
45 * request
46 *
47 * Expected Interrupt Level (for execution) :
48 *
49 * IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
50 * to be deferred to a worker thread context)
51 *
52 * Return Value: STATUS_SUCCESS/Error
53 *
54 *************************************************************************/
55 NTSTATUS NTAPI Ext2DeviceControl(
56 PDEVICE_OBJECT DeviceObject, // the logical volume device object
57 PIRP Irp) // I/O Request Packet
58 {
59 NTSTATUS RC = STATUS_SUCCESS;
60 PtrExt2IrpContext PtrIrpContext = NULL;
61 BOOLEAN AreWeTopLevel = FALSE;
62
63 // Ext2BreakPoint();
64
65 DebugTrace(DEBUG_TRACE_IRP_ENTRY, "Device Control IRP Received...", 0);
66
67 FsRtlEnterFileSystem();
68 ASSERT(DeviceObject);
69 ASSERT(Irp);
70
71 // set the top level context
72 AreWeTopLevel = Ext2IsIrpTopLevel(Irp);
73
74 try {
75
76 // get an IRP context structure and issue the request
77 PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
78 ASSERT(PtrIrpContext);
79
80 RC = Ext2CommonDeviceControl(PtrIrpContext, Irp);
81
82 } except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
83
84 RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
85
86 Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
87 }
88
89 if (AreWeTopLevel) {
90 IoSetTopLevelIrp(NULL);
91 }
92
93 FsRtlExitFileSystem();
94
95 return(RC);
96 }
97
98
99 /*************************************************************************
100 *
101 * Function: Ext2CommonDeviceControl()
102 *
103 * Description:
104 * The actual work is performed here. This routine may be invoked in one'
105 * of the two possible contexts:
106 * (a) in the context of a system worker thread
107 * (b) in the context of the original caller
108 *
109 * Expected Interrupt Level (for execution) :
110 *
111 * IRQL_PASSIVE_LEVEL
112 *
113 * Return Value: STATUS_SUCCESS/Error
114 *
115 *************************************************************************/
116 NTSTATUS NTAPI Ext2CommonDeviceControl(
117 PtrExt2IrpContext PtrIrpContext,
118 PIRP PtrIrp)
119 {
120 NTSTATUS RC = STATUS_SUCCESS;
121 PIO_STACK_LOCATION PtrIoStackLocation = NULL;
122 PIO_STACK_LOCATION PtrNextIoStackLocation = NULL;
123 PFILE_OBJECT PtrFileObject = NULL;
124 PtrExt2FCB PtrFCB = NULL;
125 PtrExt2CCB PtrCCB = NULL;
126 PtrExt2VCB PtrVCB = NULL;
127 ULONG IoControlCode = 0;
128
129 try
130 {
131 // First, get a pointer to the current I/O stack location
132 PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp);
133 ASSERT(PtrIoStackLocation);
134
135 PtrFileObject = PtrIoStackLocation->FileObject;
136 ASSERT(PtrFileObject);
137
138 PtrCCB = (PtrExt2CCB)(PtrFileObject->FsContext2);
139 ASSERT(PtrCCB);
140 PtrFCB = PtrCCB->PtrFCB;
141 ASSERT(PtrFCB);
142
143
144 if( PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB )
145 {
146 PtrVCB = (PtrExt2VCB)(PtrFCB);
147 }
148 else
149 {
150 AssertFCB( PtrFCB );
151 ASSERT(PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB);
152 PtrVCB = PtrFCB->PtrVCB;
153 }
154
155 // Get the IoControlCode value
156 IoControlCode = PtrIoStackLocation->Parameters.DeviceIoControl.IoControlCode;
157
158 // You may wish to allow only volume open operations.
159
160 // Invoke the lower level driver in the chain.
161 PtrNextIoStackLocation = IoGetNextIrpStackLocation(PtrIrp);
162 *PtrNextIoStackLocation = *PtrIoStackLocation;
163 // Set a completion routine.
164 IoSetCompletionRoutine(PtrIrp, Ext2DevIoctlCompletion, NULL, TRUE, TRUE, TRUE);
165 // Send the request.
166 RC = IoCallDriver(PtrVCB->TargetDeviceObject, PtrIrp);
167 }
168 finally
169 {
170 // Release the IRP context
171 if (!(PtrIrpContext->IrpContextFlags & EXT2_IRP_CONTEXT_EXCEPTION))
172 {
173 // Free up the Irp Context
174 Ext2ReleaseIrpContext(PtrIrpContext);
175 }
176 }
177
178 return(RC);
179 }
180
181
182 /*************************************************************************
183 *
184 * Function: Ext2DevIoctlCompletion()
185 *
186 * Description:
187 * Completion routine.
188 *
189 * Expected Interrupt Level (for execution) :
190 *
191 * IRQL_PASSIVE_LEVEL
192 *
193 * Return Value: STATUS_SUCCESS
194 *
195 *************************************************************************/
196 NTSTATUS NTAPI Ext2DevIoctlCompletion(
197 PDEVICE_OBJECT PtrDeviceObject,
198 PIRP PtrIrp,
199 void *Context)
200 {
201 if (PtrIrp->PendingReturned) {
202 IoMarkIrpPending(PtrIrp);
203 }
204
205 return(STATUS_SUCCESS);
206 }