Windows: Fix uninitialized variables
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSLockControl.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011, 2014 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSLockControl.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 NTSTATUS
42 AFSLockControl( IN PDEVICE_OBJECT LibDeviceObject,
43                   IN PIRP Irp)
44 {
45
46     UNREFERENCED_PARAMETER(LibDeviceObject);
47     NTSTATUS ntStatus = STATUS_SUCCESS;
48     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
49     AFSFcb *pFcb = NULL;
50     AFSCcb *pCcb = NULL;
51     BOOLEAN bCompleteRequest = TRUE;
52     AFSByteRangeLockRequestCB  stLockRequestCB;
53     AFSByteRangeLockResultCB  stLockResultCB;
54     AFSByteRangeUnlockRequestCB stUnlockRequestCB;
55     AFSByteRangeUnlockResultCB stUnlockResultCB;
56     ULONG           ulResultLen = 0;
57     BOOLEAN         bReleaseResource = FALSE;
58     IO_STATUS_BLOCK stIoStatus;
59
60     __try
61     {
62
63         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
64
65         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
66
67         if( pFcb == NULL)
68         {
69
70             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
71                           AFS_TRACE_LEVEL_ERROR,
72                           "AFSLockControl Attempted access (%p) when pFcb == NULL\n",
73                           Irp));
74
75             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
76         }
77
78         //
79         // Acquire the main shared for adding the lock control to the list
80         //
81
82         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
83                       AFS_TRACE_LEVEL_VERBOSE,
84                       "AFSLockControl Acquiring Fcb lock %p SHARED %08lX\n",
85                       &pFcb->NPFcb->Resource,
86                       PsGetCurrentThread()));
87
88         AFSAcquireShared( &pFcb->NPFcb->Resource,
89                           TRUE);
90
91         bReleaseResource = TRUE;
92
93         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
94         {
95
96             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
97                           AFS_TRACE_LEVEL_ERROR,
98                           "AFSLockControl Failing request against PIOCtl Fcb\n"));
99
100             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
101         }
102         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
103         {
104
105             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
106                           AFS_TRACE_LEVEL_ERROR,
107                           "AFSLockControl Failing request against SpecialShare Fcb\n"));
108
109             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
110         }
111         else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
112         {
113
114             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
115                           AFS_TRACE_LEVEL_ERROR,
116                           "AFSLockControl Failing request against Invalid Fcb\n"));
117
118             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
119         }
120
121         //
122         // Post the request to the service for checks
123         //
124
125         switch( pIrpSp->MinorFunction)
126         {
127
128             case IRP_MN_LOCK:
129             {
130
131                 stLockRequestCB.Count = 1;
132
133                 stLockRequestCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
134
135                 stLockRequestCB.Request[ 0].LockType = AFS_BYTE_RANGE_LOCK_TYPE_EXCL;
136
137                 stLockRequestCB.Request[ 0].Offset = pIrpSp->Parameters.LockControl.ByteOffset;
138
139                 stLockRequestCB.Request[ 0].Length.QuadPart = pIrpSp->Parameters.LockControl.Length->QuadPart;
140
141                 ulResultLen = sizeof( AFSByteRangeLockResultCB);
142
143                 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_LOCK,
144                                               AFS_REQUEST_FLAG_SYNCHRONOUS,
145                                               &pCcb->AuthGroup,
146                                               &pCcb->DirectoryCB->NameInformation.FileName,
147                                               &pFcb->ObjectInformation->FileId,
148                                               pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
149                                               pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
150                                               &stLockRequestCB,
151                                               sizeof( AFSByteRangeLockRequestCB),
152                                               &stLockResultCB,
153                                               &ulResultLen);
154
155                 if( !NT_SUCCESS( ntStatus))
156                 {
157
158                     try_return( ntStatus);
159                 }
160
161                 break;
162             }
163
164             case IRP_MN_UNLOCK_ALL:
165             case IRP_MN_UNLOCK_ALL_BY_KEY:
166             {
167                 //
168                 // Flush data and then release the locks on the file server
169                 //
170
171                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
172                               AFS_TRACE_LEVEL_VERBOSE,
173                               "AFSLockControl Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
174                               &pFcb->NPFcb->SectionObjectResource,
175                               PsGetCurrentThread()));
176
177                 AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
178                                   TRUE);
179
180                 __try
181                 {
182
183                     CcFlushCache( &pFcb->NPFcb->SectionObjectPointers,
184                                   NULL,
185                                   0,
186                                   &stIoStatus);
187                 }
188                 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
189                 {
190
191                     ntStatus = GetExceptionCode();
192
193                     stIoStatus.Status = ntStatus;
194
195                     AFSDbgTrace(( 0,
196                                   0,
197                                   "EXCEPTION - AFSLockControl CcFlushCache failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
198                                   pFcb->ObjectInformation->FileId.Cell,
199                                   pFcb->ObjectInformation->FileId.Volume,
200                                   pFcb->ObjectInformation->FileId.Vnode,
201                                   pFcb->ObjectInformation->FileId.Unique,
202                                   ntStatus));
203                 }
204
205                 if( !NT_SUCCESS( stIoStatus.Status))
206                 {
207
208                     AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
209                                   AFS_TRACE_LEVEL_ERROR,
210                                   "AFSLockControl CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
211                                   pFcb->ObjectInformation->FileId.Cell,
212                                   pFcb->ObjectInformation->FileId.Volume,
213                                   pFcb->ObjectInformation->FileId.Vnode,
214                                   pFcb->ObjectInformation->FileId.Unique,
215                                   stIoStatus.Status,
216                                   stIoStatus.Information));
217
218                     ntStatus = stIoStatus.Status;
219                 }
220
221                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
222                               AFS_TRACE_LEVEL_VERBOSE,
223                               "AFSLockControl Releasing Fcb SectionObject lock %p SHARED %08lX\n",
224                               &pFcb->NPFcb->SectionObjectResource,
225                               PsGetCurrentThread()));
226
227                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
228
229                 RtlZeroMemory( &stUnlockRequestCB,
230                                sizeof( AFSByteRangeUnlockRequestCB));
231
232                 stUnlockRequestCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
233
234                 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL,
235                                               AFS_REQUEST_FLAG_SYNCHRONOUS,
236                                               &pCcb->AuthGroup,
237                                               &pCcb->DirectoryCB->NameInformation.FileName,
238                                               &pFcb->ObjectInformation->FileId,
239                                               pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
240                                               pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
241                                               (void *)&stUnlockRequestCB,
242                                               sizeof( AFSByteRangeUnlockRequestCB),
243                                               NULL,
244                                               NULL);
245
246                 //
247                 // Even on a failure we need to notify the rtl package of the unlock
248                 //
249
250                 break;
251             }
252
253             case IRP_MN_UNLOCK_SINGLE:
254             {
255                 //
256                 // Flush the data and then release the file server locks
257                 //
258
259                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
260                               AFS_TRACE_LEVEL_VERBOSE,
261                               "AFSLockControl Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
262                               &pFcb->NPFcb->SectionObjectResource,
263                               PsGetCurrentThread()));
264
265                 AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
266                                   TRUE);
267
268                 __try
269                 {
270
271                     CcFlushCache( &pFcb->NPFcb->SectionObjectPointers,
272                                   &pIrpSp->Parameters.LockControl.ByteOffset,
273                                   pIrpSp->Parameters.LockControl.Length->LowPart,
274                                   &stIoStatus);
275                 }
276                 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
277                 {
278
279                     ntStatus = GetExceptionCode();
280
281                     stIoStatus.Status = ntStatus;
282
283                     AFSDbgTrace(( 0,
284                                   0,
285                                   "EXCEPTION - AFSLockControl CcFlushCache failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
286                                   pFcb->ObjectInformation->FileId.Cell,
287                                   pFcb->ObjectInformation->FileId.Volume,
288                                   pFcb->ObjectInformation->FileId.Vnode,
289                                   pFcb->ObjectInformation->FileId.Unique,
290                                   ntStatus));
291                 }
292
293                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
294                               AFS_TRACE_LEVEL_VERBOSE,
295                               "AFSLockControl Releasing Fcb SectionObject lock %p SHARED %08lX\n",
296                               &pFcb->NPFcb->SectionObjectResource,
297                               PsGetCurrentThread()));
298
299                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
300
301                 if( !NT_SUCCESS( stIoStatus.Status))
302                 {
303
304                     AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
305                                   AFS_TRACE_LEVEL_ERROR,
306                                   "AFSLockControl CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
307                                   pFcb->ObjectInformation->FileId.Cell,
308                                   pFcb->ObjectInformation->FileId.Volume,
309                                   pFcb->ObjectInformation->FileId.Vnode,
310                                   pFcb->ObjectInformation->FileId.Unique,
311                                   stIoStatus.Status,
312                                   stIoStatus.Information));
313
314                     ntStatus = stIoStatus.Status;
315                 }
316
317                 stUnlockRequestCB.Count = 1;
318
319                 stUnlockRequestCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
320
321                 stUnlockRequestCB.Request[ 0].LockType = AFS_BYTE_RANGE_LOCK_TYPE_EXCL;
322
323                 stUnlockRequestCB.Request[ 0].Offset = pIrpSp->Parameters.LockControl.ByteOffset;
324
325                 stUnlockRequestCB.Request[ 0].Length.QuadPart = pIrpSp->Parameters.LockControl.Length->QuadPart;
326
327                 ulResultLen = sizeof( AFSByteRangeUnlockResultCB);
328
329                 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK,
330                                               AFS_REQUEST_FLAG_SYNCHRONOUS,
331                                               &pCcb->AuthGroup,
332                                               &pCcb->DirectoryCB->NameInformation.FileName,
333                                               &pFcb->ObjectInformation->FileId,
334                                               pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
335                                               pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
336                                               (void *)&stUnlockRequestCB,
337                                               sizeof( AFSByteRangeUnlockRequestCB),
338                                               (void *)&stUnlockResultCB,
339                                               &ulResultLen);
340
341                 break;
342             }
343
344             default:
345
346                 break;
347         }
348
349         //
350         // Below here we won't complete the request, it is handled by the lock package
351         //
352
353         bCompleteRequest = FALSE;
354
355         //
356         //  Now call the system package for actually processing the lock request
357         //
358
359         ntStatus = FsRtlProcessFileLock( &pFcb->Specific.File.FileLock,
360                                          Irp,
361                                          NULL);
362
363 try_exit:
364
365         if( bReleaseResource)
366         {
367
368             //
369             // And drop it
370             //
371
372             AFSReleaseResource( &pFcb->NPFcb->Resource);
373         }
374
375         if( bCompleteRequest)
376         {
377
378             AFSCompleteRequest( Irp,
379                                 ntStatus);
380         }
381     }
382     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
383     {
384
385         AFSDbgTrace(( 0,
386                       0,
387                       "EXCEPTION - AFSLockControl\n"));
388
389         AFSDumpTraceFilesFnc();
390
391         //
392         // Again, there is little point in failing this request but pass back some type of failure status
393         //
394
395         ntStatus = STATUS_UNSUCCESSFUL;
396
397         AFSCompleteRequest( Irp,
398                             ntStatus);
399     }
400
401     return ntStatus;
402 }